LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbDsKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5TZXJ2ZXJFdmVudDsKLyoqCiAqIE5vdGlmaWNhdGlvbiBtYW5hZ2VyIGZvciBzZXJ2ZXIuCiAqIAogKiBAc2luY2UgMS4wCiAqLwpwdWJsaWMgY2xhc3MgU2VydmVyTm90aWZpY2F0aW9uTWFuYWdlciB7Cglwcml2YXRlIExpc3QgbGlzdGVuZXJMaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCgkvKioKCSAqIEZvciBtYXNraW5nIGV2ZW50IG9uIGFsbCBjaGFuZ2VzLgoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTExfRVZFTlRTID0gMHhGRkZGOwoJCglwcml2YXRlIGNsYXNzIExpc3RlbmVyRW50cnkgewoJCXByaXZhdGUgSVNlcnZlckxpc3RlbmVyIGxpc3RlbmVyOwoJCXByaXZhdGUgaW50IGV2ZW50TWFzazsKCQkKCQlwcml2YXRlIExpc3RlbmVyRW50cnkoSVNlcnZlckxpc3RlbmVyIGN1ckxpc3RlbmVyLCBpbnQgY3VyRXZlbnRNYXNrKSB7CgkJCWxpc3RlbmVyID0gY3VyTGlzdGVuZXI7CgkJCWV2ZW50TWFzayA9IGN1ckV2ZW50TWFzazsKCQl9CgkJCgkJSVNlcnZlckxpc3RlbmVyIGdldExpc3RlbmVyKCkgewoJCQlyZXR1cm4gbGlzdGVuZXI7CgkJfQoJCQoJCWludCBnZXRFdmVudE1hc2soKSB7CgkJCXJldHVybiBldmVudE1hc2s7CgkJfQoJfQoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IG5vdGlmaWNhdGlvbiBtYW5hZ2VyLgoJICovCglwdWJsaWMgU2VydmVyTm90aWZpY2F0aW9uTWFuYWdlcigpIHsKCQlzdXBlcigpOwoJfQoKCS8qKgoJICogQWRkIGxpc3RlbmVyIGZvciBhbGwgZXZlbnRzLgoJICogCgkgKiBAcGFyYW0gY3VyTGlzdGVuZXIKCSAqLwoJcHVibGljIHZvaWQgYWRkTGlzdGVuZXIoSVNlcnZlckxpc3RlbmVyIGN1ckxpc3RlbmVyKSB7CgkJYWRkTGlzdGVuZXIoY3VyTGlzdGVuZXIsIEFMTF9FVkVOVFMpOwoJfQoJCgkvKioKCSAqIEFkZCBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50cyBzcGVjaWZpZWQgYnkgdGhlIG1hc2suCgkgKiAKCSAqIEBwYXJhbSBjdXJMaXN0ZW5lcgoJICogQHBhcmFtIGV2ZW50TWFzawoJICovCglwdWJsaWMgdm9pZCBhZGRMaXN0ZW5lcihJU2VydmVyTGlzdGVuZXIgY3VyTGlzdGVuZXIsIGludCBldmVudE1hc2spIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICItPi0gQWRkaW5nIHNlcnZlciBsaXN0ZW5lciB0byBub3RpZmljYXRpb24gbWFuYWdlcjogIiArIGN1ckxpc3RlbmVyICsgIiAiICsgZXZlbnRNYXNrICsgIiAtPi0iKTsKCQlpZiAoY3VyTGlzdGVuZXIgPT0gbnVsbCkgewoJCQlyZXR1cm47CgkJfQoJCQoJCXN5bmNocm9uaXplZCAobGlzdGVuZXJMaXN0KSB7CgkJCWxpc3RlbmVyTGlzdC5hZGQobmV3IExpc3RlbmVyRW50cnkoY3VyTGlzdGVuZXIsIGV2ZW50TWFzaykpOwoJCX0KCX0KCglwcm90ZWN0ZWQgdm9pZCBicm9hZGNhc3RDaGFuZ2UoU2VydmVyRXZlbnQgZXZlbnQpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICItPi0gQnJvYWRjYXN0aW5nIHNlcnZlciBldmVudDogIiArIGV2ZW50ICsgIiAtPi0iKTsKCQlpZiAoZXZlbnQgPT0gbnVsbCkgewoJCQlyZXR1cm47CgkJfQoJCWludCBldmVudEtpbmQgPSBldmVudC5nZXRLaW5kKCk7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiICBTZXJ2ZXIgZXZlbnQga2luZDogIiArIGV2ZW50S2luZCArICIgLT4tIik7CgkJCgkJLy8gb25seSBub3RpZnkgbGlzdGVuZXJzIHRoYXQgbGlzdGVuIHRvIG1vZHVsZSBldmVudAoJCWludCBzaXplOwoJCUxpc3RlbmVyRW50cnlbXSBsaXN0ZW5lcnM7CgkJc3luY2hyb25pemVkIChsaXN0ZW5lckxpc3QpIHsKCQkJc2l6ZSA9IGxpc3RlbmVyTGlzdC5zaXplKCk7CgkJCWxpc3RlbmVycyA9IChMaXN0ZW5lckVudHJ5W10pIGxpc3RlbmVyTGlzdC50b0FycmF5KG5ldyBMaXN0ZW5lckVudHJ5W3NpemVdKTsKCQl9CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJTGlzdGVuZXJFbnRyeSBjdXJFbnRyeSA9IGxpc3RlbmVyc1tpXTsKCQkJaW50IG1hc2sgPSBjdXJFbnRyeS5nZXRFdmVudE1hc2soKTsKCgkJCS8vIGNoZWNrIGlmIHRoZSB0eXBlIG9mIHRoZSBldmVudCBtYXRjaGVzIHRoZSBtYXNrLCBlLmcuIHNlcnZlciBvciBtb2R1bGUgY2hhbmdlCgkJCWJvb2xlYW4gaXNUeXBlTWF0Y2ggPSAoKG1hc2sgJiBldmVudEtpbmQgJiBTZXJ2ZXJFdmVudC5TRVJWRVJfQ0hBTkdFKSAhPSAwKSAKCQkJCQl8fCAoKG1hc2sgJiBldmVudEtpbmQgJiBTZXJ2ZXJFdmVudC5NT0RVTEVfQ0hBTkdFKSAhPSAwKTsKCQkJLy8gY2hlY2sgdGhlIGtpbmQgb2YgY2hhbmdlCgkJCWJvb2xlYW4gaXNLaW5kTWF0Y2ggPSAobWFzayAmIGV2ZW50S2luZCBeIFNlcnZlckV2ZW50LlNFUlZFUl9DSEFOR0UgXiBTZXJ2ZXJFdmVudC5NT0RVTEVfQ0hBTkdFKSAhPSAwOwoJCQkKCQkJaWYgKGlzVHlwZU1hdGNoICYmIGlzS2luZE1hdGNoKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICItPi0gRmlyaW5nIHNlcnZlciBldmVudCB0byBsaXN0ZW5lcjogIiArIGN1ckVudHJ5LmdldExpc3RlbmVyKCkgKyAiIC0+LSIpOwoJCQkJdHJ5IHsKCQkJCQlUcmFjZS50cmFjZShUcmFjZS5MSVNURU5FUlMsICIgIEZpcmluZyBzZXJ2ZXIgZXZlbnQgdG8gbGlzdGVuZXI6ICIgKyBjdXJFbnRyeS5nZXRMaXN0ZW5lcigpKTsKCQkJCQljdXJFbnRyeS5nZXRMaXN0ZW5lcigpLnNlcnZlckNoYW5nZWQoZXZlbnQpOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICIgIEVycm9yIGZpcmluZyBzZXJ2ZXIgZXZlbnQ6ICIgKyBjdXJFbnRyeS5nZXRMaXN0ZW5lcigpLCBlKTsKCQkJCX0KCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkxJU1RFTkVSUywgIi08LSBEb25lIEZpcmluZyBzZXJ2ZXIgZXZlbnQgLTwtIik7CgkJCX0KCQl9CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiLTwtIERvbmUgYnJvYWRjYXN0aW5nIHNlcnZlciBldmVudCAtPC0iKTsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGxpc3RlbmVyIGxpc3QgaXMgbm90IGVtcHR5OyBvdGhlcndpc2UsIHJldHVybnMgZmFsc2UuCgkgKiAKCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgbGlzdGVuZXIgbGlzdCBpcyBub3QgZW1wdHk7IG90aGVyd2lzZSwgcmV0dXJucyBmYWxzZQoJICovCglwcm90ZWN0ZWQgYm9vbGVhbiBoYXNMaXN0ZW5lckVudHJpZXMoKSB7CgkJcmV0dXJuIGxpc3RlbmVyTGlzdC5zaXplKCkgPT0gMDsKCX0KCQoJLyoqCgkgKiBSZW1vdmUgYSBsaXN0ZW5lciBmcm9tIG5vdGlmaWNhdGlvbi4KCSAqIAoJICogQHBhcmFtIGN1ckxpc3RlbmVyCgkgKi8KCXB1YmxpYyB2b2lkIHJlbW92ZUxpc3RlbmVyKElTZXJ2ZXJMaXN0ZW5lciBjdXJMaXN0ZW5lcikgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIi0+LSBSZW1vdmluZyBzZXJ2ZXIgbGlzdGVuZXIgZnJvbSBub3RpZmljYXRpb24gbWFuYWdlcjogIiArIGN1ckxpc3RlbmVyICsgIiAtPi0iKTsKCQlpZiAoY3VyTGlzdGVuZXIgPT0gbnVsbCkgewoJCQlyZXR1cm47CgkJfQoJCUxpc3RlbmVyRW50cnkgbWF0Y2hlZExpc3RlbmVyRW50cnkgPSBudWxsOwoJCUl0ZXJhdG9yIGxpc3RlbmVySXRlciA9IGxpc3RlbmVyTGlzdC5pdGVyYXRvcigpOwoJCXdoaWxlIChtYXRjaGVkTGlzdGVuZXJFbnRyeSA9PSBudWxsICYmIGxpc3RlbmVySXRlci5oYXNOZXh0KCkpIHsKCQkJTGlzdGVuZXJFbnRyeSBjdXJFbnRyeSA9IChMaXN0ZW5lckVudHJ5KWxpc3RlbmVySXRlci5uZXh0KCk7CgkJCWlmIChjdXJMaXN0ZW5lci5lcXVhbHMoY3VyRW50cnkuZ2V0TGlzdGVuZXIoKSkpIHsKCQkJCW1hdGNoZWRMaXN0ZW5lckVudHJ5ID0gY3VyRW50cnk7CgkJCX0KCQl9CgkJaWYgKG1hdGNoZWRMaXN0ZW5lckVudHJ5ICE9IG51bGwpIHsKCQkJc3luY2hyb25pemVkIChsaXN0ZW5lckxpc3QpIHsKCQkJCWxpc3RlbmVyTGlzdC5yZW1vdmUobWF0Y2hlZExpc3RlbmVyRW50cnkpOwoJCQl9CgkJfQoJfQp9