LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWw7CgppbXBvcnQgamF2YS51dGlsLio7CmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JTW9kdWxlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXI7Ci8qKgogKiBIZWxwZXIgdG8gb2J0YWluIGFuZCBzdG9yZSB0aGUgZ2xvYmFsIHB1Ymxpc2ggaW5mb3JtYXRpb24uCiAqICh3aGF0IGZpbGVzIHdlcmUgcHVibGlzaGVkIGFuZCB3aGVuKSBEZWxlZ2F0ZXMgdG8gUHVibGlzaFN0YXRlCiAqIGZvciBhbGwgc2VydmVyIHNwZWNpZmljIHB1Ymxpc2hpbmcgaW5mb3JtYXRpb24uCiAqLwpwdWJsaWMgY2xhc3MgUHVibGlzaEluZm8gewoJcHJvdGVjdGVkIHN0YXRpYyBQdWJsaXNoSW5mbyBpbnN0YW5jZTsKCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBQVUJMSVNIX0RJUiA9ICJwdWJsaXNoIjsKCgkvLyBtYXAgb2Ygc2VydmVyIHJlZnMgdG8gSVBhdGhzCglwcm90ZWN0ZWQgTWFwIHNlcnZlcnM7CgoJLy8gbWFwIG9mIGNvbnRyb2wgcmVmIHRvIFB1Ymxpc2hDb250cm9sCglwcm90ZWN0ZWQgTWFwIHB1Ymxpc2hDb250cm9sczsKCgkvLyBsaXN0IG9mIHNlcnZlclJlZnMgdGhhdCBoYXZlIGJlZW4gbG9hZGVkCglwcm90ZWN0ZWQgTGlzdCBsb2FkZWRTZXJ2ZXJzOwoKCS8qKgoJICogUHVibGlzaEluZm8gY29uc3RydWN0b3IgY29tbWVudC4KCSAqLwoJcHJpdmF0ZSBQdWJsaXNoSW5mbygpIHsKCQlzdXBlcigpOwoJCgkJc2VydmVycyA9IG5ldyBIYXNoTWFwKCk7CgkJbG9hZGVkU2VydmVycyA9IG5ldyBBcnJheUxpc3QoKTsKCQlwdWJsaXNoQ29udHJvbHMgPSBuZXcgSGFzaE1hcCgpOwoJCWxvYWQoKTsKCX0KCgkvKioKCSAqIFJldHVybiB0aGUgcHVibGlzaCBpbmZvLgoJICogCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5QdWJsaXNoSW5mbwoJICovCglwdWJsaWMgc3RhdGljIFB1Ymxpc2hJbmZvIGdldFB1Ymxpc2hJbmZvKCkgewoJCWlmIChpbnN0YW5jZSA9PSBudWxsKQoJCQlpbnN0YW5jZSA9IG5ldyBQdWJsaXNoSW5mbygpOwoJCXJldHVybiBpbnN0YW5jZTsKCX0KCglwcm90ZWN0ZWQgU3RyaW5nIGdldFB1Ymxpc2hDb250cm9sUmVmKElTZXJ2ZXIgc2VydmVyLCBJTW9kdWxlW10gcGFyZW50cywgSU1vZHVsZSBtb2R1bGUpIHsKCQlTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkJc2IuYXBwZW5kKHNlcnZlci5nZXRJZCgpKTsKCgkJaWYgKHBhcmVudHMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHBhcmVudHMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJc2IuYXBwZW5kKCIjIik7CgkJCQlzYi5hcHBlbmQocGFyZW50c1tpXS5nZXRJZCgpKTsKCQkJfQoJCX0KCQkKCQlzYi5hcHBlbmQoIiMiKTsKCQlzYi5hcHBlbmQobW9kdWxlLmdldElkKCkpOwoJCXJldHVybiBzYi50b1N0cmluZygpOwoJfQoJCglwcm90ZWN0ZWQgU3RyaW5nIGdldFB1Ymxpc2hDb250cm9sUmVmKFN0cmluZyBzZXJ2ZXJJZCwgU3RyaW5nIHBhcmVudHNSZWYsIFN0cmluZyBtZW1lbnRvKSB7CgkJU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoJCXNiLmFwcGVuZChzZXJ2ZXJJZCk7CgkJCgkJaWYgKHBhcmVudHNSZWYgIT0gbnVsbCAmJiBwYXJlbnRzUmVmLmxlbmd0aCgpID4gMCkgewoJCQlzYi5hcHBlbmQoIiMiKTsKCQkJc2IuYXBwZW5kKHBhcmVudHNSZWYpOwoJCX0KCQkKCQlzYi5hcHBlbmQoIiMiKTsKCQlzYi5hcHBlbmQobWVtZW50byk7CgkJcmV0dXJuIHNiLnRvU3RyaW5nKCk7Cgl9CgkKCXByb3RlY3RlZCBTdHJpbmcgZ2V0UGFyZW50c01lbWVudG8oSU1vZHVsZVtdIHBhcmVudHMpIHsKCQlTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkJYm9vbGVhbiBmaXJzdCA9IHRydWU7CgkJCgkJaWYgKHBhcmVudHMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHBhcmVudHMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJaWYgKCFmaXJzdCkKCQkJCQlzYi5hcHBlbmQoIiMiKTsKCQkJCWVsc2UKCQkJCQlmaXJzdCA9IGZhbHNlOwoJCQkJc2IuYXBwZW5kKHBhcmVudHNbaV0uZ2V0SWQoKSk7CgkJCX0KCQl9CgkJCgkJcmV0dXJuIHNiLnRvU3RyaW5nKCk7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gdGhlIHB1Ymxpc2ggc3RhdGUuCgkgKiAKCSAqIEByZXR1cm4gb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlB1Ymxpc2hTdGF0ZQoJICogQHBhcmFtIHNlcnZlciBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlcgoJICovCglwdWJsaWMgUHVibGlzaENvbnRyb2wgZ2V0UHVibGlzaENvbnRyb2woSVNlcnZlciBzZXJ2ZXIsIElNb2R1bGVbXSBwYXJlbnRzLCBJTW9kdWxlIG1vZHVsZSkgewoJCVN0cmluZyBjb250cm9sUmVmID0gZ2V0UHVibGlzaENvbnRyb2xSZWYoc2VydmVyLCBwYXJlbnRzLCBtb2R1bGUpOwoJCQoJCS8vIGhhdmUgd2UgdHJpZWQgbG9hZGluZyB5ZXQ/CgkJU3RyaW5nIHNlcnZlcklkID0gc2VydmVyLmdldElkKCk7CgkJaWYgKHNlcnZlcnMuY29udGFpbnNLZXkoc2VydmVySWQpKSB7CgkJCWlmICghbG9hZGVkU2VydmVycy5jb250YWlucyhzZXJ2ZXJJZCkpIHsKCQkJCWxvYWRTZXJ2ZXJQdWJsaXNoQ29udHJvbHMoc2VydmVySWQpOwoJCQkJbG9hZGVkU2VydmVycy5hZGQoc2VydmVySWQpOwoJCQl9IGVsc2UgewoJCQkJLy8gYWxyZWFkeSBsb2FkZWQKCQkJfQoJCX0gZWxzZSB7CgkJCS8vIGZpcnN0IHRpbWUgc2VydmVyIGlzIGJlaW5nIHVzZWQKCQkJSVBhdGggcGF0aCA9IFNlcnZlclBsdWdpbi5nZXRJbnN0YW5jZSgpLmdldFN0YXRlTG9jYXRpb24oKS5hcHBlbmQoUFVCTElTSF9ESVIpOwoJCQlGaWxlIGZpbGUgPSBuZXcgRmlsZShwYXRoLnRvT1NTdHJpbmcoKSk7CgkJCWlmICghZmlsZS5leGlzdHMoKSkKCQkJCWZpbGUubWtkaXIoKTsKCQoJCQlmaWxlID0gbnVsbDsKCQkJaW50IGkgPSAwOwoJCQl3aGlsZSAoZmlsZSA9PSBudWxsIHx8IGZpbGUuZXhpc3RzKCkpIHsKCQkJCXBhdGggPSBTZXJ2ZXJQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRTdGF0ZUxvY2F0aW9uKCkuYXBwZW5kKFBVQkxJU0hfRElSKS5hcHBlbmQoImRhdGEiICsgaSArICIueG1sIik7CgkJCQlpZiAoc2VydmVycy5nZXQocGF0aCkgPT0gbnVsbCkKCQkJCQlmaWxlID0gbmV3IEZpbGUocGF0aC50b09TU3RyaW5nKCkpOwoJCQkJaSsrOwoJCQl9CgkJCQoJCQlzZXJ2ZXJzLnB1dChzZXJ2ZXJJZCwgcGF0aCk7CgkJCWxvYWRlZFNlcnZlcnMuYWRkKHNlcnZlcklkKTsKCQkJc2F2ZSgpOwoJCX0KCgkJLy8gY2hlY2sgaWYgaXQgbm93IGV4aXN0cwoJCWlmIChwdWJsaXNoQ29udHJvbHMuY29udGFpbnNLZXkoY29udHJvbFJlZikpIHsKCQkJUHVibGlzaENvbnRyb2wgY29udHJvbCA9IChQdWJsaXNoQ29udHJvbCkgcHVibGlzaENvbnRyb2xzLmdldChjb250cm9sUmVmKTsKCQkJaWYgKGNvbnRyb2wgIT0gbnVsbCkKCQkJCXJldHVybiBjb250cm9sOwoJCX0KCQoJCS8vIGhhdmUgdG8gY3JlYXRlIGEgbmV3IG9uZQoJCVB1Ymxpc2hDb250cm9sIGNvbnRyb2wgPSBuZXcgUHVibGlzaENvbnRyb2woZ2V0UGFyZW50c01lbWVudG8ocGFyZW50cyksIG1vZHVsZS5nZXRJZCgpKTsKCQlwdWJsaXNoQ29udHJvbHMucHV0KGNvbnRyb2xSZWYsIGNvbnRyb2wpOwoJCXJldHVybiBjb250cm9sOwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIGxvYWQoKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiTG9hZGluZyBwdWJsaXNoIGluZm8iKTsKCQlTdHJpbmcgZmlsZW5hbWUgPSBTZXJ2ZXJQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRTdGF0ZUxvY2F0aW9uKCkuYXBwZW5kKCJwdWJsaXNoLnhtbCIpLnRvT1NTdHJpbmcoKTsKCQoJCXRyeSB7CgkJCUlNZW1lbnRvIG1lbWVudG8gPSBYTUxNZW1lbnRvLmxvYWRNZW1lbnRvKGZpbGVuYW1lKTsKCQoJCQlJTWVtZW50b1tdIHNlcnZlckNoaWxkID0gbWVtZW50by5nZXRDaGlsZHJlbigic2VydmVyIik7CgkJCWludCBzaXplID0gc2VydmVyQ2hpbGQubGVuZ3RoOwoJCQlzZXJ2ZXJzID0gbmV3IEhhc2hNYXAoc2l6ZSArIDIpOwoJCgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlTdHJpbmcgaWQgPSBzZXJ2ZXJDaGlsZFtpXS5nZXRTdHJpbmcoImlkIik7CgkJCQlTdHJpbmcgcGF0aCA9IHNlcnZlckNoaWxkW2ldLmdldFN0cmluZygicGF0aCIpOwoJCgkJCQlzZXJ2ZXJzLnB1dChpZCwgbmV3IFBhdGgocGF0aCkpOwoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkNvdWxkIG5vdCBsb2FkIGdsb2JhbCBwdWJsaXNoIGluZm86ICIgKyBlLmdldE1lc3NhZ2UoKSk7CgkJfQoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIHNhdmUoKSB7CgkJU3RyaW5nIGZpbGVuYW1lID0gU2VydmVyUGx1Z2luLmdldEluc3RhbmNlKCkuZ2V0U3RhdGVMb2NhdGlvbigpLmFwcGVuZCgicHVibGlzaC54bWwiKS50b09TU3RyaW5nKCk7CgkKCQl0cnkgewoJCQlYTUxNZW1lbnRvIG1lbWVudG8gPSBYTUxNZW1lbnRvLmNyZWF0ZVdyaXRlUm9vdCgicHVibGlzaC1pbmZvIik7CgkKCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBzZXJ2ZXJzLmtleVNldCgpLml0ZXJhdG9yKCk7CgkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCVN0cmluZyBzZXJ2ZXJJZCA9IChTdHJpbmcpIGl0ZXJhdG9yLm5leHQoKTsKCQkJCUlQYXRoIHBhdGggPSAoSVBhdGgpIHNlcnZlcnMuZ2V0KHNlcnZlcklkKTsKCQoJCQkJSU1lbWVudG8gc2VydmVyID0gbWVtZW50by5jcmVhdGVDaGlsZCgic2VydmVyIik7CgkJCQlzZXJ2ZXIucHV0U3RyaW5nKCJpZCIsIHNlcnZlcklkKTsKCQkJCXNlcnZlci5wdXRTdHJpbmcoInBhdGgiLCBwYXRoLnRvU3RyaW5nKCkpOwoJCQl9CgkKCQkJbWVtZW50by5zYXZlVG9GaWxlKGZpbGVuYW1lKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDb3VsZCBub3Qgc2F2ZSBnbG9iYWwgcHVibGlzaCBpbmZvIiwgZSk7CgkJfQoJfQoJCglwdWJsaWMgdm9pZCBzYXZlKElTZXJ2ZXIgc2VydmVyKSB7CgkJc2F2ZVNlcnZlclB1Ymxpc2hDb250cm9scyhzZXJ2ZXIuZ2V0SWQoKSk7Cgl9CgoJLyoqCgkgKiAKCSAqLwoJcHJvdGVjdGVkIHZvaWQgbG9hZFNlcnZlclB1Ymxpc2hDb250cm9scyhTdHJpbmcgc2VydmVyUmVmKSB7CgkJSVBhdGggcGF0aCA9IChJUGF0aCkgc2VydmVycy5nZXQoc2VydmVyUmVmKTsKCQlTdHJpbmcgZmlsZW5hbWUgPSBwYXRoLnRvT1NTdHJpbmcoKTsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJMb2FkaW5nIHB1Ymxpc2ggY29udHJvbHMgZnJvbSAiICsgZmlsZW5hbWUpOwoKCQl0cnkgewoJCQlJTWVtZW50byBtZW1lbnRvMiA9IFhNTE1lbWVudG8ubG9hZE1lbWVudG8oZmlsZW5hbWUpOwoJCQlJTWVtZW50b1tdIGNoaWxkcmVuID0gbWVtZW50bzIuZ2V0Q2hpbGRyZW4oIm1vZHVsZSIpOwoJCgkJCWludCBzaXplID0gY2hpbGRyZW4ubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJUHVibGlzaENvbnRyb2wgY29udHJvbCA9IG5ldyBQdWJsaXNoQ29udHJvbChjaGlsZHJlbltpXSk7CgkJCQlwdWJsaXNoQ29udHJvbHMucHV0KGdldFB1Ymxpc2hDb250cm9sUmVmKHNlcnZlclJlZiwgY29udHJvbC5nZXRQYXJlbnRzUmVmKCksIGNvbnRyb2wuZ2V0TWVtZW50bygpKSwgY29udHJvbCk7CgkJCX0KCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5XQVJOSU5HLCAiQ291bGQgbm90IGxvYWQgcHVibGlzaCBjb250cm9sIGluZm9ybWF0aW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOwoJCX0KCX0KCQoJLyoqCgkgKiAKCSAqLwoJcHJvdGVjdGVkIHZvaWQgc2F2ZVNlcnZlclB1Ymxpc2hDb250cm9scyhTdHJpbmcgc2VydmVyUmVmKSB7CgkJaWYgKCFzZXJ2ZXJzLmNvbnRhaW5zS2V5KHNlcnZlclJlZikpCgkJCXJldHVybjsKCgkJSVBhdGggcGF0aCA9IChJUGF0aCkgc2VydmVycy5nZXQoc2VydmVyUmVmKTsKCQlTdHJpbmcgZmlsZW5hbWUgPSBwYXRoLnRvT1NTdHJpbmcoKTsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJTYXZpbmcgcHVibGlzaCBjb250cm9scyB0byAiICsgZmlsZW5hbWUpOwoJCgkJdHJ5IHsKCQkJWE1MTWVtZW50byBtZW1lbnRvID0gWE1MTWVtZW50by5jcmVhdGVXcml0ZVJvb3QoInNlcnZlciIpOwoKCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBwdWJsaXNoQ29udHJvbHMua2V5U2V0KCkuaXRlcmF0b3IoKTsKCQkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQkJU3RyaW5nIGNvbnRyb2xSZWYgPSAoU3RyaW5nKSBpdGVyYXRvci5uZXh0KCk7CgkJCQlpZiAoY29udHJvbFJlZi5zdGFydHNXaXRoKHNlcnZlclJlZiArICIjIikpIHsKCQkJCQlQdWJsaXNoQ29udHJvbCBjb250cm9sID0gKFB1Ymxpc2hDb250cm9sKSBwdWJsaXNoQ29udHJvbHMuZ2V0KGNvbnRyb2xSZWYpOwoJCQkJCUlNZW1lbnRvIGNoaWxkID0gbWVtZW50by5jcmVhdGVDaGlsZCgibW9kdWxlIik7CgkJCQkJY29udHJvbC5zYXZlKGNoaWxkKTsKCQkJCX0KCQkJfQoJCQltZW1lbnRvLnNhdmVUb0ZpbGUoZmlsZW5hbWUpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNvdWxkIG5vdCBzYXZlIHB1Ymxpc2ggY29udHJvbCBpbmZvcm1hdGlvbiIsIGUpOwoJCX0KCX0KfQ==