LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZTsKCmltcG9ydCBqYXZhLnV0aWwuKjsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuKjsKLyoqCiAqIE1haW4gY2xhc3MgZm9yIHNlcnZlciBjb3JlIEFQSS4KICogPHA+CiAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgQVBJIHRvIGFjY2VzcyBtb3N0IG9mIHRoZSB0eXBlcyBpbiB0aGUgc2VydmVyCiAqIGZyYW1ld29yaywgaW5jbHVkaW5nIHNlcnZlciBydW50aW1lcyBhbmQgc2VydmVycy4gTWV0aG9kcyAqKgogKiBUaGUgbWV0aG9kcyBvbiB0aGlzIGNsYXNzIGFyZSB0aHJlYWQgc2FmZS4KICogPC9wPgogKiA8cD4KICogVGhpcyBjbGFzcyBwcm92aWRlcyBhbGwgaXRzIGZ1bmN0aW9uYWxpdHkgdGhyb3VnaCBzdGF0aWMgbWVtYmVycy4KICogSXQgaXMgbm90IGludGVuZGVkIHRvIGJlIHN1YmNsYXNzZWQgb3IgaW5zdGFudGlhdGVkLgogKiA8L3A+CiAqIDxwPgogKiA8aXQ+Q2F2ZWF0OiBUaGUgc2VydmVyIGNvcmUgQVBJIGlzIHN0aWxsIGluIGFuIGVhcmx5IGZvcm0sIGFuZCBpcwogKiBsaWtlbHkgdG8gY2hhbmdlIHNpZ25pZmljYW50bHkgYmVmb3JlIHRoZSBpbml0aWFsIHJlbGVhc2UuPC9pdD4KICogPC9wPgogKiAKICogQHNpbmNlIDEuMAogKi8KcHVibGljIGNsYXNzIFNlcnZlckNvcmUgewoJLy8JY2FjaGVkIGNvcHkgb2YgYWxsIHJ1bnRpbWUgdHlwZXMKCXByaXZhdGUgc3RhdGljIExpc3QgcnVudGltZVR5cGVzOwoJCgkvLwljYWNoZWQgY29weSBvZiBhbGwgcnVudGltZSB0YXJnZXQgaGFuZGxlcnMKCXByaXZhdGUgc3RhdGljIExpc3QgcnVudGltZVRhcmdldEhhbmRsZXJzOwoKCS8vCWNhY2hlZCBjb3B5IG9mIGFsbCBzZXJ2ZXIgYW5kIGNvbmZpZ3VyYXRpb24gdHlwZXMKCXByaXZhdGUgc3RhdGljIExpc3Qgc2VydmVyVHlwZXM7CgoJc3RhdGljIHsKCQlleGVjdXRlU3RhcnR1cHMoKTsKCX0KCgkvKioKCSAqIENhbm5vdCBjcmVhdGUgU2VydmVyQ29yZSAtIHVzZSBzdGF0aWMgbWV0aG9kcy4KCSAqLwoJcHJpdmF0ZSBTZXJ2ZXJDb3JlKCkgewoJCS8vIGNhbid0IGNyZWF0ZQoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcmVzb3VyY2UgbWFuYWdlci4KCSAqCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5SZXNvdXJjZU1hbmFnZXIKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgUmVzb3VyY2VNYW5hZ2VyIGdldFJlc291cmNlTWFuYWdlcigpIHsKCQlyZXR1cm4gUmVzb3VyY2VNYW5hZ2VyLmdldEluc3RhbmNlKCk7Cgl9CgkKCS8qKgoJICogUmV0dXJucyB0aGUgcHJlZmVyZW5jZSBpbmZvcm1hdGlvbiBmb3IgdGhlIHByb2plY3QuIFRoZSBwcm9qZWN0IG1heSBub3QKCSAqIGJlIG51bGwuCgkgKgoJICogQHBhcmFtIHByb2plY3QgYSBwcm9qZWN0CgkgKiBAcmV0dXJuIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBwcm9qZWN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgSVByb2plY3RQcm9wZXJ0aWVzIGdldFByb2plY3RQcm9wZXJ0aWVzKElQcm9qZWN0IHByb2plY3QpIHsKCQlpZiAocHJvamVjdCA9PSBudWxsKQoJCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CgkJcmV0dXJuIG5ldyBQcm9qZWN0UHJvcGVydGllcyhwcm9qZWN0KTsKCX0KCgkvKioKCSAqIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIGtub3duIHJ1bnRpbWUgdHlwZXMuCgkgKiA8cD4KCSAqIEEgbmV3IGFycmF5IGlzIHJldHVybmVkIG9uIGVhY2ggY2FsbCwgc28gY2xpZW50cyBtYXkgc3RvcmUgb3IgbW9kaWZ5IHRoZSByZXN1bHQuCgkgKiA8L3A+CgkgKiAKCSAqIEByZXR1cm4gdGhlIGFycmF5IG9mIHJ1bnRpbWUgdHlwZXMge0BsaW5rIElSdW50aW1lVHlwZX0KCSAqLwoJcHVibGljIHN0YXRpYyBJUnVudGltZVR5cGVbXSBnZXRSdW50aW1lVHlwZXMoKSB7CgkJaWYgKHJ1bnRpbWVUeXBlcyA9PSBudWxsKQoJCQlsb2FkUnVudGltZVR5cGVzKCk7CgkJCgkJSVJ1bnRpbWVUeXBlW10gcnQgPSBuZXcgSVJ1bnRpbWVUeXBlW3J1bnRpbWVUeXBlcy5zaXplKCldOwoJCXJ1bnRpbWVUeXBlcy50b0FycmF5KHJ0KTsKCQlyZXR1cm4gcnQ7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBydW50aW1lIHR5cGUgd2l0aCB0aGUgZ2l2ZW4gaWQsIG9yIDxjb2RlPm51bGw8L2NvZGU+CgkgKiBpZiBub25lLiBUaGlzIGNvbnZlbmllbmNlIG1ldGhvZCBzZWFyY2hlcyB0aGUgbGlzdCBvZiBrbm93bgoJICogcnVudGltZSB0eXBlcyAoe0BsaW5rICNnZXRSdW50aW1lVHlwZXMoKX0pIGZvciB0aGUgb25lIHdpdGggYSBtYXRjaGluZwoJICogcnVudGltZSB0eXBlIGlkICh7QGxpbmsgSVJ1bnRpbWVUeXBlI2dldElkKCl9KS4gVGhlIGlkIG1heSBub3QgYmUgbnVsbC4KCSAqCgkgKiBAcGFyYW0gaWQgdGhlIHJ1bnRpbWUgdHlwZSBpZAoJICogQHJldHVybiB0aGUgcnVudGltZSB0eXBlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBydW50aW1lIHR5cGUKCSAqIHdpdGggdGhlIGdpdmVuIGlkCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVJ1bnRpbWVUeXBlIGZpbmRSdW50aW1lVHlwZShTdHJpbmcgaWQpIHsKCQlpZiAoaWQgPT0gbnVsbCkKCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoKCQlpZiAocnVudGltZVR5cGVzID09IG51bGwpCgkJCWxvYWRSdW50aW1lVHlwZXMoKTsKCQkKCQlJdGVyYXRvciBpdGVyYXRvciA9IHJ1bnRpbWVUeXBlcy5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSVJ1bnRpbWVUeXBlIHJ1bnRpbWVUeXBlID0gKElSdW50aW1lVHlwZSkgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAoaWQuZXF1YWxzKHJ1bnRpbWVUeXBlLmdldElkKCkpKQoJCQkJcmV0dXJuIHJ1bnRpbWVUeXBlOwoJCX0KCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIGtub3duIHJ1bnRpbWUgdGFyZ2V0IGhhbmRsZXIgaW5zdGFuY2VzLgoJICogPHA+CgkgKiBBIG5ldyBhcnJheSBpcyByZXR1cm5lZCBvbiBlYWNoIGNhbGwsIHNvIGNsaWVudHMgbWF5IHN0b3JlIG9yIG1vZGlmeSB0aGUgcmVzdWx0LgoJICogPC9wPgoJICogCgkgKiBAcmV0dXJuIGEgcG9zc2libHktZW1wdHkgYXJyYXkgb2YgcnVudGltZSB0YXJnZXQgaGFuZGxlciBpbnN0YW5jZXMKCSAqICAgIHtAbGluayBJUnVudGltZVRhcmdldEhhbmRsZXJ9CgkgKi8KCXB1YmxpYyBzdGF0aWMgSVJ1bnRpbWVUYXJnZXRIYW5kbGVyW10gZ2V0UnVudGltZVRhcmdldEhhbmRsZXJzKCkgewoJCWlmIChydW50aW1lVGFyZ2V0SGFuZGxlcnMgPT0gbnVsbCkKCQkJbG9hZFJ1bnRpbWVUYXJnZXRIYW5kbGVycygpOwoJCQoJCUlSdW50aW1lVGFyZ2V0SGFuZGxlcltdIHJ0aCA9IG5ldyBJUnVudGltZVRhcmdldEhhbmRsZXJbcnVudGltZVRhcmdldEhhbmRsZXJzLnNpemUoKV07CgkJcnVudGltZVRhcmdldEhhbmRsZXJzLnRvQXJyYXkocnRoKTsKCQlyZXR1cm4gcnRoOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcnVudGltZSB0YXJnZXQgaGFuZGxlciB3aXRoIHRoZSBnaXZlbiBpZCwgb3IgPGNvZGU+bnVsbDwvY29kZT4KCSAqIGlmIG5vbmUuIFRoaXMgY29udmVuaWVuY2UgbWV0aG9kIHNlYXJjaGVzIHRoZSBsaXN0IG9mIGtub3duIHJ1bnRpbWUKCSAqIHRhcmdldCBoYW5kbGVycyAoe0BsaW5rICNnZXRSdW50aW1lVGFyZ2V0SGFuZGxlcnMoKX0pIGZvciB0aGUgb25lIHdpdGgKCSAqIGEgbWF0Y2hpbmcgcnVudGltZSB0YXJnZXQgaGFuZGxlciBpZCAoe0BsaW5rIElSdW50aW1lVGFyZ2V0SGFuZGxlciNnZXRJZCgpfSkuCgkgKiBUaGUgaWQgbWF5IG5vdCBiZSBudWxsLgoJICoKCSAqIEBwYXJhbSBpZCB0aGUgcnVudGltZSB0YXJnZXQgaGFuZGxlciBpZAoJICogQHJldHVybiB0aGUgcnVudGltZSB0YXJnZXQgaGFuZGxlciBpbnN0YW5jZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYKCSAqICAgdGhlcmUgaXMgbm8gcnVudGltZSB0YXJnZXQgaGFuZGxlciB3aXRoIHRoZSBnaXZlbiBpZAoJICovCglwdWJsaWMgc3RhdGljIElSdW50aW1lVGFyZ2V0SGFuZGxlciBmaW5kUnVudGltZVRhcmdldEhhbmRsZXIoU3RyaW5nIGlkKSB7CgkJaWYgKGlkID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCgkJaWYgKHJ1bnRpbWVUYXJnZXRIYW5kbGVycyA9PSBudWxsKQoJCQlsb2FkUnVudGltZVRhcmdldEhhbmRsZXJzKCk7CgkJCgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBydW50aW1lVGFyZ2V0SGFuZGxlcnMuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlSdW50aW1lVGFyZ2V0SGFuZGxlciBydW50aW1lVGFyZ2V0TGlzdGVuZXIgPSAoSVJ1bnRpbWVUYXJnZXRIYW5kbGVyKSBpdGVyYXRvci5uZXh0KCk7CgkJCWlmIChpZC5lcXVhbHMocnVudGltZVRhcmdldExpc3RlbmVyLmdldElkKCkpKQoJCQkJcmV0dXJuIHJ1bnRpbWVUYXJnZXRMaXN0ZW5lcjsKCQl9CgkJcmV0dXJuIG51bGw7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBrbm93biBzZXJ2ZXIgdHlwZXMuCgkgKiA8cD4KCSAqIEEgbmV3IGFycmF5IGlzIHJldHVybmVkIG9uIGVhY2ggY2FsbCwgc28gY2xpZW50cyBtYXkgc3RvcmUgb3IgbW9kaWZ5IHRoZSByZXN1bHQuCgkgKiA8L3A+CgkgKiAKCSAqIEByZXR1cm4gdGhlIGFycmF5IG9mIHNlcnZlciB0eXBlcyB7QGxpbmsgSVNlcnZlclR5cGV9CgkgKi8KCXB1YmxpYyBzdGF0aWMgSVNlcnZlclR5cGVbXSBnZXRTZXJ2ZXJUeXBlcygpIHsKCQlpZiAoc2VydmVyVHlwZXMgPT0gbnVsbCkKCQkJbG9hZFNlcnZlclR5cGVzKCk7CgkJCgkJSVNlcnZlclR5cGVbXSBzdCA9IG5ldyBJU2VydmVyVHlwZVtzZXJ2ZXJUeXBlcy5zaXplKCldOwoJCXNlcnZlclR5cGVzLnRvQXJyYXkoc3QpOwoJCXJldHVybiBzdDsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHNlcnZlciB0eXBlIHdpdGggdGhlIGdpdmVuIGlkLCBvciA8Y29kZT5udWxsPC9jb2RlPgoJICogaWYgbm9uZS4gVGhpcyBjb252ZW5pZW5jZSBtZXRob2Qgc2VhcmNoZXMgdGhlIGxpc3Qgb2Yga25vd24KCSAqIHNlcnZlciB0eXBlcyAoe0BsaW5rICNnZXRTZXJ2ZXJUeXBlcygpfSkgZm9yIHRoZSBvbmUgd2l0aCBhIG1hdGNoaW5nCgkgKiBzZXJ2ZXIgdHlwZSBpZCAoe0BsaW5rIElTZXJ2ZXJUeXBlI2dldElkKCl9KS4gVGhlIGlkIG1heSBub3QgYmUgbnVsbC4KCSAqCgkgKiBAcGFyYW0gaWQgdGhlIHNlcnZlciB0eXBlIGlkCgkgKiBAcmV0dXJuIHRoZSBzZXJ2ZXIgdHlwZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gc2VydmVyIHR5cGUKCSAqIHdpdGggdGhlIGdpdmVuIGlkCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVNlcnZlclR5cGUgZmluZFNlcnZlclR5cGUoU3RyaW5nIGlkKSB7CgkJaWYgKGlkID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCgkJaWYgKHNlcnZlclR5cGVzID09IG51bGwpCgkJCWxvYWRTZXJ2ZXJUeXBlcygpOwoJCQoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gc2VydmVyVHlwZXMuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlTZXJ2ZXJUeXBlIHNlcnZlclR5cGUgPSAoSVNlcnZlclR5cGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJaWYgKGlkLmVxdWFscyhzZXJ2ZXJUeXBlLmdldElkKCkpKQoJCQkJcmV0dXJuIHNlcnZlclR5cGU7CgkJfQoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogRXhlY3V0ZSB0aGUgc2VydmVyIHN0YXJ0dXAgZXh0ZW5zaW9uIHBvaW50cy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgc3luY2hyb25pemVkIHZvaWQgZXhlY3V0ZVN0YXJ0dXBzKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi0+LSBMb2FkaW5nIC5zdGFydHVwIGV4dGVuc2lvbiBwb2ludCAtPi0iKTsKCQlJRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkgPSBQbGF0Zm9ybS5nZXRFeHRlbnNpb25SZWdpc3RyeSgpOwoJCUlDb25maWd1cmF0aW9uRWxlbWVudFtdIGNmID0gcmVnaXN0cnkuZ2V0Q29uZmlndXJhdGlvbkVsZW1lbnRzRm9yKFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsICJpbnRlcm5hbFN0YXJ0dXAiKTsKCgkJaW50IHNpemUgPSBjZi5sZW5ndGg7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJdHJ5IHsKCQkJCUlTdGFydHVwIHN0YXJ0dXAgPSAoSVN0YXJ0dXApIGNmW2ldLmNyZWF0ZUV4ZWN1dGFibGVFeHRlbnNpb24oImNsYXNzIik7CgkJCQl0cnkgewoJCQkJCXN0YXJ0dXAuc3RhcnR1cCgpOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CgkJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiU3RhcnR1cCBmYWlsZWQiICsgc3RhcnR1cC50b1N0cmluZygpLCBleCk7CgkJCQl9CgkJCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICIgIExvYWRlZCBzdGFydHVwOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpKTsKCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgQ291bGQgbm90IGxvYWQgc3RhcnR1cDogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSwgdCk7CgkJCX0KCQl9CgkJCgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLTwtIERvbmUgbG9hZGluZyAuc3RhcnR1cCBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgoJLyoqCgkgKiBMb2FkIHRoZSBydW50aW1lIHR5cGVzLgoJICovCglwcml2YXRlIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBsb2FkUnVudGltZVR5cGVzKCkgewoJCWlmIChydW50aW1lVHlwZXMgIT0gbnVsbCkKCQkJcmV0dXJuOwoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi0+LSBMb2FkaW5nIC5ydW50aW1lVHlwZXMgZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgInJ1bnRpbWVUeXBlcyIpOwoKCQlpbnQgc2l6ZSA9IGNmLmxlbmd0aDsKCQlydW50aW1lVHlwZXMgPSBuZXcgQXJyYXlMaXN0KHNpemUpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCXRyeSB7CgkJCQlSdW50aW1lVHlwZSBydW50aW1lVHlwZSA9IG5ldyBSdW50aW1lVHlwZShjZltpXSk7CgkJCQlydW50aW1lVHlwZXMuYWRkKHJ1bnRpbWVUeXBlKTsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIiAgTG9hZGVkIHJ1bnRpbWVUeXBlOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpKTsKCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgQ291bGQgbm90IGxvYWQgcnVudGltZVR5cGU6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIiksIHQpOwoJCQl9CgkJfQoJCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLnJ1bnRpbWVUeXBlcyBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgkKCS8qKgoJICogTG9hZCB0aGUgcnVudGltZSB0YXJnZXQgaGFuZGxlcnMuCgkgKi8KCXByaXZhdGUgc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIGxvYWRSdW50aW1lVGFyZ2V0SGFuZGxlcnMoKSB7CgkJaWYgKHJ1bnRpbWVUYXJnZXRIYW5kbGVycyAhPSBudWxsKQoJCQlyZXR1cm47CgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLT4tIExvYWRpbmcgLnJ1bnRpbWVUYXJnZXRIYW5kbGVycyBleHRlbnNpb24gcG9pbnQgLT4tIik7CgkJSUV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gUGxhdGZvcm0uZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKTsKCQlJQ29uZmlndXJhdGlvbkVsZW1lbnRbXSBjZiA9IHJlZ2lzdHJ5LmdldENvbmZpZ3VyYXRpb25FbGVtZW50c0ZvcihTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAicnVudGltZVRhcmdldEhhbmRsZXJzIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCXJ1bnRpbWVUYXJnZXRIYW5kbGVycyA9IG5ldyBBcnJheUxpc3Qoc2l6ZSk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJdHJ5IHsKCQkJCVJ1bnRpbWVUYXJnZXRIYW5kbGVyIHJ1bnRpbWVUYXJnZXRMaXN0ZW5lciA9IG5ldyBSdW50aW1lVGFyZ2V0SGFuZGxlcihjZltpXSk7CgkJCQlydW50aW1lVGFyZ2V0SGFuZGxlcnMuYWRkKHJ1bnRpbWVUYXJnZXRMaXN0ZW5lcik7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICIgIExvYWRlZCBydW50aW1lVGFyZ2V0SGFuZGxlcjogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSk7CgkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICIgIENvdWxkIG5vdCBsb2FkIHJ1bnRpbWVUYXJnZXRIYW5kbGVyOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpLCB0KTsKCQkJfQoJCX0KCQlzb3J0T3JkZXJlZExpc3QocnVudGltZVRhcmdldEhhbmRsZXJzKTsKCQkKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPC0gRG9uZSBsb2FkaW5nIC5ydW50aW1lVGFyZ2V0SGFuZGxlcnMgZXh0ZW5zaW9uIHBvaW50IC08LSIpOwoJfQoKCS8qKgoJICogTG9hZCB0aGUgc2VydmVyIHR5cGVzLgoJICovCglwcml2YXRlIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBsb2FkU2VydmVyVHlwZXMoKSB7CgkJaWYgKHNlcnZlclR5cGVzICE9IG51bGwpCgkJCXJldHVybjsKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPi0gTG9hZGluZyAuc2VydmVyVHlwZXMgZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgInNlcnZlclR5cGVzIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCXNlcnZlclR5cGVzID0gbmV3IEFycmF5TGlzdChzaXplKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQl0cnkgewoJCQkJU2VydmVyVHlwZSBzZXJ2ZXJUeXBlID0gbmV3IFNlcnZlclR5cGUoY2ZbaV0pOwoJCQkJc2VydmVyVHlwZXMuYWRkKHNlcnZlclR5cGUpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiICBMb2FkZWQgc2VydmVyVHlwZTogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSk7CgkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICIgIENvdWxkIG5vdCBsb2FkIHNlcnZlclR5cGU6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIiksIHQpOwoJCQl9CgkJfQoJCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLnNlcnZlclR5cGVzIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHJ1bnRpbWUgd2l0aCB0aGUgZ2l2ZW4gaWQsIG9yIDxjb2RlPm51bGw8L2NvZGU+CgkgKiBpZiBub25lLiBUaGlzIGNvbnZlbmllbmNlIG1ldGhvZCBzZWFyY2hlcyB0aGUgbGlzdCBvZiBrbm93bgoJICogcnVudGltZXMgKHtAbGluayAjZ2V0UnVudGltZXMoKX0pIGZvciB0aGUgb25lIHdpdGggYSBtYXRjaGluZwoJICogcnVudGltZSBpZCAoe0BsaW5rIElSdW50aW1lI2dldElkKCl9KS4gVGhlIGlkIG1heSBub3QgYmUgbnVsbC4KCSAqCgkgKiBAcGFyYW0gaWQgdGhlIHJ1bnRpbWUgaWQKCSAqIEByZXR1cm4gdGhlIHJ1bnRpbWUgaW5zdGFuY2UsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGlzIG5vIHJ1bnRpbWUKCSAqIHdpdGggdGhlIGdpdmVuIGlkCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVJ1bnRpbWUgZmluZFJ1bnRpbWUoU3RyaW5nIGlkKSB7CgkJcmV0dXJuIGdldFJlc291cmNlTWFuYWdlcigpLmdldFJ1bnRpbWUoaWQpOwoJfQoKCS8qKgoJICogUmV0dXJucyBhbiBhcnJheSBvZiBhbGwga25vd24gcnVudGltZSBpbnN0YW5jZXMuIFRoZSBsaXN0IHdpbGwgbm90IGNvbnRhaW4gYW55CgkgKiB3b3JraW5nIGNvcGllcy4KCSAqIDxwPgoJICogQSBuZXcgYXJyYXkgaXMgcmV0dXJuZWQgb24gZWFjaCBjYWxsLCBzbyBjbGllbnRzIG1heSBzdG9yZSBvciBtb2RpZnkgdGhlIHJlc3VsdC4KCSAqIDwvcD4KCSAqIAoJICogQHJldHVybiBhIHBvc3NpYmx5LWVtcHR5IGFycmF5IG9mIHJ1bnRpbWUgaW5zdGFuY2VzIHtAbGluayBJUnVudGltZX0KCSAqLwoJcHVibGljIHN0YXRpYyBJUnVudGltZVtdIGdldFJ1bnRpbWVzKCkgewoJCXJldHVybiBnZXRSZXNvdXJjZU1hbmFnZXIoKS5nZXRSdW50aW1lcygpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgc2VydmVyIHdpdGggdGhlIGdpdmVuIGlkLCBvciA8Y29kZT5udWxsPC9jb2RlPgoJICogaWYgbm9uZS4gVGhpcyBjb252ZW5pZW5jZSBtZXRob2Qgc2VhcmNoZXMgdGhlIGxpc3Qgb2Yga25vd24KCSAqIHNlcnZlcnMgKHtAbGluayAjZ2V0U2VydmVycygpfSkgZm9yIHRoZSBvbmUgd2l0aCBhIG1hdGNoaW5nCgkgKiBzZXJ2ZXIgaWQgKHtAbGluayBJU2VydmVyI2dldElkKCl9KS4gVGhlIGlkIG11c3Qgbm90IGJlIG51bGwuCgkgKgoJICogQHBhcmFtIGlkIHRoZSBzZXJ2ZXIgaWQKCSAqIEByZXR1cm4gdGhlIHNlcnZlciBpbnN0YW5jZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gc2VydmVyCgkgKiB3aXRoIHRoZSBnaXZlbiBpZAoJICovCglwdWJsaWMgc3RhdGljIElTZXJ2ZXIgZmluZFNlcnZlcihTdHJpbmcgaWQpIHsKCQlyZXR1cm4gZ2V0UmVzb3VyY2VNYW5hZ2VyKCkuZ2V0U2VydmVyKGlkKTsKCX0KCgkvKioKCSAqIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIGtub3duIHNlcnZlciBpbnN0YW5jZXMuIFRoZSBhcnJheSB3aWxsIG5vdCBpbmNsdWRlIGFueQoJICogd29ya2luZyBjb3BpZXMuCgkgKiA8cD4KCSAqIEEgbmV3IGFycmF5IGlzIHJldHVybmVkIG9uIGVhY2ggY2FsbCwgc28gY2xpZW50cyBtYXkgc3RvcmUgb3IgbW9kaWZ5IHRoZSByZXN1bHQuCgkgKiA8L3A+CgkgKiAKCSAqIEByZXR1cm4gYSBwb3NzaWJseS1lbXB0eSBhcnJheSBvZiBzZXJ2ZXIgaW5zdGFuY2VzIHtAbGluayBJU2VydmVyfQoJICovCglwdWJsaWMgc3RhdGljIElTZXJ2ZXJbXSBnZXRTZXJ2ZXJzKCkgewoJCXJldHVybiBnZXRSZXNvdXJjZU1hbmFnZXIoKS5nZXRTZXJ2ZXJzKCk7Cgl9CgoJLyoqCgkgKiBBZGRzIGEgbmV3IHJ1bnRpbWUgbGlmZWN5Y2xlIGxpc3RlbmVyLgoJICogSGFzIG5vIGVmZmVjdCBpZiBhbiBpZGVudGljYWwgbGlzdGVuZXIgaXMgYWxyZWFkeSByZWdpc3RlcmVkLgoJICoKCSAqIEBwYXJhbSBsaXN0ZW5lciBhIHJ1bnRpbWUgbGlmZWN5Y2xlIGxpc3RlbmVyCgkgKiBAc2VlICNyZW1vdmVSdW50aW1lTGlmZWN5Y2xlTGlzdGVuZXIoSVJ1bnRpbWVMaWZlY3ljbGVMaXN0ZW5lcikKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIGFkZFJ1bnRpbWVMaWZlY3ljbGVMaXN0ZW5lcihJUnVudGltZUxpZmVjeWNsZUxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJZ2V0UmVzb3VyY2VNYW5hZ2VyKCkuYWRkUnVudGltZUxpZmVjeWNsZUxpc3RlbmVyKGxpc3RlbmVyKTsKCX0KCgkvKioKCSAqIFJlbW92ZXMgYSBydW50aW1lIGxpZmVjeWNsZSBsaXN0ZW5lci4KCSAqIEhhcyBubyBlZmZlY3QgaWYgdGhlIGxpc3RlbmVyIGlzIG5vdCByZWdpc3RlcmVkLgoJICoKCSAqIEBwYXJhbSBsaXN0ZW5lciBhIHJ1bnRpbWUgbGlmZWN5Y2xlIGxpc3RlbmVyCgkgKiBAc2VlICNhZGRSdW50aW1lTGlmZWN5Y2xlTGlzdGVuZXIoSVJ1bnRpbWVMaWZlY3ljbGVMaXN0ZW5lcikKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIHJlbW92ZVJ1bnRpbWVMaWZlY3ljbGVMaXN0ZW5lcihJUnVudGltZUxpZmVjeWNsZUxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJZ2V0UmVzb3VyY2VNYW5hZ2VyKCkucmVtb3ZlUnVudGltZUxpZmVjeWNsZUxpc3RlbmVyKGxpc3RlbmVyKTsKCX0KCgkvKioKCSAqIEFkZHMgYSBuZXcgc2VydmVyIGxpZmVjeWNsZSBsaXN0ZW5lci4KCSAqIEhhcyBubyBlZmZlY3QgaWYgYW4gaWRlbnRpY2FsIGxpc3RlbmVyIGlzIGFscmVhZHkgcmVnaXN0ZXJlZC4KCSAqCgkgKiBAcGFyYW0gbGlzdGVuZXIgYSBzZXJ2ZXIgbGlmZWN5Y2xlIGxpc3RlbmVyCgkgKiBAc2VlICNyZW1vdmVTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lcihJU2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIpCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCBhZGRTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lcihJU2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIgbGlzdGVuZXIpIHsKCQlnZXRSZXNvdXJjZU1hbmFnZXIoKS5hZGRTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lcihsaXN0ZW5lcik7Cgl9CgoJLyoqCgkgKiBSZW1vdmVzIGEgc2VydmVyIGxpZmVjeWNsZSBsaXN0ZW5lci4KCSAqIEhhcyBubyBlZmZlY3QgaWYgdGhlIGxpc3RlbmVyIGlzIG5vdCByZWdpc3RlcmVkLgoJICoKCSAqIEBwYXJhbSBsaXN0ZW5lciBhIHNlcnZlciBsaWZlY3ljbGUgbGlzdGVuZXIKCSAqICNhZGRTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lcihJU2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIpCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCByZW1vdmVTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lcihJU2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIgbGlzdGVuZXIpIHsKCQlnZXRSZXNvdXJjZU1hbmFnZXIoKS5yZW1vdmVTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lcihsaXN0ZW5lcik7Cgl9CgoJLyoqCgkgKiBTb3J0IHRoZSBnaXZlbiBsaXN0IG9mIElPcmRlcmVkIGl0ZW1zIGludG8gaW5kZXhlZCBvcmRlci4KCSAqCgkgKiBAcGFyYW0gbGlzdCBqYXZhLnV0aWwuTGlzdAoJICogQHJldHVybiBqYXZhLnV0aWwuTGlzdAoJICovCglwcml2YXRlIHN0YXRpYyBMaXN0IHNvcnRPcmRlcmVkTGlzdChMaXN0IGxpc3QpIHsKCQlpZiAobGlzdCA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCgkJaW50IHNpemUgPSBsaXN0LnNpemUoKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemUgLSAxOyBpKyspIHsKCQkJZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgc2l6ZTsgaisrKSB7CgkJCQlJT3JkZXJlZCBhID0gKElPcmRlcmVkKSBsaXN0LmdldChpKTsKCQkJCUlPcmRlcmVkIGIgPSAoSU9yZGVyZWQpIGxpc3QuZ2V0KGopOwoJCQkJaWYgKGEuZ2V0T3JkZXIoKSA+IGIuZ2V0T3JkZXIoKSkgewoJCQkJCU9iamVjdCB0ZW1wID0gYTsKCQkJCQlsaXN0LnNldChpLCBiKTsKCQkJCQlsaXN0LnNldChqLCB0ZW1wKTsKCQkJCX0KCQkJfQoJCX0KCQlyZXR1cm4gbGlzdDsKCX0KfQ==