LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbDsKCmltcG9ydCBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlTGlzdGVuZXI7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZpbGU7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRm9sZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVByb2plY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2U7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JbnRlcm5hbEluaXRpYWxpemVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLlNlcnZlckRlbGVnYXRlOwovKioKICogCiAqLwpwdWJsaWMgY2xhc3MgU2VydmVyV29ya2luZ0NvcHkgZXh0ZW5kcyBTZXJ2ZXIgaW1wbGVtZW50cyBJU2VydmVyV29ya2luZ0NvcHkgewoJcHJvdGVjdGVkIFNlcnZlciBzZXJ2ZXI7Cglwcm90ZWN0ZWQgV29ya2luZ0NvcHlIZWxwZXIgd2NoOwoJCglwcm90ZWN0ZWQgU2VydmVyRGVsZWdhdGUgd29ya2luZ0NvcHlEZWxlZ2F0ZTsKCQoJLy8gd29ya2luZyBjb3B5CglwdWJsaWMgU2VydmVyV29ya2luZ0NvcHkoU2VydmVyIHNlcnZlcikgewoJCXN1cGVyKHNlcnZlci5nZXRGaWxlKCkpOwoJCXRoaXMuc2VydmVyID0gc2VydmVyOwoJCQoJCW1hcCA9IG5ldyBIYXNoTWFwKHNlcnZlci5tYXApOwoJCXdjaCA9IG5ldyBXb3JraW5nQ29weUhlbHBlcih0aGlzKTsKCQkKCQlyZXNvbHZlKCk7Cgl9CgkKCS8vIGNyZWF0aW9uCglwdWJsaWMgU2VydmVyV29ya2luZ0NvcHkoU3RyaW5nIGlkLCBJRmlsZSBmaWxlLCBJUnVudGltZSBydW50aW1lLCBJU2VydmVyVHlwZSBzZXJ2ZXJUeXBlKSB7CgkJc3VwZXIoaWQsIGZpbGUsIHJ1bnRpbWUsIHNlcnZlclR5cGUpOwoJCS8vc2VydmVyID0gdGhpczsKCQl3Y2ggPSBuZXcgV29ya2luZ0NvcHlIZWxwZXIodGhpcyk7CgkJd2NoLnNldERpcnR5KHRydWUpOwoJCXNlcnZlclN0YXRlID0gKChTZXJ2ZXJUeXBlKXNlcnZlclR5cGUpLmdldEluaXRpYWxTdGF0ZSgpOwoJfQoKCXB1YmxpYyBib29sZWFuIGlzV29ya2luZ0NvcHkoKSB7CgkJcmV0dXJuIHRydWU7Cgl9CgkKCXB1YmxpYyBJU2VydmVyIGdldE9yaWdpbmFsKCkgewoJCXJldHVybiBzZXJ2ZXI7Cgl9CgkKCXB1YmxpYyBJU2VydmVyV29ya2luZ0NvcHkgY3JlYXRlV29ya2luZ0NvcHkoKSB7CgkJcmV0dXJuIHRoaXM7Cgl9CgoJcHVibGljIGludCBnZXRTZXJ2ZXJTdGF0ZSgpIHsKCQlpZiAoc2VydmVyICE9IG51bGwpCgkJCXJldHVybiBzZXJ2ZXIuZ2V0U2VydmVyU3RhdGUoKTsKCQlyZXR1cm4gc2VydmVyU3RhdGU7Cgl9CgoJcHVibGljIHZvaWQgc2V0U2VydmVyU3RhdGUoaW50IHN0YXRlKSB7CgkJaWYgKHNlcnZlciAhPSBudWxsKQoJCQlzZXJ2ZXIuc2V0U2VydmVyU3RhdGUoc3RhdGUpOwoJCWVsc2UKCQkJc3VwZXIuc2V0U2VydmVyU3RhdGUoc3RhdGUpOwoJfQoJCglwdWJsaWMgaW50IGdldFNlcnZlclB1Ymxpc2hTdGF0ZSgpIHsKCQlpZiAoc2VydmVyICE9IG51bGwpCgkJCXJldHVybiBzZXJ2ZXIuZ2V0U2VydmVyUHVibGlzaFN0YXRlKCk7CgkJcmV0dXJuIHNlcnZlclN0YXRlOwoJfQoKCXB1YmxpYyB2b2lkIHNldFNlcnZlclB1Ymxpc2hTdGF0ZShpbnQgc3RhdGUpIHsKCQlpZiAoc2VydmVyICE9IG51bGwpCgkJCXNlcnZlci5zZXRTZXJ2ZXJQdWJsaXNoU3RhdGUoc3RhdGUpOwoJCWVsc2UKCQkJc3VwZXIuc2V0U2VydmVyUHVibGlzaFN0YXRlKHN0YXRlKTsKCX0KCQoJcHVibGljIFN0cmluZyBnZXRNb2RlKCkgewoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkKCQkJcmV0dXJuIHNlcnZlci5nZXRNb2RlKCk7CgkJcmV0dXJuIG1vZGU7Cgl9CgoJcHVibGljIHZvaWQgc2V0TW9kZShTdHJpbmcgbW9kZSkgewoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkKCQkJc2VydmVyLnNldE1vZGUobW9kZSk7CgkJZWxzZQoJCQlzdXBlci5zZXRNb2RlKG1vZGUpOwoJfQoKCXB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgYXR0cmlidXRlTmFtZSwgaW50IHZhbHVlKSB7CgkJd2NoLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCB2YWx1ZSk7Cgl9CgoJcHVibGljIHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBhdHRyaWJ1dGVOYW1lLCBib29sZWFuIHZhbHVlKSB7CgkJd2NoLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCB2YWx1ZSk7Cgl9CgoJcHVibGljIHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBhdHRyaWJ1dGVOYW1lLCBTdHJpbmcgdmFsdWUpIHsKCQl3Y2guc2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUsIHZhbHVlKTsKCX0KCglwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIGF0dHJpYnV0ZU5hbWUsIExpc3QgdmFsdWUpIHsKCQl3Y2guc2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUsIHZhbHVlKTsKCX0KCglwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIGF0dHJpYnV0ZU5hbWUsIE1hcCB2YWx1ZSkgewoJCXdjaC5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSwgdmFsdWUpOwoJfQoKCS8qIChub24tSmF2YWRvYykKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJXb3JraW5nQ29weSNzZXROYW1lKGphdmEubGFuZy5TdHJpbmcpCgkgKi8KCXB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUF9OQU1FLCBuYW1lKTsKCX0KCglwdWJsaWMgdm9pZCBzZXRSZWFkT25seShib29sZWFuIGIpIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUF9MT0NLRUQsIGIpOwoJfQoKCS8qKgoJICogU2V0cyB3aGV0aGVyIHRoaXMgZWxlbWVudCBpcyBwcml2YXRlLgoJICogR2VuZXJhbGx5IHNwZWFraW5nLCBlbGVtZW50cyBtYXJrZWQgcHJpdmF0ZSBhcmUgaW50ZXJuYWwgb25lcwoJICogdGhhdCBzaG91bGQgbm90IGJlIHNob3duIHRvIHVzZXJzIChiZWNhdXNlIHRoZXkgd29uJ3Qga25vdwoJICogYW55dGhpbmcgYWJvdXQgdGhlbSkuCgkgKiAKCSAqIEBwYXJhbSBiIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoaXMgZWxlbWVudCBpcyBwcml2YXRlLAoJICogYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UKCSAqIEBzZWUgI2lzUHJpdmF0ZSgpCgkgKi8KCXB1YmxpYyB2b2lkIHNldFByaXZhdGUoYm9vbGVhbiBiKSB7CgkJc2V0QXR0cmlidXRlKFBST1BfUFJJVkFURSwgYik7Cgl9CgoJcHVibGljIHZvaWQgc2V0SG9zdChTdHJpbmcgaG9zdCkgewoJCXNldEF0dHJpYnV0ZShQUk9QX0hPU1ROQU1FLCBob3N0KTsKCX0KCglwdWJsaWMgdm9pZCBzZXRBdXRvUHVibGlzaFRpbWUoaW50IHApIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUF9BVVRPX1BVQkxJU0hfVElNRSwgcCk7Cgl9CgkKCXB1YmxpYyB2b2lkIHNldEF1dG9QdWJsaXNoRGVmYXVsdChib29sZWFuIHApIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUF9BVVRPX1BVQkxJU0hfREVGQVVMVCwgcCk7Cgl9CgoJcHVibGljIHZvaWQgc2V0U2VydmVyQ29uZmlndXJhdGlvbihJRm9sZGVyIGNvbmZpZykgewoJCXRoaXMuY29uZmlndXJhdGlvbiA9IGNvbmZpZzsKCQlpZiAoY29uZmlndXJhdGlvbiA9PSBudWxsKQoJCQlzZXRBdHRyaWJ1dGUoQ09ORklHVVJBVElPTl9JRCwgKFN0cmluZyludWxsKTsKCQllbHNlCgkJCXNldEF0dHJpYnV0ZShDT05GSUdVUkFUSU9OX0lELCBjb25maWd1cmF0aW9uLmdldEZ1bGxQYXRoKCkudG9TdHJpbmcoKSk7Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSBmaWxlIHdoZXJlIHRoaXMgc2VydmVyIGluc3RhbmNlIGlzIHNlcmlhbGl6ZWQuCgkgKiAKCSAqIEBwYXJhbSBmaWxlIHRoZSBmaWxlIGluIHRoZSB3b3Jrc3BhY2Ugd2hlcmUgdGhlIHNlcnZlciBpbnN0YW5jZQoJICogICAgaXMgc2VyaWFsaXplZCwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGluZm9ybWF0aW9uIGlzCgkgKiAgICBpbnN0ZWFkIHRvIGJlIHBlcnNpc3RlZCB3aXRoIHRoZSB3b3Jrc3BhY2UgYnV0IG5vdCB3aXRoIGFueQoJICogICAgcGFydGljdWxhciB3b3Jrc3BhY2UgcmVzb3VyY2UKCSAqLwoJcHVibGljIHZvaWQgc2V0RmlsZShJRmlsZSBmaWxlKSB7CgkJdGhpcy5maWxlID0gZmlsZTsKCX0KCgkvKiAobm9uLUphdmFkb2MpCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyV29ya2luZ0NvcHkjaXNEaXJ0eSgpCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzRGlydHkoKSB7CgkJcmV0dXJuIHdjaC5pc0RpcnR5KCk7Cgl9CgkKCXB1YmxpYyBTZXJ2ZXJEZWxlZ2F0ZSBnZXRXb3JraW5nQ29weURlbGVnYXRlKElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCS8vIG1ha2Ugc3VyZSB0aGF0IHRoZSByZWd1bGFyIGRlbGVnYXRlIGlzIGxvYWRlZCAKCQkvL2dldERlbGVnYXRlKCk7CgkJCgkJaWYgKHdvcmtpbmdDb3B5RGVsZWdhdGUgIT0gbnVsbCB8fCBzZXJ2ZXJUeXBlID09IG51bGwpCgkJCXJldHVybiB3b3JraW5nQ29weURlbGVnYXRlOwoJCQoJCXN5bmNocm9uaXplZCAodGhpcykgewoJCQlpZiAod29ya2luZ0NvcHlEZWxlZ2F0ZSA9PSBudWxsKSB7CgkJCQl0cnkgewoJCQkJCWxvbmcgdGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwoJCQkJCUlDb25maWd1cmF0aW9uRWxlbWVudCBlbGVtZW50ID0gKChTZXJ2ZXJUeXBlKSBzZXJ2ZXJUeXBlKS5nZXRFbGVtZW50KCk7CgkJCQkJd29ya2luZ0NvcHlEZWxlZ2F0ZSA9IChTZXJ2ZXJEZWxlZ2F0ZSkgZWxlbWVudC5jcmVhdGVFeGVjdXRhYmxlRXh0ZW5zaW9uKCJjbGFzcyIpOwoJCQkJCUludGVybmFsSW5pdGlhbGl6ZXIuaW5pdGlhbGl6ZVNlcnZlckRlbGVnYXRlKHdvcmtpbmdDb3B5RGVsZWdhdGUsIHRoaXMsIG1vbml0b3IpOwoJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlBFUkZPUk1BTkNFLCAiU2VydmVyV29ya2luZ0NvcHkuZ2V0V29ya2luZ0NvcHlEZWxlZ2F0ZSgpOiA8IiArIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHRpbWUpICsgIj4gIiArIGdldFNlcnZlclR5cGUoKS5nZXRJZCgpKTsKCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiQ291bGQgbm90IGNyZWF0ZSBkZWxlZ2F0ZSAiICsgdG9TdHJpbmcoKSwgZSk7CgkJCQl9CgkJCX0KCQl9CgkJcmV0dXJuIHdvcmtpbmdDb3B5RGVsZWdhdGU7Cgl9CgkKCXB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CgkJc3VwZXIuZGlzcG9zZSgpOwoJCWlmICh3b3JraW5nQ29weURlbGVnYXRlICE9IG51bGwpCgkJCXdvcmtpbmdDb3B5RGVsZWdhdGUuZGlzcG9zZSgpOwoJfQoJCglwdWJsaWMgSVNlcnZlciBzYXZlKGJvb2xlYW4gZm9yY2UsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCW1vbml0b3IgPSBQcm9ncmVzc1V0aWwuZ2V0TW9uaXRvckZvcihtb25pdG9yKTsKCQltb25pdG9yLnN1YlRhc2soTkxTLmJpbmQoTWVzc2FnZXMuc2F2aW5nVGFzaywgZ2V0TmFtZSgpKSk7CgoJCWlmICghZm9yY2UgJiYgZ2V0T3JpZ2luYWwoKSAhPSBudWxsKQoJCQl3Y2gudmFsaWRhdGVUaW1lc3RhbXAoKChTZXJ2ZXIpZ2V0T3JpZ2luYWwoKSkuZ2V0VGltZXN0YW1wKCkpOwoKCQlpZiAoc2VydmVyID09IG51bGwpIHsKCQkJc2VydmVyID0gbmV3IFNlcnZlcihmaWxlKTsKCQkJc2VydmVyLnNldFNlcnZlclN0YXRlKHNlcnZlclN0YXRlKTsKCQkJc2VydmVyLnB1Ymxpc2hMaXN0ZW5lcnMgPSBwdWJsaXNoTGlzdGVuZXJzOwoJCQlzZXJ2ZXIubm90aWZpY2F0aW9uTWFuYWdlciA9IG5vdGlmaWNhdGlvbk1hbmFnZXI7CgkJfQoJCQoJCWlmIChnZXRTZXJ2ZXJUeXBlKCkuaGFzU2VydmVyQ29uZmlndXJhdGlvbigpKSB7CgkJCUlGb2xkZXIgZm9sZGVyID0gZ2V0U2VydmVyQ29uZmlndXJhdGlvbigpOwoJCQlpZiAoZm9sZGVyID09IG51bGwpIHsKCQkJCWZvbGRlciA9IFNlcnZlclR5cGUuZ2V0U2VydmVyUHJvamVjdCgpLmdldEZvbGRlcihnZXROYW1lKCkgKyAiLWNvbmZpZyIpOwoJCQkJaWYgKCFmb2xkZXIuZXhpc3RzKCkpCgkJCQkJZm9sZGVyLmNyZWF0ZSh0cnVlLCB0cnVlLCBudWxsKTsKCQkJCXNldFNlcnZlckNvbmZpZ3VyYXRpb24oZm9sZGVyKTsKCQkJfQoJCX0KCQkKCQlzZXJ2ZXIuc2V0SW50ZXJuYWwodGhpcyk7CgkJc2VydmVyLmRvU2F2ZShtb25pdG9yKTsKCQlpZiAoZ2V0U2VydmVyVHlwZSgpLmhhc1NlcnZlckNvbmZpZ3VyYXRpb24oKSkgewoJCQlJRm9sZGVyIGZvbGRlciA9IGdldFNlcnZlckNvbmZpZ3VyYXRpb24oKTsKCQkJaWYgKGZvbGRlciAhPSBudWxsKSB7CgkJCQlJUHJvamVjdCBwcm9qZWN0ID0gZm9sZGVyLmdldFByb2plY3QoKTsKCQkJCWlmIChwcm9qZWN0ICE9IG51bGwgJiYgIXByb2plY3QuZXhpc3RzKCkpIHsKCQkJCQlwcm9qZWN0LmNyZWF0ZShudWxsKTsKCQkJCQlwcm9qZWN0Lm9wZW4obnVsbCk7CgkJCQkJKChQcm9qZWN0UHJvcGVydGllcylTZXJ2ZXJDb3JlLmdldFByb2plY3RQcm9wZXJ0aWVzKHByb2plY3QpKS5zZXRTZXJ2ZXJQcm9qZWN0KHRydWUsIG1vbml0b3IpOwoJCQkJfQoJCQkJaWYgKCFmb2xkZXIuZXhpc3RzKCkpCgkJCQkJZm9sZGVyLmNyZWF0ZShJUmVzb3VyY2UuRk9SQ0UsIHRydWUsIG51bGwpOwoJCQl9CgkJfQoJCWdldERlbGVnYXRlKG1vbml0b3IpLnNhdmVDb25maWd1cmF0aW9uKG1vbml0b3IpOwoJCXdjaC5zZXREaXJ0eShmYWxzZSk7CgkJCgkJcmV0dXJuIHNlcnZlcjsKCX0KCglwdWJsaWMgSVNlcnZlciBzYXZlQWxsKGJvb2xlYW4gZm9yY2UsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCWlmIChydW50aW1lICE9IG51bGwgJiYgcnVudGltZS5pc1dvcmtpbmdDb3B5KCkpIHsKCQkJSVJ1bnRpbWVXb3JraW5nQ29weSB3YyA9IChJUnVudGltZVdvcmtpbmdDb3B5KSBydW50aW1lOwoJCQl3Yy5zYXZlKGZvcmNlLCBtb25pdG9yKTsKCQl9CgkJCgkJcmV0dXJuIHNhdmUoZm9yY2UsIG1vbml0b3IpOwoJfQoKCS8qKgoJICogQWRkIGEgcHJvcGVydHkgY2hhbmdlIGxpc3RlbmVyIHRvIHRoaXMgc2VydmVyLgoJICoKCSAqIEBwYXJhbSBsaXN0ZW5lciBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlTGlzdGVuZXIKCSAqLwoJcHVibGljIHZvaWQgYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJaWYgKGxpc3RlbmVyID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkxpc3RlbmVyIGNhbm5vdCBiZSBudWxsIik7CgkJd2NoLmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIobGlzdGVuZXIpOwoJfQoJCgkvKioKCSAqIFJlbW92ZSBhIHByb3BlcnR5IGNoYW5nZSBsaXN0ZW5lciBmcm9tIHRoaXMgc2VydmVyLgoJICoKCSAqIEBwYXJhbSBsaXN0ZW5lciBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlTGlzdGVuZXIKCSAqLwoJcHVibGljIHZvaWQgcmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJaWYgKGxpc3RlbmVyID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkxpc3RlbmVyIGNhbm5vdCBiZSBudWxsIik7CgkJd2NoLnJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIobGlzdGVuZXIpOwoJfQoJCgkvKioKCSAqIEZpcmUgYSBwcm9wZXJ0eSBjaGFuZ2UgZXZlbnQuCgkgKiAKCSAqIEBwYXJhbSBwcm9wZXJ0eU5hbWUgYSBwcm9wZXJ0eSBuYW1lCgkgKiBAcGFyYW0gb2xkVmFsdWUgdGhlIG9sZCB2YWx1ZQoJICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKCSAqLwoJcHVibGljIHZvaWQgZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQoU3RyaW5nIHByb3BlcnR5TmFtZSwgT2JqZWN0IG9sZFZhbHVlLCBPYmplY3QgbmV3VmFsdWUpIHsKCQl3Y2guZmlyZVByb3BlcnR5Q2hhbmdlRXZlbnQocHJvcGVydHlOYW1lLCBvbGRWYWx1ZSwgbmV3VmFsdWUpOwoJfQoJCglwdWJsaWMgdm9pZCBhZGRTZXJ2ZXJMaXN0ZW5lcihJU2VydmVyTGlzdGVuZXIgbGlzdGVuZXIpIHsKCQlpZiAoc2VydmVyICE9IG51bGwpCgkJCXNlcnZlci5hZGRTZXJ2ZXJMaXN0ZW5lcihsaXN0ZW5lcik7CgkJZWxzZQoJCQlzdXBlci5hZGRTZXJ2ZXJMaXN0ZW5lcihsaXN0ZW5lcik7Cgl9CgkKCXB1YmxpYyB2b2lkIHJlbW92ZVNlcnZlckxpc3RlbmVyKElTZXJ2ZXJMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkKCQkJc2VydmVyLnJlbW92ZVNlcnZlckxpc3RlbmVyKGxpc3RlbmVyKTsKCQllbHNlCgkJCXN1cGVyLnJlbW92ZVNlcnZlckxpc3RlbmVyKGxpc3RlbmVyKTsKCX0KCQoJcHVibGljIHZvaWQgYWRkUHVibGlzaExpc3RlbmVyKElQdWJsaXNoTGlzdGVuZXIgbGlzdGVuZXIpIHsKCQlpZiAoc2VydmVyICE9IG51bGwpCgkJCXNlcnZlci5hZGRQdWJsaXNoTGlzdGVuZXIobGlzdGVuZXIpOwoJCWVsc2UKCQkJc3VwZXIuYWRkUHVibGlzaExpc3RlbmVyKGxpc3RlbmVyKTsKCX0KCQoJcHVibGljIHZvaWQgcmVtb3ZlUHVibGlzaExpc3RlbmVyKElQdWJsaXNoTGlzdGVuZXIgbGlzdGVuZXIpIHsKCQlpZiAoc2VydmVyICE9IG51bGwpCgkJCXNlcnZlci5yZW1vdmVQdWJsaXNoTGlzdGVuZXIobGlzdGVuZXIpOwoJCWVsc2UKCQkJc3VwZXIucmVtb3ZlUHVibGlzaExpc3RlbmVyKGxpc3RlbmVyKTsKCX0KCglwdWJsaWMgdm9pZCBzZXRSdW50aW1lKElSdW50aW1lIHJ1bnRpbWUpIHsKCQl0aGlzLnJ1bnRpbWUgPSBydW50aW1lOwoJCWlmIChydW50aW1lICE9IG51bGwpCgkJCXNldEF0dHJpYnV0ZShSVU5USU1FX0lELCBydW50aW1lLmdldElkKCkpOwoJCWVsc2UKCQkJc2V0QXR0cmlidXRlKFJVTlRJTUVfSUQsIChTdHJpbmcpbnVsbCk7Cgl9CgkKCXB1YmxpYyB2b2lkIHNldFJ1bnRpbWVJZChTdHJpbmcgcnVudGltZUlkKSB7CgkJc2V0QXR0cmlidXRlKFJVTlRJTUVfSUQsIHJ1bnRpbWVJZCk7CgkJcmVzb2x2ZSgpOwoJfQoKCS8qIChub24tSmF2YWRvYykKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXIjbW9kaWZ5TW9kdWxlKG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlKQoJICovCglwdWJsaWMgdm9pZCBtb2RpZnlNb2R1bGVzKElNb2R1bGVbXSBhZGQsIElNb2R1bGVbXSByZW1vdmUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCWlmIChhZGQgPT0gbnVsbCAmJiByZW1vdmUgPT0gbnVsbCkKCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQWRkIGFuZCByZW1vdmUgY2Fubm90IGJvdGggYmUgbnVsbCIpOwoJCXRyeSB7CgkJCW1vbml0b3IgPSBQcm9ncmVzc1V0aWwuZ2V0TW9uaXRvckZvcihtb25pdG9yKTsKCQkJbW9uaXRvci5zdWJUYXNrKE1lc3NhZ2VzLnRhc2tNb2RpZnlNb2R1bGVzKTsKCQkJZ2V0V29ya2luZ0NvcHlEZWxlZ2F0ZShtb25pdG9yKS5tb2RpZnlNb2R1bGVzKGFkZCwgcmVtb3ZlLCBtb25pdG9yKTsKCQkJd2NoLnNldERpcnR5KHRydWUpOwoJCQkKCQkJLy8gdHJpZ2dlciBsb2FkIG9mIG1vZHVsZXMgbGlzdAoJCQlnZXRNb2R1bGVzKCk7CgkJCQoJCQlpZiAoYWRkICE9IG51bGwpIHsKCQkJCWludCBzaXplID0gYWRkLmxlbmd0aDsKCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQkJaWYgKCFtb2R1bGVzLmNvbnRhaW5zKGFkZFtpXSkpCgkJCQkJCW1vZHVsZXMuYWRkKGFkZFtpXSk7CgkJCQl9CgkJCX0KCQkJCgkJCWlmIChyZW1vdmUgIT0gbnVsbCkgewoJCQkJaW50IHNpemUgPSByZW1vdmUubGVuZ3RoOwoJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQlpZiAobW9kdWxlcy5jb250YWlucyhyZW1vdmVbaV0pKQoJCQkJCQltb2R1bGVzLnJlbW92ZShyZW1vdmVbaV0pOwoJCQkJfQoJCQl9CgkJCQoJCQkvLyBjb252ZXJ0IHRvIGF0dHJpYnV0ZQoJCQlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gbW9kdWxlcy5pdGVyYXRvcigpOwoJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQlJTW9kdWxlIG1vZHVsZSA9IChJTW9kdWxlKSBpdGVyYXRvci5uZXh0KCk7CgkJCQlsaXN0LmFkZChtb2R1bGUuZ2V0SWQoKSk7CgkJCX0KCQkJc2V0QXR0cmlidXRlKE1PRFVMRV9MSVNULCBsaXN0KTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCXRocm93IGNlOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIGNhbGxpbmcgZGVsZWdhdGUgbW9kaWZ5TW9kdWxlKCkgIiArIHRvU3RyaW5nKCksIGUpOwoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsIDAsICIiICsgZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCksIGUpKTsKCQl9Cgl9CgoJcHVibGljIHZvaWQgc2V0RGVmYXVsdHMoSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJdHJ5IHsKCQkJZ2V0V29ya2luZ0NvcHlEZWxlZ2F0ZShtb25pdG9yKS5zZXREZWZhdWx0cyhtb25pdG9yKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBjYWxsaW5nIGRlbGVnYXRlIHNldERlZmF1bHRzKCkgIiArIHRvU3RyaW5nKCksIGUpOwoJCX0KCX0KCQoJcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKCQlyZXR1cm4gIlNlcnZlcldvcmtpbmdDb3B5ICIgKyBnZXRJZCgpOwoJfQp9