LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbDsKCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLnV0aWwuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5Db3JlRXhjZXB0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQYXRoOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklNb2R1bGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuU2VydmVyVXRpbDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC4qOwovKioKICogSGVscGVyIHRvIG9idGFpbiBhbmQgc3RvcmUgdGhlIHB1Ymxpc2hpbmcgaW5mb3JtYXRpb24gKHdoYXQgZmlsZXMKICogd2VyZSBwdWJsaXNoZWQgYW5kIHdoZW4pIGZvciBhIHNpbmdsZSBzZXJ2ZXIuCiAqLwpwdWJsaWMgY2xhc3MgU2VydmVyUHVibGlzaEluZm8gewoJcHJvdGVjdGVkIElQYXRoIHBhdGg7CgoJLy8gbWFwIG9mIG1vZHVsZSBpZHMgdG8gTW9kdWxlUHVibGlzaEluZm8KCXByb3RlY3RlZCBNYXAgbW9kdWxlUHVibGlzaEluZm87CgoJLyoqCgkgKiBTZXJ2ZXJQdWJsaXNoSW5mbyBjb25zdHJ1Y3RvciBjb21tZW50LgoJICovCglwcm90ZWN0ZWQgU2VydmVyUHVibGlzaEluZm8oSVBhdGggcGF0aCkgewoJCXN1cGVyKCk7CgkJCgkJdGhpcy5wYXRoID0gcGF0aDsKCQltb2R1bGVQdWJsaXNoSW5mbyA9IG5ldyBIYXNoTWFwKCk7CgkJbG9hZCgpOwoJfQoKCXByaXZhdGUgU3RyaW5nIGdldEtleShJTW9kdWxlW10gbW9kdWxlKSB7CgkJU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoJCQoJCWlmIChtb2R1bGUgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IG1vZHVsZS5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlpZiAoaSAhPSAwKQoJCQkJCXNiLmFwcGVuZCgiIyIpOwoJCQkJc2IuYXBwZW5kKG1vZHVsZVtpXS5nZXRJZCgpKTsKCQkJfQoJCX0KCQkKCQlyZXR1cm4gc2IudG9TdHJpbmcoKTsKCX0KCglwcml2YXRlIFN0cmluZyBnZXRLZXkoU3RyaW5nIG1vZHVsZUlkKSB7CgkJcmV0dXJuIG1vZHVsZUlkOwoJfQoJCglwcml2YXRlIElNb2R1bGVbXSBnZXRNb2R1bGUoU3RyaW5nIG1vZHVsZUlkKSB7CgkJaWYgKG1vZHVsZUlkID09IG51bGwgfHwgbW9kdWxlSWQubGVuZ3RoKCkgPT0gMCkKCQkJcmV0dXJuIG5ldyBJTW9kdWxlWzBdOwoJCQoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQlTdHJpbmdUb2tlbml6ZXIgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKG1vZHVsZUlkLCAiIyIpOwoJCXdoaWxlIChzdC5oYXNNb3JlVG9rZW5zKCkpIHsKCQkJU3RyaW5nIG1pZCA9IHN0Lm5leHRUb2tlbigpOwoJCQlpZiAobWlkICE9IG51bGwgJiYgbWlkLmxlbmd0aCgpID4gMCkgewoJCQkJSU1vZHVsZSBtID0gU2VydmVyVXRpbC5nZXRNb2R1bGUobWlkKTsKCQkJCWlmIChtID09IG51bGwpCgkJCQkJcmV0dXJuIG51bGw7CgkJCQlsaXN0LmFkZChtKTsKCQkJfQoJCX0KCQkKCQlJTW9kdWxlW10gbW9kdWxlcyA9IG5ldyBJTW9kdWxlW2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkobW9kdWxlcyk7CgkJcmV0dXJuIG1vZHVsZXM7Cgl9CgoJcHVibGljIGJvb2xlYW4gaGFzTW9kdWxlUHVibGlzaEluZm8oSU1vZHVsZVtdIG1vZHVsZSkgewoJCVN0cmluZyBrZXkgPSBnZXRLZXkobW9kdWxlKTsKCQlyZXR1cm4gbW9kdWxlUHVibGlzaEluZm8uY29udGFpbnNLZXkoa2V5KTsKCX0KCglwdWJsaWMgdm9pZCByZW1vdmVNb2R1bGVQdWJsaXNoSW5mbyhJTW9kdWxlW10gbW9kdWxlKSB7CgkJU3RyaW5nIGtleSA9IGdldEtleShtb2R1bGUpOwoJCW1vZHVsZVB1Ymxpc2hJbmZvLnJlbW92ZShrZXkpOwoJCQoJCXNhdmUoKTsKCX0KCgkvKioKCSAqIFJldHVybiB0aGUgcHVibGlzaCBzdGF0ZS4KCSAqLwoJcHJvdGVjdGVkIE1vZHVsZVB1Ymxpc2hJbmZvIGdldE1vZHVsZVB1Ymxpc2hJbmZvKElNb2R1bGVbXSBtb2R1bGUpIHsKCQlTdHJpbmcga2V5ID0gZ2V0S2V5KG1vZHVsZSk7CgoJCS8vIGNoZWNrIGlmIGl0IG5vdyBleGlzdHMKCQlpZiAobW9kdWxlUHVibGlzaEluZm8uY29udGFpbnNLZXkoa2V5KSkKCQkJcmV0dXJuIChNb2R1bGVQdWJsaXNoSW5mbykgbW9kdWxlUHVibGlzaEluZm8uZ2V0KGtleSk7CgkKCQkvLyBoYXZlIHRvIGNyZWF0ZSBhIG5ldyBvbmUKCQlNb2R1bGVQdWJsaXNoSW5mbyBtcGkgPSBuZXcgTW9kdWxlUHVibGlzaEluZm8oZ2V0S2V5KG1vZHVsZSkpOwoJCW1vZHVsZVB1Ymxpc2hJbmZvLnB1dChrZXksIG1waSk7CgkJcmV0dXJuIG1waTsKCX0KCglwdWJsaWMgdm9pZCBhZGRSZW1vdmVkTW9kdWxlcyhMaXN0IG1vZHVsZUxpc3QsIExpc3Qga2luZExpc3QpIHsKCQlpbnQgc2l6ZSA9IG1vZHVsZUxpc3Quc2l6ZSgpOwoJCUxpc3QgcmVtb3ZlZCA9IG5ldyBBcnJheUxpc3QoKTsKCQlJdGVyYXRvciBpdGVyYXRvciA9IG1vZHVsZVB1Ymxpc2hJbmZvLmtleVNldCgpLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlTdHJpbmcga2V5ID0gKFN0cmluZykgaXRlcmF0b3IubmV4dCgpOwoJCQoJCQlib29sZWFuIGZvdW5kID0gZmFsc2U7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlJTW9kdWxlW10gbW9kdWxlID0gKElNb2R1bGVbXSkgbW9kdWxlTGlzdC5nZXQoaSk7CgkJCQlTdHJpbmcga2V5MiA9IGdldEtleShtb2R1bGUpOwoJCQkJaWYgKGtleSAhPSBudWxsICYmIGtleS5lcXVhbHMoa2V5MikpCgkJCQkJZm91bmQgPSB0cnVlOwoJCQl9CgkJCWlmICghZm91bmQpIHsKCQkJCU1vZHVsZVB1Ymxpc2hJbmZvIG1waSA9IChNb2R1bGVQdWJsaXNoSW5mbykgbW9kdWxlUHVibGlzaEluZm8uZ2V0KGtleSk7CgkJCQlyZW1vdmVkLmFkZChtcGkpOwoJCQl9CgkJfQoJCQoJCWl0ZXJhdG9yID0gcmVtb3ZlZC5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJTW9kdWxlUHVibGlzaEluZm8gbXBpID0gKE1vZHVsZVB1Ymxpc2hJbmZvKSBpdGVyYXRvci5uZXh0KCk7CgkJCUlNb2R1bGVbXSBtb2R1bGUyID0gZ2V0TW9kdWxlKG1waS5nZXRNb2R1bGVJZCgpKTsKCQkJaWYgKG1vZHVsZTIgPT0gbnVsbCB8fCBtb2R1bGUyLmxlbmd0aCA9PSAwKSB7CgkJCQlTdHJpbmcgbW9kdWxlSWQgPSBtcGkuZ2V0TW9kdWxlSWQoKTsKCQkJCWlmIChtb2R1bGVJZCAhPSBudWxsKSB7CgkJCQkJaW50IGluZGV4ID0gbW9kdWxlSWQubGFzdEluZGV4T2YoIiMiKTsKCQkJCQltb2R1bGUyID0gbmV3IElNb2R1bGVbXSB7IG5ldyBEZWxldGVkTW9kdWxlKG1vZHVsZUlkLnN1YnN0cmluZyhpbmRleCArIDEpKSB9OwoJCQkJfQoJCQl9CgkJCWlmIChtb2R1bGUyICE9IG51bGwgJiYgbW9kdWxlMi5sZW5ndGggPiAwKSB7CgkJCQltb2R1bGVMaXN0LmFkZChtb2R1bGUyKTsKCQkJCWtpbmRMaXN0LmFkZChuZXcgSW50ZWdlcihTZXJ2ZXJCZWhhdmlvdXJEZWxlZ2F0ZS5SRU1PVkVEKSk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgbG9hZCgpIHsKCQlTdHJpbmcgZmlsZW5hbWUgPSBwYXRoLnRvT1NTdHJpbmcoKTsKCQlpZiAoIShuZXcgRmlsZShmaWxlbmFtZSkuZXhpc3RzKCkpKQoJCQlyZXR1cm47CgkKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJMb2FkaW5nIHB1Ymxpc2ggaW5mbyBmcm9tICIgKyBmaWxlbmFtZSk7CgoJCXRyeSB7CgkJCUlNZW1lbnRvIG1lbWVudG8yID0gWE1MTWVtZW50by5sb2FkTWVtZW50byhmaWxlbmFtZSk7CgkJCUlNZW1lbnRvW10gY2hpbGRyZW4gPSBtZW1lbnRvMi5nZXRDaGlsZHJlbigibW9kdWxlIik7CgkKCQkJaW50IHNpemUgPSBjaGlsZHJlbi5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlNb2R1bGVQdWJsaXNoSW5mbyBtcGkgPSBuZXcgTW9kdWxlUHVibGlzaEluZm8oY2hpbGRyZW5baV0pOwoJCQkJbW9kdWxlUHVibGlzaEluZm8ucHV0KGdldEtleShtcGkuZ2V0TW9kdWxlSWQoKSksIG1waSk7CgkJCX0KCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5XQVJOSU5HLCAiQ291bGQgbm90IGxvYWQgcHVibGlzaCBpbmZvcm1hdGlvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKCQl9Cgl9CgoJLyoqCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgc2F2ZSgpIHsKCQlTdHJpbmcgZmlsZW5hbWUgPSBwYXRoLnRvT1NTdHJpbmcoKTsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJTYXZpbmcgcHVibGlzaCBpbmZvIHRvICIgKyBmaWxlbmFtZSk7CgkKCQl0cnkgewoJCQlYTUxNZW1lbnRvIG1lbWVudG8gPSBYTUxNZW1lbnRvLmNyZWF0ZVdyaXRlUm9vdCgic2VydmVyIik7CgoJCQlJdGVyYXRvciBpdGVyYXRvciA9IG1vZHVsZVB1Ymxpc2hJbmZvLmtleVNldCgpLml0ZXJhdG9yKCk7CgkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCVN0cmluZyBjb250cm9sUmVmID0gKFN0cmluZykgaXRlcmF0b3IubmV4dCgpOwoJCQkJTW9kdWxlUHVibGlzaEluZm8gbXBpID0gKE1vZHVsZVB1Ymxpc2hJbmZvKSBtb2R1bGVQdWJsaXNoSW5mby5nZXQoY29udHJvbFJlZik7CgkJCQlJTWVtZW50byBjaGlsZCA9IG1lbWVudG8uY3JlYXRlQ2hpbGQoIm1vZHVsZSIpOwoJCQkJbXBpLnNhdmUoY2hpbGQpOwoJCQl9CgkJCW1lbWVudG8uc2F2ZVRvRmlsZShmaWxlbmFtZSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiQ291bGQgbm90IHNhdmUgcHVibGlzaCBpbmZvcm1hdGlvbiIsIGUpOwoJCX0KCX0KCQoJcHVibGljIHZvaWQgZmlsbChJTW9kdWxlW10gbW9kdWxlKSB7CgkJTW9kdWxlUHVibGlzaEluZm8gbXBpID0gZ2V0TW9kdWxlUHVibGlzaEluZm8obW9kdWxlKTsKCQlpbnQgc2l6ZSA9IG1vZHVsZS5sZW5ndGg7CgkJTW9kdWxlRGVsZWdhdGUgcG0gPSAoTW9kdWxlRGVsZWdhdGUpIG1vZHVsZVtzaXplIC0gMV0ubG9hZEFkYXB0ZXIoTW9kdWxlRGVsZWdhdGUuY2xhc3MsIG51bGwpOwoJCXRyeSB7CgkJCWlmIChwbSAhPSBudWxsKQoJCQkJbXBpLnNldFJlc291cmNlcyhwbS5tZW1iZXJzKCkpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJLy8gaWdub3JlCgkJfQoJCXNhdmUoKTsKCX0KCglwcm90ZWN0ZWQgSU1vZHVsZVJlc291cmNlRGVsdGFbXSBnZXREZWx0YShJTW9kdWxlW10gbW9kdWxlKSB7CgkJaWYgKG1vZHVsZSA9PSBudWxsKQoJCQlyZXR1cm4gbmV3IElNb2R1bGVSZXNvdXJjZURlbHRhWzBdOwoJCQoJCU1vZHVsZVB1Ymxpc2hJbmZvIG1waSA9IGdldE1vZHVsZVB1Ymxpc2hJbmZvKG1vZHVsZSk7CgkJaW50IHNpemUgPSBtb2R1bGUubGVuZ3RoOwoJCU1vZHVsZURlbGVnYXRlIHBtID0gKE1vZHVsZURlbGVnYXRlKSBtb2R1bGVbc2l6ZSAtIDFdLmxvYWRBZGFwdGVyKE1vZHVsZURlbGVnYXRlLmNsYXNzLCBudWxsKTsKCQlJTW9kdWxlUmVzb3VyY2VbXSByZXNvdXJjZXMgPSBudWxsOwoJCXRyeSB7CgkJCWlmIChwbSAhPSBudWxsKQoJCQkJcmVzb3VyY2VzID0gcG0ubWVtYmVycygpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJLy8gaWdub3JlCgkJfQoJCWlmIChyZXNvdXJjZXMgPT0gbnVsbCkKCQkJcmVzb3VyY2VzID0gbmV3IElNb2R1bGVSZXNvdXJjZVswXTsKCQlyZXR1cm4gZ2V0RGVsdGEobXBpLmdldFJlc291cmNlcygpLCByZXNvdXJjZXMpOwoJfQoKCXByb3RlY3RlZCBJTW9kdWxlUmVzb3VyY2VEZWx0YVtdIGdldERlbHRhKElNb2R1bGVSZXNvdXJjZVtdIG9yaWdpbmFsLCBJTW9kdWxlUmVzb3VyY2VbXSBjdXJyZW50KSB7CgkJaWYgKG9yaWdpbmFsID09IG51bGwgfHwgY3VycmVudCA9PSBudWxsKQoJCQlyZXR1cm4gbmV3IElNb2R1bGVSZXNvdXJjZURlbHRhWzBdOwoJCgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCQoJCS8vIGxvb2sgZm9yIGR1cGxpY2F0ZXMKCQlMaXN0IGZvdW5kID0gbmV3IEFycmF5TGlzdCgpOwoJCWludCBzaXplID0gb3JpZ2luYWwubGVuZ3RoOwoJCWludCBzaXplMiA9IGN1cnJlbnQubGVuZ3RoOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCWZvciAoaW50IGogPSAwOyBqIDwgc2l6ZTI7IGorKykgewoJCQkJaWYgKCFmb3VuZC5jb250YWlucyhvcmlnaW5hbFtpXSkgJiYgIWZvdW5kLmNvbnRhaW5zKGN1cnJlbnRbal0pICYmIG9yaWdpbmFsW2ldLmVxdWFscyhjdXJyZW50W2pdKSkgewoJCQkJCS8vIGZvdW5kIGEgbWF0Y2gKCQkJCQlmb3VuZC5hZGQob3JpZ2luYWxbaV0pOwoJCQkJCWlmIChvcmlnaW5hbFtpXSBpbnN0YW5jZW9mIElNb2R1bGVGaWxlKSB7CgkJCQkJCS8vIGluY2x1ZGUgZmlsZXMgb25seSBpZiB0aGUgbW9kaWZpY2F0aW9uIHN0YW1wIGhhcyBjaGFuZ2VkCgkJCQkJCUlNb2R1bGVGaWxlIG1mMSA9IChJTW9kdWxlRmlsZSkgb3JpZ2luYWxbaV07CgkJCQkJCUlNb2R1bGVGaWxlIG1mMiA9IChJTW9kdWxlRmlsZSkgY3VycmVudFtqXTsKCQkJCQkJaWYgKG1mMS5nZXRNb2RpZmljYXRpb25TdGFtcCgpICE9IG1mMi5nZXRNb2RpZmljYXRpb25TdGFtcCgpKSB7CgkJCQkJCQlsaXN0LmFkZChuZXcgTW9kdWxlUmVzb3VyY2VEZWx0YShvcmlnaW5hbFtpXSwgSU1vZHVsZVJlc291cmNlRGVsdGEuQ0hBTkdFRCkpOwoJCQkJCQl9CgkJCQkJfSBlbHNlIHsKCQkJCQkJLy8gaW5jbHVkZSBmb2xkZXJzIG9ubHkgaWYgdGhlaXIgY29udGVudHMgaGF2ZSBjaGFuZ2VkCgkJCQkJCUlNb2R1bGVGb2xkZXIgbWYxID0gKElNb2R1bGVGb2xkZXIpIG9yaWdpbmFsW2ldOwoJCQkJCQlJTW9kdWxlRm9sZGVyIG1mMiA9IChJTW9kdWxlRm9sZGVyKSBjdXJyZW50W2pdOwoJCQkJCQlJTW9kdWxlUmVzb3VyY2VEZWx0YVtdIG1yZGMgPSBnZXREZWx0YShtZjEubWVtYmVycygpLCBtZjIubWVtYmVycygpKTsKCQkJCQkJaWYgKG1yZGMubGVuZ3RoID4gMCkgewoJCQkJCQkJTW9kdWxlUmVzb3VyY2VEZWx0YSBtcmQgPSBuZXcgTW9kdWxlUmVzb3VyY2VEZWx0YShvcmlnaW5hbFtpXSwgSU1vZHVsZVJlc291cmNlRGVsdGEuTk9fQ0hBTkdFKTsKCQkJCQkJCW1yZC5zZXRDaGlsZHJlbihtcmRjKTsKCQkJCQkJCWxpc3QuYWRkKG1yZCk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgkJCgkJLy8gYWRkIGRlbGV0aW9ucyAodW5mb3VuZCBpdGVtcyBpbiB0aGUgb3JpZ2luYWwgbGlzdCkKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQlpZiAoIWZvdW5kLmNvbnRhaW5zKG9yaWdpbmFsW2ldKSkgewoJCQkJaWYgKG9yaWdpbmFsW2ldIGluc3RhbmNlb2YgSU1vZHVsZUZpbGUpIHsKCQkJCQlsaXN0LmFkZChuZXcgTW9kdWxlUmVzb3VyY2VEZWx0YShvcmlnaW5hbFtpXSwgSU1vZHVsZVJlc291cmNlRGVsdGEuUkVNT1ZFRCkpOwoJCQkJfSBlbHNlIHsKCQkJCQlJTW9kdWxlRm9sZGVyIG1mID0gKElNb2R1bGVGb2xkZXIpIG9yaWdpbmFsW2ldOwoJCQkJCU1vZHVsZVJlc291cmNlRGVsdGEgbXJkID0gbmV3IE1vZHVsZVJlc291cmNlRGVsdGEob3JpZ2luYWxbaV0sIElNb2R1bGVSZXNvdXJjZURlbHRhLlJFTU9WRUQpOwoJCQkJCUlNb2R1bGVSZXNvdXJjZURlbHRhW10gbXJkYyA9IGdldERlbHRhVHJlZShtZi5tZW1iZXJzKCksIElNb2R1bGVSZXNvdXJjZURlbHRhLlJFTU9WRUQpOwoJCQkJCW1yZC5zZXRDaGlsZHJlbihtcmRjKTsKCQkJCQlsaXN0LmFkZChtcmQpOwoJCQkJfQoJCQl9CgkJfQoJCQoJCS8vCWFkZCBhZGRpdGlvbnMgKHVuZm91bmQgaXRlbXMgaW4gdGhlIGN1cnJlbnQgbGlzdCkKCQlmb3IgKGludCBqID0gMDsgaiA8IHNpemUyOyBqKyspIHsKCQkJaWYgKCFmb3VuZC5jb250YWlucyhjdXJyZW50W2pdKSkgewoJCQkJaWYgKGN1cnJlbnRbal0gaW5zdGFuY2VvZiBJTW9kdWxlRmlsZSkgewoJCQkJCWxpc3QuYWRkKG5ldyBNb2R1bGVSZXNvdXJjZURlbHRhKGN1cnJlbnRbal0sIElNb2R1bGVSZXNvdXJjZURlbHRhLkFEREVEKSk7CgkJCQl9IGVsc2UgewoJCQkJCUlNb2R1bGVGb2xkZXIgbWYgPSAoSU1vZHVsZUZvbGRlcikgY3VycmVudFtqXTsKCQkJCQlNb2R1bGVSZXNvdXJjZURlbHRhIG1yZCA9IG5ldyBNb2R1bGVSZXNvdXJjZURlbHRhKGN1cnJlbnRbal0sIElNb2R1bGVSZXNvdXJjZURlbHRhLkFEREVEKTsKCQkJCQlJTW9kdWxlUmVzb3VyY2VEZWx0YVtdIG1yZGMgPSBnZXREZWx0YVRyZWUobWYubWVtYmVycygpLCBJTW9kdWxlUmVzb3VyY2VEZWx0YS5BRERFRCk7CgkJCQkJbXJkLnNldENoaWxkcmVuKG1yZGMpOwoJCQkJCWxpc3QuYWRkKG1yZCk7CgkJCQl9CgkJCX0KCQl9CgkJCgkJSU1vZHVsZVJlc291cmNlRGVsdGFbXSBkZWx0YSA9IG5ldyBJTW9kdWxlUmVzb3VyY2VEZWx0YVtsaXN0LnNpemUoKV07CgkJbGlzdC50b0FycmF5KGRlbHRhKTsKCQlyZXR1cm4gZGVsdGE7Cgl9CgoJLyoqCgkgKiBDcmVhdGUgYSByZXNvdXJjZSBkZWx0YSBmb3IgYW4gZW50aXJlIHRyZWUuCgkgKi8KCXByb3RlY3RlZCBJTW9kdWxlUmVzb3VyY2VEZWx0YVtdIGdldERlbHRhVHJlZShJTW9kdWxlUmVzb3VyY2VbXSByZXNvdXJjZXMsIGludCBraW5kKSB7CgkJaWYgKHJlc291cmNlcyA9PSBudWxsKQoJCQlyZXR1cm4gbmV3IElNb2R1bGVSZXNvdXJjZURlbHRhWzBdOwoJCgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCQoJCS8vIGxvb2sgZm9yIGR1cGxpY2F0ZXMKCQlpbnQgc2l6ZSA9IHJlc291cmNlcy5sZW5ndGg7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJTW9kdWxlUmVzb3VyY2VEZWx0YSBtcmQgPSBuZXcgTW9kdWxlUmVzb3VyY2VEZWx0YShyZXNvdXJjZXNbaV0sIGtpbmQpOwoJCQlpZiAocmVzb3VyY2VzW2ldIGluc3RhbmNlb2YgSU1vZHVsZUZvbGRlcikgewoJCQkJSU1vZHVsZUZvbGRlciBtZiA9IChJTW9kdWxlRm9sZGVyKSByZXNvdXJjZXNbaV07CgkJCQltcmQuc2V0Q2hpbGRyZW4oZ2V0RGVsdGFUcmVlKG1mLm1lbWJlcnMoKSwga2luZCkpOwoJCQl9CgkJCWxpc3QuYWRkKG1yZCk7CgkJfQoJCQoJCUlNb2R1bGVSZXNvdXJjZURlbHRhW10gZGVsdGEgPSBuZXcgSU1vZHVsZVJlc291cmNlRGVsdGFbbGlzdC5zaXplKCldOwoJCWxpc3QudG9BcnJheShkZWx0YSk7CgkJcmV0dXJuIGRlbHRhOwoJfQp9