cGFja2FnZSBvcmcuZWNsaXBzZS54dGVuZC5saWIuYW5ub3RhdGlvbnMKCmltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5hbm5vdGF0aW9ucy5CZXRhCmltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5hbm5vdGF0aW9ucy5Hd3RDb21wYXRpYmxlCmltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LlNldHMKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkVsZW1lbnRUeXBlCmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQKaW1wb3J0IGphdmEudXRpbC5MaXN0CmltcG9ydCBqYXZhLnV0aWwuU2V0CmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uQWN0aXZlCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uVHJhbnNmb3JtYXRpb25Db250ZXh0CmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uVHJhbnNmb3JtYXRpb25QYXJ0aWNpcGFudAppbXBvcnQgb3JnLmVjbGlwc2UueHRlbmQubGliLm1hY3JvLmRlY2xhcmF0aW9uLkZpZWxkRGVjbGFyYXRpb24KaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5kZWNsYXJhdGlvbi5JbnRlcmZhY2VEZWNsYXJhdGlvbgppbXBvcnQgb3JnLmVjbGlwc2UueHRlbmQubGliLm1hY3JvLmRlY2xhcmF0aW9uLk1lbWJlckRlY2xhcmF0aW9uCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uZGVjbGFyYXRpb24uTWV0aG9kRGVjbGFyYXRpb24KaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5kZWNsYXJhdGlvbi5NdXRhYmxlTWVtYmVyRGVjbGFyYXRpb24KaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5kZWNsYXJhdGlvbi5SZXNvbHZlZE1ldGhvZAppbXBvcnQgb3JnLmVjbGlwc2UueHRlbmQubGliLm1hY3JvLmRlY2xhcmF0aW9uLlR5cGVEZWNsYXJhdGlvbgppbXBvcnQgb3JnLmVjbGlwc2UueHRlbmQubGliLm1hY3JvLmRlY2xhcmF0aW9uLlR5cGVSZWZlcmVuY2UKaW1wb3J0IGphdmEudXRpbC5NYXAKaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLkRvY3VtZW50ZWQKCi8qKgogKiBJbXBsZW1lbnRzIGludGVyZmFjZXMgYnkgZm9yd2FyZGluZyBtZXRob2QgY2FsbHMgdG8gYW4gYW5ub3RhdGVkIGZpZWxkIG9yIG1ldGhvZC4KICogCiAqIDxwPgogKiA8cHJlPgogKiBpbnRlcmZhY2UgSSB7CiAqICBkZWYgU3RyaW5nIG0oKQogKiB9CiAqIGNsYXNzIEZvbyBpbXBsZW1lbnRzIEkgewogKiAgb3ZlcnJpZGUgU3RyaW5nIG0oKSB7CiAqICAgIkZvbyIKICogIH0KICogfQogKiBjbGFzcyBCYXIgaW1wbGVtZW50cyBJIHsKICogIC8vVGhpcyB3aWxsIGdlbmVyYXRlIGEgbWV0aG9kIG0oKSwgd2hpY2ggY2FsbHMgZm9vLm0oKQogKiAgJiM2NDtEZWxlZ2F0ZSB2YWwgZm9vID0gbmV3IEZvbwogKiB9CiAqIDwvcHJlPgogKiAKICogRm9yIGVhY2ggaW50ZXJmYWNlIHRoYXQgdGhlIGRlY2xhcmluZyBjbGFzcyBhbmQgdGhlIGRlbGVnYXRlIGhhdmUgaW4gY29tbW9uLAogKiBhbiBpbXBsZW1lbnRhdGlvbiBmb3IgZWFjaCBtZXRob2QgaXMgYWRkZWQgaWYgaXQgZG9lcyBub3QgeWV0IGV4aXN0LiBUaGlzCiAqIGltcGxlbWVudGF0aW9uIGZvcndhcmRzIGFsbCBjYWxscyBkaXJlY3RseSB0byB0aGUgZGVsZWdhdGUuIFlvdSBjYW4gcmVzdHJpY3QKICogd2hpY2ggaW50ZXJmYWNlcyB0byBpbXBsZW1lbnQgdXNpbmcgdGhlIHtAbGluayBDbGFzc31bXSB2YWx1ZSBvZiB0aGlzCiAqIGFubm90YXRpb24uIFRoaXMgaXMgZXNwZWNpYWxseSB1c2VmdWwgd2hlbiB0aGVyZSBhcmUgc2V2ZXJhbCBkZWxlZ2F0ZXMgdGhhdAogKiBoYXZlIHNvbWUgaW50ZXJmYWNlcyBpbiBjb21tb24uCiAqIAogKiA8L3A+CiAqIERlbGVnYXRlIG1ldGhvZHMgY2FuIGVpdGhlciB0YWtlCiAqIDx1bD4KICogPGxpPm5vIGFyZ3VtZW50czwvbGk+CiAqIDxsaT50aGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGJlIGNhbGxlZCAoU3RyaW5nKTwvbGk+CiAqIDxsaT50aGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGJlIGNhbGxlZCAoU3RyaW5nKSwgaXRzIHBhcmFtZXRlciB0eXBlcwogKiAoQ2xhc3NbXSkgYW5kIHRoZSBhY3R1YWwgYXJndW1lbnRzIChPYmplY3RbXSkgb2YgdGhlIGNhbGw8L2xpPgogKiA8L3VsPgogKiBUaGlzIGFsbG93cyB5b3UgdG8gZ2VuZXJhdGUgbWVhbmluZ2Z1bCBlcnJvciBtZXNzYWdlcyBvciB0byBkeW5hbWljYWxseQogKiBkaXNwYXRjaCBiYXNlZCBvbiB0aGUgYXJndW1lbnRzLgogKiAKICogQHNpbmNlIDIuNwogKi8KQEJldGEKQEd3dENvbXBhdGlibGUKQFRhcmdldChFbGVtZW50VHlwZS5GSUVMRCwgRWxlbWVudFR5cGUuTUVUSE9EKQpAQWN0aXZlKERlbGVnYXRlUHJvY2Vzc29yKQpARG9jdW1lbnRlZAphbm5vdGF0aW9uIERlbGVnYXRlIHsKCS8qKgoJICogT3B0aW9uYWwgbGlzdCBvZiBpbnRlcmZhY2VzIHRoYXQgdGhpcyBkZWxlZ2F0ZSBpcyByZXN0cmljdGVkIHRvLgoJICogRGVmYXVsdHMgdG8gdGhlIGNvbW1vbiBpbnRlcmZhY2VzIG9mIHRoZSBjb250ZXh0IHR5cGUgYW5kIHRoZSBhbm5vdGF0ZWQKCSAqIGVsZW1lbnQuCgkgKi8KCUNsYXNzPD8+W10gdmFsdWUgPSAjW10KfQoKLyoqCiAqIEBzaW5jZSAyLjcKICogQG5vZXh0ZW5kCiAqIEBub3JlZmVyZW5jZQogKi8KQEJldGEKY2xhc3MgRGVsZWdhdGVQcm9jZXNzb3IgaW1wbGVtZW50cyBUcmFuc2Zvcm1hdGlvblBhcnRpY2lwYW50PE11dGFibGVNZW1iZXJEZWNsYXJhdGlvbj4gewoKCW92ZXJyaWRlIGRvVHJhbnNmb3JtKExpc3Q8PyBleHRlbmRzIE11dGFibGVNZW1iZXJEZWNsYXJhdGlvbj4gZWxlbWVudHMsIGV4dGVuc2lvbiBUcmFuc2Zvcm1hdGlvbkNvbnRleHQgY29udGV4dCkgewoJCXZhbCBleHRlbnNpb24gdXRpbCA9IG5ldyBEZWxlZ2F0ZVByb2Nlc3Nvci5VdGlsKGNvbnRleHQpCgkJZWxlbWVudHMuZm9yRWFjaCBbCgkJCWlmICh2YWxpZERlbGVnYXRlKSB7CgkJCQltZXRob2RzVG9JbXBsZW1lbnQuZm9yRWFjaFttZXRob2R8aW1wbGVtZW50TWV0aG9kKG1ldGhvZCldCgkJCX0KCQldCgl9CgoJLyoqCgkgKiBAc2luY2UgMi43CgkgKiBAbm9leHRlbmQKCSAqIEBub3JlZmVyZW5jZQogCSovCiAJQEJldGEKCXN0YXRpYyBjbGFzcyBVdGlsIHsKCQlleHRlbnNpb24gVHJhbnNmb3JtYXRpb25Db250ZXh0IGNvbnRleHQKCgkJbmV3KFRyYW5zZm9ybWF0aW9uQ29udGV4dCBjb250ZXh0KSB7CgkJCXRoaXMuY29udGV4dCA9IGNvbnRleHQKCQl9CgkJCgkJZGVmIGRpc3BhdGNoIGlzVmFsaWREZWxlZ2F0ZShGaWVsZERlY2xhcmF0aW9uIGl0KSB7CgkJCWhhc1ZhbGlkVHlwZSAmJiAhaGFzRGVsZWdhdGlvbkNvbmZsaWN0cyAmJiBhcmVMaXN0ZWRJbnRlcmZhY2VzVmFsaWQKCQl9CgoJCWRlZiBkaXNwYXRjaCBpc1ZhbGlkRGVsZWdhdGUoTWV0aG9kRGVjbGFyYXRpb24gaXQpIHsKCQkJaGFzVmFsaWRUeXBlICYmIGhhc1ZhbGlkU2lnbmF0dXJlICYmICFoYXNEZWxlZ2F0aW9uQ29uZmxpY3RzICYmIGFyZUxpc3RlZEludGVyZmFjZXNWYWxpZAoJCX0KCgkJZGVmIGhhc1ZhbGlkVHlwZShNZW1iZXJEZWNsYXJhdGlvbiBpdCkgewoJCQlpZiAodHlwZSA9PT0gbnVsbCB8fCB0eXBlLmluZmVycmVkKSB7CgkJCQlhZGRFcnJvcigiQ2Fubm90IHVzZSBpbmZlcnJlZCB0eXBlcyBvbiBkZWxlZ2F0ZXMiKQoJCQkJZmFsc2UKCQkJfSBlbHNlIHsKCQkJCXRydWUKCQkJfQoJCX0KCQkKCQlkZWYgZGlzcGF0Y2ggZ2V0VHlwZShGaWVsZERlY2xhcmF0aW9uIGl0KSB7CgkJCXR5cGUKCQl9CgoJCWRlZiBkaXNwYXRjaCBnZXRUeXBlKE1ldGhvZERlY2xhcmF0aW9uIGl0KSB7CgkJCXJldHVyblR5cGUKCQl9CgkJCgkJZGVmIGhhc1ZhbGlkU2lnbmF0dXJlKE1ldGhvZERlY2xhcmF0aW9uIGl0KSB7CgkJCXN3aXRjaCBwYXJhbWV0ZXJzLm1hcFt0eXBlXS50b0xpc3QgewoJCQkJY2FzZSAjW10sCgkJCQljYXNlICNbc3RyaW5nXSwKCQkJCWNhc2UgI1tzdHJpbmcsIENsYXNzLm5ld1R5cGVSZWZlcmVuY2UobmV3V2lsZGNhcmRUeXBlUmVmZXJlbmNlKS5uZXdBcnJheVR5cGVSZWZlcmVuY2UsIG9iamVjdC5uZXdBcnJheVR5cGVSZWZlcmVuY2VdOgoJCQkJCXRydWUKCQkJCWRlZmF1bHQ6IHsKCQkJCQlhZGRFcnJvcigiTm90IGEgdmFsaWQgZGVsZWdhdGUgc2lnbmF0dXJlLCB1c2UgKCkgb3IgKFN0cmluZyBtZXRob2ROYW1lKSBvciAoU3RyaW5nIG1ldGhvZE5hbWUsIENsYXNzPD8+W10gYXJndW1lbnRUeXBlcywgT2JqZWN0W10gYXJndW1lbnRzKSIpCgkJCQkJZmFsc2UKCQkJCX0KCQkJfQoJCX0KCgkJZGVmIGhhc0RlbGVnYXRpb25Db25mbGljdHMoTWVtYmVyRGVjbGFyYXRpb24gZGVsZWdhdGUpIHsKCQkJdmFyIGNvbmZsaWN0ID0gZmFsc2UKCQkJZm9yIChvdGhlciA6IGRlbGVnYXRlLm90aGVyRGVsZWdhdGVzKSB7CgkJCQl2YWwgb3RoZXJJbnRlcmZhY2VzID0gb3RoZXIuZGVsZWdhdGVkSW50ZXJmYWNlcwoJCQkJZm9yIChpZmFjZSA6IGRlbGVnYXRlLmRlbGVnYXRlZEludGVyZmFjZXMpIHsKCQkJCQlpZiAob3RoZXJJbnRlcmZhY2VzLmNvbnRhaW5zKGlmYWNlKSkgewoJCQkJCQljb25mbGljdCA9IHRydWUKCQkJCQkJZGVsZWdhdGUuYWRkRXJyb3IoJycnVGhlIGludGVyZmFjZSCraWZhY2Uuc2ltcGxlTmFtZbsgaXMgYWxzbyBpbXBsZW1lbnRlZCBieSB0aGUgZGVsZWdhdGUgq290aGVyLnNpbXBsZU5hbWW7JycnKQoJCQkJCX0KCQkJCX0KCQkJfQoJCQljb25mbGljdAoJCX0KCQkKCQlkZWYgb3RoZXJEZWxlZ2F0ZXMoTWVtYmVyRGVjbGFyYXRpb24gZGVsZWdhdGUpIHsKCQkJZGVsZWdhdGUuZGVjbGFyaW5nVHlwZS5kZWxlZ2F0ZXMuZmlsdGVyW2l0ICE9IGRlbGVnYXRlXQoJCX0KCgkJZGVmIGFyZUxpc3RlZEludGVyZmFjZXNWYWxpZChNZW1iZXJEZWNsYXJhdGlvbiBkZWxlZ2F0ZSkgewoJCQl2YWwgZGVjbGFyaW5nVHlwZSA9IGRlbGVnYXRlLmRlY2xhcmluZ1R5cGUubmV3U2VsZlR5cGVSZWZlcmVuY2UKCQkJdmFsIGludGVyZmFjZXNPZkRlY2xhcmluZ1R5cGUgPSBkZWNsYXJpbmdUeXBlLmltcGxlbWVudGVkSW50ZXJmYWNlcwoJCQl2YWwgYXZhaWxhYmxlSW50ZXJmYWNlcyA9IGRlbGVnYXRlLnR5cGUuaW1wbGVtZW50ZWRJbnRlcmZhY2VzCgkJCXZhbCBsaXN0ZWRJbnRlcmZhY2VzID0gZGVsZWdhdGUubGlzdGVkSW50ZXJmYWNlcwoJCQl2YXIgdmFsaWQgPSB0cnVlCgkJCWZvcihpZmFjZSA6IGxpc3RlZEludGVyZmFjZXMpIHsKCQkJCWlmICghYXZhaWxhYmxlSW50ZXJmYWNlcy5leGlzdHNbdHlwZSA9PSBpZmFjZS50eXBlXSkgewoJCQkJCWRlbGVnYXRlLmFkZEVycm9yKCcnJ6tkZWxlZ2F0ZS50eXBlLnNpbXBsZU5hbWW7IGRvZXMgbm90IGltcGxlbWVudCCraWZhY2Uuc2ltcGxlTmFtZbsnJycpCgkJCQkJdmFsaWQgPSBmYWxzZQoJCQkJfQoJCQkJaWYgKCFpbnRlcmZhY2VzT2ZEZWNsYXJpbmdUeXBlLmV4aXN0c1t0eXBlID09IGlmYWNlLnR5cGVdKSB7CgkJCQkJZGVsZWdhdGUuYWRkRXJyb3IoJycnq2RlY2xhcmluZ1R5cGUuc2ltcGxlTmFtZbsgZG9lcyBub3QgaW1wbGVtZW50IKtpZmFjZS5zaW1wbGVOYW1luycnJykKCQkJCQl2YWxpZCA9IGZhbHNlCgkJCQl9CgkJCX0KCQkJaWYgKGxpc3RlZEludGVyZmFjZXMuZW1wdHkgJiYgU2V0cy5pbnRlcnNlY3Rpb24oaW50ZXJmYWNlc09mRGVjbGFyaW5nVHlwZSwgYXZhaWxhYmxlSW50ZXJmYWNlcykuZW1wdHkpIHsKCQkJCWRlbGVnYXRlLmFkZEVycm9yKCcnJ6tkZWxlZ2F0ZS50eXBlLnNpbXBsZU5hbWW7IGFuZCCrZGVjbGFyaW5nVHlwZS5zaW1wbGVOYW1luyBoYXZlIG5vIGludGVyZmFjZXMgaW4gY29tbW9uJycnKQoJCQkJdmFsaWQgPSBmYWxzZQoJCQl9CgkJCXZhbGlkCgkJfQoKCQlkZWYgZ2V0RGVsZWdhdGVzKFR5cGVEZWNsYXJhdGlvbiBpdCkgewoJCQlkZWNsYXJlZE1lbWJlcnMuZmlsdGVyW2ZpbmRBbm5vdGF0aW9uKGZpbmRUeXBlR2xvYmFsbHkoRGVsZWdhdGUpKSAhPT0gbnVsbF0KCQl9CgkJCgkJZGVmIGxpc3RlZEludGVyZmFjZXMoTWVtYmVyRGVjbGFyYXRpb24gaXQpIHsKCQkJZmluZEFubm90YXRpb24oZmluZFR5cGVHbG9iYWxseShEZWxlZ2F0ZSkpLmdldENsYXNzQXJyYXlWYWx1ZSgidmFsdWUiKS50b1NldAoJCX0KCgkJZGVmIFNldDxUeXBlUmVmZXJlbmNlPiBnZXRJbXBsZW1lbnRlZEludGVyZmFjZXMoVHlwZVJlZmVyZW5jZSBpdCkgewoJCQl2YWwgc2VlbiA9IG5ld0xpbmtlZEhhc2hTZXQKCQkJY29sbGVjdEFsbFN1cGVyVHlwZXMoc2VlbikKCQkJc2Vlbi5maWx0ZXJbdHlwZSBpbnN0YW5jZW9mIEludGVyZmFjZURlY2xhcmF0aW9uXS50b1NldAoJCX0KCQkKCQlwcml2YXRlIGRlZiB2b2lkIGNvbGxlY3RBbGxTdXBlclR5cGVzKFR5cGVSZWZlcmVuY2UgaXQsIFNldDxUeXBlUmVmZXJlbmNlPiBzZWVuKSB7CgkJCXZhbCBjeWNsZSA9ICFzZWVuLmFkZChpdCkKCQkJaWYgKGN5Y2xlKQoJCQkJcmV0dXJuOwoJCQlkZWNsYXJlZFN1cGVyVHlwZXMuZm9yRWFjaFtjb2xsZWN0QWxsU3VwZXJUeXBlcyhzZWVuKV0KCQl9CgoJCWRlZiBnZXREZWxlZ2F0ZWRJbnRlcmZhY2VzKE1lbWJlckRlY2xhcmF0aW9uIGRlbGVnYXRlKSB7CgkJCXZhbCBpbnRlcmZhY2VzT2ZEZWNsYXJpbmdUeXBlID0gZGVsZWdhdGUuZGVjbGFyaW5nVHlwZS5uZXdTZWxmVHlwZVJlZmVyZW5jZS5pbXBsZW1lbnRlZEludGVyZmFjZXMKCQkJdmFsIGxpc3RlZEludGVyZmFjZXMgPSBkZWxlZ2F0ZS5saXN0ZWRJbnRlcmZhY2VzCgkJCXZhbCBhdmFpbGFibGVJbnRlcmZhY2VzID0gZGVsZWdhdGUudHlwZS5pbXBsZW1lbnRlZEludGVyZmFjZXMKCQkJYXZhaWxhYmxlSW50ZXJmYWNlcy5maWx0ZXJbaWZhY2V8CgkJCQlpbnRlcmZhY2VzT2ZEZWNsYXJpbmdUeXBlLmNvbnRhaW5zKGlmYWNlKQoJCQkJJiYgKGxpc3RlZEludGVyZmFjZXMuZW1wdHkgfHwgbGlzdGVkSW50ZXJmYWNlcy5leGlzdHNbaWZhY2UuaXNBc3NpZ25hYmxlRnJvbShpdCldKQoJCQldLnRvU2V0CgkJfQoKCQlkZWYgZ2V0TWV0aG9kc1RvSW1wbGVtZW50KE1lbWJlckRlY2xhcmF0aW9uIGRlbGVnYXRlKSB7CgkJCWRlbGVnYXRlLmRlbGVnYXRlZEludGVyZmFjZXMubWFwW2RlY2xhcmVkUmVzb2x2ZWRNZXRob2RzXS5mbGF0dGVuCgkJCQkuZmlsdGVyW2RlbGVnYXRlLmRlY2xhcmluZ1R5cGUuZmluZERlY2xhcmVkTWV0aG9kKGRlY2xhcmF0aW9uLnNpbXBsZU5hbWUsIHJlc29sdmVkUGFyYW1ldGVycy5tYXBbcmVzb2x2ZWRUeXBlXSkgPT09IG51bGxdCgkJCQkuZmlsdGVyWyFpc09iamVjdE1ldGhvZF0KCQkJCS5maWx0ZXJbIWlzU3RhdGljXQoJCQkJLmdyb3VwQnlbc2ltcGxlU2lnbmF0dXJlXS52YWx1ZXMubWFwW2hlYWRdCgkJCQkuc29ydEJ5W3NpbXBsZVNpZ25hdHVyZV0KCQkJCS50b1NldAoJCX0KCQoJCWRlZiBpc09iamVjdE1ldGhvZChSZXNvbHZlZE1ldGhvZCBpdCkgewoJCQl2YWwgbmFtZSA9IGRlY2xhcmF0aW9uLnNpbXBsZU5hbWUKCQkJdmFsIHBhcmFtZXRlclR5cGVzID0gcmVzb2x2ZWRQYXJhbWV0ZXJzLm1hcFtyZXNvbHZlZFR5cGVdLnRvTGlzdAoJCQkKCQkJbmFtZSA9PSAiaGFzaENvZGUiICYmIHBhcmFtZXRlclR5cGVzLmVtcHR5CgkJCXx8IG5hbWUgPT0gInRvU3RyaW5nIiAmJiBwYXJhbWV0ZXJUeXBlcy5lbXB0eQoJCQl8fCBuYW1lID09ICJlcXVhbHMiICYmIHBhcmFtZXRlclR5cGVzID09ICNbb2JqZWN0XQoJCQl8fCBuYW1lID09ICJmaW5hbGl6ZSIgJiYgcGFyYW1ldGVyVHlwZXMuZW1wdHkKCQkJfHwgbmFtZSA9PSAiY2xvbmUiICYmIHBhcmFtZXRlclR5cGVzLmVtcHR5CgkJfQoKCQlkZWYgaXNTdGF0aWMoUmVzb2x2ZWRNZXRob2QgaXQpIHsKCQkJZGVjbGFyYXRpb24uaXNTdGF0aWMKCQl9CgoJCWRlZiBpbXBsZW1lbnRNZXRob2QoTXV0YWJsZU1lbWJlckRlY2xhcmF0aW9uIGRlbGVnYXRlLCBSZXNvbHZlZE1ldGhvZCByZXNvbHZlZE1ldGhvZCkgewoJCQlkZWxlZ2F0ZS5tYXJrQXNSZWFkCgkJCXZhbCBkZWNsYXJhdGlvbiA9IHJlc29sdmVkTWV0aG9kLmRlY2xhcmF0aW9uCgkJCWRlbGVnYXRlLmRlY2xhcmluZ1R5cGUuYWRkTWV0aG9kKGRlY2xhcmF0aW9uLnNpbXBsZU5hbWUpIFsgaW1wbCB8CgkJCQlpbXBsLnByaW1hcnlTb3VyY2VFbGVtZW50ID0gZGVsZWdhdGUucHJpbWFyeVNvdXJjZUVsZW1lbnQKCQkJCXZhbCB0eXBlUGFyYW1ldGVyTWFwcGluZ3MgPSBuZXdIYXNoTWFwCgkJCQlyZXNvbHZlZE1ldGhvZC5yZXNvbHZlZFR5cGVQYXJhbWV0ZXJzLmZvckVhY2hbcGFyYW18CgkJCQkJdmFsIGNvcHkgPSBpbXBsLmFkZFR5cGVQYXJhbWV0ZXIocGFyYW0uZGVjbGFyYXRpb24uc2ltcGxlTmFtZSwgcGFyYW0ucmVzb2x2ZWRVcHBlckJvdW5kcykKCQkJCQl0eXBlUGFyYW1ldGVyTWFwcGluZ3MucHV0KHBhcmFtLmRlY2xhcmF0aW9uLm5ld1R5cGVSZWZlcmVuY2UsIGNvcHkubmV3VHlwZVJlZmVyZW5jZSkKCQkJCQljb3B5LnVwcGVyQm91bmRzID0gY29weS51cHBlckJvdW5kcy5tYXBbcmVwbGFjZSh0eXBlUGFyYW1ldGVyTWFwcGluZ3MpXQoJCQkJXQoJCQkJaW1wbC5leGNlcHRpb25zID0gcmVzb2x2ZWRNZXRob2QucmVzb2x2ZWRFeGNlcHRpb25UeXBlcy5tYXBbcmVwbGFjZSh0eXBlUGFyYW1ldGVyTWFwcGluZ3MpXQoJCQkJaW1wbC52YXJBcmdzID0gZGVjbGFyYXRpb24udmFyQXJncwoJCQkJaW1wbC5yZXR1cm5UeXBlID0gcmVzb2x2ZWRNZXRob2QucmVzb2x2ZWRSZXR1cm5UeXBlLnJlcGxhY2UodHlwZVBhcmFtZXRlck1hcHBpbmdzKQoJCQkJcmVzb2x2ZWRNZXRob2QucmVzb2x2ZWRQYXJhbWV0ZXJzLmZvckVhY2hbcHxpbXBsLmFkZFBhcmFtZXRlcihwLmRlY2xhcmF0aW9uLnNpbXBsZU5hbWUsIHAucmVzb2x2ZWRUeXBlLnJlcGxhY2UodHlwZVBhcmFtZXRlck1hcHBpbmdzKSldCgkJCQlpbXBsLmJvZHkgPSAnJycKCQkJCQmrcmVzb2x2ZWRNZXRob2QucmV0dXJuSWZOZWVkZWS7q2RlbGVnYXRlLmRlbGVnYXRlQWNjZXNzKGRlY2xhcmF0aW9uKbsuq2RlY2xhcmF0aW9uLnNpbXBsZU5hbWW7KKtkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzLmpvaW4oIiwgIilbc2ltcGxlTmFtZV27KTsKCQkJCScnJwoJCQldCgkJfQoJCQoJCWRlZiBUeXBlUmVmZXJlbmNlIHJlcGxhY2UoVHlwZVJlZmVyZW5jZSB0YXJnZXQsIE1hcDw/IGV4dGVuZHMgVHlwZVJlZmVyZW5jZSwgPyBleHRlbmRzIFR5cGVSZWZlcmVuY2U+IG1hcHBpbmdzKSB7CgkJCW1hcHBpbmdzLmVudHJ5U2V0LmZvbGQodGFyZ2V0KVtyZXN1bHQsIG1hcHBpbmd8cmVzdWx0LnJlcGxhY2UobWFwcGluZy5rZXksIG1hcHBpbmcudmFsdWUpXQoJCX0KCQkKCQlkZWYgVHlwZVJlZmVyZW5jZSByZXBsYWNlKFR5cGVSZWZlcmVuY2UgdGFyZ2V0LCBUeXBlUmVmZXJlbmNlIG9sZFR5cGUsIFR5cGVSZWZlcmVuY2UgbmV3VHlwZSkgewoJCQlpZiAodGFyZ2V0ID09IG9sZFR5cGUpCgkJCQlyZXR1cm4gbmV3VHlwZQoJCQlpZiAoIXRhcmdldC5hY3R1YWxUeXBlQXJndW1lbnRzLmlzRW1wdHkpCgkJCQlyZXR1cm4gbmV3VHlwZVJlZmVyZW5jZSh0YXJnZXQudHlwZSwgdGFyZ2V0LmFjdHVhbFR5cGVBcmd1bWVudHMubWFwW3JlcGxhY2Uob2xkVHlwZSwgbmV3VHlwZSldKQoJCQlpZiAodGFyZ2V0LndpbGRDYXJkKSB7CgkJCQlpZiAodGFyZ2V0LnVwcGVyQm91bmQgIT0gb2JqZWN0KQoJCQkJCXJldHVybiB0YXJnZXQudXBwZXJCb3VuZC5yZXBsYWNlKG9sZFR5cGUsIG5ld1R5cGUpLm5ld1dpbGRjYXJkVHlwZVJlZmVyZW5jZQoJCQkJZWxzZSBpZiAoIXRhcmdldC5sb3dlckJvdW5kLmlzQW55VHlwZSkKCQkJCQlyZXR1cm4gdGFyZ2V0Lmxvd2VyQm91bmQucmVwbGFjZShvbGRUeXBlLCBuZXdUeXBlKS5uZXdXaWxkY2FyZFR5cGVSZWZlcmVuY2VXaXRoTG93ZXJCb3VuZAoJCQl9CgkJCWlmICh0YXJnZXQuaXNBcnJheSkKCQkJCXJldHVybiB0YXJnZXQuYXJyYXlDb21wb25lbnRUeXBlLnJlcGxhY2Uob2xkVHlwZSwgbmV3VHlwZSkubmV3QXJyYXlUeXBlUmVmZXJlbmNlCgkJCXJldHVybiB0YXJnZXQKCQl9CgkJCgkJZGVmIGRpc3BhdGNoIGRlbGVnYXRlQWNjZXNzKEZpZWxkRGVjbGFyYXRpb24gaXQsIE1ldGhvZERlY2xhcmF0aW9uIG1ldGhvZCkgewoJCQknJyd0aGlzLqtzaW1wbGVOYW1luycnJwoJCX0KCgkJZGVmIGRpc3BhdGNoIGRlbGVnYXRlQWNjZXNzKE1ldGhvZERlY2xhcmF0aW9uIGl0LCBNZXRob2REZWNsYXJhdGlvbiBtZXRob2QpIHsKCQkJc3dpdGNoIHBhcmFtZXRlcnMubWFwW3R5cGVdLnRvTGlzdCB7CgkJCQljYXNlICNbXTogCgkJCQkJJycndGhpcy6rc2ltcGxlTmFtZbsoKScnJwoJCQkJY2FzZSAjW3N0cmluZ106IAoJCQkJCScnJ3RoaXMuq3NpbXBsZU5hbWW7KCKrbWV0aG9kLnNpbXBsZU5hbWW7IiknJycKCQkJCWNhc2UgI1tzdHJpbmcsIENsYXNzLm5ld1R5cGVSZWZlcmVuY2UobmV3V2lsZGNhcmRUeXBlUmVmZXJlbmNlKS5uZXdBcnJheVR5cGVSZWZlcmVuY2UsIG9iamVjdC5uZXdBcnJheVR5cGVSZWZlcmVuY2VdOiB7CgkJCQkJJycndGhpcy6rc2ltcGxlTmFtZbsoIqttZXRob2Quc2ltcGxlTmFtZbsiLCBuZXcgQ2xhc3NbXXurbWV0aG9kLnBhcmFtZXRlcnMuam9pbigiLCAiKVt0eXBlLnR5cGUuc2ltcGxlTmFtZSArICIuY2xhc3MiXbt9LCBuZXcgT2JqZWN0W117q21ldGhvZC5wYXJhbWV0ZXJzLmpvaW4oIiwgIilbc2ltcGxlTmFtZV27fSknJycKCQkJCX0KCQkJCWRlZmF1bHQ6CgkJCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiZGVsZWdhdGUgc2lnbmF0dXJlIikKCQkJfQoJCX0KCgkJZGVmIHJldHVybklmTmVlZGVkKFJlc29sdmVkTWV0aG9kIGl0KSB7CgkJCWlmKHJlc29sdmVkUmV0dXJuVHlwZS5pc1ZvaWQpICIiIGVsc2UgInJldHVybiAiCgkJfQoJfQoKfQo=