LyoqDQogKiBDb3B5cmlnaHQgKGMpIDIwMTAsIDIwMTUgTWlhLVNvZnR3YXJlLg0KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscw0KICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wDQogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdA0KICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwNCiAqIA0KICogQ29udHJpYnV0b3JzOg0KICogICAgIEZyZWRlcmljIE1hZGlvdCAoTWlhLVNvZnR3YXJlKSAtIG1ldGFtb2RlbCBkZXNpZ24gYW5kIGluaXRpYWwgaW1wbGVtZW50YXRpb24NCiAqICAgICBHculnb2lyZSBEdXDpIChNaWEtU29mdHdhcmUpIC0gQnVnIDQ4MDE4MyAtIFRoZSBtYW5pZmVzdC5tZiBkaXNjb3ZlcmVyIHNob3VsZCBtYW5hZ2UgJ0V4cG9ydC1QYWNrYWdlJyANCiAqLw0KcGFja2FnZSBvcmcuZWNsaXBzZS5tb2Rpc2NvLm1hbmlmZXN0LmltcGw7DQoNCmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsNCg0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5jb21tb24ubm90aWZ5Lk5vdGlmaWNhdGlvbjsNCg0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5jb21tb24udXRpbC5FTGlzdDsNCg0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS5FQ2xhc3M7DQoNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWNvcmUuaW1wbC5FTm90aWZpY2F0aW9uSW1wbDsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWNvcmUuaW1wbC5FT2JqZWN0SW1wbDsNCg0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS51dGlsLkVPYmplY3RSZXNvbHZpbmdFTGlzdDsNCg0KaW1wb3J0IG9yZy5lY2xpcHNlLm1vZGlzY28ubWFuaWZlc3QuQnVuZGxlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLm1vZGlzY28ubWFuaWZlc3QuRXhwb3J0ZWRQYWNrYWdlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLm1vZGlzY28ubWFuaWZlc3QuTWFuaWZlc3RQYWNrYWdlOw0KDQovKioNCiAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQogKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgbW9kZWwgb2JqZWN0ICc8ZW0+PGI+RXhwb3J0ZWQgUGFja2FnZTwvYj48L2VtPicuDQogKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCiAqIDxwPg0KICogVGhlIGZvbGxvd2luZyBmZWF0dXJlcyBhcmUgaW1wbGVtZW50ZWQ6DQogKiA8L3A+DQogKiA8dWw+DQogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2UubW9kaXNjby5tYW5pZmVzdC5pbXBsLkV4cG9ydGVkUGFja2FnZUltcGwjZ2V0TmFtZSA8ZW0+TmFtZTwvZW0+fTwvbGk+DQogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2UubW9kaXNjby5tYW5pZmVzdC5pbXBsLkV4cG9ydGVkUGFja2FnZUltcGwjZ2V0WEZyaWVuZHMgPGVtPlhGcmllbmRzPC9lbT59PC9saT4NCiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5tb2Rpc2NvLm1hbmlmZXN0LmltcGwuRXhwb3J0ZWRQYWNrYWdlSW1wbCNpc1hJbnRlcm5hbCA8ZW0+WEludGVybmFsPC9lbT59PC9saT4NCiAqIDwvdWw+DQogKg0KICogQGdlbmVyYXRlZA0KICovDQpwdWJsaWMgY2xhc3MgRXhwb3J0ZWRQYWNrYWdlSW1wbCBleHRlbmRzIEVPYmplY3RJbXBsIGltcGxlbWVudHMgRXhwb3J0ZWRQYWNrYWdlIHsNCgkvKioNCgkgKiBUaGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGUgJ3tAbGluayAjZ2V0TmFtZSgpIDxlbT5OYW1lPC9lbT59JyBhdHRyaWJ1dGUuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAc2VlICNnZXROYW1lKCkNCgkgKiBAZ2VuZXJhdGVkDQoJICogQG9yZGVyZWQNCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FX0VERUZBVUxUID0gbnVsbDsNCg0KCS8qKg0KCSAqIFRoZSBjYWNoZWQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldE5hbWUoKSA8ZW0+TmFtZTwvZW0+fScgYXR0cmlidXRlLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQHNlZSAjZ2V0TmFtZSgpDQoJICogQGdlbmVyYXRlZA0KCSAqIEBvcmRlcmVkDQoJICovDQoJcHJvdGVjdGVkIFN0cmluZyBuYW1lID0gTkFNRV9FREVGQVVMVDsNCg0KCS8qKg0KCSAqIFRoZSBjYWNoZWQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldFhGcmllbmRzKCkgPGVtPlhGcmllbmRzPC9lbT59JyByZWZlcmVuY2UgbGlzdC4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBzZWUgI2dldFhGcmllbmRzKCkNCgkgKiBAZ2VuZXJhdGVkDQoJICogQG9yZGVyZWQNCgkgKi8NCglwcm90ZWN0ZWQgRUxpc3Q8QnVuZGxlPiB4RnJpZW5kczsNCg0KCS8qKg0KCSAqIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoZSAne0BsaW5rICNpc1hJbnRlcm5hbCgpIDxlbT5YSW50ZXJuYWw8L2VtPn0nIGF0dHJpYnV0ZS4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBzZWUgI2lzWEludGVybmFsKCkNCgkgKiBAZ2VuZXJhdGVkDQoJICogQG9yZGVyZWQNCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJvb2xlYW4gWElOVEVSTkFMX0VERUZBVUxUID0gZmFsc2U7DQoNCgkvKioNCgkgKiBUaGUgY2FjaGVkIHZhbHVlIG9mIHRoZSAne0BsaW5rICNpc1hJbnRlcm5hbCgpIDxlbT5YSW50ZXJuYWw8L2VtPn0nIGF0dHJpYnV0ZS4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBzZWUgI2lzWEludGVybmFsKCkNCgkgKiBAZ2VuZXJhdGVkDQoJICogQG9yZGVyZWQNCgkgKi8NCglwcm90ZWN0ZWQgYm9vbGVhbiB4SW50ZXJuYWwgPSBYSU5URVJOQUxfRURFRkFVTFQ7DQoNCgkvKioNCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgRXhwb3J0ZWRQYWNrYWdlSW1wbCgpIHsNCgkJc3VwZXIoKTsNCgl9DQoNCgkvKioNCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglAT3ZlcnJpZGUNCglwcm90ZWN0ZWQgRUNsYXNzIGVTdGF0aWNDbGFzcygpIHsNCgkJcmV0dXJuIE1hbmlmZXN0UGFja2FnZS5MaXRlcmFscy5FWFBPUlRFRF9QQUNLQUdFOw0KCX0NCg0KCS8qKg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsNCgkJcmV0dXJuIG5hbWU7DQoJfQ0KDQoJLyoqDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIHZvaWQgc2V0TmFtZShTdHJpbmcgbmV3TmFtZSkgew0KCQlTdHJpbmcgb2xkTmFtZSA9IG5hbWU7DQoJCW5hbWUgPSBuZXdOYW1lOw0KCQlpZiAoZU5vdGlmaWNhdGlvblJlcXVpcmVkKCkpDQoJCQllTm90aWZ5KG5ldyBFTm90aWZpY2F0aW9uSW1wbCh0aGlzLCBOb3RpZmljYXRpb24uU0VULCBNYW5pZmVzdFBhY2thZ2UuRVhQT1JURURfUEFDS0FHRV9fTkFNRSwgb2xkTmFtZSwgbmFtZSkpOw0KCX0NCg0KCS8qKg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyBFTGlzdDxCdW5kbGU+IGdldFhGcmllbmRzKCkgew0KCQlpZiAoeEZyaWVuZHMgPT0gbnVsbCkgew0KCQkJeEZyaWVuZHMgPSBuZXcgRU9iamVjdFJlc29sdmluZ0VMaXN0PEJ1bmRsZT4oQnVuZGxlLmNsYXNzLCB0aGlzLCBNYW5pZmVzdFBhY2thZ2UuRVhQT1JURURfUEFDS0FHRV9fWEZSSUVORFMpOw0KCQl9DQoJCXJldHVybiB4RnJpZW5kczsNCgl9DQoNCgkvKioNCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwdWJsaWMgYm9vbGVhbiBpc1hJbnRlcm5hbCgpIHsNCgkJcmV0dXJuIHhJbnRlcm5hbDsNCgl9DQoNCgkvKioNCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwdWJsaWMgdm9pZCBzZXRYSW50ZXJuYWwoYm9vbGVhbiBuZXdYSW50ZXJuYWwpIHsNCgkJYm9vbGVhbiBvbGRYSW50ZXJuYWwgPSB4SW50ZXJuYWw7DQoJCXhJbnRlcm5hbCA9IG5ld1hJbnRlcm5hbDsNCgkJaWYgKGVOb3RpZmljYXRpb25SZXF1aXJlZCgpKQ0KCQkJZU5vdGlmeShuZXcgRU5vdGlmaWNhdGlvbkltcGwodGhpcywgTm90aWZpY2F0aW9uLlNFVCwgTWFuaWZlc3RQYWNrYWdlLkVYUE9SVEVEX1BBQ0tBR0VfX1hJTlRFUk5BTCwgb2xkWEludGVybmFsLCB4SW50ZXJuYWwpKTsNCgl9DQoNCgkvKioNCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglAT3ZlcnJpZGUNCglwdWJsaWMgT2JqZWN0IGVHZXQoaW50IGZlYXR1cmVJRCwgYm9vbGVhbiByZXNvbHZlLCBib29sZWFuIGNvcmVUeXBlKSB7DQoJCXN3aXRjaCAoZmVhdHVyZUlEKSB7DQoJCQljYXNlIE1hbmlmZXN0UGFja2FnZS5FWFBPUlRFRF9QQUNLQUdFX19OQU1FOg0KCQkJCXJldHVybiBnZXROYW1lKCk7DQoJCQljYXNlIE1hbmlmZXN0UGFja2FnZS5FWFBPUlRFRF9QQUNLQUdFX19YRlJJRU5EUzoNCgkJCQlyZXR1cm4gZ2V0WEZyaWVuZHMoKTsNCgkJCWNhc2UgTWFuaWZlc3RQYWNrYWdlLkVYUE9SVEVEX1BBQ0tBR0VfX1hJTlRFUk5BTDoNCgkJCQlyZXR1cm4gaXNYSW50ZXJuYWwoKTsNCgkJfQ0KCQlyZXR1cm4gc3VwZXIuZUdldChmZWF0dXJlSUQsIHJlc29sdmUsIGNvcmVUeXBlKTsNCgl9DQoNCgkvKioNCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikNCglAT3ZlcnJpZGUNCglwdWJsaWMgdm9pZCBlU2V0KGludCBmZWF0dXJlSUQsIE9iamVjdCBuZXdWYWx1ZSkgew0KCQlzd2l0Y2ggKGZlYXR1cmVJRCkgew0KCQkJY2FzZSBNYW5pZmVzdFBhY2thZ2UuRVhQT1JURURfUEFDS0FHRV9fTkFNRToNCgkJCQlzZXROYW1lKChTdHJpbmcpbmV3VmFsdWUpOw0KCQkJCXJldHVybjsNCgkJCWNhc2UgTWFuaWZlc3RQYWNrYWdlLkVYUE9SVEVEX1BBQ0tBR0VfX1hGUklFTkRTOg0KCQkJCWdldFhGcmllbmRzKCkuY2xlYXIoKTsNCgkJCQlnZXRYRnJpZW5kcygpLmFkZEFsbCgoQ29sbGVjdGlvbjw/IGV4dGVuZHMgQnVuZGxlPiluZXdWYWx1ZSk7DQoJCQkJcmV0dXJuOw0KCQkJY2FzZSBNYW5pZmVzdFBhY2thZ2UuRVhQT1JURURfUEFDS0FHRV9fWElOVEVSTkFMOg0KCQkJCXNldFhJbnRlcm5hbCgoQm9vbGVhbiluZXdWYWx1ZSk7DQoJCQkJcmV0dXJuOw0KCQl9DQoJCXN1cGVyLmVTZXQoZmVhdHVyZUlELCBuZXdWYWx1ZSk7DQoJfQ0KDQoJLyoqDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJQE92ZXJyaWRlDQoJcHVibGljIHZvaWQgZVVuc2V0KGludCBmZWF0dXJlSUQpIHsNCgkJc3dpdGNoIChmZWF0dXJlSUQpIHsNCgkJCWNhc2UgTWFuaWZlc3RQYWNrYWdlLkVYUE9SVEVEX1BBQ0tBR0VfX05BTUU6DQoJCQkJc2V0TmFtZShOQU1FX0VERUZBVUxUKTsNCgkJCQlyZXR1cm47DQoJCQljYXNlIE1hbmlmZXN0UGFja2FnZS5FWFBPUlRFRF9QQUNLQUdFX19YRlJJRU5EUzoNCgkJCQlnZXRYRnJpZW5kcygpLmNsZWFyKCk7DQoJCQkJcmV0dXJuOw0KCQkJY2FzZSBNYW5pZmVzdFBhY2thZ2UuRVhQT1JURURfUEFDS0FHRV9fWElOVEVSTkFMOg0KCQkJCXNldFhJbnRlcm5hbChYSU5URVJOQUxfRURFRkFVTFQpOw0KCQkJCXJldHVybjsNCgkJfQ0KCQlzdXBlci5lVW5zZXQoZmVhdHVyZUlEKTsNCgl9DQoNCgkvKioNCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglAT3ZlcnJpZGUNCglwdWJsaWMgYm9vbGVhbiBlSXNTZXQoaW50IGZlYXR1cmVJRCkgew0KCQlzd2l0Y2ggKGZlYXR1cmVJRCkgew0KCQkJY2FzZSBNYW5pZmVzdFBhY2thZ2UuRVhQT1JURURfUEFDS0FHRV9fTkFNRToNCgkJCQlyZXR1cm4gTkFNRV9FREVGQVVMVCA9PSBudWxsID8gbmFtZSAhPSBudWxsIDogIU5BTUVfRURFRkFVTFQuZXF1YWxzKG5hbWUpOw0KCQkJY2FzZSBNYW5pZmVzdFBhY2thZ2UuRVhQT1JURURfUEFDS0FHRV9fWEZSSUVORFM6DQoJCQkJcmV0dXJuIHhGcmllbmRzICE9IG51bGwgJiYgIXhGcmllbmRzLmlzRW1wdHkoKTsNCgkJCWNhc2UgTWFuaWZlc3RQYWNrYWdlLkVYUE9SVEVEX1BBQ0tBR0VfX1hJTlRFUk5BTDoNCgkJCQlyZXR1cm4geEludGVybmFsICE9IFhJTlRFUk5BTF9FREVGQVVMVDsNCgkJfQ0KCQlyZXR1cm4gc3VwZXIuZUlzU2V0KGZlYXR1cmVJRCk7DQoJfQ0KDQoJLyoqDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJQE92ZXJyaWRlDQoJcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsNCgkJaWYgKGVJc1Byb3h5KCkpIHJldHVybiBzdXBlci50b1N0cmluZygpOw0KDQoJCVN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKHN1cGVyLnRvU3RyaW5nKCkpOw0KCQlyZXN1bHQuYXBwZW5kKCIgKG5hbWU6ICIpOw0KCQlyZXN1bHQuYXBwZW5kKG5hbWUpOw0KCQlyZXN1bHQuYXBwZW5kKCIsIHhJbnRlcm5hbDogIik7DQoJCXJlc3VsdC5hcHBlbmQoeEludGVybmFsKTsNCgkJcmVzdWx0LmFwcGVuZCgnKScpOw0KCQlyZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7DQoJfQ0KDQp9IC8vRXhwb3J0ZWRQYWNrYWdlSW1wbA0K