LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgSUJNIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwud2l6YXJkLnBhZ2U7Ci8qaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklDb250YWluZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRmlsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklQcm9qZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVJlc291cmNlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVdvcmtzcGFjZVJ1bm5hYmxlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuUmVzb3VyY2VzUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLio7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLkRpYWxvZzsqLwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUNvbnRhaW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLndpemFyZC5XaXphcmRQYWdlOwovKmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0FkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLk1vZGlmeUV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Nb2RpZnlMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uQWRhcHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkTGF5b3V0OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQnV0dG9uOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tYm87Ki8KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZTsKLyppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuRGlyZWN0b3J5RGlhbG9nOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuRGlzcGxheTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkZpbGVEaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5MYWJlbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlRleHQ7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5oZWxwLldvcmtiZW5jaEhlbHA7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuU2VydmVyUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5TZXJ2ZXJVSUNvcmU7Ki8KaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuKjsKLyoqCiAqIFdpemFyZCBwYWdlIHRvIGltcG9ydCBhIGNvbmZpZ3VyYXRpb24uCiAqLwpwdWJsaWMgY2xhc3MgSW1wb3J0Q29uZmlndXJhdGlvbldpemFyZFBhZ2UgZXh0ZW5kcyBXaXphcmRQYWdlIHsKCS8qCgkvL3Byb3RlY3RlZCBJU2VydmVyQ29uZmlndXJhdGlvblR5cGUgc2VsZWN0ZWRDb25maWdUeXBlOwoJLy9wcm90ZWN0ZWQgSVNlcnZlckNvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSBjb25maWd1cmF0aW9uOwoJcHJvdGVjdGVkIENvbWJvIHNlcnZlclByb2plY3Q7Cglwcm90ZWN0ZWQgQnV0dG9uIGNyZWF0ZTsKCXByb3RlY3RlZCBUZXh0IG5hbWU7Cglwcm90ZWN0ZWQgVGV4dCBmaWxlbmFtZTsKCS8vcHJvdGVjdGVkIFNlcnZlckNvbmZpZ3VyYXRpb25UeXBlQ29tcG9zaXRlIGNvbmZpZ1R5cGVDb21wb3NpdGU7Cglwcml2YXRlIExhYmVsIGRlc2NyaXB0aW9uOwoJcHJvdGVjdGVkIEJ1dHRvbiBicm93c2U7Cglwcml2YXRlIElDb250YWluZXIgZGVmYXVsdENvbnRhaW5lcjsKCQoJcHJpdmF0ZSBTdHJpbmdbXSB2YWxpZGF0aW9uRXJyb3JzID0gbmV3IFN0cmluZ1s1XTsKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTlZBTElEX05BTUUgPSAwOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOVkFMSURfRk9MREVSID0gMTsKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBJTlZBTElEX1RZUEUgPSAyOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOVkFMSURfRklMRU5BTUUgPSAzOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IElOVkFMSURfSU1QT1JUID0gNDsKCQoJcHJvdGVjdGVkIExvYWRUaHJlYWQgdGhyZWFkOwoJcHJvdGVjdGVkIGJvb2xlYW4gdGhyZWFkRG9uZTsqLwoKCS8qY2xhc3MgTG9hZFRocmVhZCBleHRlbmRzIFRocmVhZCB7CgkJZmluYWwgaW50IERFTEFZID0gODAwOwoJCVN0cmluZyBmaWxlbmFtZTI7CgkJSUZpbGUgZmlsZTsKCQlwdWJsaWMgdm9pZCBydW4oKSB7CgkJCWJvb2xlYW4gYiA9IHRydWU7CgkJCXdoaWxlIChiKSB7CgkJCQl0cnkgewoJCQkJCXNsZWVwKERFTEFZKTsKCQkJCQliID0gZmFsc2U7CgkJCQkJdGhyZWFkID0gbnVsbDsKCQkJCX0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGllKSB7CgkJCQkJLy8gaWdub3JlCgkJCQl9CgkJCX0KCQkJdHJ5IHsKCQkJCXBlcmZvcm1Mb2FkQ29uZmlndXJhdGlvbihmaWxlLCBmaWxlbmFtZTIpOwoJCQkJRGlzcGxheS5nZXREZWZhdWx0KCkuYXN5bmNFeGVjKG5ldyBSdW5uYWJsZSgpIHsKCQkJCQlwdWJsaWMgdm9pZCBydW4oKSB7CgkJCQkJCXZhbGlkYXRlUGFnZShJTlZBTElEX0lNUE9SVCk7CgkJCQkJfQoJCQkJfSk7CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBpbXBvcnRpbmcgY29uZmlndXJhdGlvbiIsIGUpOwoJCQl9CgkJCXRocmVhZERvbmUgPSB0cnVlOwoJCX0KCX0qLwoKCS8qKgoJICogSW1wb3J0Q29uZmlndXJhdGlvbldpemFyZFBhZ2UgY29uc3RydWN0b3IgY29tbWVudC4KCSAqLwoJcHVibGljIEltcG9ydENvbmZpZ3VyYXRpb25XaXphcmRQYWdlKCkgewoJCXN1cGVyKCJpbXBvcnQgY29uZmlndXJhdGlvbiIpOwoJCgkJc2V0VGl0bGUoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpJbXBvcnRDb25maWd1cmF0aW9uVGl0bGUiKSk7CgkJc2V0RGVzY3JpcHRpb24oU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpJbXBvcnRDb25maWd1cmF0aW9uRGVzY3JpcHRpb24iKSk7CgkJc2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX1dJWkJBTl9JTVBPUlRfU0VSVkVSX0NPTkZJR1VSQVRJT04pKTsKCX0KCQoJLyoqCgkgKiBDcmVhdGVzIHRoZSBVSSBwYXJ0IG9mIHRoZSBwYWdlLiBTdWJjbGFzc2VzIG11c3QgcmVpbXBsZW1lbnQgCgkgKiB0aGlzIG1ldGhvZCB0byBwcm92aWRlIHRoZWlyIG93biBncmFwaGljYWwgcGFnZSBjb250ZW50LgoJICovCglwdWJsaWMgdm9pZCBjcmVhdGVDb250cm9sKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQlpbml0aWFsaXplRGlhbG9nVW5pdHMocGFyZW50KTsKCX0KCS8qCgkJQ29tcG9zaXRlIGNvbXBvc2l0ZSA9IG5ldyBDb21wb3NpdGUocGFyZW50LCBTV1QuTk9ORSk7CgkJR3JpZExheW91dCBsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5udW1Db2x1bW5zID0gMzsKCQlsYXlvdXQuaG9yaXpvbnRhbFNwYWNpbmcgPSBjb252ZXJ0SG9yaXpvbnRhbERMVXNUb1BpeGVscyg0KTsKCQlsYXlvdXQudmVydGljYWxTcGFjaW5nID0gY29udmVydFZlcnRpY2FsRExVc1RvUGl4ZWxzKDQpOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IGNvbnZlcnRIb3Jpem9udGFsRExVc1RvUGl4ZWxzKDUpOwoJCWxheW91dC5tYXJnaW5IZWlnaHQgPSBjb252ZXJ0VmVydGljYWxETFVzVG9QaXhlbHMoNSk7CgkJY29tcG9zaXRlLnNldExheW91dChsYXlvdXQpOwoJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9CT1RIKTsKCQlkYXRhLndpZHRoSGludCA9IGNvbnZlcnRIb3Jpem9udGFsRExVc1RvUGl4ZWxzKDUwMCk7CgkJZGF0YS5oZWlnaHRIaW50ID0gY29udmVydFZlcnRpY2FsRExVc1RvUGl4ZWxzKDQ3MCk7CgkJV29ya2JlbmNoSGVscC5zZXRIZWxwKGNvbXBvc2l0ZSwgQ29udGV4dElkcy5JTVBPUlRfQ09ORklHVVJBVElPTl9XSVpBUkQpOwoJCgkJbmV3IExhYmVsKGNvbXBvc2l0ZSwgU1dULk5PTkUpLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVzZXJ2ZXJFZGl0b3JPdmVydmlld1NlcnZlckNvbmZpZ3VyYXRpb25OYW1lIikpOwoJCgkJbmFtZSA9IG5ldyBUZXh0KGNvbXBvc2l0ZSwgU1dULkJPUkRFUik7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCW5hbWUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQluYW1lLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBtZSkgewoJCQkJdmFsaWRhdGVOYW1lKCk7CgkJCQl2YWxpZGF0ZVBhZ2UoSU5WQUxJRF9OQU1FKTsKCQkJfQoJCX0pOwoJCW5hbWUuYWRkRm9jdXNMaXN0ZW5lcihuZXcgRm9jdXNBZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCBmb2N1c0dhaW5lZChGb2N1c0V2ZW50IGUpIHsKCQkJCSB2YWxpZGF0ZVBhZ2UoSU5WQUxJRF9OQU1FKTsKCQkJfQoJCX0pOwoJCVdvcmtiZW5jaEhlbHAuc2V0SGVscChuYW1lLCBDb250ZXh0SWRzLklNUE9SVF9DT05GSUdVUkFUSU9OX05BTUUpOwoJCgkJLy8gY2hvb3NlIGEgc2VydmVyIHByb2plY3QKCQluZXcgTGFiZWwoY29tcG9zaXRlLCBTV1QuTk9ORSkuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpekZvbGRlciIpKTsKCQlzZXJ2ZXJQcm9qZWN0ID0gbmV3IENvbWJvKGNvbXBvc2l0ZSwgU1dULkJPUkRFUik7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCXNlcnZlclByb2plY3Quc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlpZiAoZGVmYXVsdENvbnRhaW5lciAhPSBudWxsKQoJCQlzZXJ2ZXJQcm9qZWN0LnNldFRleHQoV2l6YXJkVXRpbC5nZXRDb250YWluZXJUZXh0KGRlZmF1bHRDb250YWluZXIpKTsKCQllbHNlIGlmIChzZXJ2ZXJQcm9qZWN0LmdldEl0ZW1Db3VudCgpID09IDApCgkJCXNlcnZlclByb2plY3Quc2V0VGV4dChTZXJ2ZXJQbHVnaW4uZ2V0UmVzb3VyY2UoIiVkZWZhdWx0U2VydmVyUHJvamVjdE5hbWUiLCAiIikpOwoJCgkJc2VydmVyUHJvamVjdC5hZGRNb2RpZnlMaXN0ZW5lcihuZXcgTW9kaWZ5TGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIG1vZGlmeVRleHQoTW9kaWZ5RXZlbnQgbWUpIHsKCQkJCXZhbGlkYXRlTmFtZSgpOwoJCQkJdmFsaWRhdGVGb2xkZXIoKTsKCQkJCXZhbGlkYXRlUGFnZShJTlZBTElEX0ZPTERFUik7CgkJCX0KCQl9KTsKCQlzZXJ2ZXJQcm9qZWN0LmFkZEZvY3VzTGlzdGVuZXIobmV3IEZvY3VzQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgZm9jdXNHYWluZWQoRm9jdXNFdmVudCBlKSB7CgkJCQkgdmFsaWRhdGVQYWdlKElOVkFMSURfRk9MREVSKTsKCQkJfQoJCX0pOwoJCVdvcmtiZW5jaEhlbHAuc2V0SGVscChzZXJ2ZXJQcm9qZWN0LCBDb250ZXh0SWRzLklNUE9SVF9DT05GSUdVUkFUSU9OX0ZPTERFUik7CgkKCQljb25maWdUeXBlQ29tcG9zaXRlID0gbmV3IFNlcnZlckNvbmZpZ3VyYXRpb25UeXBlQ29tcG9zaXRlKGNvbXBvc2l0ZSwgU1dULk5PTkUsIG5ldyBTZXJ2ZXJDb25maWd1cmF0aW9uVHlwZUNvbXBvc2l0ZS5TZXJ2ZXJDb25maWd1cmF0aW9uVHlwZVNlbGVjdGlvbkxpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCBjb25maWd1cmF0aW9uVHlwZVNlbGVjdGVkKElTZXJ2ZXJDb25maWd1cmF0aW9uVHlwZSB0eXBlKSB7CgkJCQloYW5kbGVGYWN0b3J5U2VsZWN0aW9uKHR5cGUpOwoJCQkJdmFsaWRhdGVOYW1lKCk7CgkJCQl2YWxpZGF0ZVBhZ2UoSU5WQUxJRF9UWVBFKTsKCQkJfQoJCX0pOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlkYXRhLmhlaWdodEhpbnQgPSAxMzA7CgkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJY29uZmlnVHlwZUNvbXBvc2l0ZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCVdvcmtiZW5jaEhlbHAuc2V0SGVscChjb25maWdUeXBlQ29tcG9zaXRlLCBDb250ZXh0SWRzLklNUE9SVF9DT05GSUdVUkFUSU9OX0ZBQ1RPUlkpOwoJCgkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoY29tcG9zaXRlLCBTV1QuTk9ORSk7CgkJbGFiZWwuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpekRlc2NyaXB0aW9uIikpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuVkVSVElDQUxfQUxJR05fQkVHSU5OSU5HKTsKCQlsYWJlbC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCgkJZGVzY3JpcHRpb24gPSBuZXcgTGFiZWwoY29tcG9zaXRlLCBTV1QuV1JBUCk7CgkJZGVzY3JpcHRpb24uc2V0VGV4dCgiIik7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWRhdGEuaGVpZ2h0SGludCA9IDU4OwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCWRlc2NyaXB0aW9uLnNldExheW91dERhdGEoZGF0YSk7CgkKCQlsYWJlbCA9IG5ldyBMYWJlbChjb21wb3NpdGUsIFNXVC5OT05FKTsKCQlsYWJlbC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6SW1wb3J0Q29uZmlndXJhdGlvbkxvY2F0aW9uIikpOwoJCgkJZmlsZW5hbWUgPSBuZXcgVGV4dChjb21wb3NpdGUsIFNXVC5CT1JERVIpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlkYXRhLndpZHRoSGludCA9IDMwMDsKCQlmaWxlbmFtZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCWZpbGVuYW1lLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBtZSkgewoJCQkJaGFuZGxlRmlsZVNlbGVjdGlvbigpOwoJCQkJdmFsaWRhdGVQYWdlKElOVkFMSURfVFlQRSk7CgkJCX0KCQl9KTsKCQlXb3JrYmVuY2hIZWxwLnNldEhlbHAoZmlsZW5hbWUsIENvbnRleHRJZHMuSU1QT1JUX0NPTkZJR1VSQVRJT05fTE9DQVRJT04pOwoJCgkJYnJvd3NlID0gU1dUVXRpbC5jcmVhdGVCdXR0b24oY29tcG9zaXRlLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpekJyb3dzZSIpKTsgCgkJYnJvd3NlLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBzZSkgewoJCQkJaWYgKHNlbGVjdGVkQ29uZmlnVHlwZSA9PSBudWxsKQoJCQkJCXJldHVybjsKCQkJCVN0cmluZ1tdIGZpbHRlciA9IHNlbGVjdGVkQ29uZmlnVHlwZS5nZXRJbXBvcnRGaWx0ZXJFeHRlbnNpb25zKCk7CgkJCQlpZiAoZmlsdGVyICE9IG51bGwpIHsKCQkJCQlpbnQgc2l6ZSA9IGZpbHRlci5sZW5ndGg7CgkJCQkJU3RyaW5nW10gcyA9IG5ldyBTdHJpbmdbc2l6ZV07CgkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQkJaWYgKCFmaWx0ZXJbaV0uc3RhcnRzV2l0aCgiKi4iKSkKCQkJCQkJCXNbaV0gPSAiKi4iICsgZmlsdGVyW2ldOwoJCQkJCQllbHNlCgkJCQkJCQlzW2ldID0gZmlsdGVyW2ldOwoJCQkJCX0KCQkJCQlGaWxlRGlhbG9nIGRpYWxvZyA9IG5ldyBGaWxlRGlhbG9nKGdldFNoZWxsKCkpOwoJCQkJCWRpYWxvZy5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6SW1wb3J0Q29uZmlndXJhdGlvbkZpbGUiKSk7CgkJCQkJZGlhbG9nLnNldEZpbHRlclBhdGgoZmlsZW5hbWUuZ2V0VGV4dCgpKTsKCQkJCQlkaWFsb2cuc2V0RmlsdGVyRXh0ZW5zaW9ucyhzKTsKCQkJCQlTdHJpbmcgc2VsZWN0ZWRGaWxlID0gZGlhbG9nLm9wZW4oKTsKCQkJCQlpZiAoc2VsZWN0ZWRGaWxlICE9IG51bGwpCgkJCQkJCWZpbGVuYW1lLnNldFRleHQoc2VsZWN0ZWRGaWxlKTsKCQkJCX0gZWxzZSB7CgkJCQkJRGlyZWN0b3J5RGlhbG9nIGRpYWxvZyA9IG5ldyBEaXJlY3RvcnlEaWFsb2coZ2V0U2hlbGwoKSk7CgkJCQkJZGlhbG9nLnNldE1lc3NhZ2UoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpJbXBvcnRDb25maWd1cmF0aW9uRGlyZWN0b3J5IikpOwoJCQkJCWRpYWxvZy5zZXRGaWx0ZXJQYXRoKGZpbGVuYW1lLmdldFRleHQoKSk7CgkJCQkJU3RyaW5nIHNlbGVjdGVkRGlyZWN0b3J5ID0gZGlhbG9nLm9wZW4oKTsKCQkJCQlpZiAoc2VsZWN0ZWREaXJlY3RvcnkgIT0gbnVsbCkKCQkJCQkJZmlsZW5hbWUuc2V0VGV4dChzZWxlY3RlZERpcmVjdG9yeSk7CgkJCQl9CgkJCX0KCQl9KTsKCQlicm93c2Uuc2V0RW5hYmxlZChmYWxzZSk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpOwoJCS8vZGF0YS53aWR0aEhpbnQgPSA3NTsKCQlkYXRhLmhlaWdodEhpbnQgPSAyMjsKCQlicm93c2Uuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlXb3JrYmVuY2hIZWxwLnNldEhlbHAoYnJvd3NlLCBDb250ZXh0SWRzLklNUE9SVF9DT05GSUdVUkFUSU9OX0xPQ0FUSU9OX0JST1dTRSk7CgkKCQkvL2ZpbGxGYWN0b3J5VHJlZSgpOwoJCXZhbGlkYXRpb25FcnJvcnNbSU5WQUxJRF9UWVBFXSA9ICIiOwoJCXZhbGlkYXRpb25FcnJvcnNbSU5WQUxJRF9GSUxFTkFNRV0gPSAiIjsKCQkKCQlTZXJ2ZXJVSVByZWZlcmVuY2VzIHNwID0gKFNlcnZlclVJUHJlZmVyZW5jZXMpIFNlcnZlclVJQ29yZS5nZXRQcmVmZXJlbmNlcygpOwoJCWlmIChzcC5nZXRJbXBvcnRMb2NhdGlvbigpICE9IG51bGwpIHsKCQkJZmlsZW5hbWUuc2V0VGV4dChzcC5nZXRJbXBvcnRMb2NhdGlvbigpKTsKCQkJaGFuZGxlRmlsZVNlbGVjdGlvbigpOwoJCQl2YWxpZGF0ZVBhZ2UoSU5WQUxJRF9UWVBFKTsKCQl9CgkKCQlzZXRDb250cm9sKGNvbXBvc2l0ZSk7CgkJRGlhbG9nLmFwcGx5RGlhbG9nRm9udChjb21wb3NpdGUpOwoJfSovCgkKCS8qcHJvdGVjdGVkIHZvaWQgbG9hZENvbmZpZ3VyYXRpb24oKSB7CgkJaWYgKHRocmVhZCAhPSBudWxsKSB7CgkJCXRyeSB7CgkJCQl0aHJlYWQuaW50ZXJydXB0KCk7CgkJCQl0aHJlYWQuZmlsZW5hbWUyID0gZmlsZW5hbWUuZ2V0VGV4dCgpOwoJCQkJSUZpbGUgZmlsZSA9IG51bGw7CgkJCQlTdHJpbmcgdGhlTmFtZSA9IG5hbWUuZ2V0VGV4dCgpOwoJCQkJaWYgKHRoZU5hbWUgIT0gbnVsbCAmJiAhdGhlTmFtZS5lbmRzV2l0aChJU2VydmVyQ29uZmlndXJhdGlvbi5GSUxFX0VYVEVOU0lPTikpCgkJCQkJdGhlTmFtZSArPSAiLiIgKyBJU2VydmVyQ29uZmlndXJhdGlvbi5GSUxFX0VYVEVOU0lPTjsKCQkJCVN0cmluZyBwcm9qZWN0TmFtZSA9IHNlcnZlclByb2plY3QuZ2V0VGV4dCgpOwoJCQkJaWYgKCEibWV0YWRhdGEiLmVxdWFscyhwcm9qZWN0TmFtZSkpCgkJCQkJZmlsZSA9IFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCkuZ2V0RmlsZShuZXcgUGF0aChwcm9qZWN0TmFtZSkuYXBwZW5kKHRoZU5hbWUpKTsKCQkJCXRocmVhZC5maWxlID0gZmlsZTsKCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCS8vIGlnbm9yZQoJCQl9CgkJfSBlbHNlIHsKCQkJLy8gdHJ5IHRvIGF2b2lkIG11bHRpcGxlIHRocmVhZHMKCQkJaWYgKCF0aHJlYWREb25lKSB7CgkJCQl0cnkgewoJCQkJCVRocmVhZC5zbGVlcCgyMDApOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQkvLyBpZ25vcmUKCQkJCX0KCQkJfQoJCQlpZiAodmFsaWRhdGlvbkVycm9yc1tJTlZBTElEX1RZUEVdICE9IG51bGwgfHwgdmFsaWRhdGlvbkVycm9yc1tJTlZBTElEX0ZJTEVOQU1FXSAhPSBudWxsKQoJCQkJcmV0dXJuOwoJCQl0aHJlYWQgPSBuZXcgTG9hZFRocmVhZCgpOwoJCQl0aHJlYWQuZmlsZW5hbWUyID0gZmlsZW5hbWUuZ2V0VGV4dCgpOwoJCQlJRmlsZSBmaWxlID0gbnVsbDsKCQkJU3RyaW5nIHRoZU5hbWUgPSBuYW1lLmdldFRleHQoKTsKCQkJaWYgKHRoZU5hbWUgIT0gbnVsbCAmJiAhdGhlTmFtZS5lbmRzV2l0aChJU2VydmVyQ29uZmlndXJhdGlvbi5GSUxFX0VYVEVOU0lPTikpCgkJCQl0aGVOYW1lICs9ICIuIiArIElTZXJ2ZXJDb25maWd1cmF0aW9uLkZJTEVfRVhURU5TSU9OOwoJCQlTdHJpbmcgcHJvamVjdE5hbWUgPSBzZXJ2ZXJQcm9qZWN0LmdldFRleHQoKTsKCQkJaWYgKCEibWV0YWRhdGEiLmVxdWFscyhwcm9qZWN0TmFtZSkpCgkJCQlmaWxlID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKS5nZXRGaWxlKG5ldyBQYXRoKHByb2plY3ROYW1lKS5hcHBlbmQodGhlTmFtZSkpOwoJCQl0aHJlYWQuZmlsZSA9IGZpbGU7CgkJCWdldENvbnRhaW5lcigpLnVwZGF0ZUJ1dHRvbnMoKTsKCQkJdGhyZWFkRG9uZSA9IGZhbHNlOwoJCQl0aHJlYWQuc3RhcnQoKTsKCQl9Cgl9Ki8KCQoJLyoqCgkgKiBIYW5kbGUgdGhlIHNlcnZlciBmYWN0b3J5IHNlbGVjdGlvbi4KCSAqLwoJLypwcm90ZWN0ZWQgdm9pZCBoYW5kbGVGYWN0b3J5U2VsZWN0aW9uKElTZXJ2ZXJDb25maWd1cmF0aW9uVHlwZSB0eXBlKSB7CgkJdmFsaWRhdGlvbkVycm9yc1tJTlZBTElEX0lNUE9SVF0gPSBudWxsOwoJCWNvbmZpZ3VyYXRpb24gPSBudWxsOwoJCXNlbGVjdGVkQ29uZmlnVHlwZSA9IHR5cGU7CgkKCQl2YWxpZGF0aW9uRXJyb3JzW0lOVkFMSURfVFlQRV0gPSBudWxsOwoJCQoJCWlmIChzZWxlY3RlZENvbmZpZ1R5cGUgPT0gbnVsbCkgewoJCQlicm93c2Uuc2V0RW5hYmxlZChmYWxzZSk7CgkJCWRlc2NyaXB0aW9uLnNldFRleHQoIiIpOwoJCQlyZXR1cm47CgkJfQoJCgkJdHJ5IHsKCQkJU3RyaW5nIHRleHQgPSBzZWxlY3RlZENvbmZpZ1R5cGUuZ2V0RGVzY3JpcHRpb24oKTsKCQkJaWYgKHRleHQgPT0gbnVsbCkKCQkJCXRleHQgPSAiIjsKCQkJZGVzY3JpcHRpb24uc2V0VGV4dCh0ZXh0KTsKCQkJYnJvd3NlLnNldEVuYWJsZWQodHJ1ZSk7CgkJCQoJCQlsb2FkQ29uZmlndXJhdGlvbigpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCXZhbGlkYXRpb25FcnJvcnNbSU5WQUxJRF9UWVBFXSA9IFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6RXJyb3JJbXBvcnQiKTsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiQ291bGQgbm90IGltcG9ydCBmcm9tICIgKyBmaWxlbmFtZS5nZXRUZXh0KCksIGUpOwoJCX0KCX0KCQoJcHJvdGVjdGVkIHZvaWQgaGFuZGxlRmlsZVNlbGVjdGlvbigpIHsKCQl2YWxpZGF0aW9uRXJyb3JzW0lOVkFMSURfSU1QT1JUXSA9IG51bGw7CgkJU3RyaW5nIHRleHQgPSBmaWxlbmFtZS5nZXRUZXh0KCk7CgkJaWYgKHRleHQgPT0gbnVsbCB8fCB0ZXh0Lmxlbmd0aCgpID09IDApCgkJCXZhbGlkYXRpb25FcnJvcnNbSU5WQUxJRF9GSUxFTkFNRV0gPSAiIjsKCQllbHNlIHsKCQkJdmFsaWRhdGlvbkVycm9yc1tJTlZBTElEX0ZJTEVOQU1FXSA9IG51bGw7CgkJCWxvYWRDb25maWd1cmF0aW9uKCk7CgkJfQoJfQoJCglwcm90ZWN0ZWQgdm9pZCBwZXJmb3JtTG9hZENvbmZpZ3VyYXRpb24oSUZpbGUgZmlsZSwgU3RyaW5nIGZpbGVuYW1lMikgewoJCXRyeSB7CgkJCXRyeSB7CgkJCQljb25maWd1cmF0aW9uID0gc2VsZWN0ZWRDb25maWdUeXBlLmltcG9ydEZyb21QYXRoKG51bGwsIGZpbGUsIG5ldyBQYXRoKGZpbGVuYW1lMiksIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwoJCQkJaWYgKGNvbmZpZ3VyYXRpb24gPT0gbnVsbCkKCQkJCQl2YWxpZGF0aW9uRXJyb3JzW0lOVkFMSURfSU1QT1JUXSA9IFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6RXJyb3JJbXBvcnQiKTsKCQkJCWVsc2UKCQkJCQl2YWxpZGF0aW9uRXJyb3JzW0lOVkFMSURfSU1QT1JUXSA9IG51bGw7CgkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJCUlTdGF0dXMgc3RhdHVzID0gY2UuZ2V0U3RhdHVzKCk7CgkJCQlpZiAoc3RhdHVzICE9IG51bGwgJiYgc3RhdHVzLmdldE1lc3NhZ2UoKSAhPSBudWxsICYmIHN0YXR1cy5nZXRNZXNzYWdlKCkubGVuZ3RoKCkgPiAxKQoJCQkJCXZhbGlkYXRpb25FcnJvcnNbSU5WQUxJRF9JTVBPUlRdID0gY2UuZ2V0U3RhdHVzKCkuZ2V0TWVzc2FnZSgpOwoJCQkJZWxzZQoJCQkJCXZhbGlkYXRpb25FcnJvcnNbSU5WQUxJRF9JTVBPUlRdID0gU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpFcnJvckltcG9ydCIpOwoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJdmFsaWRhdGlvbkVycm9yc1tJTlZBTElEX0lNUE9SVF0gPSBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpekVycm9ySW1wb3J0Iik7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNvdWxkIG5vdCBpbXBvcnQgZnJvbSAiICsgZmlsZW5hbWUsIGUpOwoJCX0KCX0qLwoJCgkvKioKCSAqIFJldHVybiB0cnVlIGlmIHRoaXMgcGFnZSBpcyBjb21wbGV0ZS4KCSAqIEByZXR1cm4gYm9vbGVhbgoJICovCgkvKnB1YmxpYyBib29sZWFuIGlzUGFnZUNvbXBsZXRlKCkgewoJCS8vIGNoZWNrIGZvciB2YWxpZGF0aW9uIGZpcnN0CgkJZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxpZGF0aW9uRXJyb3JzLmxlbmd0aDsgaSsrKSB7CgkJCWlmICh2YWxpZGF0aW9uRXJyb3JzW2ldICE9IG51bGwpCgkJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCgkJaWYgKGNvbmZpZ3VyYXRpb24gPT0gbnVsbCkKCQkJcmV0dXJuIGZhbHNlOwoJCQkKCQlpZiAodGhyZWFkICE9IG51bGwpCgkJCXJldHVybiBmYWxzZTsKCQoJCS8vIG90aGVyd2lzZSwgZGVmZXIgdG8gc3VwZXJjbGFzcwoJCXJldHVybiBzdXBlci5pc1BhZ2VDb21wbGV0ZSgpOwoJfSovCgkKCS8qKgoJICogRmluaXNoIHRoZSB3aXphcmQgYnkgc2F2aW5nIHRoZSBjb25maWd1cmF0aW9uIGludG8KCSAqIHRoZSBzZWxlY3RlZCBmb2xkZXIuCgkgKiBAcmV0dXJuIGJvb2xlYW4KCSAqLwoJcHVibGljIGJvb2xlYW4gcGVyZm9ybUZpbmlzaCgpIHsKCQlyZXR1cm4gdHJ1ZTsKCX0KCS8qCgkJaWYgKGNvbmZpZ3VyYXRpb24gPT0gbnVsbCkKCQkJcmV0dXJuIGZhbHNlOwoJCQkKCQlTZXJ2ZXJVSVByZWZlcmVuY2VzIHNwID0gKFNlcnZlclVJUHJlZmVyZW5jZXMpIFNlcnZlclVJQ29yZS5nZXRQcmVmZXJlbmNlcygpOwoJCXNwLnNldEltcG9ydExvY2F0aW9uKGZpbGVuYW1lLmdldFRleHQoKSk7CgkKCQl0cnkgewoJCQlmaW5hbCBTdHJpbmcgdGhlTmFtZSA9IG5hbWUuZ2V0VGV4dCgpOwoJCQlJV29ya3NwYWNlUnVubmFibGUgcnVubmFibGUgPSBuZXcgSVdvcmtzcGFjZVJ1bm5hYmxlKCkgewoJCQkJcHVibGljIHZvaWQgcnVuKElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCQkJCXNhdmVDb25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb24sIHRoZU5hbWUsIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwoJCQkJfQoJCQl9OwoJCQkKCQkJZ2V0V2l6YXJkKCkuZ2V0Q29udGFpbmVyKCkucnVuKHRydWUsIHRydWUsIG5ldyBXb3Jrc3BhY2VSdW5uYWJsZUFkYXB0ZXIocnVubmFibGUpKTsKCgkJCXJldHVybiB0cnVlOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIHNhdmluZyBpbXBvcnRlZCBjb25maWd1cmF0aW9uIiwgZSk7CgkJCXJldHVybiBmYWxzZTsKCQl9Cgl9Ki8KCQoJLyoqCgkgKiBTYXZlIHRoZSBlbGVtZW50IHRvIHRoZSBnaXZlbiBmaWxlIG5hbWUuCgkgKiBAcGFyYW0gZWxlbWVudCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlclJlc291cmNlCgkgKiBAcGFyYW0gbmFtZSBqYXZhLmxhbmcuU3RyaW5nCgkgKiBAcGFyYW0gb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQcm9ncmVzc01vbml0b3IgbW9uaXRvcgoJICovCgkvKnByb3RlY3RlZCB2b2lkIHNhdmVDb25maWd1cmF0aW9uKElTZXJ2ZXJDb25maWd1cmF0aW9uV29ya2luZ0NvcHkgY29uZmlnLCBTdHJpbmcgdGhlTmFtZSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJLy8gc2F2ZSB0aGUgZWxlbWVudAoJCXRyeSB7CgkJCUlGaWxlIGZpbGUgPSBjb25maWcuZ2V0RmlsZSgpOwoJCQlpZiAoZmlsZSAhPSBudWxsICYmICFmaWxlLmdldFByb2plY3QoKS5leGlzdHMoKSkgewoJCQkJSVByb2plY3QgcHJvamVjdCA9IGZpbGUuZ2V0UHJvamVjdCgpOwoJCQkJRWNsaXBzZVV0aWwuY3JlYXRlTmV3U2VydmVyUHJvamVjdChnZXRTaGVsbCgpLCBwcm9qZWN0LmdldE5hbWUoKSwgbnVsbCwgbW9uaXRvcik7CgkJCX0KCQkJY29uZmlnLnNldE5hbWUodGhlTmFtZSk7CgkJCWNvbmZpZy5zYXZlKGZhbHNlLCBtb25pdG9yKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBzYXZpbmcgY3JlYXRlZCBlbGVtZW50IiwgZSk7CgkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgU2VydmVyVUlQbHVnaW4uUExVR0lOX0lELCAwLCAiQ291bGQgbm90IGNyZWF0ZSBzZXJ2ZXIgcHJvamVjdCIsIG51bGwpKTsKCQl9Cgl9Ki8KCQoJLyoqCgkgKiBTZXRzIHRoZSBkZWZhdWx0IGNvbnRhaW5lci4KCSAqIEBwYXJhbSBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JQ29udGFpbmVyCgkgKi8KCXB1YmxpYyB2b2lkIHNldERlZmF1bHRDb250YWluZXIoSUNvbnRhaW5lciBjb250YWluZXIpIHsKCQkvL2RlZmF1bHRDb250YWluZXIgPSBjb250YWluZXI7Cgl9CgkKCS8qcHVibGljIHZvaWQgc2V0VmlzaWJsZShib29sZWFuIHZpc2libGUpIHsKCQlzdXBlci5zZXRWaXNpYmxlKHZpc2libGUpOwoJCgkJaWYgKHZpc2libGUpIHsKCQkJLy8gZm9yY2UgdGhlIGZvY3VzIHRvIGluaXRpYWxseSB2YWxpZGF0ZSB0aGUgZmllbGRzCgkJCXZhbGlkYXRlTmFtZSgpOwoJCQl2YWxpZGF0ZUZvbGRlcigpOwoJCQloYW5kbGVGYWN0b3J5U2VsZWN0aW9uKG51bGwpOwoJCQl2YWxpZGF0ZVBhZ2UoSU5WQUxJRF9OQU1FKTsKCQoJCQluYW1lLmZvcmNlRm9jdXMoKTsKCQl9Cgl9Ki8KCQoJLyoqCgkgKiBWYWxpZGF0ZXMgdGhlIGZvbGRlci4KCSAqLwoJLypwcm90ZWN0ZWQgdm9pZCB2YWxpZGF0ZUZvbGRlcigpIHsKCQlTdHJpbmcgdGV4dCA9IHNlcnZlclByb2plY3QuZ2V0VGV4dCgpOwoJCWlmICh0ZXh0ID09IG51bGwgfHwgdGV4dC5sZW5ndGgoKSA9PSAwKSB7CgkJCXZhbGlkYXRpb25FcnJvcnNbSU5WQUxJRF9GT0xERVJdID0gIiI7CgkJCXJldHVybjsKCQl9CgkKCQl2YWxpZGF0aW9uRXJyb3JzW0lOVkFMSURfRk9MREVSXSA9IFdpemFyZFV0aWwudmFsaWRhdGVDb250YWluZXIodGV4dCk7Cgl9Ki8KCQoJLyoqCgkgKiBWYWxpZGF0ZXMgdGhlIG5hbWUuCgkgKi8KCS8qcHJvdGVjdGVkIHZvaWQgdmFsaWRhdGVOYW1lKCkgewoJCVN0cmluZyB0ZXh0ID0gbmFtZS5nZXRUZXh0KCk7CgkJaWYgKHRleHQgPT0gbnVsbCB8fCB0ZXh0Lmxlbmd0aCgpID09IDApIHsKCQkJdmFsaWRhdGlvbkVycm9yc1tJTlZBTElEX05BTUVdID0gIiI7CgkJCXJldHVybjsKCQl9CgkKCQlJU3RhdHVzIHN0YXR1cyA9IFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS52YWxpZGF0ZU5hbWUodGV4dCwgSVJlc291cmNlLkZJTEUpOwoJCWlmIChzdGF0dXMuaXNPSygpKQoJCQlzdGF0dXMgPSBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkudmFsaWRhdGVOYW1lKHRleHQsIElSZXNvdXJjZS5GT0xERVIpOwoJCQoJCWlmICghc3RhdHVzLmlzT0soKSkKCQkJdmFsaWRhdGlvbkVycm9yc1tJTlZBTElEX05BTUVdID0gc3RhdHVzLmdldE1lc3NhZ2UoKTsKCQllbHNlIHsKCQkJLy8gY2hlY2sgaWYgZmlsZSBleGlzdHMKCQkJU3RyaW5nIGZpbGVOYW1lID0gdGV4dDsKCQkJaWYgKHNlbGVjdGVkQ29uZmlnVHlwZSAhPSBudWxsKSB7CgkJCQlTdHJpbmcgZXh0ID0gSVNlcnZlckNvbmZpZ3VyYXRpb24uRklMRV9FWFRFTlNJT047CgkJCQlpZiAoZXh0ICE9IG51bGwgJiYgIWZpbGVOYW1lLmVuZHNXaXRoKCIuIiArIGV4dCkpCgkJCQkJZmlsZU5hbWUgKz0gIi4iICsgZXh0OwoJCQl9CgkJCgkJCUlDb250YWluZXIgY29udGFpbmVyID0gV2l6YXJkVXRpbC5maW5kQ29udGFpbmVyKHNlcnZlclByb2plY3QuZ2V0VGV4dCgpKTsKCQkJaWYgKGNvbnRhaW5lciAhPSBudWxsICYmIGNvbnRhaW5lci5nZXRMb2NhdGlvbigpLmFwcGVuZChmaWxlTmFtZSkudG9GaWxlKCkuZXhpc3RzKCkpIHsKCQkJCXZhbGlkYXRpb25FcnJvcnNbSU5WQUxJRF9OQU1FXSA9IFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6RXJyb3JSZXNvdXJjZUFscmVhZHlFeGlzdHMiKTsKCQkJfSBlbHNlCgkJCQl2YWxpZGF0aW9uRXJyb3JzW0lOVkFMSURfTkFNRV0gPSBudWxsOwoJCX0KCX0qLwoJCgkvKioKCSAqIERpc3BsYXkgdGhlIGNvcnJlY3QgZXJyb3IgbWVzc2FnZSBhbmQgZW5hYmxlL2Rpc2FibGUKCSAqIHRoZSBGaW5pc2ggb3IgTmV4dCBidXR0b24uCgkgKiBAcGFyYW0geCB0aGUgY3VycmVudCBjb250cm9sIChlcnJvciBtZXNzYWdlIGdldHMgcHJlY2VkZW5jZSkKCSAqLwoJLypwcm90ZWN0ZWQgdm9pZCB2YWxpZGF0ZVBhZ2UoaW50IHgpIHsKCQlpZiAoeCA+PSAwICYmIHZhbGlkYXRpb25FcnJvcnNbeF0gIT0gbnVsbCAmJiB2YWxpZGF0aW9uRXJyb3JzW3hdLmxlbmd0aCgpID4gMCkgewoJCQlzZXRFcnJvck1lc3NhZ2UodmFsaWRhdGlvbkVycm9yc1t4XSk7CgkJCWdldENvbnRhaW5lcigpLnVwZGF0ZUJ1dHRvbnMoKTsKCQkJcmV0dXJuOwoJCX0KCQlpbnQgc2l6ZSA9IHZhbGlkYXRpb25FcnJvcnMubGVuZ3RoOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCWlmICh2YWxpZGF0aW9uRXJyb3JzW2ldICE9IG51bGwgJiYgdmFsaWRhdGlvbkVycm9yc1tpXS5sZW5ndGgoKSA+IDApIHsKCQkJCXNldEVycm9yTWVzc2FnZSh2YWxpZGF0aW9uRXJyb3JzW2ldKTsKCQkJCWdldENvbnRhaW5lcigpLnVwZGF0ZUJ1dHRvbnMoKTsKCQkJCXJldHVybjsKCQkJfQoJCX0KCQlzZXRFcnJvck1lc3NhZ2UobnVsbCk7CgkJZ2V0Q29udGFpbmVyKCkudXBkYXRlQnV0dG9ucygpOwoJfSovCn0=