LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA1IEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4goCBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAqIAogKiBDb250cmlidXRvcnM6CiAqICAgICBHb3JrZW0gRXJjYW4gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIE5hY2kgTS4gRGFpCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECiAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCiAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBFVEVSQVRJT04gQS5TLiBPUgogKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCiAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgogKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAogKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKgogKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQogKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4gIEZvciBtb3JlCiAqIGluZm9ybWF0aW9uIG9uIGV0ZXJhdGlvbiwgcGxlYXNlIHNlZQogKiA8aHR0cDovL3d3dy5ldGVyYXRpb24uY29tLz4uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLmNvcmUuaW50ZXJuYWw7CgppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLk51bGxQcm9ncmVzc01vbml0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5TdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLkRlYnVnRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLkRlYnVnUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JRGVidWdFdmVudFNldExpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoQ29uZmlndXJhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaENvbmZpZ3VyYXRpb25UeXBlOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoQ29uZmlndXJhdGlvbldvcmtpbmdDb3B5OwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoTWFuYWdlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUubW9kZWwuSVByb2Nlc3M7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy51aS5JRGVidWdVSUNvbnN0YW50czsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5JUnVudGltZUNsYXNzcGF0aEVudHJ5OwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5JVk1JbnN0YWxsOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5KYXZhUnVudGltZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuZ2VuZXJpYy5zZXJ2ZXJ0eXBlLmRlZmluaXRpb24uQXJjaGl2ZVR5cGU7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuc2VydmVydHlwZS5kZWZpbml0aW9uLkFyZ3VtZW50UGFpcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuZ2VuZXJpYy5zZXJ2ZXJ0eXBlLmRlZmluaXRpb24uQ2xhc3NwYXRoOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLnNlcnZlcnR5cGUuZGVmaW5pdGlvbi5MYXVuY2hDb25maWd1cmF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLnNlcnZlcnR5cGUuZGVmaW5pdGlvbi5TZXJ2ZXJSdW50aW1lOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklNb2R1bGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5TZXJ2ZXJQb3J0OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLlNlcnZlckJlaGF2aW91ckRlbGVnYXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLlNlcnZlckRlbGVnYXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLnV0aWwuU29ja2V0VXRpbDsKCi8qKgogKiBTZXJ2ZXIgYmVoYXZpb3VyIGRlbGVnYXRlIGltcGxlbWVudGF0aW9uIGZvciBnZW5lcmljIHNlcnZlci4KICoKICogQGF1dGhvciBHb3JrZW0gRXJjYW4KICovCnB1YmxpYyBjbGFzcyBHZW5lcmljU2VydmVyQmVoYXZpb3VyIGV4dGVuZHMgU2VydmVyQmVoYXZpb3VyRGVsZWdhdGUgewoJCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9TVE9QID0gInN0b3Atc2VydmVyIjsKICAgIAoJLy8gdGhlIHRocmVhZCB1c2VkIHRvIHBpbmcgdGhlIHNlcnZlciB0byBjaGVjayBmb3Igc3RhcnR1cAoJcHJvdGVjdGVkIHRyYW5zaWVudCBQaW5nVGhyZWFkIHBpbmcgPSBudWxsOwogICAgcHJvdGVjdGVkIHRyYW5zaWVudCBJRGVidWdFdmVudFNldExpc3RlbmVyIHByb2Nlc3NMaXN0ZW5lcjsKICAgIHByb3RlY3RlZCB0cmFuc2llbnQgSVByb2Nlc3MgcHJvY2VzczsKICAgIAogICAgLyogKG5vbi1KYXZhZG9jKQogICAgICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuU2VydmVyQmVoYXZpb3VyRGVsZWdhdGUjcHVibGlzaFNlcnZlcihvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcikKICAgICAqLwogICAgcHVibGljIHZvaWQgcHVibGlzaFNlcnZlcihpbnQga2luZCwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CiAgICAgICAgLy8gZG8gbm90aGluZwogICAgfQoKICAgIC8qIChub24tSmF2YWRvYykKICAgICAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLlNlcnZlckJlaGF2aW91ckRlbGVnYXRlI3B1Ymxpc2hNb2R1bGUob3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklNb2R1bGVbXSwgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklNb2R1bGUsIG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yKQogICAgICovCiAgICBwdWJsaWMgdm9pZCBwdWJsaXNoTW9kdWxlKGludCBraW5kLCBpbnQgZGVsdGFLaW5kLCBJTW9kdWxlW10gbW9kdWxlLAogICAgICAgICAgICBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKIAogICAgICAgIGlmKFJFTU9WRUQgPT0gZGVsdGFLaW5kKXsKICAgICAgICAgICAgcmVtb3ZlRnJvbVNlcnZlcihtb2R1bGUsbW9uaXRvcik7CiAgICAgICAgfQogICAgICAgIGVsc2V7CiAgICAgICAgICAgIFN0cmluZyBwdWJsaXNoZXJJZCA9IFNlcnZlclR5cGVEZWZpbml0aW9uVXRpbC5nZXRQdWJsaXNoZXJJRChtb2R1bGVbMF0sIGdldFNlcnZlckRlZmluaXRpb24oKSk7CiAgICAgICAgICAgIEdlbmVyaWNQdWJsaXNoZXIgcHVibGlzaGVyID0gUHVibGlzaE1hbmFnZXIuZ2V0UHVibGlzaGVyKHB1Ymxpc2hlcklkKTsKICAgICAgICAgICAgaWYocHVibGlzaGVyPT1udWxsKXsKICAgICAgICAgICAgICAgIElTdGF0dXMgc3RhdHVzID0gbmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLENvcmVQbHVnaW4uUExVR0lOX0lELDAsIlVuYWJsZSB0byBjcmVhdGUgcHVibGlzaGVyIixudWxsKTsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKHN0YXR1cyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHVibGlzaGVyLmluaXRpYWxpemUobW9kdWxlLGdldFNlcnZlcigpKTsKICAgICAgICAgICAgSVN0YXR1c1tdIHN0YXR1cz0gcHVibGlzaGVyLnB1Ymxpc2gobnVsbCxtb25pdG9yKTsKICAgICAgICAgICAgaWYoc3RhdHVzPT1udWxsKXsKICAgICAgICAgICAgICAgIHNldE1vZHVsZVB1Ymxpc2hTdGF0ZShtb2R1bGUsIElTZXJ2ZXIuUFVCTElTSF9TVEFURV9OT05FKTsKICAgICAgICAgICAgfWVsc2UgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpIDwgc3RhdHVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKElTdGF0dXMuRVJST1IgPT0gc3RhdHVzW2ldLmdldFNldmVyaXR5KCkpewogICAgICAgICAgICAgICAgICAgIAlzZXRNb2R1bGVQdWJsaXNoU3RhdGUobW9kdWxlLCBJU2VydmVyLlBVQkxJU0hfU1RBVEVfVU5LTk9XTik7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKHN0YXR1c1tpXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCByZW1vdmVGcm9tU2VydmVyKElNb2R1bGVbXSBtb2R1bGUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24KICAgIHsKICAgIAlTdHJpbmcgcHVibGlzaGVySWQgPSBTZXJ2ZXJUeXBlRGVmaW5pdGlvblV0aWwuZ2V0UHVibGlzaGVySUQobW9kdWxlWzBdLCBnZXRTZXJ2ZXJEZWZpbml0aW9uKCkpOwogICAgICAgIEdlbmVyaWNQdWJsaXNoZXIgcHVibGlzaGVyID0gUHVibGlzaE1hbmFnZXIuZ2V0UHVibGlzaGVyKHB1Ymxpc2hlcklkKTsgIAogICAgICAgIGlmKHB1Ymxpc2hlcj09bnVsbCl7CiAgICAgICAgICAgIElTdGF0dXMgc3RhdHVzID0gbmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLENvcmVQbHVnaW4uUExVR0lOX0lELDAsIlVuYWJsZSB0byBjcmVhdGUgcHVibGlzaGVyIHRvIHJlbW92ZSBtb2R1bGUiLG51bGwpOwogICAgICAgICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihzdGF0dXMpOwogICAgICAgIH0KICAgICAgICBwdWJsaXNoZXIuaW5pdGlhbGl6ZShtb2R1bGUsZ2V0U2VydmVyKCkpOwogICAgICAgIHB1Ymxpc2hlci51bnB1Ymxpc2gobW9uaXRvcik7CiAgICB9CiAgICAKICAgIAogICAgLyogKG5vbi1KYXZhZG9jKQogICAgICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuU2VydmVyQmVoYXZpb3VyRGVsZWdhdGUjc3RvcChib29sZWFuKQogICAgICovCiAgICBwdWJsaWMgdm9pZCBzdG9wKGJvb2xlYW4gZm9yY2UpIHsKCQlpZiAoZm9yY2UpIHsKCQkJdGVybWluYXRlKCk7CgkJCXJldHVybjsKCQl9CgoJCWludCBzdGF0ZSA9IGdldFNlcnZlcigpLmdldFNlcnZlclN0YXRlKCk7CgkJaWYgKHN0YXRlID09IElTZXJ2ZXIuU1RBVEVfU1RPUFBFRCkKCQkJcmV0dXJuOwoJCWVsc2UgaWYgKHN0YXRlID09IElTZXJ2ZXIuU1RBVEVfU1RBUlRJTkcgfHwgc3RhdGUgPT0gSVNlcnZlci5TVEFURV9TVE9QUElORykgewoJCQl0ZXJtaW5hdGUoKTsKCQkJcmV0dXJuOwoJCX0KCQkKCQlzaHV0ZG93bihzdGF0ZSk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2h1dHMgZG93biB0aGUgc2VydmVyIHZpYSB0aGUgbGF1bmNoIGNvbmZpZ3VyYXRpb24uCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHNodXRkb3duKGludCBzdGF0ZSkgewoJCUdlbmVyaWNTZXJ2ZXJSdW50aW1lIHJ1bnRpbWUgPSAoR2VuZXJpY1NlcnZlclJ1bnRpbWUpIGdldFJ1bnRpbWVEZWxlZ2F0ZSgpOwoJCXRyeSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIlN0b3BwaW5nIFNlcnZlciIpOwoJCQlpZiAoc3RhdGUgIT0gSVNlcnZlci5TVEFURV9TVE9QUEVEKQoJCQkJc2V0U2VydmVyU3RhdGUoSVNlcnZlci5TVEFURV9TVE9QUElORyk7CgkJCVN0cmluZyBjb25maWdUeXBlSUQgPSBnZXRDb25maWdUeXBlSUQoKTsgCgkJCUlMYXVuY2hNYW5hZ2VyIG1nciA9IERlYnVnUGx1Z2luLmdldERlZmF1bHQoKS5nZXRMYXVuY2hNYW5hZ2VyKCk7CgkJCUlMYXVuY2hDb25maWd1cmF0aW9uVHlwZSB0eXBlID0gbWdyLmdldExhdW5jaENvbmZpZ3VyYXRpb25UeXBlKGNvbmZpZ1R5cGVJRCk7CgkJCVN0cmluZyBsYXVuY2hOYW1lID0gZ2V0U3RvcExhdW5jaE5hbWUoKTsKCQkJU3RyaW5nIHVuaXF1ZUxhdW5jaE5hbWUgPSBtZ3IuZ2VuZXJhdGVVbmlxdWVMYXVuY2hDb25maWd1cmF0aW9uTmFtZUZyb20obGF1bmNoTmFtZSk7CgkJCUlMYXVuY2hDb25maWd1cmF0aW9uIGNvbmYgPSBudWxsOwoJCQlJTGF1bmNoQ29uZmlndXJhdGlvbltdIGxjaCA9IG1nci5nZXRMYXVuY2hDb25maWd1cmF0aW9ucyh0eXBlKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBsY2gubGVuZ3RoOyBpKyspIHsKCQkJCWlmIChsYXVuY2hOYW1lLmVxdWFscyhsY2hbaV0uZ2V0TmFtZSgpKSkgewoJCQkJCWNvbmYgPSBsY2hbaV07CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCgkJCUlMYXVuY2hDb25maWd1cmF0aW9uV29ya2luZ0NvcHkgd2MgPSBudWxsOwoJCQlpZiAoY29uZiAhPSBudWxsKSB7CgkJCQl3YyA9IGNvbmYuZ2V0V29ya2luZ0NvcHkoKTsKCQkJfSBlbHNlIHsKCQkJCXdjID0gdHlwZS5uZXdJbnN0YW5jZShudWxsLCB1bmlxdWVMYXVuY2hOYW1lKTsKCQkJfQoJCQkKCQkJLy8gVG8gc3RvcCBmcm9tIGFwcGVhcmluZyBpbiBoaXN0b3J5IGxpc3RzCgkJCXdjLnNldEF0dHJpYnV0ZShJRGVidWdVSUNvbnN0YW50cy5BVFRSX1BSSVZBVEUsIHRydWUpOwkJCgkJCS8vIFNldCB0aGUgc3RvcCBhdHRyaWJ1dGUgc28gdGhhdCB3ZSBrbm93IHdlIGFyZSBzdG9wcGluZwoJCQl3Yy5zZXRBdHRyaWJ1dGUoQVRUUl9TVE9QLCAidHJ1ZSIpOwoJCQkKCQkJLy8gU2V0dXAgdGhlIGxhdW5jaCBjb25maWcgZm9yIHN0b3BwaW5nIHRoZSBzZXJ2ZXIKCQkJc2V0dXBTdG9wTGF1bmNoQ29uZmlndXJhdGlvbihydW50aW1lLCB3Yyk7CgkJCQoJCQkvLyBMYXVuY2ggdGhlIHN0b3AgbGF1bmNoIGNvbmZpZwoJCQl3Yy5sYXVuY2goSUxhdW5jaE1hbmFnZXIuUlVOX01PREUsIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwoKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBzdG9wcGluZyBTZXJ2ZXIiLCBlKTsKCQl9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBTdHJpbmcgSUQgb2YgdGhlIGxhdW5jaCBjb25maWd1cmF0aW9uIHR5cGUuCiAgICAgKiBAcmV0dXJuCiAgICAgKi8KCXByb3RlY3RlZCBTdHJpbmcgZ2V0Q29uZmlnVHlwZUlEKCkgewoJCXJldHVybiBJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuSURfSkFWQV9BUFBMSUNBVElPTjsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIFN0cmluZyBuYW1lIG9mIHRoZSBzdG9wIGxhdW5jaCBjb25maWd1cmF0aW9uLgoJICogQHJldHVybgoJICovCglwcm90ZWN0ZWQgU3RyaW5nIGdldFN0b3BMYXVuY2hOYW1lKCkgewoJCXJldHVybiAiR2VuZXJpY1NlcnZlclN0b3BwZXIiOwoJfQoJCgkvKioKCSAqIFNldHMgdXAgdGhlIGxhdW5jaCBjb25maWd1cmF0aW9uIGZvciBzdG9wcGluZyB0aGUgc2VydmVyLgoJICogQHBhcmFtIHdvcmtpbmdDb3B5CgkgKi8KCXByb3RlY3RlZCB2b2lkIHNldHVwU3RvcExhdW5jaENvbmZpZ3VyYXRpb24oR2VuZXJpY1NlcnZlclJ1bnRpbWUgcnVudGltZSwgSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSB3YykgewoJCXdjLnNldEF0dHJpYnV0ZSgKCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX01BSU5fVFlQRV9OQU1FLAoJCQkJZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFJlc29sdmVyKCkucmVzb2x2ZVByb3BlcnRpZXModGhpcy5nZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0U3RvcCgpLmdldE1haW5DbGFzcygpKSk7CgoJCUlWTUluc3RhbGwgdm1JbnN0YWxsID0gcnVudGltZS5nZXRWTUluc3RhbGwoKTsKCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX1RZUEUsIHJ1bnRpbWUKCQkJCQkJLmdldFZNSW5zdGFsbFR5cGVJZCgpKTsKCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX05BTUUsCgkJCQl2bUluc3RhbGwuZ2V0TmFtZSgpKTsKCgkJc2V0dXBMYXVuY2hDbGFzc3BhdGgod2MsIHZtSW5zdGFsbCwgZ2V0U3RvcENsYXNzcGF0aCgpKTsKCiAgICAgICAgTWFwIGVudmlyb25WYXJzID0gZ2V0RW52aXJvbm1lbnRWYXJpYWJsZXMoZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0b3AoKSk7CiAgICAgICAgaWYoIWVudmlyb25WYXJzLmlzRW1wdHkoKSl7CiAgICAgICAgCXdjLnNldEF0dHJpYnV0ZShJTGF1bmNoTWFuYWdlci5BVFRSX0VOVklST05NRU5UX1ZBUklBQkxFUyxlbnZpcm9uVmFycyk7CiAgICAgICAgfQogICAgICAgIAoJCXdjLnNldEF0dHJpYnV0ZSgKCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1dPUktJTkdfRElSRUNUT1JZLAoJCQkJZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFJlc29sdmVyKCkucmVzb2x2ZVByb3BlcnRpZXMoZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0b3AoKS5nZXRXb3JraW5nRGlyZWN0b3J5KCkpKTsKCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9QUk9HUkFNX0FSR1VNRU5UUywKCQkJCWdldFNlcnZlckRlZmluaXRpb24oKS5nZXRSZXNvbHZlcigpLnJlc29sdmVQcm9wZXJ0aWVzKGdldFNlcnZlckRlZmluaXRpb24oKS5nZXRTdG9wKCkuZ2V0UHJvZ3JhbUFyZ3VtZW50c0FzU3RyaW5nKCkpKTsKCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9BUkdVTUVOVFMsCgkJCQlnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0UmVzb2x2ZXIoKS5yZXNvbHZlUHJvcGVydGllcyhnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0U3RvcCgpLmdldFZtUGFyYW1ldGVyc0FzU3RyaW5nKCkpKTsJCQkJCgl9CgogICAgcHVibGljIFN0cmluZyBnZXRTdGFydENsYXNzTmFtZSgpIHsKICAgIAlyZXR1cm4gZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFJlc29sdmVyKCkucmVzb2x2ZVByb3BlcnRpZXMoZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0YXJ0KCkuZ2V0TWFpbkNsYXNzKCkpOwogICAgfQoKICAgIHB1YmxpYyBTZXJ2ZXJSdW50aW1lIGdldFNlcnZlckRlZmluaXRpb24oKSB7CiAgICAgICAgR2VuZXJpY1NlcnZlciBzZXJ2ZXIgPSAoR2VuZXJpY1NlcnZlcilnZXRTZXJ2ZXIoKS5sb2FkQWRhcHRlcihTZXJ2ZXJEZWxlZ2F0ZS5jbGFzcywgbnVsbCk7CiAgICAgICAgcmV0dXJuIHNlcnZlci5nZXRTZXJ2ZXJEZWZpbml0aW9uKCk7CiAgICB9CiAgICAKICAgIHByb3RlY3RlZCBHZW5lcmljU2VydmVyUnVudGltZSBnZXRSdW50aW1lRGVsZWdhdGUoKSB7CiAgICAgICByZXR1cm4gKEdlbmVyaWNTZXJ2ZXJSdW50aW1lKWdldFNlcnZlcigpLmdldFJ1bnRpbWUoKS5sb2FkQWRhcHRlcihHZW5lcmljU2VydmVyUnVudGltZS5jbGFzcyxudWxsKTsKICAgIH0KCiAgICBwcml2YXRlIExpc3QgZ2V0U3RhcnRDbGFzc3BhdGgoKSB7CiAgICAJU3RyaW5nIGNwUmVmID0gZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0YXJ0KCkuZ2V0Q2xhc3NwYXRoUmVmZXJlbmNlKCk7CiAgICAJcmV0dXJuIHNlcnZlckNsYXNzcGF0aChjcFJlZik7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gY3BSZWYKICAgICAqIEByZXR1cm4KICAgICAqLwogICAgcHJvdGVjdGVkIExpc3Qgc2VydmVyQ2xhc3NwYXRoKFN0cmluZyBjcFJlZikgewogICAgCUNsYXNzcGF0aCBjbGFzc3BhdGggPSBnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0Q2xhc3NwYXRoKGNwUmVmKTsKICAgIAkKICAgICAgICBMaXN0IGNwRW50cnlMaXN0ID0gbmV3IEFycmF5TGlzdChjbGFzc3BhdGguZ2V0QXJjaGl2ZSgpLnNpemUoKSk7CiAgICAgICAgSXRlcmF0b3IgaXRlcmF0b3I9IGNsYXNzcGF0aC5nZXRBcmNoaXZlKCkuaXRlcmF0b3IoKTsKICAgICAgICB3aGlsZShpdGVyYXRvci5oYXNOZXh0KCkpCiAgICAgICAgewogICAgICAgIAlBcmNoaXZlVHlwZSBhcmNoaXZlID0gKEFyY2hpdmVUeXBlKWl0ZXJhdG9yLm5leHQoKTsKICAgICAgICAJU3RyaW5nIGNwYXRoID0gZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFJlc29sdmVyKCkucmVzb2x2ZVByb3BlcnRpZXMoYXJjaGl2ZS5nZXRQYXRoKCkpOwogICAgCQogICAgCQkJY3BFbnRyeUxpc3QuYWRkKEphdmFSdW50aW1lLm5ld0FyY2hpdmVSdW50aW1lQ2xhc3NwYXRoRW50cnkoCiAgICAJCQkJCW5ldyBQYXRoKGNwYXRoKSkpOwogICAgICAgICB9CiAgICAJcmV0dXJuIGNwRW50cnlMaXN0OwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHdjCiAgICAgKiBAcGFyYW0gdm1JbnN0YWxsCiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIHNldHVwTGF1bmNoQ2xhc3NwYXRoKElMYXVuY2hDb25maWd1cmF0aW9uV29ya2luZ0NvcHkgd2MsIElWTUluc3RhbGwgdm1JbnN0YWxsLCBMaXN0IGNwKSB7CgkJLy9tZXJnZSBleGlzdGluZyBjbGFzc3BhdGggd2l0aCBzZXJ2ZXIgY2xhc3NwYXRoCgkJdHJ5IHsKCQkJSVJ1bnRpbWVDbGFzc3BhdGhFbnRyeVtdIGV4aXN0aW5nQ3BzID0gSmF2YVJ1bnRpbWUuY29tcHV0ZVVucmVzb2x2ZWRSdW50aW1lQ2xhc3NwYXRoKHdjKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBleGlzdGluZ0Nwcy5sZW5ndGg7IGkrKykgewoJCQkJaWYoY3AuY29udGFpbnMoZXhpc3RpbmdDcHNbaV0pPT1mYWxzZSl7IAoJCQkJCWNwLmFkZChleGlzdGluZ0Nwc1tpXSk7CgkJCQl9CgkJCX0KCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJLy8gaWdub3JlCgkJfQoJCQogICAgCXdjLnNldEF0dHJpYnV0ZShJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9DTEFTU1BBVEgsIGNvbnZlcnRDUEVudHJ5VG9NZW1lbnRvKGNwKSk7CiAgICAJd2Muc2V0QXR0cmlidXRlKElKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX0RFRkFVTFRfQ0xBU1NQQVRILGZhbHNlKTsKICAgIH0KCglwcml2YXRlIExpc3QgY29udmVydENQRW50cnlUb01lbWVudG8oTGlzdCBjcEVudHJ5TGlzdCkKCXsKCQlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KGNwRW50cnlMaXN0LnNpemUoKSk7CgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBjcEVudHJ5TGlzdC5pdGVyYXRvcigpOwoJCXdoaWxlKGl0ZXJhdG9yLmhhc05leHQoKSkKCQl7CgkJCUlSdW50aW1lQ2xhc3NwYXRoRW50cnkgZW50cnkgPSAoSVJ1bnRpbWVDbGFzc3BhdGhFbnRyeSlpdGVyYXRvci5uZXh0KCk7CgkJCXRyeSB7CgkJCQlsaXN0LmFkZChlbnRyeS5nZXRNZW1lbnRvKCkpOwoJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJCS8vIGlnbm9yZQoJCQl9CgkJfQoJCXJldHVybiBsaXN0OwoJfQoKICAgIHByaXZhdGUgU3RyaW5nIGdldFdvcmtpbmdEaXJlY3RvcnkoKSB7CiAgICAJcmV0dXJuIGdldFNlcnZlckRlZmluaXRpb24oKS5nZXRSZXNvbHZlcigpLnJlc29sdmVQcm9wZXJ0aWVzKGdldFNlcnZlckRlZmluaXRpb24oKS5nZXRTdGFydCgpLmdldFdvcmtpbmdEaXJlY3RvcnkoKSk7CiAgICB9CgogICAgcHJpdmF0ZSBTdHJpbmcgZ2V0UHJvZ3JhbUFyZ3VtZW50cygpIHsKICAgIAlyZXR1cm4gZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFJlc29sdmVyKCkucmVzb2x2ZVByb3BlcnRpZXMoZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0YXJ0KCkuZ2V0UHJvZ3JhbUFyZ3VtZW50c0FzU3RyaW5nKCkpOwogICAgfQoKICAgIHByb3RlY3RlZCBNYXAgZ2V0RW52aXJvbm1lbnRWYXJpYWJsZXMoTGF1bmNoQ29uZmlndXJhdGlvbiBjb25maWcpewogICAgICAgIExpc3QgdmFyaWFibGVzID0gY29uZmlnLmdldEVudmlyb25tZW50VmFyaWFibGUoKTsKICAgICAgICBNYXAgdmFyc01hcCA9IG5ldyBIYXNoTWFwKHZhcmlhYmxlcy5zaXplKCkpOwogICAgICAgIEl0ZXJhdG9yIGl0ZXJhdG9yPSB2YXJpYWJsZXMuaXRlcmF0b3IoKTsKICAgICAgICB3aGlsZShpdGVyYXRvci5oYXNOZXh0KCkpewogICAgICAgIAlBcmd1bWVudFBhaXIgcGFpciA9IChBcmd1bWVudFBhaXIpaXRlcmF0b3IubmV4dCgpOwogICAgICAgIAl2YXJzTWFwLnB1dChwYWlyLmdldE5hbWUoKSxnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0UmVzb2x2ZXIoKS5yZXNvbHZlUHJvcGVydGllcyhwYWlyLmdldFZhbHVlKCkpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhcnNNYXA7CiAgICB9CiAgICAKICAgIHByaXZhdGUgU3RyaW5nIGdldFZtQXJndW1lbnRzKCkgewogICAgCXJldHVybiBnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0UmVzb2x2ZXIoKS5yZXNvbHZlUHJvcGVydGllcyhnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0U3RhcnQoKS5nZXRWbVBhcmFtZXRlcnNBc1N0cmluZygpKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXR1cExhdW5jaENvbmZpZ3VyYXRpb24oSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSB3b3JraW5nQ29weSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJd29ya2luZ0NvcHkuc2V0QXR0cmlidXRlKAogICAgICAgICAgICAgICAgSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfTUFJTl9UWVBFX05BTUUsCiAgICAgICAgICAgICAgICBnZXRTdGFydENsYXNzTmFtZSgpKTsKCiAgICAgICAgR2VuZXJpY1NlcnZlclJ1bnRpbWUgcnVudGltZSA9IChHZW5lcmljU2VydmVyUnVudGltZSkgZ2V0UnVudGltZURlbGVnYXRlKCk7CgogICAgICAgIElWTUluc3RhbGwgdm1JbnN0YWxsID0gcnVudGltZS5nZXRWTUluc3RhbGwoKTsKICAgICAgICB3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoCiAgICAgICAgICAgICAgICBJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX1RZUEUsIHJ1bnRpbWUKICAgICAgICAgICAgICAgICAgICAgICAgLmdldFZNSW5zdGFsbFR5cGVJZCgpKTsKICAgICAgICB3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoCiAgICAgICAgICAgICAgICBJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX05BTUUsCiAgICAgICAgICAgICAgICB2bUluc3RhbGwuZ2V0TmFtZSgpKTsKCiAgICAgICAgc2V0dXBMYXVuY2hDbGFzc3BhdGgod29ya2luZ0NvcHksIHZtSW5zdGFsbCwgZ2V0U3RhcnRDbGFzc3BhdGgoKSk7CgoKICAgICAgICB3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoCiAgICAgICAgICAgICAgICBJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9XT1JLSU5HX0RJUkVDVE9SWSwKICAgICAgICAgICAgICAgIGdldFdvcmtpbmdEaXJlY3RvcnkoKSk7CiAgICAgICAgCgogICAgICAgIE1hcCBlbnZpcm9uVmFycyA9IGdldEVudmlyb25tZW50VmFyaWFibGVzKGdldFNlcnZlckRlZmluaXRpb24oKS5nZXRTdGFydCgpKTsKICAgICAgICBpZighZW52aXJvblZhcnMuaXNFbXB0eSgpKXsKICAgICAgICAJd29ya2luZ0NvcHkuc2V0QXR0cmlidXRlKElMYXVuY2hNYW5hZ2VyLkFUVFJfRU5WSVJPTk1FTlRfVkFSSUFCTEVTLGVudmlyb25WYXJzKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgU3RyaW5nIGV4aXN0aW5nUHJvZ0FyZ3MgID0gd29ya2luZ0NvcHkuZ2V0QXR0cmlidXRlKElKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1BST0dSQU1fQVJHVU1FTlRTLCAoU3RyaW5nKW51bGwpOwogICAgICAgIFN0cmluZyBzZXJ2ZXJQcm9nQXJncyA9ICBnZXRQcm9ncmFtQXJndW1lbnRzKCk7CiAgICAgICAgaWYoZXhpc3RpbmdQcm9nQXJncz09bnVsbCB8fCBleGlzdGluZ1Byb2dBcmdzLmluZGV4T2Yoc2VydmVyUHJvZ0FyZ3MpPDApIHsKICAgICAgICAgICAgd29ya2luZ0NvcHkuc2V0QXR0cmlidXRlKElKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1BST0dSQU1fQVJHVU1FTlRTLHNlcnZlclByb2dBcmdzKTsKICAgICAgICB9CiAgICAgICAgU3RyaW5nIGV4aXN0aW5nVk1BcmdzID0gd29ya2luZ0NvcHkuZ2V0QXR0cmlidXRlKElKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1ZNX0FSR1VNRU5UUywoU3RyaW5nKW51bGwpOwogICAgICAgIFN0cmluZyBzZXJ2ZXJWTUFyZ3M9IGdldFZtQXJndW1lbnRzKCk7CiAgICAgICAgaWYoZXhpc3RpbmdWTUFyZ3M9PW51bGwgfHwgZXhpc3RpbmdWTUFyZ3MuaW5kZXhPZihzZXJ2ZXJWTUFyZ3MpPDApIHsKICAgICAgICAgICAgd29ya2luZ0NvcHkuc2V0QXR0cmlidXRlKElKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1ZNX0FSR1VNRU5UUyxzZXJ2ZXJWTUFyZ3MpOwogICAgICAgIH0KCX0KICAgIAogICAgLyoqCiAgICAgKiBTZXR1cCBmb3Igc3RhcnRpbmcgdGhlIHNlcnZlci4KICAgICAqIAogICAgICogQHBhcmFtIGxhdW5jaCBJTGF1bmNoCiAgICAgKiBAcGFyYW0gbGF1bmNoTW9kZSBTdHJpbmcKICAgICAqIEBwYXJhbSBtb25pdG9yIElQcm9ncmVzc01vbml0b3IKICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgc2V0dXBMYXVuY2goSUxhdW5jaCBsYXVuY2gsIFN0cmluZyBsYXVuY2hNb2RlLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKICAgIAlpZiAoInRydWUiLmVxdWFscyhsYXVuY2guZ2V0TGF1bmNoQ29uZmlndXJhdGlvbigpLmdldEF0dHJpYnV0ZShBVFRSX1NUT1AsICJmYWxzZSIpKSkgCiAgICAJCXJldHVybjsKCiAgICAJU3RyaW5nIGhvc3QgPSBnZXRTZXJ2ZXIoKS5nZXRIb3N0KCk7CiAgICAJU2VydmVyUG9ydFtdIHBvcnRzID0gZ2V0U2VydmVyKCkuZ2V0U2VydmVyUG9ydHMobnVsbCk7CiAgICAJU2VydmVyUG9ydCBzcCA9IG51bGw7CiAgICAJaWYoZ2V0U2VydmVyKCkuZ2V0U2VydmVyVHlwZSgpLnN1cHBvcnRzUmVtb3RlSG9zdHMoKT09ZmFsc2UgJiYgU29ja2V0VXRpbC5pc0xvY2FsaG9zdChob3N0KSl7CgkgICAgCWZvcihpbnQgaT0wO2k8cG9ydHMubGVuZ3RoO2krKyl7CgkgICAgCQlzcD0gcG9ydHNbaV07CgkgICAgCQlpZiAoU29ja2V0VXRpbC5pc1BvcnRJblVzZShwb3J0c1tpXS5nZXRQb3J0KCksIDUpKQoJICAgIAkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgQ29yZVBsdWdpbi5QTFVHSU5fSUQsIDAsIEdlbmVyaWNTZXJ2ZXJDb3JlTWVzc2FnZXMuYmluZChHZW5lcmljU2VydmVyQ29yZU1lc3NhZ2VzLmVycm9yUG9ydEluVXNlLEludGVnZXIudG9TdHJpbmcoc3AuZ2V0UG9ydCgpKSxzcC5nZXROYW1lKCkpLG51bGwpKTsKCSAgICAJfQogICAgCX0KICAgIAlzZXRTZXJ2ZXJTdGF0ZShJU2VydmVyLlNUQVRFX1NUQVJUSU5HKTsKICAgIAlzZXRNb2RlKGxhdW5jaE1vZGUpOwogICAgCQogICAgCS8vIHBpbmcgc2VydmVyIHRvIGNoZWNrIGZvciBzdGFydHVwCiAgICAJdHJ5IHsKICAgIAkJU3RyaW5nIHVybCA9ICJodHRwOi8vIitob3N0OwogICAgCQlpbnQgcG9ydCA9IHNwLmdldFBvcnQoKTsKICAgIAkJaWYgKHBvcnQgIT0gODApCiAgICAJCQl1cmwgKz0gIjoiICsgcG9ydDsKICAgIAkJcGluZyA9IG5ldyBQaW5nVGhyZWFkKGdldFNlcnZlcigpLCB1cmwsIHRoaXMpOwogICAgCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CiAgICAJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNhbid0IHBpbmcgZm9yIHNlcnZlciBzdGFydHVwLiIpOwogICAgCX0KICAgIH0KICAgIAogICAgcHJvdGVjdGVkIHZvaWQgc2V0UHJvY2VzcyhmaW5hbCBJUHJvY2VzcyBuZXdQcm9jZXNzKSB7CiAgICAJaWYgKHByb2Nlc3MgIT0gbnVsbCkKICAgIAkJcmV0dXJuOwogICAgCWlmKHByb2Nlc3NMaXN0ZW5lciE9bnVsbCkKICAgIAkJRGVidWdQbHVnaW4uZ2V0RGVmYXVsdCgpLnJlbW92ZURlYnVnRXZlbnRMaXN0ZW5lcihwcm9jZXNzTGlzdGVuZXIpOwogICAgCWlmIChuZXdQcm9jZXNzPT1udWxsKQogICAgCQlyZXR1cm47CiAgICAJcHJvY2VzcyA9IG5ld1Byb2Nlc3M7CiAgICAJcHJvY2Vzc0xpc3RlbmVyID0gbmV3IElEZWJ1Z0V2ZW50U2V0TGlzdGVuZXIoKSB7CiAgICAJCXB1YmxpYyB2b2lkIGhhbmRsZURlYnVnRXZlbnRzKERlYnVnRXZlbnRbXSBldmVudHMpIHsKICAgIAkJCWlmIChldmVudHMgIT0gbnVsbCkgewogICAgCQkJCWludCBzaXplID0gZXZlbnRzLmxlbmd0aDsKICAgIAkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewogICAgCQkJCQlpZiAocHJvY2VzcyE9IG51bGwgJiYgIHByb2Nlc3MuZXF1YWxzKGV2ZW50c1tpXS5nZXRTb3VyY2UoKSkgJiYgZXZlbnRzW2ldLmdldEtpbmQoKSA9PSBEZWJ1Z0V2ZW50LlRFUk1JTkFURSkgewogICAgCQkJCQkJRGVidWdQbHVnaW4uZ2V0RGVmYXVsdCgpLnJlbW92ZURlYnVnRXZlbnRMaXN0ZW5lcih0aGlzKTsKICAgIAkJCQkJCXN0b3BJbXBsKCk7CiAgICAJCQkJCX0KICAgIAkJCQl9CiAgICAJCQl9CiAgICAJCX0KICAgIAl9OwogICAgCURlYnVnUGx1Z2luLmdldERlZmF1bHQoKS5hZGREZWJ1Z0V2ZW50TGlzdGVuZXIocHJvY2Vzc0xpc3RlbmVyKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBzdG9wSW1wbCgpIHsKICAgIAlpZiAocGluZyAhPSBudWxsKSB7CiAgICAJCXBpbmcuc3RvcCgpOwogICAgCQlwaW5nID0gbnVsbDsKICAgIAl9CiAgICAJaWYgKHByb2Nlc3MgIT0gbnVsbCkgewogICAgCQlwcm9jZXNzID0gbnVsbDsKICAgIAkJRGVidWdQbHVnaW4uZ2V0RGVmYXVsdCgpLnJlbW92ZURlYnVnRXZlbnRMaXN0ZW5lcihwcm9jZXNzTGlzdGVuZXIpOwogICAgCQlwcm9jZXNzTGlzdGVuZXIgPSBudWxsOwogICAgCX0KICAgIAlzZXRTZXJ2ZXJTdGF0ZShJU2VydmVyLlNUQVRFX1NUT1BQRUQpOwogICAgfQoKICAgIC8qKgogICAgICogVGVybWluYXRlcyB0aGUgc2VydmVyLgogICAgICogVGhpcyBtZXRob2QgbWF5IGJlIGNhbGxlZCBiZWZvcmUgYSBwcm9jZXNzIGNyZWF0ZWQgd2hpbGUgc2V0dGluZyB1cCB0aGUgCiAgICAgKiBsYXVuY2ggY29uZmlnLiAKICAgICAqLwogICAgcHJvdGVjdGVkIHZvaWQgdGVybWluYXRlKCkgewogICAgCWlmIChnZXRTZXJ2ZXIoKS5nZXRTZXJ2ZXJTdGF0ZSgpID09IElTZXJ2ZXIuU1RBVEVfU1RPUFBFRCkKICAgIAkJcmV0dXJuOwogICAgCiAgICAJdHJ5IHsKICAgIAkJc2V0U2VydmVyU3RhdGUoSVNlcnZlci5TVEFURV9TVE9QUElORyk7CiAgICAJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIktpbGxpbmcgdGhlIFNlcnZlciBwcm9jZXNzIik7CiAgICAJCWlmIChwcm9jZXNzICE9IG51bGwgJiYgIXByb2Nlc3MuaXNUZXJtaW5hdGVkKCkpIHsKICAgIAkJCXByb2Nlc3MudGVybWluYXRlKCk7CiAgICAJCQkKICAgIAkJfQogICAgCQlzdG9wSW1wbCgpOwogICAgCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CiAgICAJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIGtpbGxpbmcgdGhlIHByb2Nlc3MiLCBlKTsKICAgIAl9CiAgICB9CgogICAgcHJpdmF0ZSBMaXN0IGdldFN0b3BDbGFzc3BhdGgoKSB7CiAgICAJU3RyaW5nIGNwUmVmID0gZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0b3AoKS5nZXRDbGFzc3BhdGhSZWZlcmVuY2UoKTsKICAgIAlyZXR1cm4gc2VydmVyQ2xhc3NwYXRoKGNwUmVmKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBwdWJsaXNoRmluaXNoKElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewogICAgICAgIElNb2R1bGVbXSBtb2R1bGVzID0gdGhpcy5nZXRTZXJ2ZXIoKS5nZXRNb2R1bGVzKCk7CiAgICAgICAgYm9vbGVhbiBhbGxwdWJsaXNoZWQ9IHRydWU7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtb2R1bGVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgCWlmKHRoaXMuZ2V0U2VydmVyKCkuZ2V0TW9kdWxlUHVibGlzaFN0YXRlKG5ldyBJTW9kdWxlW117bW9kdWxlc1tpXX0pIT1JU2VydmVyLlBVQkxJU0hfU1RBVEVfTk9ORSkKICAgICAgICAgICAgICAgIGFsbHB1Ymxpc2hlZD1mYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYoYWxscHVibGlzaGVkKQogICAgICAgICAgICBzZXRTZXJ2ZXJQdWJsaXNoU3RhdGUoSVNlcnZlci5QVUJMSVNIX1NUQVRFX05PTkUpOwogICAgfQogICAgCiAJcHJvdGVjdGVkIHZvaWQgc2V0U2VydmVyU3RhcnRlZCgpIHsKIAkJc2V0U2VydmVyU3RhdGUoSVNlcnZlci5TVEFURV9TVEFSVEVEKTsKIAl9Cn0=