LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS51dGlsOwoKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVByb2plY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2U7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2VDaGFuZ2VFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklSZXNvdXJjZUNoYW5nZUxpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVJlc291cmNlRGVsdGE7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2VEZWx0YVZpc2l0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JV29ya3NwYWNlUm9vdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLlJlc291cmNlc1BsdWdpbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JTW9kdWxlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlRyYWNlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLk1vZHVsZUZhY3RvcnlEZWxlZ2F0ZTsKLyoqCiAqIAogKiAKICogQHNpbmNlIDEuMAogKi8KcHVibGljIGFic3RyYWN0IGNsYXNzIFByb2plY3RNb2R1bGVGYWN0b3J5RGVsZWdhdGUgZXh0ZW5kcyBNb2R1bGVGYWN0b3J5RGVsZWdhdGUgewoJcHJvdGVjdGVkIHN0YXRpYyBJUmVzb3VyY2VDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lcjsKCQoJcHJvdGVjdGVkIHN0YXRpYyBMaXN0IGZhY3RvcmllcyA9IG5ldyBBcnJheUxpc3QoKTsKCglwcm90ZWN0ZWQgTGlzdCBhZGRlZDsKCXByb3RlY3RlZCBMaXN0IHJlbW92ZWQ7CgoJLy8gbWFwIGZyb20gSVByb2plY3QgdG8gSU1vZHVsZVtdCglwcm90ZWN0ZWQgZmluYWwgTWFwIHByb2plY3RzID0gbmV3IEhhc2hNYXAoKTsKCXByb3RlY3RlZCBib29sZWFuIGluaXRpYWxpemVkID0gZmFsc2U7CgoJLyoqCgkgKiBDb25zdHJ1Y3QgYSBuZXcgUHJvamVjdE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZS4KCSAqLwoJcHVibGljIFByb2plY3RNb2R1bGVGYWN0b3J5RGVsZWdhdGUoKSB7CgkJc3VwZXIoKTsKCQkKCQlmYWN0b3JpZXMuYWRkKHRoaXMpOwoJCQoJCWFkZExpc3RlbmVyKCk7Cgl9CgoKCS8qKgoJICogQ2FjaGUgYW55IHByZWV4aXN0aW5nIG1vZHVsZS4KCSAqIFRPRE86IFdoZW4vd2hlcmUgaXMgdGhpcyBjYWxsZWQ/CgkgKi8KCXByb3RlY3RlZCB2b2lkIGNhY2hlTW9kdWxlcygpIHsKCQljYWNoZU1vZHVsZXModHJ1ZSk7Cgl9CgoKCS8qKgoJICogQ2FjaGUgYW55IHByZWV4aXN0aW5nIG1vZHVsZS4KCSAqIFRPRE86IFdoZW4vd2hlcmUgaXMgdGhpcyBjYWxsZWQ/CgkgKi8KCXByb3RlY3RlZCB2b2lkIGNhY2hlTW9kdWxlcyhib29sZWFuIGZvcmNlVXBkYXRlKSB7IAoJCXRyeSB7CgkJCUlQcm9qZWN0W10gcHJvamVjdHMyID0gZ2V0V29ya3NwYWNlUm9vdCgpLmdldFByb2plY3RzKCk7CgkJCWludCBzaXplID0gcHJvamVjdHMyLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCS8vVHJhY2UudHJhY2UoImNhY2hpbmc6ICIgKyB0aGlzICsgIiAiICsgcHJvamVjdHNbaV0gKyAiICIgKyBpc1ZhbGlkTW9kdWxlKHByb2plY3RzW2ldKSk7CgkJCQlpZighcHJvamVjdHMyW2ldLmlzQWNjZXNzaWJsZSgpKQoJCQkJCXJlbW92ZU1vZHVsZXMocHJvamVjdHMyW2ldKTsKCQkJCWVsc2UgaWYgKGlzVmFsaWRNb2R1bGUocHJvamVjdHMyW2ldKSAmJiAoZm9yY2VVcGRhdGUgfHwgbmVlZHNVcGRhdGluZyhwcm9qZWN0czJbaV0pKSApIHsKCQkJCQlhZGRNb2R1bGVzKHByb2plY3RzMltpXSk7CgkJCQl9IAoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgY2FjaGluZyBtb2R1bGVzIiwgZSk7CgkJfSBmaW5hbGx5IHsKCQkJaW5pdGlhbGl6ZWQgPSB0cnVlOwoJCX0KCQlmaXJlRXZlbnRzKCk7Cgl9CgoJcHJvdGVjdGVkIGJvb2xlYW4gbmVlZHNVcGRhdGluZyhJUHJvamVjdCBwcm9qZWN0KSB7CgkJcmV0dXJuIHRydWU7Cgl9CgoKCS8qKgoJICogUmV0dXJuIHRoZSB3b3Jrc3BhY2Ugcm9vdC4KCSAqIAoJICogQHJldHVybiB0aGUgd29ya3NwYWNlIHJvb3QKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgSVdvcmtzcGFjZVJvb3QgZ2V0V29ya3NwYWNlUm9vdCgpIHsKCQlyZXR1cm4gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIG1vZHVsZXMgZm9yIHRoZSBnaXZlbiBwcm9qZWN0LCBvciBudWxsCgkgKiBpZiB0aGlzIGZhY3RvcnkgZG9lcyBub3QgaGF2ZSBhIG1vZHVsZSBmb3IgdGhlIGdpdmVuIHByb2plY3QuCgkgKiAKCSAqIEBwYXJhbSBwcm9qZWN0IGEgcHJvamVjdAoJICogQHJldHVybiBhbiBhcnJheSBvZiBtb2R1bGVzLgoJICovCglwdWJsaWMgSU1vZHVsZVtdIGdldE1vZHVsZXMoSVByb2plY3QgcHJvamVjdCkgewoJCXRyeSB7CgkJCXJldHVybiAoSU1vZHVsZVtdKSBwcm9qZWN0cy5nZXQocHJvamVjdCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJLy8gaWdub3JlCgkJfQoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogQWRkIGEgcmVzb3VyY2UgbGlzdGVuZXIgdG8gdGhlIHdvcmtzcGFjZS4KCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyB2b2lkIGFkZExpc3RlbmVyKCkgewoJCWlmIChsaXN0ZW5lciAhPSBudWxsKQoJCQlyZXR1cm47CgoJCWxpc3RlbmVyID0gbmV3IElSZXNvdXJjZUNoYW5nZUxpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCByZXNvdXJjZUNoYW5nZWQoSVJlc291cmNlQ2hhbmdlRXZlbnQgZXZlbnQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIi0+LSBQcm9qZWN0TW9kdWxlRmFjdG9yeURlbGVnYXRlIGxpc3RlbmVyIHJlc3BvbmRpbmcgdG8gcmVzb3VyY2UgY2hhbmdlOiAiICsgZXZlbnQuZ2V0VHlwZSgpICsgIiAtPi0iKTsKCQkJCXRyeSB7CgkJCQkJSVJlc291cmNlRGVsdGEgZGVsdGEgPSBldmVudC5nZXREZWx0YSgpOwoJCQkJCQoJCQkJCS8vaWYgKGRlbHRhLmdldEZsYWdzKCkgPT0gSVJlc291cmNlRGVsdGEuTUFSS0VSUyB8fCBkZWx0YS5nZXRGbGFncygpID09IElSZXNvdXJjZURlbHRhLk5PX0NIQU5HRSkKCQkJCQkvLwlyZXR1cm47CgkJCQkKCQkJCQlkZWx0YS5hY2NlcHQobmV3IElSZXNvdXJjZURlbHRhVmlzaXRvcigpIHsKCQkJCQkJcHVibGljIGJvb2xlYW4gdmlzaXQoSVJlc291cmNlRGVsdGEgdmlzaXRvckRlbHRhKSB7CgkJCQkJCQlJUmVzb3VyY2UgcmVzb3VyY2UgPSB2aXNpdG9yRGVsdGEuZ2V0UmVzb3VyY2UoKTsKCQkJCQkJCS8vVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAicmVzb3VyY2U6ICIgKyByZXNvdXJjZSk7CgkKCQkJCQkJCS8vIG9ubHkgcmVzcG9uZCBjaGFuZ2VzIHdpdGhpbiBwcm9qZWN0cwoJCQkJCQkJaWYgKHJlc291cmNlICE9IG51bGwgJiYgcmVzb3VyY2UgaW5zdGFuY2VvZiBJUHJvamVjdCkgewoJCQkJCQkJCUlQcm9qZWN0IHByb2plY3QgPSAoSVByb2plY3QpIHJlc291cmNlOwoJCQkJCQkJCWhhbmRsZUdsb2JhbFByb2plY3RDaGFuZ2UocHJvamVjdCwgdmlzaXRvckRlbHRhKTsKCQkJCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCQkJCX0gZWxzZSBpZiAocmVzb3VyY2UgIT0gbnVsbCAmJiByZXNvdXJjZS5nZXRQcm9qZWN0KCkgIT0gbnVsbCkgewoJCQkJCQkJCXJldHVybiBmYWxzZTsKCQkJCQkJCX0gZWxzZQoJCQkJCQkJCXJldHVybiB0cnVlOwoJCQkJCQl9CgkJCQkJfSk7CgkJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJCS8vVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgcmVzcG9uZGluZyB0byByZXNvdXJjZSBjaGFuZ2UiLCBlKTsKCQkJCX0KCQkJCWZpcmVHbG9iYWxFdmVudHMoKTsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIi08LSBEb25lIFByb2plY3RNb2R1bGVGYWN0b3J5RGVsZWdhdGUgcmVzcG9uZGluZyB0byByZXNvdXJjZSBjaGFuZ2UgLTwtIik7CgkJCX0KCQl9OwoJCQoJCVJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5hZGRSZXNvdXJjZUNoYW5nZUxpc3RlbmVyKGxpc3RlbmVyLCBJUmVzb3VyY2VDaGFuZ2VFdmVudC5QT1NUX0NIQU5HRSk7Cgl9CgkKCS8qKgoJICogSGFuZGxlIGNoYW5nZXMgdG8gYSBwcm9qZWN0LgoJICogCgkgKiBAcGFyYW0gcHJvamVjdCBhIHByb2plY3QKCSAqIEBwYXJhbSBkZWx0YSBhIHJlc291cmNlIGRlbHRhCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgdm9pZCBoYW5kbGVHbG9iYWxQcm9qZWN0Q2hhbmdlKGZpbmFsIElQcm9qZWN0IHByb2plY3QsIElSZXNvdXJjZURlbHRhIGRlbHRhKSB7CgkJLy8gaGFuZGxlIHByb2plY3QgbGV2ZWwgY2hhbmdlcwoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gZmFjdG9yaWVzLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlQcm9qZWN0TW9kdWxlRmFjdG9yeURlbGVnYXRlIGZhY3RvcnkgPSAoUHJvamVjdE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZSkgaXRlcmF0b3IubmV4dCgpOwoJCQkvL1RyYWNlLnRyYWNlKCJGaXJpbmcgdG86ICIgKyBmYWN0b3J5KTsKCQkJZmFjdG9yeS5oYW5kbGVQcm9qZWN0Q2hhbmdlKHByb2plY3QsIGRlbHRhKTsKCQl9CgkJCgkJLy8gaGFuZGxlIGludGVybmFsIHVwZGF0ZXMKCQlpdGVyYXRvciA9IGZhY3Rvcmllcy5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJUHJvamVjdE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZSBmYWN0b3J5ID0gKFByb2plY3RNb2R1bGVGYWN0b3J5RGVsZWdhdGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJLy9UcmFjZS50cmFjZSgiRmlyaW5nIHRvOiAiICsgZmFjdG9yeSk7CgkJCWZhY3RvcnkuaGFuZGxlUHJvamVjdEludGVybmFsQ2hhbmdlKHByb2plY3QsIGRlbHRhKTsKCQl9Cgl9CgkKCS8qKgoJICogRmlyZSB0aGUgYWNjdW11bGF0ZWQgbW9kdWxlIGZhY3RvcnkgZXZlbnRzLgoJICovCglwcm90ZWN0ZWQgc3RhdGljIHZvaWQgZmlyZUdsb2JhbEV2ZW50cygpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJGaXJpbmcgZ2xvYmFsIG1vZHVsZSBldmVudCIpOwoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gZmFjdG9yaWVzLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlQcm9qZWN0TW9kdWxlRmFjdG9yeURlbGVnYXRlIGZhY3RvcnkgPSAoUHJvamVjdE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZSkgaXRlcmF0b3IubmV4dCgpOwoJCQlmYWN0b3J5LnVwZGF0ZVByb2plY3RzKCk7CgkJfQoJCQoJCWl0ZXJhdG9yID0gZmFjdG9yaWVzLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlQcm9qZWN0TW9kdWxlRmFjdG9yeURlbGVnYXRlIGZhY3RvcnkgPSAoUHJvamVjdE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZSkgaXRlcmF0b3IubmV4dCgpOwoJCQlmYWN0b3J5LmZpcmVFdmVudHMoKTsKCQl9Cgl9CgoJLyoqCgkgKiBUZW1wb3JhcnkgdG8gbWFrZSBzdXJlIHRoYXQgYWxsIHByb2plY3QgbW9kdWxlcyBhcmUgdXBkYXRlZC4KCSAqLwoJcHJpdmF0ZSB2b2lkIHVwZGF0ZVByb2plY3RzKCkgewoJCUlNb2R1bGVbXSBtb2R1bGVzMiA9IGdldE1vZHVsZXMoKTsKCQlpZiAobW9kdWxlczIgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IG1vZHVsZXMyLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCWlmIChtb2R1bGVzMltpXSBpbnN0YW5jZW9mIFByb2plY3RNb2R1bGUpCgkJCQkJKChQcm9qZWN0TW9kdWxlKSBtb2R1bGVzMltpXSkudXBkYXRlKCk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBIYW5kbGUgY2hhbmdlcyB0byBhIHByb2plY3QuCgkgKiAKCSAqIEBwYXJhbSBwcm9qZWN0IGEgcHJvamVjdAoJICogQHBhcmFtIGRlbHRhIGEgcmVzb3VyY2UgZGVsdGEKCSAqLwoJcHJpdmF0ZSB2b2lkIGhhbmRsZVByb2plY3RDaGFuZ2UoZmluYWwgSVByb2plY3QgcHJvamVjdCwgSVJlc291cmNlRGVsdGEgZGVsdGEpIHsKCQlpZighaW5pdGlhbGl6ZWQpCgkJCWNhY2hlTW9kdWxlcyhmYWxzZSk7CgkJaWYgKHByb2plY3RzLmNvbnRhaW5zS2V5KHByb2plY3QpKSB7CgkJCS8vIGFscmVhZHkgYSBtb2R1bGUKCQkJaWYgKCgoZGVsdGEuZ2V0S2luZCgpICYgIElSZXNvdXJjZURlbHRhLlJFTU9WRUQpICE9IDApIHx8ICFpc1ZhbGlkTW9kdWxlKHByb2plY3QpKSB7CgkJCQlyZW1vdmVNb2R1bGVzKHByb2plY3QpOwoJCQl9CgkJfSBlbHNlIHsKCQkJLy8gbm90IGEgbW9kdWxlCgkJCWlmIChpc1ZhbGlkTW9kdWxlKHByb2plY3QpKSB7CgkJCQlhZGRNb2R1bGVzKHByb2plY3QpOwoJCQl9CgkJfQoJfQoJCgkvKioKCSAqIEhhbmRsZSBjaGFuZ2VzIHRvIGEgcHJvamVjdC4KCSAqIAoJICogQHBhcmFtIHByb2plY3QgYSBwcm9qZWN0CgkgKiBAcGFyYW0gZGVsdGEgYSByZXNvdXJjZSBkZWx0YQoJICovCglwcml2YXRlIHZvaWQgaGFuZGxlUHJvamVjdEludGVybmFsQ2hhbmdlKGZpbmFsIElQcm9qZWN0IHByb2plY3QsIElSZXNvdXJjZURlbHRhIGRlbHRhKSB7CgkJZmluYWwgSVBhdGhbXSBwYXRocyA9IGdldExpc3RlbmVyUGF0aHMoKTsKCQlpZiAocGF0aHMgIT0gbnVsbCkgewoJCQlmaW5hbCBJTW9kdWxlW10gbW9kdWxlcyA9IGdldE1vZHVsZXMocHJvamVjdCk7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgbW9kdWxlcy5sZW5ndGg7IGkrKykgewoJCQkJZmluYWwgSU1vZHVsZSBtb2R1bGUgPSBtb2R1bGVzW2ldOwoJCQkJaWYgKG1vZHVsZSAhPSBudWxsICYmIG1vZHVsZSBpbnN0YW5jZW9mIFByb2plY3RNb2R1bGUpIHsKCQkJCQkvLyBjaGVjayBmb3IgYW55IGNoYW5nZXMgdG8gdGhlIG1vZHVsZQoJCQkJCWZpbmFsIElQYXRoIHJvb3QgPSAoKFByb2plY3RNb2R1bGUpIG1vZHVsZSkuZ2V0Um9vdEZvbGRlcigpOwoJCQkJCUlSZXNvdXJjZURlbHRhIHJvb3REZWx0YSA9IGRlbHRhLmZpbmRNZW1iZXIocm9vdCk7CgkJCQkJaWYgKHJvb3REZWx0YSAhPSBudWxsKQoJCQkJCQkoKFByb2plY3RNb2R1bGUpIG1vZHVsZSkuZmlyZU1vZHVsZUNoYW5nZUV2ZW50KHRydWUsIG51bGwsIG51bGwsIG51bGwpOwoJCQkJCQoJCQkJCS8vIGNoZWNrIGZvciBsaXN0ZW5lciBwYXRocwoJCQkJCWZpbmFsIGludCBzaXplID0gcGF0aHMubGVuZ3RoOwoJCQkJCWNsYXNzIFRlbXAgewoJCQkJCQlib29sZWFuIGZvdW5kID0gZmFsc2U7CgkJCQkJfQoJCQkJCWZpbmFsIFRlbXAgdGVtcCA9IG5ldyBUZW1wKCk7CgkJCQkJdHJ5IHsKCQkJCQkJZGVsdGEuYWNjZXB0KG5ldyBJUmVzb3VyY2VEZWx0YVZpc2l0b3IoKSB7CgkJCQkJCQlwdWJsaWMgYm9vbGVhbiB2aXNpdChJUmVzb3VyY2VEZWx0YSB2aXNpdG9yRGVsdGEpIHsKCQkJCQkJCQlpZiAodGVtcC5mb3VuZCkKCQkJCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCQkJCUlQYXRoIHBhdGggPSB2aXNpdG9yRGVsdGEuZ2V0UHJvamVjdFJlbGF0aXZlUGF0aCgpOwoJCQkJCQkJCQoJCQkJCQkJCWJvb2xlYW4gcHJlZml4ID0gZmFsc2U7CgkJCQkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplICYmICF0ZW1wLmZvdW5kOyBqKyspIHsKCQkJCQkJCQkJaWYgKHBhdGhzW2pdLmVxdWFscyhwYXRoKSkKCQkJCQkJCQkJCXRlbXAuZm91bmQgPSB0cnVlOwoJCQkJCQkJCQllbHNlIGlmIChwYXRoLmlzUHJlZml4T2YocGF0aHNbal0pKQoJCQkJCQkJCQkJcHJlZml4ID0gdHJ1ZTsKCQkJCQkJCQl9CgkJCQkJCQkJaWYgKHRlbXAuZm91bmQpIHsKCQkJCQkJCQkJKChQcm9qZWN0TW9kdWxlKSBtb2R1bGUpLnVwZGF0ZSgpOwoJCQkJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJCQkJfSBlbHNlIGlmIChwcmVmaXgpCgkJCQkJCQkJCXJldHVybiB0cnVlOwoJCQkJCQkJCWVsc2UKCQkJCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCQkJfQoJCQkJCQl9KTsKCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBzZWFyY2hpbmcgZm9yIGxpc3RlbmluZyBwYXRocyIsIGUpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCX0KCgkvKioKCSAqIEFkZCBhIG1vZHVsZSBmb3IgdGhlIGdpdmVuIHByb2plY3QuCgkgKiAKCSAqIEBwYXJhbSBwcm9qZWN0IGEgcHJvamVjdAoJICovCglwcm90ZWN0ZWQgdm9pZCBhZGRNb2R1bGVzKElQcm9qZWN0IHByb2plY3QpIHsKCQkKCQlJTW9kdWxlW10gbW9kdWxlcyA9IGNyZWF0ZU1vZHVsZXMocHJvamVjdCk7CgkJaWYgKG1vZHVsZXMgPT0gbnVsbCB8fCBtb2R1bGVzLmxlbmd0aCA9PSAwKQoJCQlyZXR1cm47CgkJcHJvamVjdHMucHV0KHByb2plY3QsIG1vZHVsZXMpOwoJCWFkZGVkID0gbmV3IEFycmF5TGlzdCgyKTsKCQlhZGRlZC5hZGRBbGwoQXJyYXlzLmFzTGlzdChtb2R1bGVzKSk7Cgl9CgoJLyoqCgkgKiBSZW1vdmUgdGhlIG1vZHVsZXMgdGhhdCByZXByZXNlbnRzIHRoZSBnaXZlbiBwcm9qZWN0LgoJICogCgkgKiBAcGFyYW0gcHJvamVjdCBhIHByb2plY3QKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcmVtb3ZlTW9kdWxlcyhJUHJvamVjdCBwcm9qZWN0KSB7CgkJCgkJdHJ5IHsKCQkJSU1vZHVsZVtdIG1vZHVsZXMgPSAoSU1vZHVsZVtdKSBwcm9qZWN0cy5nZXQocHJvamVjdCk7CgkJCQoJCQlwcm9qZWN0cy5yZW1vdmUocHJvamVjdCk7CgkJCWlmIChyZW1vdmVkID09IG51bGwpCgkJCQlyZW1vdmVkID0gbmV3IEFycmF5TGlzdCgyKTsKCQkJaWYobW9kdWxlcyA9PSBudWxsKQoJCQkJcmV0dXJuOwoJCQlyZW1vdmVkLmFkZEFsbChBcnJheXMuYXNMaXN0KG1vZHVsZXMpKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciByZW1vdmluZyBtb2R1bGUgcHJvamVjdCIsIGUpOwoJCX0KCX0KCgkvKioKCSAqIEZpcmUgdGhlIGFjY3VtdWxhdGVkIG1vZHVsZSBmYWN0b3J5IGV2ZW50cy4KCSAqLwoJcHJvdGVjdGVkIHZvaWQgZmlyZUV2ZW50cygpIHsKCQlpZiAoKGFkZGVkID09IG51bGwgfHwgYWRkZWQuaXNFbXB0eSgpKSAmJiAocmVtb3ZlZCA9PSBudWxsIHx8IHJlbW92ZWQuaXNFbXB0eSgpKSkKCQkJcmV0dXJuOwoKCQlJTW9kdWxlW10gYWRkID0gbnVsbDsKCQlpZiAoYWRkZWQgIT0gbnVsbCkgewoJCQlhZGQgPSBuZXcgSU1vZHVsZVthZGRlZC5zaXplKCldOwoJCQlhZGRlZC50b0FycmF5KGFkZCk7CgkJfQoJCUlNb2R1bGVbXSByZW1vdmUgPSBudWxsOwoJCWlmIChyZW1vdmVkICE9IG51bGwpIHsKCQkJcmVtb3ZlID0gbmV3IElNb2R1bGVbcmVtb3ZlZC5zaXplKCldOwoJCQlyZW1vdmVkLnRvQXJyYXkocmVtb3ZlKTsKCQl9CgkJCgkJZmlyZU1vZHVsZUZhY3RvcnlFdmVudChhZGQsIHJlbW92ZSk7CgkJYWRkZWQgPSBuZXcgQXJyYXlMaXN0KDIpOwoJCXJlbW92ZWQgPSBuZXcgQXJyYXlMaXN0KDIpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoZSBwcm9qZWN0IG1heSBjb250YWluIG1vZHVsZXMgb2YgdGhlIGNvcnJlY3QgdHlwZS4KCSAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgb25seSB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLgoJICogCgkgKiBAcGFyYW0gcHJvamVjdCBhIHByb2plY3QKCSAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHByb2plY3QgbWF5IGNvbnRhaW4gbW9kdWxlcywgYW5kCgkgKiAgICA8Y29kZT5mYWxzZTwvY29kZT4gaWYgaXQgZGVmaW5pdGVseSBkb2VzIG5vdAoJICovCglwcm90ZWN0ZWQgYWJzdHJhY3QgYm9vbGVhbiBpc1ZhbGlkTW9kdWxlKElQcm9qZWN0IHByb2plY3QpOwoKCS8qKgoJICogQ3JlYXRlcyB0aGUgbW9kdWxlcyBmb3IgYSBnaXZlbiBwcm9qZWN0LgoJICogCgkgKiBAcGFyYW0gcHJvamVjdCBhIHByb2plY3QgdG8gY3JlYXRlIG1vZHVsZXMgZm9yCgkgKiBAcmV0dXJuIGEgcG9zc2libHkgZW1wdHkgYXJyYXkgb2YgbW9kdWxlcwoJICovCglwcm90ZWN0ZWQgYWJzdHJhY3QgSU1vZHVsZVtdIGNyZWF0ZU1vZHVsZXMoSVByb2plY3QgcHJvamVjdCk7CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIHJlc291cmNlcyB0aGF0IHRoZSBtb2R1bGUgc2hvdWxkIGxpc3RlbiB0bwoJICogZm9yIHN0YXRlIGNoYW5nZXMuIFRoZSBwYXRocyBzaG91bGQgYmUgcHJvamVjdCByZWxhdGl2ZSBwYXRocy4KCSAqIFN1YmNsYXNzZXMgY2FuIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHByb3ZpZGUgdGhlIHBhdGhzLgoJICoKCSAqIEByZXR1cm4gYSBwb3NzaWJseSBlbXB0eSBhcnJheSBvZiBwYXRocwoJICovCglwcm90ZWN0ZWQgSVBhdGhbXSBnZXRMaXN0ZW5lclBhdGhzKCkgewoJCXJldHVybiBudWxsOwoJfQp9