cGFja2FnZSBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC51aS5pbnRlcm5hbDsKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzIElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiCgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKoCoKICogQ29udHJpYnV0b3JzOgogKiAgICBJQk0gLSBJbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuSVZNSW5zdGFsbDsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuSVZNSW5zdGFsbFR5cGU7CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQubGF1bmNoaW5nLkphdmFSdW50aW1lOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5EaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLklNZXNzYWdlUHJvdmlkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5wcmVmZXJlbmNlLklQcmVmZXJlbmNlTm9kZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnByZWZlcmVuY2UuUHJlZmVyZW5jZURpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnByZWZlcmVuY2UuUHJlZmVyZW5jZU1hbmFnZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS53aW5kb3cuV2luZG93OwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5JVG9tY2F0UnVudGltZVdvcmtpbmdDb3B5OwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuaW50ZXJuYWwuY29yZS5Ub21jYXRSdW50aW1lV29ya2luZ0NvcHk7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmN1c3RvbS5CdXN5SW5kaWNhdG9yOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Nb2RpZnlFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuTW9kaWZ5TGlzdGVuZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkFkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25MaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZERhdGE7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWRMYXlvdXQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5CdXR0b247CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21ibzsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkRpcmVjdG9yeURpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGV4dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLlBsYXRmb3JtVUk7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5oZWxwLldvcmtiZW5jaEhlbHA7CgppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklSdW50aW1lV29ya2luZ0NvcHk7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLndpemFyZC5JV2l6YXJkSGFuZGxlOwovKioKICogV2l6YXJkIHBhZ2UgdG8gc2V0IHRoZSBzZXJ2ZXIgaW5zdGFsbCBkaXJlY3RvcnkuCiAqLwpwdWJsaWMgY2xhc3MgVG9tY2F0UnVudGltZUNvbXBvc2l0ZSBleHRlbmRzIENvbXBvc2l0ZSB7Cglwcm90ZWN0ZWQgSVJ1bnRpbWVXb3JraW5nQ29weSBydW50aW1lV0M7Cglwcm90ZWN0ZWQgSVRvbWNhdFJ1bnRpbWVXb3JraW5nQ29weSBydW50aW1lOwoJCglwcm90ZWN0ZWQgSVdpemFyZEhhbmRsZSB3aXphcmQ7CgkKCXByb3RlY3RlZCBUZXh0IGluc3RhbGxEaXI7Cglwcm90ZWN0ZWQgVGV4dCBuYW1lOwoJcHJvdGVjdGVkIENvbWJvIGNvbWJvOwoJcHJvdGVjdGVkIExpc3QgaW5zdGFsbGVkSlJFczsKCXByb3RlY3RlZCBTdHJpbmdbXSBqcmVOYW1lczsKCXByb3RlY3RlZCBpbnQgZGVmYXVsdFZNSW5kZXg7CgoJLyoqCgkgKiBUb21jYXRSdW50aW1lV2l6YXJkUGFnZSBjb25zdHJ1Y3RvciBjb21tZW50LgoJICogQHBhcmFtIHJ1bnRpbWUKCSAqLwoJcHJvdGVjdGVkIFRvbWNhdFJ1bnRpbWVDb21wb3NpdGUoQ29tcG9zaXRlIHBhcmVudCwgSVdpemFyZEhhbmRsZSB3aXphcmQpIHsKCQlzdXBlcihwYXJlbnQsIFNXVC5OT05FKTsKCQl0aGlzLndpemFyZCA9IHdpemFyZDsKCQkKCQl3aXphcmQuc2V0VGl0bGUoVG9tY2F0VUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXphcmRUaXRsZSIpKTsKCQl3aXphcmQuc2V0RGVzY3JpcHRpb24oVG9tY2F0VUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXphcmREZXNjcmlwdGlvbiIpKTsKCQl3aXphcmQuc2V0SW1hZ2VEZXNjcmlwdG9yKFRvbWNhdFVJUGx1Z2luLmdldEltYWdlRGVzY3JpcHRvcihUb21jYXRVSVBsdWdpbi5JTUdfV0laX1RPTUNBVCkpOwoJCQoJCWNyZWF0ZUNvbnRyb2woKTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgc2V0UnVudGltZShJUnVudGltZVdvcmtpbmdDb3B5IG5ld1J1bnRpbWUpIHsKCQlpZiAobmV3UnVudGltZSA9PSBudWxsKSB7CgkJCXJ1bnRpbWVXQyA9IG51bGw7CgkJCXJ1bnRpbWUgPSBudWxsOwoJCX0gZWxzZSB7CgkJCXJ1bnRpbWVXQyA9IG5ld1J1bnRpbWU7CgkJCXJ1bnRpbWUgPSAoVG9tY2F0UnVudGltZVdvcmtpbmdDb3B5KSBuZXdSdW50aW1lLmdldFdvcmtpbmdDb3B5RGVsZWdhdGUoKTsKCQl9CgkJCgkJaW5pdCgpOwoJCXZhbGlkYXRlKCk7Cgl9CgoJLyoqCgkgKiBQcm92aWRlIGEgd2l6YXJkIHBhZ2UgdG8gY2hhbmdlIHRoZSBUb21jYXQgaW5zdGFsbGF0aW9uIGRpcmVjdG9yeS4KCSAqCgkgKiBAcGFyYW0gcGFyZW50IHRoZSBwYXJlbnQgY29tcG9zaXRlCgkgKiBAcmV0dXJuIHRoZSBuZXcgY29udHJvbAoJICovCglwcm90ZWN0ZWQgdm9pZCBjcmVhdGVDb250cm9sKCkgewoJCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQubnVtQ29sdW1ucyA9IDI7CgkJc2V0TGF5b3V0KGxheW91dCk7CgkJc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9CT1RIKSk7CgkJV29ya2JlbmNoSGVscC5zZXRIZWxwKHRoaXMsIENvbnRleHRJZHMuUlVOVElNRSk7CgkJCgkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwodGhpcywgU1dULk5PTkUpOwoJCWxhYmVsLnNldFRleHQoVG9tY2F0VUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVydW50aW1lTmFtZSIpKTsKCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKCk7CgkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJbGFiZWwuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQluYW1lID0gbmV3IFRleHQodGhpcywgU1dULkJPUkRFUik7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCW5hbWUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQluYW1lLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBlKSB7CgkJCQlydW50aW1lV0Muc2V0TmFtZShuYW1lLmdldFRleHQoKSk7CgkJCQl2YWxpZGF0ZSgpOwoJCQl9CgkJfSk7CgkKCQlsYWJlbCA9IG5ldyBMYWJlbCh0aGlzLCBTV1QuTk9ORSk7CgkJbGFiZWwuc2V0VGV4dChUb21jYXRVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWluc3RhbGxEaXIiKSk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YSgpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCWxhYmVsLnNldExheW91dERhdGEoZGF0YSk7CgkKCQlpbnN0YWxsRGlyID0gbmV3IFRleHQodGhpcywgU1dULkJPUkRFUik7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWluc3RhbGxEaXIuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlpbnN0YWxsRGlyLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBlKSB7CgkJCQlydW50aW1lV0Muc2V0TG9jYXRpb24obmV3IFBhdGgoaW5zdGFsbERpci5nZXRUZXh0KCkpKTsKCQkJCXZhbGlkYXRlKCk7CgkJCX0KCQl9KTsKCQoJCUJ1dHRvbiBicm93c2UgPSBTV1RVdGlsLmNyZWF0ZUJ1dHRvbih0aGlzLCBUb21jYXRVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWJyb3dzZSIpKTsKCQlicm93c2UuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IHNlKSB7CgkJCQlEaXJlY3RvcnlEaWFsb2cgZGlhbG9nID0gbmV3IERpcmVjdG9yeURpYWxvZyhUb21jYXRSdW50aW1lQ29tcG9zaXRlLnRoaXMuZ2V0U2hlbGwoKSk7CgkJCQlkaWFsb2cuc2V0TWVzc2FnZShUb21jYXRVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXNlbGVjdEluc3RhbGxEaXIiKSk7CgkJCQlkaWFsb2cuc2V0RmlsdGVyUGF0aChpbnN0YWxsRGlyLmdldFRleHQoKSk7CgkJCQlTdHJpbmcgc2VsZWN0ZWREaXJlY3RvcnkgPSBkaWFsb2cub3BlbigpOwoJCQkJaWYgKHNlbGVjdGVkRGlyZWN0b3J5ICE9IG51bGwpCgkJCQkJaW5zdGFsbERpci5zZXRUZXh0KHNlbGVjdGVkRGlyZWN0b3J5KTsKCQkJfQoJCX0pOwoJCQoJCXVwZGF0ZUpSRXMoKTsKCQkKCQkvLyBKREsgbG9jYXRpb24KCQlsYWJlbCA9IG5ldyBMYWJlbCh0aGlzLCBTV1QuTk9ORSk7CgkJbGFiZWwuc2V0VGV4dChUb21jYXRVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWluc3RhbGxlZEpSRSIpKTsKCQlkYXRhID0gbmV3IEdyaWREYXRhKCk7CgkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJbGFiZWwuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQljb21ibyA9IG5ldyBDb21ibyh0aGlzLCBTV1QuRFJPUF9ET1dOIHwgU1dULlJFQURfT05MWSk7CgkJY29tYm8uc2V0SXRlbXMoanJlTmFtZXMpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMKTsKCQljb21iby5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQoJCWNvbWJvLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25MaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJaW50IHNlbCA9IGNvbWJvLmdldFNlbGVjdGlvbkluZGV4KCk7CgkJCQlJVk1JbnN0YWxsIHZtSW5zdGFsbCA9IChJVk1JbnN0YWxsKSBpbnN0YWxsZWRKUkVzLmdldChzZWwpOwoJCQkJcnVudGltZS5zZXRWTUluc3RhbGwodm1JbnN0YWxsLmdldFZNSW5zdGFsbFR5cGUoKS5nZXRJZCgpLCB2bUluc3RhbGwuZ2V0SWQoKSk7CgkJCQl2YWxpZGF0ZSgpOwoJCQl9CgoJCQlwdWJsaWMgdm9pZCB3aWRnZXREZWZhdWx0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJd2lkZ2V0U2VsZWN0ZWQoZSk7CgkJCX0KCQl9KTsKCQkKCQlCdXR0b24gYnV0dG9uID0gU1dUVXRpbC5jcmVhdGVCdXR0b24odGhpcywgVG9tY2F0VUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVpbnN0YWxsZWRKUkVzIikpOwoJCWJ1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJU3RyaW5nIGN1cnJlbnRWTSA9IGNvbWJvLmdldFRleHQoKTsKCQkJCWlmIChzaG93UHJlZmVyZW5jZVBhZ2UoKSkgewoJCQkJCXVwZGF0ZUpSRXMoKTsKCQkJCQljb21iby5zZXRJdGVtcyhqcmVOYW1lcyk7CgkJCQkJY29tYm8uc2V0VGV4dChjdXJyZW50Vk0pOwoJCQkJCWlmIChjb21iby5nZXRTZWxlY3Rpb25JbmRleCgpID09IC0xKQoJCQkJCQljb21iby5zZWxlY3QoZGVmYXVsdFZNSW5kZXgpOwoJCQkJfQoJCQl9CgkJfSk7CgkJCgkJaW5pdCgpOwoJCXZhbGlkYXRlKCk7CgoJCURpYWxvZy5hcHBseURpYWxvZ0ZvbnQodGhpcyk7CgoJCW5hbWUuZm9yY2VGb2N1cygpOwoJfQoKCXByb3RlY3RlZCB2b2lkIHVwZGF0ZUpSRXMoKSB7CgkJLy8gZ2V0IGFsbCBpbnN0YWxsZWQgSlZNcwoJCWluc3RhbGxlZEpSRXMgPSBuZXcgQXJyYXlMaXN0KCk7CgkJSVZNSW5zdGFsbFR5cGVbXSB2bUluc3RhbGxUeXBlcyA9IEphdmFSdW50aW1lLmdldFZNSW5zdGFsbFR5cGVzKCk7CgkJaW50IHNpemUgPSB2bUluc3RhbGxUeXBlcy5sZW5ndGg7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJSVZNSW5zdGFsbFtdIHZtSW5zdGFsbHMgPSB2bUluc3RhbGxUeXBlc1tpXS5nZXRWTUluc3RhbGxzKCk7CgkJCWludCBzaXplMiA9IHZtSW5zdGFsbHMubGVuZ3RoOwoJCQlmb3IgKGludCBqID0gMDsgaiA8IHNpemUyOyBqKyspIHsKCQkJCWluc3RhbGxlZEpSRXMuYWRkKHZtSW5zdGFsbHNbal0pOwoJCQl9CgkJfQoJCQoJCS8vIGdldCBuYW1lcwoJCXNpemUgPSBpbnN0YWxsZWRKUkVzLnNpemUoKTsKCQlqcmVOYW1lcyA9IG5ldyBTdHJpbmdbc2l6ZV07CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJSVZNSW5zdGFsbCB2bUluc3RhbGwgPSAoSVZNSW5zdGFsbCkgaW5zdGFsbGVkSlJFcy5nZXQoaSk7CgkJCWpyZU5hbWVzW2ldID0gdm1JbnN0YWxsLmdldE5hbWUoKTsKCQl9CgkJCgkJSVZNSW5zdGFsbCBkZWZhdWx0Vk0gPSBKYXZhUnVudGltZS5nZXREZWZhdWx0Vk1JbnN0YWxsKCk7CgkJZGVmYXVsdFZNSW5kZXggPSBpbnN0YWxsZWRKUkVzLmluZGV4T2YoZGVmYXVsdFZNKTsKCX0KCglwcm90ZWN0ZWQgYm9vbGVhbiBzaG93UHJlZmVyZW5jZVBhZ2UoKSB7CgkJUHJlZmVyZW5jZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtVUkuZ2V0V29ya2JlbmNoKCkuZ2V0UHJlZmVyZW5jZU1hbmFnZXIoKTsKCQlJUHJlZmVyZW5jZU5vZGUgbm9kZSA9IG1hbmFnZXIuZmluZCgib3JnLmVjbGlwc2UuamR0LnVpLnByZWZlcmVuY2VzLkphdmFCYXNlUHJlZmVyZW5jZVBhZ2UiKS5maW5kU3ViTm9kZSgib3JnLmVjbGlwc2UuamR0LmRlYnVnLnVpLnByZWZlcmVuY2VzLlZNUHJlZmVyZW5jZVBhZ2UiKTsKCQlQcmVmZXJlbmNlTWFuYWdlciBtYW5hZ2VyMiA9IG5ldyBQcmVmZXJlbmNlTWFuYWdlcigpOwoJCW1hbmFnZXIyLmFkZFRvUm9vdChub2RlKTsKCQlmaW5hbCBQcmVmZXJlbmNlRGlhbG9nIGRpYWxvZyA9IG5ldyBQcmVmZXJlbmNlRGlhbG9nKGdldFNoZWxsKCksIG1hbmFnZXIyKTsKCQlmaW5hbCBib29sZWFuW10gcmVzdWx0ID0gbmV3IGJvb2xlYW5bXSB7IGZhbHNlIH07CgkJQnVzeUluZGljYXRvci5zaG93V2hpbGUoZ2V0RGlzcGxheSgpLCBuZXcgUnVubmFibGUoKSB7CgkJCXB1YmxpYyB2b2lkIHJ1bigpIHsKCQkJCWRpYWxvZy5jcmVhdGUoKTsKCQkJCWlmIChkaWFsb2cub3BlbigpID09IFdpbmRvdy5PSykKCQkJCQlyZXN1bHRbMF0gPSB0cnVlOwoJCQl9CgkJfSk7CgkJcmV0dXJuIHJlc3VsdFswXTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgaW5pdCgpIHsKCQlpZiAobmFtZSA9PSBudWxsIHx8IHJ1bnRpbWUgPT0gbnVsbCkKCQkJcmV0dXJuOwoJCQoJCWlmIChydW50aW1lV0MuZ2V0TmFtZSgpICE9IG51bGwpCgkJCW5hbWUuc2V0VGV4dChydW50aW1lV0MuZ2V0TmFtZSgpKTsKCQllbHNlCgkJCW5hbWUuc2V0VGV4dCgiIik7CgkKCQlpZiAocnVudGltZVdDLmdldExvY2F0aW9uKCkgIT0gbnVsbCkKCQkJaW5zdGFsbERpci5zZXRUZXh0KHJ1bnRpbWVXQy5nZXRMb2NhdGlvbigpLnRvT1NTdHJpbmcoKSk7CgkJZWxzZQoJCQlpbnN0YWxsRGlyLnNldFRleHQoIiIpOwoJCQoJCS8vIHNldCBzZWxlY3Rpb24KCQlib29sZWFuIGZvdW5kID0gZmFsc2U7CgkJaW50IHNpemUgPSBpbnN0YWxsZWRKUkVzLnNpemUoKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQlJVk1JbnN0YWxsIHZtSW5zdGFsbCA9IChJVk1JbnN0YWxsKSBpbnN0YWxsZWRKUkVzLmdldChpKTsKCQkJaWYgKHZtSW5zdGFsbC5nZXRWTUluc3RhbGxUeXBlKCkuZ2V0SWQoKS5lcXVhbHMocnVudGltZS5nZXRWTUluc3RhbGxUeXBlSWQoKSkKCQkJCQkmJiB2bUluc3RhbGwuZ2V0SWQoKS5lcXVhbHMocnVudGltZS5nZXRWTUluc3RhbGxJZCgpKSkgewoJCQkJY29tYm8uc2VsZWN0KGkpOwoJCQkJZm91bmQgPSB0cnVlOwoJCQl9CgkJfQoJCWlmICghZm91bmQpCgkJCWNvbWJvLnNlbGVjdChkZWZhdWx0Vk1JbmRleCk7Cgl9CgoJcHJvdGVjdGVkIHZvaWQgdmFsaWRhdGUoKSB7CgkJaWYgKHJ1bnRpbWUgPT0gbnVsbCkgewoJCQl3aXphcmQuc2V0TWVzc2FnZSgiIiwgSU1lc3NhZ2VQcm92aWRlci5FUlJPUik7CgkJCXJldHVybjsKCQl9CgoJCUlTdGF0dXMgc3RhdHVzID0gcnVudGltZS52YWxpZGF0ZSgpOwoJCWlmIChzdGF0dXMgPT0gbnVsbCB8fCBzdGF0dXMuaXNPSygpKQoJCQl3aXphcmQuc2V0TWVzc2FnZShudWxsLCBJTWVzc2FnZVByb3ZpZGVyLk5PTkUpOwoJCWVsc2UKCQkJd2l6YXJkLnNldE1lc3NhZ2Uoc3RhdHVzLmdldE1lc3NhZ2UoKSwgSU1lc3NhZ2VQcm92aWRlci5FUlJPUik7CgkJd2l6YXJkLnVwZGF0ZSgpOwoJfQp9