LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA3LCAyMDA4IGNvbXBlb3BsZSBBRyBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqIAljb21wZW9wbGUgQUcgKFN0ZWZhbiBMaWViaWcpIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqIAlJQk0gQ29ycG9yYXRpb24gLSBhZGFwdGF0aW9uIHRvIEpBUiBkZWx0YXMgYW5kIG9uLWdvaW5nIGRldmVsb3BtZW50CioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5wMi5hcnRpZmFjdC5vcHRpbWl6ZXJzLmphcmRlbHRhOwoKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuTnVsbFByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwucDIubWV0YWRhdGEuQXJ0aWZhY3RLZXk7CmltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnByb3Zpc2lvbmFsLnAyLmFydGlmYWN0LnJlcG9zaXRvcnkuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwucHJvdmlzaW9uYWwucDIuYXJ0aWZhY3QucmVwb3NpdG9yeS5wcm9jZXNzaW5nLio7CmltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnByb3Zpc2lvbmFsLnAyLmNvcmUuUHJvdmlzaW9uRXhjZXB0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5wcm92aXNpb25hbC5wMi5tZXRhZGF0YS5JQXJ0aWZhY3RLZXk7CmltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuVmVyc2lvbjsKCnB1YmxpYyBjbGFzcyBPcHRpbWl6ZXIgewoKCXByaXZhdGUgSUFydGlmYWN0UmVwb3NpdG9yeSByZXBvc2l0b3J5OwoJcHJpdmF0ZSBpbnQgd2lkdGg7Cglwcml2YXRlIGludCBkZXB0aDsKCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSkFSX0RFTFRBX0ZPUk1BVCA9ICJqYXJEZWx0YSI7IC8vJE5PTi1OTFMtMSQKCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBKQVJfREVMVEFfUEFUQ0hfU1RFUCA9ICJvcmcuZWNsaXBzZS5lcXVpbm94LnAyLnByb2Nlc3NpbmcuSmFyRGVsdGFQYXRjaFN0ZXAiOyAvLyROT04tTkxTLTEkCgoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29tcGFyYXRvciBBUlRJRkFDVF9ERVNDUklQVE9SX1ZFUlNJT05fQ09NUEFSQVRPUiA9IG5ldyBBcnRpZmFjdERlc2NyaXB0b3JWZXJzaW9uQ29tcGFyYXRvcigpOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29tcGFyYXRvciBBUlRJRkFDVF9LRVlfVkVSU0lPTl9DT01QQVJBVE9SID0gbmV3IEFydGlmYWN0S2V5VmVyc2lvbkNvbXBhcmF0b3IoKTsKCgkvKioKCSAqIFRoaXMgb3B0aW1pemVyIHBlcmZvcm1zIGRlbHRhIGdlbmVyYXRpb24gYmFzZWQgb24gKGN1cnJlbnRseSkgamJkaWZmLiAKCSAqIFRoZSBvcHRpbWl6YXRpb24gY2FuIGJlIGNvbnRyb2xsZWQgd2l0aCB0aGUgtHdpZHRotCBhbmQgdGhlILRkZXB0aLQgcGFyYW1ldGVyLgoJICogtHdpZHRotCBkZWZpbmVzIGZvciBob3cgbWFueSC0cmVsYXRlZLQgYXJ0aWZhY3Qga2V5cyBhIGRlbHRhIHNob3VsZCBiZSBnZW5lcmF0ZWQsCgkgKiBzdGFydGluZyBmcm9tIHRoZSBtb3N0IHVwLXRvLWRhdGUuCgkgKiC0ZGVwdGi0IGRlZmluZXMgdG8gaG93IG1hbnkgcHJlZGVjZXNzb3IgYSBkZWx0YSBzaG91bGQgYmUgZ2VuZXJhdGVkLgoJICogCgkgKiBXaXRoIEFLKGMtdikgOiBBSyAtIGFydGlmYWN0IGtleSwgYyAtIGFydGlmYWN0IGlkLCB2IC0gYXJ0aWZhY3QgdmVyc2lvbgoJICogdGhlILRyZXBvc2l0b3J5IGNvbnRlbnS0IGNhbiBiZSB2aWV3ZWQgYSB0d28gZGltZW5zaW9uYWwgYXJyYXksIHdoZXJlIHRoZQoJICogYXJ0aWZhY3Qga2V5cyBmb3IgdGhlIHNhbWUgY29tcG9uZW50IGFyZSBpbiBvcmRlciBvZiB0aGVpciB2ZXJzaW9uOiAKCSAqIDxwcmU+PGNvZGU+CgkgKiAgICAgdz0xICAgICAgIHc9MgoJICogICAgICB8ICAgICAgICB8CgkgKiAgICAgIHwgKy0tLS0tLS4tLS0tLS0tLS0tLS0rIGQ9MgoJICogICAgICB8IHwgKy0tLS0uLS0tKyBkPTEgICAgfAoJICogICAgICB8IHwgfCAgICB8ICAgfCAgICAgICAgdgoJICogWyAgICB2IHwgfCAgICB2ICAgdiAgICAgICAgdgoJICogWyBBSyh4LDIuMCkgQUsoeCwxLjUpIEFLKHgsMS4xKSBdCgkgKiBbIEFLKHksMi4wKSBBSyh5LDEuOSkgXQoJICogWyBBSyh6LDIuMCkgQUsoeiwxLjUpIEFLKHosMS4zKSBBSyh6LDEuMCkgXQoJICogXQoJICogPC9jb2RlPjwvcHJlPiAgCgkgKiBFLmc6IHdpdGggYSC0d2lkdGi0IG9mIG9uZSBhbmQgYSC0ZGVwdGi0IG9mIHR3byB0aGUgb3B0aW1pemVyIHdvdWxkCgkgKiBjcmVhdGUgdHdvIGRlbHRhcyBmb3IgY29tcG9uZW50ILR4tCBmcm9tIDEuNSB0byAyLjAgYW5kIGZyb20gMS4xIHRvIDIuMC4gICAgCgkgKiAKCSAqIEBwYXJhbSByZXBvc2l0b3J5CgkgKiBAcGFyYW0gd2lkdGgKCSAqIEBwYXJhbSBkZXB0aAoJICovCglwdWJsaWMgT3B0aW1pemVyKElBcnRpZmFjdFJlcG9zaXRvcnkgcmVwb3NpdG9yeSwgaW50IHdpZHRoLCBpbnQgZGVwdGgpIHsKCQl0aGlzLnJlcG9zaXRvcnkgPSByZXBvc2l0b3J5OwoJCXRoaXMud2lkdGggPSB3aWR0aDsKCQl0aGlzLmRlcHRoID0gZGVwdGg7Cgl9CgoJcHVibGljIHZvaWQgcnVuKCkgewoJCVN5c3RlbS5vdXQucHJpbnRsbigiU3RhcnRpbmcgZGVsdGEgKGphcmRlbHRhKSBvcHRpbWl6YXRpb25zICh3aWR0aD0iICsgd2lkdGggKyAiLCBkZXB0aD0iICsgZGVwdGggKyAiKSIpOwoJCUlBcnRpZmFjdEtleVtdW10ga2V5cyA9IGdldFNvcnRlZFJlbGF0ZWRBcnRpZmFjdEtleXMocmVwb3NpdG9yeS5nZXRBcnRpZmFjdEtleXMoKSk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7CgkJCWlmIChrZXlzW2ldLmxlbmd0aCA8IDIpCgkJCQkvLyBOb3RoaW5nIHRvIGRpZmYgaGVyZSEKCQkJCWNvbnRpbnVlOwoJCQlpbnQgbWluV2lkdGggPSBNYXRoLm1pbih3aWR0aCwga2V5c1tpXS5sZW5ndGgpOwoJCQlmb3IgKGludCBqID0gMDsgaiA8IG1pbldpZHRoOyBqKyspIHsKCQkJCUlBcnRpZmFjdEtleSBrZXkgPSBrZXlzW2ldW2pdOwoJCQkJYm9vbGVhbiBpc0FyY2hpdmUgPSBrZXkuZ2V0Q2xhc3NpZmllcigpLmVxdWFscygicGx1Z2luIik7IC8vJE5PTi1OTFMtMSQKCQkJCW9wdGltaXplKGtleXNbaV0sIGtleSk7CgkJCX0KCQl9CgkJU3lzdGVtLm91dC5wcmludGxuKCJEb25lLiIpOwoKCX0KCglwcml2YXRlIHZvaWQgb3B0aW1pemUoSUFydGlmYWN0S2V5W10ga2V5cywgSUFydGlmYWN0S2V5IGtleSkgewoJCUlBcnRpZmFjdERlc2NyaXB0b3JbXSBkZXNjcmlwdG9ycyA9IHJlcG9zaXRvcnkuZ2V0QXJ0aWZhY3REZXNjcmlwdG9ycyhrZXkpOwoJCUlBcnRpZmFjdERlc2NyaXB0b3IgY2Fub25pY2FsID0gbnVsbDsKCQlmb3IgKGludCBrID0gMDsgayA8IGRlc2NyaXB0b3JzLmxlbmd0aDsgaysrKSB7CgkJCUlBcnRpZmFjdERlc2NyaXB0b3IgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JzW2tdOwoJCQlib29sZWFuIG9wdGltaXplZCA9IGZhbHNlOwoJCQlpZiAoaXNDYW5vbmljYWwoZGVzY3JpcHRvcikpCgkJCQljYW5vbmljYWwgPSBkZXNjcmlwdG9yOwoJCQllbHNlCgkJCQlvcHRpbWl6ZWQgfD0gaXNPcHRpbWl6ZWQoZGVzY3JpcHRvcik7CgkJCWlmICghb3B0aW1pemVkKQoJCQkJb3B0aW1pemUoY2Fub25pY2FsLCBrZXlzKTsKCQl9Cgl9CgoJcHJpdmF0ZSBJQXJ0aWZhY3RLZXkgZ2V0VmVyc2lvbmxlc3NLZXkoSUFydGlmYWN0S2V5IGtleSkgewoJCXJldHVybiBuZXcgQXJ0aWZhY3RLZXkoa2V5LmdldENsYXNzaWZpZXIoKSwga2V5LmdldElkKCksIFZlcnNpb24uZW1wdHlWZXJzaW9uKTsKCX0KCgkvKioKCSAqIFRoaXMgbWV0aG9kIHJldHJpZXZlcyBhIGxpc3Qgb2YgbGlzdCBvZiBJQXJ0aWZhY3RLZXlzLiBUaGUgYXJ0aWZhY3Qga2V5cyBpbiB0aGUKCSAqIGxpc3Qgb2YgYXJ0aWZhY3Qga2V5cyBhcmUgYWxsILRzdHJvbmdseSByZWxhdGVktCB0byBlYWNoIG90aGVyIHN1Y2ggdGhhdCBhcmUgIAoJICogZXF1YWwgYnV0IG5vdCBjb25zaWRlcmluZyB0aGUgdmVyc2lvbnMuIFRoaXMgbGlzdCBpcyBzb3J0ZWQgc3VjaCB0aGF0IHRoZSAKCSAqIG5ld2VyIHZlcnNpb25zIGFyZSBmaXJzdCBpbiB0aGUgbGlzdC48cD4KCSAqIFdpdGggQUsoYy12KSA6IEFLIC0gYXJ0aWZhY3Qga2V5LCBjIC0gYXJ0aWZhY3QgaWQsIHYgLSBhcnRpZmFjdCB2ZXJzaW9uCgkgKiB0aGUgcmVzdWx0IGlzIHRoYW4sIGUuZy4KCSAqIDxwcmU+PGNvZGU+CgkgKiBbCgkgKiBbIEFLKHgsMi4wKSBBSyh4LDEuNSkgQUsoeCwxLjEpIF0KCSAqIFsgQUsoeSwyLjApIEFLKHksMS45KSBdCgkgKiBbIEFLKHosMi4wKSBBSyh6LDEuNSkgQUsoeiwxLjMpIEFLKHosMS4wKSBdCgkgKiBdCgkgKiA8L2NvZGU+PC9wcmU+ICAKCSAqIEBwYXJhbSBhcnRpZmFjdEtleXMKCSAqIEByZXR1cm4gdGhlIHNvcnRlZCBhcnRpZmFjdCBrZXlzCgkgKi8KCXByaXZhdGUgSUFydGlmYWN0S2V5W11bXSBnZXRTb3J0ZWRSZWxhdGVkQXJ0aWZhY3RLZXlzKElBcnRpZmFjdEtleVtdIGFydGlmYWN0S2V5cykgewoJCU1hcCBtYXAgPSBuZXcgSGFzaE1hcCgpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgYXJ0aWZhY3RLZXlzLmxlbmd0aDsgaSsrKSB7CgkJCUlBcnRpZmFjdEtleSBmcmVlS2V5ID0gZ2V0VmVyc2lvbmxlc3NLZXkoYXJ0aWZhY3RLZXlzW2ldKTsKCQkJTGlzdCB2YWx1ZXMgPSAoTGlzdCkgbWFwLmdldChmcmVlS2V5KTsKCQkJaWYgKHZhbHVlcyA9PSBudWxsKSB7CgkJCQl2YWx1ZXMgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCQltYXAucHV0KGZyZWVLZXksIHZhbHVlcyk7CgkJCX0KCQkJdmFsdWVzLmFkZChhcnRpZmFjdEtleXNbaV0pOwoJCX0KCQlJQXJ0aWZhY3RLZXlbXVtdIGxpc3RzID0gbmV3IElBcnRpZmFjdEtleVttYXAuc2l6ZSgpXVtdOwoJCWludCBpID0gMDsKCQlmb3IgKEl0ZXJhdG9yIGl0ZXJhdG9yID0gbWFwLnZhbHVlcygpLml0ZXJhdG9yKCk7IGl0ZXJhdG9yLmhhc05leHQoKTspIHsKCQkJTGlzdCBhcnRpZmFjdEtleUxpc3QgPSAoTGlzdCkgaXRlcmF0b3IubmV4dCgpOwoJCQlJQXJ0aWZhY3RLZXlbXSByZWxhdGVkQXJ0aWZhY3RLZXlzID0gKElBcnRpZmFjdEtleVtdKSBhcnRpZmFjdEtleUxpc3QudG9BcnJheShuZXcgSUFydGlmYWN0S2V5W2FydGlmYWN0S2V5TGlzdC5zaXplKCldKTsKCQkJQXJyYXlzLnNvcnQocmVsYXRlZEFydGlmYWN0S2V5cywgQVJUSUZBQ1RfS0VZX1ZFUlNJT05fQ09NUEFSQVRPUik7CgkJCWxpc3RzW2krK10gPSByZWxhdGVkQXJ0aWZhY3RLZXlzOwoJCX0KCQlpbnQgY2FuZGlkYXRlcyA9IDA7CgkJZm9yIChpbnQgaWkgPSAwOyBpaSA8IGxpc3RzLmxlbmd0aDsgaWkrKykgewoJCQlmb3IgKGludCBqaiA9IDA7IGpqIDwgbGlzdHNbaWldLmxlbmd0aDsgamorKykgewoJCQkJU3lzdGVtLm91dC5wcmludGxuKGxpc3RzW2lpXVtqal0gKyAiLCAiKTsKCQkJfQoJCQlTeXN0ZW0ub3V0LnByaW50bG4oIiIpOwoJCQlpZiAobGlzdHNbaWldLmxlbmd0aCA+IDEpCgkJCQljYW5kaWRhdGVzKys7CgkJfQoJCVN5c3RlbS5vdXQucHJpbnRsbigiQ2FuZGlkYXRlcyBmb3VuZDogIiArIGNhbmRpZGF0ZXMpOwoJCXJldHVybiBsaXN0czsKCX0KCglwcml2YXRlIHZvaWQgb3B0aW1pemUoSUFydGlmYWN0RGVzY3JpcHRvciBjYW5vbmljYWwsIElBcnRpZmFjdEtleVtdIHJlbGF0ZWRBcnRpZmFjdEtleXMpIHsKCQlTeXN0ZW0ub3V0LnByaW50bG4oIk9wdGltaXppbmcgIiArIGNhbm9uaWNhbCk7CgoJCUlBcnRpZmFjdERlc2NyaXB0b3JbXSBkZXNjcmlwdG9ycyA9IGdldFNvcnRlZENvbXBsZXRlUHJlZGVjZXNzb3JzKGNhbm9uaWNhbC5nZXRBcnRpZmFjdEtleSgpLCByZWxhdGVkQXJ0aWZhY3RLZXlzKTsKCgkJaW50IG1pbkRlcHRoID0gTWF0aC5taW4oZGVwdGgsIGRlc2NyaXB0b3JzLmxlbmd0aCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBtaW5EZXB0aDsgaSsrKSB7CgkJCVN5c3RlbS5vdXQucHJpbnRsbigiXHQgd2l0aCBqYXIgZGVsdGEgYWdhaW5zdCAiICsgZGVzY3JpcHRvcnNbaV0uZ2V0QXJ0aWZhY3RLZXkoKSk7CgkJCVN0cmluZyBwcmVkZWNlc3NvckRhdGEgPSBkZXNjcmlwdG9yc1tpXS5nZXRBcnRpZmFjdEtleSgpLnRvRXh0ZXJuYWxGb3JtKCk7CgkJCUFydGlmYWN0RGVzY3JpcHRvciBuZXdEZXNjcmlwdG9yID0gbmV3IEFydGlmYWN0RGVzY3JpcHRvcihjYW5vbmljYWwpOwoJCQlQcm9jZXNzaW5nU3RlcERlc2NyaXB0b3IgcGF0Y2hTdGVwID0gbmV3IFByb2Nlc3NpbmdTdGVwRGVzY3JpcHRvcihKQVJfREVMVEFfUEFUQ0hfU1RFUCwgcHJlZGVjZXNzb3JEYXRhLCB0cnVlKTsKCQkJUHJvY2Vzc2luZ1N0ZXBEZXNjcmlwdG9yW10gc3RlcHMgPSBuZXcgUHJvY2Vzc2luZ1N0ZXBEZXNjcmlwdG9yW10ge3BhdGNoU3RlcH07CgkJCW5ld0Rlc2NyaXB0b3Iuc2V0UHJvY2Vzc2luZ1N0ZXBzKHN0ZXBzKTsKCQkJbmV3RGVzY3JpcHRvci5zZXRQcm9wZXJ0eShJQXJ0aWZhY3REZXNjcmlwdG9yLkZPUk1BVCwgSkFSX0RFTFRBX0ZPUk1BVCk7CgkJCU91dHB1dFN0cmVhbSByZXBvc2l0b3J5U3RyZWFtID0gbnVsbDsKCQkJdHJ5IHsKCQkJCXJlcG9zaXRvcnlTdHJlYW0gPSByZXBvc2l0b3J5LmdldE91dHB1dFN0cmVhbShuZXdEZXNjcmlwdG9yKTsKCgkJCQkvLyBBZGQgaW4gYWxsIHRoZSBwcm9jZXNzaW5nIHN0ZXBzIG5lZWRlZCB0byBvcHRpbWl6ZSAoZS5nLiwgcGFjazIwMCwgLi4uKQoJCQkJUHJvY2Vzc2luZ1N0ZXAgb3B0aW1pemVyU3RlcCA9IG5ldyBKYXJEZWx0YU9wdGltaXplclN0ZXAocmVwb3NpdG9yeSk7CgkJCQlvcHRpbWl6ZXJTdGVwLmluaXRpYWxpemUocGF0Y2hTdGVwLCBuZXdEZXNjcmlwdG9yKTsKCQkJCVByb2Nlc3NpbmdTdGVwSGFuZGxlciBoYW5kbGVyID0gbmV3IFByb2Nlc3NpbmdTdGVwSGFuZGxlcigpOwoJCQkJT3V0cHV0U3RyZWFtIGRlc3RpbmF0aW9uID0gaGFuZGxlci5saW5rKG5ldyBQcm9jZXNzaW5nU3RlcFtdIHtvcHRpbWl6ZXJTdGVwfSwgcmVwb3NpdG9yeVN0cmVhbSwgbnVsbCk7CgoJCQkJLy8gRG8gdGhlIGFjdHVhbCB3b3JrIGJ5IGFza2luZyB0aGUgcmVwbyB0byBnZXQgdGhlIGFydGlmYWN0IGFuZCBwdXQgaXQgaW4gdGhlIGRlc3RpbmF0aW9uLgoJCQkJSVN0YXR1cyBzdGF0dXMgPSByZXBvc2l0b3J5LmdldEFydGlmYWN0KGNhbm9uaWNhbCwgZGVzdGluYXRpb24sIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwoJCQkJaWYgKCFzdGF0dXMuaXNPSygpKSB7CgkJCQkJU3lzdGVtLm91dC5wcmludGxuKCJHZXR0aW5nIHRoZSBhcnRpZmFjdCBpcyBub3Qgb2suIik7IC8vJE5PTi1OTFMtMSQKCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oc3RhdHVzKTsKCQkJCX0KCQkJfSBjYXRjaCAoUHJvdmlzaW9uRXhjZXB0aW9uIGUpIHsKCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiU2tpcHBpbmcgb3B0aW1pemF0aW9uIG9mOiAiICsgZGVzY3JpcHRvcnNbaV0uZ2V0QXJ0aWZhY3RLZXkoKSk7IC8vJE5PTi1OTFMtMSQKCQkJCVN5c3RlbS5vdXQucHJpbnRsbihlLmdldE1lc3NhZ2UoKSk7CgkJCQllLnByaW50U3RhY2tUcmFjZSgpOwoJCQl9IGZpbmFsbHkgewoJCQkJaWYgKHJlcG9zaXRvcnlTdHJlYW0gIT0gbnVsbCkKCQkJCQl0cnkgewoJCQkJCQlyZXBvc2l0b3J5U3RyZWFtLmNsb3NlKCk7CgkJCQkJCUlTdGF0dXMgc3RhdHVzID0gUHJvY2Vzc2luZ1N0ZXBIYW5kbGVyLmNoZWNrU3RhdHVzKHJlcG9zaXRvcnlTdHJlYW0pOwoJCQkJCQlpZiAoIXN0YXR1cy5pc09LKCkpIHsKCQkJCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiU2tpcHBpbmcgb3B0aW1pemF0aW9uIG9mOiAiICsgZGVzY3JpcHRvcnNbaV0uZ2V0QXJ0aWZhY3RLZXkoKSk7IC8vJE5PTi1OTFMtMSQKCQkJCQkJCVN5c3RlbS5vdXQucHJpbnRsbihzdGF0dXMudG9TdHJpbmcoKSk7CgkJCQkJCX0KCQkJCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CgkJCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiU2tpcHBpbmcgb3B0aW1pemF0aW9uIG9mOiAiICsgZGVzY3JpcHRvcnNbaV0uZ2V0QXJ0aWZhY3RLZXkoKSk7IC8vJE5PTi1OTFMtMSQKCQkJCQkJU3lzdGVtLm91dC5wcmludGxuKGUuZ2V0TWVzc2FnZSgpKTsKCQkJCQkJZS5wcmludFN0YWNrVHJhY2UoKTsKCQkJCQl9CgkJCX0KCQl9Cgl9CgoJcHJpdmF0ZSBJQXJ0aWZhY3REZXNjcmlwdG9yW10gZ2V0U29ydGVkQ29tcGxldGVQcmVkZWNlc3NvcnMoSUFydGlmYWN0S2V5IGFydGlmYWN0S2V5LCBJQXJ0aWZhY3RLZXlbXSByZWxhdGVkQXJ0aWZhY3RLZXlzKSB7CgkJLy8gZ2V0IGFsbCBhcnRpZmFjdCBrZXlzCgkJTGlzdCBjb21wbGV0ZURlc2NyaXB0b3JzID0gbmV3IEFycmF5TGlzdChyZWxhdGVkQXJ0aWZhY3RLZXlzLmxlbmd0aCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCByZWxhdGVkQXJ0aWZhY3RLZXlzLmxlbmd0aDsgaSsrKSB7CgkJCS8vIGlmIHdlIGZpbmQgtG91ciBzZWxmtCBza2lwCgkJCWlmIChyZWxhdGVkQXJ0aWZhY3RLZXlzW2ldLmVxdWFscyhhcnRpZmFjdEtleSkpCgkJCQljb250aW51ZTsKCQkJLy8gbG9vayBmb3IgYSBjb21wbGV0ZSBhcnRpZmFjdCBkZXNjcmlwdG9yIG9mIHRoZSBjdXJyZW50IGtleSAgCgkJCUlBcnRpZmFjdERlc2NyaXB0b3JbXSBkZXNjcmlwdG9ycyA9IHJlcG9zaXRvcnkuZ2V0QXJ0aWZhY3REZXNjcmlwdG9ycyhyZWxhdGVkQXJ0aWZhY3RLZXlzW2ldKTsKCQkJZm9yIChpbnQgaiA9IDA7IGogPCBkZXNjcmlwdG9ycy5sZW5ndGg7IGorKykgewoJCQkJaWYgKGlzQ2Fub25pY2FsKGRlc2NyaXB0b3JzW2pdKSkgewoJCQkJCWNvbXBsZXRlRGVzY3JpcHRvcnMuYWRkKGRlc2NyaXB0b3JzW2pdKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCgkJSUFydGlmYWN0RGVzY3JpcHRvcltdIGNvbXBsZXRlU29ydGVkRGVzY3JpcHRvcnMgPSAoSUFydGlmYWN0RGVzY3JpcHRvcltdKSBjb21wbGV0ZURlc2NyaXB0b3JzLnRvQXJyYXkobmV3IElBcnRpZmFjdERlc2NyaXB0b3JbY29tcGxldGVEZXNjcmlwdG9ycy5zaXplKCldKTsKCQkvLyBTb3J0LCBzbyB0byBhbGxvdyBhIGRlcHRoIGxvb2t1cCEKCQlBcnJheXMuc29ydChjb21wbGV0ZVNvcnRlZERlc2NyaXB0b3JzLCBBUlRJRkFDVF9ERVNDUklQVE9SX1ZFUlNJT05fQ09NUEFSQVRPUik7CgkJcmV0dXJuIGNvbXBsZXRlU29ydGVkRGVzY3JpcHRvcnM7Cgl9CgoJcHJpdmF0ZSBib29sZWFuIGlzT3B0aW1pemVkKElBcnRpZmFjdERlc2NyaXB0b3IgZGVzY3JpcHRvcikgewoJCWlmIChkZXNjcmlwdG9yLmdldFByb2Nlc3NpbmdTdGVwcygpLmxlbmd0aCAhPSAxKQoJCQlyZXR1cm4gZmFsc2U7CgkJcmV0dXJuIEpBUl9ERUxUQV9GT1JNQVQuZXF1YWxzKGRlc2NyaXB0b3IuZ2V0UHJvcGVydHkoSUFydGlmYWN0RGVzY3JpcHRvci5GT1JNQVQpKTsKCX0KCglwcml2YXRlIGJvb2xlYW4gaXNDYW5vbmljYWwoSUFydGlmYWN0RGVzY3JpcHRvciBkZXNjcmlwdG9yKSB7CgkJLy8gVE9ETyBsZW5ndGggIT0gMCBpcyBub3QgbmVjZXNzYXJpbHkgYW4gaW5kaWNhdG9yIGZvciBub3QgYmVpbmcgY2Fub25pY2FsISAgIAoJCXJldHVybiBkZXNjcmlwdG9yLmdldFByb2Nlc3NpbmdTdGVwcygpLmxlbmd0aCA9PSAwOwoJfQoKCXN0YXRpYyBmaW5hbCBjbGFzcyBBcnRpZmFjdERlc2NyaXB0b3JWZXJzaW9uQ29tcGFyYXRvciBpbXBsZW1lbnRzIENvbXBhcmF0b3IgewoJCXB1YmxpYyBpbnQgY29tcGFyZShPYmplY3QgYXJ0aWZhY3REZXNjcmlwdG9yMCwgT2JqZWN0IGFydGlmYWN0RGVzY3JpcHRvcjEpIHsKCQkJcmV0dXJuIC0xICogKChJQXJ0aWZhY3REZXNjcmlwdG9yKSBhcnRpZmFjdERlc2NyaXB0b3IwKS5nZXRBcnRpZmFjdEtleSgpLmdldFZlcnNpb24oKS5jb21wYXJlVG8oKChJQXJ0aWZhY3REZXNjcmlwdG9yKSBhcnRpZmFjdERlc2NyaXB0b3IxKS5nZXRBcnRpZmFjdEtleSgpLmdldFZlcnNpb24oKSk7CgkJfQoJfQoKCXN0YXRpYyBmaW5hbCBjbGFzcyBBcnRpZmFjdEtleVZlcnNpb25Db21wYXJhdG9yIGltcGxlbWVudHMgQ29tcGFyYXRvciB7CgkJcHVibGljIGludCBjb21wYXJlKE9iamVjdCBhcnRpZmFjdEtleTAsIE9iamVjdCBhcnRpZmFjdEtleTEpIHsKCQkJcmV0dXJuIC0xICogKChJQXJ0aWZhY3RLZXkpIGFydGlmYWN0S2V5MCkuZ2V0VmVyc2lvbigpLmNvbXBhcmVUbygoKElBcnRpZmFjdEtleSkgYXJ0aWZhY3RLZXkxKS5nZXRWZXJzaW9uKCkpOwoJCX0KCX0KfQo=