LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbDsKCmltcG9ydCBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlTGlzdGVuZXI7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZpbGU7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRm9sZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVByb2plY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2U7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JbnRlcm5hbEluaXRpYWxpemVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLlNlcnZlckRlbGVnYXRlOwovKioKICogCiAqLwpwdWJsaWMgY2xhc3MgU2VydmVyV29ya2luZ0NvcHkgZXh0ZW5kcyBTZXJ2ZXIgaW1wbGVtZW50cyBJU2VydmVyV29ya2luZ0NvcHkgewoJcHJvdGVjdGVkIFNlcnZlciBzZXJ2ZXI7Cglwcm90ZWN0ZWQgV29ya2luZ0NvcHlIZWxwZXIgd2NoOwoJCglwcm90ZWN0ZWQgU2VydmVyRGVsZWdhdGUgd29ya2luZ0NvcHlEZWxlZ2F0ZTsKCQoJLy8gd29ya2luZyBjb3B5CglwdWJsaWMgU2VydmVyV29ya2luZ0NvcHkoU2VydmVyIHNlcnZlcikgewoJCXN1cGVyKHNlcnZlci5nZXRGaWxlKCkpOwoJCXRoaXMuc2VydmVyID0gc2VydmVyOwoJCQoJCW1hcCA9IG5ldyBIYXNoTWFwKHNlcnZlci5tYXApOwoJCXdjaCA9IG5ldyBXb3JraW5nQ29weUhlbHBlcih0aGlzKTsKCQkKCQlyZXNvbHZlKCk7Cgl9CgkKCS8vIGNyZWF0aW9uCglwdWJsaWMgU2VydmVyV29ya2luZ0NvcHkoU3RyaW5nIGlkLCBJRmlsZSBmaWxlLCBJUnVudGltZSBydW50aW1lLCBJU2VydmVyVHlwZSBzZXJ2ZXJUeXBlKSB7CgkJc3VwZXIoaWQsIGZpbGUsIHJ1bnRpbWUsIHNlcnZlclR5cGUpOwoJCS8vc2VydmVyID0gdGhpczsKCQl3Y2ggPSBuZXcgV29ya2luZ0NvcHlIZWxwZXIodGhpcyk7CgkJd2NoLnNldERpcnR5KHRydWUpOwoJCXNlcnZlclN0YXRlID0gKChTZXJ2ZXJUeXBlKXNlcnZlclR5cGUpLmdldEluaXRpYWxTdGF0ZSgpOwoJfQoKCXB1YmxpYyBib29sZWFuIGlzV29ya2luZ0NvcHkoKSB7CgkJcmV0dXJuIHRydWU7Cgl9CgkKCXB1YmxpYyBJU2VydmVyIGdldE9yaWdpbmFsKCkgewoJCXJldHVybiBzZXJ2ZXI7Cgl9CgkKCXB1YmxpYyBJU2VydmVyV29ya2luZ0NvcHkgY3JlYXRlV29ya2luZ0NvcHkoKSB7CgkJcmV0dXJuIHRoaXM7Cgl9CgoJcHVibGljIGludCBnZXRTZXJ2ZXJTdGF0ZSgpIHsKCQlpZiAoc2VydmVyICE9IG51bGwpCgkJCXJldHVybiBzZXJ2ZXIuZ2V0U2VydmVyU3RhdGUoKTsKCQlyZXR1cm4gc2VydmVyU3RhdGU7Cgl9CgoJcHVibGljIHZvaWQgc2V0U2VydmVyU3RhdGUoaW50IHN0YXRlKSB7CgkJaWYgKHNlcnZlciAhPSBudWxsKQoJCQlzZXJ2ZXIuc2V0U2VydmVyU3RhdGUoc3RhdGUpOwoJCWVsc2UKCQkJc3VwZXIuc2V0U2VydmVyU3RhdGUoc3RhdGUpOwoJfQoJCglwdWJsaWMgaW50IGdldFNlcnZlclB1Ymxpc2hTdGF0ZSgpIHsKCQlpZiAoc2VydmVyICE9IG51bGwpCgkJCXJldHVybiBzZXJ2ZXIuZ2V0U2VydmVyUHVibGlzaFN0YXRlKCk7CgkJcmV0dXJuIHNlcnZlclN0YXRlOwoJfQoKCXB1YmxpYyB2b2lkIHNldFNlcnZlclB1Ymxpc2hTdGF0ZShpbnQgc3RhdGUpIHsKCQlpZiAoc2VydmVyICE9IG51bGwpCgkJCXNlcnZlci5zZXRTZXJ2ZXJQdWJsaXNoU3RhdGUoc3RhdGUpOwoJCWVsc2UKCQkJc3VwZXIuc2V0U2VydmVyUHVibGlzaFN0YXRlKHN0YXRlKTsKCX0KCQoJcHVibGljIFN0cmluZyBnZXRNb2RlKCkgewoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkKCQkJcmV0dXJuIHNlcnZlci5nZXRNb2RlKCk7CgkJcmV0dXJuIG1vZGU7Cgl9CgoJcHVibGljIHZvaWQgc2V0TW9kZShTdHJpbmcgbW9kZSkgewoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkKCQkJc2VydmVyLnNldE1vZGUobW9kZSk7CgkJZWxzZQoJCQlzdXBlci5zZXRNb2RlKG1vZGUpOwoJfQoKCXB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgYXR0cmlidXRlTmFtZSwgaW50IHZhbHVlKSB7CgkJd2NoLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCB2YWx1ZSk7Cgl9CgoJcHVibGljIHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBhdHRyaWJ1dGVOYW1lLCBib29sZWFuIHZhbHVlKSB7CgkJd2NoLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCB2YWx1ZSk7Cgl9CgoJcHVibGljIHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBhdHRyaWJ1dGVOYW1lLCBTdHJpbmcgdmFsdWUpIHsKCQl3Y2guc2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUsIHZhbHVlKTsKCX0KCglwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIGF0dHJpYnV0ZU5hbWUsIExpc3QgdmFsdWUpIHsKCQl3Y2guc2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUsIHZhbHVlKTsKCX0KCglwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIGF0dHJpYnV0ZU5hbWUsIE1hcCB2YWx1ZSkgewoJCXdjaC5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSwgdmFsdWUpOwoJfQoKCS8qIChub24tSmF2YWRvYykKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJXb3JraW5nQ29weSNzZXROYW1lKGphdmEubGFuZy5TdHJpbmcpCgkgKi8KCXB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUF9OQU1FLCBuYW1lKTsKCX0KCglwdWJsaWMgdm9pZCBzZXRSZWFkT25seShib29sZWFuIGIpIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUF9MT0NLRUQsIGIpOwoJfQoKCS8qKgoJICogU2V0cyB3aGV0aGVyIHRoaXMgZWxlbWVudCBpcyBwcml2YXRlLgoJICogR2VuZXJhbGx5IHNwZWFraW5nLCBlbGVtZW50cyBtYXJrZWQgcHJpdmF0ZSBhcmUgaW50ZXJuYWwgb25lcwoJICogdGhhdCBzaG91bGQgbm90IGJlIHNob3duIHRvIHVzZXJzIChiZWNhdXNlIHRoZXkgd29uJ3Qga25vdwoJICogYW55dGhpbmcgYWJvdXQgdGhlbSkuCgkgKiAKCSAqIEBwYXJhbSBiIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoaXMgZWxlbWVudCBpcyBwcml2YXRlLAoJICogYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UKCSAqIEBzZWUgI2lzUHJpdmF0ZSgpCgkgKi8KCXB1YmxpYyB2b2lkIHNldFByaXZhdGUoYm9vbGVhbiBiKSB7CgkJc2V0QXR0cmlidXRlKFBST1BfUFJJVkFURSwgYik7Cgl9CgoJcHVibGljIHZvaWQgc2V0SG9zdChTdHJpbmcgaG9zdCkgewoJCXNldEF0dHJpYnV0ZShQUk9QX0hPU1ROQU1FLCBob3N0KTsKCX0KCglwdWJsaWMgdm9pZCBzZXRBdXRvUHVibGlzaFRpbWUoaW50IHApIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUF9BVVRPX1BVQkxJU0hfVElNRSwgcCk7Cgl9CgkKCXB1YmxpYyB2b2lkIHNldEF1dG9QdWJsaXNoRGVmYXVsdChib29sZWFuIHApIHsKCQlzZXRBdHRyaWJ1dGUoUFJPUF9BVVRPX1BVQkxJU0hfREVGQVVMVCwgcCk7Cgl9CgoJcHVibGljIHZvaWQgc2V0U2VydmVyQ29uZmlndXJhdGlvbihJRm9sZGVyIGNvbmZpZykgewoJCXRoaXMuY29uZmlndXJhdGlvbiA9IGNvbmZpZzsKCQlpZiAoY29uZmlndXJhdGlvbiA9PSBudWxsKQoJCQlzZXRBdHRyaWJ1dGUoQ09ORklHVVJBVElPTl9JRCwgKFN0cmluZyludWxsKTsKCQllbHNlCgkJCXNldEF0dHJpYnV0ZShDT05GSUdVUkFUSU9OX0lELCBjb25maWd1cmF0aW9uLmdldEZ1bGxQYXRoKCkudG9TdHJpbmcoKSk7Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSBmaWxlIHdoZXJlIHRoaXMgc2VydmVyIGluc3RhbmNlIGlzIHNlcmlhbGl6ZWQuCgkgKiAKCSAqIEBwYXJhbSBmaWxlIHRoZSBmaWxlIGluIHRoZSB3b3Jrc3BhY2Ugd2hlcmUgdGhlIHNlcnZlciBpbnN0YW5jZQoJICogICAgaXMgc2VyaWFsaXplZCwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlIGluZm9ybWF0aW9uIGlzCgkgKiAgICBpbnN0ZWFkIHRvIGJlIHBlcnNpc3RlZCB3aXRoIHRoZSB3b3Jrc3BhY2UgYnV0IG5vdCB3aXRoIGFueQoJICogICAgcGFydGljdWxhciB3b3Jrc3BhY2UgcmVzb3VyY2UKCSAqLwoJcHVibGljIHZvaWQgc2V0RmlsZShJRmlsZSBmaWxlKSB7CgkJdGhpcy5maWxlID0gZmlsZTsKCX0KCgkvKiAobm9uLUphdmFkb2MpCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyV29ya2luZ0NvcHkjaXNEaXJ0eSgpCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzRGlydHkoKSB7CgkJcmV0dXJuIHdjaC5pc0RpcnR5KCk7Cgl9CgkKCXB1YmxpYyBTZXJ2ZXJEZWxlZ2F0ZSBnZXRXb3JraW5nQ29weURlbGVnYXRlKElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCS8vIG1ha2Ugc3VyZSB0aGF0IHRoZSByZWd1bGFyIGRlbGVnYXRlIGlzIGxvYWRlZCAKCQkvL2dldERlbGVnYXRlKCk7CgkJCgkJaWYgKHdvcmtpbmdDb3B5RGVsZWdhdGUgIT0gbnVsbCkKCQkJcmV0dXJuIHdvcmtpbmdDb3B5RGVsZWdhdGU7CgkJCgkJaWYgKHNlcnZlclR5cGUgIT0gbnVsbCkgewoJCQlzeW5jaHJvbml6ZWQgKHRoaXMpIHsKCQkJCWlmICh3b3JraW5nQ29weURlbGVnYXRlID09IG51bGwpIHsKCQkJCQl0cnkgewoJCQkJCQlsb25nIHRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKCQkJCQkJSUNvbmZpZ3VyYXRpb25FbGVtZW50IGVsZW1lbnQgPSAoKFNlcnZlclR5cGUpIHNlcnZlclR5cGUpLmdldEVsZW1lbnQoKTsKCQkJCQkJd29ya2luZ0NvcHlEZWxlZ2F0ZSA9IChTZXJ2ZXJEZWxlZ2F0ZSkgZWxlbWVudC5jcmVhdGVFeGVjdXRhYmxlRXh0ZW5zaW9uKCJjbGFzcyIpOwoJCQkJCQlJbnRlcm5hbEluaXRpYWxpemVyLmluaXRpYWxpemVTZXJ2ZXJEZWxlZ2F0ZSh3b3JraW5nQ29weURlbGVnYXRlLCB0aGlzKTsKCQkJCQkJVHJhY2UudHJhY2UoVHJhY2UuUEVSRk9STUFOQ0UsICJTZXJ2ZXJXb3JraW5nQ29weS5nZXRXb3JraW5nQ29weURlbGVnYXRlKCk6IDwiICsgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gdGltZSkgKyAiPiAiICsgZ2V0U2VydmVyVHlwZSgpLmdldElkKCkpOwoJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNvdWxkIG5vdCBjcmVhdGUgZGVsZWdhdGUgIiArIHRvU3RyaW5nKCksIGUpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCQlyZXR1cm4gd29ya2luZ0NvcHlEZWxlZ2F0ZTsKCX0KCQoJcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKCQlzdXBlci5kaXNwb3NlKCk7CgkJaWYgKHdvcmtpbmdDb3B5RGVsZWdhdGUgIT0gbnVsbCkKCQkJd29ya2luZ0NvcHlEZWxlZ2F0ZS5kaXNwb3NlKCk7Cgl9CgkKCXB1YmxpYyBJU2VydmVyIHNhdmUoYm9vbGVhbiBmb3JjZSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJbW9uaXRvciA9IFByb2dyZXNzVXRpbC5nZXRNb25pdG9yRm9yKG1vbml0b3IpOwoJCW1vbml0b3Iuc3ViVGFzayhOTFMuYmluZChNZXNzYWdlcy5zYXZpbmdUYXNrLCBnZXROYW1lKCkpKTsKCgkJaWYgKCFmb3JjZSAmJiBnZXRPcmlnaW5hbCgpICE9IG51bGwpCgkJCXdjaC52YWxpZGF0ZVRpbWVzdGFtcCgoKFNlcnZlcilnZXRPcmlnaW5hbCgpKS5nZXRUaW1lc3RhbXAoKSk7CgoJCWlmIChzZXJ2ZXIgPT0gbnVsbCkgewoJCQlzZXJ2ZXIgPSBuZXcgU2VydmVyKGZpbGUpOwoJCQlzZXJ2ZXIuc2V0U2VydmVyU3RhdGUoc2VydmVyU3RhdGUpOwoJCQlzZXJ2ZXIucHVibGlzaExpc3RlbmVycyA9IHB1Ymxpc2hMaXN0ZW5lcnM7CgkJCXNlcnZlci5ub3RpZmljYXRpb25NYW5hZ2VyID0gbm90aWZpY2F0aW9uTWFuYWdlcjsKCQl9CgkJCgkJaWYgKGdldFNlcnZlclR5cGUoKS5oYXNTZXJ2ZXJDb25maWd1cmF0aW9uKCkpIHsKCQkJSUZvbGRlciBmb2xkZXIgPSBnZXRTZXJ2ZXJDb25maWd1cmF0aW9uKCk7CgkJCWlmIChmb2xkZXIgPT0gbnVsbCkgewoJCQkJZm9sZGVyID0gU2VydmVyVHlwZS5nZXRTZXJ2ZXJQcm9qZWN0KCkuZ2V0Rm9sZGVyKGdldE5hbWUoKSArICItY29uZmlnIik7CgkJCQlpZiAoIWZvbGRlci5leGlzdHMoKSkKCQkJCQlmb2xkZXIuY3JlYXRlKHRydWUsIHRydWUsIG51bGwpOwoJCQkJc2V0U2VydmVyQ29uZmlndXJhdGlvbihmb2xkZXIpOwoJCQl9CgkJfQoJCQoJCXNlcnZlci5zZXRJbnRlcm5hbCh0aGlzKTsKCQlzZXJ2ZXIuZG9TYXZlKG1vbml0b3IpOwoJCWlmIChnZXRTZXJ2ZXJUeXBlKCkuaGFzU2VydmVyQ29uZmlndXJhdGlvbigpKSB7CgkJCUlGb2xkZXIgZm9sZGVyID0gZ2V0U2VydmVyQ29uZmlndXJhdGlvbigpOwoJCQlpZiAoZm9sZGVyICE9IG51bGwpIHsKCQkJCUlQcm9qZWN0IHByb2plY3QgPSBmb2xkZXIuZ2V0UHJvamVjdCgpOwoJCQkJaWYgKHByb2plY3QgIT0gbnVsbCAmJiAhcHJvamVjdC5leGlzdHMoKSkgewoJCQkJCXByb2plY3QuY3JlYXRlKG51bGwpOwoJCQkJCXByb2plY3Qub3BlbihudWxsKTsKCQkJCQkoKFByb2plY3RQcm9wZXJ0aWVzKVNlcnZlckNvcmUuZ2V0UHJvamVjdFByb3BlcnRpZXMocHJvamVjdCkpLnNldFNlcnZlclByb2plY3QodHJ1ZSwgbW9uaXRvcik7CgkJCQl9CgkJCQlpZiAoIWZvbGRlci5leGlzdHMoKSkKCQkJCQlmb2xkZXIuY3JlYXRlKElSZXNvdXJjZS5GT1JDRSwgdHJ1ZSwgbnVsbCk7CgkJCX0KCQl9CgkJZ2V0RGVsZWdhdGUobW9uaXRvcikuc2F2ZUNvbmZpZ3VyYXRpb24obW9uaXRvcik7CgkJd2NoLnNldERpcnR5KGZhbHNlKTsKCQkKCQlyZXR1cm4gc2VydmVyOwoJfQoKCXB1YmxpYyBJU2VydmVyIHNhdmVBbGwoYm9vbGVhbiBmb3JjZSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJaWYgKHJ1bnRpbWUgIT0gbnVsbCAmJiBydW50aW1lLmlzV29ya2luZ0NvcHkoKSkgewoJCQlJUnVudGltZVdvcmtpbmdDb3B5IHdjID0gKElSdW50aW1lV29ya2luZ0NvcHkpIHJ1bnRpbWU7CgkJCXdjLnNhdmUoZm9yY2UsIG1vbml0b3IpOwoJCX0KCQkKCQlyZXR1cm4gc2F2ZShmb3JjZSwgbW9uaXRvcik7Cgl9CgoJLyoqCgkgKiBBZGQgYSBwcm9wZXJ0eSBjaGFuZ2UgbGlzdGVuZXIgdG8gdGhpcyBzZXJ2ZXIuCgkgKgoJICogQHBhcmFtIGxpc3RlbmVyIGphdmEuYmVhbnMuUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcgoJICovCglwdWJsaWMgdm9pZCBhZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIpIHsKCQlpZiAobGlzdGVuZXIgPT0gbnVsbCkKCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTGlzdGVuZXIgY2Fubm90IGJlIG51bGwiKTsKCQl3Y2guYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihsaXN0ZW5lcik7Cgl9CgkKCS8qKgoJICogUmVtb3ZlIGEgcHJvcGVydHkgY2hhbmdlIGxpc3RlbmVyIGZyb20gdGhpcyBzZXJ2ZXIuCgkgKgoJICogQHBhcmFtIGxpc3RlbmVyIGphdmEuYmVhbnMuUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcgoJICovCglwdWJsaWMgdm9pZCByZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIpIHsKCQlpZiAobGlzdGVuZXIgPT0gbnVsbCkKCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTGlzdGVuZXIgY2Fubm90IGJlIG51bGwiKTsKCQl3Y2gucmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihsaXN0ZW5lcik7Cgl9CgkKCS8qKgoJICogRmlyZSBhIHByb3BlcnR5IGNoYW5nZSBldmVudC4KCSAqIAoJICogQHBhcmFtIHByb3BlcnR5TmFtZSBhIHByb3BlcnR5IG5hbWUKCSAqIEBwYXJhbSBvbGRWYWx1ZSB0aGUgb2xkIHZhbHVlCgkgKiBAcGFyYW0gbmV3VmFsdWUgdGhlIG5ldyB2YWx1ZQoJICovCglwdWJsaWMgdm9pZCBmaXJlUHJvcGVydHlDaGFuZ2VFdmVudChTdHJpbmcgcHJvcGVydHlOYW1lLCBPYmplY3Qgb2xkVmFsdWUsIE9iamVjdCBuZXdWYWx1ZSkgewoJCXdjaC5maXJlUHJvcGVydHlDaGFuZ2VFdmVudChwcm9wZXJ0eU5hbWUsIG9sZFZhbHVlLCBuZXdWYWx1ZSk7Cgl9CgkKCXB1YmxpYyB2b2lkIGFkZFNlcnZlckxpc3RlbmVyKElTZXJ2ZXJMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkKCQkJc2VydmVyLmFkZFNlcnZlckxpc3RlbmVyKGxpc3RlbmVyKTsKCQllbHNlCgkJCXN1cGVyLmFkZFNlcnZlckxpc3RlbmVyKGxpc3RlbmVyKTsKCX0KCQoJcHVibGljIHZvaWQgcmVtb3ZlU2VydmVyTGlzdGVuZXIoSVNlcnZlckxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJaWYgKHNlcnZlciAhPSBudWxsKQoJCQlzZXJ2ZXIucmVtb3ZlU2VydmVyTGlzdGVuZXIobGlzdGVuZXIpOwoJCWVsc2UKCQkJc3VwZXIucmVtb3ZlU2VydmVyTGlzdGVuZXIobGlzdGVuZXIpOwoJfQoJCglwdWJsaWMgdm9pZCBhZGRQdWJsaXNoTGlzdGVuZXIoSVB1Ymxpc2hMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkKCQkJc2VydmVyLmFkZFB1Ymxpc2hMaXN0ZW5lcihsaXN0ZW5lcik7CgkJZWxzZQoJCQlzdXBlci5hZGRQdWJsaXNoTGlzdGVuZXIobGlzdGVuZXIpOwoJfQoJCglwdWJsaWMgdm9pZCByZW1vdmVQdWJsaXNoTGlzdGVuZXIoSVB1Ymxpc2hMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkKCQkJc2VydmVyLnJlbW92ZVB1Ymxpc2hMaXN0ZW5lcihsaXN0ZW5lcik7CgkJZWxzZQoJCQlzdXBlci5yZW1vdmVQdWJsaXNoTGlzdGVuZXIobGlzdGVuZXIpOwoJfQoKCXB1YmxpYyB2b2lkIHNldFJ1bnRpbWUoSVJ1bnRpbWUgcnVudGltZSkgewoJCXRoaXMucnVudGltZSA9IHJ1bnRpbWU7CgkJaWYgKHJ1bnRpbWUgIT0gbnVsbCkKCQkJc2V0QXR0cmlidXRlKFJVTlRJTUVfSUQsIHJ1bnRpbWUuZ2V0SWQoKSk7CgkJZWxzZQoJCQlzZXRBdHRyaWJ1dGUoUlVOVElNRV9JRCwgKFN0cmluZyludWxsKTsKCX0KCQoJcHVibGljIHZvaWQgc2V0UnVudGltZUlkKFN0cmluZyBydW50aW1lSWQpIHsKCQlzZXRBdHRyaWJ1dGUoUlVOVElNRV9JRCwgcnVudGltZUlkKTsKCQlyZXNvbHZlKCk7Cgl9CgoJLyogKG5vbi1KYXZhZG9jKQoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlciNtb2RpZnlNb2R1bGUob3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGUpCgkgKi8KCXB1YmxpYyB2b2lkIG1vZGlmeU1vZHVsZXMoSU1vZHVsZVtdIGFkZCwgSU1vZHVsZVtdIHJlbW92ZSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJaWYgKGFkZCA9PSBudWxsICYmIHJlbW92ZSA9PSBudWxsKQoJCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJBZGQgYW5kIHJlbW92ZSBjYW5ub3QgYm90aCBiZSBudWxsIik7CgkJdHJ5IHsKCQkJbW9uaXRvciA9IFByb2dyZXNzVXRpbC5nZXRNb25pdG9yRm9yKG1vbml0b3IpOwoJCQltb25pdG9yLnN1YlRhc2soTWVzc2FnZXMudGFza01vZGlmeU1vZHVsZXMpOwoJCQlnZXRXb3JraW5nQ29weURlbGVnYXRlKG1vbml0b3IpLm1vZGlmeU1vZHVsZXMoYWRkLCByZW1vdmUsIG1vbml0b3IpOwoJCQl3Y2guc2V0RGlydHkodHJ1ZSk7CgkJCQoJCQkvLyB0cmlnZ2VyIGxvYWQgb2YgbW9kdWxlcyBsaXN0CgkJCWdldE1vZHVsZXMoKTsKCQkJCgkJCWlmIChhZGQgIT0gbnVsbCkgewoJCQkJaW50IHNpemUgPSBhZGQubGVuZ3RoOwoJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQlpZiAoIW1vZHVsZXMuY29udGFpbnMoYWRkW2ldKSkKCQkJCQkJbW9kdWxlcy5hZGQoYWRkW2ldKTsKCQkJCX0KCQkJfQoJCQkKCQkJaWYgKHJlbW92ZSAhPSBudWxsKSB7CgkJCQlpbnQgc2l6ZSA9IHJlbW92ZS5sZW5ndGg7CgkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJCWlmIChtb2R1bGVzLmNvbnRhaW5zKHJlbW92ZVtpXSkpCgkJCQkJCW1vZHVsZXMucmVtb3ZlKHJlbW92ZVtpXSk7CgkJCQl9CgkJCX0KCQkJCgkJCS8vIGNvbnZlcnQgdG8gYXR0cmlidXRlCgkJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBtb2R1bGVzLml0ZXJhdG9yKCk7CgkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCUlNb2R1bGUgbW9kdWxlID0gKElNb2R1bGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJCWxpc3QuYWRkKG1vZHVsZS5nZXRJZCgpKTsKCQkJfQoJCQlzZXRBdHRyaWJ1dGUoTU9EVUxFX0xJU1QsIGxpc3QpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJdGhyb3cgY2U7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgY2FsbGluZyBkZWxlZ2F0ZSBtb2RpZnlNb2R1bGUoKSAiICsgdG9TdHJpbmcoKSwgZSk7CgkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgMCwgIiIgKyBlLmdldExvY2FsaXplZE1lc3NhZ2UoKSwgZSkpOwoJCX0KCX0KCglwdWJsaWMgdm9pZCBzZXREZWZhdWx0cyhJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQl0cnkgewoJCQlnZXRXb3JraW5nQ29weURlbGVnYXRlKG1vbml0b3IpLnNldERlZmF1bHRzKCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgY2FsbGluZyBkZWxlZ2F0ZSBzZXREZWZhdWx0cygpICIgKyB0b1N0cmluZygpLCBlKTsKCQl9Cgl9CgkKCXB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CgkJcmV0dXJuICJTZXJ2ZXJXb3JraW5nQ29weSAiICsgZ2V0SWQoKTsKCX0KfQ==