LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbDsKCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLnV0aWwuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5Db3JlRXhjZXB0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQYXRoOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklNb2R1bGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuU2VydmVyVXRpbDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC4qOwovKioKICogSGVscGVyIHRvIG9idGFpbiBhbmQgc3RvcmUgdGhlIHB1Ymxpc2hpbmcgaW5mb3JtYXRpb24gKHdoYXQgZmlsZXMKICogd2VyZSBwdWJsaXNoZWQgYW5kIHdoZW4pIGZvciBhIHNpbmdsZSBzZXJ2ZXIuCiAqLwpwdWJsaWMgY2xhc3MgU2VydmVyUHVibGlzaEluZm8gewoJcHJvdGVjdGVkIElQYXRoIHBhdGg7CgoJLy8gbWFwIG9mIG1vZHVsZSBpZHMgdG8gTW9kdWxlUHVibGlzaEluZm8KCXByb3RlY3RlZCBNYXAgbW9kdWxlUHVibGlzaEluZm87CgoJLyoqCgkgKiBTZXJ2ZXJQdWJsaXNoSW5mbyBjb25zdHJ1Y3RvciBjb21tZW50LgoJICovCglwcm90ZWN0ZWQgU2VydmVyUHVibGlzaEluZm8oSVBhdGggcGF0aCkgewoJCXN1cGVyKCk7CgkJCgkJdGhpcy5wYXRoID0gcGF0aDsKCQltb2R1bGVQdWJsaXNoSW5mbyA9IG5ldyBIYXNoTWFwKCk7CgkJbG9hZCgpOwoJfQoKCXByaXZhdGUgU3RyaW5nIGdldEtleShJTW9kdWxlW10gbW9kdWxlKSB7CgkJU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoJCQoJCWlmIChtb2R1bGUgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IG1vZHVsZS5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlpZiAoaSAhPSAwKQoJCQkJCXNiLmFwcGVuZCgiIyIpOwoJCQkJc2IuYXBwZW5kKG1vZHVsZVtpXS5nZXRJZCgpKTsKCQkJfQoJCX0KCQkKCQlyZXR1cm4gc2IudG9TdHJpbmcoKTsKCX0KCglwcml2YXRlIFN0cmluZyBnZXRLZXkoU3RyaW5nIG1vZHVsZUlkKSB7CgkJcmV0dXJuIG1vZHVsZUlkOwoJfQoJCglwcml2YXRlIElNb2R1bGVbXSBnZXRNb2R1bGUoU3RyaW5nIG1vZHVsZUlkKSB7CgkJaWYgKG1vZHVsZUlkID09IG51bGwgfHwgbW9kdWxlSWQubGVuZ3RoKCkgPT0gMCkKCQkJcmV0dXJuIG5ldyBJTW9kdWxlWzBdOwoJCQoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQlTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKG1vZHVsZUlkLCAiIyIpOwoJCXdoaWxlIChzdC5oYXNNb3JlVG9rZW5zKCkpIHsKCQkJU3RyaW5nIG1pZCA9IHN0Lm5leHRUb2tlbigpOwoJCQlpZiAobWlkICE9IG51bGwgJiYgbWlkLmxlbmd0aCgpID4gMCkgewoJCQkJSU1vZHVsZSBtID0gU2VydmVyVXRpbC5nZXRNb2R1bGUobWlkKTsKCQkJCWlmIChtID09IG51bGwpCgkJCQkJcmV0dXJuIG51bGw7CgkJCQlsaXN0LmFkZChtKTsKCQkJfQoJCX0KCQkKCQlJTW9kdWxlW10gbW9kdWxlcyA9IG5ldyBJTW9kdWxlW2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkobW9kdWxlcyk7CgkJcmV0dXJuIG1vZHVsZXM7Cgl9CgoJcHVibGljIGJvb2xlYW4gaGFzTW9kdWxlUHVibGlzaEluZm8oSU1vZHVsZVtdIG1vZHVsZSkgewoJCVN0cmluZyBrZXkgPSBnZXRLZXkobW9kdWxlKTsKCQlyZXR1cm4gbW9kdWxlUHVibGlzaEluZm8uY29udGFpbnNLZXkoa2V5KTsKCX0KCglwdWJsaWMgdm9pZCByZW1vdmVNb2R1bGVQdWJsaXNoSW5mbyhJTW9kdWxlW10gbW9kdWxlKSB7CgkJU3RyaW5nIGtleSA9IGdldEtleShtb2R1bGUpOwoJCW1vZHVsZVB1Ymxpc2hJbmZvLnJlbW92ZShrZXkpOwoJCQoJCXNhdmUoKTsKCX0KCgkvKioKCSAqIFJldHVybiB0aGUgcHVibGlzaCBzdGF0ZS4KCSAqLwoJcHJvdGVjdGVkIE1vZHVsZVB1Ymxpc2hJbmZvIGdldE1vZHVsZVB1Ymxpc2hJbmZvKElNb2R1bGVbXSBtb2R1bGUpIHsKCQlTdHJpbmcga2V5ID0gZ2V0S2V5KG1vZHVsZSk7CgoJCS8vIGNoZWNrIGlmIGl0IG5vdyBleGlzdHMKCQlpZiAobW9kdWxlUHVibGlzaEluZm8uY29udGFpbnNLZXkoa2V5KSkKCQkJcmV0dXJuIChNb2R1bGVQdWJsaXNoSW5mbykgbW9kdWxlUHVibGlzaEluZm8uZ2V0KGtleSk7CgkKCQkvLyBoYXZlIHRvIGNyZWF0ZSBhIG5ldyBvbmUKCQlNb2R1bGVQdWJsaXNoSW5mbyBtcGkgPSBuZXcgTW9kdWxlUHVibGlzaEluZm8oZ2V0S2V5KG1vZHVsZSksIG1vZHVsZVttb2R1bGUubGVuZ3RoIC0gMV0uZ2V0TmFtZSgpKTsKCQltb2R1bGVQdWJsaXNoSW5mby5wdXQoa2V5LCBtcGkpOwoJCXJldHVybiBtcGk7Cgl9CgoJcHVibGljIHZvaWQgYWRkUmVtb3ZlZE1vZHVsZXMoTGlzdCBtb2R1bGVMaXN0LCBMaXN0IGtpbmRMaXN0KSB7CgkJaW50IHNpemUgPSBtb2R1bGVMaXN0LnNpemUoKTsKCQlMaXN0IHJlbW92ZWQgPSBuZXcgQXJyYXlMaXN0KCk7CgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBtb2R1bGVQdWJsaXNoSW5mby5rZXlTZXQoKS5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJU3RyaW5nIGtleSA9IChTdHJpbmcpIGl0ZXJhdG9yLm5leHQoKTsKCQkKCQkJYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJSU1vZHVsZVtdIG1vZHVsZSA9IChJTW9kdWxlW10pIG1vZHVsZUxpc3QuZ2V0KGkpOwoJCQkJU3RyaW5nIGtleTIgPSBnZXRLZXkobW9kdWxlKTsKCQkJCWlmIChrZXkgIT0gbnVsbCAmJiBrZXkuZXF1YWxzKGtleTIpKQoJCQkJCWZvdW5kID0gdHJ1ZTsKCQkJfQoJCQlpZiAoIWZvdW5kKSB7CgkJCQlNb2R1bGVQdWJsaXNoSW5mbyBtcGkgPSAoTW9kdWxlUHVibGlzaEluZm8pIG1vZHVsZVB1Ymxpc2hJbmZvLmdldChrZXkpOwoJCQkJcmVtb3ZlZC5hZGQobXBpKTsKCQkJfQoJCX0KCQkKCQlpdGVyYXRvciA9IHJlbW92ZWQuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCU1vZHVsZVB1Ymxpc2hJbmZvIG1waSA9IChNb2R1bGVQdWJsaXNoSW5mbykgaXRlcmF0b3IubmV4dCgpOwoJCQlJTW9kdWxlW10gbW9kdWxlMiA9IGdldE1vZHVsZShtcGkuZ2V0TW9kdWxlSWQoKSk7CgkJCWlmIChtb2R1bGUyID09IG51bGwgfHwgbW9kdWxlMi5sZW5ndGggPT0gMCkgewoJCQkJU3RyaW5nIG1vZHVsZUlkID0gbXBpLmdldE1vZHVsZUlkKCk7CgkJCQlpZiAobW9kdWxlSWQgIT0gbnVsbCkgewoJCQkJCWludCBpbmRleCA9IG1vZHVsZUlkLmxhc3RJbmRleE9mKCIjIik7CgkJCQkJbW9kdWxlMiA9IG5ldyBJTW9kdWxlW10geyBuZXcgRGVsZXRlZE1vZHVsZShtb2R1bGVJZC5zdWJzdHJpbmcoaW5kZXggKyAxKSwgbXBpLmdldE5hbWUoKSkgfTsKCQkJCX0KCQkJfQoJCQlpZiAobW9kdWxlMiAhPSBudWxsICYmIG1vZHVsZTIubGVuZ3RoID4gMCkgewoJCQkJbW9kdWxlTGlzdC5hZGQobW9kdWxlMik7CgkJCQlraW5kTGlzdC5hZGQobmV3IEludGVnZXIoU2VydmVyQmVoYXZpb3VyRGVsZWdhdGUuUkVNT1ZFRCkpOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogCgkgKi8KCXB1YmxpYyB2b2lkIGxvYWQoKSB7CgkJU3RyaW5nIGZpbGVuYW1lID0gcGF0aC50b09TU3RyaW5nKCk7CgkJaWYgKCEobmV3IEZpbGUoZmlsZW5hbWUpLmV4aXN0cygpKSkKCQkJcmV0dXJuOwoJCgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiTG9hZGluZyBwdWJsaXNoIGluZm8gZnJvbSAiICsgZmlsZW5hbWUpOwoKCQl0cnkgewoJCQlJTWVtZW50byBtZW1lbnRvMiA9IFhNTE1lbWVudG8ubG9hZE1lbWVudG8oZmlsZW5hbWUpOwoJCQlJTWVtZW50b1tdIGNoaWxkcmVuID0gbWVtZW50bzIuZ2V0Q2hpbGRyZW4oIm1vZHVsZSIpOwoJCgkJCWludCBzaXplID0gY2hpbGRyZW4ubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJTW9kdWxlUHVibGlzaEluZm8gbXBpID0gbmV3IE1vZHVsZVB1Ymxpc2hJbmZvKGNoaWxkcmVuW2ldKTsKCQkJCW1vZHVsZVB1Ymxpc2hJbmZvLnB1dChnZXRLZXkobXBpLmdldE1vZHVsZUlkKCkpLCBtcGkpOwoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkNvdWxkIG5vdCBsb2FkIHB1Ymxpc2ggaW5mb3JtYXRpb246ICIgKyBlLmdldE1lc3NhZ2UoKSk7CgkJfQoJfQoKCS8qKgoJICogCgkgKi8KCXB1YmxpYyB2b2lkIHNhdmUoKSB7CgkJU3RyaW5nIGZpbGVuYW1lID0gcGF0aC50b09TU3RyaW5nKCk7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiU2F2aW5nIHB1Ymxpc2ggaW5mbyB0byAiICsgZmlsZW5hbWUpOwoJCgkJdHJ5IHsKCQkJWE1MTWVtZW50byBtZW1lbnRvID0gWE1MTWVtZW50by5jcmVhdGVXcml0ZVJvb3QoInNlcnZlciIpOwoKCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBtb2R1bGVQdWJsaXNoSW5mby5rZXlTZXQoKS5pdGVyYXRvcigpOwoJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQlTdHJpbmcgY29udHJvbFJlZiA9IChTdHJpbmcpIGl0ZXJhdG9yLm5leHQoKTsKCQkJCU1vZHVsZVB1Ymxpc2hJbmZvIG1waSA9IChNb2R1bGVQdWJsaXNoSW5mbykgbW9kdWxlUHVibGlzaEluZm8uZ2V0KGNvbnRyb2xSZWYpOwoJCQkJSU1lbWVudG8gY2hpbGQgPSBtZW1lbnRvLmNyZWF0ZUNoaWxkKCJtb2R1bGUiKTsKCQkJCW1waS5zYXZlKGNoaWxkKTsKCQkJfQoJCQltZW1lbnRvLnNhdmVUb0ZpbGUoZmlsZW5hbWUpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNvdWxkIG5vdCBzYXZlIHB1Ymxpc2ggaW5mb3JtYXRpb24iLCBlKTsKCQl9Cgl9CgkKCXB1YmxpYyB2b2lkIGZpbGwoSU1vZHVsZVtdIG1vZHVsZSkgewoJCU1vZHVsZVB1Ymxpc2hJbmZvIG1waSA9IGdldE1vZHVsZVB1Ymxpc2hJbmZvKG1vZHVsZSk7CgkJaW50IHNpemUgPSBtb2R1bGUubGVuZ3RoOwoJCU1vZHVsZURlbGVnYXRlIHBtID0gKE1vZHVsZURlbGVnYXRlKSBtb2R1bGVbc2l6ZSAtIDFdLmxvYWRBZGFwdGVyKE1vZHVsZURlbGVnYXRlLmNsYXNzLCBudWxsKTsKCQl0cnkgewoJCQlpZiAocG0gIT0gbnVsbCkKCQkJCW1waS5zZXRSZXNvdXJjZXMocG0ubWVtYmVycygpKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCS8vIGlnbm9yZQoJCX0KCQlzYXZlKCk7Cgl9CgoJcHJvdGVjdGVkIElNb2R1bGVSZXNvdXJjZURlbHRhW10gZ2V0RGVsdGEoSU1vZHVsZVtdIG1vZHVsZSkgewoJCWlmIChtb2R1bGUgPT0gbnVsbCkKCQkJcmV0dXJuIG5ldyBJTW9kdWxlUmVzb3VyY2VEZWx0YVswXTsKCQkKCQlNb2R1bGVQdWJsaXNoSW5mbyBtcGkgPSBnZXRNb2R1bGVQdWJsaXNoSW5mbyhtb2R1bGUpOwoJCWludCBzaXplID0gbW9kdWxlLmxlbmd0aDsKCQlNb2R1bGVEZWxlZ2F0ZSBwbSA9IChNb2R1bGVEZWxlZ2F0ZSkgbW9kdWxlW3NpemUgLSAxXS5sb2FkQWRhcHRlcihNb2R1bGVEZWxlZ2F0ZS5jbGFzcywgbnVsbCk7CgkJSU1vZHVsZVJlc291cmNlW10gcmVzb3VyY2VzID0gbnVsbDsKCQl0cnkgewoJCQlpZiAocG0gIT0gbnVsbCkKCQkJCXJlc291cmNlcyA9IHBtLm1lbWJlcnMoKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCS8vIGlnbm9yZQoJCX0KCQlpZiAocmVzb3VyY2VzID09IG51bGwpCgkJCXJlc291cmNlcyA9IG5ldyBJTW9kdWxlUmVzb3VyY2VbMF07CgkJcmV0dXJuIGdldERlbHRhKG1waS5nZXRSZXNvdXJjZXMoKSwgcmVzb3VyY2VzKTsKCX0KCglwcm90ZWN0ZWQgSU1vZHVsZVJlc291cmNlRGVsdGFbXSBnZXREZWx0YShJTW9kdWxlUmVzb3VyY2VbXSBvcmlnaW5hbCwgSU1vZHVsZVJlc291cmNlW10gY3VycmVudCkgewoJCWlmIChvcmlnaW5hbCA9PSBudWxsIHx8IGN1cnJlbnQgPT0gbnVsbCkKCQkJcmV0dXJuIG5ldyBJTW9kdWxlUmVzb3VyY2VEZWx0YVswXTsKCQoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQkKCQkvLyBsb29rIGZvciBkdXBsaWNhdGVzCgkJTGlzdCBmb3VuZCA9IG5ldyBBcnJheUxpc3QoKTsKCQlpbnQgc2l6ZSA9IG9yaWdpbmFsLmxlbmd0aDsKCQlpbnQgc2l6ZTIgPSBjdXJyZW50Lmxlbmd0aDsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQlmb3IgKGludCBqID0gMDsgaiA8IHNpemUyOyBqKyspIHsKCQkJCWlmICghZm91bmQuY29udGFpbnMob3JpZ2luYWxbaV0pICYmICFmb3VuZC5jb250YWlucyhjdXJyZW50W2pdKSAmJiBvcmlnaW5hbFtpXS5lcXVhbHMoY3VycmVudFtqXSkpIHsKCQkJCQkvLyBmb3VuZCBhIG1hdGNoCgkJCQkJZm91bmQuYWRkKG9yaWdpbmFsW2ldKTsKCQkJCQlpZiAob3JpZ2luYWxbaV0gaW5zdGFuY2VvZiBJTW9kdWxlRmlsZSkgewoJCQkJCQkvLyBpbmNsdWRlIGZpbGVzIG9ubHkgaWYgdGhlIG1vZGlmaWNhdGlvbiBzdGFtcCBoYXMgY2hhbmdlZAoJCQkJCQlJTW9kdWxlRmlsZSBtZjEgPSAoSU1vZHVsZUZpbGUpIG9yaWdpbmFsW2ldOwoJCQkJCQlJTW9kdWxlRmlsZSBtZjIgPSAoSU1vZHVsZUZpbGUpIGN1cnJlbnRbal07CgkJCQkJCWlmIChtZjEuZ2V0TW9kaWZpY2F0aW9uU3RhbXAoKSAhPSBtZjIuZ2V0TW9kaWZpY2F0aW9uU3RhbXAoKSkgewoJCQkJCQkJbGlzdC5hZGQobmV3IE1vZHVsZVJlc291cmNlRGVsdGEob3JpZ2luYWxbaV0sIElNb2R1bGVSZXNvdXJjZURlbHRhLkNIQU5HRUQpKTsKCQkJCQkJfQoJCQkJCX0gZWxzZSB7CgkJCQkJCS8vIGluY2x1ZGUgZm9sZGVycyBvbmx5IGlmIHRoZWlyIGNvbnRlbnRzIGhhdmUgY2hhbmdlZAoJCQkJCQlJTW9kdWxlRm9sZGVyIG1mMSA9IChJTW9kdWxlRm9sZGVyKSBvcmlnaW5hbFtpXTsKCQkJCQkJSU1vZHVsZUZvbGRlciBtZjIgPSAoSU1vZHVsZUZvbGRlcikgY3VycmVudFtqXTsKCQkJCQkJSU1vZHVsZVJlc291cmNlRGVsdGFbXSBtcmRjID0gZ2V0RGVsdGEobWYxLm1lbWJlcnMoKSwgbWYyLm1lbWJlcnMoKSk7CgkJCQkJCWlmIChtcmRjLmxlbmd0aCA+IDApIHsKCQkJCQkJCU1vZHVsZVJlc291cmNlRGVsdGEgbXJkID0gbmV3IE1vZHVsZVJlc291cmNlRGVsdGEob3JpZ2luYWxbaV0sIElNb2R1bGVSZXNvdXJjZURlbHRhLk5PX0NIQU5HRSk7CgkJCQkJCQltcmQuc2V0Q2hpbGRyZW4obXJkYyk7CgkJCQkJCQlsaXN0LmFkZChtcmQpOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJCQoJCS8vIGFkZCBkZWxldGlvbnMgKHVuZm91bmQgaXRlbXMgaW4gdGhlIG9yaWdpbmFsIGxpc3QpCgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJaWYgKCFmb3VuZC5jb250YWlucyhvcmlnaW5hbFtpXSkpIHsKCQkJCWlmIChvcmlnaW5hbFtpXSBpbnN0YW5jZW9mIElNb2R1bGVGaWxlKSB7CgkJCQkJbGlzdC5hZGQobmV3IE1vZHVsZVJlc291cmNlRGVsdGEob3JpZ2luYWxbaV0sIElNb2R1bGVSZXNvdXJjZURlbHRhLlJFTU9WRUQpKTsKCQkJCX0gZWxzZSB7CgkJCQkJSU1vZHVsZUZvbGRlciBtZiA9IChJTW9kdWxlRm9sZGVyKSBvcmlnaW5hbFtpXTsKCQkJCQlNb2R1bGVSZXNvdXJjZURlbHRhIG1yZCA9IG5ldyBNb2R1bGVSZXNvdXJjZURlbHRhKG9yaWdpbmFsW2ldLCBJTW9kdWxlUmVzb3VyY2VEZWx0YS5SRU1PVkVEKTsKCQkJCQlJTW9kdWxlUmVzb3VyY2VEZWx0YVtdIG1yZGMgPSBnZXREZWx0YVRyZWUobWYubWVtYmVycygpLCBJTW9kdWxlUmVzb3VyY2VEZWx0YS5SRU1PVkVEKTsKCQkJCQltcmQuc2V0Q2hpbGRyZW4obXJkYyk7CgkJCQkJbGlzdC5hZGQobXJkKTsKCQkJCX0KCQkJfQoJCX0KCQkKCQkvLwlhZGQgYWRkaXRpb25zICh1bmZvdW5kIGl0ZW1zIGluIHRoZSBjdXJyZW50IGxpc3QpCgkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCWlmICghZm91bmQuY29udGFpbnMoY3VycmVudFtqXSkpIHsKCQkJCWlmIChjdXJyZW50W2pdIGluc3RhbmNlb2YgSU1vZHVsZUZpbGUpIHsKCQkJCQlsaXN0LmFkZChuZXcgTW9kdWxlUmVzb3VyY2VEZWx0YShjdXJyZW50W2pdLCBJTW9kdWxlUmVzb3VyY2VEZWx0YS5BRERFRCkpOwoJCQkJfSBlbHNlIHsKCQkJCQlJTW9kdWxlRm9sZGVyIG1mID0gKElNb2R1bGVGb2xkZXIpIGN1cnJlbnRbal07CgkJCQkJTW9kdWxlUmVzb3VyY2VEZWx0YSBtcmQgPSBuZXcgTW9kdWxlUmVzb3VyY2VEZWx0YShjdXJyZW50W2pdLCBJTW9kdWxlUmVzb3VyY2VEZWx0YS5BRERFRCk7CgkJCQkJSU1vZHVsZVJlc291cmNlRGVsdGFbXSBtcmRjID0gZ2V0RGVsdGFUcmVlKG1mLm1lbWJlcnMoKSwgSU1vZHVsZVJlc291cmNlRGVsdGEuQURERUQpOwoJCQkJCW1yZC5zZXRDaGlsZHJlbihtcmRjKTsKCQkJCQlsaXN0LmFkZChtcmQpOwoJCQkJfQoJCQl9CgkJfQoJCQoJCUlNb2R1bGVSZXNvdXJjZURlbHRhW10gZGVsdGEgPSBuZXcgSU1vZHVsZVJlc291cmNlRGVsdGFbbGlzdC5zaXplKCldOwoJCWxpc3QudG9BcnJheShkZWx0YSk7CgkJcmV0dXJuIGRlbHRhOwoJfQoKCS8qKgoJICogQ3JlYXRlIGEgcmVzb3VyY2UgZGVsdGEgZm9yIGFuIGVudGlyZSB0cmVlLgoJICovCglwcm90ZWN0ZWQgSU1vZHVsZVJlc291cmNlRGVsdGFbXSBnZXREZWx0YVRyZWUoSU1vZHVsZVJlc291cmNlW10gcmVzb3VyY2VzLCBpbnQga2luZCkgewoJCWlmIChyZXNvdXJjZXMgPT0gbnVsbCkKCQkJcmV0dXJuIG5ldyBJTW9kdWxlUmVzb3VyY2VEZWx0YVswXTsKCQoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQkKCQkvLyBsb29rIGZvciBkdXBsaWNhdGVzCgkJaW50IHNpemUgPSByZXNvdXJjZXMubGVuZ3RoOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCU1vZHVsZVJlc291cmNlRGVsdGEgbXJkID0gbmV3IE1vZHVsZVJlc291cmNlRGVsdGEocmVzb3VyY2VzW2ldLCBraW5kKTsKCQkJaWYgKHJlc291cmNlc1tpXSBpbnN0YW5jZW9mIElNb2R1bGVGb2xkZXIpIHsKCQkJCUlNb2R1bGVGb2xkZXIgbWYgPSAoSU1vZHVsZUZvbGRlcikgcmVzb3VyY2VzW2ldOwoJCQkJbXJkLnNldENoaWxkcmVuKGdldERlbHRhVHJlZShtZi5tZW1iZXJzKCksIGtpbmQpKTsKCQkJfQoJCQlsaXN0LmFkZChtcmQpOwoJCX0KCQkKCQlJTW9kdWxlUmVzb3VyY2VEZWx0YVtdIGRlbHRhID0gbmV3IElNb2R1bGVSZXNvdXJjZURlbHRhW2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkoZGVsdGEpOwoJCXJldHVybiBkZWx0YTsKCX0KfQ==