LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbDsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2VSdWxlRmFjdG9yeTsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLlJlc291cmNlc1BsdWdpbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuam9icy5JU2NoZWR1bGluZ1J1bGU7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuam9icy5NdWx0aVJ1bGU7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTkxTOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXI7Ci8qKgogKiBKb2IgdG8gcHVibGlzaCB0byBhIHBhcnRpY3VsYXIgc2VydmVyLgogKi8KcHVibGljIGNsYXNzIFB1Ymxpc2hTZXJ2ZXJKb2IgZXh0ZW5kcyBDaGFpbmVkSm9iIHsKCXByb3RlY3RlZCBpbnQga2luZDsKCXByb3RlY3RlZCBib29sZWFuIGNoZWNrOwoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IHB1Ymxpc2hpbmcgam9iLgoJICogCgkgKiBAcGFyYW0gc2VydmVyIHRoZSBzZXJ2ZXIgdG8gcHVibGlzaCB0bwoJICogQHBhcmFtIGtpbmQgdGhlIGtpbmQgb2YgcHVibGlzaAoJICogQHBhcmFtIGNoZWNrCgkgKi8KCXB1YmxpYyBQdWJsaXNoU2VydmVySm9iKElTZXJ2ZXIgc2VydmVyLCBpbnQga2luZCwgYm9vbGVhbiBjaGVjaykgewoJCXN1cGVyKE5MUy5iaW5kKE1lc3NhZ2VzLnB1Ymxpc2hpbmcsIHNlcnZlci5nZXROYW1lKCkpLCBzZXJ2ZXIpOwoJCXRoaXMua2luZCA9IGtpbmQ7CgkJdGhpcy5jaGVjayA9IGNoZWNrOwoJCQoJCUlSZXNvdXJjZVJ1bGVGYWN0b3J5IHJ1bGVGYWN0b3J5ID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJ1bGVGYWN0b3J5KCk7CgkJCgkJLy8gMTAyMjI3IC0gbG9jayBlbnRpcmUgd29ya3NwYWNlIGR1cmluZyBwdWJsaXNoCgkJLy8gVE9ETyB3aWxsIGhhdmUgdG8gcmV2aXNpdCBwb3N0IDAuNyB0byBkZXRlcm1pbmUgaWYgdGhlcmUgaXMgYSBiZXR0ZXIgd2F5IHRvCgkJLy8gZG8gdGhpcywgc2luY2UgaXQgd291bGQgYmUgcHJlZmVycmFibGUgbm90IHRvIGxvY2sgdGhlIGVudGlyZSB3b3Jrc3BhY2UsIGFuZAoJCS8vIHRoZXJlZm9yZSBhbGxvdyBtdWx0aXBsZSBzZXJ2ZXJzIHRvIHB1Ymxpc2ggYXQgb25jZQoJCQoJCS8vIGZpbmQgYWxsIHByb2plY3RzIHRoYXQgbW9kdWxlcyBhcmUgaW4KCQkvKkxpc3QgcHJvamVjdExpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJSXRlcmF0b3IgaXRlcmF0b3IgPSAoKFNlcnZlcilzZXJ2ZXIpLmdldEFsbE1vZHVsZXMoKS5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSU1vZHVsZVtdIG1vZHVsZXMgPSAoSU1vZHVsZVtdKSBpdGVyYXRvci5uZXh0KCk7CgkJCUlQcm9qZWN0IHByb2plY3QgPSBtb2R1bGVzW21vZHVsZXMubGVuZ3RoIC0gMV0uZ2V0UHJvamVjdCgpOwoJCQlpZiAocHJvamVjdCAhPSBudWxsICYmICFwcm9qZWN0TGlzdC5jb250YWlucyhwcm9qZWN0KSkKCQkJCXByb2plY3RMaXN0LmFkZChwcm9qZWN0KTsKCQl9CgkJCgkJLy8gYWRkIGRlcGVuZGFudCBwcm9qZWN0cwoJCWl0ZXJhdG9yID0gcHJvamVjdExpc3QuaXRlcmF0b3IoKTsKCQlMaXN0IGRlcFByb2plY3RMaXN0ID0gbmV3IEFycmF5TGlzdCgpOyAvLyB1c2UgdG8gYXZvaWQgY29uY3VycmVudCBtb2RpZmljYXRpb24KCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlQcm9qZWN0IHByb2plY3QgPSAoSVByb2plY3QpIGl0ZXJhdG9yLm5leHQoKTsKCQkJdHJ5IHsKCQkJCUlQcm9qZWN0W10gcmVmcyA9IHByb2plY3QuZ2V0RGVzY3JpcHRpb24oKS5nZXRSZWZlcmVuY2VkUHJvamVjdHMoKTsKCQkJCWlmIChyZWZzICE9IG51bGwpIHsKCQkJCQlpbnQgc2l6ZSA9IHJlZnMubGVuZ3RoOwoJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKQoJCQkJCQlpZiAocmVmc1tpXSAhPSBudWxsICYmICFwcm9qZWN0TGlzdC5jb250YWlucyhyZWZzW2ldKSAmJiAhZGVwUHJvamVjdExpc3QuY29udGFpbnMocmVmc1tpXSkpCgkJCQkJCQlkZXBQcm9qZWN0TGlzdC5hZGQocmVmc1tpXSk7CgkJCQl9CgkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJDb3VsZCBub3QgY29tcHV0ZSByZWZlcmVuY2VkIHByb2plY3RzIiwgY2UpOwoJCQl9CgkJfQoJCQoJCWl0ZXJhdG9yID0gZGVwUHJvamVjdExpc3QuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCXByb2plY3RMaXN0LmFkZChpdGVyYXRvci5uZXh0KCkpOwoJCX0KCQkKCQkvLyBjb21iaW5lIGFuZCBidWlsZCBhbGwgdGhlIHJ1bGVzCgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCWl0ZXJhdG9yID0gcHJvamVjdExpc3QuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlQcm9qZWN0IHByb2plY3QgPSAoSVByb2plY3QpIGl0ZXJhdG9yLm5leHQoKTsKCQkJSVNjaGVkdWxpbmdSdWxlIHJ1bGUgPSBydWxlRmFjdG9yeS5jcmVhdGVSdWxlKHByb2plY3QpOwoJCQlpZiAocnVsZSAhPSBudWxsICYmICFsaXN0LmNvbnRhaW5zKHJ1bGUpKQoJCQkJbGlzdC5hZGQocnVsZSk7CgkJCQoJCQlydWxlID0gcnVsZUZhY3RvcnkubW9kaWZ5UnVsZShwcm9qZWN0KTsKCQkJaWYgKHJ1bGUgIT0gbnVsbCAmJiAhbGlzdC5jb250YWlucyhydWxlKSkKCQkJCWxpc3QuYWRkKHJ1bGUpOwoJCQkKCQkJcnVsZSA9IHJ1bGVGYWN0b3J5LnZhbGlkYXRlRWRpdFJ1bGUobmV3IElSZXNvdXJjZVtdIHsgcHJvamVjdCB9KTsKCQkJaWYgKHJ1bGUgIT0gbnVsbCAmJiAhbGlzdC5jb250YWlucyhydWxlKSkKCQkJCWxpc3QuYWRkKHJ1bGUpOwoJCQkKCQkJcnVsZSA9IHJ1bGVGYWN0b3J5Lm1hcmtlclJ1bGUocHJvamVjdCk7CgkJCWlmIChydWxlICE9IG51bGwgJiYgIWxpc3QuY29udGFpbnMocnVsZSkpCgkJCQlsaXN0LmFkZChydWxlKTsKCQkJCgkJCXJ1bGUgPSBydWxlRmFjdG9yeS5yZWZyZXNoUnVsZShwcm9qZWN0KTsKCQkJaWYgKHJ1bGUgIT0gbnVsbCAmJiAhbGlzdC5jb250YWlucyhydWxlKSkKCQkJCWxpc3QuYWRkKHJ1bGUpOwoJCX0KCQkKCQlpbnQgc2l6ZSA9IGxpc3Quc2l6ZSgpOwoJCUlTY2hlZHVsaW5nUnVsZVtdIHJ1bGVzID0gbmV3IElTY2hlZHVsaW5nUnVsZVtzaXplICsgMV07CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspCgkJCXJ1bGVzW2ldID0gKElTY2hlZHVsaW5nUnVsZSkgbGlzdC5nZXQoaSk7CgkJCgkJcnVsZXNbc2l6ZV0gPSBuZXcgU2VydmVyU2NoZWR1bGluZ1J1bGUoc2VydmVyKTsqLwoJCQoJCUlTY2hlZHVsaW5nUnVsZVtdIHJ1bGVzID0gbmV3IElTY2hlZHVsaW5nUnVsZVsyXTsKCQlydWxlc1swXSA9IHJ1bGVGYWN0b3J5LmNyZWF0ZVJ1bGUoUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKSk7CgkJcnVsZXNbMV0gPSBuZXcgU2VydmVyU2NoZWR1bGluZ1J1bGUoc2VydmVyKTsKCQkKCQlzZXRSdWxlKE11bHRpUnVsZS5jb21iaW5lKHJ1bGVzKSk7Cgl9CgoJLyoqCgkgKiBDcmVhdGUgYSBuZXcgcHVibGlzaGluZyBqb2IuCgkgKiAKCSAqIEBwYXJhbSBzZXJ2ZXIgdGhlIHNlcnZlciB0byBwdWJsaXNoIHRvCgkgKi8KCXB1YmxpYyBQdWJsaXNoU2VydmVySm9iKElTZXJ2ZXIgc2VydmVyKSB7CgkJdGhpcyhzZXJ2ZXIsIElTZXJ2ZXIuUFVCTElTSF9JTkNSRU1FTlRBTCwgdHJ1ZSk7Cgl9CgoJLyoqCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5qb2JzLkpvYiNzaG91bGRSdW4oKQoJICovCglwdWJsaWMgYm9vbGVhbiBzaG91bGRSdW4oKSB7CgkJaWYgKCFzdXBlci5zaG91bGRSdW4oKSkKCQkJcmV0dXJuIGZhbHNlOwoJCQoJCWlmICghY2hlY2spCgkJCXJldHVybiB0cnVlOwoJCXJldHVybiBTZXJ2ZXJQcmVmZXJlbmNlcy5nZXRJbnN0YW5jZSgpLmlzQXV0b1B1Ymxpc2hpbmcoKSAmJiAoKFNlcnZlcilnZXRTZXJ2ZXIoKSkuc2hvdWxkUHVibGlzaCgpOwoJfQoKCS8qKgoJICogQHNlZSBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuam9icy5Kb2IjcnVuKElQcm9ncmVzc01vbml0b3IpCgkgKi8KCXByb3RlY3RlZCBJU3RhdHVzIHJ1bihJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlyZXR1cm4gZ2V0U2VydmVyKCkucHVibGlzaChraW5kLCBtb25pdG9yKTsKCX0KfQ==