cGFja2FnZSBvcmcuZWNsaXBzZS51aS5leHRlcm5hbHRvb2xzLmludGVybmFsLnVpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSAyMDAyIElCTSBDb3JwLiBhbmQgb3RoZXJzLgpBbGwgcmlnaHRzIHJlc2VydmVkLiCgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYwLjUKd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjA1Lmh0bWwKoApDb250cmlidXRvcnM6CioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLndpbmRvdy5XaW5kb3c7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmV4dGVybmFsdG9vbHMuaW50ZXJuYWwuY29yZS4qOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuaGVscC5Xb3JrYmVuY2hIZWxwOwoKLyoqCiAqIERpYWxvZyBib3ggdG8gYWRkLCByZW1vdmUsIGFuZCBlZGl0IGV4dGVybmFsIHRvb2xzLgogKi8KcHVibGljIGNsYXNzIENvbmZpZ3VyYXRpb25EaWFsb2cgZXh0ZW5kcyBUaXRsZUFyZWFEaWFsb2cgewoJcHJpdmF0ZSBMaXN0Vmlld2VyIGxpc3RWaWV3ZXI7Cglwcml2YXRlIEJ1dHRvbiBuZXdCdXR0b247Cglwcml2YXRlIEJ1dHRvbiBlZGl0QnV0dG9uOwoJcHJpdmF0ZSBCdXR0b24gcmVtb3ZlQnV0dG9uOwoJcHJpdmF0ZSBCdXR0b24gdXBCdXR0b247Cglwcml2YXRlIEJ1dHRvbiBkb3duQnV0dG9uOwoJcHJpdmF0ZSBUZXh0IGRldGFpbFRleHQ7Cglwcml2YXRlIEV4dGVybmFsVG9vbCBjdXJyZW50U2VsZWN0aW9uOwoJcHJpdmF0ZSBBcnJheUxpc3QgdG9vbHM7CgoJLyoqCgkgKiBJbnN0YW50aWF0ZSBhIG5ldyBleHRlcm5hbCB0b29sIGNvbmZpZ3VyYXRpb24gZGlhbG9nLgoJICoKCSAqIEBwYXJhbSBwYXJlbnRTaGVsbCB0aGUgcGFyZW50IFNXVCBzaGVsbAoJICovCglwdWJsaWMgQ29uZmlndXJhdGlvbkRpYWxvZyhTaGVsbCBwYXJlbnRTaGVsbCkgewoJCXN1cGVyKHBhcmVudFNoZWxsKTsKCX0KCgkvKiAobm9uLUphdmFkb2MpCgkgKiBNZXRob2QgZGVjbGFyZWQgaW4gV2luZG93LgoJICovCglwcm90ZWN0ZWQgdm9pZCBjb25maWd1cmVTaGVsbChTaGVsbCBzaGVsbCkgewoJCXN1cGVyLmNvbmZpZ3VyZVNoZWxsKHNoZWxsKTsKCQlzaGVsbC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkNvbmZpZ3VyYXRpb25EaWFsb2cuc2hlbGxUaXRsZSIpKTsgLy8kTk9OLU5MUy0xJAoJCVdvcmtiZW5jaEhlbHAuc2V0SGVscCgKCQkJc2hlbGwsCgkJCUlIZWxwQ29udGV4dElkcy5DT05GSUdVUkVfRElBTE9HKTsKCX0KCgkvKiAobm9uLUphdmFkb2MpCgkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJICovCglwcm90ZWN0ZWQgdm9pZCBjcmVhdGVCdXR0b25zRm9yQnV0dG9uQmFyKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQljcmVhdGVCdXR0b24ocGFyZW50LCBJRGlhbG9nQ29uc3RhbnRzLk9LX0lELCBJRGlhbG9nQ29uc3RhbnRzLk9LX0xBQkVMLCB0cnVlKTsKCQljcmVhdGVCdXR0b24ocGFyZW50LCBJRGlhbG9nQ29uc3RhbnRzLkNBTkNFTF9JRCwgSURpYWxvZ0NvbnN0YW50cy5DQU5DRUxfTEFCRUwsIGZhbHNlKTsKCX0KCgkvKiAobm9uLUphdmFkb2MpCgkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJICovCglwcm90ZWN0ZWQgQ29udHJvbCBjcmVhdGVEaWFsb2dBcmVhKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQl0b29scyA9IG5ldyBBcnJheUxpc3QoRXh0ZXJuYWxUb29sc1BsdWdpbi5nZXREZWZhdWx0KCkuZ2V0UmVnaXN0cnkoKS5nZXRFeHRlcm5hbFRvb2xzKCkpOwoJCQoJCUNvbXBvc2l0ZSBkaWFsb2dDb21wID0gKENvbXBvc2l0ZSlzdXBlci5jcmVhdGVEaWFsb2dBcmVhKHBhcmVudCk7CgkJCQkKCQkvLyBTZXQgdGl0bGUgYW5kIG1lc3NhZ2Ugbm93IHRoYXQgdGhlIGNvbnRyb2xzIGV4aXN0CgkJc2V0VGl0bGUoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiQ29uZmlndXJhdGlvbkRpYWxvZy5kaWFsb2dUaXRsZSIpKTsgLy8kTk9OLU5MUy0xJAoJCXNldE1lc3NhZ2UoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiQ29uZmlndXJhdGlvbkRpYWxvZy5kaWFsb2dNZXNzYWdlIikpOyAvLyROT04tTkxTLTEkCgkJCgkJLy8gQnVpbGQgdGhlIHRvcCBjb250YWluZXIKCQlDb21wb3NpdGUgdG9wQ29tcCA9IG5ldyBDb21wb3NpdGUoZGlhbG9nQ29tcCwgU1dULk5PTkUpOwoJCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQubWFyZ2luSGVpZ2h0ID0gNTsKCQlsYXlvdXQubWFyZ2luV2lkdGggPSA1OwoJCXRvcENvbXAuc2V0TGF5b3V0KGxheW91dCk7CgkJR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0JPVEgpOwoJCXRvcENvbXAuc2V0TGF5b3V0RGF0YShkYXRhKTsKCgkJLy8gQnVpbGQgbWlkZGxlIGNvbnRhaW5lciB3aXRoIDIgY29sdW1ucwoJCUNvbXBvc2l0ZSBtaWRDb21wID0gbmV3IENvbXBvc2l0ZSh0b3BDb21wLCBTV1QuTk9ORSk7CgkJbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQubnVtQ29sdW1ucyA9IDI7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDA7CgkJbGF5b3V0Lm1hcmdpbldpZHRoID0gMDsKCQltaWRDb21wLnNldExheW91dChsYXlvdXQpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9CT1RIKTsKCQltaWRDb21wLnNldExheW91dERhdGEoZGF0YSk7CgoJCS8vIEJ1aWxkIHRoZSB0b29scyBsaXN0CgkJQ29tcG9zaXRlIGxpc3RDb21wID0gbmV3IENvbXBvc2l0ZShtaWRDb21wLCBTV1QuTk9ORSk7CgkJbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQubWFyZ2luSGVpZ2h0ID0gMDsKCQlsYXlvdXQubWFyZ2luV2lkdGggPSAwOwoJCWxpc3RDb21wLnNldExheW91dChsYXlvdXQpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9CT1RIKTsKCQlsaXN0Q29tcC5zZXRMYXlvdXREYXRhKGRhdGEpOwoKCQlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChsaXN0Q29tcCwgU1dULkxFRlQpOwoJCWxhYmVsLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCkpOwoJCWxhYmVsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiQ29uZmlndXJhdGlvbkRpYWxvZy50b29sTGlzdCIpKTsgLy8kTk9OLU5MUy0xJAoJCQoJCWxpc3RWaWV3ZXIgPSBuZXcgTGlzdFZpZXdlcihsaXN0Q29tcCwgU1dULlNJTkdMRSB8IFNXVC5IX1NDUk9MTCB8IFNXVC5WX1NDUk9MTCB8IFNXVC5CT1JERVIpOwoJCWxpc3RWaWV3ZXIuZ2V0TGlzdCgpLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfQk9USCkpOwoJCWxpc3RWaWV3ZXIuc2V0Q29udGVudFByb3ZpZGVyKG5ldyBUb29sQ29udGVudFByb3ZpZGVyKCkpOwoJCWxpc3RWaWV3ZXIuc2V0TGFiZWxQcm92aWRlcihuZXcgVG9vbExhYmVsUHJvdmlkZXIoKSk7CgkJbGlzdFZpZXdlci5zZXRJbnB1dCh0b29scyk7CgkJbGlzdFZpZXdlci5hZGREb3VibGVDbGlja0xpc3RlbmVyKG5ldyBJRG91YmxlQ2xpY2tMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgZG91YmxlQ2xpY2soRG91YmxlQ2xpY2tFdmVudCBldmVudCkgewoJCQkJb3BlbkVkaXRUb29sRGlhbG9nKCk7CgkJCX0KCQl9KTsKCgkJLy8gQnVpbGQgdGhlIGJ1dHRvbiBsaXN0CgkJQ29tcG9zaXRlIGJ1dHRvbkNvbXAgPSBuZXcgQ29tcG9zaXRlKG1pZENvbXAsIFNXVC5OT05FKTsKCQlsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5tYXJnaW5IZWlnaHQgPSAwOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDA7CgkJYnV0dG9uQ29tcC5zZXRMYXlvdXQobGF5b3V0KTsKCQlkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfVkVSVElDQUwpOwoJCWJ1dHRvbkNvbXAuc2V0TGF5b3V0RGF0YShkYXRhKTsKCgkJbGFiZWwgPSBuZXcgTGFiZWwoYnV0dG9uQ29tcCwgU1dULkxFRlQpOyAvLyBzcGFjZXIKCQlsYWJlbC5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpKTsKCQluZXdCdXR0b24gPSBjcmVhdGVQdXNoQnV0dG9uKGJ1dHRvbkNvbXAsICJDb25maWd1cmF0aW9uRGlhbG9nLm5ld0J1dHRvbiIsIHRydWUpOyAvLyROT04tTkxTLTEkCgkJZWRpdEJ1dHRvbiA9IGNyZWF0ZVB1c2hCdXR0b24oYnV0dG9uQ29tcCwgIkNvbmZpZ3VyYXRpb25EaWFsb2cuZWRpdEJ1dHRvbiIsIGZhbHNlKTsgLy8kTk9OLU5MUy0xJAoJCXJlbW92ZUJ1dHRvbiA9IGNyZWF0ZVB1c2hCdXR0b24oYnV0dG9uQ29tcCwgIkNvbmZpZ3VyYXRpb25EaWFsb2cucmVtb3ZlQnV0dG9uIiwgZmFsc2UpOyAvLyROT04tTkxTLTEkCgkJbGFiZWwgPSBuZXcgTGFiZWwoYnV0dG9uQ29tcCwgU1dULkxFRlQpOyAvLyBzcGFjZXIKCQlsYWJlbC5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpKTsKCQl1cEJ1dHRvbiA9IGNyZWF0ZVB1c2hCdXR0b24oYnV0dG9uQ29tcCwgIkNvbmZpZ3VyYXRpb25EaWFsb2cudXBCdXR0b24iLCBmYWxzZSk7IC8vJE5PTi1OTFMtMSQKCQlkb3duQnV0dG9uID0gY3JlYXRlUHVzaEJ1dHRvbihidXR0b25Db21wLCAiQ29uZmlndXJhdGlvbkRpYWxvZy5kb3duQnV0dG9uIiwgZmFsc2UpOyAvLyROT04tTkxTLTEkCgkJCgkJLy8gQnVpbGQgdGhlIGRldGFpbHMgZmllbGQKCQlsYWJlbCA9IG5ldyBMYWJlbCh0b3BDb21wLCBTV1QuTEVGVCk7CgkJbGFiZWwuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJDb25maWd1cmF0aW9uRGlhbG9nLmRldGFpbHMiKSk7IC8vJE5PTi1OTFMtMSQKCQlsYWJlbC5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpKTsKCgkJZGV0YWlsVGV4dCA9IG5ldyBUZXh0KHRvcENvbXAsIFNXVC5XUkFQIHwgU1dULk1VTFRJIHwgU1dULlZfU0NST0xMIHwgU1dULkJPUkRFUik7CgkJZGV0YWlsVGV4dC5zZXRFZGl0YWJsZShmYWxzZSk7CgkJZGV0YWlsVGV4dC5zZXRUZXh0KCJcblxuXG5cblxuIik7IC8vJE5PTi1OTFMtMSQKCQlkZXRhaWxUZXh0LnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCkpOwoJCQoJCS8vIEJ1aWxkIHRoZSBzZXBhcmF0b3IgbGluZQoJCUxhYmVsIHNlcGFyYXRvciA9IG5ldyBMYWJlbCh0b3BDb21wLCBTV1QuSE9SSVpPTlRBTCB8IFNXVC5TRVBBUkFUT1IpOwoJCXNlcGFyYXRvci5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpKTsKCQkKCQkvLyBGaW5pc2ggc2V0dXAKCQlob29rQnV0dG9uQWN0aW9ucygpOwoJCWhvb2tTdGF0ZVVwZGF0ZXMoKTsKCQkKCQlyZXR1cm4gZGlhbG9nQ29tcDsKCX0KCQoJcHJpdmF0ZSBCdXR0b24gY3JlYXRlUHVzaEJ1dHRvbihDb21wb3NpdGUgcGFyZW50LCBTdHJpbmcgbGFiZWxLZXksIGJvb2xlYW4gZW5hYmxlZCkgewoJCUJ1dHRvbiBidXR0b24gPSBuZXcgQnV0dG9uKHBhcmVudCwgU1dULlBVU0gpOwoJCWJ1dHRvbi5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcobGFiZWxLZXkpKTsKCQlidXR0b24uc2V0RW5hYmxlZChlbmFibGVkKTsKCQkKCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTCk7CgkJZGF0YS5oZWlnaHRIaW50ID0gY29udmVydFZlcnRpY2FsRExVc1RvUGl4ZWxzKElEaWFsb2dDb25zdGFudHMuQlVUVE9OX0hFSUdIVCk7CgkJaW50IHdpZHRoSGludCA9IGNvbnZlcnRIb3Jpem9udGFsRExVc1RvUGl4ZWxzKElEaWFsb2dDb25zdGFudHMuQlVUVE9OX1dJRFRIKTsKCQlkYXRhLndpZHRoSGludCA9IE1hdGgubWF4KHdpZHRoSGludCwgYnV0dG9uLmNvbXB1dGVTaXplKFNXVC5ERUZBVUxULCBTV1QuREVGQVVMVCwgdHJ1ZSkueCk7CgkJYnV0dG9uLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJcmV0dXJuIGJ1dHRvbjsKCX0KCQoJLyoqCgkgKiBBZGRzIHRoZSBsaXN0ZW5lcnMgcmVxdWlyZWQgdG8gaGFuZGxlIHRoZSBidXR0b24KCSAqIGFjdGlvbnMKCSAqLwoJcHJpdmF0ZSB2b2lkIGhvb2tCdXR0b25BY3Rpb25zKCkgewoJCW5ld0J1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJRWRpdERpYWxvZyBkaWFsb2c7CgkJCQlkaWFsb2cgPSBuZXcgRWRpdERpYWxvZyhnZXRTaGVsbCgpLCBudWxsKTsKCQkJCWlmIChkaWFsb2cub3BlbigpID09IFdpbmRvdy5PSykgewoJCQkJCUV4dGVybmFsVG9vbCB0b29sID0gZGlhbG9nLmdldEV4dGVybmFsVG9vbCgpOwoJCQkJCXRvb2xzLmFkZCh0b29sKTsKCQkJCQlsaXN0Vmlld2VyLmFkZCh0b29sKTsKCQkJCQlsaXN0Vmlld2VyLnNldFNlbGVjdGlvbihuZXcgU3RydWN0dXJlZFNlbGVjdGlvbih0b29sKSwgdHJ1ZSk7CgkJCQl9CgkJCX0KCQl9KTsKCgkJZWRpdEJ1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJb3BlbkVkaXRUb29sRGlhbG9nKCk7CgkJCX0KCQl9KTsKCgkJcmVtb3ZlQnV0dG9uLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQl0b29scy5yZW1vdmUoY3VycmVudFNlbGVjdGlvbik7CgkJCQlsaXN0Vmlld2VyLnJlbW92ZShjdXJyZW50U2VsZWN0aW9uKTsKCQkJfQoJCX0pOwoKCQl1cEJ1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJaW50IGluZGV4ID0gdG9vbHMuaW5kZXhPZihjdXJyZW50U2VsZWN0aW9uKTsKCQkJCWlmIChpbmRleCA8IDEpCgkJCQkJcmV0dXJuOwoJCQkJT2JqZWN0IHRvb2wgPSB0b29scy5nZXQoaW5kZXggLSAxKTsKCQkJCXRvb2xzLnNldChpbmRleCAtIDEsIGN1cnJlbnRTZWxlY3Rpb24pOwoJCQkJdG9vbHMuc2V0KGluZGV4LCB0b29sKTsKCQkJCWxpc3RWaWV3ZXIucmVmcmVzaChmYWxzZSk7CgkJCQl1cGRhdGVVcERvd25CdXR0b25zKCk7CgkJCX0KCQl9KTsKCgkJZG93bkJ1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJaW50IGluZGV4ID0gdG9vbHMuaW5kZXhPZihjdXJyZW50U2VsZWN0aW9uKTsKCQkJCWlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdG9vbHMuc2l6ZSgpIC0gMSkKCQkJCQlyZXR1cm47CgkJCQlPYmplY3QgdG9vbCA9IHRvb2xzLmdldChpbmRleCArIDEpOwoJCQkJdG9vbHMuc2V0KGluZGV4ICsgMSwgY3VycmVudFNlbGVjdGlvbik7CgkJCQl0b29scy5zZXQoaW5kZXgsIHRvb2wpOwoJCQkJbGlzdFZpZXdlci5yZWZyZXNoKGZhbHNlKTsKCQkJCXVwZGF0ZVVwRG93bkJ1dHRvbnMoKTsKCQkJfQoJCX0pOwoJfQoKCS8qKgoJICogQWRkcyBhIGxpc3RlbmVyIHRvIGNvbnRyb2wgYnV0dG9uIGVuYWJsZW1lbnQgYmFzZWQgb24KCSAqIHRoZSBjdXJyZW50IHNlbGVjdGlvbi4KCSAqLwoJcHJpdmF0ZSB2b2lkIGhvb2tTdGF0ZVVwZGF0ZXMoKSB7CgkJbGlzdFZpZXdlci5hZGRTZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXIobmV3IElTZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHNlbGVjdGlvbkNoYW5nZWQoU2VsZWN0aW9uQ2hhbmdlZEV2ZW50IGV2ZW50KSB7CgkJCQljdXJyZW50U2VsZWN0aW9uID0gbnVsbDsKCQkJCWlmIChldmVudC5nZXRTZWxlY3Rpb24oKSBpbnN0YW5jZW9mIElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSB7CgkJCQkJSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsID0gKElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSBldmVudC5nZXRTZWxlY3Rpb24oKSA7CgkJCQkJY3VycmVudFNlbGVjdGlvbiA9IChFeHRlcm5hbFRvb2wpc2VsLmdldEZpcnN0RWxlbWVudCgpOwoJCQkJfQoKCQkJCWVkaXRCdXR0b24uc2V0RW5hYmxlZChjdXJyZW50U2VsZWN0aW9uICE9IG51bGwpOwoJCQkJcmVtb3ZlQnV0dG9uLnNldEVuYWJsZWQoY3VycmVudFNlbGVjdGlvbiAhPSBudWxsKTsKCQkJCXVwZGF0ZVVwRG93bkJ1dHRvbnMoKTsKCQkJCXVwZGF0ZURldGFpbHMoKTsKCQkJfQoJCX0pOwoJfQoKCS8qKgoJICogVXBkYXRlIHRoZSBlbmFibGUgc3RhdGUgb2YgdGhlIHVwL2Rvd24gYnV0dG9ucwoJICovCglwcml2YXRlIHZvaWQgdXBkYXRlVXBEb3duQnV0dG9ucygpIHsKCQlpbnQgc2VsSW5kZXggPSBsaXN0Vmlld2VyLmdldExpc3QoKS5nZXRTZWxlY3Rpb25JbmRleCgpOwoJCWludCBpdGVtQ291bnQgPSBsaXN0Vmlld2VyLmdldExpc3QoKS5nZXRJdGVtQ291bnQoKTsKCQl1cEJ1dHRvbi5zZXRFbmFibGVkKGN1cnJlbnRTZWxlY3Rpb24gIT0gbnVsbCAmJiBzZWxJbmRleCA+IDApOwoJCWRvd25CdXR0b24uc2V0RW5hYmxlZChjdXJyZW50U2VsZWN0aW9uICE9IG51bGwgJiYgc2VsSW5kZXggPCBpdGVtQ291bnQgLSAxKTsKCX0KCgkvKioKCSAqIE9wZW5zIHRoZSBlZGl0IGV4dGVybmFsIHRvb2wgZGlhbG9nIG9uCgkgKiB0aGUgY3VycmVudGx5IHNlbGVjdGVkIGV4dGVybmFsIHRvb2wuCgkgKi8KCXByaXZhdGUgdm9pZCBvcGVuRWRpdFRvb2xEaWFsb2coKSB7CgkJaWYgKGN1cnJlbnRTZWxlY3Rpb24gPT0gbnVsbCkKCQkJcmV0dXJuOwoJCUVkaXREaWFsb2cgZGlhbG9nOwoJCWRpYWxvZyA9IG5ldyBFZGl0RGlhbG9nKGdldFNoZWxsKCksIGN1cnJlbnRTZWxlY3Rpb24pOwoJCWRpYWxvZy5vcGVuKCk7CgkJbGlzdFZpZXdlci51cGRhdGUoY3VycmVudFNlbGVjdGlvbiwgbnVsbCk7CgkJdXBkYXRlRGV0YWlscygpOwoJfQoJCgkvKioKCSAqIFVwZGF0ZSB0aGUgZGV0YWlsIGZpZWxkCgkgKi8KCXByaXZhdGUgdm9pZCB1cGRhdGVEZXRhaWxzKCkgewoJCWlmIChjdXJyZW50U2VsZWN0aW9uID09IG51bGwpCgkJCWRldGFpbFRleHQuc2V0VGV4dCgiIik7IC8vJE5PTi1OTFMtMSQKCQllbHNlCgkJCWRldGFpbFRleHQuc2V0VGV4dChUb29sTWVzc2FnZXMuZm9ybWF0KCJDb25maWd1cmF0aW9uRGlhbG9nLmRldGFpbE1lc3NhZ2UiLCBuZXcgT2JqZWN0W10ge2N1cnJlbnRTZWxlY3Rpb24uZ2V0TG9jYXRpb24oKSwgY3VycmVudFNlbGVjdGlvbi5nZXRBcmd1bWVudHMoKSwgY3VycmVudFNlbGVjdGlvbi5nZXRXb3JraW5nRGlyZWN0b3J5KCl9KSk7IC8vJE5PTi1OTFMtMSQKCX0KCQoJLyogKG5vbi1KYXZhZG9jKQoJICogTWV0aG9kIGRlY2xhcmVkIG9uIERpYWxvZy4KCSAqLwoJcHJvdGVjdGVkIHZvaWQgb2tQcmVzc2VkKCkgewoJCUV4dGVybmFsVG9vbHNQbHVnaW4uZ2V0RGVmYXVsdCgpLmdldFJlZ2lzdHJ5KCkuc2V0RXh0ZXJuYWxUb29scyh0b29scyk7CgkJc3VwZXIub2tQcmVzc2VkKCk7Cgl9CgoJCgkvKioKCSAqIEludGVybmFsIGNvbnRlbnQgcHJvdmlkZXIgb2YgZXhpc3RpbmcgdG9vbCB0b29scwoJICovCglwcml2YXRlIGNsYXNzIFRvb2xDb250ZW50UHJvdmlkZXIgaW1wbGVtZW50cyBJU3RydWN0dXJlZENvbnRlbnRQcm92aWRlciB7CgkJcHVibGljIE9iamVjdFtdIGdldEVsZW1lbnRzKE9iamVjdCBpbnB1dEVsZW1lbnQpIHsKCQkJcmV0dXJuIHRvb2xzLnRvQXJyYXkoKTsKCQl9CgoJCXB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CgkJfQoKCQlwdWJsaWMgdm9pZCBpbnB1dENoYW5nZWQoVmlld2VyIHZpZXdlciwgT2JqZWN0IG9sZElucHV0LCBPYmplY3QgbmV3SW5wdXQpIHsKCQl9Cgl9CgkKCS8qKgoJICogSW50ZXJuYWwgbGFiZWwgcHJvdmlkZXIgb2YgZXhpc3RpbmcgdG9vbCB0b29scwoJICovCglwcml2YXRlIGNsYXNzIFRvb2xMYWJlbFByb3ZpZGVyIGV4dGVuZHMgTGFiZWxQcm92aWRlciB7CgkJcHVibGljIFN0cmluZyBnZXRUZXh0KE9iamVjdCBlbGVtZW50KSB7CgkJCWlmIChlbGVtZW50IGluc3RhbmNlb2YgRXh0ZXJuYWxUb29sKQoJCQkJcmV0dXJuICgoRXh0ZXJuYWxUb29sKWVsZW1lbnQpLmdldE5hbWUoKTsKCQkJZWxzZQoJCQkJcmV0dXJuICIiOy8vJE5PTi1OTFMtMSQKCQl9Cgl9Cn0K