LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZTsKCmltcG9ydCBqYXZhLnV0aWwuKjsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUHJvamVjdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLio7Ci8qKgogKiBNYWluIGNsYXNzIGZvciBzZXJ2ZXIgY29yZSBBUEkuCiAqIDxwPgogKiBUaGlzIGNsYXNzIHByb3ZpZGVzIEFQSSB0byBhY2Nlc3MgbW9zdCBvZiB0aGUgdHlwZXMgaW4gdGhlIHNlcnZlcgogKiBmcmFtZXdvcmssIGluY2x1ZGluZyBzZXJ2ZXIgcnVudGltZXMgYW5kIHNlcnZlcnMuIE1ldGhvZHMgKioKICogVGhlIG1ldGhvZHMgb24gdGhpcyBjbGFzcyBhcmUgdGhyZWFkIHNhZmUuCiAqIDwvcD4KICogPHA+CiAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgYWxsIGl0cyBmdW5jdGlvbmFsaXR5IHRocm91Z2ggc3RhdGljIG1lbWJlcnMuCiAqIEl0IGlzIG5vdCBpbnRlbmRlZCB0byBiZSBzdWJjbGFzc2VkIG9yIGluc3RhbnRpYXRlZC4KICogPC9wPgogKiAKICogQHNpbmNlIDEuMAogKi8KcHVibGljIGNsYXNzIFNlcnZlckNvcmUgewoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVYVEVOU0lPTl9TRVJWRVJfVFlQRSA9ICJzZXJ2ZXJUeXBlcyI7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVhURU5TSU9OX1JVTlRJTUVfVFlQRSA9ICJydW50aW1lVHlwZXMiOwoKCS8vCWNhY2hlZCBjb3B5IG9mIGFsbCBydW50aW1lIHR5cGVzCglwcml2YXRlIHN0YXRpYyBMaXN0IHJ1bnRpbWVUeXBlczsKCgkvLwljYWNoZWQgY29weSBvZiBhbGwgc2VydmVyIGFuZCBjb25maWd1cmF0aW9uIHR5cGVzCglwcml2YXRlIHN0YXRpYyBMaXN0IHNlcnZlclR5cGVzOwoKCXByaXZhdGUgc3RhdGljIElSZWdpc3RyeUNoYW5nZUxpc3RlbmVyIHJlZ2lzdHJ5TGlzdGVuZXI7CgoJc3RhdGljIHsKCQlleGVjdXRlU3RhcnR1cHMoKTsKCX0KCglwcml2YXRlIHN0YXRpYyBjbGFzcyBSZWdpc3RyeUNoYW5nZUxpc3RlbmVyIGltcGxlbWVudHMgSVJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIgewoJCXB1YmxpYyB2b2lkIHJlZ2lzdHJ5Q2hhbmdlZChJUmVnaXN0cnlDaGFuZ2VFdmVudCBldmVudCkgewoJCQlJRXh0ZW5zaW9uRGVsdGFbXSBkZWx0YXMgPSBldmVudC5nZXRFeHRlbnNpb25EZWx0YXMoU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgRVhURU5TSU9OX1JVTlRJTUVfVFlQRSk7CgkJCWlmIChkZWx0YXMgIT0gbnVsbCkgewoJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBkZWx0YXMubGVuZ3RoOyBpKyspIHsKCQkJCQloYW5kbGVSdW50aW1lVHlwZURlbHRhKGRlbHRhc1tpXSk7CgkJCQl9CgkJCX0KCQkJCgkJCWRlbHRhcyA9IGV2ZW50LmdldEV4dGVuc2lvbkRlbHRhcyhTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCBFWFRFTlNJT05fU0VSVkVSX1RZUEUpOwoJCQlpZiAoZGVsdGFzICE9IG51bGwpIHsKCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgZGVsdGFzLmxlbmd0aDsgaSsrKSB7CgkJCQkJaGFuZGxlU2VydmVyVHlwZURlbHRhKGRlbHRhc1tpXSk7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBDYW5ub3QgY3JlYXRlIFNlcnZlckNvcmUgLSB1c2Ugc3RhdGljIG1ldGhvZHMuCgkgKi8KCXByaXZhdGUgU2VydmVyQ29yZSgpIHsKCQkvLyBjYW4ndCBjcmVhdGUKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHJlc291cmNlIG1hbmFnZXIuCgkgKgoJICogQHJldHVybiBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuUmVzb3VyY2VNYW5hZ2VyCgkgKi8KCXByaXZhdGUgZmluYWwgc3RhdGljIFJlc291cmNlTWFuYWdlciBnZXRSZXNvdXJjZU1hbmFnZXIoKSB7CgkJcmV0dXJuIFJlc291cmNlTWFuYWdlci5nZXRJbnN0YW5jZSgpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcHJlZmVyZW5jZSBpbmZvcm1hdGlvbiBmb3IgdGhlIHByb2plY3QuIFRoZSBwcm9qZWN0IG1heSBub3QKCSAqIGJlIG51bGwuCgkgKgoJICogQHBhcmFtIHByb2plY3QgYSBwcm9qZWN0CgkgKiBAcmV0dXJuIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBwcm9qZWN0CgkgKiBAZGVwcmVjYXRlZCBQcm9qZWN0IGZhY2V0IHN1cHBvcnQgc2hvdWxkIG5vdyBiZSB1c2VkIGluc3RlYWQgb2YgdGhpcyBBUEkuIEBzZWUKCSAqICAgIG9yZy5lY2xpcHNlLndzdC5jb21tb24ucHJvamVjdC5mYWNldC5jb3JlLklGYWNldGVkUHJvamVjdCNnZXRSdW50aW1lKCkKCSAqLwoJcHVibGljIHN0YXRpYyBJUHJvamVjdFByb3BlcnRpZXMgZ2V0UHJvamVjdFByb3BlcnRpZXMoSVByb2plY3QgcHJvamVjdCkgewoJCWlmIChwcm9qZWN0ID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCQlyZXR1cm4gbmV3IElQcm9qZWN0UHJvcGVydGllcygpIHsKCQkJcHVibGljIElSdW50aW1lIGdldFJ1bnRpbWVUYXJnZXQoKSB7CgkJCQlyZXR1cm4gbnVsbDsKCQkJfQoJCX07Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBrbm93biBydW50aW1lIHR5cGVzLgoJICogPHA+CgkgKiBBIG5ldyBhcnJheSBpcyByZXR1cm5lZCBvbiBlYWNoIGNhbGwsIHNvIGNsaWVudHMgbWF5IHN0b3JlIG9yIG1vZGlmeSB0aGUgcmVzdWx0LgoJICogPC9wPgoJICogCgkgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBydW50aW1lIHR5cGVzIHtAbGluayBJUnVudGltZVR5cGV9CgkgKi8KCXB1YmxpYyBzdGF0aWMgSVJ1bnRpbWVUeXBlW10gZ2V0UnVudGltZVR5cGVzKCkgewoJCWlmIChydW50aW1lVHlwZXMgPT0gbnVsbCkKCQkJbG9hZFJ1bnRpbWVUeXBlcygpOwoJCQoJCUlSdW50aW1lVHlwZVtdIHJ0ID0gbmV3IElSdW50aW1lVHlwZVtydW50aW1lVHlwZXMuc2l6ZSgpXTsKCQlydW50aW1lVHlwZXMudG9BcnJheShydCk7CgkJcmV0dXJuIHJ0OwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcnVudGltZSB0eXBlIHdpdGggdGhlIGdpdmVuIGlkLCBvciA8Y29kZT5udWxsPC9jb2RlPgoJICogaWYgbm9uZS4gVGhpcyBjb252ZW5pZW5jZSBtZXRob2Qgc2VhcmNoZXMgdGhlIGxpc3Qgb2Yga25vd24KCSAqIHJ1bnRpbWUgdHlwZXMgKHtAbGluayAjZ2V0UnVudGltZVR5cGVzKCl9KSBmb3IgdGhlIG9uZSB3aXRoIGEgbWF0Y2hpbmcKCSAqIHJ1bnRpbWUgdHlwZSBpZCAoe0BsaW5rIElSdW50aW1lVHlwZSNnZXRJZCgpfSkuIFRoZSBpZCBtYXkgbm90IGJlIG51bGwuCgkgKgoJICogQHBhcmFtIGlkIHRoZSBydW50aW1lIHR5cGUgaWQKCSAqIEByZXR1cm4gdGhlIHJ1bnRpbWUgdHlwZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gcnVudGltZSB0eXBlCgkgKiB3aXRoIHRoZSBnaXZlbiBpZAoJICovCglwdWJsaWMgc3RhdGljIElSdW50aW1lVHlwZSBmaW5kUnVudGltZVR5cGUoU3RyaW5nIGlkKSB7CgkJaWYgKGlkID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCgkJaWYgKHJ1bnRpbWVUeXBlcyA9PSBudWxsKQoJCQlsb2FkUnVudGltZVR5cGVzKCk7CgkJCgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBydW50aW1lVHlwZXMuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlSdW50aW1lVHlwZSBydW50aW1lVHlwZSA9IChJUnVudGltZVR5cGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJaWYgKGlkLmVxdWFscyhydW50aW1lVHlwZS5nZXRJZCgpKSkKCQkJCXJldHVybiBydW50aW1lVHlwZTsKCQl9CgkJcmV0dXJuIG51bGw7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBrbm93biBydW50aW1lIHRhcmdldCBoYW5kbGVyIGluc3RhbmNlcy4KCSAqIDxwPgoJICogQSBuZXcgYXJyYXkgaXMgcmV0dXJuZWQgb24gZWFjaCBjYWxsLCBzbyBjbGllbnRzIG1heSBzdG9yZSBvciBtb2RpZnkgdGhlIHJlc3VsdC4KCSAqIDwvcD4KCSAqIAoJICogQHJldHVybiBhIHBvc3NpYmx5LWVtcHR5IGFycmF5IG9mIHJ1bnRpbWUgdGFyZ2V0IGhhbmRsZXIgaW5zdGFuY2VzCgkgKiAgICB7QGxpbmsgSVJ1bnRpbWVUYXJnZXRIYW5kbGVyfQoJICovCglwdWJsaWMgc3RhdGljIElSdW50aW1lVGFyZ2V0SGFuZGxlcltdIGdldFJ1bnRpbWVUYXJnZXRIYW5kbGVycygpIHsKCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQXR0ZW1wdCB0byB1c2UgZGVwcmVjYXRlZCBjb2RlIik7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBydW50aW1lIHRhcmdldCBoYW5kbGVyIHdpdGggdGhlIGdpdmVuIGlkLCBvciA8Y29kZT5udWxsPC9jb2RlPgoJICogaWYgbm9uZS4gVGhpcyBjb252ZW5pZW5jZSBtZXRob2Qgc2VhcmNoZXMgdGhlIGxpc3Qgb2Yga25vd24gcnVudGltZQoJICogdGFyZ2V0IGhhbmRsZXJzICh7QGxpbmsgI2dldFJ1bnRpbWVUYXJnZXRIYW5kbGVycygpfSkgZm9yIHRoZSBvbmUgd2l0aAoJICogYSBtYXRjaGluZyBydW50aW1lIHRhcmdldCBoYW5kbGVyIGlkICh7QGxpbmsgSVJ1bnRpbWVUYXJnZXRIYW5kbGVyI2dldElkKCl9KS4KCSAqIFRoZSBpZCBtYXkgbm90IGJlIG51bGwuCgkgKgoJICogQHBhcmFtIGlkIHRoZSBydW50aW1lIHRhcmdldCBoYW5kbGVyIGlkCgkgKiBAcmV0dXJuIHRoZSBydW50aW1lIHRhcmdldCBoYW5kbGVyIGluc3RhbmNlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgoJICogICB0aGVyZSBpcyBubyBydW50aW1lIHRhcmdldCBoYW5kbGVyIHdpdGggdGhlIGdpdmVuIGlkCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVJ1bnRpbWVUYXJnZXRIYW5kbGVyIGZpbmRSdW50aW1lVGFyZ2V0SGFuZGxlcihTdHJpbmcgaWQpIHsKCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiQXR0ZW1wdCB0byB1c2UgZGVwcmVjYXRlZCBjb2RlIik7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBrbm93biBzZXJ2ZXIgdHlwZXMuCgkgKiA8cD4KCSAqIEEgbmV3IGFycmF5IGlzIHJldHVybmVkIG9uIGVhY2ggY2FsbCwgc28gY2xpZW50cyBtYXkgc3RvcmUgb3IgbW9kaWZ5IHRoZSByZXN1bHQuCgkgKiA8L3A+CgkgKiAKCSAqIEByZXR1cm4gdGhlIGFycmF5IG9mIHNlcnZlciB0eXBlcyB7QGxpbmsgSVNlcnZlclR5cGV9CgkgKi8KCXB1YmxpYyBzdGF0aWMgSVNlcnZlclR5cGVbXSBnZXRTZXJ2ZXJUeXBlcygpIHsKCQlpZiAoc2VydmVyVHlwZXMgPT0gbnVsbCkKCQkJbG9hZFNlcnZlclR5cGVzKCk7CgkJCgkJSVNlcnZlclR5cGVbXSBzdCA9IG5ldyBJU2VydmVyVHlwZVtzZXJ2ZXJUeXBlcy5zaXplKCldOwoJCXNlcnZlclR5cGVzLnRvQXJyYXkoc3QpOwoJCXJldHVybiBzdDsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHNlcnZlciB0eXBlIHdpdGggdGhlIGdpdmVuIGlkLCBvciA8Y29kZT5udWxsPC9jb2RlPgoJICogaWYgbm9uZS4gVGhpcyBjb252ZW5pZW5jZSBtZXRob2Qgc2VhcmNoZXMgdGhlIGxpc3Qgb2Yga25vd24KCSAqIHNlcnZlciB0eXBlcyAoe0BsaW5rICNnZXRTZXJ2ZXJUeXBlcygpfSkgZm9yIHRoZSBvbmUgd2l0aCBhIG1hdGNoaW5nCgkgKiBzZXJ2ZXIgdHlwZSBpZCAoe0BsaW5rIElTZXJ2ZXJUeXBlI2dldElkKCl9KS4gVGhlIGlkIG1heSBub3QgYmUgbnVsbC4KCSAqCgkgKiBAcGFyYW0gaWQgdGhlIHNlcnZlciB0eXBlIGlkCgkgKiBAcmV0dXJuIHRoZSBzZXJ2ZXIgdHlwZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gc2VydmVyIHR5cGUKCSAqIHdpdGggdGhlIGdpdmVuIGlkCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVNlcnZlclR5cGUgZmluZFNlcnZlclR5cGUoU3RyaW5nIGlkKSB7CgkJaWYgKGlkID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCgkJaWYgKHNlcnZlclR5cGVzID09IG51bGwpCgkJCWxvYWRTZXJ2ZXJUeXBlcygpOwoJCQoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gc2VydmVyVHlwZXMuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlTZXJ2ZXJUeXBlIHNlcnZlclR5cGUgPSAoSVNlcnZlclR5cGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJaWYgKGlkLmVxdWFscyhzZXJ2ZXJUeXBlLmdldElkKCkpKQoJCQkJcmV0dXJuIHNlcnZlclR5cGU7CgkJfQoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogRXhlY3V0ZSB0aGUgc2VydmVyIHN0YXJ0dXAgZXh0ZW5zaW9uIHBvaW50cy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgc3luY2hyb25pemVkIHZvaWQgZXhlY3V0ZVN0YXJ0dXBzKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi0+LSBMb2FkaW5nIC5zdGFydHVwIGV4dGVuc2lvbiBwb2ludCAtPi0iKTsKCQlJRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkgPSBQbGF0Zm9ybS5nZXRFeHRlbnNpb25SZWdpc3RyeSgpOwoJCUlDb25maWd1cmF0aW9uRWxlbWVudFtdIGNmID0gcmVnaXN0cnkuZ2V0Q29uZmlndXJhdGlvbkVsZW1lbnRzRm9yKFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsICJpbnRlcm5hbFN0YXJ0dXAiKTsKCgkJaW50IHNpemUgPSBjZi5sZW5ndGg7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJdHJ5IHsKCQkJCUlTdGFydHVwIHN0YXJ0dXAgPSAoSVN0YXJ0dXApIGNmW2ldLmNyZWF0ZUV4ZWN1dGFibGVFeHRlbnNpb24oImNsYXNzIik7CgkJCQl0cnkgewoJCQkJCXN0YXJ0dXAuc3RhcnR1cCgpOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CgkJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiU3RhcnR1cCBmYWlsZWQiICsgc3RhcnR1cC50b1N0cmluZygpLCBleCk7CgkJCQl9CgkJCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICIgIExvYWRlZCBzdGFydHVwOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpKTsKCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgQ291bGQgbm90IGxvYWQgc3RhcnR1cDogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSwgdCk7CgkJCX0KCQl9CgkJCgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLTwtIERvbmUgbG9hZGluZyAuc3RhcnR1cCBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgoJLyoqCgkgKiBMb2FkIHRoZSBydW50aW1lIHR5cGVzLgoJICovCglwcml2YXRlIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBsb2FkUnVudGltZVR5cGVzKCkgewoJCWlmIChydW50aW1lVHlwZXMgIT0gbnVsbCkKCQkJcmV0dXJuOwoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi0+LSBMb2FkaW5nIC5ydW50aW1lVHlwZXMgZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCQoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgRVhURU5TSU9OX1JVTlRJTUVfVFlQRSk7CgkJcnVudGltZVR5cGVzID0gbmV3IEFycmF5TGlzdChjZi5sZW5ndGgpOwoJCWFkZFJ1bnRpbWVUeXBlcyhjZik7CgkJYWRkUmVnaXN0cnlMaXN0ZW5lcigpOwoJCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLnJ1bnRpbWVUeXBlcyBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgoJLyoqCgkgKiBMb2FkIHRoZSBydW50aW1lIHR5cGVzLgoJICovCglwcml2YXRlIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRSdW50aW1lVHlwZXMoSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YpIHsKCQlmb3IgKGludCBpID0gMDsgaSA8IGNmLmxlbmd0aDsgaSsrKSB7CgkJCXRyeSB7CgkJCQlSdW50aW1lVHlwZSBydW50aW1lVHlwZSA9IG5ldyBSdW50aW1lVHlwZShjZltpXSk7CgkJCQlydW50aW1lVHlwZXMuYWRkKHJ1bnRpbWVUeXBlKTsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIiAgTG9hZGVkIHJ1bnRpbWVUeXBlOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpKTsKCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgQ291bGQgbm90IGxvYWQgcnVudGltZVR5cGU6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIiksIHQpOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogTG9hZCB0aGUgc2VydmVyIHR5cGVzLgoJICovCglwcml2YXRlIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBsb2FkU2VydmVyVHlwZXMoKSB7CgkJaWYgKHNlcnZlclR5cGVzICE9IG51bGwpCgkJCXJldHVybjsKCQkKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPi0gTG9hZGluZyAuc2VydmVyVHlwZXMgZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCQoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgRVhURU5TSU9OX1NFUlZFUl9UWVBFKTsKCQlzZXJ2ZXJUeXBlcyA9IG5ldyBBcnJheUxpc3QoY2YubGVuZ3RoKTsKCQlhZGRTZXJ2ZXJUeXBlcyhjZik7CgkJYWRkUmVnaXN0cnlMaXN0ZW5lcigpOwoJCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLnNlcnZlclR5cGVzIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KCgkvKioKCSAqIExvYWQgdGhlIHNlcnZlciB0eXBlcy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgc3luY2hyb25pemVkIHZvaWQgYWRkU2VydmVyVHlwZXMoSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YpIHsKCQlmb3IgKGludCBpID0gMDsgaSA8IGNmLmxlbmd0aDsgaSsrKSB7CgkJCXRyeSB7CgkJCQlTZXJ2ZXJUeXBlIHNlcnZlclR5cGUgPSBuZXcgU2VydmVyVHlwZShjZltpXSk7CgkJCQlzZXJ2ZXJUeXBlcy5hZGQoc2VydmVyVHlwZSk7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICIgIExvYWRlZCBzZXJ2ZXJUeXBlOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpKTsKCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgQ291bGQgbm90IGxvYWQgc2VydmVyVHlwZTogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSwgdCk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBydW50aW1lIHdpdGggdGhlIGdpdmVuIGlkLCBvciA8Y29kZT5udWxsPC9jb2RlPgoJICogaWYgbm9uZS4gVGhpcyBjb252ZW5pZW5jZSBtZXRob2Qgc2VhcmNoZXMgdGhlIGxpc3Qgb2Yga25vd24KCSAqIHJ1bnRpbWVzICh7QGxpbmsgI2dldFJ1bnRpbWVzKCl9KSBmb3IgdGhlIG9uZSB3aXRoIGEgbWF0Y2hpbmcKCSAqIHJ1bnRpbWUgaWQgKHtAbGluayBJUnVudGltZSNnZXRJZCgpfSkuIFRoZSBpZCBtYXkgbm90IGJlIG51bGwuCgkgKgoJICogQHBhcmFtIGlkIHRoZSBydW50aW1lIGlkCgkgKiBAcmV0dXJuIHRoZSBydW50aW1lIGluc3RhbmNlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBydW50aW1lCgkgKiB3aXRoIHRoZSBnaXZlbiBpZAoJICovCglwdWJsaWMgc3RhdGljIElSdW50aW1lIGZpbmRSdW50aW1lKFN0cmluZyBpZCkgewoJCXJldHVybiBnZXRSZXNvdXJjZU1hbmFnZXIoKS5nZXRSdW50aW1lKGlkKTsKCX0KCgkvKioKCSAqIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIGtub3duIHJ1bnRpbWUgaW5zdGFuY2VzLiBUaGUgbGlzdCB3aWxsIG5vdCBjb250YWluIGFueQoJICogd29ya2luZyBjb3BpZXMuCgkgKiA8cD4KCSAqIEEgbmV3IGFycmF5IGlzIHJldHVybmVkIG9uIGVhY2ggY2FsbCwgc28gY2xpZW50cyBtYXkgc3RvcmUgb3IgbW9kaWZ5IHRoZSByZXN1bHQuCgkgKiA8L3A+CgkgKiAKCSAqIEByZXR1cm4gYSBwb3NzaWJseS1lbXB0eSBhcnJheSBvZiBydW50aW1lIGluc3RhbmNlcyB7QGxpbmsgSVJ1bnRpbWV9CgkgKi8KCXB1YmxpYyBzdGF0aWMgSVJ1bnRpbWVbXSBnZXRSdW50aW1lcygpIHsKCQlyZXR1cm4gZ2V0UmVzb3VyY2VNYW5hZ2VyKCkuZ2V0UnVudGltZXMoKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHNlcnZlciB3aXRoIHRoZSBnaXZlbiBpZCwgb3IgPGNvZGU+bnVsbDwvY29kZT4KCSAqIGlmIG5vbmUuIFRoaXMgY29udmVuaWVuY2UgbWV0aG9kIHNlYXJjaGVzIHRoZSBsaXN0IG9mIGtub3duCgkgKiBzZXJ2ZXJzICh7QGxpbmsgI2dldFNlcnZlcnMoKX0pIGZvciB0aGUgb25lIHdpdGggYSBtYXRjaGluZwoJICogc2VydmVyIGlkICh7QGxpbmsgSVNlcnZlciNnZXRJZCgpfSkuIFRoZSBpZCBtdXN0IG5vdCBiZSBudWxsLgoJICoKCSAqIEBwYXJhbSBpZCB0aGUgc2VydmVyIGlkCgkgKiBAcmV0dXJuIHRoZSBzZXJ2ZXIgaW5zdGFuY2UsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGlzIG5vIHNlcnZlcgoJICogd2l0aCB0aGUgZ2l2ZW4gaWQKCSAqLwoJcHVibGljIHN0YXRpYyBJU2VydmVyIGZpbmRTZXJ2ZXIoU3RyaW5nIGlkKSB7CgkJcmV0dXJuIGdldFJlc291cmNlTWFuYWdlcigpLmdldFNlcnZlcihpZCk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBrbm93biBzZXJ2ZXIgaW5zdGFuY2VzLiBUaGUgYXJyYXkgd2lsbCBub3QgaW5jbHVkZSBhbnkKCSAqIHdvcmtpbmcgY29waWVzLgoJICogPHA+CgkgKiBBIG5ldyBhcnJheSBpcyByZXR1cm5lZCBvbiBlYWNoIGNhbGwsIHNvIGNsaWVudHMgbWF5IHN0b3JlIG9yIG1vZGlmeSB0aGUgcmVzdWx0LgoJICogPC9wPgoJICogCgkgKiBAcmV0dXJuIGEgcG9zc2libHktZW1wdHkgYXJyYXkgb2Ygc2VydmVyIGluc3RhbmNlcyB7QGxpbmsgSVNlcnZlcn0KCSAqLwoJcHVibGljIHN0YXRpYyBJU2VydmVyW10gZ2V0U2VydmVycygpIHsKCQlyZXR1cm4gZ2V0UmVzb3VyY2VNYW5hZ2VyKCkuZ2V0U2VydmVycygpOwoJfQoKCS8qKgoJICogQWRkcyBhIG5ldyBydW50aW1lIGxpZmVjeWNsZSBsaXN0ZW5lci4KCSAqIEhhcyBubyBlZmZlY3QgaWYgYW4gaWRlbnRpY2FsIGxpc3RlbmVyIGlzIGFscmVhZHkgcmVnaXN0ZXJlZC4KCSAqCgkgKiBAcGFyYW0gbGlzdGVuZXIgYSBydW50aW1lIGxpZmVjeWNsZSBsaXN0ZW5lcgoJICogQHNlZSAjcmVtb3ZlUnVudGltZUxpZmVjeWNsZUxpc3RlbmVyKElSdW50aW1lTGlmZWN5Y2xlTGlzdGVuZXIpCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCBhZGRSdW50aW1lTGlmZWN5Y2xlTGlzdGVuZXIoSVJ1bnRpbWVMaWZlY3ljbGVMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWdldFJlc291cmNlTWFuYWdlcigpLmFkZFJ1bnRpbWVMaWZlY3ljbGVMaXN0ZW5lcihsaXN0ZW5lcik7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIGEgcnVudGltZSBsaWZlY3ljbGUgbGlzdGVuZXIuCgkgKiBIYXMgbm8gZWZmZWN0IGlmIHRoZSBsaXN0ZW5lciBpcyBub3QgcmVnaXN0ZXJlZC4KCSAqCgkgKiBAcGFyYW0gbGlzdGVuZXIgYSBydW50aW1lIGxpZmVjeWNsZSBsaXN0ZW5lcgoJICogQHNlZSAjYWRkUnVudGltZUxpZmVjeWNsZUxpc3RlbmVyKElSdW50aW1lTGlmZWN5Y2xlTGlzdGVuZXIpCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCByZW1vdmVSdW50aW1lTGlmZWN5Y2xlTGlzdGVuZXIoSVJ1bnRpbWVMaWZlY3ljbGVMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWdldFJlc291cmNlTWFuYWdlcigpLnJlbW92ZVJ1bnRpbWVMaWZlY3ljbGVMaXN0ZW5lcihsaXN0ZW5lcik7Cgl9CgoJLyoqCgkgKiBBZGRzIGEgbmV3IHNlcnZlciBsaWZlY3ljbGUgbGlzdGVuZXIuCgkgKiBIYXMgbm8gZWZmZWN0IGlmIGFuIGlkZW50aWNhbCBsaXN0ZW5lciBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQuCgkgKgoJICogQHBhcmFtIGxpc3RlbmVyIGEgc2VydmVyIGxpZmVjeWNsZSBsaXN0ZW5lcgoJICogQHNlZSAjcmVtb3ZlU2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIoSVNlcnZlckxpZmVjeWNsZUxpc3RlbmVyKQoJICovCglwdWJsaWMgc3RhdGljIHZvaWQgYWRkU2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIoSVNlcnZlckxpZmVjeWNsZUxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJZ2V0UmVzb3VyY2VNYW5hZ2VyKCkuYWRkU2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIobGlzdGVuZXIpOwoJfQoKCS8qKgoJICogUmVtb3ZlcyBhIHNlcnZlciBsaWZlY3ljbGUgbGlzdGVuZXIuCgkgKiBIYXMgbm8gZWZmZWN0IGlmIHRoZSBsaXN0ZW5lciBpcyBub3QgcmVnaXN0ZXJlZC4KCSAqCgkgKiBAcGFyYW0gbGlzdGVuZXIgYSBzZXJ2ZXIgbGlmZWN5Y2xlIGxpc3RlbmVyCgkgKiAjYWRkU2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIoSVNlcnZlckxpZmVjeWNsZUxpc3RlbmVyKQoJICovCglwdWJsaWMgc3RhdGljIHZvaWQgcmVtb3ZlU2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIoSVNlcnZlckxpZmVjeWNsZUxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJZ2V0UmVzb3VyY2VNYW5hZ2VyKCkucmVtb3ZlU2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIobGlzdGVuZXIpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcHJlZmVycmVkIHJ1bnRpbWUgc2VydmVyIGZvciB0aGUgZ2l2ZW4gbW9kdWxlLiBUaGlzIG1ldGhvZAoJICogcmV0dXJucyBudWxsIGlmIHRoZSBzZXJ2ZXIgd2FzIG5ldmVyIGNob3NlbiBvciBkb2VzIG5vdCBjdXJyZW50bHkgZXhpc3QuIChpZiB0aGUKCSAqIHNlcnZlciBpcyByZWNyZWF0ZWQgb3Igd2FzIGluIGEgY2xvc2VkIHByb2plY3QsIGV0Yy4gdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4KCSAqIHRoZSBvcmlnaW5hbCB2YWx1ZSBpZiBpdCBiZWNvbWVzIGF2YWlsYWJsZSBhZ2FpbikKCSAqCgkgKiBAcGFyYW0gbW9kdWxlIGEgbW9kdWxlCgkgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGRlZmF1bHQgc2VydmVyLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBpcyBubwoJICogICAgZGVmYXVsdCBzZXJ2ZXIKCSAqLwoJcHVibGljIHN0YXRpYyBJU2VydmVyIGdldERlZmF1bHRTZXJ2ZXIoSU1vZHVsZSBtb2R1bGUpIHsKCQlyZXR1cm4gTW9kdWxlUHJvcGVydGllcy5nZXRJbnN0YW5jZSgpLmdldERlZmF1bHRTZXJ2ZXIobW9kdWxlKTsKCX0KCgkvKioKCSAqIFNldHMgdGhlIHByZWZlcnJlZCBydW50aW1lIHNlcnZlciBmb3IgdGhlIGdpdmVuIG1vZHVsZS4gU2V0IHRoZSBzZXJ2ZXIgdG8KCSAqIG51bGwgdG8gY2xlYXIgdGhlIHNldHRpbmcuIElmIHRoZXJlIGlzIGEgcHJvYmxlbSBzYXZpbmcgdGhlIGZpbGUsIGEgQ29yZUV4Y2VwdGlvbgoJICogd2lsbCBiZSB0aHJvd24uCgkgKiAKCSAqIEBwYXJhbSBtb2R1bGUgdGhlIG1vZHVsZSB0byBzZXQgdGhlIGRlZmF1bHQgZm9yCgkgKiBAcGFyYW0gc2VydmVyIHRoZSBzZXJ2ZXIgdG8gc2V0IHRoZSBkZWZhdWx0IHNlcnZlciwgb3IgPGNvZGU+bnVsbDwvY29kZT4KCSAqICAgIHRvIHVuc2V0IHRoZSBkZWZhdWx0CgkgKiBAcGFyYW0gbW9uaXRvciBhIHByb2dyZXNzIG1vbml0b3IsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHByb2dyZXNzCgkgKiAgICByZXBvcnRpbmcgYW5kIGNhbmNlbGxhdGlvbiBhcmUgbm90IGRlc2lyZWQKCSAqIEB0aHJvd3MgQ29yZUV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0gc2V0dGluZyB0aGUgZGVmYXVsdCBzZXJ2ZXIKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIHNldERlZmF1bHRTZXJ2ZXIoSU1vZHVsZSBtb2R1bGUsIElTZXJ2ZXIgc2VydmVyLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlNb2R1bGVQcm9wZXJ0aWVzLmdldEluc3RhbmNlKCkuc2V0RGVmYXVsdFNlcnZlcihtb2R1bGUsIHNlcnZlciwgbW9uaXRvcik7Cgl9CgoJLyoqCgkgKiBIYW5kbGVzIGEgY2hhbmdlIHRvIHRoZSBzZXJ2ZXIgdHlwZSBleHRlbnNpb24gcG9pbnQgZHVlIHRvIGJ1bmRsZXMgZ2V0dGluZyBhZGRlZAoJICogb3IgcmVtb3ZlZCBkeW5hbWljYWxseSBhdCBydW50aW1lLgoJICogCgkgKiBAcGFyYW0gZGVsdGEgYW4gZXh0ZW5zaW9uIGRlbHRhCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgdm9pZCBoYW5kbGVTZXJ2ZXJUeXBlRGVsdGEoSUV4dGVuc2lvbkRlbHRhIGRlbHRhKSB7CgkJaWYgKHNlcnZlclR5cGVzID09IG51bGwpIC8vIG5vdCBsb2FkZWQgeWV0CgkJCXJldHVybjsKCQkKCQlJQ29uZmlndXJhdGlvbkVsZW1lbnRbXSBjZiA9IGRlbHRhLmdldEV4dGVuc2lvbigpLmdldENvbmZpZ3VyYXRpb25FbGVtZW50cygpOwoJCQoJCWlmIChkZWx0YS5nZXRLaW5kKCkgPT0gSUV4dGVuc2lvbkRlbHRhLkFEREVEKSB7CgkJCWFkZFNlcnZlclR5cGVzKGNmKTsKCQl9IGVsc2UgewoJCQlpbnQgc2l6ZSA9IHNlcnZlclR5cGVzLnNpemUoKTsKCQkJU2VydmVyVHlwZVtdIHN0ID0gbmV3IFNlcnZlclR5cGVbc2l6ZV07CgkJCXNlcnZlclR5cGVzLnRvQXJyYXkoc3QpOwoJCQlpbnQgc2l6ZTIgPSBjZi5sZW5ndGg7CgkJCQoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCQkJaWYgKHN0W2ldLmdldElkKCkuZXF1YWxzKGNmW2pdLmdldEF0dHJpYnV0ZSgiaWQiKSkpIHsKCQkJCQkJc3RbaV0uZGlzcG9zZSgpOwoJCQkJCQlzZXJ2ZXJUeXBlcy5yZW1vdmUoc3RbaV0pOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCQlnZXRSZXNvdXJjZU1hbmFnZXIoKS5yZXNvbHZlU2VydmVycygpOwoJfQoKCS8qKgoJICogSGFuZGxlcyBhIGNoYW5nZSB0byB0aGUgcnVudGltZSB0eXBlIGV4dGVuc2lvbiBwb2ludCBkdWUgdG8gYnVuZGxlcyBnZXR0aW5nIGFkZGVkCgkgKiBvciByZW1vdmVkIGR5bmFtaWNhbGx5IGF0IHJ1bnRpbWUuCgkgKiAKCSAqIEBwYXJhbSBkZWx0YSBhbiBleHRlbnNpb24gZGVsdGEKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyB2b2lkIGhhbmRsZVJ1bnRpbWVUeXBlRGVsdGEoSUV4dGVuc2lvbkRlbHRhIGRlbHRhKSB7CgkJaWYgKHJ1bnRpbWVUeXBlcyA9PSBudWxsKSAvLyBub3QgbG9hZGVkIHlldAoJCQlyZXR1cm47CgkJCgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSBkZWx0YS5nZXRFeHRlbnNpb24oKS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHMoKTsKCQkKCQlpZiAoZGVsdGEuZ2V0S2luZCgpID09IElFeHRlbnNpb25EZWx0YS5BRERFRCkgewoJCQlhZGRSdW50aW1lVHlwZXMoY2YpOwoJCX0gZWxzZSB7CgkJCWludCBzaXplID0gcnVudGltZVR5cGVzLnNpemUoKTsKCQkJUnVudGltZVR5cGVbXSBydCA9IG5ldyBSdW50aW1lVHlwZVtzaXplXTsKCQkJcnVudGltZVR5cGVzLnRvQXJyYXkocnQpOwoJCQlpbnQgc2l6ZTIgPSBjZi5sZW5ndGg7CgkJCQoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCQkJaWYgKHJ0W2ldLmdldElkKCkuZXF1YWxzKGNmW2pdLmdldEF0dHJpYnV0ZSgiaWQiKSkpIHsKCQkJCQkJcnRbaV0uZGlzcG9zZSgpOwoJCQkJCQlydW50aW1lVHlwZXMucmVtb3ZlKHJ0W2ldKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgkJZ2V0UmVzb3VyY2VNYW5hZ2VyKCkucmVzb2x2ZVJ1bnRpbWVzKCk7CgkJZ2V0UmVzb3VyY2VNYW5hZ2VyKCkucmVzb2x2ZVNlcnZlcnMoKTsKCX0KCglwcml2YXRlIHN0YXRpYyB2b2lkIGFkZFJlZ2lzdHJ5TGlzdGVuZXIoKSB7CgkJaWYgKHJlZ2lzdHJ5TGlzdGVuZXIgIT0gbnVsbCkKCQkJcmV0dXJuOwoJCQoJCXJlZ2lzdHJ5TGlzdGVuZXIgPSBuZXcgUmVnaXN0cnlDaGFuZ2VMaXN0ZW5lcigpOwoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJcmVnaXN0cnkuYWRkUmVnaXN0cnlDaGFuZ2VMaXN0ZW5lcihyZWdpc3RyeUxpc3RlbmVyLCBTZXJ2ZXJQbHVnaW4uUExVR0lOX0lEKTsKCQlTZXJ2ZXJQbHVnaW4uc2V0UmVnaXN0cnlMaXN0ZW5lcihyZWdpc3RyeUxpc3RlbmVyKTsKCX0KfQ==