LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZTsKCmltcG9ydCBqYXZhLnV0aWwuKjsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuKjsKLyoqCiAqIE1haW4gY2xhc3MgZm9yIHNlcnZlciBjb3JlIEFQSS4KICogPHA+CiAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgQVBJIHRvIGFjY2VzcyBtb3N0IG9mIHRoZSB0eXBlcyBpbiB0aGUgc2VydmVyCiAqIGZyYW1ld29yaywgaW5jbHVkaW5nIHNlcnZlciBydW50aW1lcyBhbmQgc2VydmVycy4gTWV0aG9kcyAqKgogKiBUaGUgbWV0aG9kcyBvbiB0aGlzIGNsYXNzIGFyZSB0aHJlYWQgc2FmZS4KICogPC9wPgogKiA8cD4KICogVGhpcyBjbGFzcyBwcm92aWRlcyBhbGwgaXRzIGZ1bmN0aW9uYWxpdHkgdGhyb3VnaCBzdGF0aWMgbWVtYmVycy4KICogSXQgaXMgbm90IGludGVuZGVkIHRvIGJlIHN1YmNsYXNzZWQgb3IgaW5zdGFudGlhdGVkLgogKiA8L3A+CiAqIAogKiBAc2luY2UgMS4wCiAqLwpwdWJsaWMgY2xhc3MgU2VydmVyQ29yZSB7CgkvLwljYWNoZWQgY29weSBvZiBhbGwgcnVudGltZSB0eXBlcwoJcHJpdmF0ZSBzdGF0aWMgTGlzdCBydW50aW1lVHlwZXM7CgkKCS8vCWNhY2hlZCBjb3B5IG9mIGFsbCBydW50aW1lIHRhcmdldCBoYW5kbGVycwoJcHJpdmF0ZSBzdGF0aWMgTGlzdCBydW50aW1lVGFyZ2V0SGFuZGxlcnM7CgoJLy8JY2FjaGVkIGNvcHkgb2YgYWxsIHNlcnZlciBhbmQgY29uZmlndXJhdGlvbiB0eXBlcwoJcHJpdmF0ZSBzdGF0aWMgTGlzdCBzZXJ2ZXJUeXBlczsKCglzdGF0aWMgewoJCWV4ZWN1dGVTdGFydHVwcygpOwoJfQoKCS8qKgoJICogQ2Fubm90IGNyZWF0ZSBTZXJ2ZXJDb3JlIC0gdXNlIHN0YXRpYyBtZXRob2RzLgoJICovCglwcml2YXRlIFNlcnZlckNvcmUoKSB7CgkJLy8gY2FuJ3QgY3JlYXRlCgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSByZXNvdXJjZSBtYW5hZ2VyLgoJICoKCSAqIEByZXR1cm4gb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlJlc291cmNlTWFuYWdlcgoJICovCglwcml2YXRlIHN0YXRpYyBSZXNvdXJjZU1hbmFnZXIgZ2V0UmVzb3VyY2VNYW5hZ2VyKCkgewoJCXJldHVybiBSZXNvdXJjZU1hbmFnZXIuZ2V0SW5zdGFuY2UoKTsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBwcmVmZXJlbmNlIGluZm9ybWF0aW9uIGZvciB0aGUgcHJvamVjdC4gVGhlIHByb2plY3QgbWF5IG5vdAoJICogYmUgbnVsbC4KCSAqCgkgKiBAcGFyYW0gcHJvamVjdCBhIHByb2plY3QKCSAqIEByZXR1cm4gdGhlIHByb3BlcnRpZXMgb2YgdGhlIHByb2plY3QKCSAqLwoJcHVibGljIHN0YXRpYyBJUHJvamVjdFByb3BlcnRpZXMgZ2V0UHJvamVjdFByb3BlcnRpZXMoSVByb2plY3QgcHJvamVjdCkgewoJCWlmIChwcm9qZWN0ID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCQlyZXR1cm4gbmV3IFByb2plY3RQcm9wZXJ0aWVzKHByb2plY3QpOwoJfQoKCS8qKgoJICogUmV0dXJucyBhbiBhcnJheSBvZiBhbGwga25vd24gcnVudGltZSB0eXBlcy4KCSAqIDxwPgoJICogQSBuZXcgYXJyYXkgaXMgcmV0dXJuZWQgb24gZWFjaCBjYWxsLCBzbyBjbGllbnRzIG1heSBzdG9yZSBvciBtb2RpZnkgdGhlIHJlc3VsdC4KCSAqIDwvcD4KCSAqIAoJICogQHJldHVybiB0aGUgYXJyYXkgb2YgcnVudGltZSB0eXBlcyB7QGxpbmsgSVJ1bnRpbWVUeXBlfQoJICovCglwdWJsaWMgc3RhdGljIElSdW50aW1lVHlwZVtdIGdldFJ1bnRpbWVUeXBlcygpIHsKCQlpZiAocnVudGltZVR5cGVzID09IG51bGwpCgkJCWxvYWRSdW50aW1lVHlwZXMoKTsKCQkKCQlJUnVudGltZVR5cGVbXSBydCA9IG5ldyBJUnVudGltZVR5cGVbcnVudGltZVR5cGVzLnNpemUoKV07CgkJcnVudGltZVR5cGVzLnRvQXJyYXkocnQpOwoJCXJldHVybiBydDsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHJ1bnRpbWUgdHlwZSB3aXRoIHRoZSBnaXZlbiBpZCwgb3IgPGNvZGU+bnVsbDwvY29kZT4KCSAqIGlmIG5vbmUuIFRoaXMgY29udmVuaWVuY2UgbWV0aG9kIHNlYXJjaGVzIHRoZSBsaXN0IG9mIGtub3duCgkgKiBydW50aW1lIHR5cGVzICh7QGxpbmsgI2dldFJ1bnRpbWVUeXBlcygpfSkgZm9yIHRoZSBvbmUgd2l0aCBhIG1hdGNoaW5nCgkgKiBydW50aW1lIHR5cGUgaWQgKHtAbGluayBJUnVudGltZVR5cGUjZ2V0SWQoKX0pLiBUaGUgaWQgbWF5IG5vdCBiZSBudWxsLgoJICoKCSAqIEBwYXJhbSBpZCB0aGUgcnVudGltZSB0eXBlIGlkCgkgKiBAcmV0dXJuIHRoZSBydW50aW1lIHR5cGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGlzIG5vIHJ1bnRpbWUgdHlwZQoJICogd2l0aCB0aGUgZ2l2ZW4gaWQKCSAqLwoJcHVibGljIHN0YXRpYyBJUnVudGltZVR5cGUgZmluZFJ1bnRpbWVUeXBlKFN0cmluZyBpZCkgewoJCWlmIChpZCA9PSBudWxsKQoJCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CgoJCWlmIChydW50aW1lVHlwZXMgPT0gbnVsbCkKCQkJbG9hZFJ1bnRpbWVUeXBlcygpOwoJCQoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gcnVudGltZVR5cGVzLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlJUnVudGltZVR5cGUgcnVudGltZVR5cGUgPSAoSVJ1bnRpbWVUeXBlKSBpdGVyYXRvci5uZXh0KCk7CgkJCWlmIChpZC5lcXVhbHMocnVudGltZVR5cGUuZ2V0SWQoKSkpCgkJCQlyZXR1cm4gcnVudGltZVR5cGU7CgkJfQoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogUmV0dXJucyBhbiBhcnJheSBvZiBhbGwga25vd24gcnVudGltZSB0YXJnZXQgaGFuZGxlciBpbnN0YW5jZXMuCgkgKiA8cD4KCSAqIEEgbmV3IGFycmF5IGlzIHJldHVybmVkIG9uIGVhY2ggY2FsbCwgc28gY2xpZW50cyBtYXkgc3RvcmUgb3IgbW9kaWZ5IHRoZSByZXN1bHQuCgkgKiA8L3A+CgkgKiAKCSAqIEByZXR1cm4gYSBwb3NzaWJseS1lbXB0eSBhcnJheSBvZiBydW50aW1lIHRhcmdldCBoYW5kbGVyIGluc3RhbmNlcwoJICogICAge0BsaW5rIElSdW50aW1lVGFyZ2V0SGFuZGxlcn0KCSAqLwoJcHVibGljIHN0YXRpYyBJUnVudGltZVRhcmdldEhhbmRsZXJbXSBnZXRSdW50aW1lVGFyZ2V0SGFuZGxlcnMoKSB7CgkJaWYgKHJ1bnRpbWVUYXJnZXRIYW5kbGVycyA9PSBudWxsKQoJCQlsb2FkUnVudGltZVRhcmdldEhhbmRsZXJzKCk7CgkJCgkJSVJ1bnRpbWVUYXJnZXRIYW5kbGVyW10gcnRoID0gbmV3IElSdW50aW1lVGFyZ2V0SGFuZGxlcltydW50aW1lVGFyZ2V0SGFuZGxlcnMuc2l6ZSgpXTsKCQlydW50aW1lVGFyZ2V0SGFuZGxlcnMudG9BcnJheShydGgpOwoJCXJldHVybiBydGg7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBydW50aW1lIHRhcmdldCBoYW5kbGVyIHdpdGggdGhlIGdpdmVuIGlkLCBvciA8Y29kZT5udWxsPC9jb2RlPgoJICogaWYgbm9uZS4gVGhpcyBjb252ZW5pZW5jZSBtZXRob2Qgc2VhcmNoZXMgdGhlIGxpc3Qgb2Yga25vd24gcnVudGltZQoJICogdGFyZ2V0IGhhbmRsZXJzICh7QGxpbmsgI2dldFJ1bnRpbWVUYXJnZXRIYW5kbGVycygpfSkgZm9yIHRoZSBvbmUgd2l0aAoJICogYSBtYXRjaGluZyBydW50aW1lIHRhcmdldCBoYW5kbGVyIGlkICh7QGxpbmsgSVJ1bnRpbWVUYXJnZXRIYW5kbGVyI2dldElkKCl9KS4KCSAqIFRoZSBpZCBtYXkgbm90IGJlIG51bGwuCgkgKgoJICogQHBhcmFtIGlkIHRoZSBydW50aW1lIHRhcmdldCBoYW5kbGVyIGlkCgkgKiBAcmV0dXJuIHRoZSBydW50aW1lIHRhcmdldCBoYW5kbGVyIGluc3RhbmNlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZgoJICogICB0aGVyZSBpcyBubyBydW50aW1lIHRhcmdldCBoYW5kbGVyIHdpdGggdGhlIGdpdmVuIGlkCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVJ1bnRpbWVUYXJnZXRIYW5kbGVyIGZpbmRSdW50aW1lVGFyZ2V0SGFuZGxlcihTdHJpbmcgaWQpIHsKCQlpZiAoaWQgPT0gbnVsbCkKCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoKCQlpZiAocnVudGltZVRhcmdldEhhbmRsZXJzID09IG51bGwpCgkJCWxvYWRSdW50aW1lVGFyZ2V0SGFuZGxlcnMoKTsKCQkKCQlJdGVyYXRvciBpdGVyYXRvciA9IHJ1bnRpbWVUYXJnZXRIYW5kbGVycy5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSVJ1bnRpbWVUYXJnZXRIYW5kbGVyIHJ1bnRpbWVUYXJnZXRMaXN0ZW5lciA9IChJUnVudGltZVRhcmdldEhhbmRsZXIpIGl0ZXJhdG9yLm5leHQoKTsKCQkJaWYgKGlkLmVxdWFscyhydW50aW1lVGFyZ2V0TGlzdGVuZXIuZ2V0SWQoKSkpCgkJCQlyZXR1cm4gcnVudGltZVRhcmdldExpc3RlbmVyOwoJCX0KCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIGtub3duIHNlcnZlciB0eXBlcy4KCSAqIDxwPgoJICogQSBuZXcgYXJyYXkgaXMgcmV0dXJuZWQgb24gZWFjaCBjYWxsLCBzbyBjbGllbnRzIG1heSBzdG9yZSBvciBtb2RpZnkgdGhlIHJlc3VsdC4KCSAqIDwvcD4KCSAqIAoJICogQHJldHVybiB0aGUgYXJyYXkgb2Ygc2VydmVyIHR5cGVzIHtAbGluayBJU2VydmVyVHlwZX0KCSAqLwoJcHVibGljIHN0YXRpYyBJU2VydmVyVHlwZVtdIGdldFNlcnZlclR5cGVzKCkgewoJCWlmIChzZXJ2ZXJUeXBlcyA9PSBudWxsKQoJCQlsb2FkU2VydmVyVHlwZXMoKTsKCQkKCQlJU2VydmVyVHlwZVtdIHN0ID0gbmV3IElTZXJ2ZXJUeXBlW3NlcnZlclR5cGVzLnNpemUoKV07CgkJc2VydmVyVHlwZXMudG9BcnJheShzdCk7CgkJcmV0dXJuIHN0OwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgc2VydmVyIHR5cGUgd2l0aCB0aGUgZ2l2ZW4gaWQsIG9yIDxjb2RlPm51bGw8L2NvZGU+CgkgKiBpZiBub25lLiBUaGlzIGNvbnZlbmllbmNlIG1ldGhvZCBzZWFyY2hlcyB0aGUgbGlzdCBvZiBrbm93bgoJICogc2VydmVyIHR5cGVzICh7QGxpbmsgI2dldFNlcnZlclR5cGVzKCl9KSBmb3IgdGhlIG9uZSB3aXRoIGEgbWF0Y2hpbmcKCSAqIHNlcnZlciB0eXBlIGlkICh7QGxpbmsgSVNlcnZlclR5cGUjZ2V0SWQoKX0pLiBUaGUgaWQgbWF5IG5vdCBiZSBudWxsLgoJICoKCSAqIEBwYXJhbSBpZCB0aGUgc2VydmVyIHR5cGUgaWQKCSAqIEByZXR1cm4gdGhlIHNlcnZlciB0eXBlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBzZXJ2ZXIgdHlwZQoJICogd2l0aCB0aGUgZ2l2ZW4gaWQKCSAqLwoJcHVibGljIHN0YXRpYyBJU2VydmVyVHlwZSBmaW5kU2VydmVyVHlwZShTdHJpbmcgaWQpIHsKCQlpZiAoaWQgPT0gbnVsbCkKCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoKCQlpZiAoc2VydmVyVHlwZXMgPT0gbnVsbCkKCQkJbG9hZFNlcnZlclR5cGVzKCk7CgkJCgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBzZXJ2ZXJUeXBlcy5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSVNlcnZlclR5cGUgc2VydmVyVHlwZSA9IChJU2VydmVyVHlwZSkgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAoaWQuZXF1YWxzKHNlcnZlclR5cGUuZ2V0SWQoKSkpCgkJCQlyZXR1cm4gc2VydmVyVHlwZTsKCQl9CgkJcmV0dXJuIG51bGw7Cgl9CgoJLyoqCgkgKiBFeGVjdXRlIHRoZSBzZXJ2ZXIgc3RhcnR1cCBleHRlbnNpb24gcG9pbnRzLgoJICovCglwcml2YXRlIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBleGVjdXRlU3RhcnR1cHMoKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLT4tIExvYWRpbmcgLnN0YXJ0dXAgZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgImludGVybmFsU3RhcnR1cCIpOwoKCQlpbnQgc2l6ZSA9IGNmLmxlbmd0aDsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQl0cnkgewoJCQkJSVN0YXJ0dXAgc3RhcnR1cCA9IChJU3RhcnR1cCkgY2ZbaV0uY3JlYXRlRXhlY3V0YWJsZUV4dGVuc2lvbigiY2xhc3MiKTsKCQkJCXRyeSB7CgkJCQkJc3RhcnR1cC5zdGFydHVwKCk7CgkJCQl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKCQkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJTdGFydHVwIGZhaWxlZCIgKyBzdGFydHVwLnRvU3RyaW5nKCksIGV4KTsKCQkJCX0KCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIiAgTG9hZGVkIHN0YXJ0dXA6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIikpOwoJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiICBDb3VsZCBub3QgbG9hZCBzdGFydHVwOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpLCB0KTsKCQkJfQoJCX0KCQkKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPC0gRG9uZSBsb2FkaW5nIC5zdGFydHVwIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KCgkvKioKCSAqIExvYWQgdGhlIHJ1bnRpbWUgdHlwZXMuCgkgKi8KCXByaXZhdGUgc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIGxvYWRSdW50aW1lVHlwZXMoKSB7CgkJaWYgKHJ1bnRpbWVUeXBlcyAhPSBudWxsKQoJCQlyZXR1cm47CgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLT4tIExvYWRpbmcgLnJ1bnRpbWVUeXBlcyBleHRlbnNpb24gcG9pbnQgLT4tIik7CgkJSUV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gUGxhdGZvcm0uZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKTsKCQlJQ29uZmlndXJhdGlvbkVsZW1lbnRbXSBjZiA9IHJlZ2lzdHJ5LmdldENvbmZpZ3VyYXRpb25FbGVtZW50c0ZvcihTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAicnVudGltZVR5cGVzIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCXJ1bnRpbWVUeXBlcyA9IG5ldyBBcnJheUxpc3Qoc2l6ZSk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJdHJ5IHsKCQkJCVJ1bnRpbWVUeXBlIHJ1bnRpbWVUeXBlID0gbmV3IFJ1bnRpbWVUeXBlKGNmW2ldKTsKCQkJCXJ1bnRpbWVUeXBlcy5hZGQocnVudGltZVR5cGUpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiICBMb2FkZWQgcnVudGltZVR5cGU6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIikpOwoJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiICBDb3VsZCBub3QgbG9hZCBydW50aW1lVHlwZTogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSwgdCk7CgkJCX0KCQl9CgkJCgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLTwtIERvbmUgbG9hZGluZyAucnVudGltZVR5cGVzIGV4dGVuc2lvbiBwb2ludCAtPC0iKTsKCX0KCQoJLyoqCgkgKiBMb2FkIHRoZSBydW50aW1lIHRhcmdldCBoYW5kbGVycy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgc3luY2hyb25pemVkIHZvaWQgbG9hZFJ1bnRpbWVUYXJnZXRIYW5kbGVycygpIHsKCQlpZiAocnVudGltZVRhcmdldEhhbmRsZXJzICE9IG51bGwpCgkJCXJldHVybjsKCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICItPi0gTG9hZGluZyAucnVudGltZVRhcmdldEhhbmRsZXJzIGV4dGVuc2lvbiBwb2ludCAtPi0iKTsKCQlJRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkgPSBQbGF0Zm9ybS5nZXRFeHRlbnNpb25SZWdpc3RyeSgpOwoJCUlDb25maWd1cmF0aW9uRWxlbWVudFtdIGNmID0gcmVnaXN0cnkuZ2V0Q29uZmlndXJhdGlvbkVsZW1lbnRzRm9yKFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsICJydW50aW1lVGFyZ2V0SGFuZGxlcnMiKTsKCgkJaW50IHNpemUgPSBjZi5sZW5ndGg7CgkJcnVudGltZVRhcmdldEhhbmRsZXJzID0gbmV3IEFycmF5TGlzdChzaXplKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQl0cnkgewoJCQkJUnVudGltZVRhcmdldEhhbmRsZXIgcnVudGltZVRhcmdldExpc3RlbmVyID0gbmV3IFJ1bnRpbWVUYXJnZXRIYW5kbGVyKGNmW2ldKTsKCQkJCXJ1bnRpbWVUYXJnZXRIYW5kbGVycy5hZGQocnVudGltZVRhcmdldExpc3RlbmVyKTsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIiAgTG9hZGVkIHJ1bnRpbWVUYXJnZXRIYW5kbGVyOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpKTsKCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgQ291bGQgbm90IGxvYWQgcnVudGltZVRhcmdldEhhbmRsZXI6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIiksIHQpOwoJCQl9CgkJfQoJCXNvcnRPcmRlcmVkTGlzdChydW50aW1lVGFyZ2V0SGFuZGxlcnMpOwoJCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi08LSBEb25lIGxvYWRpbmcgLnJ1bnRpbWVUYXJnZXRIYW5kbGVycyBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgoJLyoqCgkgKiBMb2FkIHRoZSBzZXJ2ZXIgdHlwZXMuCgkgKi8KCXByaXZhdGUgc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIGxvYWRTZXJ2ZXJUeXBlcygpIHsKCQlpZiAoc2VydmVyVHlwZXMgIT0gbnVsbCkKCQkJcmV0dXJuOwoJCVRyYWNlLnRyYWNlKFRyYWNlLkVYVEVOU0lPTl9QT0lOVCwgIi0+LSBMb2FkaW5nIC5zZXJ2ZXJUeXBlcyBleHRlbnNpb24gcG9pbnQgLT4tIik7CgkJSUV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0gUGxhdGZvcm0uZ2V0RXh0ZW5zaW9uUmVnaXN0cnkoKTsKCQlJQ29uZmlndXJhdGlvbkVsZW1lbnRbXSBjZiA9IHJlZ2lzdHJ5LmdldENvbmZpZ3VyYXRpb25FbGVtZW50c0ZvcihTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAic2VydmVyVHlwZXMiKTsKCgkJaW50IHNpemUgPSBjZi5sZW5ndGg7CgkJc2VydmVyVHlwZXMgPSBuZXcgQXJyYXlMaXN0KHNpemUpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCXRyeSB7CgkJCQlTZXJ2ZXJUeXBlIHNlcnZlclR5cGUgPSBuZXcgU2VydmVyVHlwZShjZltpXSk7CgkJCQlzZXJ2ZXJUeXBlcy5hZGQoc2VydmVyVHlwZSk7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5FWFRFTlNJT05fUE9JTlQsICIgIExvYWRlZCBzZXJ2ZXJUeXBlOiAiICsgY2ZbaV0uZ2V0QXR0cmlidXRlKCJpZCIpKTsKCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgQ291bGQgbm90IGxvYWQgc2VydmVyVHlwZTogIiArIGNmW2ldLmdldEF0dHJpYnV0ZSgiaWQiKSwgdCk7CgkJCX0KCQl9CgkJCgkJVHJhY2UudHJhY2UoVHJhY2UuRVhURU5TSU9OX1BPSU5ULCAiLTwtIERvbmUgbG9hZGluZyAuc2VydmVyVHlwZXMgZXh0ZW5zaW9uIHBvaW50IC08LSIpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcnVudGltZSB3aXRoIHRoZSBnaXZlbiBpZCwgb3IgPGNvZGU+bnVsbDwvY29kZT4KCSAqIGlmIG5vbmUuIFRoaXMgY29udmVuaWVuY2UgbWV0aG9kIHNlYXJjaGVzIHRoZSBsaXN0IG9mIGtub3duCgkgKiBydW50aW1lcyAoe0BsaW5rICNnZXRSdW50aW1lcygpfSkgZm9yIHRoZSBvbmUgd2l0aCBhIG1hdGNoaW5nCgkgKiBydW50aW1lIGlkICh7QGxpbmsgSVJ1bnRpbWUjZ2V0SWQoKX0pLiBUaGUgaWQgbWF5IG5vdCBiZSBudWxsLgoJICoKCSAqIEBwYXJhbSBpZCB0aGUgcnVudGltZSBpZAoJICogQHJldHVybiB0aGUgcnVudGltZSBpbnN0YW5jZSwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8gcnVudGltZQoJICogd2l0aCB0aGUgZ2l2ZW4gaWQKCSAqLwoJcHVibGljIHN0YXRpYyBJUnVudGltZSBmaW5kUnVudGltZShTdHJpbmcgaWQpIHsKCQlyZXR1cm4gZ2V0UmVzb3VyY2VNYW5hZ2VyKCkuZ2V0UnVudGltZShpZCk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBrbm93biBydW50aW1lIGluc3RhbmNlcy4gVGhlIGxpc3Qgd2lsbCBub3QgY29udGFpbiBhbnkKCSAqIHdvcmtpbmcgY29waWVzLgoJICogPHA+CgkgKiBBIG5ldyBhcnJheSBpcyByZXR1cm5lZCBvbiBlYWNoIGNhbGwsIHNvIGNsaWVudHMgbWF5IHN0b3JlIG9yIG1vZGlmeSB0aGUgcmVzdWx0LgoJICogPC9wPgoJICogCgkgKiBAcmV0dXJuIGEgcG9zc2libHktZW1wdHkgYXJyYXkgb2YgcnVudGltZSBpbnN0YW5jZXMge0BsaW5rIElSdW50aW1lfQoJICovCglwdWJsaWMgc3RhdGljIElSdW50aW1lW10gZ2V0UnVudGltZXMoKSB7CgkJcmV0dXJuIGdldFJlc291cmNlTWFuYWdlcigpLmdldFJ1bnRpbWVzKCk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBzZXJ2ZXIgd2l0aCB0aGUgZ2l2ZW4gaWQsIG9yIDxjb2RlPm51bGw8L2NvZGU+CgkgKiBpZiBub25lLiBUaGlzIGNvbnZlbmllbmNlIG1ldGhvZCBzZWFyY2hlcyB0aGUgbGlzdCBvZiBrbm93bgoJICogc2VydmVycyAoe0BsaW5rICNnZXRTZXJ2ZXJzKCl9KSBmb3IgdGhlIG9uZSB3aXRoIGEgbWF0Y2hpbmcKCSAqIHNlcnZlciBpZCAoe0BsaW5rIElTZXJ2ZXIjZ2V0SWQoKX0pLiBUaGUgaWQgbXVzdCBub3QgYmUgbnVsbC4KCSAqCgkgKiBAcGFyYW0gaWQgdGhlIHNlcnZlciBpZAoJICogQHJldHVybiB0aGUgc2VydmVyIGluc3RhbmNlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBpcyBubyBzZXJ2ZXIKCSAqIHdpdGggdGhlIGdpdmVuIGlkCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVNlcnZlciBmaW5kU2VydmVyKFN0cmluZyBpZCkgewoJCXJldHVybiBnZXRSZXNvdXJjZU1hbmFnZXIoKS5nZXRTZXJ2ZXIoaWQpOwoJfQoKCS8qKgoJICogUmV0dXJucyBhbiBhcnJheSBvZiBhbGwga25vd24gc2VydmVyIGluc3RhbmNlcy4gVGhlIGFycmF5IHdpbGwgbm90IGluY2x1ZGUgYW55CgkgKiB3b3JraW5nIGNvcGllcy4KCSAqIDxwPgoJICogQSBuZXcgYXJyYXkgaXMgcmV0dXJuZWQgb24gZWFjaCBjYWxsLCBzbyBjbGllbnRzIG1heSBzdG9yZSBvciBtb2RpZnkgdGhlIHJlc3VsdC4KCSAqIDwvcD4KCSAqIAoJICogQHJldHVybiBhIHBvc3NpYmx5LWVtcHR5IGFycmF5IG9mIHNlcnZlciBpbnN0YW5jZXMge0BsaW5rIElTZXJ2ZXJ9CgkgKi8KCXB1YmxpYyBzdGF0aWMgSVNlcnZlcltdIGdldFNlcnZlcnMoKSB7CgkJcmV0dXJuIGdldFJlc291cmNlTWFuYWdlcigpLmdldFNlcnZlcnMoKTsKCX0KCgkvKioKCSAqIEFkZHMgYSBuZXcgcnVudGltZSBsaWZlY3ljbGUgbGlzdGVuZXIuCgkgKiBIYXMgbm8gZWZmZWN0IGlmIGFuIGlkZW50aWNhbCBsaXN0ZW5lciBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQuCgkgKgoJICogQHBhcmFtIGxpc3RlbmVyIGEgcnVudGltZSBsaWZlY3ljbGUgbGlzdGVuZXIKCSAqIEBzZWUgI3JlbW92ZVJ1bnRpbWVMaWZlY3ljbGVMaXN0ZW5lcihJUnVudGltZUxpZmVjeWNsZUxpc3RlbmVyKQoJICovCglwdWJsaWMgc3RhdGljIHZvaWQgYWRkUnVudGltZUxpZmVjeWNsZUxpc3RlbmVyKElSdW50aW1lTGlmZWN5Y2xlTGlzdGVuZXIgbGlzdGVuZXIpIHsKCQlnZXRSZXNvdXJjZU1hbmFnZXIoKS5hZGRSdW50aW1lTGlmZWN5Y2xlTGlzdGVuZXIobGlzdGVuZXIpOwoJfQoKCS8qKgoJICogUmVtb3ZlcyBhIHJ1bnRpbWUgbGlmZWN5Y2xlIGxpc3RlbmVyLgoJICogSGFzIG5vIGVmZmVjdCBpZiB0aGUgbGlzdGVuZXIgaXMgbm90IHJlZ2lzdGVyZWQuCgkgKgoJICogQHBhcmFtIGxpc3RlbmVyIGEgcnVudGltZSBsaWZlY3ljbGUgbGlzdGVuZXIKCSAqIEBzZWUgI2FkZFJ1bnRpbWVMaWZlY3ljbGVMaXN0ZW5lcihJUnVudGltZUxpZmVjeWNsZUxpc3RlbmVyKQoJICovCglwdWJsaWMgc3RhdGljIHZvaWQgcmVtb3ZlUnVudGltZUxpZmVjeWNsZUxpc3RlbmVyKElSdW50aW1lTGlmZWN5Y2xlTGlzdGVuZXIgbGlzdGVuZXIpIHsKCQlnZXRSZXNvdXJjZU1hbmFnZXIoKS5yZW1vdmVSdW50aW1lTGlmZWN5Y2xlTGlzdGVuZXIobGlzdGVuZXIpOwoJfQoKCS8qKgoJICogQWRkcyBhIG5ldyBzZXJ2ZXIgbGlmZWN5Y2xlIGxpc3RlbmVyLgoJICogSGFzIG5vIGVmZmVjdCBpZiBhbiBpZGVudGljYWwgbGlzdGVuZXIgaXMgYWxyZWFkeSByZWdpc3RlcmVkLgoJICoKCSAqIEBwYXJhbSBsaXN0ZW5lciBhIHNlcnZlciBsaWZlY3ljbGUgbGlzdGVuZXIKCSAqIEBzZWUgI3JlbW92ZVNlcnZlckxpZmVjeWNsZUxpc3RlbmVyKElTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lcikKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIGFkZFNlcnZlckxpZmVjeWNsZUxpc3RlbmVyKElTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWdldFJlc291cmNlTWFuYWdlcigpLmFkZFNlcnZlckxpZmVjeWNsZUxpc3RlbmVyKGxpc3RlbmVyKTsKCX0KCgkvKioKCSAqIFJlbW92ZXMgYSBzZXJ2ZXIgbGlmZWN5Y2xlIGxpc3RlbmVyLgoJICogSGFzIG5vIGVmZmVjdCBpZiB0aGUgbGlzdGVuZXIgaXMgbm90IHJlZ2lzdGVyZWQuCgkgKgoJICogQHBhcmFtIGxpc3RlbmVyIGEgc2VydmVyIGxpZmVjeWNsZSBsaXN0ZW5lcgoJICogI2FkZFNlcnZlckxpZmVjeWNsZUxpc3RlbmVyKElTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lcikKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIHJlbW92ZVNlcnZlckxpZmVjeWNsZUxpc3RlbmVyKElTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWdldFJlc291cmNlTWFuYWdlcigpLnJlbW92ZVNlcnZlckxpZmVjeWNsZUxpc3RlbmVyKGxpc3RlbmVyKTsKCX0KCgkvKioKCSAqIFNvcnQgdGhlIGdpdmVuIGxpc3Qgb2YgSU9yZGVyZWQgaXRlbXMgaW50byBpbmRleGVkIG9yZGVyLgoJICoKCSAqIEBwYXJhbSBsaXN0IGphdmEudXRpbC5MaXN0CgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXByaXZhdGUgc3RhdGljIExpc3Qgc29ydE9yZGVyZWRMaXN0KExpc3QgbGlzdCkgewoJCWlmIChsaXN0ID09IG51bGwpCgkJCXJldHVybiBudWxsOwoKCQlpbnQgc2l6ZSA9IGxpc3Quc2l6ZSgpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZSAtIDE7IGkrKykgewoJCQlmb3IgKGludCBqID0gaSArIDE7IGogPCBzaXplOyBqKyspIHsKCQkJCUlPcmRlcmVkIGEgPSAoSU9yZGVyZWQpIGxpc3QuZ2V0KGkpOwoJCQkJSU9yZGVyZWQgYiA9IChJT3JkZXJlZCkgbGlzdC5nZXQoaik7CgkJCQlpZiAoYS5nZXRPcmRlcigpID4gYi5nZXRPcmRlcigpKSB7CgkJCQkJT2JqZWN0IHRlbXAgPSBhOwoJCQkJCWxpc3Quc2V0KGksIGIpOwoJCQkJCWxpc3Quc2V0KGosIHRlbXApOwoJCQkJfQoJCQl9CgkJfQoJCXJldHVybiBsaXN0OwoJfQoJCgkvKioKCSAqIFJldHVybnMgdGhlIHByZWZlcnJlZCBydW50aW1lIHNlcnZlciBmb3IgdGhlIGdpdmVuIG1vZHVsZS4gVGhpcyBtZXRob2QKCSAqIHJldHVybnMgbnVsbCBpZiB0aGUgc2VydmVyIHdhcyBuZXZlciBjaG9zZW4gb3IgZG9lcyBub3QgY3VycmVudGx5IGV4aXN0LiAoaWYgdGhlCgkgKiBzZXJ2ZXIgaXMgcmVjcmVhdGVkIG9yIHdhcyBpbiBhIGNsb3NlZCBwcm9qZWN0LCBldGMuIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuCgkgKiB0aGUgb3JpZ2luYWwgdmFsdWUgaWYgaXQgYmVjb21lcyBhdmFpbGFibGUgYWdhaW4pCgkgKgoJICogQHBhcmFtIG1vZHVsZSBhIG1vZHVsZQoJICogQHJldHVybiB0aGUgY3VycmVudCBkZWZhdWx0IHNlcnZlciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlcmUgaXMgbm8KCSAqICAgIGRlZmF1bHQgc2VydmVyCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVNlcnZlciBnZXREZWZhdWx0U2VydmVyKElNb2R1bGUgbW9kdWxlKSB7CgkJcmV0dXJuIE1vZHVsZVByb3BlcnRpZXMuZ2V0SW5zdGFuY2UoKS5nZXREZWZhdWx0U2VydmVyKG1vZHVsZSk7Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSBwcmVmZXJyZWQgcnVudGltZSBzZXJ2ZXIgZm9yIHRoZSBnaXZlbiBtb2R1bGUuIFNldCB0aGUgc2VydmVyIHRvCgkgKiBudWxsIHRvIGNsZWFyIHRoZSBzZXR0aW5nLiBJZiB0aGVyZSBpcyBhIHByb2JsZW0gc2F2aW5nIHRoZSBmaWxlLCBhIENvcmVFeGNlcHRpb24KCSAqIHdpbGwgYmUgdGhyb3duLgoJICogCgkgKiBAcGFyYW0gbW9kdWxlIHRoZSBtb2R1bGUgdG8gc2V0IHRoZSBkZWZhdWx0IGZvcgoJICogQHBhcmFtIHNlcnZlciB0aGUgc2VydmVyIHRvIHNldCB0aGUgZGVmYXVsdCBzZXJ2ZXIsIG9yIDxjb2RlPm51bGw8L2NvZGU+CgkgKiAgICB0byB1bnNldCB0aGUgZGVmYXVsdAoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwcm9ncmVzcwoJICogICAgcmVwb3J0aW5nIGFuZCBjYW5jZWxsYXRpb24gYXJlIG5vdCBkZXNpcmVkCgkgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtIHNldHRpbmcgdGhlIGRlZmF1bHQgc2VydmVyCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCBzZXREZWZhdWx0U2VydmVyKElNb2R1bGUgbW9kdWxlLCBJU2VydmVyIHNlcnZlciwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJTW9kdWxlUHJvcGVydGllcy5nZXRJbnN0YW5jZSgpLnNldERlZmF1bHRTZXJ2ZXIobW9kdWxlLCBzZXJ2ZXIsIG1vbml0b3IpOwoJfQp9