LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmU7CgppbXBvcnQgamF2YS51dGlsLio7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5Db3JlRXhjZXB0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQcm9ncmVzc01vbml0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVN0YXR1czsKCmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuTW9kdWxlRmFjdG9yeTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TZXJ2ZXJQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuVHJhY2U7Ci8qKgogKiBTZXJ2ZXIgdXRpbGl0eSBtZXRob2RzLgogKi8KcHVibGljIGNsYXNzIFNlcnZlclV0aWwgewoJLyoqCgkgKiBTdGF0aWMgY2xhc3MgLSBjYW5ub3QgY3JlYXRlIGFuIGluc3RhbmNlLgoJICovCglwcml2YXRlIFNlcnZlclV0aWwoKSB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBzZXJ2ZXIgY3VycmVudGx5IGNvbnRhaW5zIHRoZSBnaXZlbiBtb2R1bGUuCgkgKgoJICogQHBhcmFtIHNlcnZlciBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlcgoJICogQHBhcmFtIG1vZHVsZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSU1vZHVsZQoJICogQHJldHVybiBib29sZWFuCgkgKi8KCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiBjb250YWluc01vZHVsZShJU2VydmVyIHNlcnZlciwgSU1vZHVsZSBtb2R1bGUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCWlmIChzZXJ2ZXIgPT0gbnVsbCkKCQkJcmV0dXJuIGZhbHNlOwoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgImNvbnRhaW5zTW9kdWxlKCkgIiArIHNlcnZlciArICIgIiArIG1vZHVsZSk7CgkJdHJ5IHsKCQkJSU1vZHVsZVtdIG1vZHVsZXMgPSBnZXRBbGxDb250YWluZWRNb2R1bGVzKHNlcnZlciwgbW9uaXRvcik7CgkJCWlmIChtb2R1bGVzICE9IG51bGwpIHsKCQkJCWludCBzaXplID0gbW9kdWxlcy5sZW5ndGg7CgkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIm1vZHVsZTogIiArIG1vZHVsZXNbaV0gKyAiICIgKyBtb2R1bGUuZXF1YWxzKG1vZHVsZXNbaV0pKTsKCQkJCQlpZiAobW9kdWxlLmVxdWFscyhtb2R1bGVzW2ldKSkKCQkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgkJCX0KCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewoJCQkvLyBpZ25vcmUKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogUmV0dXJucyBhbGwgcHJvamVjdHMgY29udGFpbmVkIGJ5IHRoZSBzZXJ2ZXIuIFRoaXMgaW5jbHVkZWQgdGhlCgkgKiBwcm9qZWN0cyB0aGF0IGFyZSBpbiB0aGUgY29uZmlndXJhdGlvbiwgYXMgd2VsbCBhcyB0aGVpcgoJICogY2hpbGRyZW4sIGFuZCB0aGVpciBjaGlsZHJlbi4uLgoJICoKCSAqIEBwYXJhbSBzZXJ2ZXIgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXIKCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIHN0YXRpYyBJTW9kdWxlW10gZ2V0QWxsQ29udGFpbmVkTW9kdWxlcyhJU2VydmVyIHNlcnZlciwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJLy9UcmFjZS50cmFjZSgiPiBnZXRBbGxDb250YWluZWRNb2R1bGVzOiAiICsgZ2V0TmFtZShjb25maWd1cmF0aW9uKSk7CgkJTGlzdCBtb2R1bGVzID0gbmV3IEFycmF5TGlzdCgpOwoJCWlmIChzZXJ2ZXIgPT0gbnVsbCkKCQkJcmV0dXJuIG5ldyBJTW9kdWxlWzBdOwoKCQkvLyBnZXQgYWxsIG9mIHRoZSBkaXJlY3RseSBjb250YWluZWQgcHJvamVjdHMKCQlJTW9kdWxlW10gZGVwbG95cyA9IHNlcnZlci5nZXRNb2R1bGVzKG1vbml0b3IpOwoJCWlmIChkZXBsb3lzID09IG51bGwgfHwgZGVwbG95cy5sZW5ndGggPT0gMCkKCQkJcmV0dXJuIG5ldyBJTW9kdWxlWzBdOwoKCQlpbnQgc2l6ZSA9IGRlcGxveXMubGVuZ3RoOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCWlmIChkZXBsb3lzW2ldICE9IG51bGwgJiYgIW1vZHVsZXMuY29udGFpbnMoZGVwbG95c1tpXSkpCgkJCQltb2R1bGVzLmFkZChkZXBsb3lzW2ldKTsKCQl9CgoJCS8vVHJhY2UudHJhY2UoIiAgZ2V0QWxsQ29udGFpbmVkTW9kdWxlczogcm9vdCBsZXZlbCBkb25lIik7CgoJCS8vIGdldCBhbGwgb2YgdGhlIG1vZHVsZSdzIGNoaWxkcmVuCgkJaW50IGNvdW50ID0gMDsKCQl3aGlsZSAoY291bnQgPCBtb2R1bGVzLnNpemUoKSkgewoJCQlJTW9kdWxlIG1vZHVsZSA9IChJTW9kdWxlKSBtb2R1bGVzLmdldChjb3VudCk7CgkJCXRyeSB7CgkJCQlJTW9kdWxlW10gY2hpbGRyZW4gPSBzZXJ2ZXIuZ2V0Q2hpbGRNb2R1bGVzKG1vZHVsZSwgbW9uaXRvcik7CgkJCQlpZiAoY2hpbGRyZW4gIT0gbnVsbCkgewoJCQkJCXNpemUgPSBjaGlsZHJlbi5sZW5ndGg7CgkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQkJaWYgKGNoaWxkcmVuW2ldICE9IG51bGwgJiYgIW1vZHVsZXMuY29udGFpbnMoY2hpbGRyZW5baV0pKQoJCQkJCQkJbW9kdWxlcy5hZGQoY2hpbGRyZW5baV0pOwoJCQkJCX0KCQkJCX0KCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIGdldHRpbmcgY2hpbGQgbW9kdWxlcyBmb3I6ICIgKyBtb2R1bGUuZ2V0TmFtZSgpLCBlKTsKCQkJfQoJCQljb3VudCArKzsKCQl9CgoJCS8vVHJhY2UudHJhY2UoIjwgZ2V0QWxsQ29udGFpbmVkTW9kdWxlcyIpOwoKCQlJTW9kdWxlW10gbW9kdWxlczIgPSBuZXcgSU1vZHVsZVttb2R1bGVzLnNpemUoKV07CgkJbW9kdWxlcy50b0FycmF5KG1vZHVsZXMyKTsKCQlyZXR1cm4gbW9kdWxlczI7Cgl9CgkKCS8qKgoJICogUmV0dXJucyBhIGxpc3Qgb2YgYWxsIHNlcnZlcnMgdGhhdCB0aGlzIG1vZHVsZSBpcyBjb25maWd1cmVkIG9uLgoJICoKCSAqIEBwYXJhbSBtb2R1bGUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGUKCSAqIEByZXR1cm4gamF2YS51dGlsLkxpc3QKCSAqLwoJcHVibGljIHN0YXRpYyBJU2VydmVyW10gZ2V0U2VydmVyc0J5TW9kdWxlKElNb2R1bGUgbW9kdWxlLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlpZiAobW9kdWxlID09IG51bGwpCgkJCXJldHVybiBuZXcgSVNlcnZlclswXTsKCgkJLy8gZG8gaXQgdGhlIHNsb3cgd2F5IC0gZ28gdGhyb3VnaCBhbGwgc2VydmVycyBhbmQKCQkvLyBzZWUgaWYgdGhpcyBtb2R1bGUgaXMgY29uZmlndXJlZCBpbiBpdAoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQlJU2VydmVyW10gc2VydmVycyA9IFNlcnZlckNvcmUuZ2V0U2VydmVycygpOwoJCWlmIChzZXJ2ZXJzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBzZXJ2ZXJzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCWlmIChjb250YWluc01vZHVsZShzZXJ2ZXJzW2ldLCBtb2R1bGUsIG1vbml0b3IpKQoJCQkJCWxpc3QuYWRkKHNlcnZlcnNbaV0pOwoJCQl9CgkJfQoJCQoJCUlTZXJ2ZXJbXSBhbGxTZXJ2ZXJzID0gbmV3IElTZXJ2ZXJbbGlzdC5zaXplKCldOwoJCWxpc3QudG9BcnJheShhbGxTZXJ2ZXJzKTsKCQlyZXR1cm4gYWxsU2VydmVyczsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBwcm9qZWN0IG1vZHVsZXMgYXR0YWNoZWQgdG8gYSBwcm9qZWN0LgoJICovCglwdWJsaWMgc3RhdGljIElNb2R1bGVbXSBnZXRNb2R1bGVzKElQcm9qZWN0IHByb2plY3QpIHsKCQlpZiAocHJvamVjdCA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCUlNb2R1bGVbXSBtb2R1bGVzID0gZ2V0TW9kdWxlcygpOwoJCWlmIChtb2R1bGVzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBtb2R1bGVzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCWlmIChtb2R1bGVzW2ldICE9IG51bGwgJiYgcHJvamVjdC5lcXVhbHMobW9kdWxlc1tpXS5nZXRQcm9qZWN0KCkpKQoJCQkJCWxpc3QuYWRkKG1vZHVsZXNbaV0pOwoJCQl9CgkJfQoJCQoJCUlNb2R1bGVbXSBtb2R1bGVzMiA9IG5ldyBJTW9kdWxlW2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkobW9kdWxlczIpOwoJCXJldHVybiBtb2R1bGVzMjsKCX0KCgkvKioKCSAqIFJldHVybnMgYSBtb2R1bGUgZnJvbSB0aGUgZ2l2ZW4gbW9kdWxlSWQuCgkgKiAKCSAqIEBwYXJhbSBqYXZhLmxhbmcuU3RyaW5nIG1vZHVsZUlkCgkgKiBAcmV0dXJuIHRoZSBtb2R1bGUKCSAqLwoJcHVibGljIHN0YXRpYyBJTW9kdWxlIGdldE1vZHVsZShTdHJpbmcgbW9kdWxlSWQpIHsKCQlpbnQgaW5kZXggPSBtb2R1bGVJZC5pbmRleE9mKCI6Iik7CgkJaWYgKGluZGV4IDw9IDApCgkJCXJldHVybiBudWxsOwoJCQoJCVN0cmluZyBmYWN0b3J5SWQgPSBtb2R1bGVJZC5zdWJzdHJpbmcoMCwgaW5kZXgpOwoJCU1vZHVsZUZhY3RvcnkgbW9kdWxlRmFjdG9yeSA9IFNlcnZlckNvcmUuZmluZE1vZHVsZUZhY3RvcnkoZmFjdG9yeUlkKTsKCQlpZiAobW9kdWxlRmFjdG9yeSA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCgkJU3RyaW5nIG1vZHVsZVN1YklkID0gbW9kdWxlSWQuc3Vic3RyaW5nKGluZGV4KzEpOwoJCUlNb2R1bGUgbW9kdWxlID0gbW9kdWxlRmFjdG9yeS5nZXRNb2R1bGUobW9kdWxlU3ViSWQpOwoJCWlmIChtb2R1bGUgIT0gbnVsbCkKCQkJcmV0dXJuIG1vZHVsZTsKCQlyZXR1cm4gbnVsbDsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGNsYXNzIG5hbWUgcyBpcyBhIHN1cGVyY2xhc3Mgb3IgaW50ZXJmYWNlIG9mCgkgKiB0aGUgY2xhc3Mgb2JqLgoJICogCgkgKiBAcGFyYW0gYyBqYXZhLmxhbmcuQ2xhc3MKCSAqIEBwYXJhbSBzIGphdmEubGFuZy5TdHJpbmcKCSAqIEByZXR1cm4gYm9vbGVhbgoJICovCglwcm90ZWN0ZWQgc3RhdGljIGJvb2xlYW4gaXNFbmFibGVkKENsYXNzIGMsIFN0cmluZyBzKSB7CgkJaWYgKHMgPT0gbnVsbCB8fCBzLmxlbmd0aCgpID09IDApCgkJCXJldHVybiB0cnVlOwoKCQl3aGlsZSAoYyAhPSBudWxsICYmIGMgIT0gT2JqZWN0LmNsYXNzKSB7CgkJCWlmIChzLmVxdWFscyhjLmdldE5hbWUoKSkpCgkJCQlyZXR1cm4gdHJ1ZTsKCQkJQ2xhc3NbXSBpbmYgPSBjLmdldEludGVyZmFjZXMoKTsKCQkJaWYgKGluZiAhPSBudWxsKSB7CgkJCQlpbnQgc2l6ZSA9IGluZi5sZW5ndGg7CgkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJCWlmIChzLmVxdWFscyhpbmZbaV0uZ2V0TmFtZSgpKSkKCQkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgkJCX0KCQkJYyA9IGMuZ2V0U3VwZXJjbGFzcygpOwoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9CgkKCS8qKgoJICogUmV0dXJucyBhIG1vZHVsZSBmb3IgdGhlIGdpdmVuIG9iamVjdCB0aGF0IG1heSBiZSBsYXVuY2hhYmxlIG9uCgkgKiBhIHNlcnZlciB1c2luZyB0aGUgUnVuIG9uIFNlcnZlciBvcHRpb24uIFRocm93cyBhbiBleGNlcHRpb24gaWYgaXQKCSAqIGNhbid0IGRldGVybWluZSB0aGUgb2JqZWN0IHdpdGhvdXQgcG9zc2libGUgcGx1Z2luIGxvYWRpbmcuCgkgKiAKCSAqIEBwYXJhbSBvYmogamF2YS5sYW5nLk9iamVjdAoJICogQHJldHVybiBJTW9kdWxlCgkgKiBAdGhyb3dzIGphdmEubGFuZy5FeGNlcHRpb24KCSAqLwoJcHVibGljIHN0YXRpYyBJTW9kdWxlIGdldE1vZHVsZShPYmplY3Qgb2JqLCBib29sZWFuIGluaXRpYWxpemVkKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlpZiAob2JqID09IG51bGwpCgkJCXJldHVybiBudWxsOwoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIlNlcnZlclV0aWwuZ2V0TW9kdWxlKCkiKTsKCQlJTW9kdWxlQXJ0aWZhY3RBZGFwdGVyW10gYWRhcHRlcnMgPSBTZXJ2ZXJDb3JlLmdldE1vZHVsZUFydGlmYWN0QWRhcHRlcnMoKTsKCQlpZiAoYWRhcHRlcnMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IGFkYXB0ZXJzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCWlmIChpc0VuYWJsZWQob2JqLmdldENsYXNzKCksIGFkYXB0ZXJzW2ldLmdldE9iamVjdENsYXNzTmFtZSgpKSkgewoJCQkJCWlmICghaW5pdGlhbGl6ZWQpIHsKCQkJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiZ2V0TW9kdWxlKCk6ICIgKyBvYmouZ2V0Q2xhc3MoKSArICIgIiArIGFkYXB0ZXJzW2ldLmdldE9iamVjdENsYXNzTmFtZSgpKTsKCQkJCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbigpOwoJCQkJCX0KCQkJCQlJTW9kdWxlQXJ0aWZhY3QgbW9kdWxlT2JqZWN0ID0gYWRhcHRlcnNbaV0uZ2V0TW9kdWxlT2JqZWN0KG9iaik7CgkJCQkJaWYgKG1vZHVsZU9iamVjdCAhPSBudWxsKQoJCQkJCQlyZXR1cm4gbW9kdWxlT2JqZWN0LmdldE1vZHVsZSgpOwoJCQkJfQoJCQl9CgkJfQoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogUmV0dXJucyBhIGxpc3Qgb2YgdGhlIGxhdW5jaGFibGUgY2xpZW50cyBmb3IgdGhlIGdpdmVuIG9iamVjdC4KCSAqCgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgSU1vZHVsZUFydGlmYWN0W10gZ2V0TW9kdWxlT2JqZWN0cyhPYmplY3Qgb2JqKSB7CgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIlNlcnZlclV0aWwuZ2V0TW9kdWxlT2JqZWN0cygpIik7CgkJSU1vZHVsZUFydGlmYWN0QWRhcHRlcltdIGFkYXB0ZXJzID0gU2VydmVyQ29yZS5nZXRNb2R1bGVBcnRpZmFjdEFkYXB0ZXJzKCk7CgkJaWYgKGFkYXB0ZXJzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBhZGFwdGVycy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlpZiAoaXNFbmFibGVkKG9iai5nZXRDbGFzcygpLCBhZGFwdGVyc1tpXS5nZXRPYmplY3RDbGFzc05hbWUoKSkpIHsKCQkJCQlJTW9kdWxlQXJ0aWZhY3QgbW9kdWxlT2JqZWN0ID0gYWRhcHRlcnNbaV0uZ2V0TW9kdWxlT2JqZWN0KG9iaik7CgkJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAibW9kdWxlT2JqZWN0OiAiICsgbW9kdWxlT2JqZWN0KTsKCQkJCQlpZiAobW9kdWxlT2JqZWN0ICE9IG51bGwpCgkJCQkJCWxpc3QuYWRkKG1vZHVsZU9iamVjdCk7CgkJCQl9CgkJCX0KCQl9CgkJCgkJSU1vZHVsZUFydGlmYWN0W10gbW8gPSBuZXcgSU1vZHVsZUFydGlmYWN0W2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkobW8pOwoJCXJldHVybiBtbzsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIGZpcnN0IGxhdW5jaGFibGUgb2JqZWN0IGZvciB0aGUgZ2l2ZW4gc2VydmVyIGFuZCBtb2R1bGUKCSAqIG9iamVjdC4KCSAqIAoJICogQHBhcmFtIHNlcnZlcgoJICogQHBhcmFtIG1vZHVsZU9iamVjdAoJICogQHJldHVybiBJTGF1bmNoYWJsZQoJICovCgkvKnB1YmxpYyBzdGF0aWMgSUxhdW5jaGFibGUgZ2V0TGF1bmNoYWJsZShJU2VydmVyIHNlcnZlciwgSU1vZHVsZUFydGlmYWN0IG1vZHVsZU9iamVjdCkgewoJCUlMYXVuY2hhYmxlQWRhcHRlcltdIGFkYXB0ZXJzID0gU2VydmVyQ29yZS5nZXRMYXVuY2hhYmxlQWRhcHRlcnMoKTsKCQlpZiAoYWRhcHRlcnMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IGFkYXB0ZXJzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCXRyeSB7CgkJCQkJSUxhdW5jaGFibGUgbGF1bmNoYWJsZSA9IGFkYXB0ZXJzW2ldLmdldExhdW5jaGFibGUoc2VydmVyLCBtb2R1bGVPYmplY3QpOwoJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgImFkYXB0ZXI9ICIgKyBhZGFwdGVyc1tpXSArICIsIGxhdW5jaGFibGU9ICIgKyBsYXVuY2hhYmxlKTsKCQkJCQlpZiAobGF1bmNoYWJsZSAhPSBudWxsKQoJCQkJCQlyZXR1cm4gbGF1bmNoYWJsZTsKCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgaW4gbGF1bmNoYWJsZSBhZGFwdGVyIiwgZSk7CgkJCQl9CgkJCX0KCQl9CgkJcmV0dXJuIG51bGw7Cgl9Ki8KCgkvKioKCSAqIFJldHVybnMgdGhlIGZpcnN0IGxhdW5jaGFibGUgb2JqZWN0IGZvciB0aGUgZ2l2ZW4gc2VydmVyIGFuZCBtb2R1bGUKCSAqIG9iamVjdC4KCSAqIAoJICogQHBhcmFtIHNlcnZlcgoJICogQHBhcmFtIG1vZHVsZU9iamVjdAoJICogQHJldHVybiBJTGF1bmNoYWJsZQoJICovCgkvKnB1YmxpYyBzdGF0aWMgSUxhdW5jaGFibGUgZ2V0TGF1bmNoYWJsZShJU2VydmVyIHNlcnZlciwgTGlzdCBtb2R1bGVPYmplY3RzKSB7CgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBtb2R1bGVPYmplY3RzLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlJTW9kdWxlQXJ0aWZhY3QgbW9kdWxlT2JqZWN0ID0gKElNb2R1bGVBcnRpZmFjdCkgaXRlcmF0b3IubmV4dCgpOwoJCQlJTGF1bmNoYWJsZSBsYXVuY2hhYmxlID0gZ2V0TGF1bmNoYWJsZShzZXJ2ZXIsIG1vZHVsZU9iamVjdCk7CgkJCWlmIChsYXVuY2hhYmxlICE9IG51bGwpCgkJCQlyZXR1cm4gbGF1bmNoYWJsZTsKCQl9CgkJcmV0dXJuIG51bGw7Cgl9Ki8KCgkvKioKCSAqIFJldHVybnMgdGhlIGZhY3RvcnkgdGhhdCBjcmVhdGVkIHRoZSBnaXZlbiBtb2R1bGUuCgkgKgoJICogQHBhcmFtIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JTW9kdWxlCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JTW9kdWxlRmFjdG9yeQoJICovCgkvKnB1YmxpYyBzdGF0aWMgSU1vZHVsZUZhY3RvcnkgZ2V0TW9kdWxlRmFjdG9yeShJTW9kdWxlIG1vZHVsZSkgewoJCVN0cmluZyBpZCA9IG1vZHVsZS5nZXRGYWN0b3J5SWQoKTsKCQlpZiAoaWQgPT0gbnVsbCkKCQkJcmV0dXJuIG51bGw7CgoJCUlNb2R1bGVGYWN0b3J5W10gZmFjdG9yaWVzID0gU2VydmVyQ29yZS5nZXRNb2R1bGVGYWN0b3JpZXMoKTsKCQlpZiAoZmFjdG9yaWVzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBmYWN0b3JpZXMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJaWYgKGlkLmVxdWFscyhmYWN0b3JpZXNbaV0uZ2V0SWQoKSkpCgkJCQkJcmV0dXJuIGZhY3Rvcmllc1tpXTsKCQkJfQoJCX0KCQlyZXR1cm4gbnVsbDsKCX0qLwoKCS8qKgoJICogUmV0dXJuIGFsbCB0aGUgYXZhaWxhYmxlIG1vZHVsZXMgZnJvbSBhbGwgZmFjdG9yaWVzIHdob3NlCgkgKiB0eXBlIGluY2x1ZGVzIHRoZSBnaXZlbiBpZC4KCSAqIAoJICogQHBhcmFtIHR5cGUgamF2YS5sYW5nLlN0cmluZwoJICogQHBhcmFtIG9ubHlQcm9qZWN0TW9kdWxlcyBib29sZWFuCgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXB1YmxpYyBzdGF0aWMgSU1vZHVsZVtdIGdldE1vZHVsZXMoSU1vZHVsZVR5cGVbXSBtb2R1bGVUeXBlcykgewoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCgkJTW9kdWxlRmFjdG9yeVtdIGZhY3RvcmllcyA9IFNlcnZlckNvcmUuZ2V0TW9kdWxlRmFjdG9yaWVzKCk7CgkJaWYgKGZhY3RvcmllcyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gZmFjdG9yaWVzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCWlmIChpc1N1cHBvcnRlZE1vZHVsZShmYWN0b3JpZXNbaV0uZ2V0TW9kdWxlVHlwZXMoKSwgbW9kdWxlVHlwZXMpKSB7CgkJCQkJSU1vZHVsZVtdIG1vZHVsZXMgPSBmYWN0b3JpZXNbaV0uZ2V0TW9kdWxlcygpOwoJCQkJCWlmIChtb2R1bGVzICE9IG51bGwpIHsKCQkJCQkJaW50IHNpemUyID0gbW9kdWxlcy5sZW5ndGg7CgkJCQkJCWZvciAoaW50IGogPSAwOyBqIDwgc2l6ZTI7IGorKykKCQkJCQkJCWxpc3QuYWRkKG1vZHVsZXNbal0pOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCQlJTW9kdWxlW10gbW9kdWxlcyA9IG5ldyBJTW9kdWxlW2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkobW9kdWxlcyk7CgkJcmV0dXJuIG1vZHVsZXM7Cgl9CgkKCXB1YmxpYyBzdGF0aWMgSU1vZHVsZVtdIGdldE1vZHVsZXMoU3RyaW5nIHR5cGUpIHsKCQlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgoJCU1vZHVsZUZhY3RvcnlbXSBmYWN0b3JpZXMgPSBTZXJ2ZXJDb3JlLmdldE1vZHVsZUZhY3RvcmllcygpOwoJCWlmIChmYWN0b3JpZXMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IGZhY3Rvcmllcy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlpZiAoaXNTdXBwb3J0ZWRNb2R1bGUoZmFjdG9yaWVzW2ldLmdldE1vZHVsZVR5cGVzKCksIHR5cGUsIG51bGwpKSB7CgkJCQkJSU1vZHVsZVtdIG1vZHVsZXMgPSBmYWN0b3JpZXNbaV0uZ2V0TW9kdWxlcygpOwoJCQkJCWlmIChtb2R1bGVzICE9IG51bGwpIHsKCQkJCQkJaW50IHNpemUyID0gbW9kdWxlcy5sZW5ndGg7CgkJCQkJCWZvciAoaW50IGogPSAwOyBqIDwgc2l6ZTI7IGorKykKCQkJCQkJCWxpc3QuYWRkKG1vZHVsZXNbal0pOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCQlJTW9kdWxlW10gbW9kdWxlcyA9IG5ldyBJTW9kdWxlW2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkobW9kdWxlcyk7CgkJcmV0dXJuIG1vZHVsZXM7Cgl9CgkKCS8qcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3VwcG9ydGVkTW9kdWxlKElTZXJ2ZXJUeXBlIHNlcnZlclR5cGUsIElNb2R1bGVUeXBlIG1vZHVsZVR5cGUpIHsKCQlJUnVudGltZVR5cGUgcnVudGltZVR5cGUgPSBzZXJ2ZXJUeXBlLmdldFJ1bnRpbWVUeXBlKCk7CgkJcmV0dXJuIGlzU3VwcG9ydGVkTW9kdWxlKHJ1bnRpbWVUeXBlLmdldE1vZHVsZVR5cGVzKCksIG1vZHVsZVR5cGUuZ2V0SWQoKSwgbW9kdWxlVHlwZS5nZXRWZXJzaW9uKCkpOwoJfSovCgkKCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1N1cHBvcnRlZE1vZHVsZShJTW9kdWxlVHlwZVtdIG1vZHVsZVR5cGVzLCBTdHJpbmcgdHlwZSwgU3RyaW5nIHZlcnNpb24pIHsKCQlpZiAobW9kdWxlVHlwZXMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IG1vZHVsZVR5cGVzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCWlmIChpc1N1cHBvcnRlZE1vZHVsZShtb2R1bGVUeXBlc1tpXSwgdHlwZSwgdmVyc2lvbikpCgkJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCXByb3RlY3RlZCBzdGF0aWMgYm9vbGVhbiBpc1N1cHBvcnRlZE1vZHVsZShJTW9kdWxlVHlwZVtdIG1vZHVsZVR5cGVzLCBJTW9kdWxlVHlwZVtdIG10KSB7CgkJaWYgKG10ICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBtdC5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlpZiAoaXNTdXBwb3J0ZWRNb2R1bGUobW9kdWxlVHlwZXMsIG10W2ldKSkKCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9CgoJcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3VwcG9ydGVkTW9kdWxlKElNb2R1bGVUeXBlW10gbW9kdWxlVHlwZXMsIElNb2R1bGVUeXBlIG10KSB7CgkJaWYgKG1vZHVsZVR5cGVzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBtb2R1bGVUeXBlcy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlpZiAoaXNTdXBwb3J0ZWRNb2R1bGUobW9kdWxlVHlwZXNbaV0sIG10KSkKCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9CgkKCXByb3RlY3RlZCBzdGF0aWMgYm9vbGVhbiBpc1N1cHBvcnRlZE1vZHVsZShJTW9kdWxlVHlwZSBtb2R1bGVUeXBlLCBTdHJpbmcgdHlwZSwgU3RyaW5nIHZlcnNpb24pIHsKCQlTdHJpbmcgdHlwZTIgPSBtb2R1bGVUeXBlLmdldElkKCk7CgkJaWYgKG1hdGNoZXModHlwZSwgdHlwZTIpKSB7CgkJCVN0cmluZyB2ZXJzaW9uMiA9IG1vZHVsZVR5cGUuZ2V0VmVyc2lvbigpOwoJCQlpZiAobWF0Y2hlcyh2ZXJzaW9uLCB2ZXJzaW9uMikpCgkJCQlyZXR1cm4gdHJ1ZTsKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1N1cHBvcnRlZE1vZHVsZShJTW9kdWxlVHlwZSBtb2R1bGVUeXBlLCBJTW9kdWxlVHlwZSBtdCkgewoJCVN0cmluZyB0eXBlMiA9IG1vZHVsZVR5cGUuZ2V0SWQoKTsKCQlpZiAobWF0Y2hlcyhtdC5nZXRJZCgpLCB0eXBlMikpIHsKCQkJU3RyaW5nIHZlcnNpb24yID0gbW9kdWxlVHlwZS5nZXRWZXJzaW9uKCk7CgkJCWlmIChtYXRjaGVzKG10LmdldFZlcnNpb24oKSwgdmVyc2lvbjIpKQoJCQkJcmV0dXJuIHRydWU7CgkJfQoJCXJldHVybiBmYWxzZTsKCX0KCglwcm90ZWN0ZWQgc3RhdGljIGJvb2xlYW4gbWF0Y2hlcyhTdHJpbmcgYSwgU3RyaW5nIGIpIHsKCQlpZiAoYSA9PSBudWxsIHx8IGIgPT0gbnVsbCB8fCAiKiIuZXF1YWxzKGEpIHx8ICIqIi5lcXVhbHMoYikgfHwgYS5zdGFydHNXaXRoKGIpIHx8IGIuc3RhcnRzV2l0aChhKSkKCQkJcmV0dXJuIHRydWU7CgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogUmV0dXJuIGFsbCB0aGUgYXZhaWxhYmxlIG1vZHVsZXMgZnJvbSBhbGwgZmFjdG9yaWVzLgoJICogCgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgSU1vZHVsZVtdIGdldE1vZHVsZXMoKSB7CgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCQoJCU1vZHVsZUZhY3RvcnlbXSBmYWN0b3JpZXMgPSBTZXJ2ZXJDb3JlLmdldE1vZHVsZUZhY3RvcmllcygpOwoJCWlmIChmYWN0b3JpZXMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IGZhY3Rvcmllcy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlJTW9kdWxlW10gbW9kdWxlcyA9IGZhY3Rvcmllc1tpXS5nZXRNb2R1bGVzKCk7CgkJCQlpZiAobW9kdWxlcyAhPSBudWxsKSB7CgkJCQkJaW50IHNpemUyID0gbW9kdWxlcy5sZW5ndGg7CgkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCQkJCWlmICghbGlzdC5jb250YWlucyhtb2R1bGVzW2ldKSkKCQkJCQkJCWxpc3QuYWRkKG1vZHVsZXNbaV0pOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCQlJTW9kdWxlW10gbW9kdWxlcyA9IG5ldyBJTW9kdWxlW2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkobW9kdWxlcyk7CgkJcmV0dXJuIG1vZHVsZXM7Cgl9CgoJLyoqCgkgKiBBZGRzIG9yIHJlbW92ZXMgbW9kdWxlcyBmcm9tIGEgc2VydmVyLiBXaWxsIHNlYXJjaCBmb3IgdGhlIGZpcnN0IHBhcmVudCBtb2R1bGUKCSAqIG9mIGVhY2ggbW9kdWxlIGFuZCBhZGQgaXQgdG8gdGhlIHNlcnZlciBpbnN0ZWFkLiBUaGlzIG1ldGhvZCB3aWxsIGhhbmRsZSBtdWx0aXBsZQoJICogbW9kdWxlcyBoYXZpbmcgdGhlIHNhbWUgcGFyZW50ICh0aGUgcGFyZW50IHdpbGwgb25seSBiZSBhZGRlZCBvbmNlKSwgYnV0IG1heSBub3QKCSAqIGhhbmRsZSB0aGUgY2FzZSB3aGVyZSB0aGUgc2FtZSBtb2R1bGUgb3IgcGFyZW50IGlzIGJlaW5nIGJvdGggYWRkZWQgYW5kIHJlbW92ZWQuCgkgKiAKCSAqIEBwYXJhbSBzZXJ2ZXIKCSAqIEBwYXJhbSBhZGQKCSAqIEBwYXJhbSByZW1vdmUKCSAqIEBwYXJhbSBtb25pdG9yCgkgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24KCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIG1vZGlmeU1vZHVsZXMoSVNlcnZlcldvcmtpbmdDb3B5IHNlcnZlciwgSU1vZHVsZVtdIGFkZCwgSU1vZHVsZVtdIHJlbW92ZSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJaWYgKGFkZCA9PSBudWxsKQoJCQlhZGQgPSBuZXcgSU1vZHVsZVswXTsKCQlpZiAocmVtb3ZlID09IG51bGwpCgkJCXJlbW92ZSA9IG5ldyBJTW9kdWxlWzBdOwoJCQoJCWludCBzaXplID0gYWRkLmxlbmd0aDsKCQlMaXN0IGFkZFBhcmVudE1vZHVsZXMgPSBuZXcgQXJyYXlMaXN0KCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwoJCQl0cnkgewoJCQkJSU1vZHVsZVtdIHBhcmVudHMgPSBzZXJ2ZXIuZ2V0UGFyZW50TW9kdWxlcyhhZGRbaV0sIG1vbml0b3IpOwoJCQkJaWYgKHBhcmVudHMgIT0gbnVsbCkgewoJCQkJCWZvdW5kID0gdHJ1ZTsKCQkJCQlpZiAocGFyZW50cy5sZW5ndGggPiAwKSB7CQkJCQoJCQkJCQlPYmplY3QgcGFyZW50ID0gcGFyZW50c1swXTsKCQkJCQkJZm91bmQgPSB0cnVlOwoJCQkJCQlpZiAoIWFkZFBhcmVudE1vZHVsZXMuY29udGFpbnMocGFyZW50KSkKCQkJCQkJCWFkZFBhcmVudE1vZHVsZXMuYWRkKHBhcmVudCk7CgkJCQkJfQoJCQkJfSAKCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJDb3VsZCBub3QgZmluZCBwYXJlbnQgbW9kdWxlIiwgZSk7CgkJCX0KCQkJCgkJCWlmICghZm91bmQpCgkJCQlhZGRQYXJlbnRNb2R1bGVzLmFkZChhZGRbaV0pOwoJCX0KCQkKCQlzaXplID0gcmVtb3ZlLmxlbmd0aDsKCQlMaXN0IHJlbW92ZVBhcmVudE1vZHVsZXMgPSBuZXcgQXJyYXlMaXN0KCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwoJCQl0cnkgewoJCQkJSU1vZHVsZVtdIHBhcmVudHMgPSBzZXJ2ZXIuZ2V0UGFyZW50TW9kdWxlcyhyZW1vdmVbaV0sIG1vbml0b3IpOwoJCQkJaWYgKHBhcmVudHMgIT0gbnVsbCkgewoJCQkJCWZvdW5kID0gdHJ1ZTsKCQkJCQlpZiAocGFyZW50cy5sZW5ndGggPiAwKSB7CQkJCQoJCQkJCQlPYmplY3QgcGFyZW50ID0gcGFyZW50c1swXTsKCQkJCQkJZm91bmQgPSB0cnVlOwoJCQkJCQlpZiAoIXJlbW92ZVBhcmVudE1vZHVsZXMuY29udGFpbnMocGFyZW50KSkKCQkJCQkJCXJlbW92ZVBhcmVudE1vZHVsZXMuYWRkKHBhcmVudCk7CgkJCQkJfQoJCQkJfSAKCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJDb3VsZCBub3QgZmluZCBwYXJlbnQgbW9kdWxlIDIiLCBlKTsKCQkJfQoJCQkKCQkJaWYgKCFmb3VuZCkKCQkJCXJlbW92ZVBhcmVudE1vZHVsZXMuYWRkKHJlbW92ZVtpXSk7CgkJfQoJCQoJCUlNb2R1bGVbXSBhZGQyID0gbmV3IElNb2R1bGVbYWRkUGFyZW50TW9kdWxlcy5zaXplKCldOwoJCWFkZFBhcmVudE1vZHVsZXMudG9BcnJheShhZGQyKTsKCQlJTW9kdWxlW10gcmVtb3ZlMiA9IG5ldyBJTW9kdWxlW3JlbW92ZVBhcmVudE1vZHVsZXMuc2l6ZSgpXTsKCQlyZW1vdmVQYXJlbnRNb2R1bGVzLnRvQXJyYXkocmVtb3ZlMik7CgkJCgkJc2VydmVyLm1vZGlmeU1vZHVsZXMoYWRkMiwgcmVtb3ZlMiwgbW9uaXRvcik7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNlcnZlciBpcyBhbHJlYWR5IHN0YXJ0ZWQgaW4gdGhlIGdpdmVuCgkgKiBtb2RlLCBvciBjb3VsZCBiZSAocmUpc3RhcnRlZCBpbiB0aGUgc3RhcnQgbW9kZS4KCSAqIAoJICogQHBhcmFtIHNlcnZlciBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlcgoJICogQHBhcmFtIGxhdW5jaE1vZGUgamF2YS5sYW5nLlN0cmluZwoJICogQHJldHVybiBib29sZWFuCgkgKi8KCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0NvbXBhdGlibGVXaXRoTGF1bmNoTW9kZShJU2VydmVyIHNlcnZlciwgU3RyaW5nIGxhdW5jaE1vZGUpIHsKCQlpZiAoc2VydmVyID09IG51bGwgfHwgbGF1bmNoTW9kZSA9PSBudWxsKQoJCQlyZXR1cm4gZmFsc2U7CgoJCWludCBzdGF0ZSA9IHNlcnZlci5nZXRTZXJ2ZXJTdGF0ZSgpOwoJCWlmIChzdGF0ZSA9PSBJU2VydmVyLlNUQVRFX1NUQVJURUQgJiYgbGF1bmNoTW9kZS5lcXVhbHMoc2VydmVyLmdldE1vZGUoKSkpCgkJCXJldHVybiB0cnVlOwoKCQlpZiAoc2VydmVyLmdldFNlcnZlclR5cGUoKS5zdXBwb3J0c0xhdW5jaE1vZGUobGF1bmNoTW9kZSkpCgkJCXJldHVybiB0cnVlOwoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIEZpbHRlcnMgdGhlIHNlcnZlcnMgdG8gdGhvc2UgdGhhdCBhcmUgYWxyZWFkeSBzdGFydGVkIGluIHRoZSBnaXZlbiBsYXVuY2hNb2RlCgkgKiBvciBjYW4gYmUgKHJlKXN0YXJ0ZWQgaW4gdGhlIGdpdmVuIGxhdW5jaE1vZGUuCgkgKiAKCSAqIEBwYXJhbSBzZXJ2ZXIgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJbXQoJICogQHBhcmFtIGxhdW5jaE1vZGUgamF2YS5sYW5nLlN0cmluZwoJICogQHJldHVybiBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlcltdCgkgKi8KCS8qcHVibGljIHN0YXRpYyBJU2VydmVyW10gZmlsdGVyU2VydmVyc0J5TGF1bmNoTW9kZShJU2VydmVyW10gc2VydmVycywgU3RyaW5nIGxhdW5jaE1vZGUpIHsKCQlpZiAoc2VydmVycyA9PSBudWxsIHx8IHNlcnZlcnMubGVuZ3RoID09IDApCgkJCXJldHVybiBzZXJ2ZXJzOwoJCQoJCWludCBzaXplID0gc2VydmVycy5sZW5ndGg7CgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCWlmIChpc0NvbXBhdGlibGVXaXRoTGF1bmNoTW9kZShzZXJ2ZXJzW2ldLCBsYXVuY2hNb2RlKSkKCQkJCWxpc3QuYWRkKHNlcnZlcnNbaV0pOwoJCX0KCQlJU2VydmVyW10gdGVtcCA9IG5ldyBJU2VydmVyW2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkodGVtcCk7CgkJcmV0dXJuIHRlbXA7Cgl9Ki8KCgkvKioKCSAqIFZpc2l0IGFsbCB0aGUgbW9kdWxlcyBpbiB0aGUgc2VydmVyIGNvbmZpZ3VyYXRpb24uCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCB2aXNpdChJU2VydmVyQXR0cmlidXRlcyBzZXJ2ZXIsIElNb2R1bGVWaXNpdG9yIHZpc2l0b3IsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCWlmIChzZXJ2ZXIgPT0gbnVsbCkKCQkJcmV0dXJuOwoJCQoJCUlNb2R1bGVbXSBtb2R1bGVzID0gc2VydmVyLmdldE1vZHVsZXMobW9uaXRvcik7CgkJaWYgKG1vZHVsZXMgIT0gbnVsbCkgeyAKCQkJaW50IHNpemUgPSBtb2R1bGVzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCWlmICghdmlzaXRNb2R1bGUoc2VydmVyLCBuZXcgSU1vZHVsZVswXSwgbW9kdWxlc1tpXSwgdmlzaXRvciwgbW9uaXRvcikpCgkJCQkJcmV0dXJuOwoJCQl9CgkJfQoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIHRvIGtlZXAgdmlzaXRpbmcsIGFuZCBmYWxzZSB0byBzdG9wLgoJICovCglwcml2YXRlIHN0YXRpYyBib29sZWFuIHZpc2l0TW9kdWxlKElTZXJ2ZXJBdHRyaWJ1dGVzIHNlcnZlciwgSU1vZHVsZVtdIHBhcmVudHMsIElNb2R1bGUgbW9kdWxlLCBJTW9kdWxlVmlzaXRvciB2aXNpdG9yLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlpZiAoc2VydmVyID09IG51bGwgfHwgbW9kdWxlID09IG51bGwgfHwgcGFyZW50cyA9PSBudWxsKQoJCQlyZXR1cm4gdHJ1ZTsKCQkKCQlpZiAoIXZpc2l0b3IudmlzaXQocGFyZW50cywgbW9kdWxlKSkKCQkJcmV0dXJuIGZhbHNlOwoJCQoJCUlNb2R1bGVbXSBjaGlsZHJlbiA9IHNlcnZlci5nZXRDaGlsZE1vZHVsZXMobW9kdWxlLCBtb25pdG9yKTsKCQlpZiAoY2hpbGRyZW4gIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IGNoaWxkcmVuLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCUlNb2R1bGUgbW9kdWxlMiA9IGNoaWxkcmVuW2ldOwoJCQkJSU1vZHVsZVtdIHBhcmVudHMyID0gbmV3IElNb2R1bGVbcGFyZW50cy5sZW5ndGggKyAxXTsKCQkJCVN5c3RlbS5hcnJheWNvcHkocGFyZW50cywgMCwgcGFyZW50czIsIDAsIHBhcmVudHMubGVuZ3RoKTsKCQkJCXBhcmVudHMyW3BhcmVudHMubGVuZ3RoXSA9IG1vZHVsZTsKCQkJCQoJCQkJaWYgKCF2aXNpdE1vZHVsZShzZXJ2ZXIsIHBhcmVudHMyLCBtb2R1bGUyLCB2aXNpdG9yLCBtb25pdG9yKSkKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9CgkJCQoJCXJldHVybiB0cnVlOwoJfQoKCXB1YmxpYyBzdGF0aWMgdm9pZCBzZXRSdW50aW1lRGVmYXVsdE5hbWUoSVJ1bnRpbWVXb3JraW5nQ29weSB3YykgewoJCVN0cmluZyB0eXBlTmFtZSA9IHdjLmdldFJ1bnRpbWVUeXBlKCkuZ2V0TmFtZSgpOwoJCQoJCVN0cmluZyBuYW1lID0gU2VydmVyUGx1Z2luLmdldFJlc291cmNlKCIlZGVmYXVsdFJ1bnRpbWVOYW1lIiwgbmV3IFN0cmluZ1tdIHt0eXBlTmFtZX0pOwoJCWludCBpID0gMjsKCQl3aGlsZSAoaXNOYW1lSW5Vc2UobmFtZSkpIHsKCQkJbmFtZSA9IFNlcnZlclBsdWdpbi5nZXRSZXNvdXJjZSgiJWRlZmF1bHRSdW50aW1lTmFtZTIiLCBuZXcgU3RyaW5nW10ge3R5cGVOYW1lLCBpICsgIiJ9KTsKCQkJaSsrOwoJCX0KCQl3Yy5zZXROYW1lKG5hbWUpOwoJfQoKCXB1YmxpYyBzdGF0aWMgdm9pZCBzZXRTZXJ2ZXJEZWZhdWx0TmFtZShJU2VydmVyV29ya2luZ0NvcHkgd2MpIHsKCQlTdHJpbmcgdHlwZU5hbWUgPSB3Yy5nZXRTZXJ2ZXJUeXBlKCkuZ2V0TmFtZSgpOwoJCVN0cmluZyBob3N0ID0gd2MuZ2V0SG9zdCgpOwoJCQoJCVN0cmluZyBuYW1lID0gU2VydmVyUGx1Z2luLmdldFJlc291cmNlKCIlZGVmYXVsdFNlcnZlck5hbWUiLCBuZXcgU3RyaW5nW10ge3R5cGVOYW1lLCBob3N0fSk7CgkJaW50IGkgPSAyOwoJCXdoaWxlIChpc05hbWVJblVzZShuYW1lKSkgewoJCQluYW1lID0gU2VydmVyUGx1Z2luLmdldFJlc291cmNlKCIlZGVmYXVsdFNlcnZlck5hbWUyIiwgbmV3IFN0cmluZ1tdIHt0eXBlTmFtZSwgaG9zdCwgaSArICIifSk7CgkJCWkrKzsKCQl9CgkJd2Muc2V0TmFtZShuYW1lKTsKCX0KCglwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzVmFsaWRGaWxlbmFtZShTdHJpbmcgbmFtZSkgewoJCUlTdGF0dXMgc3RhdHVzID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLnZhbGlkYXRlTmFtZShuYW1lLCBJUmVzb3VyY2UuRklMRSk7CgkJaWYgKHN0YXR1cyAhPSBudWxsICYmICFzdGF0dXMuaXNPSygpKQoJCQlyZXR1cm4gZmFsc2U7CgkJCgkJc3RhdHVzID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLnZhbGlkYXRlTmFtZShuYW1lLCBJUmVzb3VyY2UuRk9MREVSKTsKCQlpZiAoc3RhdHVzICE9IG51bGwgJiYgIXN0YXR1cy5pc09LKCkpCgkJCXJldHVybiBmYWxzZTsKCQkKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0VmFsaWRGaWxlTmFtZShTdHJpbmcgbmFtZSkgewoJCWlmIChpc1ZhbGlkRmlsZW5hbWUobmFtZSkpCgkJCXJldHVybiBuYW1lOwoJCgkJLy8gcmVtb3ZlIGludmFsaWQgY2hhcmFjdGVycwoJCVN0cmluZ1tdIHMgPSBuZXcgU3RyaW5nW10geyIuIiwgIlxcIiwgIi8iLCAiPyIsICI6IiwgIioiLCAiXCIiLCAifCIsICI8IiwgIj4ifTsKCQlpbnQgaW5kID0gMDsKCQl3aGlsZSAoaW5kIDwgcy5sZW5ndGgpIHsKCQkJaW50IGluZGV4ID0gbmFtZS5pbmRleE9mKHNbaW5kXSk7CgkJCXdoaWxlIChpbmRleCA+PSAwKSB7CgkJCQluYW1lID0gbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpICsgbmFtZS5zdWJzdHJpbmcoaW5kZXgrMSk7CgkJCQlpbmRleCA9IG5hbWUuaW5kZXhPZihzW2luZF0pOwoJCQl9CgkJCWluZCsrOwoJCX0KCQlyZXR1cm4gbmFtZTsKCX0KCglwdWJsaWMgc3RhdGljIElGaWxlIGdldFVudXNlZFNlcnZlckZpbGUoSVByb2plY3QgcHJvamVjdCwgSVNlcnZlclR5cGUgdHlwZSkgewoJCVN0cmluZyB0eXBlTmFtZSA9IGdldFZhbGlkRmlsZU5hbWUodHlwZS5nZXROYW1lKCkpOwoJCVN0cmluZyBuYW1lID0gU2VydmVyUGx1Z2luLmdldFJlc291cmNlKCIlZGVmYXVsdFNlcnZlck5hbWUzIiwgbmV3IFN0cmluZ1tdIHt0eXBlTmFtZX0pKyAiLiIgICsgSVNlcnZlci5GSUxFX0VYVEVOU0lPTjsKCQlpbnQgaSA9IDI7CgkJd2hpbGUgKGlzRmlsZU5hbWVJblVzZShwcm9qZWN0LCBuYW1lKSkgewoJCQluYW1lID0gU2VydmVyUGx1Z2luLmdldFJlc291cmNlKCIlZGVmYXVsdFNlcnZlck5hbWU0IiwgbmV3IFN0cmluZ1tdIHt0eXBlTmFtZSwgaSArICIifSkgKyAiLiIgICsgSVNlcnZlci5GSUxFX0VYVEVOU0lPTjsKCQkJaSsrOwoJCX0KCQlyZXR1cm4gcHJvamVjdC5nZXRGaWxlKG5hbWUpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIGFuIGVsZW1lbnQgZXhpc3RzIHdpdGggdGhlIGdpdmVuIG5hbWUuCgkgKgoJICogQHBhcmFtIG5hbWUgamF2YS5sYW5nLlN0cmluZwoJICogQHJldHVybiBib29sZWFuCgkgKi8KCXByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNOYW1lSW5Vc2UoU3RyaW5nIG5hbWUpIHsKCQlpZiAobmFtZSA9PSBudWxsKQoJCQlyZXR1cm4gdHJ1ZTsKCQoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQkKCQlhZGRBbGwobGlzdCwgU2VydmVyQ29yZS5nZXRSdW50aW1lcygpKTsKCQlhZGRBbGwobGlzdCwgU2VydmVyQ29yZS5nZXRTZXJ2ZXJzKCkpOwoKCQlJdGVyYXRvciBpdGVyYXRvciA9IGxpc3QuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlFbGVtZW50IGVsZW1lbnQgPSAoSUVsZW1lbnQpIGl0ZXJhdG9yLm5leHQoKTsKCQkJaWYgKG5hbWUuZXF1YWxzSWdub3JlQ2FzZShlbGVtZW50LmdldE5hbWUoKSkpCgkJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCQoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBhZGRBbGwoTGlzdCBsaXN0LCBPYmplY3RbXSBvYmopIHsKCQlpZiAob2JqID09IG51bGwpCgkJCXJldHVybjsKCQkKCQlpbnQgc2l6ZSA9IG9iai5sZW5ndGg7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJbGlzdC5hZGQob2JqW2ldKTsKCQl9Cgl9CgkKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIGFuIGVsZW1lbnQgZXhpc3RzIHdpdGggdGhlIGdpdmVuIG5hbWUuCgkgKgoJICogQHBhcmFtIG5hbWUgamF2YS5sYW5nLlN0cmluZwoJICogQHJldHVybiBib29sZWFuCgkgKi8KCXByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNGaWxlTmFtZUluVXNlKElQcm9qZWN0IHByb2plY3QsIFN0cmluZyBuYW1lKSB7CgkJaWYgKG5hbWUgPT0gbnVsbCB8fCBwcm9qZWN0ID09IG51bGwpCgkJCXJldHVybiBmYWxzZTsKCQkKCQlpZiAocHJvamVjdC5nZXRGaWxlKG5hbWUpLmV4aXN0cygpKQoJCQlyZXR1cm4gdHJ1ZTsKCQlpZiAocHJvamVjdC5nZXRGb2xkZXIobmFtZSkuZXhpc3RzKCkpCgkJCXJldHVybiB0cnVlOwoJCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogUmV0dXJuIGEgbGlzdCBvZiBhbGwgcnVudGltZSB0YXJnZXRzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIHR5cGUgYW5kIHZlcnNpb24uCgkgKiBJZiB0eXBlIG9yIHZlcnNpb24gaXMgbnVsbCwgaXQgbWF0Y2hlcyBhbGwgb2YgdGhhdCB0eXBlIG9yIHZlcnNpb24uCgkgKiAKCSAqIEBwYXJhbSB0eXBlCgkgKiBAcGFyYW0gdmVyc2lvbgoJICogQHJldHVybiAKCSAqLwoJcHVibGljIHN0YXRpYyBJUnVudGltZVtdIGdldFJ1bnRpbWVzKFN0cmluZyB0eXBlLCBTdHJpbmcgdmVyc2lvbikgewoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQlJUnVudGltZVtdIHJ1bnRpbWVzID0gU2VydmVyQ29yZS5nZXRSdW50aW1lcygpOwoJCWlmIChydW50aW1lcyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gcnVudGltZXMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJSVJ1bnRpbWVUeXBlIHJ1bnRpbWVUeXBlID0gcnVudGltZXNbaV0uZ2V0UnVudGltZVR5cGUoKTsKCQkJCWlmIChydW50aW1lVHlwZSAhPSBudWxsICYmIGlzU3VwcG9ydGVkTW9kdWxlKHJ1bnRpbWVUeXBlLmdldE1vZHVsZVR5cGVzKCksIHR5cGUsIHZlcnNpb24pKSB7CgkJCQkJbGlzdC5hZGQocnVudGltZXNbaV0pOwoJCQkJfQoJCQl9CgkJfQoJCQoJCUlSdW50aW1lW10gcnVudGltZXMyID0gbmV3IElSdW50aW1lW2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkocnVudGltZXMyKTsKCQlyZXR1cm4gcnVudGltZXMyOwoJfQoKCS8qKgoJICogUmV0dXJuIGEgbGlzdCBvZiBhbGwgcnVudGltZSB0eXBlcyB0aGF0IG1hdGNoIHRoZSBnaXZlbiB0eXBlIGFuZCB2ZXJzaW9uLgoJICogSWYgdHlwZSBvciB2ZXJzaW9uIGlzIG51bGwsIGl0IG1hdGNoZXMgYWxsIG9mIHRoYXQgdHlwZSBvciB2ZXJzaW9uLgoJICogCgkgKiBAcGFyYW0gdHlwZQoJICogQHBhcmFtIHZlcnNpb24KCSAqIEByZXR1cm4gCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVJ1bnRpbWVUeXBlW10gZ2V0UnVudGltZVR5cGVzKFN0cmluZyB0eXBlLCBTdHJpbmcgdmVyc2lvbikgewoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQlJUnVudGltZVR5cGVbXSBydW50aW1lVHlwZXMgPSBTZXJ2ZXJDb3JlLmdldFJ1bnRpbWVUeXBlcygpOwoJCWlmIChydW50aW1lVHlwZXMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHJ1bnRpbWVUeXBlcy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlpZiAoaXNTdXBwb3J0ZWRNb2R1bGUocnVudGltZVR5cGVzW2ldLmdldE1vZHVsZVR5cGVzKCksIHR5cGUsIHZlcnNpb24pKSB7CgkJCQkJbGlzdC5hZGQocnVudGltZVR5cGVzW2ldKTsKCQkJCX0KCQkJfQoJCX0KCQkKCQlJUnVudGltZVR5cGVbXSBydCA9IG5ldyBJUnVudGltZVR5cGVbbGlzdC5zaXplKCldOwoJCWxpc3QudG9BcnJheShydCk7CgkJcmV0dXJuIHJ0OwoJfQoJCgkvKioKCSAqIFJldHVybiBhIGxpc3Qgb2YgYWxsIHJ1bnRpbWUgdHlwZXMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gdHlwZSwgdmVyc2lvbiwKCSAqIGFuZCBwYXJ0aWFsIHJ1bnRpbWUgdHlwZSBpZC4gSWYgdHlwZSwgdmVyc2lvbiwgb3IgcnVudGltZVR5cGVJZCBpcyBudWxsLAoJICogaXQgbWF0Y2hlcyBhbGwgb2YgdGhhdCB0eXBlIG9yIHZlcnNpb24uCgkgKiAKCSAqIEBwYXJhbSB0eXBlCgkgKiBAcGFyYW0gdmVyc2lvbgoJICogQHJldHVybiAKCSAqLwoJcHVibGljIHN0YXRpYyBJUnVudGltZVR5cGVbXSBnZXRSdW50aW1lVHlwZXMoU3RyaW5nIHR5cGUsIFN0cmluZyB2ZXJzaW9uLCBTdHJpbmcgcnVudGltZVR5cGVJZCkgewoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQlJUnVudGltZVR5cGVbXSBydW50aW1lVHlwZXMgPSBTZXJ2ZXJDb3JlLmdldFJ1bnRpbWVUeXBlcygpOwoJCWlmIChydW50aW1lVHlwZXMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHJ1bnRpbWVUeXBlcy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlpZiAoaXNTdXBwb3J0ZWRNb2R1bGUocnVudGltZVR5cGVzW2ldLmdldE1vZHVsZVR5cGVzKCksIHR5cGUsIHZlcnNpb24pKSB7CgkJCQkJaWYgKHJ1bnRpbWVUeXBlSWQgPT0gbnVsbCB8fCBydW50aW1lVHlwZXNbaV0uZ2V0SWQoKS5zdGFydHNXaXRoKHJ1bnRpbWVUeXBlSWQpKQoJCQkJCQlsaXN0LmFkZChydW50aW1lVHlwZXNbaV0pOwoJCQkJfQoJCQl9CgkJfQoJCQoJCUlSdW50aW1lVHlwZVtdIHJ0ID0gbmV3IElSdW50aW1lVHlwZVtsaXN0LnNpemUoKV07CgkJbGlzdC50b0FycmF5KHJ0KTsKCQlyZXR1cm4gcnQ7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgc2VydmVycyB0aGF0IHRoaXMgZGVwbG95YWJsZSBpcyBub3QgY3VycmVudGx5CgkgKiBjb25maWd1cmVkIG9uLCBidXQgY291bGQgYmUgYWRkZWQgdG8uIElmIGluY2x1ZGVFcnJvcnMgaXMgdHJ1ZSwgdGhpcwoJICogbWV0aG9kIHJldHVybiBzZXJ2ZXJzIHdoZXJlIHRoZSBwYXJlbnQgZGVwbG95YWJsZSBtYXkgdGhyb3cgZXJyb3JzLiBGb3IKCSAqIGluc3RhbmNlLCB0aGlzIGRlcGxveWFibGUgbWF5IGJlIHRoZSB3cm9uZyBzcGVjIGxldmVsLgoJICoKCSAqIEBwYXJhbSBtb2R1bGUgY29tLmlibS5ldG9vbHMuc2VydmVyLmNvcmUuSU1vZHVsZQoJICogQHJldHVybiBjb20uaWJtLmV0b29scy5zZXJ2ZXIuY29yZS5JU2VydmVyW10KCSAqLwoJcHVibGljIHN0YXRpYyBJU2VydmVyW10gZ2V0QXZhaWxhYmxlU2VydmVyc0Zvck1vZHVsZShJTW9kdWxlIG1vZHVsZSwgYm9vbGVhbiBpbmNsdWRlRXJyb3JzLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlpZiAobW9kdWxlID09IG51bGwpCgkJCXJldHVybiBuZXcgSVNlcnZlclswXTsKCgkJLy8gZG8gaXQgdGhlIHNsb3cgd2F5IC0gZ28gdGhyb3VnaCBhbGwgc2VydmVycyBhbmQKCQkvLyBzZWUgaWYgdGhpcyBkZXBsb3lhYmxlIGlzIG5vdCBjb25maWd1cmVkIGluIGl0CgkJLy8gYnV0IGNvdWxkIGJlIGFkZGVkCgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCUlTZXJ2ZXJbXSBzZXJ2ZXJzID0gU2VydmVyQ29yZS5nZXRTZXJ2ZXJzKCk7CgkJaWYgKHNlcnZlcnMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHNlcnZlcnMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJaWYgKCFjb250YWluc01vZHVsZShzZXJ2ZXJzW2ldLCBtb2R1bGUsIG1vbml0b3IpKSB7CgkJCQkJdHJ5IHsKCQkJCQkJSU1vZHVsZVtdIHBhcmVudHMgPSBzZXJ2ZXJzW2ldLmdldFBhcmVudE1vZHVsZXMobW9kdWxlLCBtb25pdG9yKTsKCQkJCQkJaWYgKHBhcmVudHMgIT0gbnVsbCAmJiBwYXJlbnRzLmxlbmd0aCA+IDApIHsKCQkJCQkJCWJvb2xlYW4gZm91bmQgPSBmYWxzZTsKCQkJCQkJCWlmIChwYXJlbnRzICE9IG51bGwpIHsKCQkJCQkJCQlpbnQgc2l6ZTIgPSBwYXJlbnRzLmxlbmd0aDsKCQkJCQkJCQlmb3IgKGludCBqID0gMDsgIWZvdW5kICYmIGogPCBzaXplMjsgaisrKSB7CgkJCQkJCQkJCUlNb2R1bGUgcGFyZW50ID0gcGFyZW50c1tqXTsKCQkJCQkJCQkJSVN0YXR1cyBzdGF0dXMgPSBzZXJ2ZXJzW2ldLmNhbk1vZGlmeU1vZHVsZXMobmV3IElNb2R1bGVbXSB7IHBhcmVudCB9LCBuZXcgSU1vZHVsZVswXSwgbW9uaXRvcik7CgkJCQkJCQkJCWlmIChzdGF0dXMgPT0gbnVsbCB8fCBzdGF0dXMuaXNPSygpKXsKCQkJCQkJCQkJCWxpc3QuYWRkKHNlcnZlcnNbaV0pOwoJCQkJCQkJCQkJZm91bmQgPSB0cnVlOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIHNlKSB7CgkJCQkJCWlmIChpbmNsdWRlRXJyb3JzKQoJCQkJCQkJbGlzdC5hZGQoc2VydmVyc1tpXSk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJCQoJCS8vIG1ha2Ugc3VyZSB0aGF0IHRoZSBwcmVmZXJyZWQgc2VydmVyIGlzIHRoZSBmaXJzdCBvbmUKCQkvL0lTZXJ2ZXIgc2VydmVyID0gU2VydmVyQ29yZS5nZXRTZXJ2ZXJQcmVmZXJlbmNlcygpLmdldERlcGxveWFibGVTZXJ2ZXJQcmVmZXJlbmNlKGRlcGxveWFibGUpOwoJCS8vaWYgKHNlcnZlciAhPSBudWxsICYmIGxpc3QuY29udGFpbnMoc2VydmVyKSAmJiBsaXN0LmluZGV4T2Yoc2VydmVyKSAhPSAwKSB7CgkJLy8JbGlzdC5yZW1vdmUoc2VydmVyKTsKCQkvLwlsaXN0LmFkZCgwLCBzZXJ2ZXIpOwoJCS8vfQoKCQlJU2VydmVyW10gYWxsU2VydmVycyA9IG5ldyBJU2VydmVyW2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkoYWxsU2VydmVycyk7CgkJcmV0dXJuIGFsbFNlcnZlcnM7Cgl9CgoJLypwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNEZWZhdWx0QXZhaWxhYmxlKElTZXJ2ZXJUeXBlIHNlcnZlclR5cGUsIElNb2R1bGVUeXBlIG1vZHVsZVR5cGUpIHsKCQlpZiAoIWlzU3VwcG9ydGVkTW9kdWxlKHNlcnZlclR5cGUsIG1vZHVsZVR5cGUpKQoJCQlyZXR1cm4gZmFsc2U7CgkKCQkvLyByZW1vdGUgc2VydmVycyB3b24ndCBhdXRvbWF0aWNhbGx5IHdvcmsgKGkuZS4gd2l0aG91dCBob3N0bmFtZSkKCQlpZiAoIXNlcnZlclR5cGUuc3VwcG9ydHNMb2NhbGhvc3QoKSkKCQkJcmV0dXJuIGZhbHNlOwoJCQoJCS8vIGlmIGl0IG5lZWRzIGEgcnVudGltZSwgY2hlY2sgaWYgdGhlcmUgaXMgb25lCgkJaWYgKHNlcnZlclR5cGUuaGFzUnVudGltZSgpKSB7CgkJCUlSdW50aW1lW10gcnVudGltZXMgPSBTZXJ2ZXJDb3JlLmdldFJlc291cmNlTWFuYWdlcigpLmdldFJ1bnRpbWVzKHNlcnZlclR5cGUuZ2V0UnVudGltZVR5cGUoKSk7CgkJCWlmIChydW50aW1lcyA9PSBudWxsIHx8IHJ1bnRpbWVzLmxlbmd0aCA9PSAwKQoJCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0qLwoJCgkvKioKCSAqIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIGtub3duIHJ1bnRpbWUgaW5zdGFuY2VzIG9mCgkgKiB0aGUgZ2l2ZW4gcnVudGltZSB0eXBlLiBUaGlzIGNvbnZlbmllbmNlIG1ldGhvZCBmaWx0ZXJzIHRoZSBsaXN0IG9mIGtub3duCgkgKiBydW50aW1lICh7QGxpbmsgI2dldFJ1bnRpbWVzKCl9KSBmb3Igb25lcyB3aXRoIGEgbWF0Y2hpbmcKCSAqIHJ1bnRpbWUgdHlwZSAoe0BsaW5rIElSdW50aW1lI2dldFJ1bnRpbWVUeXBlKCl9KS4gVGhlIGFycmF5IHdpbGwgbm90CgkgKiBjb250YWluIGFueSB3b3JraW5nIGNvcGllcy4KCSAqIDxwPgoJICogQSBuZXcgYXJyYXkgaXMgcmV0dXJuZWQgb24gZWFjaCBjYWxsLCBzbyBjbGllbnRzIG1heSBzdG9yZSBvciBtb2RpZnkgdGhlIHJlc3VsdC4KCSAqIDwvcD4KCSAqIDxwPgoJICogW2lzc3VlOiBJcyB0aGlzIGNvbnZlbmllbmNlIG1ldGhvZCByZWFsbHkgbmVjZXNzYXJ5PwoJICogSXQncyBzdHJhaWdodGZvcndhcmQgZW5vdWdoIGZvciBhIGNsaWVudCB0byBkby5dCgkgKiA8L3A+CgkgKiAKCSAqIEBwYXJhbSBydW50aW1lVHlwZSB0aGUgcnVudGltZSB0eXBlCgkgKiBAcmV0dXJuIGEgcG9zc2libHktZW1wdHkgbGlzdCBvZiBydW50aW1lIGluc3RhbmNlcyB7QGxpbmsgSVJ1bnRpbWV9CgkgKiBvZiB0aGUgZ2l2ZW4gcnVudGltZSB0eXBlCgkgKi8KCXB1YmxpYyBzdGF0aWMgSVJ1bnRpbWVbXSBnZXRSdW50aW1lcyhJUnVudGltZVR5cGUgcnVudGltZVR5cGUpIHsKCQlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJSVJ1bnRpbWVbXSBydW50aW1lcyA9IFNlcnZlckNvcmUuZ2V0UnVudGltZXMoKTsKCQlpZiAocnVudGltZXMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHJ1bnRpbWVzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCWlmIChydW50aW1lc1tpXS5nZXRSdW50aW1lVHlwZSgpICE9IG51bGwgJiYgcnVudGltZXNbaV0uZ2V0UnVudGltZVR5cGUoKS5lcXVhbHMocnVudGltZVR5cGUpKQoJCQkJCWxpc3QuYWRkKHJ1bnRpbWVzW2ldKTsKCQkJfQoJCX0KCQkKCQlJUnVudGltZVtdIHIgPSBuZXcgSVJ1bnRpbWVbbGlzdC5zaXplKCldOwoJCWxpc3QudG9BcnJheShyKTsKCQlyZXR1cm4gcjsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBzZXJ2ZXIgdGhhdCBjYW1lIGZyb20gdGhlIGdpdmVuIGZpbGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+CgkgKiBpZiBub25lLiBUaGlzIGNvbnZlbmllbmNlIG1ldGhvZCBzZWFyY2hlcyB0aGUgbGlzdCBvZiBrbm93bgoJICogc2VydmVycyAoe0BsaW5rICNnZXRTZXJ2ZXJzKCl9KSBmb3IgdGhlIG9uZSB3aXRoIGEgbWF0Y2hpbmcKCSAqIGxvY2F0aW9uICh7QGxpbmsgSVNlcnZlciNnZXRGaWxlKCl9KS4gVGhlIGZpbGUgbWF5IG5vdCBiZSBudWxsLgoJICogPHA+CgkgKiBbaXNzdWU6IElzIHRoaXMgY29udmVuaWVuY2UgbWV0aG9kIHJlYWxseSBuZWNlc3Nhcnk/CgkgKiBJdCdzIHN0cmFpZ2h0Zm9yd2FyZCBlbm91Z2ggZm9yIGEgY2xpZW50IHRvIGRvLl0KCSAqIDwvcD4KCSAqCgkgKiBAcGFyYW0gYSBzZXJ2ZXIgZmlsZQoJICogQHJldHVybiB0aGUgc2VydmVyIGluc3RhbmNlLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiAKCSAqIHRoZXJlIGlzIG5vIHNlcnZlciBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIGZpbGUKCSAqLwoJcHVibGljIHN0YXRpYyBJU2VydmVyIGZpbmRTZXJ2ZXIoSUZpbGUgZmlsZSkgewoJCWlmIChmaWxlID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCQkKCQlJU2VydmVyW10gc2VydmVycyA9IFNlcnZlckNvcmUuZ2V0U2VydmVycygpOwoJCWlmIChzZXJ2ZXJzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBzZXJ2ZXJzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCWlmIChmaWxlLmVxdWFscyhzZXJ2ZXJzW2ldLmdldEZpbGUoKSkpCgkJCQkJcmV0dXJuIHNlcnZlcnNbaV07CgkJCX0KCQl9CgkJcmV0dXJuIG51bGw7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBrbm93biBzZXJ2ZXIgaW5zdGFuY2VzIG9mCgkgKiB0aGUgZ2l2ZW4gc2VydmVyIHR5cGUuIFRoaXMgY29udmVuaWVuY2UgbWV0aG9kIGZpbHRlcnMgdGhlIGxpc3Qgb2Yga25vd24KCSAqIHNlcnZlcnMgKHtAbGluayAjZ2V0U2VydmVycygpfSkgZm9yIG9uZXMgd2l0aCBhIG1hdGNoaW5nCgkgKiBzZXJ2ZXIgdHlwZSAoe0BsaW5rIElTZXJ2ZXIjZ2V0U2VydmVyVHlwZSgpfSkuIFRoZSBhcnJheSB3aWxsIG5vdCBjb250YWluCgkgKiBhbnkgd29ya2luZyBjb3BpZXMuCgkgKiA8cD4KCSAqIEEgbmV3IGFycmF5IGlzIHJldHVybmVkIG9uIGVhY2ggY2FsbCwgc28gY2xpZW50cyBtYXkgc3RvcmUgb3IgbW9kaWZ5IHRoZSByZXN1bHQuCgkgKiA8L3A+CgkgKiAKCSAqIEBwYXJhbSBzZXJ2ZXJUeXBlIHRoZSBzZXJ2ZXIgdHlwZQoJICogQHJldHVybiBhIHBvc3NpYmx5LWVtcHR5IGFycmF5IG9mIHNlcnZlciBpbnN0YW5jZXMge0BsaW5rIElTZXJ2ZXJ9CgkgKiBvZiB0aGUgZ2l2ZW4gc2VydmVyIHR5cGUKCSAqLwoJLypwdWJsaWMgc3RhdGljIElTZXJ2ZXJbXSBnZXRTZXJ2ZXJzKElTZXJ2ZXJUeXBlIHNlcnZlclR5cGUpIHsKCQlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJSVNlcnZlcltdIHNlcnZlcnMgPSBTZXJ2ZXJDb3JlLmdldFNlcnZlcnMoKTsKCQlpZiAoc2VydmVycyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gc2VydmVycy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlpZiAoc2VydmVyc1tpXS5nZXRTZXJ2ZXJUeXBlKCkuZXF1YWxzKHNlcnZlclR5cGUpKQoJCQkJCWxpc3QuYWRkKHNlcnZlcnNbaV0pOwoJCQl9CgkJfQoJCQoJCUlTZXJ2ZXJbXSBzID0gbmV3IElTZXJ2ZXJbbGlzdC5zaXplKCldOwoJCWxpc3QudG9BcnJheShzKTsKCQlyZXR1cm4gczsKCX0qLwp9