LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzIElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWw7CgppbXBvcnQgamF2YS51dGlsLio7CmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGU7Ci8qKgogKiBIZWxwZXIgdG8gb2J0YWluIGFuZCBzdG9yZSB0aGUgZ2xvYmFsIHB1Ymxpc2ggaW5mb3JtYXRpb24uCiAqICh3aGF0IGZpbGVzIHdlcmUgcHVibGlzaGVkIGFuZCB3aGVuKSBEZWxlZ2F0ZXMgdG8gUHVibGlzaFN0YXRlCiAqIGZvciBhbGwgc2VydmVyIHNwZWNpZmljIHB1Ymxpc2hpbmcgaW5mb3JtYXRpb24uCiAqLwpwdWJsaWMgY2xhc3MgUHVibGlzaEluZm8gewoJcHJvdGVjdGVkIHN0YXRpYyBQdWJsaXNoSW5mbyBpbnN0YW5jZTsKCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBQVUJMSVNIX0RJUiA9ICJwdWJsaXNoIjsKCgkvLyBtYXAgb2Ygc2VydmVyIHJlZnMgdG8gSVBhdGhzCglwcm90ZWN0ZWQgTWFwIHNlcnZlcnM7CgoJLy8gbWFwIG9mIGNvbnRyb2wgcmVmIHRvIFB1Ymxpc2hDb250cm9sCglwcm90ZWN0ZWQgTWFwIHB1Ymxpc2hDb250cm9sczsKCgkvLyBsaXN0IG9mIHNlcnZlclJlZnMgdGhhdCBoYXZlIGJlZW4gbG9hZGVkCglwcm90ZWN0ZWQgTGlzdCBsb2FkZWRTZXJ2ZXJzOwoKCS8qKgoJICogUHVibGlzaEluZm8gY29uc3RydWN0b3IgY29tbWVudC4KCSAqLwoJcHJpdmF0ZSBQdWJsaXNoSW5mbygpIHsKCQlzdXBlcigpOwoJCgkJc2VydmVycyA9IG5ldyBIYXNoTWFwKCk7CgkJbG9hZGVkU2VydmVycyA9IG5ldyBBcnJheUxpc3QoKTsKCQlwdWJsaXNoQ29udHJvbHMgPSBuZXcgSGFzaE1hcCgpOwoJCWxvYWQoKTsKCX0KCgkvKioKCSAqIFJldHVybiB0aGUgcHVibGlzaCBpbmZvLgoJICogCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5QdWJsaXNoSW5mbwoJICovCglwdWJsaWMgc3RhdGljIFB1Ymxpc2hJbmZvIGdldFB1Ymxpc2hJbmZvKCkgewoJCWlmIChpbnN0YW5jZSA9PSBudWxsKQoJCQlpbnN0YW5jZSA9IG5ldyBQdWJsaXNoSW5mbygpOwoJCXJldHVybiBpbnN0YW5jZTsKCX0KCglwcm90ZWN0ZWQgU3RyaW5nIGdldFB1Ymxpc2hDb250cm9sUmVmKElTZXJ2ZXIgc2VydmVyLCBMaXN0IHBhcmVudHMsIElNb2R1bGUgbW9kdWxlKSB7CgkJU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoJCXNiLmFwcGVuZChzZXJ2ZXIuZ2V0SWQoKSk7CgkJCgkJaWYgKHBhcmVudHMgIT0gbnVsbCkgewoJCQlJdGVyYXRvciBpdGVyYXRvciA9IHBhcmVudHMuaXRlcmF0b3IoKTsKCQkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQkJSU1vZHVsZSBwYXJlbnQgPSAoSU1vZHVsZSkgaXRlcmF0b3IubmV4dCgpOwoJCQkJc2IuYXBwZW5kKCIjIik7CgkJCQlzYi5hcHBlbmQocGFyZW50LmdldElkKCkpOwoJCQl9CgkJfQoJCQoJCXNiLmFwcGVuZCgiIyIpOwoJCXNiLmFwcGVuZChtb2R1bGUuZ2V0SWQoKSk7CgkJcmV0dXJuIHNiLnRvU3RyaW5nKCk7Cgl9CgkKCXByb3RlY3RlZCBTdHJpbmcgZ2V0UHVibGlzaENvbnRyb2xSZWYoU3RyaW5nIHNlcnZlcklkLCBTdHJpbmcgcGFyZW50c1JlZiwgU3RyaW5nIG1lbWVudG8pIHsKCQlTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkJc2IuYXBwZW5kKHNlcnZlcklkKTsKCQkKCQlpZiAocGFyZW50c1JlZiAhPSBudWxsICYmIHBhcmVudHNSZWYubGVuZ3RoKCkgPiAwKSB7CgkJCXNiLmFwcGVuZCgiIyIpOwoJCQlzYi5hcHBlbmQocGFyZW50c1JlZik7CgkJfQoJCQoJCXNiLmFwcGVuZCgiIyIpOwoJCXNiLmFwcGVuZChtZW1lbnRvKTsKCQlyZXR1cm4gc2IudG9TdHJpbmcoKTsKCX0KCQoJcHJvdGVjdGVkIFN0cmluZyBnZXRQYXJlbnRzTWVtZW50byhMaXN0IHBhcmVudHMpIHsKCQlTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkJYm9vbGVhbiBmaXJzdCA9IHRydWU7CgkJCgkJaWYgKHBhcmVudHMgIT0gbnVsbCkgewoJCQlJdGVyYXRvciBpdGVyYXRvciA9IHBhcmVudHMuaXRlcmF0b3IoKTsKCQkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQkJSU1vZHVsZSBwYXJlbnQgPSAoSU1vZHVsZSkgaXRlcmF0b3IubmV4dCgpOwoJCQkJaWYgKCFmaXJzdCkKCQkJCQlzYi5hcHBlbmQoIiMiKTsKCQkJCWVsc2UKCQkJCQlmaXJzdCA9IGZhbHNlOwoJCQkJc2IuYXBwZW5kKHBhcmVudC5nZXRJZCgpKTsKCQkJfQoJCX0KCQkKCQlyZXR1cm4gc2IudG9TdHJpbmcoKTsKCX0KCQoJLyoqCgkgKiBSZXR1cm4gdGhlIHB1Ymxpc2ggc3RhdGUuCgkgKiAKCSAqIEByZXR1cm4gb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlB1Ymxpc2hTdGF0ZQoJICogQHBhcmFtIHNlcnZlciBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlcgoJICovCglwdWJsaWMgUHVibGlzaENvbnRyb2wgZ2V0UHVibGlzaENvbnRyb2woSVNlcnZlciBzZXJ2ZXIsIExpc3QgcGFyZW50cywgSU1vZHVsZSBtb2R1bGUpIHsKCQlTdHJpbmcgY29udHJvbFJlZiA9IGdldFB1Ymxpc2hDb250cm9sUmVmKHNlcnZlciwgcGFyZW50cywgbW9kdWxlKTsKCQkKCQkvLyBoYXZlIHdlIHRyaWVkIGxvYWRpbmcgeWV0PwoJCVN0cmluZyBzZXJ2ZXJJZCA9IHNlcnZlci5nZXRJZCgpOwoJCWlmIChzZXJ2ZXJzLmNvbnRhaW5zS2V5KHNlcnZlcklkKSkgewoJCQlpZiAoIWxvYWRlZFNlcnZlcnMuY29udGFpbnMoc2VydmVySWQpKSB7CgkJCQlsb2FkU2VydmVyUHVibGlzaENvbnRyb2xzKHNlcnZlcklkKTsKCQkJCWxvYWRlZFNlcnZlcnMuYWRkKHNlcnZlcklkKTsKCQkJfSBlbHNlIHsKCQkJCS8vIGFscmVhZHkgbG9hZGVkCgkJCX0KCQl9IGVsc2UgewoJCQkvLyBmaXJzdCB0aW1lIHNlcnZlciBpcyBiZWluZyB1c2VkCgkJCUlQYXRoIHBhdGggPSBTZXJ2ZXJQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRTdGF0ZUxvY2F0aW9uKCkuYXBwZW5kKFBVQkxJU0hfRElSKTsKCQkJRmlsZSBmaWxlID0gbmV3IEZpbGUocGF0aC50b09TU3RyaW5nKCkpOwoJCQlpZiAoIWZpbGUuZXhpc3RzKCkpCgkJCQlmaWxlLm1rZGlyKCk7CgkKCQkJZmlsZSA9IG51bGw7CgkJCWludCBpID0gMDsKCQkJd2hpbGUgKGZpbGUgPT0gbnVsbCB8fCBmaWxlLmV4aXN0cygpKSB7CgkJCQlwYXRoID0gU2VydmVyUGx1Z2luLmdldEluc3RhbmNlKCkuZ2V0U3RhdGVMb2NhdGlvbigpLmFwcGVuZChQVUJMSVNIX0RJUikuYXBwZW5kKCJkYXRhIiArIGkgKyAiLnhtbCIpOwoJCQkJaWYgKHNlcnZlcnMuZ2V0KHBhdGgpID09IG51bGwpCgkJCQkJZmlsZSA9IG5ldyBGaWxlKHBhdGgudG9PU1N0cmluZygpKTsKCQkJCWkrKzsKCQkJfQoJCQkKCQkJc2VydmVycy5wdXQoc2VydmVySWQsIHBhdGgpOwoJCQlsb2FkZWRTZXJ2ZXJzLmFkZChzZXJ2ZXJJZCk7CgkJCXNhdmUoKTsKCQl9CgoJCS8vIGNoZWNrIGlmIGl0IG5vdyBleGlzdHMKCQlpZiAocHVibGlzaENvbnRyb2xzLmNvbnRhaW5zS2V5KGNvbnRyb2xSZWYpKSB7CgkJCVB1Ymxpc2hDb250cm9sIGNvbnRyb2wgPSAoUHVibGlzaENvbnRyb2wpIHB1Ymxpc2hDb250cm9scy5nZXQoY29udHJvbFJlZik7CgkJCWlmIChjb250cm9sICE9IG51bGwpCgkJCQlyZXR1cm4gY29udHJvbDsKCQl9CgkKCQkvLyBoYXZlIHRvIGNyZWF0ZSBhIG5ldyBvbmUKCQlQdWJsaXNoQ29udHJvbCBjb250cm9sID0gbmV3IFB1Ymxpc2hDb250cm9sKGdldFBhcmVudHNNZW1lbnRvKHBhcmVudHMpLCBtb2R1bGUuZ2V0SWQoKSk7CgkJcHVibGlzaENvbnRyb2xzLnB1dChjb250cm9sUmVmLCBjb250cm9sKTsKCQlyZXR1cm4gY29udHJvbDsKCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgdm9pZCBsb2FkKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIkxvYWRpbmcgcHVibGlzaCBpbmZvIik7CgkJU3RyaW5nIGZpbGVuYW1lID0gU2VydmVyUGx1Z2luLmdldEluc3RhbmNlKCkuZ2V0U3RhdGVMb2NhdGlvbigpLmFwcGVuZCgicHVibGlzaC54bWwiKS50b09TU3RyaW5nKCk7CgkKCQl0cnkgewoJCQlJTWVtZW50byBtZW1lbnRvID0gWE1MTWVtZW50by5sb2FkTWVtZW50byhmaWxlbmFtZSk7CgkKCQkJSU1lbWVudG9bXSBzZXJ2ZXJDaGlsZCA9IG1lbWVudG8uZ2V0Q2hpbGRyZW4oInNlcnZlciIpOwoJCQlpbnQgc2l6ZSA9IHNlcnZlckNoaWxkLmxlbmd0aDsKCQkJc2VydmVycyA9IG5ldyBIYXNoTWFwKHNpemUgKyAyKTsKCQoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJU3RyaW5nIGlkID0gc2VydmVyQ2hpbGRbaV0uZ2V0U3RyaW5nKCJpZCIpOwoJCQkJU3RyaW5nIHBhdGggPSBzZXJ2ZXJDaGlsZFtpXS5nZXRTdHJpbmcoInBhdGgiKTsKCQoJCQkJc2VydmVycy5wdXQoaWQsIG5ldyBQYXRoKHBhdGgpKTsKCQkJfQoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJDb3VsZCBub3QgbG9hZCBnbG9iYWwgcHVibGlzaCBpbmZvOiAiICsgZS5nZXRNZXNzYWdlKCkpOwoJCX0KCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgdm9pZCBzYXZlKCkgewoJCVN0cmluZyBmaWxlbmFtZSA9IFNlcnZlclBsdWdpbi5nZXRJbnN0YW5jZSgpLmdldFN0YXRlTG9jYXRpb24oKS5hcHBlbmQoInB1Ymxpc2gueG1sIikudG9PU1N0cmluZygpOwoJCgkJdHJ5IHsKCQkJWE1MTWVtZW50byBtZW1lbnRvID0gWE1MTWVtZW50by5jcmVhdGVXcml0ZVJvb3QoInB1Ymxpc2gtaW5mbyIpOwoJCgkJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gc2VydmVycy5rZXlTZXQoKS5pdGVyYXRvcigpOwoJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQlTdHJpbmcgc2VydmVySWQgPSAoU3RyaW5nKSBpdGVyYXRvci5uZXh0KCk7CgkJCQlJUGF0aCBwYXRoID0gKElQYXRoKSBzZXJ2ZXJzLmdldChzZXJ2ZXJJZCk7CgkKCQkJCUlNZW1lbnRvIHNlcnZlciA9IG1lbWVudG8uY3JlYXRlQ2hpbGQoInNlcnZlciIpOwoJCQkJc2VydmVyLnB1dFN0cmluZygiaWQiLCBzZXJ2ZXJJZCk7CgkJCQlzZXJ2ZXIucHV0U3RyaW5nKCJwYXRoIiwgcGF0aC50b1N0cmluZygpKTsKCQkJfQoJCgkJCW1lbWVudG8uc2F2ZVRvRmlsZShmaWxlbmFtZSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiQ291bGQgbm90IHNhdmUgZ2xvYmFsIHB1Ymxpc2ggaW5mbyIsIGUpOwoJCX0KCX0KCQoJcHVibGljIHZvaWQgc2F2ZShJU2VydmVyIHNlcnZlcikgewoJCXNhdmVTZXJ2ZXJQdWJsaXNoQ29udHJvbHMoc2VydmVyLmdldElkKCkpOwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIGxvYWRTZXJ2ZXJQdWJsaXNoQ29udHJvbHMoU3RyaW5nIHNlcnZlclJlZikgewoJCUlQYXRoIHBhdGggPSAoSVBhdGgpIHNlcnZlcnMuZ2V0KHNlcnZlclJlZik7CgkJU3RyaW5nIGZpbGVuYW1lID0gcGF0aC50b09TU3RyaW5nKCk7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiTG9hZGluZyBwdWJsaXNoIGNvbnRyb2xzIGZyb20gIiArIGZpbGVuYW1lKTsKCgkJdHJ5IHsKCQkJSU1lbWVudG8gbWVtZW50bzIgPSBYTUxNZW1lbnRvLmxvYWRNZW1lbnRvKGZpbGVuYW1lKTsKCQkJSU1lbWVudG9bXSBjaGlsZHJlbiA9IG1lbWVudG8yLmdldENoaWxkcmVuKCJtb2R1bGUiKTsKCQoJCQlpbnQgc2l6ZSA9IGNoaWxkcmVuLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCVB1Ymxpc2hDb250cm9sIGNvbnRyb2wgPSBuZXcgUHVibGlzaENvbnRyb2woY2hpbGRyZW5baV0pOwoJCQkJcHVibGlzaENvbnRyb2xzLnB1dChnZXRQdWJsaXNoQ29udHJvbFJlZihzZXJ2ZXJSZWYsIGNvbnRyb2wuZ2V0UGFyZW50c1JlZigpLCBjb250cm9sLmdldE1lbWVudG8oKSksIGNvbnRyb2wpOwoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkNvdWxkIG5vdCBsb2FkIHB1Ymxpc2ggY29udHJvbCBpbmZvcm1hdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKCQl9Cgl9CgkKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIHNhdmVTZXJ2ZXJQdWJsaXNoQ29udHJvbHMoU3RyaW5nIHNlcnZlclJlZikgewoJCWlmICghc2VydmVycy5jb250YWluc0tleShzZXJ2ZXJSZWYpKQoJCQlyZXR1cm47CgoJCUlQYXRoIHBhdGggPSAoSVBhdGgpIHNlcnZlcnMuZ2V0KHNlcnZlclJlZik7CgkJU3RyaW5nIGZpbGVuYW1lID0gcGF0aC50b09TU3RyaW5nKCk7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiU2F2aW5nIHB1Ymxpc2ggY29udHJvbHMgdG8gIiArIGZpbGVuYW1lKTsKCQoJCXRyeSB7CgkJCVhNTE1lbWVudG8gbWVtZW50byA9IFhNTE1lbWVudG8uY3JlYXRlV3JpdGVSb290KCJzZXJ2ZXIiKTsKCgkJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gcHVibGlzaENvbnRyb2xzLmtleVNldCgpLml0ZXJhdG9yKCk7CgkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCVN0cmluZyBjb250cm9sUmVmID0gKFN0cmluZykgaXRlcmF0b3IubmV4dCgpOwoJCQkJaWYgKGNvbnRyb2xSZWYuc3RhcnRzV2l0aChzZXJ2ZXJSZWYgKyAiIyIpKSB7CgkJCQkJUHVibGlzaENvbnRyb2wgY29udHJvbCA9IChQdWJsaXNoQ29udHJvbCkgcHVibGlzaENvbnRyb2xzLmdldChjb250cm9sUmVmKTsKCQkJCQlJTWVtZW50byBjaGlsZCA9IG1lbWVudG8uY3JlYXRlQ2hpbGQoIm1vZHVsZSIpOwoJCQkJCWNvbnRyb2wuc2F2ZShjaGlsZCk7CgkJCQl9CgkJCX0KCQkJbWVtZW50by5zYXZlVG9GaWxlKGZpbGVuYW1lKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDb3VsZCBub3Qgc2F2ZSBwdWJsaXNoIGNvbnRyb2wgaW5mb3JtYXRpb24iLCBlKTsKCQl9Cgl9Cn0K