LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuZWRpdG9yOwoKaW1wb3J0IGphdmEuYmVhbnMuUHJvcGVydHlDaGFuZ2VFdmVudDsKaW1wb3J0IGphdmEuYmVhbnMuUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcjsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRm9sZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5OdWxsUHJvZ3Jlc3NNb25pdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uud2luZG93LldpbmRvdzsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkTGF5b3V0OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQnV0dG9uOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tYm87CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21wb3NpdGU7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Hcm91cDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuU3Bpbm5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlRleHQ7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5JRWRpdG9ySW5wdXQ7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5JRWRpdG9yU2l0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLlBsYXRmb3JtVUk7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5mb3Jtcy5Gb3JtQ29sb3JzOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuZm9ybXMuZXZlbnRzLkh5cGVybGlua0V2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2UudWkuZm9ybXMuZXZlbnRzLklIeXBlcmxpbmtMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmZvcm1zLndpZGdldHMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmhlbHAuSVdvcmtiZW5jaEhlbHBTeXN0ZW07CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TZXJ2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUudXRpbC5Tb2NrZXRVdGlsOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5lZGl0b3IuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuQ29udGV4dElkczsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuTWVzc2FnZXM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLlNlcnZlclVJUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC5jb21tYW5kLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLndpemFyZC5DbG9zYWJsZVdpemFyZERpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwud2l6YXJkLlRhc2tXaXphcmQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLndpemFyZC5XaXphcmRUYXNrVXRpbDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkud2l6YXJkLldpemFyZEZyYWdtZW50OwovKioKICogU2VydmVyIGdlbmVyYWwgZWRpdG9yIHBhZ2UuCiAqLwpwdWJsaWMgY2xhc3MgT3ZlcnZpZXdFZGl0b3JQYXJ0IGV4dGVuZHMgU2VydmVyRWRpdG9yUGFydCB7Cglwcm90ZWN0ZWQgVGV4dCBzZXJ2ZXJOYW1lOwoJcHJvdGVjdGVkIFRleHQgc2VydmVyQ29uZmlndXJhdGlvbk5hbWU7Cglwcm90ZWN0ZWQgVGV4dCBob3N0bmFtZTsKCXByb3RlY3RlZCBDb21ibyBydW50aW1lQ29tYm87Cglwcm90ZWN0ZWQgQnV0dG9uIGF1dG9QdWJsaXNoRGVmYXVsdDsKCXByb3RlY3RlZCBCdXR0b24gYXV0b1B1Ymxpc2hPdmVycmlkZTsKCXByb3RlY3RlZCBTcGlubmVyIGF1dG9QdWJsaXNoVGltZTsKCglwcm90ZWN0ZWQgYm9vbGVhbiB1cGRhdGluZzsKCglwcm90ZWN0ZWQgSVJ1bnRpbWVbXSBydW50aW1lczsKCglwcm90ZWN0ZWQgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lcjsKCgkvKioKCSAqIE92ZXJ2aWV3RWRpdG9yUGFydCBjb25zdHJ1Y3RvciBjb21tZW50LgoJICovCglwdWJsaWMgT3ZlcnZpZXdFZGl0b3JQYXJ0KCkgewoJCXN1cGVyKCk7Cgl9CgoJLyoqCgkgKiAKCSAqLwoJcHJvdGVjdGVkIHZvaWQgYWRkQ2hhbmdlTGlzdGVuZXIoKSB7CgkJbGlzdGVuZXIgPSBuZXcgUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgcHJvcGVydHlDaGFuZ2UoUHJvcGVydHlDaGFuZ2VFdmVudCBldmVudCkgewoJCQkJaWYgKHVwZGF0aW5nKQoJCQkJCXJldHVybjsKCQkJCXVwZGF0aW5nID0gdHJ1ZTsKCQkJCWlmIChldmVudC5nZXRQcm9wZXJ0eU5hbWUoKS5lcXVhbHMoIm5hbWUiKSkKCQkJCQl1cGRhdGVOYW1lcygpOwoJCQkJZWxzZSBpZiAoZXZlbnQuZ2V0UHJvcGVydHlOYW1lKCkuZXF1YWxzKCJob3N0bmFtZSIpICYmIGhvc3RuYW1lICE9IG51bGwpIHsKCQkJCQlob3N0bmFtZS5zZXRUZXh0KChTdHJpbmcpIGV2ZW50LmdldE5ld1ZhbHVlKCkpOwoJCQkJfSBlbHNlIGlmIChldmVudC5nZXRQcm9wZXJ0eU5hbWUoKS5lcXVhbHMoInJ1bnRpbWUtaWQiKSkgewoJCQkJCVN0cmluZyBydW50aW1lSWQgPSAoU3RyaW5nKSBldmVudC5nZXROZXdWYWx1ZSgpOwoJCQkJCUlSdW50aW1lIHJ1bnRpbWUgPSBudWxsOwoJCQkJCWlmIChydW50aW1lSWQgIT0gbnVsbCkKCQkJCQkJcnVudGltZSA9IFNlcnZlckNvcmUuZmluZFJ1bnRpbWUocnVudGltZUlkKTsKCQkJCQlpbnQgc2l6ZSA9IHJ1bnRpbWVzLmxlbmd0aDsKCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJCQlpZiAocnVudGltZXNbaV0uZXF1YWxzKHJ1bnRpbWUpKQoJCQkJCQkJcnVudGltZUNvbWJvLnNlbGVjdChpKTsKCQkJCQl9CgkJCQl9CgkJCQl1cGRhdGluZyA9IGZhbHNlOwoJCQl9CgkJfTsKCQlpZiAoc2VydmVyICE9IG51bGwpCgkJCXNlcnZlci5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKGxpc3RlbmVyKTsKCX0KCglwcm90ZWN0ZWQgdm9pZCB1cGRhdGVOYW1lcygpIHsKCQlpZiAoc2VydmVyTmFtZSAhPSBudWxsKQoJCQlzZXJ2ZXJOYW1lLnNldFRleHQoc2VydmVyLmdldE5hbWUoKSk7Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIHRoZSBTV1QgY29udHJvbHMgZm9yIHRoaXMgd29ya2JlbmNoIHBhcnQuCgkgKgoJICogQHBhcmFtIHBhcmVudCB0aGUgcGFyZW50IGNvbnRyb2wKCSAqLwoJcHVibGljIGZpbmFsIHZvaWQgY3JlYXRlUGFydENvbnRyb2woQ29tcG9zaXRlIHBhcmVudCkgewoJCUZvcm1Ub29sa2l0IHRvb2xraXQgPSBnZXRGb3JtVG9vbGtpdChwYXJlbnQuZ2V0RGlzcGxheSgpKTsKCQkKCQlTY3JvbGxlZEZvcm0gZm9ybSA9IHRvb2xraXQuY3JlYXRlU2Nyb2xsZWRGb3JtKHBhcmVudCk7CgkJZm9ybS5zZXRUZXh0KE1lc3NhZ2VzLnNlcnZlckVkaXRvck92ZXJ2aWV3UGFnZVRpdGxlKTsKCQlmb3JtLmdldEJvZHkoKS5zZXRMYXlvdXQobmV3IEdyaWRMYXlvdXQoKSk7CgkJCgkJQ29tcG9zaXRlIGNvbHVtbkNvbXAgPSB0b29sa2l0LmNyZWF0ZUNvbXBvc2l0ZShmb3JtLmdldEJvZHkoKSk7CgkJR3JpZExheW91dCBsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5udW1Db2x1bW5zID0gMjsKCQkvL2xheW91dC5tYXJnaW5IZWlnaHQgPSAxMDsKCQkvL2xheW91dC5tYXJnaW5XaWR0aCA9IDEwOwoJCWxheW91dC52ZXJ0aWNhbFNwYWNpbmcgPSAwOwoJCWxheW91dC5ob3Jpem9udGFsU3BhY2luZyA9IDEwOwoJCWNvbHVtbkNvbXAuc2V0TGF5b3V0KGxheW91dCk7CgkJY29sdW1uQ29tcC5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwgfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9GSUxMKSk7CgkJCgkJLy8gbGVmdCBjb2x1bW4KCQlDb21wb3NpdGUgbGVmdENvbHVtbkNvbXAgPSB0b29sa2l0LmNyZWF0ZUNvbXBvc2l0ZShjb2x1bW5Db21wKTsKCQlsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5tYXJnaW5IZWlnaHQgPSAwOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDA7CgkJbGF5b3V0LnZlcnRpY2FsU3BhY2luZyA9IDEwOwoJCWxheW91dC5ob3Jpem9udGFsU3BhY2luZyA9IDA7CgkJbGVmdENvbHVtbkNvbXAuc2V0TGF5b3V0KGxheW91dCk7CgkJbGVmdENvbHVtbkNvbXAuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMIHwgR3JpZERhdGEuVkVSVElDQUxfQUxJR05fRklMTCkpOwoJCQoJCVNlY3Rpb24gc2VjdGlvbiA9IHRvb2xraXQuY3JlYXRlU2VjdGlvbihsZWZ0Q29sdW1uQ29tcCwgRXhwYW5kYWJsZUNvbXBvc2l0ZS5UV0lTVElFfEV4cGFuZGFibGVDb21wb3NpdGUuRVhQQU5ERUQgfCBFeHBhbmRhYmxlQ29tcG9zaXRlLlRJVExFX0JBUiB8IFNlY3Rpb24uREVTQ1JJUFRJT04gfCBFeHBhbmRhYmxlQ29tcG9zaXRlLkZPQ1VTX1RJVExFKTsKCQlzZWN0aW9uLnNldFRleHQoTWVzc2FnZXMuc2VydmVyRWRpdG9yT3ZlcnZpZXdTZWN0aW9uKTsKCQlzZWN0aW9uLnNldERlc2NyaXB0aW9uKE1lc3NhZ2VzLnNlcnZlckVkaXRvck92ZXJ2aWV3RGVzY3JpcHRpb24pOwoJCXNlY3Rpb24uc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMIHwgR3JpZERhdGEuVkVSVElDQUxfQUxJR05fRklMTCkpOwoKCQlDb21wb3NpdGUgY29tcG9zaXRlID0gdG9vbGtpdC5jcmVhdGVDb21wb3NpdGUoc2VjdGlvbik7CgkJbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQubnVtQ29sdW1ucyA9IDI7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDU7CgkJbGF5b3V0Lm1hcmdpbldpZHRoID0gMTA7CgkJbGF5b3V0LnZlcnRpY2FsU3BhY2luZyA9IDU7CgkJbGF5b3V0Lmhvcml6b250YWxTcGFjaW5nID0gMTU7CgkJY29tcG9zaXRlLnNldExheW91dChsYXlvdXQpOwoJCWNvbXBvc2l0ZS5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwgfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9GSUxMKSk7CgkJSVdvcmtiZW5jaEhlbHBTeXN0ZW0gd2hzID0gUGxhdGZvcm1VSS5nZXRXb3JrYmVuY2goKS5nZXRIZWxwU3lzdGVtKCk7CgkJd2hzLnNldEhlbHAoY29tcG9zaXRlLCBDb250ZXh0SWRzLkVESVRPUl9PVkVSVklFV19QQUdFKTsKCQl0b29sa2l0LnBhaW50Qm9yZGVyc0Zvcihjb21wb3NpdGUpOwoJCXNlY3Rpb24uc2V0Q2xpZW50KGNvbXBvc2l0ZSk7CgoJCS8vIHNlcnZlciBuYW1lCgkJaWYgKHNlcnZlciAhPSBudWxsKSB7CgkJCWNyZWF0ZUxhYmVsKHRvb2xraXQsIGNvbXBvc2l0ZSwgTWVzc2FnZXMuc2VydmVyRWRpdG9yT3ZlcnZpZXdTZXJ2ZXJOYW1lKTsKCQkJCgkJCXNlcnZlck5hbWUgPSB0b29sa2l0LmNyZWF0ZVRleHQoY29tcG9zaXRlLCBzZXJ2ZXIuZ2V0TmFtZSgpKTsKCQkJR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCQlzZXJ2ZXJOYW1lLnNldExheW91dERhdGEoZGF0YSk7CgkJCXNlcnZlck5hbWUuYWRkTW9kaWZ5TGlzdGVuZXIobmV3IE1vZGlmeUxpc3RlbmVyKCkgewoJCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBlKSB7CgkJCQkJaWYgKHVwZGF0aW5nKQoJCQkJCQlyZXR1cm47CgkJCQkJdXBkYXRpbmcgPSB0cnVlOwoJCQkJCWV4ZWN1dGUobmV3IFNldFNlcnZlck5hbWVDb21tYW5kKGdldFNlcnZlcigpLCBzZXJ2ZXJOYW1lLmdldFRleHQoKSkpOwoJCQkJCXVwZGF0aW5nID0gZmFsc2U7CgkJCQl9CgkJCX0pOwoJCQl3aHMuc2V0SGVscChzZXJ2ZXJOYW1lLCBDb250ZXh0SWRzLkVESVRPUl9TRVJWRVIpOwoJCX0KCQkKCQkvLyBob3N0bmFtZQoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkgewoJCQljcmVhdGVMYWJlbCh0b29sa2l0LCBjb21wb3NpdGUsIE1lc3NhZ2VzLnNlcnZlckVkaXRvck92ZXJ2aWV3U2VydmVySG9zdG5hbWUpOwoJCQkKCQkJaG9zdG5hbWUgPSB0b29sa2l0LmNyZWF0ZVRleHQoY29tcG9zaXRlLCBzZXJ2ZXIuZ2V0SG9zdCgpKTsKCQkJR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCQlob3N0bmFtZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQlob3N0bmFtZS5hZGRNb2RpZnlMaXN0ZW5lcihuZXcgTW9kaWZ5TGlzdGVuZXIoKSB7CgkJCQlwdWJsaWMgdm9pZCBtb2RpZnlUZXh0KE1vZGlmeUV2ZW50IGUpIHsKCQkJCQlpZiAodXBkYXRpbmcpCgkJCQkJCXJldHVybjsKCQkJCQl1cGRhdGluZyA9IHRydWU7CgkJCQkJZXhlY3V0ZShuZXcgU2V0U2VydmVySG9zdG5hbWVDb21tYW5kKGdldFNlcnZlcigpLCBob3N0bmFtZS5nZXRUZXh0KCkpKTsKCQkJCQl1cGRhdGluZyA9IGZhbHNlOwoJCQkJfQoJCQl9KTsKCQkJd2hzLnNldEhlbHAoaG9zdG5hbWUsIENvbnRleHRJZHMuRURJVE9SX0hPU1ROQU1FKTsKCQl9CgkJCgkJLy8gcnVudGltZQoJCWlmIChzZXJ2ZXIgIT0gbnVsbCAmJiBzZXJ2ZXIuZ2V0U2VydmVyVHlwZSgpICE9IG51bGwgJiYgc2VydmVyLmdldFNlcnZlclR5cGUoKS5oYXNSdW50aW1lKCkpIHsKCQkJZmluYWwgSVJ1bnRpbWUgcnVudGltZSA9IHNlcnZlci5nZXRSdW50aW1lKCk7CgkJCWNyZWF0ZUxhYmVsKHRvb2xraXQsIGNvbXBvc2l0ZSwgTWVzc2FnZXMuc2VydmVyRWRpdG9yT3ZlcnZpZXdSdW50aW1lKTsKCQkJCgkJCUlSdW50aW1lVHlwZSBydW50aW1lVHlwZSA9IHNlcnZlci5nZXRTZXJ2ZXJUeXBlKCkuZ2V0UnVudGltZVR5cGUoKTsKCQkJcnVudGltZXMgPSBTZXJ2ZXJVSVBsdWdpbi5nZXRSdW50aW1lcyhydW50aW1lVHlwZSk7CgkJCQoJCQlpZiAocnVudGltZXMgPT0gbnVsbCB8fCBydW50aW1lcy5sZW5ndGggPT0gMCkKCQkJCXRvb2xraXQuY3JlYXRlTGFiZWwoY29tcG9zaXRlLCAiIik7CgkJCWVsc2UgaWYgKHJ1bnRpbWVzLmxlbmd0aCA9PSAxKQoJCQkJdG9vbGtpdC5jcmVhdGVMYWJlbChjb21wb3NpdGUsIHJ1bnRpbWUuZ2V0TmFtZSgpKTsKCQkJZWxzZSB7CgkJCQlydW50aW1lQ29tYm8gPSBuZXcgQ29tYm8oY29tcG9zaXRlLCBTV1QuUkVBRF9PTkxZKTsKCQkJCXJ1bnRpbWVDb21iby5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpKTsKCQkJCXVwZGF0ZVJ1bnRpbWVDb21ibygpOwoJCQkJCgkJCQlpbnQgc2l6ZSA9IHJ1bnRpbWVzLmxlbmd0aDsKCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQkJaWYgKHJ1bnRpbWVzW2ldLmVxdWFscyhydW50aW1lKSkKCQkJCQkJcnVudGltZUNvbWJvLnNlbGVjdChpKTsKCQkJCX0KCQkJCQoJCQkJcnVudGltZUNvbWJvLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25MaXN0ZW5lcigpIHsKCQkJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQkJCXRyeSB7CgkJCQkJCQlpZiAodXBkYXRpbmcpCgkJCQkJCQkJcmV0dXJuOwoJCQkJCQkJdXBkYXRpbmcgPSB0cnVlOwoJCQkJCQkJSVJ1bnRpbWUgbmV3UnVudGltZSA9IHJ1bnRpbWVzW3J1bnRpbWVDb21iby5nZXRTZWxlY3Rpb25JbmRleCgpXTsKCQkJCQkJCWV4ZWN1dGUobmV3IFNldFNlcnZlclJ1bnRpbWVDb21tYW5kKGdldFNlcnZlcigpLCBuZXdSdW50aW1lKSk7CgkJCQkJCQl1cGRhdGluZyA9IGZhbHNlOwoJCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKCQkJCQkJCS8vIGlnbm9yZQoJCQkJCQl9CgkJCQkJfQoJCQkJCXB1YmxpYyB2b2lkIHdpZGdldERlZmF1bHRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQkJCXdpZGdldFNlbGVjdGVkKGUpOwoJCQkJCX0KCQkJCX0pOwoJCQkJd2hzLnNldEhlbHAocnVudGltZUNvbWJvLCBDb250ZXh0SWRzLkVESVRPUl9SVU5USU1FKTsKCQkJfQoJCQkKCQkJY3JlYXRlTGFiZWwodG9vbGtpdCwgY29tcG9zaXRlLCAiIik7CgkJCUh5cGVybGluayBsaW5rID0gdG9vbGtpdC5jcmVhdGVIeXBlcmxpbmsoY29tcG9zaXRlLCBNZXNzYWdlcy5zZXJ2ZXJFZGl0b3JPdmVydmlld1J1bnRpbWVFZGl0LCBTV1QuTk9ORSk7CgkJCS8vR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpOwoJCQkvL2xpbmsuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkJbGluay5hZGRIeXBlcmxpbmtMaXN0ZW5lcihuZXcgSUh5cGVybGlua0xpc3RlbmVyKCkgewoJCQkJcHVibGljIHZvaWQgbGlua0VudGVyZWQoSHlwZXJsaW5rRXZlbnQgZSkgewoJCQkJCS8vIGlnbm9yZQoJCQkJfQoKCQkJCXB1YmxpYyB2b2lkIGxpbmtFeGl0ZWQoSHlwZXJsaW5rRXZlbnQgZSkgewoJCQkJCS8vIGlnbm9yZQoJCQkJfQoKCQkJCXB1YmxpYyB2b2lkIGxpbmtBY3RpdmF0ZWQoSHlwZXJsaW5rRXZlbnQgZSkgewoJCQkJCWVkaXRSdW50aW1lKHJ1bnRpbWUpOwoJCQkJfQoJCQl9KTsKCQl9CgkJCgkJLy8gc2VydmVyIGNvbmZpZ3VyYXRpb24gcGF0aAoJCWlmIChzZXJ2ZXIgIT0gbnVsbCAmJiBzZXJ2ZXIuZ2V0U2VydmVyVHlwZSgpLmhhc1NlcnZlckNvbmZpZ3VyYXRpb24oKSkgewoJCQljcmVhdGVMYWJlbCh0b29sa2l0LCBjb21wb3NpdGUsIE1lc3NhZ2VzLnNlcnZlckVkaXRvck92ZXJ2aWV3U2VydmVyQ29uZmlndXJhdGlvblBhdGgpOwoJCQkKCQkJSUZvbGRlciBmb2xkZXIgPSBzZXJ2ZXIuZ2V0U2VydmVyQ29uZmlndXJhdGlvbigpOwoJCQlpZiAoZm9sZGVyID09IG51bGwpCgkJCQlzZXJ2ZXJDb25maWd1cmF0aW9uTmFtZSA9IHRvb2xraXQuY3JlYXRlVGV4dChjb21wb3NpdGUsIE1lc3NhZ2VzLmVsZW1lbnRVbmtub3duTmFtZSk7CgkJCWVsc2UKCQkJCXNlcnZlckNvbmZpZ3VyYXRpb25OYW1lID0gdG9vbGtpdC5jcmVhdGVUZXh0KGNvbXBvc2l0ZSwgIiIgKyBzZXJ2ZXIuZ2V0U2VydmVyQ29uZmlndXJhdGlvbigpLmdldEZ1bGxQYXRoKCkpOwoJCQlzZXJ2ZXJDb25maWd1cmF0aW9uTmFtZS5zZXRFZGl0YWJsZShmYWxzZSk7CgkJCXNlcnZlckNvbmZpZ3VyYXRpb25OYW1lLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCkpOwoJCQkKCQkJd2hzLnNldEhlbHAoc2VydmVyQ29uZmlndXJhdGlvbk5hbWUsIENvbnRleHRJZHMuRURJVE9SX0NPTkZJR1VSQVRJT04pOwoJCX0KCQkKCQkvLyBhdXRvLXB1Ymxpc2gKCQlpZiAoc2VydmVyICE9IG51bGwpIHsKCQkJR3JvdXAgZ3JvdXAgPSBuZXcgR3JvdXAoY29tcG9zaXRlLCBTV1QuTk9ORSk7CgkJCWdyb3VwLnNldEJhY2tncm91bmQoY29tcG9zaXRlLmdldEJhY2tncm91bmQoKSk7CgkJCWdyb3VwLnNldFRleHQoTWVzc2FnZXMuc2VydmVyRWRpdG9yT3ZlcnZpZXdQdWJsaXNoaW5nKTsKCQkJbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQkJbGF5b3V0Lm51bUNvbHVtbnMgPSAyOwoJCQlsYXlvdXQubWFyZ2luSGVpZ2h0ID0gNTsKCQkJbGF5b3V0Lm1hcmdpbldpZHRoID0gMTA7CgkJCWxheW91dC52ZXJ0aWNhbFNwYWNpbmcgPSA1OwoJCQlsYXlvdXQuaG9yaXpvbnRhbFNwYWNpbmcgPSAxNTsKCQkJZ3JvdXAuc2V0TGF5b3V0KGxheW91dCk7CgkJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJCWdyb3VwLnNldExheW91dERhdGEoZGF0YSk7CgkJCQoJCQlhdXRvUHVibGlzaERlZmF1bHQgPSB0b29sa2l0LmNyZWF0ZUJ1dHRvbihncm91cCwgTWVzc2FnZXMuc2VydmVyRWRpdG9yT3ZlcnZpZXdBdXRvUHVibGlzaERlZmF1bHQsIFNXVC5SQURJTyk7CgkJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJCWF1dG9QdWJsaXNoRGVmYXVsdC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQlTZXJ2ZXIgc3ZyID0gKFNlcnZlcikgc2VydmVyOwoJCQlhdXRvUHVibGlzaERlZmF1bHQuc2V0U2VsZWN0aW9uKHN2ci5nZXRBdXRvUHVibGlzaERlZmF1bHQoKSk7CgkJCXdocy5zZXRIZWxwKGF1dG9QdWJsaXNoRGVmYXVsdCwgQ29udGV4dElkcy5FRElUT1JfQVVUT1BVQkxJU0hfREVGQVVMVCk7CgkJCQoJCQlhdXRvUHVibGlzaE92ZXJyaWRlID0gdG9vbGtpdC5jcmVhdGVCdXR0b24oZ3JvdXAsIE1lc3NhZ2VzLnNlcnZlckVkaXRvck92ZXJ2aWV3QXV0b1B1Ymxpc2hPdmVycmlkZSwgU1dULlJBRElPKTsKCQkJYXV0b1B1Ymxpc2hPdmVycmlkZS5zZXRTZWxlY3Rpb24oIXN2ci5nZXRBdXRvUHVibGlzaERlZmF1bHQoKSk7CgkJCXdocy5zZXRIZWxwKGF1dG9QdWJsaXNoT3ZlcnJpZGUsIENvbnRleHRJZHMuRURJVE9SX0FVVE9QVUJMSVNIX09WRVJSSURFKTsKCQkJCgkJCWF1dG9QdWJsaXNoT3ZlcnJpZGUuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQkJaWYgKHVwZGF0aW5nKQoJCQkJCQlyZXR1cm47CgkJCQkJdXBkYXRpbmcgPSB0cnVlOwoJCQkJCWV4ZWN1dGUobmV3IFNldFNlcnZlckF1dG9QdWJsaXNoRGVmYXVsdENvbW1hbmQoZ2V0U2VydmVyKCksIGF1dG9QdWJsaXNoRGVmYXVsdC5nZXRTZWxlY3Rpb24oKSkpOwoJCQkJCXVwZGF0aW5nID0gZmFsc2U7CgkJCQkJYXV0b1B1Ymxpc2hUaW1lLnNldEVuYWJsZWQoYXV0b1B1Ymxpc2hPdmVycmlkZS5nZXRTZWxlY3Rpb24oKSk7CgkJCQl9CgkJCX0pOwoJCQkKCQkJLy9hdXRvUHVibGlzaFRpbWUgPSB0b29sa2l0LmNyZWF0ZVRleHQoY29tcG9zaXRlLCBzdnIuZ2V0QXV0b1B1Ymxpc2hUaW1lKCkgKyAiIik7CgkJCWF1dG9QdWJsaXNoVGltZSA9IG5ldyBTcGlubmVyKGdyb3VwLCBTV1QuQk9SREVSKTsKCQkJYXV0b1B1Ymxpc2hUaW1lLnNldE1pbmltdW0oMCk7CgkJCWF1dG9QdWJsaXNoVGltZS5zZXRNYXhpbXVtKDEyMCk7CgkJCWF1dG9QdWJsaXNoVGltZS5zZXRTZWxlY3Rpb24oc3ZyLmdldEF1dG9QdWJsaXNoVGltZSgpKTsKCQkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCQlhdXRvUHVibGlzaFRpbWUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkJYXV0b1B1Ymxpc2hUaW1lLnNldEVuYWJsZWQoYXV0b1B1Ymxpc2hPdmVycmlkZS5nZXRTZWxlY3Rpb24oKSk7CgkJCXdocy5zZXRIZWxwKGF1dG9QdWJsaXNoVGltZSwgQ29udGV4dElkcy5FRElUT1JfQVVUT1BVQkxJU0hfVElNRSk7CgkJCQoJCQlhdXRvUHVibGlzaFRpbWUuYWRkTW9kaWZ5TGlzdGVuZXIobmV3IE1vZGlmeUxpc3RlbmVyKCkgewoJCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBlKSB7CgkJCQkJaWYgKHVwZGF0aW5nKQoJCQkJCQlyZXR1cm47CgkJCQkJdXBkYXRpbmcgPSB0cnVlOwoJCQkJCXRyeSB7CgkJCQkJCWV4ZWN1dGUobmV3IFNldFNlcnZlckF1dG9QdWJsaXNoVGltZUNvbW1hbmQoZ2V0U2VydmVyKCksIGF1dG9QdWJsaXNoVGltZS5nZXRTZWxlY3Rpb24oKSkpOwoJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewoJCQkJCQkvLyBpZ25vcmUKCQkJCQl9CgkJCQkJdXBkYXRpbmcgPSBmYWxzZTsKCQkJCX0KCQkJfSk7CgkJfQoJCQoJCWluc2VydFNlY3Rpb25zKGxlZnRDb2x1bW5Db21wLCAib3JnLmVjbGlwc2Uud3N0LnNlcnZlci5lZGl0b3Iub3ZlcnZpZXcubGVmdCIpOwoJCQoJCS8vIHJpZ2h0IGNvbHVtbgoJCUNvbXBvc2l0ZSByaWdodENvbHVtbkNvbXAgPSB0b29sa2l0LmNyZWF0ZUNvbXBvc2l0ZShjb2x1bW5Db21wKTsKCQlsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5tYXJnaW5IZWlnaHQgPSAwOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDA7CgkJbGF5b3V0LnZlcnRpY2FsU3BhY2luZyA9IDEwOwoJCWxheW91dC5ob3Jpem9udGFsU3BhY2luZyA9IDA7CgkJcmlnaHRDb2x1bW5Db21wLnNldExheW91dChsYXlvdXQpOwoJCXJpZ2h0Q29sdW1uQ29tcC5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwgfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9GSUxMKSk7CgkJCgkJaW5zZXJ0U2VjdGlvbnMocmlnaHRDb2x1bW5Db21wLCAib3JnLmVjbGlwc2Uud3N0LnNlcnZlci5lZGl0b3Iub3ZlcnZpZXcucmlnaHQiKTsKCQkKCQlmb3JtLnNldENvbnRlbnQoY29sdW1uQ29tcCk7CgkJZm9ybS5yZWZsb3codHJ1ZSk7CgoJCWluaXRpYWxpemUoKTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgZWRpdFJ1bnRpbWUoSVJ1bnRpbWUgcnVudGltZSkgewoJCUlSdW50aW1lV29ya2luZ0NvcHkgcnVudGltZVdvcmtpbmdDb3B5ID0gcnVudGltZS5jcmVhdGVXb3JraW5nQ29weSgpOwoJCWlmIChzaG93V2l6YXJkKHJ1bnRpbWVXb3JraW5nQ29weSkgIT0gV2luZG93LkNBTkNFTCkgewoJCQl0cnkgewoJCQkJcnVudGltZVdvcmtpbmdDb3B5LnNhdmUoZmFsc2UsIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKCQkJCS8vIGlnbm9yZQoJCQl9CgkJfQoJfQoJCglwcm90ZWN0ZWQgaW50IHNob3dXaXphcmQoZmluYWwgSVJ1bnRpbWVXb3JraW5nQ29weSBydW50aW1lV29ya2luZ0NvcHkpIHsKCQlTdHJpbmcgdGl0bGUgPSBNZXNzYWdlcy53aXpFZGl0UnVudGltZVdpemFyZFRpdGxlOwoJCWZpbmFsIFdpemFyZEZyYWdtZW50IGZyYWdtZW50MiA9IFNlcnZlclVJUGx1Z2luLmdldFdpemFyZEZyYWdtZW50KHJ1bnRpbWVXb3JraW5nQ29weS5nZXRSdW50aW1lVHlwZSgpLmdldElkKCkpOwoJCWlmIChmcmFnbWVudDIgPT0gbnVsbCkKCQkJcmV0dXJuIFdpbmRvdy5DQU5DRUw7CgkJCgkJV2l6YXJkRnJhZ21lbnQgZnJhZ21lbnQgPSBuZXcgV2l6YXJkRnJhZ21lbnQoKSB7CgkJCXByb3RlY3RlZCB2b2lkIGNyZWF0ZUNoaWxkRnJhZ21lbnRzKExpc3QgbGlzdCkgewoJCQkJbGlzdC5hZGQobmV3IFdpemFyZEZyYWdtZW50KCkgewoJCQkJCXB1YmxpYyB2b2lkIGVudGVyKCkgewoJCQkJCQlnZXRUYXNrTW9kZWwoKS5wdXRPYmplY3QoVGFza01vZGVsLlRBU0tfUlVOVElNRSwgcnVudGltZVdvcmtpbmdDb3B5KTsKCQkJCQl9CgkJCQl9KTsKCQkJCWxpc3QuYWRkKGZyYWdtZW50Mik7CgkJCQlsaXN0LmFkZChuZXcgV2l6YXJkRnJhZ21lbnQoKSB7CgkJCQkJcHVibGljIHZvaWQgcGVyZm9ybUZpbmlzaChJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQkJCQkJV2l6YXJkVGFza1V0aWwuc2F2ZVJ1bnRpbWUoZ2V0VGFza01vZGVsKCksIG1vbml0b3IpOwoJCQkJCX0KCQkJCX0pOwoJCQl9CgkJfTsKCQkKCQlUYXNrV2l6YXJkIHdpemFyZCA9IG5ldyBUYXNrV2l6YXJkKHRpdGxlLCBmcmFnbWVudCk7CgkJd2l6YXJkLnNldEZvcmNlUHJldmlvdXNBbmROZXh0QnV0dG9ucyh0cnVlKTsKCQlDbG9zYWJsZVdpemFyZERpYWxvZyBkaWFsb2cgPSBuZXcgQ2xvc2FibGVXaXphcmREaWFsb2coZ2V0RWRpdG9yU2l0ZSgpLmdldFNoZWxsKCksIHdpemFyZCk7CgkJcmV0dXJuIGRpYWxvZy5vcGVuKCk7Cgl9CgkKCXByb3RlY3RlZCB2b2lkIHVwZGF0ZVJ1bnRpbWVDb21ibygpIHsKCQlJUnVudGltZVR5cGUgcnVudGltZVR5cGUgPSBzZXJ2ZXIuZ2V0U2VydmVyVHlwZSgpLmdldFJ1bnRpbWVUeXBlKCk7CgkJcnVudGltZXMgPSBTZXJ2ZXJVSVBsdWdpbi5nZXRSdW50aW1lcyhydW50aW1lVHlwZSk7CgkJCgkJaWYgKFNvY2tldFV0aWwuaXNMb2NhbGhvc3Qoc2VydmVyLmdldEhvc3QoKSkgJiYgcnVudGltZXMgIT0gbnVsbCkgewoJCQlMaXN0IHJ1bnRpbWVzMiA9IG5ldyBBcnJheUxpc3QoKTsKCQkJaW50IHNpemUgPSBydW50aW1lcy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlJUnVudGltZSBydW50aW1lMiA9IHJ1bnRpbWVzW2ldOwoJCQkJaWYgKCFydW50aW1lMi5pc1N0dWIoKSkKCQkJCQlydW50aW1lczIuYWRkKHJ1bnRpbWUyKTsKCQkJfQoJCQlydW50aW1lcyA9IG5ldyBJUnVudGltZVtydW50aW1lczIuc2l6ZSgpXTsKCQkJcnVudGltZXMyLnRvQXJyYXkocnVudGltZXMpOwoJCX0KCQkKCQlpbnQgc2l6ZSA9IHJ1bnRpbWVzLmxlbmd0aDsKCQlTdHJpbmdbXSBpdGVtcyA9IG5ldyBTdHJpbmdbc2l6ZV07CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspCgkJCWl0ZW1zW2ldID0gcnVudGltZXNbaV0uZ2V0TmFtZSgpOwoJCQoJCXJ1bnRpbWVDb21iby5zZXRJdGVtcyhpdGVtcyk7Cgl9CgoJcHJvdGVjdGVkIExhYmVsIGNyZWF0ZUxhYmVsKEZvcm1Ub29sa2l0IHRvb2xraXQsIENvbXBvc2l0ZSBwYXJlbnQsIFN0cmluZyB0ZXh0KSB7CgkJTGFiZWwgbGFiZWwgPSB0b29sa2l0LmNyZWF0ZUxhYmVsKHBhcmVudCwgdGV4dCk7CgkJbGFiZWwuc2V0Rm9yZWdyb3VuZCh0b29sa2l0LmdldENvbG9ycygpLmdldENvbG9yKEZvcm1Db2xvcnMuVElUTEUpKTsKCQlyZXR1cm4gbGFiZWw7Cgl9CgkKCXB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CgkJc3VwZXIuZGlzcG9zZSgpOwoJCQoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkKCQkJc2VydmVyLnJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIobGlzdGVuZXIpOwoJfQoJCgkvKiAobm9uLUphdmFkb2MpCgkgKiBJbml0aWFsaXplcyB0aGUgZWRpdG9yIHBhcnQgd2l0aCBhIHNpdGUgYW5kIGlucHV0LgoJICovCglwdWJsaWMgdm9pZCBpbml0KElFZGl0b3JTaXRlIHNpdGUsIElFZGl0b3JJbnB1dCBpbnB1dCkgewoJCXN1cGVyLmluaXQoc2l0ZSwgaW5wdXQpOwoJCQoJCWFkZENoYW5nZUxpc3RlbmVyKCk7CgkJaW5pdGlhbGl6ZSgpOwoJfQoJCgkvKioKCSAqIEluaXRpYWxpemUgdGhlIGZpZWxkcyBpbiB0aGlzIGVkaXRvci4KCSAqLwoJcHJvdGVjdGVkIHZvaWQgaW5pdGlhbGl6ZSgpIHsKCQlpZiAoc2VydmVyTmFtZSA9PSBudWxsKQoJCQlyZXR1cm47CgkJdXBkYXRpbmcgPSB0cnVlOwoJCQoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkgewoJCQlzZXJ2ZXJOYW1lLnNldFRleHQoc2VydmVyLmdldE5hbWUoKSk7CgkJCWlmIChyZWFkT25seSkKCQkJCXNlcnZlck5hbWUuc2V0RWRpdGFibGUoZmFsc2UpOwoJCQllbHNlCgkJCQlzZXJ2ZXJOYW1lLnNldEVkaXRhYmxlKHRydWUpOwoJCX0KCQkKCQl1cGRhdGluZyA9IGZhbHNlOwoJfQoJCgkvL3Byb3RlY3RlZCB2b2lkIHZhbGlkYXRlKCkgeyB9CgoJLyoKCSAqIEBzZWUgSVdvcmtiZW5jaFBhcnQjc2V0Rm9jdXMoKQoJICovCglwdWJsaWMgdm9pZCBzZXRGb2N1cygpIHsKCQlpZiAoc2VydmVyTmFtZSAhPSBudWxsKQoJCQlzZXJ2ZXJOYW1lLnNldEZvY3VzKCk7CgkJZWxzZSBpZiAoc2VydmVyQ29uZmlndXJhdGlvbk5hbWUgIT0gbnVsbCkKCQkJc2VydmVyQ29uZmlndXJhdGlvbk5hbWUuc2V0Rm9jdXMoKTsKCX0KfQ==