cGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMgSUJNIENvcnBvcmF0aW9uIGFuZCBvdGhlcnMuCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIKAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuQ29yZUV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5EaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLklEaWFsb2dDb25zdGFudHM7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLlByb2dyZXNzTW9uaXRvckRpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkTGF5b3V0OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQnV0dG9uOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29udHJvbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuU2hlbGw7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5hY3Rpb25zLldvcmtzcGFjZU1vZGlmeU9wZXJhdGlvbjsKCmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSUVsZW1lbnQ7Ci8qKgogKiBEaWFsb2cgdGhhdCBwcm9tcHRzIGEgdXNlciB0byBkZWxldGUgc2VydmVyKHMpIGFuZC9vciBzZXJ2ZXIgY29uZmlndXJhdGlvbihzKS4KICovCnB1YmxpYyBjbGFzcyBEZWxldGVTZXJ2ZXJEaWFsb2cgZXh0ZW5kcyBEaWFsb2cgewoJcHJvdGVjdGVkIExpc3QgZGVsZXRlTGlzdDsKCXByb3RlY3RlZCBMaXN0IGNvbmZpZ0xpc3Q7CgoJcHJvdGVjdGVkIEJ1dHRvbiBjaGVjazsKCgkvKioKCSAqIERlbGV0ZVNlcnZlckRpYWxvZyBjb25zdHJ1Y3RvciBjb21tZW50LgoJICogQHBhcmFtIHBhcmVudFNoZWxsIG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlNoZWxsCgkgKiBACgkgKi8KCXB1YmxpYyBEZWxldGVTZXJ2ZXJEaWFsb2coU2hlbGwgcGFyZW50U2hlbGwsIExpc3QgZGVsZXRlTGlzdCwgTGlzdCBjb25maWdMaXN0KSB7CgkJc3VwZXIocGFyZW50U2hlbGwpOwoJCQoJCWlmIChkZWxldGVMaXN0ID09IG51bGwpCgkJCWRlbGV0ZUxpc3QgPSBuZXcgQXJyYXlMaXN0KDApOwoJCWlmIChjb25maWdMaXN0ID09IG51bGwpCgkJCWNvbmZpZ0xpc3QgPSBuZXcgQXJyYXlMaXN0KDApOwoJCQoJCXRoaXMuZGVsZXRlTGlzdCA9IGRlbGV0ZUxpc3Q7CgkJdGhpcy5jb25maWdMaXN0ID0gY29uZmlnTGlzdDsKCgkJc2V0QmxvY2tPbk9wZW4odHJ1ZSk7Cgl9CgoJLyoqCgkgKgoJICovCglwcm90ZWN0ZWQgdm9pZCBjb25maWd1cmVTaGVsbChTaGVsbCBuZXdTaGVsbCkgewoJCXN1cGVyLmNvbmZpZ3VyZVNoZWxsKG5ld1NoZWxsKTsKCQluZXdTaGVsbC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlZGVsZXRlU2VydmVyUmVzb3VyY2VEaWFsb2dUaXRsZSIpKTsKCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgQ29udHJvbCBjcmVhdGVEaWFsb2dBcmVhKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQkvLyBjcmVhdGUgYSBjb21wb3NpdGUgd2l0aCBzdGFuZGFyZCBtYXJnaW5zIGFuZCBzcGFjaW5nCgkJQ29tcG9zaXRlIGNvbXBvc2l0ZSA9IG5ldyBDb21wb3NpdGUocGFyZW50LCBTV1QuTk9ORSk7CgkJR3JpZExheW91dCBsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5tYXJnaW5IZWlnaHQgPSBjb252ZXJ0VmVydGljYWxETFVzVG9QaXhlbHMoSURpYWxvZ0NvbnN0YW50cy5WRVJUSUNBTF9NQVJHSU4pOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IGNvbnZlcnRIb3Jpem9udGFsRExVc1RvUGl4ZWxzKElEaWFsb2dDb25zdGFudHMuSE9SSVpPTlRBTF9NQVJHSU4pOwoJCWxheW91dC52ZXJ0aWNhbFNwYWNpbmcgPSBjb252ZXJ0VmVydGljYWxETFVzVG9QaXhlbHMoSURpYWxvZ0NvbnN0YW50cy5WRVJUSUNBTF9TUEFDSU5HKTsKCQlsYXlvdXQuaG9yaXpvbnRhbFNwYWNpbmcgPSBjb252ZXJ0SG9yaXpvbnRhbERMVXNUb1BpeGVscyhJRGlhbG9nQ29uc3RhbnRzLkhPUklaT05UQUxfU1BBQ0lORyk7CgkJY29tcG9zaXRlLnNldExheW91dChsYXlvdXQpOwoJCWNvbXBvc2l0ZS5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0JPVEgpKTsKCQljb21wb3NpdGUuc2V0Rm9udChwYXJlbnQuZ2V0Rm9udCgpKTsKCQkvL1dvcmtiZW5jaEhlbHAuc2V0SGVscChjb21wb3NpdGUsIENvbnRleHRJZHMuVEVSTUlOQVRFX1NFUlZFUl9ESUFMT0cpOwoJCgkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoY29tcG9zaXRlLCBTV1QuTk9ORSk7CgkJaWYgKGRlbGV0ZUxpc3Quc2l6ZSgpID09IDEpIHsKCQkJSUVsZW1lbnQgZWxlbWVudCA9IChJRWxlbWVudCkgZGVsZXRlTGlzdC5nZXQoMCk7CgkJCWxhYmVsLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVkZWxldGVTZXJ2ZXJSZXNvdXJjZURpYWxvZ01lc3NhZ2UiLCBlbGVtZW50LmdldE5hbWUoKSkpOwoJCX0gZWxzZQoJCQlsYWJlbC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlZGVsZXRlU2VydmVyUmVzb3VyY2VEaWFsb2dNZXNzYWdlTWFueSIsIGRlbGV0ZUxpc3Quc2l6ZSgpICsgIiIpKTsKCQlsYWJlbC5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YSgpKTsKCQkKCQlpZiAoIWNvbmZpZ0xpc3QuaXNFbXB0eSgpKSB7CgkJCWNoZWNrID0gbmV3IEJ1dHRvbihjb21wb3NpdGUsIFNXVC5DSEVDSyk7CgkJCgkJCWlmIChjb25maWdMaXN0LnNpemUoKSA9PSAxKSB7CgkJCQlJRWxlbWVudCBlbGVtZW50ID0gKElFbGVtZW50KSBjb25maWdMaXN0LmdldCgwKTsKCQkJCWNoZWNrLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVkZWxldGVTZXJ2ZXJSZXNvdXJjZURpYWxvZ0xvb3NlQ29uZmlndXJhdGlvbnMiLCBlbGVtZW50LmdldE5hbWUoKSkpOwoJCQl9IGVsc2UKCQkJCWNoZWNrLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVkZWxldGVTZXJ2ZXJSZXNvdXJjZURpYWxvZ0xvb3NlQ29uZmlndXJhdGlvbnNNYW55IiwgY29uZmlnTGlzdC5zaXplKCkgKyAiIikpOwoJCQljaGVjay5zZXRTZWxlY3Rpb24odHJ1ZSk7CgkJCWNoZWNrLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKCkpOwoJCX0KCQkKCQlEaWFsb2cuYXBwbHlEaWFsb2dGb250KGNvbXBvc2l0ZSk7CgkKCQlyZXR1cm4gY29tcG9zaXRlOwoJfQoKCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQlmaW5hbCBib29sZWFuIGNoZWNrZWQgPSAoY2hlY2sgIT0gbnVsbCAmJiBjaGVjay5nZXRTZWxlY3Rpb24oKSk7CgkJCgkJdHJ5IHsKCQkJV29ya3NwYWNlTW9kaWZ5T3BlcmF0aW9uIG9wID0gbmV3IFdvcmtzcGFjZU1vZGlmeU9wZXJhdGlvbigpIHsKCQkJCXByb3RlY3RlZCB2b2lkIGV4ZWN1dGUoSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJCQkJdHJ5IHsKCQkJCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBkZWxldGVMaXN0Lml0ZXJhdG9yKCk7CgkJCQkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCQkJCUlFbGVtZW50IGVsZW1lbnQgPSAoSUVsZW1lbnQpIGl0ZXJhdG9yLm5leHQoKTsKCQkJCQkJCWVsZW1lbnQuZGVsZXRlKCk7CgkJCQkJCX0KCQkJCQkJCgkJCQkJCWlmIChjaGVja2VkKSB7CgkJCQkJCQlpdGVyYXRvciA9IGNvbmZpZ0xpc3QuaXRlcmF0b3IoKTsKCQkJCQkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCQkJCQlJRWxlbWVudCBlbGVtZW50ID0gKElFbGVtZW50KSBpdGVyYXRvci5uZXh0KCk7CgkJCQkJCQkJZWxlbWVudC5kZWxldGUoKTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIHdoaWxlIGRlbGV0aW5nIHJlc291cmNlcyIsIGUpOwoJCQkJCX0KCQkJCX0KCQkJfTsKCQkJbmV3IFByb2dyZXNzTW9uaXRvckRpYWxvZyhnZXRTaGVsbCgpKS5ydW4odHJ1ZSwgdHJ1ZSwgb3ApOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIGRlbGV0aW5nIHJlc291cmNlcyIsIGUpOwoJCX0KCQkKCQlzdXBlci5va1ByZXNzZWQoKTsKCX0KfQ==