cGFja2FnZSBvcmcuZWNsaXBzZS54dGVuZC5saWIKCmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5Eb2N1bWVudGVkCmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZQppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0CmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIuYW5ub3RhdGlvbnMuQWNjZXNzb3JzUHJvY2Vzc29yCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIuYW5ub3RhdGlvbnMuRXF1YWxzSGFzaENvZGVQcm9jZXNzb3IKaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5hbm5vdGF0aW9ucy5GaW5hbEZpZWxkc0NvbnN0cnVjdG9yUHJvY2Vzc29yCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIuYW5ub3RhdGlvbnMuVG9TdHJpbmdQcm9jZXNzb3IKaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5BYnN0cmFjdENsYXNzUHJvY2Vzc29yCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uQWN0aXZlCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uVHJhbnNmb3JtYXRpb25Db250ZXh0CmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uZGVjbGFyYXRpb24uQ2xhc3NEZWNsYXJhdGlvbgppbXBvcnQgb3JnLmVjbGlwc2UueHRlbmQubGliLm1hY3JvLmRlY2xhcmF0aW9uLk11dGFibGVDbGFzc0RlY2xhcmF0aW9uCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uZGVjbGFyYXRpb24uVmlzaWJpbGl0eQoKLyoqCiAqIFRoaXMgYW5ub3RhdGlvbiBpcyB1c2VkIGJ5IHRoZSBYdGVuZCBjb21waWxlci4KICogSXQgdHVybnMgYW4gYW5ub3RhdGVkIGNsYXNzIGludG8gYW4gaW1tdXRhYmxlIHZhbHVlIG9iamVjdC4KICogCiAqIEFsbCBmaWVsZHMgYmVjb21lIGZpbmFsIGFuZCBhIGdldHRlciBtZXRob2QgaXMgYWRkZWQuCiAqIFRoZSBmaWVsZHMnIG5hbWUgYXJlIHByZXBlbmRlZCB3aXRoIGFuIHVuZGVyc2NvcmUgKGkuZS4gPHR0Pm15RmllbGQ8L3R0PiBiZWNvbWVzIDx0dD5fbXlGaWVsZDwvdHQ+KQogKiBPbmUgY29uc3RydWN0b3IgZm9yIGluaXRpYWxpemluZyB0aGUgdW5pbml0aWFsaXplZCBmaWVsZHMgaXMgYWRkZWQuCiAqIHtAbGluayBPYmplY3QjZXF1YWxzKE9iamVjdCl9IGFuZCB7QGxpbmsgT2JqZWN0I2hhc2hDb2RlKCl9IGltcGxlbWVudGF0aW9ucyBhcmUgYWRkZWQuCiAqIHtAbGluayBPYmplY3QjdG9TdHJpbmcoKX0gaW1wbGVtZW50YXRpb24gaXMgYWRkZWQuICAKICogCiAqIEBhdXRob3IgU3ZlbiBFZmZ0aW5nZQogKiBAZGVwcmVjYXRlZCB1c2Uge0BsaW5rIG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5hbm5vdGF0aW9ucy5EYXRhfSBpbnN0ZWFkCiAqLwpAVGFyZ2V0KEVsZW1lbnRUeXBlLlRZUEUpCkBBY3RpdmUoRGF0YVByb2Nlc3NvcikKQERlcHJlY2F0ZWQKQERvY3VtZW50ZWQKYW5ub3RhdGlvbiBEYXRhIHsKfQoKLyoqCiAqIEBzaW5jZSAyLjcKICogQG5vZXh0ZW5kCiAqIEBub3JlZmVyZW5jZQogKi8KQERlcHJlY2F0ZWQKY2xhc3MgRGF0YVByb2Nlc3NvciBleHRlbmRzIEFic3RyYWN0Q2xhc3NQcm9jZXNzb3IgewoJb3ZlcnJpZGUgZG9UcmFuc2Zvcm0oTXV0YWJsZUNsYXNzRGVjbGFyYXRpb24gaXQsIGV4dGVuc2lvbiBUcmFuc2Zvcm1hdGlvbkNvbnRleHQgY29udGV4dCkgewoJCWV4dGVuc2lvbiB2YWwgdXRpbCA9IG5ldyBEYXRhUHJvY2Vzc29yLlV0aWwoY29udGV4dCkKCQlleHRlbnNpb24gdmFsIGdldHRlclV0aWwgPSBuZXcgQWNjZXNzb3JzUHJvY2Vzc29yLlV0aWwoY29udGV4dCkKCQlleHRlbnNpb24gdmFsIGVoVXRpbCA9IG5ldyBFcXVhbHNIYXNoQ29kZVByb2Nlc3Nvci5VdGlsKGNvbnRleHQpCgkJZXh0ZW5zaW9uIHZhbCB0b1N0cmluZ1V0aWwgPSBuZXcgVG9TdHJpbmdQcm9jZXNzb3IuVXRpbChjb250ZXh0KQoJCWV4dGVuc2lvbiB2YWwgcmVxdWlyZWRBcmdzVXRpbCA9IG5ldyBGaW5hbEZpZWxkc0NvbnN0cnVjdG9yUHJvY2Vzc29yLlV0aWwoY29udGV4dCkKCgkJZGF0YUZpZWxkcy5mb3JFYWNoIFsKCQkJZmluYWwgPSB0cnVlCgkJXQoJCWlmIChuZWVkc0ZpbmFsRmllbGRDb25zdHJ1Y3RvcikgewoJCQlhZGRGaW5hbEZpZWxkc0NvbnN0cnVjdG9yCgkJfQoJCWlmICghaGFzSGFzaENvZGUpIHsKCQkJYWRkSGFzaENvZGUoZGF0YUZpZWxkcywgaGFzU3VwZXJIYXNoQ29kZSkKCQl9CgkJaWYgKCFoYXNFcXVhbHMpIHsKCQkJYWRkRXF1YWxzKGRhdGFGaWVsZHMsIGhhc1N1cGVyRXF1YWxzKQoJCX0KCQlpZiAoIWhhc1RvU3RyaW5nKSB7CgkJCWFkZERhdGFUb1N0cmluZwoJCX0KCQlkYXRhRmllbGRzLmZvckVhY2ggWwoJCQlpZiAoc2hvdWxkQWRkR2V0dGVyKSB7CgkJCQlhZGRHZXR0ZXIoVmlzaWJpbGl0eS5QVUJMSUMpCgkJCX0KCQkJc2ltcGxlTmFtZSA9ICJfIiArIHNpbXBsZU5hbWUudG9GaXJzdExvd2VyCgkJXQoJfQoKCS8qKgoJICogQHNpbmNlIDIuNwoJICogQG5vZXh0ZW5kCgkgKiBAbm9yZWZlcmVuY2UKIAkgKi8KCUBEZXByZWNhdGVkCglzdGF0aWMgY2xhc3MgVXRpbCB7CgoJCWV4dGVuc2lvbiBUcmFuc2Zvcm1hdGlvbkNvbnRleHQgY29udGV4dAoKCQluZXcoVHJhbnNmb3JtYXRpb25Db250ZXh0IGNvbnRleHQpIHsKCQkJdGhpcy5jb250ZXh0ID0gY29udGV4dAoJCX0KCgkJZGVmIGdldERhdGFGaWVsZHMoQ2xhc3NEZWNsYXJhdGlvbiBpdCkgewoJCQlkZWNsYXJlZEZpZWxkcy5maWx0ZXJbIXN0YXRpYyAmJiBpc1RoZVByaW1hcnlHZW5lcmF0ZWRKYXZhRWxlbWVudF0KCQl9CgoJCWRlZiBnZXREYXRhRmllbGRzKE11dGFibGVDbGFzc0RlY2xhcmF0aW9uIGl0KSB7CgkJCWRlY2xhcmVkRmllbGRzLmZpbHRlclshc3RhdGljICYmIGlzVGhlUHJpbWFyeUdlbmVyYXRlZEphdmFFbGVtZW50XQoJCX0KCQkKCQlkZWYgdm9pZCBhZGREYXRhVG9TdHJpbmcoTXV0YWJsZUNsYXNzRGVjbGFyYXRpb24gY2xzKSB7CgkJCWNscy5hZGRNZXRob2QoInRvU3RyaW5nIikgWwoJCQkJcHJpbWFyeVNvdXJjZUVsZW1lbnQgPSBjbHMucHJpbWFyeVNvdXJjZUVsZW1lbnQKCQkJCXJldHVyblR5cGUgPSBzdHJpbmcKCQkJCWFkZEFubm90YXRpb24obmV3QW5ub3RhdGlvblJlZmVyZW5jZShPdmVycmlkZSkpCgkJCQlhZGRBbm5vdGF0aW9uKG5ld0Fubm90YXRpb25SZWZlcmVuY2UoUHVyZSkpCgkJCQlib2R5ID0gJycnCgkJCQkJU3RyaW5nIHJlc3VsdCA9IG5ldyCrb3JnLmVjbGlwc2UueHRleHQueGJhc2UubGliLnV0aWwuVG9TdHJpbmdIZWxwZXK7KCkudG9TdHJpbmcodGhpcyk7CgkJCQkJcmV0dXJuIHJlc3VsdDsKCQkJCScnJwoJCQldCgkJfQoJfQoKfQo=