ZGlmZiAtLWdpdCBhL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9QZXJzaXN0ZW5jZU1hbmFnZXIuamF2YSBiL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9QZXJzaXN0ZW5jZU1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjRkZjQ0Ci0tLSAvZGV2L251bGwKKysrIGIvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL1BlcnNpc3RlbmNlTWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsMTIwIEBACisvKiAKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5mZWxpeC5jbTsKKworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRGljdGlvbmFyeTsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CisKKworLyoqCisgKiBUaGUgPGNvZGU+UGVyc2lzdGVuY2VNYW5hZ2VyPC9jb2RlPiBpbnRlcmZhY2UgZGVmaW5lcyB0aGUgQVBJIHRvIGJlCisgKiBpbXBsZW1lbnRlZCB0byBzdXBwb3J0IHBlcnNpc3RpbmcgY29uZmlndXJhdGlvbiBkYXRhLiBUaGlzIGludGVyZmFjZSBtYXkKKyAqIGJlIGltcGxlbWVudGVkIGJ5IGJ1bmRsZXMsIHdoaWNoIHN1cHBvcnQgc3RvcmluZyBjb25maWd1cmF0aW9uIGRhdGEgaW4KKyAqIGRpZmZlcmVudCBsb2NhdGlvbnMuCisgKiA8cD4KKyAqIFRoZSBBcGFjaGUgRmVsaXggQ29uZmlndXJhdGlvbiBBZG1pbiBTZXJ2aWNlIGJ1bmRsZXMgcHJvdmlkZXMgYW4KKyAqIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgaW50ZXJmYWNlIHVzaW5nIHRoZSBwbGF0Zm9ybSBmaWxlc3lzdGVtIHRvIHN0b3JlCisgKiBjb25maWd1cmF0aW9uIGRhdGEuCisgKiA8cD4KKyAqIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIGludGVyZmFjZSBtdXN0IHN1cHBvcnQgbG9hZGluZyBhbmQgc3RvcmluZworICogPGNvZGU+amF2YS51dGlsLkRpY3Rpb25hcnk8L2NvZGU+IG9iamVjdHMgYXMgZGVmaW5lZCBpbiBzZWN0aW9uIDEwNC40LjIsCisgKiBDb25maWd1cmF0aW9uIFByb3BlcnRpZXMsIG9mIHRoZSBDb25maWd1cmF0aW9uIEFkbWluIFNlcnZpY2UgU3BlY2lmaWNhdGlvbgorICogVmVyc2lvbiAxLjIuCisgKiA8cD4KKyAqIFRvIG1ha2UgaW1wbGVtZW50YXRpb25zIG9mIHRoaXMgaW50ZXJmYWNlIGF2YWlsYWJsZSB0byB0aGUgQ29uZmlndXJhdGlvbgorICogQWRtaW4gU2VydmljZSB0aGV5IG11c3QgYmUgcmVnaXN0ZXJlZCBhcyBzZXJ2aWNlIGZvciB0aGlzIGludGVyZmFjZS4gVGhlCisgKiBDb25maWd1cmF0aW9uIEFkbWluIFNlcnZpY2Ugd2lsbCBjb25zaWRlciBhbGwgcmVnaXN0ZXJlZCBzZXJ2aWNlcyBwbHVzIHRoZQorICogZGVmYXVsdCBwbGF0Zm9ybSBmaWxlIHN5c3RlbSBiYXNlZCBpbXBsZW1lbnRhdGlvbiB0byBsb2FkIGNvbmZpZ3VyYXRpb24gZGF0YS4KKyAqIFRvIHN0b3JlIG5ldyBjb25maWd1cmF0aW9uIGRhdGEsIHRoZSBwZXJzaXN0ZW5jZSBtYW5hZ2VyIHNlcnZpY2Ugd2l0aCB0aGUKKyAqIGhpZ2hlc3QgcmFuayB2YWx1ZSAtIHRoZSA8Y29kZT5zZXJ2aWNlLnJhbmtpbmc8L2NvZGU+IHNlcnZpY2UgcHJvcGVydHkgLSBpcworICogdXNlZC4gSWYgbm8gcGVzaXN0ZW5jZSBtYW5hZ2VyIHNlcnZpY2UgaGFzIGJlZW4gcmVnaXN0ZXJlZCwgdGhlIHBsYXRmcm9tCisgKiBmaWxlIHN5c3RlbSBiYXNlZCBpbXBsZW1lbnRhdGlvbiBpcyB1c2VkLgorICoKKyAqIEBhdXRob3IgZm1lc2NoYmUKKyAqLworcHVibGljIGludGVyZmFjZSBQZXJzaXN0ZW5jZU1hbmFnZXIKK3sKKworICAgIC8qKgorICAgICAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgYSBwZXJzaXN0ZWQgPGNvZGU+RGljdGlvbmFyeTwvY29kZT4gZXhpc3RzCisgICAgICogZm9yIHRoZSBnaXZlbiA8Y29kZT5waWQ8L2NvZGU+LiAKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGlkIFRoZSBpZGVudGlmaWVyIGZvciB0aGUgZGljdGlvbmFyeSB0byB0ZXN0LgorICAgICAqLworICAgIGJvb2xlYW4gZXhpc3RzKCBTdHJpbmcgcGlkICk7CisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgdGhlIDxjb2RlPkRpY3Rpb25hcnk8L2NvZGU+IGZvciB0aGUgZ2l2ZW4gPGNvZGU+cGlkPC9jb2RlPi4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGlkIFRoZSBpZGVudGlmaWVyIGZvciB0aGUgZGljdGlvbmFyeSB0byBsb2FkLgorICAgICAqIAorICAgICAqIEByZXR1cm4gVGhlIGRpY3Rpb25hcnkgZm9yIHRoZSBpZGVudGlmaWVyLiBUaGlzIG11c3Qgbm90IGJlCisgICAgICogICAgICA8Y29kZT5udWxsPC9jb2RlPiBidXQgbWF5IGJlIGVtcHR5LgorICAgICAqICAgICAgCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbiBlcnJvciBvY2N1cnJzIGxvYWRpbmcgdGhlIGRpY3Rpb25hcnkuIEFuCisgICAgICogICAgICA8Y29kZT5JT0V4Y2VwdGlvbjwvY29kZT4gbXVzdCBhbHNvIGJlIHRocm93biBpZiBubyBkaWN0aW9uYXJ5CisgICAgICogICAgICBleGlzdHMgZm9yIHRoZSBnaXZlbiBpZGVudGlmaWVyLiAKKyAgICAgKi8KKyAgICBEaWN0aW9uYXJ5IGxvYWQoIFN0cmluZyBwaWQgKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFJldHVybnMgYW4gZW51bWVyYXRpb24gb2YgYWxsIDxjb2RlPkRpY3Rpb25hcnk8L2NvZGU+IG9iamVjdHMga25vd24gdG8gCisgICAgICogdGhpcyBwZXJzaXN0ZW5jZSBtYW5hZ2VyLgorICAgICAqIDxwPgorICAgICAqIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIG1ldGhvZCBhcmUgYWxsb3dlZCB0byByZXR1cm4gbGF6eSBlbnVtZXJhdGlvbnMuCisgICAgICogVGhhdCBpcywgaXQgaXMgYWxsb3dhYmxlIGZvciB0aGUgZW51bWVyYXRpb24gdG8gbm90IHJldHVybiBhIGRpY3Rpb25hcnkKKyAgICAgKiBpZiBsb2FkaW5nIGl0IHJlc3VsdHMgaW4gYW4gZXJyb3IuCisgICAgICogCisgICAgICogQHJldHVybiBBIHBvc3NpYmx5IGVtcHR5IEVudW1lcmF0aW9uIG9mIGFsbCBkaWN0aW9uYXJpZXMuCisgICAgICogCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbiBlcnJvciBvY2N1cnJzIGdldHRpbmcgdGhlIGRpY3Rpb25hcmllcy4KKyAgICAgKi8KKyAgICBFbnVtZXJhdGlvbiBnZXREaWN0aW9uYXJpZXMoKSB0aHJvd3MgSU9FeGNlcHRpb247CisKKworICAgIC8qKgorICAgICAqIFN0b3JlcyB0aGUgPGNvZGU+RGljdGlvbmFyeTwvY29kZT4gdW5kZXIgdGhlIGdpdmVuIDxjb2RlPnBpZDwvY29kZT4uCisgICAgICogCisgICAgICogQHBhcmFtIHBpZCBUaGUgaWRlbnRpZmllciBvZiB0aGUgZGljdGlvbmFyeS4KKyAgICAgKiBAcGFyYW0gcHJvcGVydGllcyBUaGUgPGNvZGU+RGljdGlvbmFyeTwvY29kZT4gdG8gc3RvcmUuCisgICAgICogCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbiBlcnJvciBvY2N1cnJzIHN0b3JpbmcgdGhlIGRpY3Rpb25hcnkuIElmIHRoaXMKKyAgICAgKiAgICAgIGV4Y2VwdGlvbiBpcyB0aHJvd24sIGl0IGlzIGV4cGVjdGVkLCB0aGF0CisgICAgICogICAgICB7QGxpbmsgI2V4aXN0cyhTdHJpbmcpIGV4aXN0cyhwaWR9IHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+LgorICAgICAqLworICAgIHZvaWQgc3RvcmUoIFN0cmluZyBwaWQsIERpY3Rpb25hcnkgcHJvcGVydGllcyApIHRocm93cyBJT0V4Y2VwdGlvbjsKKworCisgICAgLyoqCisgICAgICogUmVtb3ZlcyB0aGUgPGNvZGU+RGljdGlvbmFyeTwvY29kZT4gZm9yIHRoZSBnaXZlbiA8Y29kZT5waWQ8L2NvZGU+LiBJZgorICAgICAqIHN1Y2ggYSBkaWN0aW9uYXJ5IGRvZXMgbm90IGV4aXN0LCB0aGlzIG1ldGhvZCBoYXMgbm8gZWZmZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwaWQgVGhlIGlkZW50aWZpZXIgb2YgdGhlIGRpY3Rpb25hcnkgdG8gZGVsZXQuCisgICAgICogCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbiBlcnJvciBvY2N1cnJzIGRlbGV0aW5nIHRoZSBkaWN0aW9uYXJ5LiBUaGlzCisgICAgICogICAgICBleGNlcHRpb24gbXVzdCBub3QgYmUgdGhyb3duIGlmIG5vIGRpY3Rpb25hcnkgd2l0aCB0aGUgZ2l2ZW4KKyAgICAgKiAgICAgIGlkZW50aWZpZXIgZXhpc3RzLgorICAgICAqLworICAgIHZvaWQgZGVsZXRlKCBTdHJpbmcgcGlkICkgdGhyb3dzIElPRXhjZXB0aW9uOworCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ZpbGUvQ29uZmlndXJhdGlvbkhhbmRsZXIuamF2YSBiL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9maWxlL0NvbmZpZ3VyYXRpb25IYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTY5OTJjZAotLS0gL2Rldi9udWxsCisrKyBiL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9maWxlL0NvbmZpZ3VyYXRpb25IYW5kbGVyLmphdmEKQEAgLTAsMCArMSw3OTYgQEAKKy8qIAorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmZlbGl4LmNtLmZpbGU7CisKKworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5CdWZmZXJlZFdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlB1c2hiYWNrUmVhZGVyOworaW1wb3J0IGphdmEuaW8uV3JpdGVyOworaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OworaW1wb3J0IGphdmEudXRpbC5CaXRTZXQ7CitpbXBvcnQgamF2YS51dGlsLkRpY3Rpb25hcnk7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKKworCisvKioKKyAqIFRoZSA8Y29kZT5Db25maWd1cmF0aW9uSGFuZGxlcjwvY29kZT4gY2xhc3MgaW1wbGVtZW50cyBjb25maWd1cmF0aW9uIHJlYWRpbmcKKyAqIGZvcm0gYSA8Y29kZT5qYXZhLmlvLklucHV0U3RyZWFtPC9jb2RlPiBhbmQgd3JpdGluZyB0byBhCisgKiA8Y29kZT5qYXZhLmlvLk91dHB1dFN0cmVhbTwvY29kZT4gb24gYmVoYWxmIG9mIHRoZQorICoge0BsaW5rIEZpbGVQZXJzaXN0ZW5jZU1hbmFnZXJ9IGNsYXNzLgorICogCisgKiA8cHJlPgorIGNmZyA9IHByb3AgIj0iIHZhbHVlIC4KKyBwcm9wID0gc3ltYm9saWMtbmFtZSAuIC8vIDEuNC4yIG9mIE9TR2kgQ29yZSBTcGVjaWZpY2F0aW9uCisgc3ltYm9saWMtbmFtZSA9IHRva2VuIHsgIi4iIHRva2VuIH0gLgorIHRva2VuID0geyBbIDAuLjkgXSB8IFsgYS4ueiBdIHwgWyBBLi5aIF0gfCAnXycgfCAnLScgfSAuCisgdmFsdWUgPSBbIHR5cGUgXSAoICJbIiB2YWx1ZXMgIl0iIHwgIigiIHZhbHVlcyAiKSIgfCBzaW1wbGUgKSAuCisgdmFsdWVzID0gc2ltcGxlIHsgIiwiIHNpbXBsZSB9IC4KKyBzaW1wbGUgPSAiIiIgc3RyaW5nc2ltcGxlICIiIiAuCisgdHlwZSA9IC8vIDEtY2hhciB0eXBlIGNvZGUgLgorIHN0cmluZ3NpbXBsZSA9IC8vIHF1b3RlZCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZhbHVlIC4KKyAqIDwvcHJlPgorICoKKyAqIEBhdXRob3IgZm1lc2NoYmUKKyAqLworcHVibGljIGNsYXNzIENvbmZpZ3VyYXRpb25IYW5kbGVyCit7CisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5DT0RJTkcgPSAiVVRGLTgiOworCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgVE9LRU5fTkFNRSA9ICdOJzsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUT0tFTl9FUSA9ICc9JzsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUT0tFTl9BUlJfT1BFTiA9ICdbJzsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUT0tFTl9BUlJfQ0xPUyA9ICddJzsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUT0tFTl9WRUNfT1BFTiA9ICcoJzsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUT0tFTl9WRUNfQ0xPUyA9ICcpJzsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUT0tFTl9DT01NQSA9ICcsJzsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUT0tFTl9WQUxfT1BFTiA9ICciJzsgLy8gJ3snOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRPS0VOX1ZBTF9DTE9TID0gJyInOyAvLyAnfSc7CisKKyAgICAvLyBzaW1wbGUgdHlwZXMgKHN0cmluZyAmIHByaW1pdGl2ZSB3cmFwcGVycykKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUT0tFTl9TSU1QTEVfU1RSSU5HID0gJ1QnOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRPS0VOX1NJTVBMRV9JTlRFR0VSID0gJ0knOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRPS0VOX1NJTVBMRV9MT05HID0gJ0wnOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRPS0VOX1NJTVBMRV9GTE9BVCA9ICdGJzsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUT0tFTl9TSU1QTEVfRE9VQkxFID0gJ0QnOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRPS0VOX1NJTVBMRV9CWVRFID0gJ1gnOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRPS0VOX1NJTVBMRV9TSE9SVCA9ICdTJzsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBUT0tFTl9TSU1QTEVfQ0hBUkFDVEVSID0gJ0MnOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRPS0VOX1NJTVBMRV9CT09MRUFOID0gJ0InOworCisgICAgLy8gcHJpbWl0aXZlcworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRPS0VOX1BSSU1JVElWRV9JTlQgPSAnaSc7CisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgVE9LRU5fUFJJTUlUSVZFX0xPTkcgPSAnbCc7CisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgVE9LRU5fUFJJTUlUSVZFX0ZMT0FUID0gJ2YnOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRPS0VOX1BSSU1JVElWRV9ET1VCTEUgPSAnZCc7CisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgVE9LRU5fUFJJTUlUSVZFX0JZVEUgPSAneCc7CisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBpbnQgVE9LRU5fUFJJTUlUSVZFX1NIT1JUID0gJ3MnOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRPS0VOX1BSSU1JVElWRV9DSEFSID0gJ2MnOworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgaW50IFRPS0VOX1BSSU1JVElWRV9CT09MRUFOID0gJ2InOworCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ1JMRiA9ICJcclxuIjsKKworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgTWFwIHR5cGUyQ29kZTsKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIE1hcCBjb2RlMlR5cGU7CisKKyAgICAvLyBzZXQgb2YgdmFsaWQgY2hhcmFjdGVycyBmb3IgInN5bWJsaWMtbmFtZSIKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCaXRTZXQgTkFNRV9DSEFSUzsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCaXRTZXQgVE9LRU5fQ0hBUlM7CisKKyAgICBzdGF0aWMKKyAgICB7CisgICAgICAgIHR5cGUyQ29kZSA9IG5ldyBIYXNoTWFwKCk7CisKKyAgICAgICAgLy8gc2ltcGxlIChleGNsdXNpdmUgU3RyaW5nIHdob3NlIHR5cGUgY29kZSBpcyBub3Qgd3JpdHRlbikKKyAgICAgICAgdHlwZTJDb2RlLnB1dCggSW50ZWdlci5jbGFzcywgbmV3IEludGVnZXIoIFRPS0VOX1NJTVBMRV9JTlRFR0VSICkgKTsKKyAgICAgICAgdHlwZTJDb2RlLnB1dCggTG9uZy5jbGFzcywgbmV3IEludGVnZXIoIFRPS0VOX1NJTVBMRV9MT05HICkgKTsKKyAgICAgICAgdHlwZTJDb2RlLnB1dCggRmxvYXQuY2xhc3MsIG5ldyBJbnRlZ2VyKCBUT0tFTl9TSU1QTEVfRkxPQVQgKSApOworICAgICAgICB0eXBlMkNvZGUucHV0KCBEb3VibGUuY2xhc3MsIG5ldyBJbnRlZ2VyKCBUT0tFTl9TSU1QTEVfRE9VQkxFICkgKTsKKyAgICAgICAgdHlwZTJDb2RlLnB1dCggQnl0ZS5jbGFzcywgbmV3IEludGVnZXIoIFRPS0VOX1NJTVBMRV9CWVRFICkgKTsKKyAgICAgICAgdHlwZTJDb2RlLnB1dCggU2hvcnQuY2xhc3MsIG5ldyBJbnRlZ2VyKCBUT0tFTl9TSU1QTEVfU0hPUlQgKSApOworICAgICAgICB0eXBlMkNvZGUucHV0KCBDaGFyYWN0ZXIuY2xhc3MsIG5ldyBJbnRlZ2VyKCBUT0tFTl9TSU1QTEVfQ0hBUkFDVEVSICkgKTsKKyAgICAgICAgdHlwZTJDb2RlLnB1dCggQm9vbGVhbi5jbGFzcywgbmV3IEludGVnZXIoIFRPS0VOX1NJTVBMRV9CT09MRUFOICkgKTsKKworICAgICAgICAvLyBwcmltaXRpdmVzCisgICAgICAgIHR5cGUyQ29kZS5wdXQoIEludGVnZXIuVFlQRSwgbmV3IEludGVnZXIoIFRPS0VOX1BSSU1JVElWRV9JTlQgKSApOworICAgICAgICB0eXBlMkNvZGUucHV0KCBMb25nLlRZUEUsIG5ldyBJbnRlZ2VyKCBUT0tFTl9QUklNSVRJVkVfTE9ORyApICk7CisgICAgICAgIHR5cGUyQ29kZS5wdXQoIEZsb2F0LlRZUEUsIG5ldyBJbnRlZ2VyKCBUT0tFTl9QUklNSVRJVkVfRkxPQVQgKSApOworICAgICAgICB0eXBlMkNvZGUucHV0KCBEb3VibGUuVFlQRSwgbmV3IEludGVnZXIoIFRPS0VOX1BSSU1JVElWRV9ET1VCTEUgKSApOworICAgICAgICB0eXBlMkNvZGUucHV0KCBCeXRlLlRZUEUsIG5ldyBJbnRlZ2VyKCBUT0tFTl9QUklNSVRJVkVfQllURSApICk7CisgICAgICAgIHR5cGUyQ29kZS5wdXQoIFNob3J0LlRZUEUsIG5ldyBJbnRlZ2VyKCBUT0tFTl9QUklNSVRJVkVfU0hPUlQgKSApOworICAgICAgICB0eXBlMkNvZGUucHV0KCBDaGFyYWN0ZXIuVFlQRSwgbmV3IEludGVnZXIoIFRPS0VOX1BSSU1JVElWRV9DSEFSICkgKTsKKyAgICAgICAgdHlwZTJDb2RlLnB1dCggQm9vbGVhbi5UWVBFLCBuZXcgSW50ZWdlciggVE9LRU5fUFJJTUlUSVZFX0JPT0xFQU4gKSApOworCisgICAgICAgIC8vIHJldmVyc2UgbWFwIHRvIG1hcCB0eXBlIGNvZGVzIHRvIGNsYXNzZXMsIHN0cmluZyBjbGFzcyBtYXBwaW5nCisgICAgICAgIC8vIHRvIGJlIGFkZGVkIG1hbnVhbGx5LCBhcyB0aGUgc3RyaW5nIHR5cGUgY29kZSBpcyBub3Qgd3JpdHRlbiBhbmQKKyAgICAgICAgLy8gaGVuY2Ugbm90IGluY2x1ZGVkIGluIHRoZSB0eXBlMkNvZGUgbWFwCisgICAgICAgIGNvZGUyVHlwZSA9IG5ldyBIYXNoTWFwKCk7CisgICAgICAgIGZvciAoIEl0ZXJhdG9yIHRpID0gdHlwZTJDb2RlLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsgdGkuaGFzTmV4dCgpOyApCisgICAgICAgIHsKKyAgICAgICAgICAgIE1hcC5FbnRyeSBlbnRyeSA9ICggTWFwLkVudHJ5ICkgdGkubmV4dCgpOworICAgICAgICAgICAgY29kZTJUeXBlLnB1dCggZW50cnkuZ2V0VmFsdWUoKSwgZW50cnkuZ2V0S2V5KCkgKTsKKyAgICAgICAgfQorICAgICAgICBjb2RlMlR5cGUucHV0KCBuZXcgSW50ZWdlciggVE9LRU5fU0lNUExFX1NUUklORyApLCBTdHJpbmcuY2xhc3MgKTsKKworICAgICAgICBOQU1FX0NIQVJTID0gbmV3IEJpdFNldCgpOworICAgICAgICBmb3IgKCBpbnQgaSA9ICcwJzsgaSA8PSAnOSc7IGkrKyApCisgICAgICAgICAgICBOQU1FX0NIQVJTLnNldCggaSApOworICAgICAgICBmb3IgKCBpbnQgaSA9ICdhJzsgaSA8PSAneic7IGkrKyApCisgICAgICAgICAgICBOQU1FX0NIQVJTLnNldCggaSApOworICAgICAgICBmb3IgKCBpbnQgaSA9ICdBJzsgaSA8PSAnWic7IGkrKyApCisgICAgICAgICAgICBOQU1FX0NIQVJTLnNldCggaSApOworICAgICAgICBOQU1FX0NIQVJTLnNldCggJ18nICk7CisgICAgICAgIE5BTUVfQ0hBUlMuc2V0KCAnLScgKTsKKyAgICAgICAgTkFNRV9DSEFSUy5zZXQoICcuJyApOworCisgICAgICAgIFRPS0VOX0NIQVJTID0gbmV3IEJpdFNldCgpOworICAgICAgICBUT0tFTl9DSEFSUy5zZXQoIFRPS0VOX0VRICk7CisgICAgICAgIFRPS0VOX0NIQVJTLnNldCggVE9LRU5fQVJSX09QRU4gKTsKKyAgICAgICAgVE9LRU5fQ0hBUlMuc2V0KCBUT0tFTl9BUlJfQ0xPUyApOworICAgICAgICBUT0tFTl9DSEFSUy5zZXQoIFRPS0VOX1ZFQ19PUEVOICk7CisgICAgICAgIFRPS0VOX0NIQVJTLnNldCggVE9LRU5fVkVDX0NMT1MgKTsKKyAgICAgICAgVE9LRU5fQ0hBUlMuc2V0KCBUT0tFTl9DT01NQSApOworICAgICAgICBUT0tFTl9DSEFSUy5zZXQoIFRPS0VOX1ZBTF9PUEVOICk7CisgICAgICAgIFRPS0VOX0NIQVJTLnNldCggVE9LRU5fVkFMX0NMT1MgKTsKKyAgICAgICAgVE9LRU5fQ0hBUlMuc2V0KCBUT0tFTl9TSU1QTEVfU1RSSU5HICk7CisgICAgICAgIFRPS0VOX0NIQVJTLnNldCggVE9LRU5fU0lNUExFX0lOVEVHRVIgKTsKKyAgICAgICAgVE9LRU5fQ0hBUlMuc2V0KCBUT0tFTl9TSU1QTEVfTE9ORyApOworICAgICAgICBUT0tFTl9DSEFSUy5zZXQoIFRPS0VOX1NJTVBMRV9GTE9BVCApOworICAgICAgICBUT0tFTl9DSEFSUy5zZXQoIFRPS0VOX1NJTVBMRV9ET1VCTEUgKTsKKyAgICAgICAgVE9LRU5fQ0hBUlMuc2V0KCBUT0tFTl9TSU1QTEVfQllURSApOworICAgICAgICBUT0tFTl9DSEFSUy5zZXQoIFRPS0VOX1NJTVBMRV9TSE9SVCApOworICAgICAgICBUT0tFTl9DSEFSUy5zZXQoIFRPS0VOX1NJTVBMRV9DSEFSQUNURVIgKTsKKyAgICAgICAgVE9LRU5fQ0hBUlMuc2V0KCBUT0tFTl9TSU1QTEVfQk9PTEVBTiApOworCisgICAgICAgIC8vIHByaW1pdGl2ZXMKKyAgICAgICAgVE9LRU5fQ0hBUlMuc2V0KCBUT0tFTl9QUklNSVRJVkVfSU5UICk7CisgICAgICAgIFRPS0VOX0NIQVJTLnNldCggVE9LRU5fUFJJTUlUSVZFX0xPTkcgKTsKKyAgICAgICAgVE9LRU5fQ0hBUlMuc2V0KCBUT0tFTl9QUklNSVRJVkVfRkxPQVQgKTsKKyAgICAgICAgVE9LRU5fQ0hBUlMuc2V0KCBUT0tFTl9QUklNSVRJVkVfRE9VQkxFICk7CisgICAgICAgIFRPS0VOX0NIQVJTLnNldCggVE9LRU5fUFJJTUlUSVZFX0JZVEUgKTsKKyAgICAgICAgVE9LRU5fQ0hBUlMuc2V0KCBUT0tFTl9QUklNSVRJVkVfU0hPUlQgKTsKKyAgICAgICAgVE9LRU5fQ0hBUlMuc2V0KCBUT0tFTl9QUklNSVRJVkVfQ0hBUiApOworICAgICAgICBUT0tFTl9DSEFSUy5zZXQoIFRPS0VOX1BSSU1JVElWRV9CT09MRUFOICk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBXcml0ZXMgdGhlIGNvbmZpZ3VyYXRpb24gZGF0YSBmcm9tIHRoZSA8Y29kZT5EaWN0aW9uYXJ5PC9jb2RlPiB0byB0aGUKKyAgICAgKiBnaXZlbiA8Y29kZT5PdXRwdXRTdHJlYW08L2NvZGU+LgorICAgICAqIDxwPgorICAgICAqIFRoaXMgbWV0aG9kIHdyaXRlcyBhdCB0aGUgY3VycmVudCBsb2NhdGlvbiBpbiB0aGUgc3RyZWFtIGFuZCBkb2VzIG5vdAorICAgICAqIGNsb3NlIHRoZSBvdXRwdXRzdHJlYW0uCisgICAgICogCisgICAgICogQHBhcmFtIG91dCBUaGUgPGNvZGU+T3V0cHV0U3RyZWFtPC9jb2RlPiB0byB3cml0ZSB0aGUgY29uZmlndXJ0aW9uIGRhdGEKKyAgICAgKiAgICAgIHRvLgorICAgICAqIEBwYXJhbSBwcm9wZXJ0aWVzIFRoZSA8Y29kZT5EaWN0aW9uYXJ5PC9jb2RlPiB0byB3cml0ZS4KKyAgICAgKiAKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIElmIGFuIGVycm9yIG9jY3VycnMgd3JpdGluZyB0byB0aGUgb3V0cHV0IHN0cmVhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgd3JpdGUoIE91dHB1dFN0cmVhbSBvdXQsIERpY3Rpb25hcnkgcHJvcGVydGllcyApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgQnVmZmVyZWRXcml0ZXIgYncgPSBuZXcgQnVmZmVyZWRXcml0ZXIoIG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoIG91dCwgRU5DT0RJTkcgKSApOworCisgICAgICAgIGZvciAoIEVudW1lcmF0aW9uIGNlID0gcHJvcGVydGllcy5rZXlzKCk7IGNlLmhhc01vcmVFbGVtZW50cygpOyApCisgICAgICAgIHsKKyAgICAgICAgICAgIFN0cmluZyBrZXkgPSAoIFN0cmluZyApIGNlLm5leHRFbGVtZW50KCk7CisKKyAgICAgICAgICAgIC8vICAgICBjZmcgPSBwcm9wICI9IiB2YWx1ZSAiLiIgLgorICAgICAgICAgICAgd3JpdGVRdW90ZWQoIGJ3LCBrZXkgKTsKKyAgICAgICAgICAgIGJ3LndyaXRlKCBUT0tFTl9FUSApOworICAgICAgICAgICAgd3JpdGVWYWx1ZSggYncsIHByb3BlcnRpZXMuZ2V0KCBrZXkgKSApOworICAgICAgICAgICAgYncud3JpdGUoIENSTEYgKTsKKyAgICAgICAgfQorCisgICAgICAgIGJ3LmZsdXNoKCk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBSZWFkcyBjb25maWd1cmF0aW9uIGRhdGEgZnJvbSB0aGUgZ2l2ZW4gPGNvZGU+SW5wdXRTdHJlYW08L2NvZGU+IGFuZAorICAgICAqIHJldHVybnMgYSBuZXcgPGNvZGU+RGljdGlvbmFyeTwvY29kZT4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGRhdGEuCisgICAgICogPHA+CisgICAgICogVGhpcyBtZXRob2QgcmVhZHMgZnJvbSB0aGUgY3VycmVudCBsb2NhdGlvbiBpbiB0aGUgc3RyZWFtIHVwdG8gdGhlIGVuZAorICAgICAqIG9mIHRoZSBzdHJlYW0gYnV0IGRvZXMgbm90IGNsb3NlIHRoZSBzdHJlYW0gYXQgdGhlIGVuZC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gaW5zIFRoZSA8Y29kZT5JbnB1dFN0cmVhbTwvY29kZT4gZnJvbSB3aGljaCB0byByZWFkIHRoZQorICAgICAqICAgICAgY29uZmlndXJhdGlvbiBkYXRhLgorICAgICAqICAgICAgCisgICAgICogQHJldHVybiBBIDxjb2RlPkRpY3Rpb25hcnk8L2NvZGU+IG9iamVjdCBjb250YWluaW5nIHRoZSBjb25maWd1cmF0aW9uCisgICAgICogICAgICBkYXRhLiBUaGlzIG9iamVjdCBtYXkgYmUgZW1wdHkgaWYgdGhlIHN0cmVhbSBjb250YWlucyBubworICAgICAqICAgICAgY29uZmlndXJhdGlvbiBkYXRhLgorICAgICAqICAgICAgCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbiBlcnJvciBvY2N1cnJzIHJlYWRpbmcgZnJvbSB0aGUgc3RyZWFtLiBUaGlzCisgICAgICogICAgICBleGNlcHRpb24gaXMgYWxzbyB0aHJvd24gaWYgYSBzeW50YXggZXJyb3IgaXMgZW5jb3VudGVyZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBEaWN0aW9uYXJ5IHJlYWQoIElucHV0U3RyZWFtIGlucyApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgcmV0dXJuIG5ldyBDb25maWd1cmF0aW9uSGFuZGxlcigpLnJlYWRJbnRlcm5hbCggaW5zICk7CisgICAgfQorCisKKyAgICAvLyBwcml2YXRlIGNvbnN0cnVjdG9yLCB0aGlzIGNsYXNzIGlzIG5vdCB0byBiZSBpbnN0YW50aWF0ZWQgZnJvbSB0aGUgb3V0c2lkZQorICAgIHByaXZhdGUgQ29uZmlndXJhdGlvbkhhbmRsZXIoKQorICAgIHsKKyAgICB9CisKKyAgICAvLy0tLS0tLS0tLS0gQ29uZmlndXJhdGlvbiBJbnB1dCBJbXBsZW1lbnRhdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHByaXZhdGUgaW50IHRva2VuOworICAgIHByaXZhdGUgU3RyaW5nIHRva2VuVmFsdWU7CisgICAgcHJpdmF0ZSBpbnQgbGluZTsKKyAgICBwcml2YXRlIGludCBwb3M7CisKKworICAgIHByaXZhdGUgRGljdGlvbmFyeSByZWFkSW50ZXJuYWwoIElucHV0U3RyZWFtIGlucyApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgQnVmZmVyZWRSZWFkZXIgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIoIG5ldyBJbnB1dFN0cmVhbVJlYWRlciggaW5zLCBFTkNPRElORyApICk7CisgICAgICAgIFB1c2hiYWNrUmVhZGVyIHByID0gbmV3IFB1c2hiYWNrUmVhZGVyKCBiciwgMSApOworCisgICAgICAgIHRva2VuID0gMDsKKyAgICAgICAgdG9rZW5WYWx1ZSA9IG51bGw7CisgICAgICAgIGxpbmUgPSAwOworICAgICAgICBwb3MgPSAwOworCisgICAgICAgIEhhc2h0YWJsZSBjb25maWd1cmF0aW9uID0gbmV3IEhhc2h0YWJsZSgpOworICAgICAgICB0b2tlbiA9IDA7CisgICAgICAgIHdoaWxlICggbmV4dFRva2VuKCBwciApID09IFRPS0VOX05BTUUgKQorICAgICAgICB7CisgICAgICAgICAgICBTdHJpbmcga2V5ID0gdG9rZW5WYWx1ZTsKKworICAgICAgICAgICAgLy8gZXhwZWN0IGVxdWFsIHNpZ24KKyAgICAgICAgICAgIGlmICggbmV4dFRva2VuKCBwciApICE9IFRPS0VOX0VRICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICB0aHJvdyByZWFkRmFpbHVyZSggdG9rZW4sIFRPS0VOX0VRICk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGV4cGVjdCB0aGUgdG9rZW4gdmFsdWUKKyAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IHJlYWRWYWx1ZSggcHIgKTsKKyAgICAgICAgICAgIGlmICggdmFsdWUgIT0gbnVsbCApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgY29uZmlndXJhdGlvbi5wdXQoIGtleSwgdmFsdWUgKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjb25maWd1cmF0aW9uOworICAgIH0KKworCisgICAgLyoqCisgICAgIHZhbHVlID0gdHlwZSAoICJbIiB2YWx1ZXMgIl0iIHwgIigiIHZhbHVlcyAiKSIgfCBzaW1wbGUgKSAuCisgICAgIHZhbHVlcyA9IHZhbHVlIHsgIiwiIHZhbHVlIH0gLgorICAgICBzaW1wbGUgPSAieyIgc3RyaW5nc2ltcGxlICJ9IiAuCisgICAgIHR5cGUgPSAvLyAxLWNoYXIgdHlwZSBjb2RlIC4KKyAgICAgc3RyaW5nc2ltcGxlID0gLy8gcXVvdGVkIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmFsdWUgLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwcgorICAgICAqIEByZXR1cm4KKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSBPYmplY3QgcmVhZFZhbHVlKCBQdXNoYmFja1JlYWRlciBwciApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgLy8gcmVhZCAob3B0aW9uYWwpIHR5cGUgY29kZQorICAgICAgICBpbnQgdHlwZSA9IHJlYWQoIHByICk7CisKKyAgICAgICAgLy8gcmVhZCB2YWx1ZSBraW5kIGNvZGUgaWYgdHlwZSBjb2RlIGlzIG5vdCBhIHZhbHVlIGtpbmRlIGNvZGUKKyAgICAgICAgaW50IGNvZGU7CisgICAgICAgIGlmICggY29kZTJUeXBlLmNvbnRhaW5zS2V5KCBuZXcgSW50ZWdlciggdHlwZSApICkgKQorICAgICAgICB7CisgICAgICAgICAgICBjb2RlID0gcmVhZCggcHIgKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICAgIGNvZGUgPSB0eXBlOworICAgICAgICAgICAgdHlwZSA9IFRPS0VOX1NJTVBMRV9TVFJJTkc7CisgICAgICAgIH0KKworICAgICAgICBzd2l0Y2ggKCBjb2RlICkKKyAgICAgICAgeworICAgICAgICAgICAgY2FzZSBUT0tFTl9BUlJfT1BFTjoKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVhZEFycmF5KCB0eXBlLCBwciApOworCisgICAgICAgICAgICBjYXNlIFRPS0VOX1ZFQ19PUEVOOgorICAgICAgICAgICAgICAgIHJldHVybiByZWFkVmVjdG9yKCB0eXBlLCBwciApOworCisgICAgICAgICAgICBjYXNlIFRPS0VOX1ZBTF9PUEVOOgorICAgICAgICAgICAgICAgIHJldHVybiByZWFkU2ltcGxlKCB0eXBlLCBwciApOworCisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorCisKKyAgICBwcml2YXRlIE9iamVjdCByZWFkQXJyYXkoIGludCB0eXBlQ29kZSwgUHVzaGJhY2tSZWFkZXIgcHIgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIFZlY3RvciB2ZWN0b3IgPSBuZXcgVmVjdG9yKCk7CisgICAgICAgIGZvciAoIDs7ICkKKyAgICAgICAgeworICAgICAgICAgICAgaWYgKCAhY2hlY2tOZXh0KCBwciwgVE9LRU5fVkFMX09QRU4gKSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IHJlYWRTaW1wbGUoIHR5cGVDb2RlLCBwciApOworICAgICAgICAgICAgaWYgKCB2YWx1ZSA9PSBudWxsICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAvLyBhYm9ydCBkdWUgdG8gZXJyb3IKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdmVjdG9yLmFkZCggdmFsdWUgKTsKKworICAgICAgICAgICAgaW50IGMgPSByZWFkKCBwciApOworICAgICAgICAgICAgaWYgKCBjID09IFRPS0VOX0FSUl9DTE9TICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBDbGFzcyB0eXBlID0gKCBDbGFzcyApIGNvZGUyVHlwZS5nZXQoIG5ldyBJbnRlZ2VyKCB0eXBlQ29kZSApICk7CisgICAgICAgICAgICAgICAgT2JqZWN0IGFycmF5ID0gQXJyYXkubmV3SW5zdGFuY2UoIHR5cGUsIHZlY3Rvci5zaXplKCkgKTsKKyAgICAgICAgICAgICAgICBmb3IgKCBpbnQgaSA9IDA7IGkgPCB2ZWN0b3Iuc2l6ZSgpOyBpKysgKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgQXJyYXkuc2V0KCBhcnJheSwgaSwgdmVjdG9yLmdldCggaSApICk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBhcnJheTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKCBjIDwgMCApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGlmICggYyAhPSBUT0tFTl9DT01NQSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKworICAgIHByaXZhdGUgVmVjdG9yIHJlYWRWZWN0b3IoIGludCB0eXBlQ29kZSwgUHVzaGJhY2tSZWFkZXIgcHIgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIFZlY3RvciB2ZWN0b3IgPSBuZXcgVmVjdG9yKCk7CisgICAgICAgIGZvciAoIDs7ICkKKyAgICAgICAgeworICAgICAgICAgICAgaWYgKCAhY2hlY2tOZXh0KCBwciwgVE9LRU5fVkFMX09QRU4gKSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IHJlYWRTaW1wbGUoIHR5cGVDb2RlLCBwciApOworICAgICAgICAgICAgaWYgKCB2YWx1ZSA9PSBudWxsICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAvLyBhYm9ydCBkdWUgdG8gZXJyb3IKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgdmVjdG9yLmFkZCggdmFsdWUgKTsKKworICAgICAgICAgICAgaW50IGMgPSByZWFkKCBwciApOworICAgICAgICAgICAgaWYgKCBjID09IFRPS0VOX1ZFQ19DTE9TICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gdmVjdG9yOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSBpZiAoIGMgPCAwICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKCBjICE9IFRPS0VOX0NPTU1BICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworCisgICAgcHJpdmF0ZSBPYmplY3QgcmVhZFNpbXBsZSggaW50IGNvZGUsIFB1c2hiYWNrUmVhZGVyIHByICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBzd2l0Y2ggKCBjb2RlICkKKyAgICAgICAgeworICAgICAgICAgICAgY2FzZSAtMToKKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKworICAgICAgICAgICAgY2FzZSBUT0tFTl9TSU1QTEVfU1RSSU5HOgorICAgICAgICAgICAgICAgIHJldHVybiByZWFkUXVvdGVkKCBwciApOworCisgICAgICAgICAgICAgICAgLy8gU2ltcGxlL1ByaW1pdGl2ZSwgb25seSB1c2Ugd3JhcHBlciBjbGFzc2VzCisgICAgICAgICAgICBjYXNlIFRPS0VOX1NJTVBMRV9JTlRFR0VSOgorICAgICAgICAgICAgY2FzZSBUT0tFTl9QUklNSVRJVkVfSU5UOgorICAgICAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLnZhbHVlT2YoIHJlYWRRdW90ZWQoIHByICkgKTsKKworICAgICAgICAgICAgY2FzZSBUT0tFTl9TSU1QTEVfTE9ORzoKKyAgICAgICAgICAgIGNhc2UgVE9LRU5fUFJJTUlUSVZFX0xPTkc6CisgICAgICAgICAgICAgICAgcmV0dXJuIExvbmcudmFsdWVPZiggcmVhZFF1b3RlZCggcHIgKSApOworCisgICAgICAgICAgICBjYXNlIFRPS0VOX1NJTVBMRV9GTE9BVDoKKyAgICAgICAgICAgIGNhc2UgVE9LRU5fUFJJTUlUSVZFX0ZMT0FUOgorICAgICAgICAgICAgICAgIGludCBmQml0cyA9IEludGVnZXIucGFyc2VJbnQoIHJlYWRRdW90ZWQoIHByICkgKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEZsb2F0KCBGbG9hdC5pbnRCaXRzVG9GbG9hdCggZkJpdHMgKSApOworCisgICAgICAgICAgICBjYXNlIFRPS0VOX1NJTVBMRV9ET1VCTEU6CisgICAgICAgICAgICBjYXNlIFRPS0VOX1BSSU1JVElWRV9ET1VCTEU6CisgICAgICAgICAgICAgICAgbG9uZyBkQml0cyA9IExvbmcucGFyc2VMb25nKCByZWFkUXVvdGVkKCBwciApICk7CisgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBEb3VibGUoIERvdWJsZS5sb25nQml0c1RvRG91YmxlKCBkQml0cyApICk7CisKKyAgICAgICAgICAgIGNhc2UgVE9LRU5fU0lNUExFX0JZVEU6CisgICAgICAgICAgICBjYXNlIFRPS0VOX1BSSU1JVElWRV9CWVRFOgorICAgICAgICAgICAgICAgIHJldHVybiBCeXRlLnZhbHVlT2YoIHJlYWRRdW90ZWQoIHByICkgKTsKKworICAgICAgICAgICAgY2FzZSBUT0tFTl9TSU1QTEVfU0hPUlQ6CisgICAgICAgICAgICBjYXNlIFRPS0VOX1BSSU1JVElWRV9TSE9SVDoKKyAgICAgICAgICAgICAgICByZXR1cm4gU2hvcnQudmFsdWVPZiggcmVhZFF1b3RlZCggcHIgKSApOworCisgICAgICAgICAgICBjYXNlIFRPS0VOX1NJTVBMRV9DSEFSQUNURVI6CisgICAgICAgICAgICBjYXNlIFRPS0VOX1BSSU1JVElWRV9DSEFSOgorICAgICAgICAgICAgICAgIFN0cmluZyBjU3RyaW5nID0gcmVhZFF1b3RlZCggcHIgKTsKKyAgICAgICAgICAgICAgICBpZiAoIGNTdHJpbmcgIT0gbnVsbCAmJiBjU3RyaW5nLmxlbmd0aCgpID4gMCApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENoYXJhY3RlciggY1N0cmluZy5jaGFyQXQoIDAgKSApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKworICAgICAgICAgICAgY2FzZSBUT0tFTl9TSU1QTEVfQk9PTEVBTjoKKyAgICAgICAgICAgIGNhc2UgVE9LRU5fUFJJTUlUSVZFX0JPT0xFQU46CisgICAgICAgICAgICAgICAgcmV0dXJuIEJvb2xlYW4udmFsdWVPZiggcmVhZFF1b3RlZCggcHIgKSApOworCisgICAgICAgICAgICAgICAgLy8gdW5rbm93biB0eXBlIGNvZGUKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIHByaXZhdGUgYm9vbGVhbiBjaGVja05leHQoIFB1c2hiYWNrUmVhZGVyIHByLCBpbnQgZXhwZWN0ZWQgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIGludCBuZXh0ID0gcmVhZCggcHIgKTsKKyAgICAgICAgaWYgKCBuZXh0IDwgMCApCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICggbmV4dCA9PSBleHBlY3RlZCApCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworCisgICAgcHJpdmF0ZSBTdHJpbmcgcmVhZFF1b3RlZCggUHVzaGJhY2tSZWFkZXIgcHIgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIGZvciAoIDs7ICkKKyAgICAgICAgeworICAgICAgICAgICAgaW50IGMgPSByZWFkKCBwciApOworICAgICAgICAgICAgc3dpdGNoICggYyApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgLy8gZXNjYXBlZCBjaGFyYWN0ZXIKKyAgICAgICAgICAgICAgICBjYXNlICdcXCc6CisgICAgICAgICAgICAgICAgICAgIGMgPSByZWFkKCBwciApOworICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKCBjICkKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2VsbCBrbm93biBlc2NhcGVzCisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdiJzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAnXGInICk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICd0JzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAnXHQnICk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICduJzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAnXG4nICk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdmJzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAnXGYnICk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdyJzoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAnXHInICk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICd1JzovLyBuZWVkIDQgY2hhcmFjdGVycyAhCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhcltdIGNidWYgPSBuZXcgY2hhcls0XTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHJlYWQoIHByLCBjYnVmICkgPT0gNCApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjID0gSW50ZWdlci5wYXJzZUludCggbmV3IFN0cmluZyggY2J1ZiApLCAxNiApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAoIGNoYXIgKSBjICk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBqdXN0IGFuIGVzY2FwZWQgY2hhcmFjdGVyLCB1bmVzY2FwZQorICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAoIGNoYXIgKSBjICk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICAvLyBlb2YKKyAgICAgICAgICAgICAgICBjYXNlIC0xOiAvLyBmYWxsIHRocm91Z2gKKworICAgICAgICAgICAgICAgICAgICAvLyBzZXBhcmF0b3IgdG9rZW4KKyAgICAgICAgICAgICAgICBjYXNlIFRPS0VOX1ZBTF9DTE9TOgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gbm8gZXNjYXBpbmcKKyAgICAgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAoIGNoYXIgKSBjICk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKworICAgIHByaXZhdGUgaW50IG5leHRUb2tlbiggUHVzaGJhY2tSZWFkZXIgcHIgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIGludCBjID0gaWdub3JhYmxlV2hpdGVTcGFjZSggcHIgKTsKKworICAgICAgICAvLyBpbW1lZGlhdGVseSByZXR1cm4gRU9GCisgICAgICAgIGlmICggYyA8IDAgKQorICAgICAgICB7CisgICAgICAgICAgICByZXR1cm4gKCB0b2tlbiA9IGMgKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYSBuYW1lCisgICAgICAgIGlmICggTkFNRV9DSEFSUy5nZXQoIGMgKSApCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIHJlYWQgdGhlIHByb3BlcnR5IG5hbWUKKyAgICAgICAgICAgIHRva2VuVmFsdWUgPSByZWFkTmFtZSggcHIsICggY2hhciApIGMgKTsKKyAgICAgICAgICAgIHJldHVybiAoIHRva2VuID0gVE9LRU5fTkFNRSApOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2hlY2sgYW5vdGhlciB0b2tlbgorICAgICAgICBpZiAoIFRPS0VOX0NIQVJTLmdldCggYyApICkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuICggdG9rZW4gPSBjICk7CisgICAgICAgIH0KKworICAgICAgICAvLyB1bmV4cGVjdGVkIGNoYXJhY3RlciAtPiBzbyB3aGF0ID8/CisgICAgICAgIHJldHVybiAoIHRva2VuID0gLTEgKTsKKyAgICB9CisKKworICAgIHByaXZhdGUgaW50IGlnbm9yYWJsZVdoaXRlU3BhY2UoIFB1c2hiYWNrUmVhZGVyIHByICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBpbnQgYyA9IHJlYWQoIHByICk7CisgICAgICAgIHdoaWxlICggYyA+PSAwICYmIENoYXJhY3Rlci5pc1doaXRlc3BhY2UoICggY2hhciApIGMgKSApCisgICAgICAgIHsKKyAgICAgICAgICAgIGMgPSByZWFkKCBwciApOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjOworICAgIH0KKworCisgICAgcHJpdmF0ZSBTdHJpbmcgcmVhZE5hbWUoIFB1c2hiYWNrUmVhZGVyIHByLCBjaGFyIGZpcnN0Q2hhciApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKyAgICAgICAgYnVmLmFwcGVuZCggZmlyc3RDaGFyICk7CisKKyAgICAgICAgaW50IGMgPSByZWFkKCBwciApOworICAgICAgICB3aGlsZSAoIGMgPj0gMCAmJiBOQU1FX0NIQVJTLmdldCggYyApICkKKyAgICAgICAgeworICAgICAgICAgICAgYnVmLmFwcGVuZCggKCBjaGFyICkgYyApOworICAgICAgICAgICAgYyA9IHJlYWQoIHByICk7CisgICAgICAgIH0KKyAgICAgICAgcHIudW5yZWFkKCBjICk7CisKKyAgICAgICAgaWYgKCBidWYuY2hhckF0KCAwICkgPT0gJy4nIHx8IGJ1Zi5jaGFyQXQoIGJ1Zi5sZW5ndGgoKSAtIDEgKSA9PSAnLicgKQorICAgICAgICB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oICJOYW1lICgiICsgYnVmICsgIikgbXVzdCBub3Qgc3RhcnQgb3IgZW5kIHdpdGggYSBkb3QiICk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgfQorCisKKyAgICBwcml2YXRlIGludCByZWFkKCBQdXNoYmFja1JlYWRlciBwciApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgaW50IGMgPSBwci5yZWFkKCk7CisgICAgICAgIGlmICggYyA9PSAnXHInICkKKyAgICAgICAgeworICAgICAgICAgICAgaW50IGMxID0gcHIucmVhZCgpOworICAgICAgICAgICAgaWYgKCBjMSAhPSAnXG4nICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBwci51bnJlYWQoIGMxICk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjID0gJ1xuJzsKKyAgICAgICAgfQorCisgICAgICAgIGlmICggYyA9PSAnXG4nICkKKyAgICAgICAgeworICAgICAgICAgICAgbGluZSsrOworICAgICAgICAgICAgcG9zID0gMDsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICAgIHBvcysrOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGM7CisgICAgfQorCisKKyAgICBwcml2YXRlIGludCByZWFkKCBQdXNoYmFja1JlYWRlciBwciwgY2hhcltdIGJ1ZiApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgZm9yICggaW50IGkgPSAwOyBpIDwgYnVmLmxlbmd0aDsgaSsrICkKKyAgICAgICAgeworICAgICAgICAgICAgaW50IGMgPSByZWFkKCBwciApOworICAgICAgICAgICAgaWYgKCBjID49IDAgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGJ1ZltpXSA9ICggY2hhciApIGM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gYnVmLmxlbmd0aDsKKyAgICB9CisKKworICAgIHByaXZhdGUgSU9FeGNlcHRpb24gcmVhZEZhaWx1cmUoIGludCBjdXJyZW50LCBpbnQgZXhwZWN0ZWQgKQorICAgIHsKKyAgICAgICAgcmV0dXJuIG5ldyBJT0V4Y2VwdGlvbiggIlVuZXhwZWN0ZWQgdG9rZW4gIiArIGN1cnJlbnQgKyAiOyBleHBlY3RlZDogIiArIGV4cGVjdGVkICsgIiAobGluZT0iICsgbGluZSArICIsIHBvcz0iCisgICAgICAgICAgICArIHBvcyArICIpIiApOworICAgIH0KKworCisgICAgLy8tLS0tLS0tLS0tIENvbmZpZ3VyYXRpb24gT3V0cHV0IEltcGxlbWVudGF0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHdyaXRlVmFsdWUoIFdyaXRlciBvdXQsIE9iamVjdCB2YWx1ZSApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgQ2xhc3MgY2xhenogPSB2YWx1ZS5nZXRDbGFzcygpOworICAgICAgICBpZiAoIGNsYXp6LmlzQXJyYXkoKSApCisgICAgICAgIHsKKyAgICAgICAgICAgIHdyaXRlQXJyYXkoIG91dCwgdmFsdWUgKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmICggY2xhenogPT0gVmVjdG9yLmNsYXNzICkKKyAgICAgICAgeworICAgICAgICAgICAgd3JpdGVWZWN0b3IoIG91dCwgKCBWZWN0b3IgKSB2YWx1ZSApOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgICAgd3JpdGVUeXBlKCBvdXQsIGNsYXp6ICk7CisgICAgICAgICAgICB3cml0ZVNpbXBsZSggb3V0LCB2YWx1ZSApOworICAgICAgICB9CisgICAgfQorCisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHdyaXRlQXJyYXkoIFdyaXRlciBvdXQsIE9iamVjdCBhcnJheVZhbHVlICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBpbnQgc2l6ZSA9IEFycmF5LmdldExlbmd0aCggYXJyYXlWYWx1ZSApOworICAgICAgICBpZiAoIHNpemUgPT0gMCApCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHdyaXRlVHlwZSggb3V0LCBhcnJheVZhbHVlLmdldENsYXNzKCkuZ2V0Q29tcG9uZW50VHlwZSgpICk7CisgICAgICAgIG91dC53cml0ZSggVE9LRU5fQVJSX09QRU4gKTsKKyAgICAgICAgZm9yICggaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrICkKKyAgICAgICAgeworICAgICAgICAgICAgaWYgKCBpID4gMCApCisgICAgICAgICAgICAgICAgb3V0LndyaXRlKCBUT0tFTl9DT01NQSApOworICAgICAgICAgICAgd3JpdGVTaW1wbGUoIG91dCwgQXJyYXkuZ2V0KCBhcnJheVZhbHVlLCBpICkgKTsKKyAgICAgICAgfQorICAgICAgICBvdXQud3JpdGUoIFRPS0VOX0FSUl9DTE9TICk7CisgICAgfQorCisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHdyaXRlVmVjdG9yKCBXcml0ZXIgb3V0LCBWZWN0b3IgdmVjdG9yICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBpZiAoIHZlY3Rvci5pc0VtcHR5KCkgKQorICAgICAgICB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICB3cml0ZVR5cGUoIG91dCwgdmVjdG9yLmdldCggMCApLmdldENsYXNzKCkgKTsKKyAgICAgICAgb3V0LndyaXRlKCBUT0tFTl9WRUNfT1BFTiApOworICAgICAgICBmb3IgKCBpbnQgaSA9IDA7IGkgPCB2ZWN0b3Iuc2l6ZSgpOyBpKysgKQorICAgICAgICB7CisgICAgICAgICAgICBpZiAoIGkgPiAwICkKKyAgICAgICAgICAgICAgICBvdXQud3JpdGUoIFRPS0VOX0NPTU1BICk7CisgICAgICAgICAgICB3cml0ZVNpbXBsZSggb3V0LCB2ZWN0b3IuZ2V0KCBpICkgKTsKKyAgICAgICAgfQorICAgICAgICBvdXQud3JpdGUoIFRPS0VOX1ZFQ19DTE9TICk7CisgICAgfQorCisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHdyaXRlVHlwZSggV3JpdGVyIG91dCwgQ2xhc3MgdmFsdWVUeXBlICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBJbnRlZ2VyIGNvZGUgPSAoIEludGVnZXIgKSB0eXBlMkNvZGUuZ2V0KCB2YWx1ZVR5cGUgKTsKKyAgICAgICAgaWYgKCBjb2RlICE9IG51bGwgKQorICAgICAgICB7CisgICAgICAgICAgICBvdXQud3JpdGUoICggY2hhciApIGNvZGUuaW50VmFsdWUoKSApOworICAgICAgICB9CisgICAgfQorCisKKyAgICBwcml2YXRlIHN0YXRpYyB2b2lkIHdyaXRlU2ltcGxlKCBXcml0ZXIgb3V0LCBPYmplY3QgdmFsdWUgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIGlmICggdmFsdWUgaW5zdGFuY2VvZiBEb3VibGUgKQorICAgICAgICB7CisgICAgICAgICAgICBkb3VibGUgZFZhbCA9ICggKCBEb3VibGUgKSB2YWx1ZSApLmRvdWJsZVZhbHVlKCk7CisgICAgICAgICAgICB2YWx1ZSA9IG5ldyBMb25nKCBEb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyggZFZhbCApICk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoIHZhbHVlIGluc3RhbmNlb2YgRmxvYXQgKQorICAgICAgICB7CisgICAgICAgICAgICBmbG9hdCBmVmFsID0gKCAoIEZsb2F0ICkgdmFsdWUgKS5mbG9hdFZhbHVlKCk7CisgICAgICAgICAgICB2YWx1ZSA9IG5ldyBJbnRlZ2VyKCBGbG9hdC5mbG9hdFRvUmF3SW50Qml0cyggZlZhbCApICk7CisgICAgICAgIH0KKworICAgICAgICBvdXQud3JpdGUoIFRPS0VOX1ZBTF9PUEVOICk7CisgICAgICAgIHdyaXRlUXVvdGVkKCBvdXQsIFN0cmluZy52YWx1ZU9mKCB2YWx1ZSApICk7CisgICAgICAgIG91dC53cml0ZSggVE9LRU5fVkFMX0NMT1MgKTsKKyAgICB9CisKKworICAgIHByaXZhdGUgc3RhdGljIHZvaWQgd3JpdGVRdW90ZWQoIFdyaXRlciBvdXQsIFN0cmluZyBzaW1wbGUgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIGlmICggc2ltcGxlID09IG51bGwgfHwgc2ltcGxlLmxlbmd0aCgpID09IDAgKQorICAgICAgICB7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAgICBjaGFyIGMgPSAwOworICAgICAgICBpbnQgbGVuID0gc2ltcGxlLmxlbmd0aCgpOworICAgICAgICBmb3IgKCBpbnQgaSA9IDA7IGkgPCBsZW47IGkrKyApCisgICAgICAgIHsKKyAgICAgICAgICAgIGMgPSBzaW1wbGUuY2hhckF0KCBpICk7CisgICAgICAgICAgICBzd2l0Y2ggKCBjICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBjYXNlICdcXCc6CisgICAgICAgICAgICAgICAgY2FzZSBUT0tFTl9WQUxfQ0xPUzoKKyAgICAgICAgICAgICAgICAgICAgb3V0LndyaXRlKCAnXFwnICk7CisgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZSggYyApOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgICAgIC8vIHdlbGwga25vd24gZXNjYXBlcworICAgICAgICAgICAgICAgIGNhc2UgJ1xiJzoKKyAgICAgICAgICAgICAgICAgICAgb3V0LndyaXRlKCAiXFxiIiApOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdcdCc6CisgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZSggIlxcdCIgKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgY2FzZSAnXG4nOgorICAgICAgICAgICAgICAgICAgICBvdXQud3JpdGUoICJcXG4iICk7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGNhc2UgJ1xmJzoKKyAgICAgICAgICAgICAgICAgICAgb3V0LndyaXRlKCAiXFxmIiApOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjYXNlICdccic6CisgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZSggIlxcciIgKTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgICAgICAvLyBvdGhlciBlc2NhcGluZworICAgICAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgICAgIGlmICggYyA8ICcgJyApCisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB0ID0gIjAwMCIgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKCBjICk7CisgICAgICAgICAgICAgICAgICAgICAgICBvdXQud3JpdGUoICJcXHUiICsgdC5zdWJzdHJpbmcoIHQubGVuZ3RoKCkgLSA0ICkgKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZSggYyApOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9jb25maWdhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvZmVsaXgvY20vZmlsZS9GaWxlUGVyc2lzdGVuY2VNYW5hZ2VyLmphdmEgYi9jb25maWdhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvZmVsaXgvY20vZmlsZS9GaWxlUGVyc2lzdGVuY2VNYW5hZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGI5OWIwYgotLS0gL2Rldi9udWxsCisrKyBiL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9maWxlL0ZpbGVQZXJzaXN0ZW5jZU1hbmFnZXIuamF2YQpAQCAtMCwwICsxLDQzNiBAQAorLyogCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuZmVsaXguY20uZmlsZTsKKworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkJpdFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuRGljdGlvbmFyeTsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuTm9TdWNoRWxlbWVudEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuU3RhY2s7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmZlbGl4LmNtLlBlcnNpc3RlbmNlTWFuYWdlcjsKK2ltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlQ29udGV4dDsKK2ltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuQ29uc3RhbnRzOworCisKKy8qKgorICogVGhlIDxjb2RlPkZpbGVQZXJzaXN0ZW5jZU1hbmFnZXI8L2NvZGU+IGNsYXNzIHN0b3JlcyBjb25maWd1cmF0aW9uIGRhdGEgaW4KKyAqIHByb3BlcnRpZXMtbGlrZSBmaWxlcyBpbnNpZGUgYSBnaXZlbiBkaXJlY3RvcnkuIEFsbCBjb25maWd1cmF0aW9uIGZpbGVzIGFyZQorICogbG9jYXRlZCBpbiB0aGUgc2FtZSBkaXJlY3RvcnkuCisgKiA8cD4KKyAqIFRoZSBjb25maWd1cmF0aW9uIGRpcmVjdG9yeSBtYXkgYmUgc2V0IGJ5IHVzaW5nIHRoZQorICoge0BsaW5rICNGaWxlUGVyc2lzdGVuY2VNYW5hZ2VyKFN0cmluZyl9IG5hbWluZyB0aGUgcGF0aCB0byB0aGUgZGlyZWN0cnkuIFdoZW4KKyAqIHRoaXMgcGVyc2lzdGVuY2UgbWFuYWdlciBpcyB1c2VkIGJ5IHRoZSBDb25maWd1cmF0aW9uIEFkbWluIFNlcnZpY2UsIHRoZQorICogbG9jYXRpb24gbWF5IGJlIGNvbmZpZ3VyZWQgdXNpbmcgdGhlIHtAbGluayAjQ01fQ09ORklHX0RJUn0gYnVuZGxlIGNvbnRleHQKKyAqIHByb3BlcnR5LgorICogPHA+CisgKiBJZiB0aGUgbG9jYXRpb24gaXMgbm90IHNldCwgdGhlIDxjb2RlPmNvbmZpZzwvY29kZT4gZGlyZWN0b3J5IGluIHRoZSBjdXJyZW50CisgKiB3b3JraW5nIGRpcmVjdG9yeSAoYXMgc2V0IGluIHRoZSA8Y29kZT51c2VyLmRpcjwvY29kZT4gc3lzdGVtIHByb3BlcnR5KSBpcworICogdXNlZC4gSWYgdGhlIHRoZSBsb2NhdGlvbiBpcyBzZXQgYnV0LCBubyBzdWNoIGRpcmVjdG9yeSBleGlzdHMsIHRoZSBkaXJlY3RvcnkKKyAqIGFuZCBhbnkgbWlzc2luZyBwYXJlbnQgZGlyZWN0b3JpZXMgYXJlIGNyZWF0ZWQuIElmIGEgZmlsZSBleGlzdHMgYXQgdGhlIGdpdmVuCisgKiBsb2NhdGlvbiwgdGhlIGNvbnN0cnVjdG9yIGZhaWxzLgorICogPHA+CisgKiBDb25maWd1cmF0aW9uIGZpbGVzIGFyZSBjcmVhdGVkIGluIHRoZSBjb25maWd1cmF0aW9uIGRpcmVjdG9yeSBieSBhcHBlbmRpbmcKKyAqIHRoZSBleHRlbnNpb24gPGNvZGU+LmNvbmZpZzwvY29kZT4gdG8gdGhlIFBJRCBvZiB0aGUgY29uZmlndXJhdGlvbi4gVGhlIFBJRAorICogaXMgY29udmVydGVkIGludG8gYSByZWxhdGl2ZSBwYXRoIG5hbWUgYnkgcmVwbGFjaW5nIGVuY2xvc2VkIGRvdHMgdG8gc2xhc2hlcy4KKyAqIE5vbi08Y29kZT5zeW1ib2xpYy1uYW1lPC9jb2RlPiBjaGFyYWN0ZXJzIGluIHRoZSBQSUQgYXJlIGVuY29kZWQgd2l0aCB0aGVpcgorICogVW5pY29kZSBjaGFyYWN0ZXIgY29kZSBpbiBoZXhhZGVjaW1hbC4KKyAqIDxwPgorICogPHRhYmxlIGJvcmRlcj0iMCIgY2VsbHNwYWNpbmc9IjMiIGNlbGxwYWRkaW5nPSIwIj4KKyAqIDx0cj48dGQgY29sc3Bhbj0iMiI+PGI+RXhhbXBsZXMgb2YgUElEIHRvIG5hbWUgY29udmVyc2lvbjo8L3RkPjwvdHI+CisgKiA8dHI+PHRoPlBJRDwvdGg+PHRoPkNvbmZpZ3VyYXRpb24gRmlsZSBOYW1lPC90aD48L3RyPgorICogPHRyPjx0ZD48Y29kZT5zYW1wbGU8L2NvZGU+PHRkPjxjb2RlPnNhbXBsZS5jb25maWc8L2NvZGU+PC90cj4KKyAqIDx0cj48dGQ+PGNvZGU+b3JnLmFwYWNoZS5mZWxpeC5sb2cuTG9nU2VydmljZTwvY29kZT48dGQ+PGNvZGU+b3JnL2FwYWNoZS9mZWxpeC9sb2cvTG9nU2VydmljZS5jb25maWc8L2NvZGU+PC90cj4KKyAqIDx0cj48dGQ+PGNvZGU+c2FtcGxlLmZs6GNoZTwvY29kZT48dGQ+PGNvZGU+c2FtcGxlL2ZsJTAwZThjaGUuY29uZmlnPC9jb2RlPjwvdHI+CisgKiA8L3RhYmxlPgorICoKKyAqIEBhdXRob3IgZm1lc2NoYmUKKyAqLworcHVibGljIGNsYXNzIEZpbGVQZXJzaXN0ZW5jZU1hbmFnZXIgaW1wbGVtZW50cyBQZXJzaXN0ZW5jZU1hbmFnZXIKK3sKKworICAgIC8qKgorICAgICAqIFRoZSBleHRlbnNpb24gb2YgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZXMuCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfRVhUID0gIi5jb25maWciOworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQml0U2V0IFZBTElEX1BBVEhfQ0hBUlM7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYWJzdHJhY3QgcGF0aCBuYW1lIG9mIHRoZSBjb25maWd1cmF0aW9uIGZpbGVzLgorICAgICAqLworICAgIHByaXZhdGUgZmluYWwgRmlsZSBsb2NhdGlvbjsKKworICAgIC8vIHNldHMgdXAgdGhpcyBjbGFzcyBkZWZpbmluZyB0aGUgc2V0IG9mIHZhbGlkIGNoYXJhY3RlcnMgaW4gcGF0aAorICAgIC8vIHNldCBnZXRGaWxlKFN0cmluZykgZm9yIGRldGFpbHMuCisgICAgc3RhdGljCisgICAgeworICAgICAgICBWQUxJRF9QQVRIX0NIQVJTID0gbmV3IEJpdFNldCgpOworCisgICAgICAgIGZvciAoIGludCBpID0gJ2EnOyBpIDw9ICd6JzsgaSsrICkKKyAgICAgICAgeworICAgICAgICAgICAgVkFMSURfUEFUSF9DSEFSUy5zZXQoIGkgKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKCBpbnQgaSA9ICdBJzsgaSA8PSAnWic7IGkrKyApCisgICAgICAgIHsKKyAgICAgICAgICAgIFZBTElEX1BBVEhfQ0hBUlMuc2V0KCBpICk7CisgICAgICAgIH0KKyAgICAgICAgZm9yICggaW50IGkgPSAnMCc7IGkgPD0gJzknOyBpKysgKQorICAgICAgICB7CisgICAgICAgICAgICBWQUxJRF9QQVRIX0NIQVJTLnNldCggaSApOworICAgICAgICB9CisgICAgICAgIFZBTElEX1BBVEhfQ0hBUlMuc2V0KCBGaWxlLnNlcGFyYXRvckNoYXIgKTsKKyAgICAgICAgVkFMSURfUEFUSF9DSEFSUy5zZXQoICcgJyApOworICAgICAgICBWQUxJRF9QQVRIX0NIQVJTLnNldCggJy0nICk7CisgICAgICAgIFZBTElEX1BBVEhfQ0hBUlMuc2V0KCAnXycgKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgdGhpcyBwZXJzaXN0ZW5jZSBtYW5hZ2VyIHVzaW5nIHRoZSBnaXZlbiBsb2NhdGlvbgorICAgICAqIGFzIHRoZSBkaXJlY3RvcnkgdG8gc3RvcmUgYW5kIHJldHJpZXZlIHRoZSBjb25maWd1cmF0aW9uIGZpbGVzLgorICAgICAqIAorICAgICAqIEBwYXJhbSBsb2NhdGlvbiBUaGUgY29uZmlndXJhdGlvbiBmaWxlIGxvY2F0aW9uLiBJZiB0aGlzIGlzCisgICAgICogICAgICA8Y29kZT5udWxsPC9jb2RlPiB0aGUgPGNvZGU+Y29uZmlnPC9jb2RlPiBkaXJlY3RvcnkgYmVsb3cgdGhlIGN1cnJlbnQKKyAgICAgKiAgICAgIHdvcmtpbmcgZGlyZWN0b3J5IGlzIHVzZWQuCisgICAgICogCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIGxvY2F0aW9uIGV4aXN0cyBidXQgaXMgbm90IGEKKyAgICAgKiAgICAgIGRpcmVjdG9yeSBvciBkb2VzIG5vdCBleGlzdCBhbmQgY2Fubm90IGJlIGNyZWF0ZWQuCisgICAgICovCisgICAgcHVibGljIEZpbGVQZXJzaXN0ZW5jZU1hbmFnZXIoIFN0cmluZyBsb2NhdGlvbiApCisgICAgeworICAgICAgICBpZiAoIGxvY2F0aW9uID09IG51bGwgKQorICAgICAgICB7CisgICAgICAgICAgICBsb2NhdGlvbiA9IFN5c3RlbS5nZXRQcm9wZXJ0eSggInVzZXIuZGlyIiApICsgIi9jb25maWciOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2hlY2sgdGhlIGxvY2F0aW9uCisgICAgICAgIEZpbGUgbG9jYXRpb25GaWxlID0gbmV3IEZpbGUoIGxvY2F0aW9uICk7CisgICAgICAgIGlmICggIWxvY2F0aW9uRmlsZS5pc0RpcmVjdG9yeSgpICkKKyAgICAgICAgeworICAgICAgICAgICAgaWYgKCBsb2NhdGlvbkZpbGUuZXhpc3RzKCkgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIGxvY2F0aW9uICsgIiBpcyBub3QgYSBkaXJlY3RvcnkiICk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICggIWxvY2F0aW9uRmlsZS5ta2RpcnMoKSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiggIkNhbm5vdCBjcmVhdGUgZGlyZWN0b3J5ICIgKyBsb2NhdGlvbiApOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgdGhpcy5sb2NhdGlvbiA9IGxvY2F0aW9uRmlsZTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIExvYWRzIGNvbmZpZ3VyYXRpb24gZGF0YSBmcm9tIHRoZSBjb25maWd1cmF0aW9uIGxvY2F0aW9uIGFuZCByZXR1cm5zCisgICAgICogaXQgYXMgPGNvZGU+RGljdGlvbmFyeTwvY29kZT4gb2JqZWN0cy4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBhIGxhenkgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIGp1c3Qgb25lIGNvbmZpZ3VyYXRpb24KKyAgICAgKiBmaWxlIGFoZWFkIG9mIHRoZSBjdXJyZW50IGVudW1lcmF0aW9uIGxvY2F0aW9uLgorICAgICAqIAorICAgICAqIEByZXR1cm4gYW4gZW51bWVyYXRpb24gb2YgY29uZmlndXJhdGlvbiBkYXRhIHJldHVybmVkIGFzIGluc3RhbmNlcyBvZgorICAgICAqICAgICAgdGhlIDxjb2RlPkRpY3Rpb25hcnk8L2NvZGU+IGNsYXNzLgorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBnZXREaWN0aW9uYXJpZXMoKQorICAgIHsKKyAgICAgICAgcmV0dXJuIG5ldyBEaWN0aW9uYXJ5RW51bWVyYXRpb24oKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIERlbGV0ZXMgdGhlIGZpbGUgZm9yIHRoZSBnaXZlbiBpZGVudGlmaWVyLgorICAgICAqIAorICAgICAqIEBwYXJhbSBwaWQgVGhlIGlkZW50aWZpZXIgb2YgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZSB0byBkZWxldGUuCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVsZXRlKCBTdHJpbmcgcGlkICkKKyAgICB7CisgICAgICAgIGdldEZpbGUoIHBpZCApLmRlbGV0ZSgpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiBhIChjb25maWd1cmF0aW9uKSBmaWxlIGV4aXN0cyBmb3IgdGhlIGdpdmVuCisgICAgICogaWRlbnRpZmllci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGlkIFRoZSBpZGVudGlmaWVyIG9mIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgdG8gY2hlY2suCisgICAgICogCisgICAgICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgZmlsZSBleGlzdHMKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoIFN0cmluZyBwaWQgKQorICAgIHsKKyAgICAgICAgcmV0dXJuIGdldEZpbGUoIHBpZCApLmlzRmlsZSgpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmVhZHMgdGhlIChjb25maWd1cmF0aW9uKSBmb3IgdGhlIGdpdmVuIGlkZW50aWZpZXIgaW50byBhCisgICAgICogPGNvZGU+RGljdGlvbmFyeTwvY29kZT4gb2JqZWN0LgorICAgICAqIAorICAgICAqIEBwYXJhbSBwaWQgVGhlIGlkZW50aWZpZXIgb2YgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZSB0byBkZWxldGUuCisgICAgICogCisgICAgICogQHJldHVybiBUaGUgY29uZmlndXJhdGlvbiByZWFkIGZyb20gdGhlIGZpbGUuIFRoaXMgPGNvZGU+RGljdGlvbmFyeTwvY29kZT4KKyAgICAgKiAgICAgIG1heSBiZSBlbXB0eSBpZiB0aGUgZmlsZSBjb250YWlucyBubyBjb25maWd1cmF0aW9uIGluZm9ybWF0aW9uCisgICAgICogICAgICBvciBpcyBub3QgcHJvcGVybHkgZm9ybWF0dGVkLgorICAgICAqLworICAgIHB1YmxpYyBEaWN0aW9uYXJ5IGxvYWQoIFN0cmluZyBwaWQgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIHJldHVybiBsb2FkKCBnZXRGaWxlKCBwaWQgKSApOworICAgIH0KKworCisgICAgLyoqCisgICAgICogU3RvcmVzIHRoZSBjb250ZW50cyBvZiB0aGUgPGNvZGU+RGljdGlvbmFyeTwvY29kZT4gaW4gYSBmaWxlIGRlbm90ZWQKKyAgICAgKiBieSB0aGUgZ2l2ZW4gaWRlbnRpZmllci4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gcGlkIFRoZSBpZGVudGlmaWVyIG9mIHRoZSBjb25maWd1cmF0aW9uIGZpbGUgdG8gd2hpY2ggdG8gd3JpdGUKKyAgICAgKiAgICAgIHRoZSBjb25maWd1cmF0aW9uIGNvbnRlbnRzLgorICAgICAqIEBwYXJhbSBwcm9wcyBUaGUgY29uZmlndXJhdGlvbiBkYXRhIHRvIHdyaXRlLgorICAgICAqIAorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gSWYgYW4gZXJyb3Igb2NjdXJycyB3cml0aW5nIHRoZSBjb25maWd1cmF0aW9uIGRhdGEuCisgICAgICovCisgICAgcHVibGljIHZvaWQgc3RvcmUoIFN0cmluZyBwaWQsIERpY3Rpb25hcnkgcHJvcHMgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIE91dHB1dFN0cmVhbSBvdXQgPSBudWxsOworICAgICAgICB0cnkKKyAgICAgICAgeworICAgICAgICAgICAgRmlsZSBjZmdGaWxlID0gZ2V0RmlsZSggcGlkICk7CisgICAgICAgICAgICAKKyAgICAgICAgICAgIC8vIGVuc3VyZSBwYXJlbnQgcGF0aAorICAgICAgICAgICAgY2ZnRmlsZS5nZXRQYXJlbnRGaWxlKCkubWtkaXJzKCk7CisKKyAgICAgICAgICAgIAorICAgICAgICAgICAgb3V0ID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oIGNmZ0ZpbGUgKTsKKyAgICAgICAgICAgIENvbmZpZ3VyYXRpb25IYW5kbGVyLndyaXRlKCBvdXQsIHByb3BzICk7CisgICAgICAgIH0KKyAgICAgICAgZmluYWxseQorICAgICAgICB7CisgICAgICAgICAgICBpZiAoIG91dCAhPSBudWxsICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICB0cnkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXRjaCAoIElPRXhjZXB0aW9uIGlvZSApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKworICAgIC8qKgorICAgICAqIExvYWRzIHRoZSBjb250ZW50cyBvZiB0aGUgPGNvZGU+Y2ZnRmlsZTwvY29kZT4gaW50byBhIG5ldworICAgICAqIDxjb2RlPkRpY3Rpb25hcnk8L2NvZGU+IG9iamVjdC4KKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gY2ZnRmlsZSBUaGUgZmlsZSBmcm9tIHdoaWNoIHRvIGxvYWQgdGhlIGRhdGEuCisgICAgICogCisgICAgICogQHJldHVybiBBIG5ldyA8Y29kZT5EaWN0aW9uYXJ5PC9jb2RlPiBvYmplY3QgcHJvdmlkaW5nIHRoZSBmaWxlIGNvbnRlbnRzLgorICAgICAqIAorICAgICAqIEB0aHJvd3MgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb24gSWYgdGhlIGdpdmVuIGZpbGUgZG9lcyBub3QgZXhpc3QuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBJZiBhbiBlcnJvciBvY2N1cnJzIHJlYWRpbmcgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIERpY3Rpb25hcnkgbG9hZCggRmlsZSBjZmdGaWxlICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBJbnB1dFN0cmVhbSBpbnMgPSBudWxsOworICAgICAgICB0cnkKKyAgICAgICAgeworICAgICAgICAgICAgaW5zID0gbmV3IEZpbGVJbnB1dFN0cmVhbSggY2ZnRmlsZSApOworICAgICAgICAgICAgcmV0dXJuIENvbmZpZ3VyYXRpb25IYW5kbGVyLnJlYWQoIGlucyApOworICAgICAgICB9CisgICAgICAgIGZpbmFsbHkKKyAgICAgICAgeworICAgICAgICAgICAgaWYgKCBpbnMgIT0gbnVsbCApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgdHJ5CisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBpbnMuY2xvc2UoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2F0Y2ggKCBJT0V4Y2VwdGlvbiBpb2UgKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDcmVhdGVzIGFuIGFic3RyYWN0IHBhdGggbmFtZSBmb3IgdGhlIDxjb2RlPnBpZDwvY29kZT4gZW5jb2RpbmcgaXQgYXMKKyAgICAgKiBmb2xsb3dzOgorICAgICAqIDx1bD4KKyAgICAgKiA8bGk+RG90cyAoPGNvZGU+LjwvY29kZT4pIGFyZSByZXBsYWNlZCBieSA8Y29kZT5GaWxlLnNlcGFyYXRvckNoYXI8L2NvZGU+CisgICAgICogPGxpPkNoYXJhY3RlcnMgbm90IG1hdGNoaW5nIFthLXpBLVowLTkgXy1dIGFyZSBlbmNvZGVkIHdpdGggYSBwZXJjZW50CisgICAgICogIGNoYXJhY3RlciAoPGNvZGU+JTwvY29kZT4pIGFuZCBhIDQtcGxhY2UgaGV4YWRlY2ltYWwgdW5pY29kZSB2YWx1ZS4KKyAgICAgKiA8L3VsPgorICAgICAqIEJlZm9yZSByZXR1cm5pbmcgdGhlIHBhdGggbmFtZSwgdGhlIHBhcmVudCBkaXJlY3RvcnkgYW5kIGFueSBhbmNlc3RvcnMKKyAgICAgKiBhcmUgY3JlYXRlZC4KKyAgICAgKiAgCisgICAgICogQHBhcmFtIHBpZCBUaGUgaWRlbnRpZmllciBmb3Igd2hpY2ggdG8gY3JlYXRlIHRoZSBhYnN0cmFjdCBmaWxlIG5hbWUuCisgICAgICogCisgICAgICogQHJldHVybiBUaGUgYWJzdHJhY3QgcGF0aCBuYW1lLCB3aGljaCB0aGUgcGFyZW50IGRpcmVjdG9yeSBwYXRoIGNyZWF0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBGaWxlIGdldEZpbGUoIFN0cmluZyBwaWQgKQorICAgIHsKKyAgICAgICAgLy8gcmVwbGFjZSBkb3RzIGJ5IEZpbGUuc2VwYXJhdG9yQ2hhcgorICAgICAgICBwaWQgPSBwaWQucmVwbGFjZSggJy4nLCBGaWxlLnNlcGFyYXRvckNoYXIgKTsKKworICAgICAgICAvLyByZXBsYWNlIHNsYXNoIGJ5IEZpbGUuc2VwYXJhdG9yQ2hhciBpZiBkaWZmZXJlbnQKKyAgICAgICAgaWYgKCBGaWxlLnNlcGFyYXRvckNoYXIgIT0gJy8nICkKKyAgICAgICAgeworICAgICAgICAgICAgcGlkID0gcGlkLnJlcGxhY2UoICcvJywgRmlsZS5zZXBhcmF0b3JDaGFyICk7CisgICAgICAgIH0KKworICAgICAgICAvLyBzY2FuIGZvciBmaXJzdCBub24tdmFsaWQgY2hhcmFjdGVyIChpZiBhbnkpCisgICAgICAgIGludCBmaXJzdCA9IDA7CisgICAgICAgIHdoaWxlICggZmlyc3QgPCBwaWQubGVuZ3RoKCkgJiYgVkFMSURfUEFUSF9DSEFSUy5nZXQoIHBpZC5jaGFyQXQoIGZpcnN0ICkgKSApCisgICAgICAgIHsKKyAgICAgICAgICAgIGZpcnN0Kys7CisgICAgICAgIH0KKworICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHdlIGV4aGF1c3RlZAorICAgICAgICBpZiAoIGZpcnN0IDwgcGlkLmxlbmd0aCgpICkKKyAgICAgICAgeworICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoIHBpZC5zdWJzdHJpbmcoIDAsIGZpcnN0ICkgKTsKKworICAgICAgICAgICAgZm9yICggaW50IGkgPSBmaXJzdDsgaSA8IHBpZC5sZW5ndGgoKTsgaSsrICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBjaGFyIGMgPSBwaWQuY2hhckF0KCBpICk7CisgICAgICAgICAgICAgICAgaWYgKCBWQUxJRF9QQVRIX0NIQVJTLmdldCggYyApICkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIGMgKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbCA9ICIwMDAiICsgSW50ZWdlci50b0hleFN0cmluZyggYyApOworICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAnJScgKTsKKyAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCggdmFsLnN1YnN0cmluZyggdmFsLmxlbmd0aCgpIC0gNCApICk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwaWQgPSBidWYudG9TdHJpbmcoKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBuZXcgRmlsZSggbG9jYXRpb24sIHBpZCArIEZJTEVfRVhUICk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhlIDxjb2RlPkRpY3Rpb25hcnlFbnVtZXJhdGlvbjwvY29kZT4gY2xhc3MgaW1wbGVtZW50cyB0aGUKKyAgICAgKiA8Y29kZT5FbnVtZXJhdGlvbjwvY29kZT4gcmV0dXJuaW5nIGNvbmZpZ3VyYXRpb24gPGNvZGU+RGljdGlvbmFyeTwvY29kZT4KKyAgICAgKiBvYmplY3RzIG9uIGJlaGFsZiBvZiB0aGUge0BsaW5rIEZpbGVQZXJzaXN0ZW5jZU1hbmFnZXIjZ2V0RGljdGlvbmFyaWVzKCl9CisgICAgICogbWV0aG9kLgorICAgICAqIDxwPgorICAgICAqIFRoaXMgZW51bWVyYXRpb24gbG9hZHMgY29uZmlndXJhdGlvbiBsYXppbHkgd2l0aCBhIGxvb2sgYWhlYWQgb2Ygb25lCisgICAgICogZGljdGlvbmFyeS4KKyAgICAgKgorICAgICAqIEBhdXRob3IgZm1lc2NoYmUKKyAgICAgKi8KKyAgICBwcml2YXRlIGNsYXNzIERpY3Rpb25hcnlFbnVtZXJhdGlvbiBpbXBsZW1lbnRzIEVudW1lcmF0aW9uCisgICAgeworICAgICAgICBwcml2YXRlIFN0YWNrIGRpclN0YWNrOworICAgICAgICBwcml2YXRlIEZpbGVbXSBmaWxlTGlzdDsKKyAgICAgICAgcHJpdmF0ZSBpbnQgaWR4OworICAgICAgICBwcml2YXRlIERpY3Rpb25hcnkgbmV4dDsKKworCisgICAgICAgIERpY3Rpb25hcnlFbnVtZXJhdGlvbigpCisgICAgICAgIHsKKyAgICAgICAgICAgIGRpclN0YWNrID0gbmV3IFN0YWNrKCk7CisgICAgICAgICAgICBmaWxlTGlzdCA9IG51bGw7CisgICAgICAgICAgICBpZHggPSAwOworCisgICAgICAgICAgICBkaXJTdGFjay5wdXNoKCBsb2NhdGlvbiApOworICAgICAgICAgICAgbmV4dCA9IHNlZWsoKTsKKyAgICAgICAgfQorCisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuIG5leHQgIT0gbnVsbDsKKyAgICAgICAgfQorCisKKyAgICAgICAgcHVibGljIE9iamVjdCBuZXh0RWxlbWVudCgpCisgICAgICAgIHsKKyAgICAgICAgICAgIGlmICggbmV4dCA9PSBudWxsICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm9TdWNoRWxlbWVudEV4Y2VwdGlvbigpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBEaWN0aW9uYXJ5IHRvUmV0dXJuID0gbmV4dDsKKyAgICAgICAgICAgIG5leHQgPSBzZWVrKCk7CisgICAgICAgICAgICByZXR1cm4gdG9SZXR1cm47CisgICAgICAgIH0KKworCisgICAgICAgIHByaXZhdGUgRGljdGlvbmFyeSBzZWVrKCkKKyAgICAgICAgeworICAgICAgICAgICAgd2hpbGUgKCAoIGZpbGVMaXN0ICE9IG51bGwgJiYgaWR4IDwgZmlsZUxpc3QubGVuZ3RoICkgfHwgIWRpclN0YWNrLmlzRW1wdHkoKSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgaWYgKCBmaWxlTGlzdCA9PSBudWxsIHx8IGlkeCA+PSBmaWxlTGlzdC5sZW5ndGggKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgRmlsZSBkaXIgPSAoIEZpbGUgKSBkaXJTdGFjay5wb3AoKTsKKyAgICAgICAgICAgICAgICAgICAgZmlsZUxpc3QgPSBkaXIubGlzdEZpbGVzKCk7CisgICAgICAgICAgICAgICAgICAgIGlkeCA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICB7CisKKyAgICAgICAgICAgICAgICAgICAgRmlsZSBjZmdGaWxlID0gZmlsZUxpc3RbaWR4KytdOworICAgICAgICAgICAgICAgICAgICBpZiAoIGNmZ0ZpbGUuaXNGaWxlKCkgKQorICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkKKyAgICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWN0aW9uYXJ5IGRpY3QgPSAgbG9hZCggY2ZnRmlsZSApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZSB0aGUgZGljdGlvbmFyeSBpZiBpdCBoYXMgYSBQSUQgYW5kIHRoZSBQSUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZXJpdmVkIGZpbGUgbmFtZSBtYXRjaGVzIHRoZSBzb3VyY2UgZmlsZSBuYW1lIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggZGljdC5nZXQoIENvbnN0YW50cy5TRVJWSUNFX1BJRCApICE9IG51bGwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgY2ZnRmlsZS5lcXVhbHMoIGdldEZpbGUoICggU3RyaW5nICkgZGljdC5nZXQoIENvbnN0YW50cy5TRVJWSUNFX1BJRCApICkgKSApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGljdDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoIElPRXhjZXB0aW9uIGlvZSApCisgICAgICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlLCBjaGVjayBuZXh0IGZpbGUKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICggY2ZnRmlsZS5pc0RpcmVjdG9yeSgpICkKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgZGlyU3RhY2sucHVzaCggY2ZnRmlsZSApOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBleGhhdXN0ZWQKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ltcGwvQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeS5qYXZhIGIvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ltcGwvQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM5Yjk5MmQKLS0tIC9kZXYvbnVsbAorKysgYi9jb25maWdhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvZmVsaXgvY20vaW1wbC9DYXNlSW5zZW5zaXRpdmVEaWN0aW9uYXJ5LmphdmEKQEAgLTAsMCArMSwyNjYgQEAKKy8qIAorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmZlbGl4LmNtLmltcGw7CisKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuRGljdGlvbmFyeTsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCisKKy8qKgorICogVGhlIDxjb2RlPkNhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnk8L2NvZGU+IGlzIGEKKyAqIDxjb2RlPmphdmEudXRpbC5EaWN0aW9uYXJ5PC9jb2RlPiB3aGljaCBjb25mb3JtcyB0byB0aGUgcmVxdWlyZW1lbnRzIGxhaWQKKyAqIG91dCBieSB0aGUgQ29uZmlndXJhdGlvbiBBZG1pbiBTZXJ2aWNlIFNwZWNpZmljYXRpb24gcmVxdWlyaW5nIHRoZSBwcm9wZXJ0eQorICogbmFtZXMgdG8ga2VlcCBjYXNlIGJ1dCB0byBpZ25vcmUgY2FzZSB3aGVuIGFjY2Vzc2luZyB0aGUgcHJvcGVydGllcy4KKyAqCisgKiBAYXV0aG9yIGZtZXNjaGJlCisgKi8KK2NsYXNzIENhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnkgZXh0ZW5kcyBEaWN0aW9uYXJ5Cit7CisKKyAgICAvKioKKyAgICAgKiBUaGUgYmFja2VuZCBkaWN0aW9uYXJ5IHdpdGggbG93ZXIgY2FzZSBrZXlzLgorICAgICAqLworICAgIHByaXZhdGUgSGFzaHRhYmxlIGludGVybmFsTWFwOworCisgICAgLyoqCisgICAgICogTWFwcGluZyBvZiBsb3dlciBjYXNlIGtleXMgdG8gb3JpZ2luYWwgY2FzZSBrZXlzIGFzIGxhc3QgdXNlZCB0byBzZXQKKyAgICAgKiBhIHByb3BlcnR5IHZhbHVlLgorICAgICAqLworICAgIHByaXZhdGUgSGFzaHRhYmxlIG9yaWdpbmFsS2V5czsKKworCisgICAgQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeSgpCisgICAgeworICAgICAgICBpbnRlcm5hbE1hcCA9IG5ldyBIYXNodGFibGUoKTsKKyAgICAgICAgb3JpZ2luYWxLZXlzID0gbmV3IEhhc2h0YWJsZSgpOworICAgIH0KKworCisgICAgQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeSggRGljdGlvbmFyeSBwcm9wcyApCisgICAgeworICAgICAgICB0aGlzKCk7CisKKyAgICAgICAgRW51bWVyYXRpb24ga2V5cyA9IHByb3BzLmtleXMoKTsKKyAgICAgICAgd2hpbGUgKCBrZXlzLmhhc01vcmVFbGVtZW50cygpICkKKyAgICAgICAgeworICAgICAgICAgICAgT2JqZWN0IGtleSA9IGtleXMubmV4dEVsZW1lbnQoKTsKKyAgICAgICAgICAgIGlmICggISgga2V5IGluc3RhbmNlb2YgU3RyaW5nICkgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oICJLZXkgWyIgKyBrZXkgKyAiXSBtdXN0IGJlIGEgU3RyaW5nIiApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBjaGVjayB1bmlxdWVuZXNzIG9mIGtleQorICAgICAgICAgICAgU3RyaW5nIGxvd2VyQ2FzZSA9ICggKCBTdHJpbmcgKSBrZXkgKS50b0xvd2VyQ2FzZSgpOworICAgICAgICAgICAgaWYgKCBpbnRlcm5hbE1hcC5jb250YWluc0tleSggbG93ZXJDYXNlICkgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oICJLZXkgWyIgKyBrZXkgKyAiXSBhbHJlYWR5IHByZXNlbnQgaW4gZGlmZmVyZW50IGNhc2UiICk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGNoZWNrIHRoZSB2YWx1ZQorICAgICAgICAgICAgT2JqZWN0IHZhbHVlID0gcHJvcHMuZ2V0KCBrZXkgKTsKKyAgICAgICAgICAgIGNoZWNrVmFsdWUoIHZhbHVlICk7CisKKyAgICAgICAgICAgIC8vIGFkZCB0aGUga2V5L3ZhbHVlIHBhaXIKKyAgICAgICAgICAgIGludGVybmFsTWFwLnB1dCggbG93ZXJDYXNlLCB2YWx1ZSApOworICAgICAgICAgICAgb3JpZ2luYWxLZXlzLnB1dCggbG93ZXJDYXNlLCBrZXkgKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeSggQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeSBwcm9wcyApCisgICAgeworICAgICAgICBpbnRlcm5hbE1hcCA9IG5ldyBIYXNodGFibGUoIHByb3BzLmludGVybmFsTWFwICk7CisgICAgICAgIG9yaWdpbmFsS2V5cyA9IG5ldyBIYXNodGFibGUoIHByb3BzLm9yaWdpbmFsS2V5cyApOworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgamF2YS51dGlsLkRpY3Rpb25hcnkjZWxlbWVudHMoKQorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBlbGVtZW50cygpCisgICAgeworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW51bWVyYXRpb24oIGludGVybmFsTWFwLnZhbHVlcygpICk7CisgICAgfQorCisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBqYXZhLnV0aWwuRGljdGlvbmFyeSNnZXQoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldCggT2JqZWN0IGtleSApCisgICAgeworICAgICAgICBpZiAoIGtleSA9PSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCAia2V5IiApOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIHN0cmluZ0tleSA9IFN0cmluZy52YWx1ZU9mKCBrZXkgKS50b0xvd2VyQ2FzZSgpOworICAgICAgICByZXR1cm4gaW50ZXJuYWxNYXAuZ2V0KCBzdHJpbmdLZXkgKTsKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIGphdmEudXRpbC5EaWN0aW9uYXJ5I2lzRW1wdHkoKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKQorICAgIHsKKyAgICAgICAgcmV0dXJuIGludGVybmFsTWFwLmlzRW1wdHkoKTsKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIGphdmEudXRpbC5EaWN0aW9uYXJ5I2tleXMoKQorICAgICAqLworICAgIHB1YmxpYyBFbnVtZXJhdGlvbiBrZXlzKCkKKyAgICB7CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbiggb3JpZ2luYWxLZXlzLnZhbHVlcygpICk7CisgICAgfQorCisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBqYXZhLnV0aWwuRGljdGlvbmFyeSNwdXQoamF2YS5sYW5nLk9iamVjdCwgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IHB1dCggT2JqZWN0IGtleSwgT2JqZWN0IHZhbHVlICkKKyAgICB7CisgICAgICAgIGlmICgga2V5ID09IG51bGwgfHwgdmFsdWUgPT0gbnVsbCApCisgICAgICAgIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbiggImtleSBvciB2YWx1ZSIgKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICggISgga2V5IGluc3RhbmNlb2YgU3RyaW5nICkgKQorICAgICAgICB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCAiS2V5IFsiICsga2V5ICsgIl0gbXVzdCBiZSBhIFN0cmluZyIgKTsKKyAgICAgICAgfQorCisgICAgICAgIGNoZWNrVmFsdWUoIHZhbHVlICk7CisKKyAgICAgICAgU3RyaW5nIGxvd2VyQ2FzZSA9IFN0cmluZy52YWx1ZU9mKCBrZXkgKS50b0xvd2VyQ2FzZSgpOworICAgICAgICBvcmlnaW5hbEtleXMucHV0KCBsb3dlckNhc2UsIGtleSApOworICAgICAgICByZXR1cm4gaW50ZXJuYWxNYXAucHV0KCBsb3dlckNhc2UsIHZhbHVlICk7CisgICAgfQorCisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBqYXZhLnV0aWwuRGljdGlvbmFyeSNyZW1vdmUoamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IHJlbW92ZSggT2JqZWN0IGtleSApCisgICAgeworICAgICAgICBpZiAoIGtleSA9PSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCAia2V5IiApOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGxvd2VyQ2FzZSA9IFN0cmluZy52YWx1ZU9mKCBrZXkgKS50b0xvd2VyQ2FzZSgpOworICAgICAgICBvcmlnaW5hbEtleXMucmVtb3ZlKCBsb3dlckNhc2UgKTsKKyAgICAgICAgcmV0dXJuIGludGVybmFsTWFwLnJlbW92ZSggbG93ZXJDYXNlICk7CisgICAgfQorCisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBqYXZhLnV0aWwuRGljdGlvbmFyeSNzaXplKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IHNpemUoKQorICAgIHsKKyAgICAgICAgcmV0dXJuIGludGVybmFsTWFwLnNpemUoKTsKKyAgICB9CisKKworICAgIC8vLS0tLS0tLS0tLSBpbnRlcm5hbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgc3RhdGljIHZvaWQgY2hlY2tWYWx1ZSggT2JqZWN0IHZhbHVlICkKKyAgICB7CisgICAgICAgIENsYXNzIHR5cGU7CisgICAgICAgIGlmICggdmFsdWUgaW5zdGFuY2VvZiBPYmplY3RbXSApCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIGNoZWNrIHNpbXBsZSBvciBwcmltaXRpdmUKKyAgICAgICAgICAgIHR5cGUgPSB2YWx1ZS5nZXRDbGFzcygpLmdldENvbXBvbmVudFR5cGUoKTsKKworICAgICAgICAgICAgLy8gY2hlY2sgZm9yIHByaW1pdGl2ZSB0eXBlCisgICAgICAgICAgICBpZiAoIHR5cGUgPT0gSW50ZWdlci5UWVBFIHx8IHR5cGUgPT0gTG9uZy5UWVBFIHx8IHR5cGUgPT0gRmxvYXQuVFlQRSB8fCB0eXBlID09IERvdWJsZS5UWVBFCisgICAgICAgICAgICAgICAgfHwgdHlwZSA9PSBCeXRlLlRZUEUgfHwgdHlwZSA9PSBTaG9ydC5UWVBFIHx8IHR5cGUgPT0gQ2hhcmFjdGVyLlRZUEUgfHwgdHlwZSA9PSBCb29sZWFuLlRZUEUgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKCB2YWx1ZSBpbnN0YW5jZW9mIFZlY3RvciApCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIGNoZWNrIHNpbXBsZQorICAgICAgICAgICAgVmVjdG9yIHZlY3RvciA9ICggVmVjdG9yICkgdmFsdWU7CisgICAgICAgICAgICBpZiAoIHZlY3Rvci5pc0VtcHR5KCkgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oICJWZWN0b3IgbXVzdCBub3QgYmUgZW1wdHkiICk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGVuc3VyZSBhbGwgZWxlbWVudHMgaGF2ZSB0aGUgc2FtZSB0eXBlCisgICAgICAgICAgICB0eXBlID0gbnVsbDsKKyAgICAgICAgICAgIGZvciAoIGludCBpID0gMDsgaSA8IHZlY3Rvci5zaXplKCk7IGkrKyApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgT2JqZWN0IGVsID0gdmVjdG9yLmdldCggaSApOworICAgICAgICAgICAgICAgIGlmICggZWwgPT0gbnVsbCApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCAiVmVjdG9yIG11c3Qgbm90IGNvbnRhaW4gbnVsbCBlbGVtZW50cyIgKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKCB0eXBlID09IG51bGwgKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgdHlwZSA9IGVsLmdldENsYXNzKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgaWYgKCB0eXBlICE9IGVsLmdldENsYXNzKCkgKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiggIlZlY3RvciBlbGVtZW50IHR5cGVzIG11c3Qgbm90IGJlIG1peGVkIiApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKCB2YWx1ZSAhPSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgLy8gZ2V0IHRoZSB0eXBlIHRvIGNoZWNrIChtdXN0IGJlIHNpbXBsZSkKKyAgICAgICAgICAgIHR5cGUgPSB2YWx1ZS5nZXRDbGFzcygpOworCisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgICAvLyBudWxsIGlzIGlsbGVnYWwKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oICJWYWx1ZSBtdXN0IG5vdCBiZSBudWxsIiApOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2hlY2sgZm9yIHNpbXBsZSB0eXBlCisgICAgICAgIGlmICggdHlwZSA9PSBTdHJpbmcuY2xhc3MgfHwgdHlwZSA9PSBJbnRlZ2VyLmNsYXNzIHx8IHR5cGUgPT0gTG9uZy5jbGFzcyB8fCB0eXBlID09IEZsb2F0LmNsYXNzCisgICAgICAgICAgICB8fCB0eXBlID09IERvdWJsZS5jbGFzcyB8fCB0eXBlID09IEJ5dGUuY2xhc3MgfHwgdHlwZSA9PSBTaG9ydC5jbGFzcyB8fCB0eXBlID09IENoYXJhY3Rlci5jbGFzcworICAgICAgICAgICAgfHwgdHlwZSA9PSBCb29sZWFuLmNsYXNzICkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgLy8gbm90IGEgdmFsaWQgdHlwZQorICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCAiVmFsdWUgWyIgKyB2YWx1ZSArICJdIGhhcyB1bnN1cHBvcnRlZCAoYmFzZS0pIHR5cGUgIiArIHR5cGUgKTsKKyAgICB9CisKKworICAgIC8vLS0tLS0tLS0tLSBPYmplY3QgT3ZlcndyaXRlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCisgICAgeworICAgICAgICByZXR1cm4gaW50ZXJuYWxNYXAudG9TdHJpbmcoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL0NvbmZpZ3VyYXRpb25BZGFwdGVyLmphdmEgYi9jb25maWdhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvZmVsaXgvY20vaW1wbC9Db25maWd1cmF0aW9uQWRhcHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmOWIyMmQKLS0tIC9kZXYvbnVsbAorKysgYi9jb25maWdhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvZmVsaXgvY20vaW1wbC9Db25maWd1cmF0aW9uQWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsMTc2IEBACisvKgorICogJFVybDogJAorICogJElkJAorICoKKyAqIENvcHlyaWdodCAxOTk3LTIwMDUgRGF5IE1hbmFnZW1lbnQgQUcKKyAqIEJhcmZ1ZXNzZXJwbGF0eiA2LCA0MDAxIEJhc2VsLCBTd2l0emVybGFuZAorICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqCisgKiBUaGlzIHNvZnR3YXJlIGlzIHRoZSBjb25maWRlbnRpYWwgYW5kIHByb3ByaWV0YXJ5IGluZm9ybWF0aW9uIG9mCisgKiBEYXkgTWFuYWdlbWVudCBBRywgKCJDb25maWRlbnRpYWwgSW5mb3JtYXRpb24iKS4gWW91IHNoYWxsIG5vdAorICogZGlzY2xvc2Ugc3VjaCBDb25maWRlbnRpYWwgSW5mb3JtYXRpb24gYW5kIHNoYWxsIHVzZSBpdCBvbmx5IGluCisgKiBhY2NvcmRhbmNlIHdpdGggdGhlIHRlcm1zIG9mIHRoZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgZW50ZXJlZCBpbnRvCisgKiB3aXRoIERheS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmZlbGl4LmNtLmltcGw7CisKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkRpY3Rpb25hcnk7CisKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNtLkNvbmZpZ3VyYXRpb247CisKKworLyoqCisgKiBUaGUgPGNvZGU+Q29uZmlndXJhdGlvbkFkYXB0ZXI8L2NvZGU+IFRPRE8KKyAqCisgKiBAYXV0aG9yIGZtZXNjaGJlCisgKiBAdmVyc2lvbiAkUmV2OiQsICREYXRlOiQKKyAqLworcHVibGljIGNsYXNzIENvbmZpZ3VyYXRpb25BZGFwdGVyIGltcGxlbWVudHMgQ29uZmlndXJhdGlvbgoreworCisgICAgcHJpdmF0ZSBDb25maWd1cmF0aW9uQWRtaW5JbXBsIGNvbmZpZ3VyYXRpb25BZG1pbjsKKyAgICBwcml2YXRlIENvbmZpZ3VyYXRpb25JbXBsIGRlbGVnYXRlZTsKKworCisgICAgQ29uZmlndXJhdGlvbkFkYXB0ZXIoIENvbmZpZ3VyYXRpb25BZG1pbkltcGwgY29uZmlndXJhdGlvbkFkbWluLCBDb25maWd1cmF0aW9uSW1wbCBkZWxlZ2F0ZWUgKQorICAgIHsKKyAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uQWRtaW4gPSBjb25maWd1cmF0aW9uQWRtaW47CisgICAgICAgIHRoaXMuZGVsZWdhdGVlID0gZGVsZWdhdGVlOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQHJldHVybgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5mZWxpeC5jbS5pbXBsLkNvbmZpZ3VyYXRpb25JbXBsI2dldFBpZCgpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQaWQoKQorICAgIHsKKyAgICAgICAgY2hlY2tEZWxldGVkKCk7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZWUuZ2V0UGlkKCk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBAcmV0dXJuCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmZlbGl4LmNtLmltcGwuQ29uZmlndXJhdGlvbkltcGwjZ2V0RmFjdG9yeVBpZCgpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRGYWN0b3J5UGlkKCkKKyAgICB7CisgICAgICAgIGNoZWNrRGVsZXRlZCgpOworICAgICAgICByZXR1cm4gZGVsZWdhdGVlLmdldEZhY3RvcnlQaWQoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEByZXR1cm4KKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuZmVsaXguY20uaW1wbC5Db25maWd1cmF0aW9uSW1wbCNnZXRCdW5kbGVMb2NhdGlvbigpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRCdW5kbGVMb2NhdGlvbigpCisgICAgeworICAgICAgICBjb25maWd1cmF0aW9uQWRtaW4uY2hlY2tQZXJtaXNzaW9uKCk7CisgICAgICAgIGNoZWNrRGVsZXRlZCgpOworICAgICAgICByZXR1cm4gZGVsZWdhdGVlLmdldEJ1bmRsZUxvY2F0aW9uKCk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gYnVuZGxlTG9jYXRpb24KKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuZmVsaXguY20uaW1wbC5Db25maWd1cmF0aW9uSW1wbCNzZXRCdW5kbGVMb2NhdGlvbihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJ1bmRsZUxvY2F0aW9uKCBTdHJpbmcgYnVuZGxlTG9jYXRpb24gKQorICAgIHsKKyAgICAgICAgY29uZmlndXJhdGlvbkFkbWluLmNoZWNrUGVybWlzc2lvbigpOworICAgICAgICBjaGVja0RlbGV0ZWQoKTsKKyAgICAgICAgZGVsZWdhdGVlLnNldEJ1bmRsZUxvY2F0aW9uKCBidW5kbGVMb2NhdGlvbiApOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5mZWxpeC5jbS5pbXBsLkNvbmZpZ3VyYXRpb25JbXBsI3VwZGF0ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBjaGVja0RlbGV0ZWQoKTsKKyAgICAgICAgZGVsZWdhdGVlLnVwZGF0ZSgpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQHBhcmFtIHByb3BlcnRpZXMKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmZlbGl4LmNtLmltcGwuQ29uZmlndXJhdGlvbkltcGwjdXBkYXRlKGphdmEudXRpbC5EaWN0aW9uYXJ5KQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVwZGF0ZSggRGljdGlvbmFyeSBwcm9wZXJ0aWVzICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBjaGVja0RlbGV0ZWQoKTsKKyAgICAgICAgZGVsZWdhdGVlLnVwZGF0ZSggcHJvcGVydGllcyApOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQHJldHVybgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5mZWxpeC5jbS5pbXBsLkNvbmZpZ3VyYXRpb25JbXBsI2dldFByb3BlcnRpZXMoKQorICAgICAqLworICAgIHB1YmxpYyBEaWN0aW9uYXJ5IGdldFByb3BlcnRpZXMoKQorICAgIHsKKyAgICAgICAgY2hlY2tEZWxldGVkKCk7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZWUuZ2V0UHJvcGVydGllcygpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5mZWxpeC5jbS5pbXBsLkNvbmZpZ3VyYXRpb25JbXBsI2RlbGV0ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVsZXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBjaGVja0RlbGV0ZWQoKTsKKyAgICAgICAgZGVsZWdhdGVlLmRlbGV0ZSgpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQHJldHVybgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5mZWxpeC5jbS5pbXBsLkNvbmZpZ3VyYXRpb25JbXBsI2hhc2hDb2RlKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkKKyAgICB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZWUuaGFzaENvZGUoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEBwYXJhbSBvYmoKKyAgICAgKiBAcmV0dXJuCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmZlbGl4LmNtLmltcGwuQ29uZmlndXJhdGlvbkltcGwjZXF1YWxzKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKCBPYmplY3Qgb2JqICkKKyAgICB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZWUuZXF1YWxzKCBvYmogKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEByZXR1cm4KKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuZmVsaXguY20uaW1wbC5Db25maWd1cmF0aW9uSW1wbCN0b1N0cmluZygpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpCisgICAgeworICAgICAgICByZXR1cm4gZGVsZWdhdGVlLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhpcyBjb25maWd1cmF0aW9uIG9iamVjdCBoYXMgYWxyZWFkeSBiZWVuIGRlbGV0ZWQuCisgICAgICogCisgICAgICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gSWYgdGhpcyBjb25maWd1cmF0aW9uIG9iamVjdCBoYXMgYmVlbgorICAgICAqICAgICAgZGVsZXRlZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgY2hlY2tEZWxldGVkKCkgeworICAgICAgICBpZiAoZGVsZWdhdGVlLmlzRGVsZXRlZCgpKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCAiQ29uZmlndXJhdGlvbiAiICsgZGVsZWdhdGVlLmdldFBpZCgpICsgIiBkZWxldGVkIiApOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ltcGwvQ29uZmlndXJhdGlvbkFkbWluRmFjdG9yeS5qYXZhIGIvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ltcGwvQ29uZmlndXJhdGlvbkFkbWluRmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI3MTk3MDQKLS0tIC9kZXYvbnVsbAorKysgYi9jb25maWdhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvZmVsaXgvY20vaW1wbC9Db25maWd1cmF0aW9uQWRtaW5GYWN0b3J5LmphdmEKQEAgLTAsMCArMSw2OCBAQAorLyogCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuZmVsaXguY20uaW1wbDsKKworCitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZTsKK2ltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuU2VydmljZUZhY3Rvcnk7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLlNlcnZpY2VSZWdpc3RyYXRpb247CisKKworLyoqCisgKiBUaGUgPGNvZGU+Q29uZmlndXJhdGlvbkFkbWluRmFjdG9yeTwvY29kZT4gaXMgdGhlIDxjb2RlPlNlcnZpY2VGYWN0b3J5PC9jb2RlPgorICogcmVnaXN0ZXJlZCBhcyB0aGUgPGNvZGU+Q29uZmlndXJhdGlvbkFkbWluPC9jb2RlPiBzZXJ2aWNlIHJlc3BvbnNpYmxlIHRvCisgKiBjcmVhdGUgdGhlIHJlYWwgPGNvZGU+Q29uZmlndXJhdEFkbWluPC9jb2RlPiBpbnN0YW5jZXMgcmV0dXJlbmQgdG8gY2xpZW50CisgKiBidW5kbGVzLiBFYWNoIGJ1bmRsZSBnZXRzIGEgc2VwYXJhdGUgaW5zdGFuY2UuCisgKgorICogQGF1dGhvciBmbWVzY2hiZQorICovCitjbGFzcyBDb25maWd1cmF0aW9uQWRtaW5GYWN0b3J5IGltcGxlbWVudHMgU2VydmljZUZhY3RvcnkKK3sKKworICAgIC8vIFRoZSBjb25maWd1cmF0aW9uIG1hbmFnZXIgdG8gd2hpY2ggdGhlIGNvbmZpZ3VyYXRpb24gYWRtaW4gaW5zdGFuY2VzCisgICAgLy8gZGVsZWdhdGUgbW9zdCBvZiB0aGVpciB3b3JrCisgICAgcHJpdmF0ZSBDb25maWd1cmF0aW9uTWFuYWdlciBjb25maWd1cmF0aW9uTWFuYWdlcjsKKworCisgICAgQ29uZmlndXJhdGlvbkFkbWluRmFjdG9yeSggQ29uZmlndXJhdGlvbk1hbmFnZXIgY29uZmlndXJhdGlvbk1hbmFnZXIgKQorICAgIHsKKyAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uTWFuYWdlciA9IGNvbmZpZ3VyYXRpb25NYW5hZ2VyOworICAgIH0KKworCisgICAgLyoqCisgICAgICogUmV0dXJucyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUge0BsaW5rIENvbmZpZ3VyYXRpb25BZG1pbkltcGx9IGNsYXNzIGZvcgorICAgICAqIHRoZSBnaXZlbiBidW5kbGUuCisgICAgICovCisgICAgcHVibGljIE9iamVjdCBnZXRTZXJ2aWNlKCBCdW5kbGUgYnVuZGxlLCBTZXJ2aWNlUmVnaXN0cmF0aW9uIHJlZ2lzdHJhdGlvbiApCisgICAgeworICAgICAgICByZXR1cm4gbmV3IENvbmZpZ3VyYXRpb25BZG1pbkltcGwoIGNvbmZpZ3VyYXRpb25NYW5hZ2VyLCBidW5kbGUgKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIERpc3Bvc2VzIG9mZiB0aGUgZ2l2ZW4ge0BsaW5rIENvbmZpZ3VyYXRpb25BZG1pbkltcGx9IGluc3RhbmNlIGFzIHRoZQorICAgICAqIGdpdmVuIGJ1bmRsZSBoYXMgbm8gdXNlIG9mIGl0IGFueSBtb3JlLgorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHVuZ2V0U2VydmljZSggQnVuZGxlIGJ1bmRsZSwgU2VydmljZVJlZ2lzdHJhdGlvbiByZWdpc3RyYXRpb24sIE9iamVjdCBzZXJ2aWNlICkKKyAgICB7CisgICAgICAgICggKCBDb25maWd1cmF0aW9uQWRtaW5JbXBsICkgc2VydmljZSApLmRpc3Bvc2UoKTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL0NvbmZpZ3VyYXRpb25BZG1pbkltcGwuamF2YSBiL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL0NvbmZpZ3VyYXRpb25BZG1pbkltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YTkxYjJiCi0tLSAvZGV2L251bGwKKysrIGIvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ltcGwvQ29uZmlndXJhdGlvbkFkbWluSW1wbC5qYXZhCkBAIC0wLDAgKzEsMTgxIEBACisvKiAKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5mZWxpeC5jbS5pbXBsOworCisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlOworaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5JbnZhbGlkU3ludGF4RXhjZXB0aW9uOworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbjsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNtLkNvbmZpZ3VyYXRpb25BZG1pbjsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNtLkNvbmZpZ3VyYXRpb25QZXJtaXNzaW9uOworCisKKy8qKgorICogVGhlIDxjb2RlPkNvbmZpZ3VyYXRpb25BZG1pbkltcGw8L2NvZGU+IGlzIHRoZSBwZXItYnVuZGxlIGZyb250ZW5kIHRvIHRoZQorICogY29uZmlndXJhdGlvbiBtYW5hZ2VyLiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBhcmUgY3JlYXRlZCBvbi1kZW1hbmQgZm9yCisgKiBlYWNoIGJ1bmRsZSB0cnlpbmcgdG8gZ2V0IGhvbGQgb2YgdGhlIDxjb2RlPkNvbmZpZ3VyYXRpb25BZG1pbjwvY29kZT4KKyAqIHNlcnZpY2UuCisgKgorICogQGF1dGhvciBmbWVzY2hiZQorICovCitwdWJsaWMgY2xhc3MgQ29uZmlndXJhdGlvbkFkbWluSW1wbCBpbXBsZW1lbnRzIENvbmZpZ3VyYXRpb25BZG1pbgoreworCisgICAgLy8gVGhlIGNvbmZpZ3VyYXRpb24gbWFuYWdlciB0byB3aGljaCBtb3N0IG9mIHRoZSB0YXNrcyBhcmUgZGVsZWdhdGVkCisgICAgcHJpdmF0ZSBDb25maWd1cmF0aW9uTWFuYWdlciBjb25maWd1cmF0aW9uTWFuYWdlcjsKKworICAgIC8vIFRoZSBidW5kbGUgZm9yIHdoaWNoIHRoaXMgaW5zdGFuY2UgaGFzIGJlZW4gY3JlYXRlZAorICAgIHByaXZhdGUgQnVuZGxlIGJ1bmRsZTsKKworCisgICAgQ29uZmlndXJhdGlvbkFkbWluSW1wbCggQ29uZmlndXJhdGlvbk1hbmFnZXIgY29uZmlndXJhdGlvbk1hbmFnZXIsIEJ1bmRsZSBidW5kbGUgKQorICAgIHsKKyAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uTWFuYWdlciA9IGNvbmZpZ3VyYXRpb25NYW5hZ2VyOworICAgICAgICB0aGlzLmJ1bmRsZSA9IGJ1bmRsZTsKKyAgICB9CisKKworICAgIHZvaWQgZGlzcG9zZSgpCisgICAgeworICAgICAgICB0aGlzLmJ1bmRsZSA9IG51bGw7CisgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbk1hbmFnZXIgPSBudWxsOworICAgIH0KKworCisgICAgQnVuZGxlIGdldEJ1bmRsZSgpCisgICAgeworICAgICAgICByZXR1cm4gYnVuZGxlOworICAgIH0KKworCisgICAgLy8tLS0tLS0tLS0tIENvbmZpZ3VyYXRpb25BZG1pbiBpbnRlcmZhY2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcub3NnaS5zZXJ2aWNlLmNtLkNvbmZpZ3VyYXRpb25BZG1pbiNjcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBDb25maWd1cmF0aW9uIGNyZWF0ZUZhY3RvcnlDb25maWd1cmF0aW9uKCBTdHJpbmcgZmFjdG9yeVBpZCApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgcmV0dXJuIHdyYXAoIGNvbmZpZ3VyYXRpb25NYW5hZ2VyLmNyZWF0ZUZhY3RvcnlDb25maWd1cmF0aW9uKCB0aGlzLCBmYWN0b3J5UGlkICkgKTsKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbkFkbWluI2NyZWF0ZUZhY3RvcnlDb25maWd1cmF0aW9uKGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIENvbmZpZ3VyYXRpb24gY3JlYXRlRmFjdG9yeUNvbmZpZ3VyYXRpb24oIFN0cmluZyBmYWN0b3J5UGlkLCBTdHJpbmcgbG9jYXRpb24gKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIGNoZWNrUGVybWlzc2lvbigpOworCisgICAgICAgIHJldHVybiB3cmFwKCBjb25maWd1cmF0aW9uTWFuYWdlci5jcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbiggZmFjdG9yeVBpZCwgbG9jYXRpb24gKSApOworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5jbS5Db25maWd1cmF0aW9uQWRtaW4jZ2V0Q29uZmlndXJhdGlvbihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBDb25maWd1cmF0aW9uIGdldENvbmZpZ3VyYXRpb24oIFN0cmluZyBwaWQgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIENvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZyA9IGNvbmZpZ3VyYXRpb25NYW5hZ2VyLmdldENvbmZpZ3VyYXRpb24oIHBpZCApOworCisgICAgICAgIGlmICggY29uZmlnLmdldEJ1bmRsZUxvY2F0aW9uKCkgPT0gbnVsbCApCisgICAgICAgIHsKKyAgICAgICAgICAgIGNvbmZpZy5zZXRCdW5kbGVMb2NhdGlvbiggZ2V0QnVuZGxlKCkuZ2V0TG9jYXRpb24oKSApOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKCAhY29uZmlnLmdldEJ1bmRsZUxvY2F0aW9uKCkuZXF1YWxzKCBnZXRCdW5kbGUoKS5nZXRMb2NhdGlvbigpICkgKQorICAgICAgICB7CisgICAgICAgICAgICBjaGVja1Blcm1pc3Npb24oKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB3cmFwKCBjb25maWcgKTsKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbkFkbWluI2dldENvbmZpZ3VyYXRpb24oamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29uZmlndXJhdGlvbiBnZXRDb25maWd1cmF0aW9uKCBTdHJpbmcgcGlkLCBTdHJpbmcgbG9jYXRpb24gKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIGNoZWNrUGVybWlzc2lvbigpOworCisgICAgICAgIHJldHVybiB3cmFwKCBjb25maWd1cmF0aW9uTWFuYWdlci5nZXRDb25maWd1cmF0aW9uKCBwaWQsIGxvY2F0aW9uICkgKTsKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbkFkbWluI2xpc3RDb25maWd1cmF0aW9ucyhqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBDb25maWd1cmF0aW9uW10gbGlzdENvbmZpZ3VyYXRpb25zKCBTdHJpbmcgZmlsdGVyICkgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnZhbGlkU3ludGF4RXhjZXB0aW9uCisgICAgeworICAgICAgICBDb25maWd1cmF0aW9uSW1wbCBjaVtdID0gY29uZmlndXJhdGlvbk1hbmFnZXIubGlzdENvbmZpZ3VyYXRpb25zKCB0aGlzLCBmaWx0ZXIgKTsKKyAgICAgICAgaWYgKCBjaSA9PSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICBDb25maWd1cmF0aW9uW10gY2ZncyA9IG5ldyBDb25maWd1cmF0aW9uW2NpLmxlbmd0aF07CisgICAgICAgIGZvciAoIGludCBpID0gMDsgaSA8IGNmZ3MubGVuZ3RoOyBpKysgKQorICAgICAgICB7CisgICAgICAgICAgICBjZmdzW2ldID0gd3JhcCggY2lbaV0gKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjZmdzOworICAgIH0KKworCisgICAgLy8tLS0tLS0tLS0tIFNlY3VyaXR5IGNoZWNrcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICBwcml2YXRlIENvbmZpZ3VyYXRpb24gd3JhcCggQ29uZmlndXJhdGlvbkltcGwgY29uZmlndXJhdGlvbiApCisgICAgeworICAgICAgICByZXR1cm4gbmV3IENvbmZpZ3VyYXRpb25BZGFwdGVyKCB0aGlzLCBjb25maWd1cmF0aW9uICk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgYnVuZGxlIHRvIHdoaWNoIHRoaXMgaW5zdGFuY2UgaGFzIGJlZW4gZ2l2ZW4gaGFzIHRoZQorICAgICAqIDxjb2RlPkNPTkZJR1VSRTwvY29kZT4gcGVybWlzc2lvbiBhbmQgcmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpbiB0aGlzCisgICAgICogY2FzZS4KKyAgICAgKi8KKyAgICBib29sZWFuIGhhc1Blcm1pc3Npb24oKQorICAgIHsKKyAgICAgICAgcmV0dXJuIGJ1bmRsZS5oYXNQZXJtaXNzaW9uKCBuZXcgQ29uZmlndXJhdGlvblBlcm1pc3Npb24oICIqIiwgQ29uZmlndXJhdGlvblBlcm1pc3Npb24uQ09ORklHVVJFICkgKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBidW5kbGUgdG8gd2hpY2ggdGhpcyBpbnN0YW5jZSBoYXMgYmVlbiBnaXZlbiBoYXMgdGhlCisgICAgICogPGNvZGU+Q09ORklHVVJFPC9jb2RlPiBwZXJtaXNzaW9uIGFuZCB0aHJvd3MgYSA8Y29kZT5TZWN1cml0eUV4Y2VwdGlvbjwvY29kZT4KKyAgICAgKiBpZiB0aGlzIGlzIG5vdCB0aGUgY2FzZS4KKyAgICAgKiAKKyAgICAgKiBAdGhyb3dzIFNlY3VyaXR5RXhjZXB0aW9uIGlmIHRoZSBidW5kbGUgdG8gd2hpY2ggdGhpcyBpbnN0YW5jZSBiZWxvbmdzCisgICAgICogICAgICBkb2VzIG5vdCBoYXZlIHRoZSA8Y29kZT5DT05GSUdVUkU8L2NvZGU+IHBlcm1pc3Npb24uCisgICAgICovCisgICAgdm9pZCBjaGVja1Blcm1pc3Npb24oKQorICAgIHsKKyAgICAgICAgaWYgKCAhaGFzUGVybWlzc2lvbigpICkKKyAgICAgICAgeworICAgICAgICAgICAgdGhyb3cgbmV3IFNlY3VyaXR5RXhjZXB0aW9uKCAiQnVuZGxlICIgKyBidW5kbGUuZ2V0U3ltYm9saWNOYW1lKCkKKyAgICAgICAgICAgICAgICArICIgbm90IHBlcm1pdHRlZCBmb3IgQ29uZmlndXJhdGlvbiBUYXNrcyIgKTsKKyAgICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ltcGwvQ29uZmlndXJhdGlvbkltcGwuamF2YSBiL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL0NvbmZpZ3VyYXRpb25JbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjM1OTY1MgotLS0gL2Rldi9udWxsCisrKyBiL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL0NvbmZpZ3VyYXRpb25JbXBsLmphdmEKQEAgLTAsMCArMSwzODMgQEAKKy8qIAorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmZlbGl4LmNtLmltcGw7CisKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkRpY3Rpb25hcnk7CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKKworaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXguY20uUGVyc2lzdGVuY2VNYW5hZ2VyOworaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5Db25zdGFudHM7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLlNlcnZpY2VSZWZlcmVuY2U7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5jbS5Db25maWd1cmF0aW9uOworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbkFkbWluOworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmxvZy5Mb2dTZXJ2aWNlOworCisKKy8qKgorICogVGhlIDxjb2RlPkNvbmZpZ3VyYXRpb25JbXBsPC9jb2RlPiBpcyB0aGUgaW1wbGVtZW50YXRpb24gb2YgdGhlIENvbmZpZ3VyYXRpb24KKyAqIEFkbWluIFNlcnZpY2UgU3BlY2lmaWNhdGlvbiA8aT5Db25maWd1cmF0aW9uIG9iamVjdDwvaT4gKHNlY3Rpb24gMTA0LjQpLgorICoKKyAqIEBhdXRob3IgZm1lc2NoYmUKKyAqLworY2xhc3MgQ29uZmlndXJhdGlvbkltcGwKK3sKKworICAgIC8qKgorICAgICAqIFRoZSB7QGxpbmsgQ29uZmlndXJhdGlvbk1hbmFnZXIgY29uZmlndXJhdGlvbiBtYW5hZ2VyfSBpbnN0YW5jZSB3aGljaAorICAgICAqIGNhdXNlZCB0aGlzIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHRvIGJlIGNyZWF0ZWQuCisgICAgICovCisgICAgcHJpdmF0ZSBDb25maWd1cmF0aW9uTWFuYWdlciBjb25maWd1cmF0aW9uTWFuYWdlcjsKKworICAgIC8qKgorICAgICAqIFRoZSB7QGxpbmsgUGVyc2lzdGVuY2VNYW5hZ2VyIHBlcnNpc3RlbmNlIG1hbmFnZXJ9IHdoaWNoIGxvYWRlZCB0aGlzCisgICAgICogY29uZmlndXJhdGlvbiBpbnN0YW5jZSBhbmQgd2hpY2ggaXMgdXNlZCB0byBzdG9yZSBhbmQgZGVsZXRlIGNvbmZpZ3VyYXRpb24KKyAgICAgKiBkYXRhLgorICAgICAqLworICAgIHByaXZhdGUgUGVyc2lzdGVuY2VNYW5hZ2VyIHBlcnNpc3RlbmNlTWFuYWdlcjsKKworICAgIC8qKgorICAgICAqIFRoZSBzZXJ2aWNlUmVmZXJlbmNlIFBJRCBvZiB0aGlzIGNvbmZpZ3VyYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgcGlkOworCisgICAgLyoqCisgICAgICogVGhlIGZhY3Rvcnkgc2VydmljZVJlZmVyZW5jZSBQSUQgb2YgdGhpcyBjb25maWd1cmF0aW9uIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMKKyAgICAgKiBpcyBub3QgYSBmYWN0b3J5IGNvbmZpZ3VyYXRpb24uCisgICAgICovCisgICAgcHJpdmF0ZSBTdHJpbmcgZmFjdG9yeVBJRDsKKworICAgIC8qKgorICAgICAqIFRoZSBsb2NhdGlvbiBvZiB0aGUgYnVuZGxlIHRvIHdoaWNoIHRoaXMgY29uZmlndXJhdGlvbiBpbnN0YW5jZSBpcyBib3VuZC4KKyAgICAgKiBUaGlzIGlzIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBhcyB0aGUgYnVuZGxlIG9mIHRoZQorICAgICAqIHtAbGluayAjY29uZmlndXJhdGlvbkFkbWlufS4gSWYgdGhpcyBjb25maWd1cmF0aW9uIGlzIG5vdCBib3VuZCB0byBhCisgICAgICogYnVuZGxlLCB0aGlzIGZpZWxkIGlzIDxjb2RlPm51bGw8L2NvZGU+LgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGJ1bmRsZUxvY2F0aW9uOworCisgICAgLyoqCisgICAgICogVGhlIDxjb2RlPlNlcnZpY2VSZWZlcmVuY2U8L2NvZGU+IG9mIHRoZSBzZXJ2aWNlUmVmZXJlbmNlIHdoaWNoIGZpcnN0IGFza2VkIGZvcgorICAgICAqIHRoaXMgY29uZmlndXJhdGlvbi4gVGhpcyBmaWVsZCBpcyA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgY29uZmlndXJhdGlvbgorICAgICAqIGhhcyBub3QgYmVlbiBoYW5kZWQgdG8gYSBzZXJ2aWNlUmVmZXJlbmNlIGJ5IHdheSBvZiB0aGUgPGNvZGU+TWFuYWdlZFNlcnZpY2UudXBkYXRlKERpY3Rpb25hcnkpPC9jb2RlPiAKKyAgICAgKiBvciA8Y29kZT5NYW5hZ2VkU2VydmljZUZhY3RvcnkudXBkYXRlZChTdHJpbmcsIERpY3Rpb25hcnkpPC9jb2RlPgorICAgICAqIG1ldGhvZC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFNlcnZpY2VSZWZlcmVuY2Ugc2VydmljZVJlZmVyZW5jZTsKKworICAgIC8qKgorICAgICAqIFRoZSBjb25maWd1cmF0aW9uIGRhdGEgb2YgdGhpcyBjb25maWd1cmF0aW9uIGluc3RhbmNlLiBUaGlzIGlzIGEgcHJpdmF0ZQorICAgICAqIGNvcHkgb2YgdGhlIHByb3BlcnRpZXMgb2Ygd2hpY2ggYSBjb3B5IGlzIG1hZGUgd2hlbiB0aGUKKyAgICAgKiB7QGxpbmsgI2dldFByb3BlcnRpZXMoKX0gbWV0aG9kIGlzIGNhbGxlZC4gVGhpcyBmaWVsZCBpcyA8Y29kZT5udWxsPC9jb2RlPiBpZgorICAgICAqIHRoZSBjb25maWd1cmF0aW9uIGhhcyBiZWVuIGNyZWF0ZWQgYW5kIG5ldmVyIHN0b3JlZCB0byBwZXJzaXN0ZW5jZS4KKyAgICAgKi8KKyAgICBwcml2YXRlIENhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnkgcHJvcGVydGllczsKKworCisgICAgQ29uZmlndXJhdGlvbkltcGwoIENvbmZpZ3VyYXRpb25NYW5hZ2VyIGNvbmZpZ3VyYXRpb25NYW5hZ2VyLCBQZXJzaXN0ZW5jZU1hbmFnZXIgcGVyc2lzdGVuY2VNYW5hZ2VyLAorICAgICAgICBEaWN0aW9uYXJ5IHByb3BlcnRpZXMgKQorICAgIHsKKyAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uTWFuYWdlciA9IGNvbmZpZ3VyYXRpb25NYW5hZ2VyOworICAgICAgICB0aGlzLnBlcnNpc3RlbmNlTWFuYWdlciA9IHBlcnNpc3RlbmNlTWFuYWdlcjsKKworICAgICAgICB0aGlzLnBpZCA9ICggU3RyaW5nICkgcHJvcGVydGllcy5yZW1vdmUoIENvbnN0YW50cy5TRVJWSUNFX1BJRCApOworICAgICAgICB0aGlzLmZhY3RvcnlQSUQgPSAoIFN0cmluZyApIHByb3BlcnRpZXMucmVtb3ZlKCBDb25maWd1cmF0aW9uQWRtaW4uU0VSVklDRV9GQUNUT1JZUElEICk7CisgICAgICAgIHRoaXMuYnVuZGxlTG9jYXRpb24gPSAoIFN0cmluZyApIHByb3BlcnRpZXMucmVtb3ZlKCBDb25maWd1cmF0aW9uQWRtaW4uU0VSVklDRV9CVU5ETEVMT0NBVElPTiApOworCisgICAgICAgIGNvbmZpZ3VyZSggcHJvcGVydGllcyApOworICAgIH0KKworCisgICAgQ29uZmlndXJhdGlvbkltcGwoIENvbmZpZ3VyYXRpb25NYW5hZ2VyIGNvbmZpZ3VyYXRpb25NYW5hZ2VyLCBQZXJzaXN0ZW5jZU1hbmFnZXIgcGVyc2lzdGVuY2VNYW5hZ2VyLCBTdHJpbmcgcGlkLAorICAgICAgICBTdHJpbmcgZmFjdG9yeVBpZCApCisgICAgeworICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb25NYW5hZ2VyID0gY29uZmlndXJhdGlvbk1hbmFnZXI7CisgICAgICAgIHRoaXMucGVyc2lzdGVuY2VNYW5hZ2VyID0gcGVyc2lzdGVuY2VNYW5hZ2VyOworICAgICAgICB0aGlzLnBpZCA9IHBpZDsKKyAgICAgICAgdGhpcy5mYWN0b3J5UElEID0gZmFjdG9yeVBpZDsKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbiNkZWxldGUoKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGRlbGV0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgaWYgKCAhaXNEZWxldGVkKCkgKQorICAgICAgICB7CisgICAgICAgICAgICBwZXJzaXN0ZW5jZU1hbmFnZXIuZGVsZXRlKCBwaWQgKTsKKyAgICAgICAgICAgIHBlcnNpc3RlbmNlTWFuYWdlciA9IG51bGw7CisKKyAgICAgICAgICAgIGNvbmZpZ3VyYXRpb25NYW5hZ2VyLmRlbGV0ZWQoIHRoaXMgKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5jbS5Db25maWd1cmF0aW9uI2dldFBpZCgpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXRQaWQoKQorICAgIHsKKyAgICAgICAgcmV0dXJuIHBpZDsKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbiNnZXRGYWN0b3J5UGlkKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldEZhY3RvcnlQaWQoKQorICAgIHsKKyAgICAgICAgcmV0dXJuIGZhY3RvcnlQSUQ7CisgICAgfQorCisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcub3NnaS5zZXJ2aWNlLmNtLkNvbmZpZ3VyYXRpb24jZ2V0QnVuZGxlTG9jYXRpb24oKQorICAgICAqLworICAgIHB1YmxpYyBTdHJpbmcgZ2V0QnVuZGxlTG9jYXRpb24oKQorICAgIHsKKyAgICAgICAgcmV0dXJuIGJ1bmRsZUxvY2F0aW9uOworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5jbS5Db25maWd1cmF0aW9uI2dldFByb3BlcnRpZXMoKQorICAgICAqLworICAgIHB1YmxpYyBEaWN0aW9uYXJ5IGdldFByb3BlcnRpZXMoKQorICAgIHsKKyAgICAgICAgLy8gbm8gcHJvcGVydGllcyB5ZXQKKyAgICAgICAgaWYgKCBwcm9wZXJ0aWVzID09IG51bGwgKQorICAgICAgICB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIENhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnkgcHJvcHMgPSBuZXcgQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeSggcHJvcGVydGllcyApOworCisgICAgICAgIC8vIGZpeCBzcGVjaWFsIHByb3BlcnRpZXMgKHBpZCwgZmFjdG9yeSBQSUQsIGJ1bmRsZSBsb2NhdGlvbikKKyAgICAgICAgc2V0QXV0b1Byb3BlcnRpZXMoIHByb3BzLCBmYWxzZSApOworCisgICAgICAgIHJldHVybiBwcm9wczsKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbiNzZXRCdW5kbGVMb2NhdGlvbihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHNldEJ1bmRsZUxvY2F0aW9uKCBTdHJpbmcgYnVuZGxlTG9jYXRpb24gKQorICAgIHsKKyAgICAgICAgaWYgKCAhaXNEZWxldGVkKCkgKQorICAgICAgICB7CisgICAgICAgICAgICB0aGlzLmJ1bmRsZUxvY2F0aW9uID0gYnVuZGxlTG9jYXRpb247CisKKyAgICAgICAgICAgIC8vIDEwNC4xNS4yLjggVGhlIGJ1bmRsZSBsb2NhdGlvbiB3aWxsIGJlIHNldCBwZXJzaXN0ZW50bHkKKyAgICAgICAgICAgIHRyeQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHN0b3JlKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXRjaCAoIElPRXhjZXB0aW9uIGlvZSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgY29uZmlndXJhdGlvbk1hbmFnZXIubG9nKCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgIlBlcnNpc3RpbmcgbmV3IGJ1bmRsZSBsb2NhdGlvbiBmYWlsZWQiLCBpb2UgKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5jbS5Db25maWd1cmF0aW9uI3VwZGF0ZSgpCisgICAgICovCisgICAgcHVibGljIHZvaWQgdXBkYXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBpZiAoICFpc0RlbGV0ZWQoKSApCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIHJlYWQgY29uZmlndXJhdGlvbiBmcm9tIHBlcnNpc3RlbmNlIChhZ2FpbikKKyAgICAgICAgICAgIERpY3Rpb25hcnkgcHJvcGVydGllcyA9IHBlcnNpc3RlbmNlTWFuYWdlci5sb2FkKCBwaWQgKTsKKworICAgICAgICAgICAgLy8gZW5zdXJlIHNlcnZpY2VSZWZlcmVuY2UgcGlkCisgICAgICAgICAgICBTdHJpbmcgc2VydmljZVBpZCA9ICggU3RyaW5nICkgcHJvcGVydGllcy5nZXQoIENvbnN0YW50cy5TRVJWSUNFX1BJRCApOworICAgICAgICAgICAgaWYgKCBzZXJ2aWNlUGlkICE9IG51bGwgJiYgIXBpZC5lcXVhbHMoIHNlcnZpY2VQaWQgKSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCAiUElEIG9mIGNvbmZpZ3VyYXRpb24gZmlsZSBkb2VzIG1hdGNoIHJlcXVlc3RlZCBQSUQ7IGV4cGVjdGVkICIgKyBwaWQgKyAiLCBnb3QgIgorICAgICAgICAgICAgICAgICAgICArIHNlcnZpY2VQaWQgKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY29uZmlndXJlKCBwcm9wZXJ0aWVzICk7CisKKyAgICAgICAgICAgIGNvbmZpZ3VyYXRpb25NYW5hZ2VyLnVwZGF0ZWQoIHRoaXMgKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5jbS5Db25maWd1cmF0aW9uI3VwZGF0ZShqYXZhLnV0aWwuRGljdGlvbmFyeSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCB1cGRhdGUoIERpY3Rpb25hcnkgcHJvcGVydGllcyApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgaWYgKCAhaXNEZWxldGVkKCkgKQorICAgICAgICB7CisgICAgICAgICAgICBDYXNlSW5zZW5zaXRpdmVEaWN0aW9uYXJ5IG5ld1Byb3BlcnRpZXMgPSBuZXcgQ2FzZUluc2Vuc2l0aXZlRGljdGlvbmFyeSggcHJvcGVydGllcyApOworCisgICAgICAgICAgICBzZXRBdXRvUHJvcGVydGllcyggbmV3UHJvcGVydGllcywgdHJ1ZSApOworCisgICAgICAgICAgICBwZXJzaXN0ZW5jZU1hbmFnZXIuc3RvcmUoIHBpZCwgbmV3UHJvcGVydGllcyApOworCisgICAgICAgICAgICBjb25maWd1cmUoIG5ld1Byb3BlcnRpZXMgKTsKKworICAgICAgICAgICAgY29uZmlndXJhdGlvbk1hbmFnZXIudXBkYXRlZCggdGhpcyApOworICAgICAgICB9CisgICAgfQorCisKKyAgICAvLy0tLS0tLS0tLS0gT2JqZWN0IG92ZXJ3cml0ZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyggT2JqZWN0IG9iaiApCisgICAgeworICAgICAgICBpZiAoIG9iaiA9PSB0aGlzICkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIG9iaiBpbnN0YW5jZW9mIENvbmZpZ3VyYXRpb24gKQorICAgICAgICB7CisgICAgICAgICAgICByZXR1cm4gcGlkLmVxdWFscyggKCAoIENvbmZpZ3VyYXRpb24gKSBvYmogKS5nZXRQaWQoKSApOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworCisgICAgcHVibGljIGludCBoYXNoQ29kZSgpCisgICAgeworICAgICAgICByZXR1cm4gcGlkLmhhc2hDb2RlKCk7CisgICAgfQorCisKKyAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkKKyAgICB7CisgICAgICAgIHJldHVybiAiQ29uZmlndXJhdGlvbiBQSUQ9IiArIHBpZCArICIsIGZhY3RvcnlQSUQ9IiArIGZhY3RvcnlQSUQgKyAiLCBidW5kbGVMb2NhdGlvbj0iICsgYnVuZGxlTG9jYXRpb247CisgICAgfQorCisKKyAgICAvLy0tLS0tLS0tLS0gcHJpdmF0ZSBoZWxwZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHZvaWQgc2V0U2VydmljZVJlZmVyZW5jZSggU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlICkKKyAgICB7CisgICAgICAgIHRoaXMuc2VydmljZVJlZmVyZW5jZSA9IHNlcnZpY2VSZWZlcmVuY2U7CisgICAgfQorCisKKyAgICBTZXJ2aWNlUmVmZXJlbmNlIGdldFNlcnZpY2VSZWZlcmVuY2UoKQorICAgIHsKKyAgICAgICAgcmV0dXJuIHNlcnZpY2VSZWZlcmVuY2U7CisgICAgfQorCisKKyAgICB2b2lkIHN0b3JlKCkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBEaWN0aW9uYXJ5IHByb3BzID0gZ2V0UHJvcGVydGllcygpOworCisgICAgICAgIC8vIGlmIHRoaXMgaXMgYSBuZXcgY29uZmlndXJhdGlvbiwgd2UganVzdCB1c2UgYW4gZW1wdHkgRGljdGlvbmFyeQorICAgICAgICBpZiAoIHByb3BzID09IG51bGwgKQorICAgICAgICB7CisgICAgICAgICAgICBwcm9wcyA9IG5ldyBIYXNodGFibGUoKTsKKworICAgICAgICAgICAgLy8gYWRkIGF1dG9tYXRpYyBwcm9wZXJ0aWVzIGluY2x1ZGluZyB0aGUgYnVuZGxlIGxvY2F0aW9uIChpZiBzZXQpCisgICAgICAgICAgICBzZXRBdXRvUHJvcGVydGllcyggcHJvcHMsIHRydWUgKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmICggZ2V0QnVuZGxlTG9jYXRpb24oKSAhPSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgcHJvcHMucHV0KCBDb25maWd1cmF0aW9uQWRtaW4uU0VSVklDRV9CVU5ETEVMT0NBVElPTiwgZ2V0QnVuZGxlTG9jYXRpb24oKSApOworICAgICAgICB9CisKKyAgICAgICAgLy8gb25seSBzdG9yZSBub3csIGlmIHRoaXMgaXMgbm90IGEgbmV3IGNvbmZpZ3VyYXRpb24KKyAgICAgICAgcGVyc2lzdGVuY2VNYW5hZ2VyLnN0b3JlKCBwaWQsIHByb3BzICk7CisgICAgfQorCisKKyAgICBib29sZWFuIGlzRGVsZXRlZCgpCisgICAgeworICAgICAgICBpZiAoIHBlcnNpc3RlbmNlTWFuYWdlciAhPSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgaWYgKCBwcm9wZXJ0aWVzID09IG51bGwgfHwgcGVyc2lzdGVuY2VNYW5hZ2VyLmV4aXN0cyggcGlkICkgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcGVyc2lzdGVuY2VNYW5hZ2VyID0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKworCisgICAgcHJpdmF0ZSB2b2lkIGNvbmZpZ3VyZSggRGljdGlvbmFyeSBwcm9wZXJ0aWVzICkKKyAgICB7CisgICAgICAgIC8vIHJlbW92ZSBwcmVkZWZpbmVkIHByb3BlcnRpZXMKKyAgICAgICAgY2xlYXJBdXRvUHJvcGVydGllcyggcHJvcGVydGllcyApOworCisgICAgICAgIC8vIGVuc3VyZSBDYXNlSW5zZW5zaXRpdmVEaWN0aW9uYXJ5CisgICAgICAgIGlmICggcHJvcGVydGllcyBpbnN0YW5jZW9mIENhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnkgKQorICAgICAgICB7CisgICAgICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSAoIENhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnkgKSBwcm9wZXJ0aWVzOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gbmV3IENhc2VJbnNlbnNpdGl2ZURpY3Rpb25hcnkoIHByb3BlcnRpZXMgKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgdm9pZCBzZXRBdXRvUHJvcGVydGllcyggRGljdGlvbmFyeSBwcm9wZXJ0aWVzLCBib29sZWFuIHdpdGhCdW5kbGVMb2NhdGlvbiApCisgICAgeworICAgICAgICAvLyBzZXQgcGlkIGFuZCBmYWN0b3J5IHBpZCBpbiB0aGUgcHJvcGVydGllcworICAgICAgICByZXBsYWNlUHJvcGVydHkoIHByb3BlcnRpZXMsIENvbnN0YW50cy5TRVJWSUNFX1BJRCwgcGlkICk7CisgICAgICAgIHJlcGxhY2VQcm9wZXJ0eSggcHJvcGVydGllcywgQ29uZmlndXJhdGlvbkFkbWluLlNFUlZJQ0VfRkFDVE9SWVBJRCwgZmFjdG9yeVBJRCApOworCisgICAgICAgIC8vIGJ1bmRsZSBsb2NhdGlvbiBpcyBub3Qgc2V0IGhlcmUKKyAgICAgICAgaWYgKCB3aXRoQnVuZGxlTG9jYXRpb24gKQorICAgICAgICB7CisgICAgICAgICAgICByZXBsYWNlUHJvcGVydHkoIHByb3BlcnRpZXMsIENvbmZpZ3VyYXRpb25BZG1pbi5TRVJWSUNFX0JVTkRMRUxPQ0FUSU9OLCBnZXRCdW5kbGVMb2NhdGlvbigpICk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgICBwcm9wZXJ0aWVzLnJlbW92ZSggQ29uZmlndXJhdGlvbkFkbWluLlNFUlZJQ0VfQlVORExFTE9DQVRJT04gKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgdm9pZCBjbGVhckF1dG9Qcm9wZXJ0aWVzKCBEaWN0aW9uYXJ5IHByb3BlcnRpZXMgKQorICAgIHsKKyAgICAgICAgcHJvcGVydGllcy5yZW1vdmUoIENvbnN0YW50cy5TRVJWSUNFX1BJRCApOworICAgICAgICBwcm9wZXJ0aWVzLnJlbW92ZSggQ29uZmlndXJhdGlvbkFkbWluLlNFUlZJQ0VfRkFDVE9SWVBJRCApOworICAgICAgICBwcm9wZXJ0aWVzLnJlbW92ZSggQ29uZmlndXJhdGlvbkFkbWluLlNFUlZJQ0VfQlVORExFTE9DQVRJT04gKTsKKyAgICB9CisKKworICAgIHByaXZhdGUgdm9pZCByZXBsYWNlUHJvcGVydHkoIERpY3Rpb25hcnkgcHJvcGVydGllcywgU3RyaW5nIGtleSwgU3RyaW5nIHZhbHVlICkKKyAgICB7CisgICAgICAgIGlmICggdmFsdWUgPT0gbnVsbCApCisgICAgICAgIHsKKyAgICAgICAgICAgIHByb3BlcnRpZXMucmVtb3ZlKCBrZXkgKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICAgIHByb3BlcnRpZXMucHV0KCBrZXksIHZhbHVlICk7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9jb25maWdhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvZmVsaXgvY20vaW1wbC9Db25maWd1cmF0aW9uTWFuYWdlci5qYXZhIGIvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ltcGwvQ29uZmlndXJhdGlvbk1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNmIyMTkwCi0tLSAvZGV2L251bGwKKysrIGIvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ltcGwvQ29uZmlndXJhdGlvbk1hbmFnZXIuamF2YQpAQCAtMCwwICsxLDEyNjEgQEAKKy8qIAorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmZlbGl4LmNtLmltcGw7CisKKworaW1wb3J0IGphdmEuYXd0LmltYWdlLkltYWdpbmdPcEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuc2VjdXJpdHkuU2VjdXJlUmFuZG9tOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkRpY3Rpb25hcnk7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuU29ydGVkU2V0OworaW1wb3J0IGphdmEudXRpbC5UcmVlU2V0OworCitpbXBvcnQgb3JnLmFwYWNoZS5mZWxpeC5jbS5QZXJzaXN0ZW5jZU1hbmFnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5mZWxpeC5jbS5maWxlLkZpbGVQZXJzaXN0ZW5jZU1hbmFnZXI7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUFjdGl2YXRvcjsKK2ltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlQ29udGV4dDsKK2ltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlRXZlbnQ7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUxpc3RlbmVyOworaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5Db25zdGFudHM7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkZpbHRlcjsKK2ltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuSW52YWxpZFN5bnRheEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuU2VydmljZVJlZmVyZW5jZTsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNtLkNvbmZpZ3VyYXRpb25BZG1pbjsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNtLkNvbmZpZ3VyYXRpb25FdmVudDsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNtLkNvbmZpZ3VyYXRpb25FeGNlcHRpb247CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5jbS5Db25maWd1cmF0aW9uTGlzdGVuZXI7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5jbS5Db25maWd1cmF0aW9uUGx1Z2luOworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY20uTWFuYWdlZFNlcnZpY2U7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5jbS5NYW5hZ2VkU2VydmljZUZhY3Rvcnk7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5sb2cuTG9nU2VydmljZTsKK2ltcG9ydCBvcmcub3NnaS51dGlsLnRyYWNrZXIuU2VydmljZVRyYWNrZXI7CisKKworLyoqCisgKiBUaGUgPGNvZGU+Q29uZmlndXJhdGlvbk1hbmFnZXI8L2NvZGU+IGlzIHRoZSBjZW50cmFsIGNsYXNzIGluIHRoaXMKKyAqIGltcGxlbWVudGF0aW9uIG9mIHRoZSBDb25maWd1cmF0aW9uIEFkbWluIFNlcnZpY2UgU3BlY2lmaWNhdGlvbi4gQXMgc3VjaCBpdAorICogaGFzIHRoZSBmb2xsb3dpbmcgdGFza3M6CisgKiA8dWw+CisgKiA8bGk+SXQgaXMgYSA8Y29kZT5CdW5kbGVBY3RpdmF0b3I8L2NvZGU+IHdoaWNoIGlzIGNhbGxlZCB3aGVuIHRoZSBidW5kbGUKKyAqIGlzIHN0YXJ0ZWQgYW5kIHN0b3BwZWQuCisgKiA8bGk+SXQgaXMgYSA8Y29kZT5CdW5kbGVMaXN0ZW5lcjwvY29kZT4gd2hpY2ggZ2V0cyBpbmZvcm1lZCB3aGVuIHRoZQorICogc3RhdGVzIG9mIGJ1bmRsZXMgY2hhbmdlLiBNb3N0bHkgdGhpcyBpcyBuZWVkZWQgdG8gdW5iaW5kIGFueSBib3VuZAorICogY29uZmlndXJhdGlvbiBpbiBjYXNlIGEgYnVuZGxlIGlzIHVuaW5zdGFsbGVkLgorICogPGxpPkl0IGlzIGEgPGNvZGU+U2VydmljZUxpc3RlbmVyPC9jb2RlPiB3aGljaCBnZXRzIGluZm9ybWVkIHdoZW4KKyAqIDxjb2RlPk1hbmFnZWRTZXJ2aWNlPC9jb2RlPiBhbmQgPGNvZGU+TWFuYWdlZFNlcnZpY2VGYWN0b3J5PC9jb2RlPgorICogc2VydmljZXMgYXJlIHJlZ2lzdGVyZWQgYW5kIHVucmVnaXN0ZXJlZC4gVGhpcyBpcyB1c2VkIHRvIHByb3ZpZGUKKyAqIGNvbmZpZ3VyYXRpb24gdG8gdGhlc2Ugc2VydmljZXMuIEFzIGEgc2VydmljZSBsaXN0ZW5lciBpdCBhbHNvIGxpc3RlbnMgZm9yCisgKiB7QGxpbmsgUGVyc2lzdGVuY2VNYW5hZ2VyfSBpbnN0YW5jZXMgYmVpbmcgcmVnaXN0ZXJlZCB0byBzdXBwb3J0IGRpZmZlcmVudAorICogY29uZmlndXJhdGlvbiBwZXJzaXN0ZW5jZSBsYXllcnMuCisgKiA8bGk+QSB7QGxpbmsgQ29uZmlndXJhdGlvbkFkbWluRmFjdG9yeX0gaW5zdGFuY2UgaXMgcmVnaXN0ZXJlZCBhcyB0aGUKKyAqIDxjb2RlPkNvbmZpZ3VyYXRpb25BZG1pbjwvY29kZT4gc2VydmljZS4KKyAqIDxsaT5BIHtAbGluayBGaWxlUGVyc2lzdGVuY2VNYW5hZ2VyfSBpbnN0YW5jZSBpcyByZWdpc3RlcmVkIGFzIGEgZGVmYXVsdAorICoge0BsaW5rIFBlcnNpc3RlbmNlTWFuYWdlcn0uCisgKiA8bGk+TGFzdCBidXQgbm90IGxlYXN0IHRoaXMgaW5zdGFuY2UgbWFuYWdlcyBhbGwgdGFza3MgbGFpZCBvdXQgaW4gdGhlCisgKiBzcGVjaWZpY2F0aW9uIHN1Y2ggYXMgbWFpbnRhaW5pbmcgY29uZmlndXJhdGlvbiwgdGFraW5nIGNhcmUgb2YgY29uZmlndXJhdGlvbgorICogZXZlbnRzLCBldGMuCisgKiA8L3VsPgorICogPHA+CisgKiBUaGUgZGVmYXVsdCB7QGxpbmsgRmlsZVBlcnNpc3RlbmNlTWFuYWdlcn0gaXMgY29uZmlndXJlZCB3aXRoIGEgY29uZmlndXJhdGlvbgorICogbG9jYXRpb24gdGFrZW4gZnJvbSB0aGUgPGNvZGU+ZmVsaXguY20uZGlyPC9jb2RlPiBmcmFtZXdvcmsgcHJvcGVydHkuIElmCisgKiB0aGlzIHByb3BlcnR5IGlzIG5vdCBzZXQgdGhlIDxjb2RlPmNvbmZpZzwvY29kZT4gZGlyZWN0b3J5IGluIHRoZSBjdXJyZW50CisgKiB3b3JraW5nIGRpcmVjdG9yeSBhcyBzcGVjaWZpZWQgaW4gdGhlIDxjb2RlPnVzZXIuZGlyPC9jb2RlPiBzeXN0ZW0gcHJvcGVydHkKKyAqIGlzIHVzZWQuCisgKiAKKyAqIEBhdXRob3IgZm1lc2NoYmUKKyAqLworcHVibGljIGNsYXNzIENvbmZpZ3VyYXRpb25NYW5hZ2VyIGltcGxlbWVudHMgQnVuZGxlQWN0aXZhdG9yLCBCdW5kbGVMaXN0ZW5lcgoreworCisgICAgLyoqCisgICAgICogVGhlIG5hbWUgb2YgdGhlIGJ1bmRsZSBjb250ZXh0IHByb3BlcnR5IGRlZmluaW5nIHRoZSBsb2NhdGlvbiBmb3IgdGhlCisgICAgICogY29uZmlndXJhdGlvbiBmaWxlcyAodmFsdWUgaXMgImZlbGl4LmNtLmRpciIpLgorICAgICAqIAorICAgICAqIEBzZWUgI0ZpbGVQZXJzaXN0ZW5jZU1hbmFnZXIoQnVuZGxlQ29udGV4dCkKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDTV9DT05GSUdfRElSID0gImZlbGl4LmNtLmRpciI7CisKKyAgICAvLyByYW5kb20gbnVtYmVyIGdlbmVyYXRvciB0byBjcmVhdGUgY29uZmlndXJhdGlvbiBQSURzIGZvciBmYWN0b3J5CisgICAgLy8gY29uZmlndXJhdGlvbnMKKyAgICBwcml2YXRlIHN0YXRpYyBTZWN1cmVSYW5kb20gbnVtYmVyR2VuZXJhdG9yOworCisgICAgLy8gY29tcGFyYXRvciB1c2VkIHRvIGtlZXAgdGhlIG9yZGVyZWQgcGVyc2lzdGVuY2UgbWFuYWdlciBtYXAKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb21wYXJhdG9yIGNtUmFua0NvbXAgPSBuZXcgUmFua2luZ0NvbXBhcmF0b3IoIHRydWUsIENvbmZpZ3VyYXRpb25QbHVnaW4uQ01fUkFOS0lORyApOworCisgICAgLy8gdGhlIEJ1bmRsZUNvbnRleHQgb2YgdGhlIENvbmZpZ3VyYXRpb24gQWRtaW4gU2VydmljZSBidW5kbGUKKyAgICBwcml2YXRlIEJ1bmRsZUNvbnRleHQgYnVuZGxlQ29udGV4dDsKKworICAgIC8vIHRoZSBzZXJ2aWNlIHJlZmVyZW5jZSB0byB0aGUgQ29uZmlndXJhdGlvbkFkbWluIHNlcnZpY2UKKyAgICBwcml2YXRlIFNlcnZpY2VSZWZlcmVuY2UgY29uZmlndXJhdGlvbkFkbWluUmVmZXJlbmNlOworCisgICAgLy8gdGhlIFNlcnZpY2VUcmFja2VyIHRvIGVtaXQgbG9nIHNlcnZpY2VzIChzZWUgbG9nKGludCwgU3RyaW5nLCBUaHJvd2FibGUpKQorICAgIHByaXZhdGUgU2VydmljZVRyYWNrZXIgbG9nVHJhY2tlcjsKKworICAgIC8vIHRoZSBDb25maWd1cmF0aW9uRXZlbnQgbGlzdGVuZXJzCisgICAgcHJpdmF0ZSBTZXJ2aWNlVHJhY2tlciBjb25maWd1cmF0aW9uTGlzdGVuZXJUcmFja2VyOworCisgICAgLy8gc2VydmljZSB0cmFja2VyIGZvciBtYW5hZ2VkIHNlcnZpY2VzCisgICAgcHJpdmF0ZSBTZXJ2aWNlVHJhY2tlciBtYW5hZ2VkU2VydmljZVRyYWNrZXI7CisKKyAgICAvLyBzZXJ2aWNlIHRyYWNrZXIgZm9yIG1hbmFnZWQgc2VydmljZSBmYWN0b3JpZXMKKyAgICBwcml2YXRlIFNlcnZpY2VUcmFja2VyIG1hbmFnZWRTZXJ2aWNlRmFjdG9yeVRyYWNrZXI7CisKKyAgICAvLyBQZXJzaXN0ZW5jZU1hbmFnZXIgc2VydmljZXMKKyAgICBwcml2YXRlIFNlcnZpY2VUcmFja2VyIHBlcnNpc3RlbmNlTWFuYWdlclRyYWNrZXI7CisKKyAgICAvLyB0aGUgdGhyZWFkIHVzZWQgdG8gc2NoZWR1bGUgdGFza3MgcmVxdWlyZWQgdG8gcnVuIGFzeW5jaHJvbm91c2x5CisgICAgcHJpdmF0ZSBVcGRhdGVUaHJlYWQgdXBkYXRlVGhyZWFkOworCisgICAgLyoqCisgICAgICogVGhlIGFjdHVhbCBsaXN0IG9mIHtAbGluayBQZXJzaXN0ZW5jZU1hbmFnZXIgcGVyc2lzdGVuY2UgbWFuYWdlcnN9IHRvIHVzZQorICAgICAqIHdoZW4gbG9va2luZyBmb3IgY29uZmlndXJhdGlvbiBkYXRhLiBUaGlzIGxpc3QgaXMgYnVpbHQgZnJvbSB0aGUKKyAgICAgKiB7QGxpbmsgI3BlcnNpc3RlbmNlTWFuYWdlck1hcH0sIHdoaWNoIGlzIG9yZGVyZWQgYWNjb3JkaW5nIHRvIHRoZQorICAgICAqIHtAbGluayBSYW5raW5nQ29tcGFyYXRvcn0uCisgICAgICovCisgICAgcHJpdmF0ZSBQZXJzaXN0ZW5jZU1hbmFnZXJbXSBwZXJzaXN0ZW5jZU1hbmFnZXJzOworCisgICAgLy8gdGhlIHBlcnNpc3RlbmNlTWFuYWdlclRyYWNrZXIuZ2V0VHJhY2tpbmdDb3VudCB3aGVuIHRoZQorICAgIC8vIHBlcnNpc3RlbmNlTWFuYWdlcnMgd2VyZSBsYXN0IGdvdAorICAgIHByaXZhdGUgaW50IHBtdENvdW50OworCisgICAgLy8gdGhlIGNhY2hlIG9mIEZhY3RvcnkgaW5zdGFuY2VzIG1hcHBlZCBieSB0aGVpciBmYWN0b3J5IFBJRAorICAgIHByaXZhdGUgTWFwIGZhY3RvcmllczsKKworICAgIC8vIHRoZSBjYWNoZSBvZiBDb25maWd1cmF0aW9uIGluc3RhbmNlcyBtYXBwZWQgYnkgdGhlaXIgUElECisgICAgcHJpdmF0ZSBNYXAgY29uZmlndXJhdGlvbnM7CisKKworICAgIHB1YmxpYyB2b2lkIHN0YXJ0KCBCdW5kbGVDb250ZXh0IGJ1bmRsZUNvbnRleHQgKQorICAgIHsKKyAgICAgICAgLy8gdHJhY2sgdGhlIGxvZyBzZXJ2aWNlIHVzaW5nIGEgU2VydmljZVRyYWNrZXIKKyAgICAgICAgbG9nVHJhY2tlciA9IG5ldyBTZXJ2aWNlVHJhY2tlciggYnVuZGxlQ29udGV4dCwgTG9nU2VydmljZS5jbGFzcy5nZXROYW1lKCksIG51bGwgKTsKKyAgICAgICAgbG9nVHJhY2tlci5vcGVuKCk7CisKKyAgICAgICAgLy8gc2V0IHVwIHNvbWUgZmllbGRzCisgICAgICAgIHRoaXMuYnVuZGxlQ29udGV4dCA9IGJ1bmRsZUNvbnRleHQ7CisgICAgICAgIHRoaXMuZmFjdG9yaWVzID0gbmV3IEhhc2hNYXAoKTsKKyAgICAgICAgdGhpcy5jb25maWd1cmF0aW9ucyA9IG5ldyBIYXNoTWFwKCk7CisKKyAgICAgICAgLy8gY29uZmlndXJhdGlvbmxpc3RlbmVyIHN1cHBvcnQKKyAgICAgICAgY29uZmlndXJhdGlvbkxpc3RlbmVyVHJhY2tlciA9IG5ldyBTZXJ2aWNlVHJhY2tlciggYnVuZGxlQ29udGV4dCwgQ29uZmlndXJhdGlvbkxpc3RlbmVyLmNsYXNzLmdldE5hbWUoKSwgbnVsbCApOworICAgICAgICBjb25maWd1cmF0aW9uTGlzdGVuZXJUcmFja2VyLm9wZW4oKTsKKworICAgICAgICAvLyBpbml0aWFsaXplIHRoZSBhc3luY2hvbm91cyB1cGRhdGVyIHRocmVhZAorICAgICAgICB0aGlzLnVwZGF0ZVRocmVhZCA9IG5ldyBVcGRhdGVUaHJlYWQoIHRoaXMgKTsKKyAgICAgICAgdGhpcy51cGRhdGVUaHJlYWQuc3RhcnQoKTsKKworICAgICAgICAvLyBzZXQgdXAgdGhlIGxvY2F0aW9uIChtaWdodCB0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pCisgICAgICAgIHRyeQorICAgICAgICB7CisgICAgICAgICAgICBGaWxlUGVyc2lzdGVuY2VNYW5hZ2VyIGZwbSA9IG5ldyBGaWxlUGVyc2lzdGVuY2VNYW5hZ2VyKCBidW5kbGVDb250ZXh0LmdldFByb3BlcnR5KCBDTV9DT05GSUdfRElSICkgKTsKKyAgICAgICAgICAgIEhhc2h0YWJsZSBwcm9wcyA9IG5ldyBIYXNodGFibGUoKTsKKyAgICAgICAgICAgIHByb3BzLnB1dCggQ29uc3RhbnRzLlNFUlZJQ0VfUElELCBmcG0uZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKTsKKyAgICAgICAgICAgIHByb3BzLnB1dCggQ29uc3RhbnRzLlNFUlZJQ0VfREVTQ1JJUFRJT04sICJQbGF0Zm9ybSBGaWxlc3lzdGVtIFBlcnNpc3RlbmNlIE1hbmFnZXIiICk7CisgICAgICAgICAgICBwcm9wcy5wdXQoIENvbnN0YW50cy5TRVJWSUNFX1ZFTkRPUiwgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiApOworICAgICAgICAgICAgcHJvcHMucHV0KCBDb25zdGFudHMuU0VSVklDRV9SQU5LSU5HLCBuZXcgSW50ZWdlciggSW50ZWdlci5NSU5fVkFMVUUgKSApOworICAgICAgICAgICAgYnVuZGxlQ29udGV4dC5yZWdpc3RlclNlcnZpY2UoIFBlcnNpc3RlbmNlTWFuYWdlci5jbGFzcy5nZXROYW1lKCksIGZwbSwgcHJvcHMgKTsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUgKQorICAgICAgICB7CisgICAgICAgICAgICBsb2coIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCAiQ2Fubm90IGNyZWF0ZSB0aGUgRmlsZVBlcnNpc3RlbmNlTWFuYWdlciIsIGlhZSApOworICAgICAgICB9CisKKyAgICAgICAgLy8gcmVnaXN0ZXIgYXMgYnVuZGxlIGFuZCBzZXJ2aWNlIGxpc3RlbmVyCisgICAgICAgIGJ1bmRsZUNvbnRleHQuYWRkQnVuZGxlTGlzdGVuZXIoIHRoaXMgKTsKKworICAgICAgICAvLyBnZXQgYWxsIHBlcnNpc3RlbmNlIG1hbmFnZXJzIHRvIGJlZ2luIHdpdGgKKyAgICAgICAgcG10Q291bnQgPSAxOyAvLyBtYWtlIHN1cmUgdG8gZ2V0IHRoZSBwZXJzaXN0ZW5jZSBtYW5hZ2VycyBhdCBsZWFzdAorICAgICAgICAvLyBvbmNlCisgICAgICAgIHBlcnNpc3RlbmNlTWFuYWdlclRyYWNrZXIgPSBuZXcgU2VydmljZVRyYWNrZXIoIGJ1bmRsZUNvbnRleHQsIFBlcnNpc3RlbmNlTWFuYWdlci5jbGFzcy5nZXROYW1lKCksIG51bGwgKTsKKyAgICAgICAgcGVyc2lzdGVuY2VNYW5hZ2VyVHJhY2tlci5vcGVuKCk7CisKKyAgICAgICAgLy8gY3JlYXRlIGFuZCByZWdpc3RlciBjb25maWd1cmF0aW9uIGFkbWluIC0gc3RhcnQgYWZ0ZXIgUE0gdHJhY2tlciAuLi4KKyAgICAgICAgQ29uZmlndXJhdGlvbkFkbWluRmFjdG9yeSBjYWYgPSBuZXcgQ29uZmlndXJhdGlvbkFkbWluRmFjdG9yeSggdGhpcyApOworICAgICAgICBIYXNodGFibGUgcHJvcHMgPSBuZXcgSGFzaHRhYmxlKCk7CisgICAgICAgIHByb3BzLnB1dCggQ29uc3RhbnRzLlNFUlZJQ0VfUElELCAib3JnLmFwYWNoZS5mZWxpeC5jbS5Db25maWd1cmF0aW9uQWRtaW4iICk7CisgICAgICAgIHByb3BzLnB1dCggQ29uc3RhbnRzLlNFUlZJQ0VfREVTQ1JJUFRJT04sICJDb25maWd1cmF0aW9uIEFkbWluIFNlcnZpY2UgU3BlY2lmaWNhdGlvbiAxLjIgSW1wbGVtZW50YXRpb24iICk7CisgICAgICAgIHByb3BzLnB1dCggQ29uc3RhbnRzLlNFUlZJQ0VfVkVORE9SLCAiQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24iICk7CisgICAgICAgIGJ1bmRsZUNvbnRleHQucmVnaXN0ZXJTZXJ2aWNlKCBDb25maWd1cmF0aW9uQWRtaW4uY2xhc3MuZ2V0TmFtZSgpLCBjYWYsIHByb3BzICk7CisKKyAgICAgICAgLy8gc3RhcnQgaGFuZGxpbmcgTWFuYWdlZFNlcnZpY2VbRmFjdG9yeV0gc2VydmljZXMKKyAgICAgICAgbWFuYWdlZFNlcnZpY2VUcmFja2VyID0gbmV3IE1hbmFnZWRTZXJ2aWNlVHJhY2tlcigpOworICAgICAgICBtYW5hZ2VkU2VydmljZUZhY3RvcnlUcmFja2VyID0gbmV3IE1hbmFnZWRTZXJ2aWNlRmFjdG9yeVRyYWNrZXIoKTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHN0b3AoIEJ1bmRsZUNvbnRleHQgYnVuZGxlQ29udGV4dCApCisgICAgeworICAgICAgICAvLyBzdG9wIGhhbmRsaW5nIE1hbmFnZWRTZXJ2aWNlW0ZhY3RvcnldIHNlcnZpY2VzCisgICAgICAgIG1hbmFnZWRTZXJ2aWNlRmFjdG9yeVRyYWNrZXIuY2xvc2UoKTsKKyAgICAgICAgbWFuYWdlZFNlcnZpY2VUcmFja2VyLmNsb3NlKCk7CisKKyAgICAgICAgLy8gZG9uJ3QgY2FyZSBmb3IgUGVyc2lzdGVuY2VNYW5hZ2VycyBhbnkgbW9yZQorICAgICAgICBwZXJzaXN0ZW5jZU1hbmFnZXJUcmFja2VyLmNsb3NlKCk7CisKKyAgICAgICAgLy8gc3RvcCBsaXN0ZW5pbmcgZm9yIGV2ZW50cworICAgICAgICBidW5kbGVDb250ZXh0LnJlbW92ZUJ1bmRsZUxpc3RlbmVyKCB0aGlzICk7CisKKyAgICAgICAgaWYgKCBjb25maWd1cmF0aW9uTGlzdGVuZXJUcmFja2VyICE9IG51bGwgKQorICAgICAgICB7CisgICAgICAgICAgICBjb25maWd1cmF0aW9uTGlzdGVuZXJUcmFja2VyLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIHVwZGF0ZVRocmVhZCAhPSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgLy8gdGVybWluYXRlIGFzeW5jaHJvdW5vdXMgdXBkYXRlcworICAgICAgICAgICAgdXBkYXRlVGhyZWFkLnRlcm1pbmF0ZSgpOworCisgICAgICAgICAgICAvLyB3YWl0IGZvciBhbGwgdXBkYXRlcyB0byB0ZXJtaW5hdGUKKyAgICAgICAgICAgIHRyeQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHVwZGF0ZVRocmVhZC5qb2luKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXRjaCAoIEludGVycnVwdGVkRXhjZXB0aW9uIGllICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAvLyBkb24ndCByZWFsbHkgY2FyZQorICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgaWYgKCBsb2dUcmFja2VyICE9IG51bGwgKQorICAgICAgICB7CisgICAgICAgICAgICBsb2dUcmFja2VyLmNsb3NlKCk7CisgICAgICAgIH0KKworICAgICAgICB0aGlzLmJ1bmRsZUNvbnRleHQgPSBudWxsOworICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb25zID0gbnVsbDsKKyAgICB9CisKKworICAgIC8vIC0tLS0tLS0tLS0gQ29uZmlndXJhdGlvbiBjYWNoaW5nIHN1cHBvcnQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIENvbmZpZ3VyYXRpb25JbXBsIGdldENhY2hlZENvbmZpZ3VyYXRpb24oIFN0cmluZyBwaWQgKQorICAgIHsKKyAgICAgICAgc3luY2hyb25pemVkICggY29uZmlndXJhdGlvbnMgKQorICAgICAgICB7CisgICAgICAgICAgICByZXR1cm4gKCBDb25maWd1cmF0aW9uSW1wbCApIGNvbmZpZ3VyYXRpb25zLmdldCggcGlkICk7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIEl0ZXJhdG9yIGdldENhY2hlZENvbmZpZ3VyYXRpb25zKCkKKyAgICB7CisgICAgICAgIHN5bmNocm9uaXplZCAoIGNvbmZpZ3VyYXRpb25zICkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuIGNvbmZpZ3VyYXRpb25zLnZhbHVlcygpLml0ZXJhdG9yKCk7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIHZvaWQgY2FjaGVDb25maWd1cmF0aW9uKCBDb25maWd1cmF0aW9uSW1wbCBjb25maWd1cmF0aW9uICkKKyAgICB7CisgICAgICAgIHN5bmNocm9uaXplZCAoIGNvbmZpZ3VyYXRpb25zICkKKyAgICAgICAgeworICAgICAgICAgICAgY29uZmlndXJhdGlvbnMucHV0KCBjb25maWd1cmF0aW9uLmdldFBpZCgpLCBjb25maWd1cmF0aW9uICk7CisgICAgICAgIH0KKyAgICB9CisKKworICAgIHZvaWQgcmVtb3ZlQ29uZmlndXJhdGlvbiggQ29uZmlndXJhdGlvbkltcGwgY29uZmlndXJhdGlvbiApCisgICAgeworICAgICAgICBzeW5jaHJvbml6ZWQgKCBjb25maWd1cmF0aW9ucyApCisgICAgICAgIHsKKyAgICAgICAgICAgIGNvbmZpZ3VyYXRpb25zLnJlbW92ZSggY29uZmlndXJhdGlvbi5nZXRQaWQoKSApOworICAgICAgICB9CisgICAgfQorCisKKyAgICAvLyAtLS0tLS0tLS0tIENvbmZpZ3VyYXRpb25BZG1pbkltcGwgc3VwcG9ydCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICAvKgorICAgICAqIChub24tSmF2YWRvYykKKyAgICAgKiAKKyAgICAgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbkFkbWluI2NyZWF0ZUZhY3RvcnlDb25maWd1cmF0aW9uKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgQ29uZmlndXJhdGlvbkltcGwgY3JlYXRlRmFjdG9yeUNvbmZpZ3VyYXRpb24oIENvbmZpZ3VyYXRpb25BZG1pbkltcGwgY29uZmlndXJhdGlvbkFkbWluLCBTdHJpbmcgZmFjdG9yeVBpZCApCisgICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgRmFjdG9yeSBmYWN0b3J5ID0gZ2V0RmFjdG9yeSggZmFjdG9yeVBpZCApOworCisgICAgICAgIC8vIGNoZWNrIFBlcnNtaXNzaW9uIGlmIGZhY3RvcnkgaXMgYm91bmQgdG8gYW5vdGhlciBidW5kbGUKKyAgICAgICAgaWYgKCBmYWN0b3J5LmdldEJ1bmRsZUxvY2F0aW9uKCkgIT0gbnVsbAorICAgICAgICAgICAgJiYgIWZhY3RvcnkuZ2V0QnVuZGxlTG9jYXRpb24oKS5lcXVhbHMoIGNvbmZpZ3VyYXRpb25BZG1pbi5nZXRCdW5kbGUoKS5nZXRMb2NhdGlvbigpICkgKQorICAgICAgICB7CisgICAgICAgICAgICBjb25maWd1cmF0aW9uQWRtaW4uY2hlY2tQZXJtaXNzaW9uKCk7CisgICAgICAgIH0KKworICAgICAgICAvLyBjcmVhdGUgdGhlIGNvbmZpZ3VyYXRpb24KKyAgICAgICAgU3RyaW5nIHBpZCA9IGNyZWF0ZVBpZCggZmFjdG9yeVBpZCApOworICAgICAgICBDb25maWd1cmF0aW9uSW1wbCBjb25maWcgPSBjcmVhdGVDb25maWd1cmF0aW9uKCBwaWQsIGZhY3RvcnlQaWQgKTsKKyAgICAgICAgY29uZmlnLnNldEJ1bmRsZUxvY2F0aW9uKCBjb25maWd1cmF0aW9uQWRtaW4uZ2V0QnVuZGxlKCkuZ2V0TG9jYXRpb24oKSApOworCisgICAgICAgIC8vIGFkZCB0aGUgY29uZmlndXJhdGlvbiB0byB0aGUgZmFjdG9yeQorICAgICAgICBmYWN0b3J5LmFkZFBJRCggcGlkICk7CisgICAgICAgIGZhY3Rvcnkuc3RvcmUoKTsKKworICAgICAgICByZXR1cm4gY29uZmlnOworICAgIH0KKworCisgICAgLyoKKyAgICAgKiAobm9uLUphdmFkb2MpCisgICAgICogCisgICAgICogQHNlZSBvcmcub3NnaS5zZXJ2aWNlLmNtLkNvbmZpZ3VyYXRpb25BZG1pbiNjcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbihqYXZhLmxhbmcuU3RyaW5nLAorICAgICAqICAgICAgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBDb25maWd1cmF0aW9uSW1wbCBjcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbiggU3RyaW5nIGZhY3RvcnlQaWQsIFN0cmluZyBsb2NhdGlvbiApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgLy8gY3JlYXRlIHRoZSBjb25maWd1cmF0aW9uCisgICAgICAgIFN0cmluZyBwaWQgPSBjcmVhdGVQaWQoIGZhY3RvcnlQaWQgKTsKKyAgICAgICAgQ29uZmlndXJhdGlvbkltcGwgY29uZmlnID0gY3JlYXRlQ29uZmlndXJhdGlvbiggcGlkLCBmYWN0b3J5UGlkICk7CisgICAgICAgIGlmICggbG9jYXRpb24gIT0gbnVsbCApCisgICAgICAgIHsKKyAgICAgICAgICAgIGNvbmZpZy5zZXRCdW5kbGVMb2NhdGlvbiggbG9jYXRpb24gKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIGFkZCB0aGUgY29uZmlndXJhdGlvbiB0byB0aGUgZmFjdG9yeQorICAgICAgICBGYWN0b3J5IGZhY3RvcnkgPSBnZXRGYWN0b3J5KCBmYWN0b3J5UGlkICk7CisgICAgICAgIGZhY3RvcnkuYWRkUElEKCBwaWQgKTsKKyAgICAgICAgZmFjdG9yeS5zdG9yZSgpOworCisgICAgICAgIHJldHVybiBjb25maWc7CisgICAgfQorCisKKyAgICBDb25maWd1cmF0aW9uSW1wbCBnZXRDb25maWd1cmF0aW9uKCBTdHJpbmcgcGlkICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICByZXR1cm4gZ2V0Q29uZmlndXJhdGlvbiggcGlkLCB0cnVlICk7CisgICAgfQorCisKKyAgICBDb25maWd1cmF0aW9uSW1wbCBnZXRDb25maWd1cmF0aW9uKCBTdHJpbmcgcGlkLCBTdHJpbmcgYnVuZGxlTG9jYXRpb24gKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIENvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZyA9IGdldENvbmZpZ3VyYXRpb24oIHBpZCwgZmFsc2UgKTsKKworICAgICAgICBpZiAoIGNvbmZpZyA9PSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgY29uZmlnID0gY3JlYXRlQ29uZmlndXJhdGlvbiggcGlkLCBudWxsICk7CisgICAgICAgICAgICBpZiAoIGJ1bmRsZUxvY2F0aW9uICE9IG51bGwgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGNvbmZpZy5zZXRCdW5kbGVMb2NhdGlvbiggYnVuZGxlTG9jYXRpb24gKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBjb25maWc7CisgICAgfQorCisKKyAgICBDb25maWd1cmF0aW9uSW1wbFtdIGxpc3RDb25maWd1cmF0aW9ucyggQ29uZmlndXJhdGlvbkFkbWluSW1wbCBjb25maWd1cmF0aW9uQWRtaW4sIFN0cmluZyBmaWx0ZXJTdHJpbmcgKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24sIEludmFsaWRTeW50YXhFeGNlcHRpb24KKyAgICB7CisgICAgICAgIEZpbHRlciBmaWx0ZXIgPSBudWxsOworICAgICAgICBpZiAoIGZpbHRlclN0cmluZyAhPSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgZmlsdGVyID0gYnVuZGxlQ29udGV4dC5jcmVhdGVGaWx0ZXIoIGZpbHRlclN0cmluZyApOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiB1bnByaXZpbGVnZWQgPSBjb25maWd1cmF0aW9uQWRtaW4gIT0gbnVsbCAmJiAhY29uZmlndXJhdGlvbkFkbWluLmhhc1Blcm1pc3Npb24oKTsKKyAgICAgICAgU3RyaW5nIGxvY2F0aW9uID0gdW5wcml2aWxlZ2VkID8gY29uZmlndXJhdGlvbkFkbWluLmdldEJ1bmRsZSgpLmdldExvY2F0aW9uKCkgOiBudWxsOworCisgICAgICAgIExpc3QgY29uZmlnTGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKKworICAgICAgICBQZXJzaXN0ZW5jZU1hbmFnZXJbXSBwbUxpc3QgPSBnZXRQZXJzaXN0ZW5jZU1hbmFnZXJzKCk7CisgICAgICAgIGZvciAoIGludCBpID0gMDsgaSA8IHBtTGlzdC5sZW5ndGg7IGkrKyApCisgICAgICAgIHsKKyAgICAgICAgICAgIEVudW1lcmF0aW9uIGNvbmZpZ3MgPSBwbUxpc3RbaV0uZ2V0RGljdGlvbmFyaWVzKCk7CisgICAgICAgICAgICB3aGlsZSAoIGNvbmZpZ3MuaGFzTW9yZUVsZW1lbnRzKCkgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIERpY3Rpb25hcnkgY29uZmlnID0gKCBEaWN0aW9uYXJ5ICkgY29uZmlncy5uZXh0RWxlbWVudCgpOworCisgICAgICAgICAgICAgICAgLy8gaWdub3JlIG5vbi1Db25maWd1cmF0aW9uIGRpY3Rpb25hcmllcworICAgICAgICAgICAgICAgIGlmICggY29uZmlnLmdldCggQ29uc3RhbnRzLlNFUlZJQ0VfUElEICkgPT0gbnVsbCApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBpZ25vcmUgdGhpcyBjb25maWcgaWYgbm90IHByaXZpbGVnZWQgYW5kIG5vdCBib3VuZCB0byBidW5kbGUKKyAgICAgICAgICAgICAgICBpZiAoIHVucHJpdmlsZWdlZCApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBPYmplY3QgYm91bmRMb2NhdGlvbiA9IGNvbmZpZy5nZXQoIENvbmZpZ3VyYXRpb25BZG1pbi5TRVJWSUNFX0JVTkRMRUxPQ0FUSU9OICk7CisgICAgICAgICAgICAgICAgICAgIGlmICggIWxvY2F0aW9uLmVxdWFscyggYm91bmRMb2NhdGlvbiApICkKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBjaGVjayBmaWx0ZXIKKyAgICAgICAgICAgICAgICBpZiAoIGZpbHRlciA9PSBudWxsIHx8IGZpbHRlci5tYXRjaCggY29uZmlnICkgKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgY29uZmlnTGlzdC5hZGQoIG5ldyBDb25maWd1cmF0aW9uSW1wbCggdGhpcywgcG1MaXN0W2ldLCBjb25maWcgKSApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiAoIG9yZy5hcGFjaGUuZmVsaXguY20uaW1wbC5Db25maWd1cmF0aW9uSW1wbFtdICkgY29uZmlnTGlzdC50b0FycmF5KCBuZXcgQ29uZmlndXJhdGlvbkltcGxbY29uZmlnTGlzdAorICAgICAgICAgICAgLnNpemUoKV0gKTsKKyAgICB9CisKKworICAgIHZvaWQgZGVsZXRlZCggQ29uZmlndXJhdGlvbkltcGwgY29uZmlnICkKKyAgICB7CisgICAgICAgIC8vIHJlbW92ZSB0aGUgY29uZmlndXJhdGlvbiBmcm9tIHRoZSBjYWNoZQorICAgICAgICByZW1vdmVDb25maWd1cmF0aW9uKCBjb25maWcgKTsKKyAgICAgICAgdXBkYXRlVGhyZWFkLnNjaGVkdWxlKCBuZXcgRGVsZXRlQ29uZmlndXJhdGlvbiggY29uZmlnICkgKTsKKyAgICB9CisKKworICAgIHZvaWQgdXBkYXRlZCggQ29uZmlndXJhdGlvbkltcGwgY29uZmlnICkKKyAgICB7CisgICAgICAgIHVwZGF0ZVRocmVhZC5zY2hlZHVsZSggbmV3IFVwZGF0ZUNvbmZpZ3VyYXRpb24oIGNvbmZpZyApICk7CisgICAgfQorCisKKyAgICB2b2lkIGZpcmVDb25maWd1cmF0aW9uRXZlbnQoIGludCB0eXBlLCBDb25maWd1cmF0aW9uSW1wbCBjb25maWcgKQorICAgIHsKKworICAgICAgICB1cGRhdGVUaHJlYWQuc2NoZWR1bGUoIG5ldyBGaXJlQ29uZmlndXJhdGlvbkV2ZW50KCB0eXBlLCBjb25maWcgKSApOworICAgIH0KKworCisgICAgLy8gLS0tLS0tLS0tLSBCdW5kbGVMaXN0ZW5lciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgcHVibGljIHZvaWQgYnVuZGxlQ2hhbmdlZCggQnVuZGxlRXZlbnQgZXZlbnQgKQorICAgIHsKKyAgICAgICAgaWYgKCBldmVudC5nZXRUeXBlKCkgPT0gQnVuZGxlRXZlbnQuVU5JTlNUQUxMRUQgKQorICAgICAgICB7CisgICAgICAgICAgICBTdHJpbmcgbG9jYXRpb24gPSBldmVudC5nZXRCdW5kbGUoKS5nZXRMb2NhdGlvbigpOworICAgICAgICAgICAgU3RyaW5nIGZpbHRlciA9ICIoc2VydmljZS5idW5kbGVMb2NhdGlvbj0iICsgbG9jYXRpb24gKyAiKSI7CisKKyAgICAgICAgICAgIHRyeQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIENvbmZpZ3VyYXRpb25JbXBsW10gY29uZmlncyA9IGxpc3RDb25maWd1cmF0aW9ucyggbnVsbCwgZmlsdGVyICk7CisgICAgICAgICAgICAgICAgaWYgKCBjb25maWdzICE9IG51bGwgJiYgY29uZmlncy5sZW5ndGggPiAwICkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIGZvciAoIGludCBpID0gMDsgaSA8IGNvbmZpZ3MubGVuZ3RoOyBpKysgKQorICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICBjb25maWdzW2ldLnNldEJ1bmRsZUxvY2F0aW9uKCBudWxsICk7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkKKyAgICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWdzW2ldLnN0b3JlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoIElPRXhjZXB0aW9uIGlvZSApCisgICAgICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKCBMb2dTZXJ2aWNlLkxPR19XQVJOSU5HLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHJvYmxlbSBzdG9yaW5nIHVuYm91bmQgY29uZmlndXJhdGlvbiAiICsgY29uZmlnc1tpXS5nZXRQaWQoKSwgaW9lICk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXRjaCAoIEV4Y2VwdGlvbiBlICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBsb2coIExvZ1NlcnZpY2UuTE9HX1dBUk5JTkcsICJQcm9ibGVtIHVuYmluZGluZyBjb25maWd1cmF0aW9ucyBmb3IgYnVuZGxlICIgKyBsb2NhdGlvbiwgZSApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyB1bmJpbmQgY2FjaGVkIGNvbmZpZ3VyYXRpb25zCisgICAgICAgICAgICBJdGVyYXRvciBjb25maWd1cmF0aW9ucyA9IGdldENhY2hlZENvbmZpZ3VyYXRpb25zKCk7CisgICAgICAgICAgICB3aGlsZSAoIGNvbmZpZ3VyYXRpb25zLmhhc05leHQoKSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgQ29uZmlndXJhdGlvbkltcGwgY2ZnID0gKCBDb25maWd1cmF0aW9uSW1wbCApIGNvbmZpZ3VyYXRpb25zLm5leHQoKTsKKyAgICAgICAgICAgICAgICBpZiAoIGxvY2F0aW9uLmVxdWFscyggY2ZnLmdldEJ1bmRsZUxvY2F0aW9uKCkgKSApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBjZmcuc2V0QnVuZGxlTG9jYXRpb24oIG51bGwgKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIFRPRE86IGZpbmQgZmFjdG9yaWVzIHRvIHVuYmluZCAhIQorICAgICAgICB9CisgICAgfQorCisKKyAgICAvLyAtLS0tLS0tLS0tIGludGVybmFsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyAgICBwcml2YXRlIFBlcnNpc3RlbmNlTWFuYWdlcltdIGdldFBlcnNpc3RlbmNlTWFuYWdlcnMoKQorICAgIHsKKyAgICAgICAgaWYgKCBwZXJzaXN0ZW5jZU1hbmFnZXJzID09IG51bGwgfHwgcGVyc2lzdGVuY2VNYW5hZ2VyVHJhY2tlci5nZXRUcmFja2luZ0NvdW50KCkgPiBwbXRDb3VudCApCisgICAgICAgIHsKKworICAgICAgICAgICAgU2VydmljZVJlZmVyZW5jZVtdIHJlZnMgPSBwZXJzaXN0ZW5jZU1hbmFnZXJUcmFja2VyLmdldFNlcnZpY2VSZWZlcmVuY2VzKCk7CisgICAgICAgICAgICBpZiAoIHJlZnMgPT0gbnVsbCB8fCByZWZzLmxlbmd0aCA9PSAwICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFBlcnNpc3RlbmNlTWFuYWdlclswXTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU29ydGVkU2V0IHBtcyA9IG5ldyBUcmVlU2V0KCBjbVJhbmtDb21wICk7CisgICAgICAgICAgICBmb3IgKCBpbnQgaSA9IDA7IGkgPCByZWZzLmxlbmd0aDsgaSsrICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBwbXMuYWRkKCBwZXJzaXN0ZW5jZU1hbmFnZXJUcmFja2VyLmdldFNlcnZpY2UoIHJlZnNbaV0gKSApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBwZXJzaXN0ZW5jZU1hbmFnZXJzID0gKCBQZXJzaXN0ZW5jZU1hbmFnZXJbXSApIHBtcy50b0FycmF5KCBuZXcgUGVyc2lzdGVuY2VNYW5hZ2VyW3Btcy5zaXplKCldICk7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gcGVyc2lzdGVuY2VNYW5hZ2VyczsKKyAgICB9CisKKworICAgIHByaXZhdGUgdm9pZCBjb25maWd1cmUoIFNlcnZpY2VSZWZlcmVuY2Ugc3IsIE1hbmFnZWRTZXJ2aWNlIHNlcnZpY2UgKQorICAgIHsKKyAgICAgICAgU3RyaW5nIHBpZCA9ICggU3RyaW5nICkgc3IuZ2V0UHJvcGVydHkoIENvbnN0YW50cy5TRVJWSUNFX1BJRCApOworICAgICAgICBpZiAoIHBpZCAhPSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgTWFuYWdlZFNlcnZpY2VVcGRhdGUgdXBkYXRlID0gbmV3IE1hbmFnZWRTZXJ2aWNlVXBkYXRlKCBwaWQsIHNyLCBzZXJ2aWNlICk7CisgICAgICAgICAgICB1cGRhdGVUaHJlYWQuc2NoZWR1bGUoIHVwZGF0ZSApOworICAgICAgICB9CisKKyAgICB9CisKKworICAgIHByaXZhdGUgdm9pZCBjb25maWd1cmUoIFNlcnZpY2VSZWZlcmVuY2Ugc3IsIE1hbmFnZWRTZXJ2aWNlRmFjdG9yeSBzZXJ2aWNlICkKKyAgICB7CisgICAgICAgIFN0cmluZyBwaWQgPSAoIFN0cmluZyApIHNyLmdldFByb3BlcnR5KCBDb25zdGFudHMuU0VSVklDRV9QSUQgKTsKKyAgICAgICAgaWYgKCBwaWQgIT0gbnVsbCApCisgICAgICAgIHsKKyAgICAgICAgICAgIE1hbmFnZWRTZXJ2aWNlRmFjdG9yeVVwZGF0ZSB1cGRhdGUgPSBuZXcgTWFuYWdlZFNlcnZpY2VGYWN0b3J5VXBkYXRlKCBwaWQsIHNyLCBzZXJ2aWNlICk7CisgICAgICAgICAgICB1cGRhdGVUaHJlYWQuc2NoZWR1bGUoIHVwZGF0ZSApOworICAgICAgICB9CisKKyAgICB9CisKKworICAgIENvbmZpZ3VyYXRpb25JbXBsIGdldENvbmZpZ3VyYXRpb24oIFN0cmluZyBwaWQsIGJvb2xlYW4gY3JlYXRlICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBDb25maWd1cmF0aW9uSW1wbCBjb25maWcgPSBnZXRDYWNoZWRDb25maWd1cmF0aW9uKCBwaWQgKTsKKyAgICAgICAgaWYgKCBjb25maWcgIT0gbnVsbCApCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybiBjb25maWc7CisgICAgICAgIH0KKworICAgICAgICBQZXJzaXN0ZW5jZU1hbmFnZXJbXSBwbUxpc3QgPSBnZXRQZXJzaXN0ZW5jZU1hbmFnZXJzKCk7CisgICAgICAgIGZvciAoIGludCBpID0gMDsgaSA8IHBtTGlzdC5sZW5ndGg7IGkrKyApCisgICAgICAgIHsKKyAgICAgICAgICAgIGlmICggcG1MaXN0W2ldLmV4aXN0cyggcGlkICkgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIERpY3Rpb25hcnkgcHJvcHMgPSBwbUxpc3RbaV0ubG9hZCggcGlkICk7CisgICAgICAgICAgICAgICAgY29uZmlnID0gbmV3IENvbmZpZ3VyYXRpb25JbXBsKCB0aGlzLCBwbUxpc3RbaV0sIHByb3BzICk7CisgICAgICAgICAgICAgICAgY2FjaGVDb25maWd1cmF0aW9uKCBjb25maWcgKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gY29uZmlnOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLy8gaWYgZ2V0dGluZyBoZXJlLCB0aGVyZSBpcyBubyBjb25maWd1cmF0aW9uIHlldCwgb3B0aW9uYWxseSBjcmVhdGUgbmV3CisgICAgICAgIHJldHVybiAoIGNyZWF0ZSApID8gY3JlYXRlQ29uZmlndXJhdGlvbiggcGlkLCBudWxsICkgOiBudWxsOworICAgIH0KKworCisgICAgQ29uZmlndXJhdGlvbkltcGwgY3JlYXRlQ29uZmlndXJhdGlvbiggU3RyaW5nIHBpZCwgU3RyaW5nIGZhY3RvcnlQaWQgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIENvbmZpZ3VyYXRpb25JbXBsIGNvbmZpZyA9IG5ldyBDb25maWd1cmF0aW9uSW1wbCggdGhpcywgZ2V0UGVyc2lzdGVuY2VNYW5hZ2VycygpWzBdLCBwaWQsIGZhY3RvcnlQaWQgKTsKKworICAgICAgICAvLyBpbW1lZGlhdGVseSBzdG9yZSB0aGUgY29uZmlndXJhdGlvbiwgeWV0IGdldFByb3BlcnRpZXMoKSBtdXN0IHN0aWxsCisgICAgICAgIC8vIHJldHVybiBudWxsCisgICAgICAgIGNvbmZpZy5zdG9yZSgpOworCisgICAgICAgIGNhY2hlQ29uZmlndXJhdGlvbiggY29uZmlnICk7CisKKyAgICAgICAgcmV0dXJuIGNvbmZpZzsKKyAgICB9CisKKworICAgIEZhY3RvcnkgZ2V0RmFjdG9yeSggU3RyaW5nIGZhY3RvcnlQaWQgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIEZhY3RvcnkgZmFjdG9yeSA9ICggRmFjdG9yeSApIGZhY3Rvcmllcy5nZXQoIGZhY3RvcnlQaWQgKTsKKyAgICAgICAgaWYgKCBmYWN0b3J5ICE9IG51bGwgKQorICAgICAgICB7CisgICAgICAgICAgICByZXR1cm4gZmFjdG9yeTsKKyAgICAgICAgfQorCisgICAgICAgIFBlcnNpc3RlbmNlTWFuYWdlcltdIHBtTGlzdCA9IGdldFBlcnNpc3RlbmNlTWFuYWdlcnMoKTsKKyAgICAgICAgZm9yICggaW50IGkgPSAwOyBpIDwgcG1MaXN0Lmxlbmd0aDsgaSsrICkKKyAgICAgICAgeworICAgICAgICAgICAgaWYgKCBGYWN0b3J5LmV4aXN0cyggcG1MaXN0W2ldLCBmYWN0b3J5UGlkICkgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGZhY3RvcnkgPSBGYWN0b3J5LmxvYWQoIHBtTGlzdFtpXSwgZmFjdG9yeVBpZCApOworICAgICAgICAgICAgICAgIGZhY3Rvcmllcy5wdXQoIGZhY3RvcnlQaWQsIGZhY3RvcnkgKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gZmFjdG9yeTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8vIGlmIGdldHRpbmcgaGVyZSwgdGhlcmUgaXMgbm8gY29uZmlndXJhdGlvbiB5ZXQsIG9wdGlvbmFsbHkgY3JlYXRlIG5ldworICAgICAgICByZXR1cm4gY3JlYXRlRmFjdG9yeSggZmFjdG9yeVBpZCApOworICAgIH0KKworCisgICAgRmFjdG9yeSBjcmVhdGVGYWN0b3J5KCBTdHJpbmcgZmFjdG9yeVBpZCApCisgICAgeworICAgICAgICBGYWN0b3J5IGZhY3RvcnkgPSBuZXcgRmFjdG9yeSggZ2V0UGVyc2lzdGVuY2VNYW5hZ2VycygpWzBdLCBmYWN0b3J5UGlkICk7CisgICAgICAgIGZhY3Rvcmllcy5wdXQoIGZhY3RvcnlQaWQsIGZhY3RvcnkgKTsKKyAgICAgICAgcmV0dXJuIGZhY3Rvcnk7CisgICAgfQorCisKKyAgICBwcml2YXRlIERpY3Rpb25hcnkgY2FsbFBsdWdpbnMoIFNlcnZpY2VSZWZlcmVuY2Ugc3IsIENvbmZpZ3VyYXRpb25JbXBsIGNmZyApCisgICAgeworICAgICAgICBEaWN0aW9uYXJ5IHByb3BzID0gY2ZnLmdldFByb3BlcnRpZXMoKTsKKworICAgICAgICBTZXJ2aWNlUmVmZXJlbmNlW10gcGx1Z2lucyA9IG51bGw7CisgICAgICAgIHRyeQorICAgICAgICB7CisgICAgICAgICAgICBTdHJpbmcgcGlkID0gKCBTdHJpbmcgKSBzci5nZXRQcm9wZXJ0eSggQ29uc3RhbnRzLlNFUlZJQ0VfUElEICk7CisgICAgICAgICAgICBTdHJpbmcgZmlsdGVyID0gIih8KCEoY20udGFyZ2V0PSopKShjbS50YXJnZXQ9IiArIHBpZCArICIpKSI7CisgICAgICAgICAgICBwbHVnaW5zID0gYnVuZGxlQ29udGV4dC5nZXRTZXJ2aWNlUmVmZXJlbmNlcyggQ29uZmlndXJhdGlvblBsdWdpbi5jbGFzcy5nZXROYW1lKCksIGZpbHRlciApOworCisgICAgICAgIH0KKyAgICAgICAgY2F0Y2ggKCBJbnZhbGlkU3ludGF4RXhjZXB0aW9uIGlzZSApCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIG5vIGZpbHRlciwgbm8gZXhjZXB0aW9uIC4uLgorICAgICAgICB9CisKKyAgICAgICAgLy8gYWJvcnQgZWFybHkgaWYgdGhlcmUgYXJlIG5vIHBsdWdpbnMKKyAgICAgICAgaWYgKCBwbHVnaW5zID09IG51bGwgfHwgcGx1Z2lucy5sZW5ndGggPT0gMCApCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybiBwcm9wczsKKyAgICAgICAgfQorCisgICAgICAgIC8vIHNvcnQgdGhlIHBsdWdpbnMgYnkgdGhlaXIgc2VydmljZS5jbVJhbmtpbmcKKyAgICAgICAgU29ydGVkU2V0IHBsdWdpblNldCA9IG5ldyBUcmVlU2V0KCBjbVJhbmtDb21wICk7CisgICAgICAgIGZvciAoIGludCBpID0gMDsgcGx1Z2lucyAhPSBudWxsICYmIGkgPCBwbHVnaW5zLmxlbmd0aDsgaSsrICkKKyAgICAgICAgeworICAgICAgICAgICAgcGx1Z2luU2V0LmFkZCggcGx1Z2luc1tpXSApOworICAgICAgICB9CisKKyAgICAgICAgLy8gY2FsbCB0aGUgcGx1Z2lucyBpbiBvcmRlcgorICAgICAgICBmb3IgKCBJdGVyYXRvciBwaSA9IHBsdWdpblNldC5pdGVyYXRvcigpOyBwaS5oYXNOZXh0KCk7ICkKKyAgICAgICAgeworICAgICAgICAgICAgU2VydmljZVJlZmVyZW5jZSBwbHVnaW5SZWYgPSAoIFNlcnZpY2VSZWZlcmVuY2UgKSBwaS5uZXh0KCk7CisgICAgICAgICAgICBDb25maWd1cmF0aW9uUGx1Z2luIHBsdWdpbiA9ICggQ29uZmlndXJhdGlvblBsdWdpbiApIGJ1bmRsZUNvbnRleHQuZ2V0U2VydmljZSggcGx1Z2luUmVmICk7CisgICAgICAgICAgICB0cnkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBwbHVnaW4ubW9kaWZ5Q29uZmlndXJhdGlvbiggc3IsIHByb3BzICk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXRjaCAoIFRocm93YWJsZSB0ICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBsb2coIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCAiVW5leHBlY3RlZCBwcm9ibGVtIGNhbGxpbmciICsgIiBjb25maWd1cmF0aW9uIHBsdWdpbiIsIHQgKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmFsbHkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAvLyBlbnN1cmUgdW5nZXR0aW5nIHRoZSBwbHVnaW4KKyAgICAgICAgICAgICAgICBidW5kbGVDb250ZXh0LnVuZ2V0U2VydmljZSggcGx1Z2luUmVmICk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjZmcuc2V0QXV0b1Byb3BlcnRpZXMoIHByb3BzLCBmYWxzZSApOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHByb3BzOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQ3JlYXRlcyBhIFBJRCBmb3IgdGhlIGdpdmVuIGZhY3RvcnlQaWQKKyAgICAgKiAKKyAgICAgKiBAcGFyYW0gZmFjdG9yeVBpZAorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgY3JlYXRlUGlkKCBTdHJpbmcgZmFjdG9yeVBpZCApCisgICAgeworICAgICAgICBTZWN1cmVSYW5kb20gbmcgPSBudW1iZXJHZW5lcmF0b3I7CisgICAgICAgIGlmICggbmcgPT0gbnVsbCApCisgICAgICAgIHsKKyAgICAgICAgICAgIG51bWJlckdlbmVyYXRvciA9IG5nID0gbmV3IFNlY3VyZVJhbmRvbSgpOworICAgICAgICB9CisKKyAgICAgICAgYnl0ZVtdIHJhbmRvbUJ5dGVzID0gbmV3IGJ5dGVbMTZdOworICAgICAgICBuZy5uZXh0Qnl0ZXMoIHJhbmRvbUJ5dGVzICk7CisgICAgICAgIHJhbmRvbUJ5dGVzWzZdICY9IDB4MGY7IC8qIGNsZWFyIHZlcnNpb24gKi8KKyAgICAgICAgcmFuZG9tQnl0ZXNbNl0gfD0gMHg0MDsgLyogc2V0IHRvIHZlcnNpb24gNCAqLworICAgICAgICByYW5kb21CeXRlc1s4XSAmPSAweDNmOyAvKiBjbGVhciB2YXJpYW50ICovCisgICAgICAgIHJhbmRvbUJ5dGVzWzhdIHw9IDB4ODA7IC8qIHNldCB0byBJRVRGIHZhcmlhbnQgKi8KKworICAgICAgICBTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlciggZmFjdG9yeVBpZC5sZW5ndGgoKSArIDEgKyAzNiApOworCisgICAgICAgIC8vIHByZWZpeCB0aGUgbmV3IHBpZCB3aXRoIHRoZSBmYWN0b3J5IHBpZAorICAgICAgICBidWYuYXBwZW5kKCBmYWN0b3J5UGlkICkuYXBwZW5kKCAiLiIgKTsKKworICAgICAgICAvLyBzZXJpYWxpemUgdGhlIFVVSUQgaW50byB0aGUgYnVmZmVyCisgICAgICAgIGZvciAoIGludCBpID0gMDsgaSA8IHJhbmRvbUJ5dGVzLmxlbmd0aDsgaSsrICkKKyAgICAgICAgeworCisgICAgICAgICAgICBpZiAoIGkgPT0gNCB8fCBpID09IDYgfHwgaSA9PSA4IHx8IGkgPT0gMTAgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoICctJyApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpbnQgdmFsID0gcmFuZG9tQnl0ZXNbaV0gJiAweGZmOworICAgICAgICAgICAgYnVmLmFwcGVuZCggSW50ZWdlci50b0hleFN0cmluZyggdmFsID4+IDQgKSApOworICAgICAgICAgICAgYnVmLmFwcGVuZCggSW50ZWdlci50b0hleFN0cmluZyggdmFsICYgMHhmICkgKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBidWYudG9TdHJpbmcoKTsKKyAgICB9CisKKworICAgIHZvaWQgbG9nKCBpbnQgbGV2ZWwsIFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgdCApCisgICAgeworICAgICAgICBMb2dTZXJ2aWNlIGxvZyA9ICggTG9nU2VydmljZSApIGxvZ1RyYWNrZXIuZ2V0U2VydmljZSgpOworICAgICAgICBpZiAoIGxvZyAhPSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgbG9nLmxvZyggY29uZmlndXJhdGlvbkFkbWluUmVmZXJlbmNlLCBsZXZlbCwgbWVzc2FnZSwgdCApOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgU3RyaW5nIGNvZGU7CisgICAgICAgIHN3aXRjaCAoIGxldmVsICkKKyAgICAgICAgeworICAgICAgICAgICAgY2FzZSBMb2dTZXJ2aWNlLkxPR19JTkZPOgorICAgICAgICAgICAgICAgIGNvZGUgPSAiKklORk8gKiI7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgTG9nU2VydmljZS5MT0dfV0FSTklORzoKKyAgICAgICAgICAgICAgICBjb2RlID0gIipXQVJOICoiOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlIExvZ1NlcnZpY2UuTE9HX0VSUk9SOgorICAgICAgICAgICAgICAgIGNvZGUgPSAiKkVSUk9SKiI7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgTG9nU2VydmljZS5MT0dfREVCVUc6CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIGNvZGUgPSAiKkRFQlVHKiI7CisgICAgICAgIH0KKworICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIGNvZGUgKyAiICIgKyBtZXNzYWdlICk7CisgICAgICAgIGlmICggdCAhPSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgdC5wcmludFN0YWNrVHJhY2UoIFN5c3RlbS5lcnIgKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8vIC0tLS0tLS0tLS0gaW5uZXIgY2xhc3NlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIHByaXZhdGUgY2xhc3MgTWFuYWdlZFNlcnZpY2VVcGRhdGUgaW1wbGVtZW50cyBSdW5uYWJsZQorICAgIHsKKyAgICAgICAgcHJpdmF0ZSBTdHJpbmcgcGlkOworCisgICAgICAgIHByaXZhdGUgU2VydmljZVJlZmVyZW5jZSBzcjsKKworICAgICAgICBwcml2YXRlIE1hbmFnZWRTZXJ2aWNlIHNlcnZpY2U7CisKKworICAgICAgICBNYW5hZ2VkU2VydmljZVVwZGF0ZSggU3RyaW5nIHBpZCwgU2VydmljZVJlZmVyZW5jZSBzciwgTWFuYWdlZFNlcnZpY2Ugc2VydmljZSApCisgICAgICAgIHsKKyAgICAgICAgICAgIHRoaXMucGlkID0gcGlkOworICAgICAgICAgICAgdGhpcy5zciA9IHNyOworICAgICAgICAgICAgdGhpcy5zZXJ2aWNlID0gc2VydmljZTsKKyAgICAgICAgfQorCisKKyAgICAgICAgcHVibGljIHZvaWQgcnVuKCkKKyAgICAgICAgeworICAgICAgICAgICAgQ29uZmlndXJhdGlvbkltcGwgY2ZnOworICAgICAgICAgICAgdHJ5CisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgY2ZnID0gZ2V0Q29uZmlndXJhdGlvbiggcGlkLCBzci5nZXRCdW5kbGUoKS5nZXRMb2NhdGlvbigpICk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXRjaCAoIElPRXhjZXB0aW9uIGlvZSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgbG9nKCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgIkVycm9yIGxvYWRpbmcgY29uZmlndXJhdGlvbiBmb3IgIiArIHBpZCwgaW9lICk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyAxMDQuMyBJZ25vcmUgZHVwbGljYXRlIFBJRHMgZnJvbSBvdGhlciBidW5kbGVzIGFuZCByZXBvcnQgdGhlbSB0bworICAgICAgICAgICAgLy8gdGhlIGxvZworICAgICAgICAgICAgLy8gMTA0LjQuMSBObyB1cGRhdGUgY2FsbCBiYWNrIGZvciBQSUQgYWxyZWFkeSBib3VuZCB0byBhbm90aGVyCisgICAgICAgICAgICAvLyBidW5kbGUgbG9jYXRpb24KKyAgICAgICAgICAgIFN0cmluZyBidW5kbGVMb2NhdGlvbiA9IHNyLmdldEJ1bmRsZSgpLmdldExvY2F0aW9uKCk7CisgICAgICAgICAgICBpZiAoIGNmZy5nZXRCdW5kbGVMb2NhdGlvbigpICE9IG51bGwgJiYgIWJ1bmRsZUxvY2F0aW9uLmVxdWFscyggY2ZnLmdldEJ1bmRsZUxvY2F0aW9uKCkgKSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgbG9nKCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgIkNhbm5vdCB1c2UgY29uZmlndXJhdGlvbiBmb3IgIiArIHBpZCArICIgcmVxdWVzdGVkIGJ5IGJ1bmRsZSAiCisgICAgICAgICAgICAgICAgICAgICsgc3IuZ2V0QnVuZGxlKCkuZ2V0TG9jYXRpb24oKSArICIgYnV0IGJlbG9uZ3MgdG8gIiArIGNmZy5nZXRCdW5kbGVMb2NhdGlvbigpLCBudWxsICk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyAxMDQuMyBSZXBvcnQgYW4gZXJyb3IgaW4gdGhlIGxvZyBpZiBtb3JlIHRoYW4gb25lIHNlcnZpY2Ugd2l0aAorICAgICAgICAgICAgLy8gdGhlIHNhbWUgUElEIGFza3MgZm9yIHRoZSBjb25maWd1cmF0aW9uCisgICAgICAgICAgICBpZiAoIGNmZy5nZXRTZXJ2aWNlUmVmZXJlbmNlKCkgIT0gbnVsbCAmJiAhc3IuZXF1YWxzKCBjZmcuZ2V0U2VydmljZVJlZmVyZW5jZSgpICkgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGxvZyggTG9nU2VydmljZS5MT0dfRVJST1IsICJDb25maWd1cmF0aW9uIGZvciAiICsgcGlkICsgIiBoYXMgYWxyZWFkeSBiZWVuIHVzZWQgZm9yIHNlcnZpY2UgIgorICAgICAgICAgICAgICAgICAgICArIGNmZy5nZXRTZXJ2aWNlUmVmZXJlbmNlKCkgKyAiIGFuZCB3aWxsIG5vdyBhbHNvIGJlIGdpdmVuIHRvICIgKyBzciwgbnVsbCApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIC8vIGFzc2lnbiB0aGUgY29uZmlndXJhdGlvbiB0byB0aGUgc2VydmljZQorICAgICAgICAgICAgICAgIGNmZy5zZXRTZXJ2aWNlUmVmZXJlbmNlKCBzciApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBwcmVwYXJlIHRoZSBjb25maWd1cmF0aW9uIGZvciB0aGUgc2VydmljZSAoY2FsbCBwbHVnaW5zKQorICAgICAgICAgICAgRGljdGlvbmFyeSBkaWN0aW9uYXJ5ID0gY2FsbFBsdWdpbnMoIHNyLCBjZmcgKTsKKworICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSBzZXJ2aWNlIHdpdGggdGhlIGNvbmZpZ3VyYXRpb24KKyAgICAgICAgICAgIHRyeQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHNlcnZpY2UudXBkYXRlZCggZGljdGlvbmFyeSApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2F0Y2ggKCBDb25maWd1cmF0aW9uRXhjZXB0aW9uIGNlICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBpZiAoIGNlLmdldFByb3BlcnR5KCkgIT0gbnVsbCApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBsb2coIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBzciArICI6IFVwZGF0aW5nIGNvbmZpZ3VyYXRpb24gcHJvcGVydHkgIiArIGNlLmdldFByb3BlcnR5KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBjYXVzZWQgYSBwcm9ibGVtOiAiICsgY2UuZ2V0UmVhc29uKCksIGNlICk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIGxvZyggTG9nU2VydmljZS5MT0dfRVJST1IsIHNyICsgIjogVXBkYXRpbmcgY29uZmlndXJhdGlvbiBjYXVzZWQgYSBwcm9ibGVtOiAiICsgY2UuZ2V0UmVhc29uKCksIGNlICk7CisKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXRjaCAoIFRocm93YWJsZSB0ICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBsb2coIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBzciArICI6IFVuZXhwZWN0ZWQgcHJvYmxlbSB1cGRhdGluZyBjb25maWd1cmF0aW9uIiwgdCApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyAxMDQuNS4zIENNX1VQREFURUQgaXMgc2VudCBhc3luY2hyb25vdXNseSB0byBhbGwKKyAgICAgICAgICAgIC8vIENvbmZpZ3VyYXRpb25MaXN0ZW5lcnMKKyAgICAgICAgICAgIGZpcmVDb25maWd1cmF0aW9uRXZlbnQoIENvbmZpZ3VyYXRpb25FdmVudC5DTV9VUERBVEVELCBjZmcgKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgTWFuYWdlZFNlcnZpY2VGYWN0b3J5VXBkYXRlIGltcGxlbWVudHMgUnVubmFibGUKKyAgICB7CisgICAgICAgIHByaXZhdGUgU3RyaW5nIGZhY3RvcnlQaWQ7CisKKyAgICAgICAgcHJpdmF0ZSBTZXJ2aWNlUmVmZXJlbmNlIHNyOworCisgICAgICAgIHByaXZhdGUgTWFuYWdlZFNlcnZpY2VGYWN0b3J5IHNlcnZpY2U7CisKKworICAgICAgICBNYW5hZ2VkU2VydmljZUZhY3RvcnlVcGRhdGUoIFN0cmluZyBmYWN0b3J5UGlkLCBTZXJ2aWNlUmVmZXJlbmNlIHNyLCBNYW5hZ2VkU2VydmljZUZhY3Rvcnkgc2VydmljZSApCisgICAgICAgIHsKKyAgICAgICAgICAgIHRoaXMuZmFjdG9yeVBpZCA9IGZhY3RvcnlQaWQ7CisgICAgICAgICAgICB0aGlzLnNyID0gc3I7CisgICAgICAgICAgICB0aGlzLnNlcnZpY2UgPSBzZXJ2aWNlOworICAgICAgICB9CisKKworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKQorICAgICAgICB7CisgICAgICAgICAgICBGYWN0b3J5IGZhY3Rvcnk7CisgICAgICAgICAgICB0cnkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBmYWN0b3J5ID0gZ2V0RmFjdG9yeSggZmFjdG9yeVBpZCApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2F0Y2ggKCBJT0V4Y2VwdGlvbiBpb2UgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGxvZyggTG9nU2VydmljZS5MT0dfRVJST1IsICJDYW5ub3QgZ2V0IGZhY3RvcnkgbWFwcGluZyBmb3IgZmFjdG9yeSBQSUQgIiArIGZhY3RvcnlQaWQsIGlvZSApOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU3RyaW5nIGJ1bmRsZUxvY2F0aW9uID0gc3IuZ2V0QnVuZGxlKCkuZ2V0TG9jYXRpb24oKTsKKyAgICAgICAgICAgIGlmICggZmFjdG9yeS5nZXRCdW5kbGVMb2NhdGlvbigpID09IG51bGwgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIC8vIGJpbmQgdG8gdGhlIGxvY2F0aW9uIG9mIHRoZSBzZXJ2aWNlIGlmIHVuYm91bmQKKyAgICAgICAgICAgICAgICBmYWN0b3J5LnNldEJ1bmRsZUxvY2F0aW9uKCBidW5kbGVMb2NhdGlvbiApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSBpZiAoICFidW5kbGVMb2NhdGlvbi5lcXVhbHMoIGZhY3RvcnkuZ2V0QnVuZGxlTG9jYXRpb24oKSApICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAvLyBmYWN0b3J5IFBJRCBpcyBib3VuZCB0byBhbm90aGVyIGJ1bmRsZQorICAgICAgICAgICAgICAgIGxvZyggTG9nU2VydmljZS5MT0dfRVJST1IsICJDYW5ub3QgdXNlIEZhY3RvcnkgY29uZmlndXJhdGlvbiBmb3IgIiArIGZhY3RvcnlQaWQKKyAgICAgICAgICAgICAgICAgICAgKyAiIHJlcXVlc3RlZCBieSBidW5kbGUgIiArIHNyLmdldEJ1bmRsZSgpLmdldExvY2F0aW9uKCkgKyAiIGJ1dCBiZWxvbmdzIHRvICIKKyAgICAgICAgICAgICAgICAgICAgKyBmYWN0b3J5LmdldEJ1bmRsZUxvY2F0aW9uKCksIG51bGwgKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFNldCBwaWRzID0gZmFjdG9yeS5nZXRQSURzKCk7CisKKyAgICAgICAgICAgIGZvciAoIEl0ZXJhdG9yIHBpID0gcGlkcy5pdGVyYXRvcigpOyBwaS5oYXNOZXh0KCk7ICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBTdHJpbmcgcGlkID0gKCBTdHJpbmcgKSBwaS5uZXh0KCk7CisgICAgICAgICAgICAgICAgQ29uZmlndXJhdGlvbkltcGwgY2ZnOworICAgICAgICAgICAgICAgIHRyeQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgY2ZnID0gZ2V0Q29uZmlndXJhdGlvbiggcGlkLCBidW5kbGVMb2NhdGlvbiApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXRjaCAoIElPRXhjZXB0aW9uIGlvZSApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBsb2coIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCAiRXJyb3IgbG9hZGluZyBjb25maWd1cmF0aW9uIGZvciAiICsgcGlkLCBpb2UgKTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gc2FuaXR5IGNoZWNrIG9uIHRoZSBjb25maWd1cmF0aW9uCisgICAgICAgICAgICAgICAgaWYgKCBjZmcgPT0gbnVsbCApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBsb2coIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCAiQ29uZmlndXJhdGlvbiAiICsgcGlkICsgIiByZWZlcnJlZCB0byBieSBmYWN0b3J5ICIgKyBmYWN0b3J5UGlkCisgICAgICAgICAgICAgICAgICAgICAgICArICIgZG9lcyBub3QgZXhpc3QiLCBudWxsICk7CisgICAgICAgICAgICAgICAgICAgIGZhY3RvcnkucmVtb3ZlUElEKCBwaWQgKTsKKyAgICAgICAgICAgICAgICAgICAgZmFjdG9yeS5zdG9yZVNpbGVudGx5KCk7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIGlmICggIWZhY3RvcnlQaWQuZXF1YWxzKCBjZmcuZ2V0RmFjdG9yeVBpZCgpICkgKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgbG9nKCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgIkNvbmZpZ3VyYXRpb24gIiArIHBpZCArICIgcmVmZXJyZWQgdG8gYnkgZmFjdG9yeSAiICsgZmFjdG9yeVBpZAorICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGRvZXMgbm90IGV4aXN0IHNlZW1zIHRvIGJlbG9uZyB0byBmYWN0b3J5ICIgKyBjZmcuZ2V0RmFjdG9yeVBpZCgpLCBudWxsICk7CisgICAgICAgICAgICAgICAgICAgIGZhY3RvcnkucmVtb3ZlUElEKCBwaWQgKTsKKyAgICAgICAgICAgICAgICAgICAgZmFjdG9yeS5zdG9yZVNpbGVudGx5KCk7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIGNoZWNrIGJ1bmRsZSBsb2NhdGlvbiBvZiBjb25maWd1cmF0aW9uCisgICAgICAgICAgICAgICAgaWYgKCBjZmcuZ2V0QnVuZGxlTG9jYXRpb24oKSA9PSBudWxsICkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIC8vIGJpbmQgdG8gdGhlIGxvY2F0aW9uIG9mIHRoZSBzZXJ2aWNlIGlmIHVuYm91bmQKKyAgICAgICAgICAgICAgICAgICAgY2ZnLnNldEJ1bmRsZUxvY2F0aW9uKCBidW5kbGVMb2NhdGlvbiApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIGlmICggIWJ1bmRsZUxvY2F0aW9uLmVxdWFscyggY2ZnLmdldEJ1bmRsZUxvY2F0aW9uKCkgKSApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAvLyBjb25maWd1cmF0aW9uIGlzIGJvdW5kIHRvIGFub3RoZXIgYnVuZGxlCisgICAgICAgICAgICAgICAgICAgIGxvZyggTG9nU2VydmljZS5MT0dfRVJST1IsICJDb25maWd1cmF0aW9uICIgKyBwaWQgKyAiIChmYWN0b3J5ICIgKyBmYWN0b3J5UGlkCisgICAgICAgICAgICAgICAgICAgICAgICArICIpIGJlbG9uZ3MgdG8gYnVuZGxlICIgKyBjZmcuZ2V0QnVuZGxlTG9jYXRpb24oKSArICIgYnV0IHdhcyByZXF1ZXN0ZWQgZm9yIGJ1bmRsZSAiCisgICAgICAgICAgICAgICAgICAgICAgICArIGJ1bmRsZUxvY2F0aW9uLCBudWxsICk7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIHByZXBhcmUgdGhlIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBzZXJ2aWNlIChjYWxsIHBsdWdpbnMpCisgICAgICAgICAgICAgICAgRGljdGlvbmFyeSBkaWN0aW9uYXJ5ID0gY2FsbFBsdWdpbnMoIHNyLCBjZmcgKTsKKworICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgc2VydmljZSB3aXRoIHRoZSBjb25maWd1cmF0aW9uCisgICAgICAgICAgICAgICAgdHJ5CisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBzZXJ2aWNlLnVwZGF0ZWQoIHBpZCwgZGljdGlvbmFyeSApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXRjaCAoIENvbmZpZ3VyYXRpb25FeGNlcHRpb24gY2UgKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCBjZS5nZXRQcm9wZXJ0eSgpICE9IG51bGwgKQorICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICBsb2coIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBzciArICI6IFVwZGF0aW5nIGNvbmZpZ3VyYXRpb24gcHJvcGVydHkgIiArIGNlLmdldFByb3BlcnR5KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgY2F1c2VkIGEgcHJvYmxlbTogIiArIGNlLmdldFJlYXNvbigpLCBjZSApOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgbG9nKCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgc3IgKyAiOiBVcGRhdGluZyBjb25maWd1cmF0aW9uIGNhdXNlZCBhIHByb2JsZW06ICIgKyBjZS5nZXRSZWFzb24oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZSApOworCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgY2F0Y2ggKCBUaHJvd2FibGUgdCApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBsb2coIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBzciArICI6IFVuZXhwZWN0ZWQgcHJvYmxlbSB1cGRhdGluZyBjb25maWd1cmF0aW9uIiwgdCApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgVXBkYXRlQ29uZmlndXJhdGlvbiBpbXBsZW1lbnRzIFJ1bm5hYmxlCisgICAgeworCisgICAgICAgIHByaXZhdGUgQ29uZmlndXJhdGlvbkltcGwgY29uZmlnOworCisKKyAgICAgICAgVXBkYXRlQ29uZmlndXJhdGlvbiggQ29uZmlndXJhdGlvbkltcGwgY29uZmlnICkKKyAgICAgICAgeworICAgICAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7CisgICAgICAgIH0KKworCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpCisgICAgICAgIHsKKyAgICAgICAgICAgIHRyeQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGlmICggY29uZmlnLmdldEZhY3RvcnlQaWQoKSA9PSBudWxsICkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIFNlcnZpY2VSZWZlcmVuY2VbXSBzciA9IGJ1bmRsZUNvbnRleHQuZ2V0U2VydmljZVJlZmVyZW5jZXMoIE1hbmFnZWRTZXJ2aWNlLmNsYXNzLmdldE5hbWUoKSwgIigiCisgICAgICAgICAgICAgICAgICAgICAgICArIENvbnN0YW50cy5TRVJWSUNFX1BJRCArICI9IiArIGNvbmZpZy5nZXRQaWQoKSArICIpIiApOworICAgICAgICAgICAgICAgICAgICBpZiAoIHNyICE9IG51bGwgJiYgc3IubGVuZ3RoID4gMCApCisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIE1hbmFnZWRTZXJ2aWNlIHNydiA9ICggTWFuYWdlZFNlcnZpY2UgKSBidW5kbGVDb250ZXh0LmdldFNlcnZpY2UoIHNyWzBdICk7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkKKyAgICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBiaW5kIHRoZSBjb25maWd1cmF0aW9uLCBmYWlsIGlmIGJvdW5kIHRvIGFub3RoZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBidW5kbGUgISEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBidW5kbGUgbG9jYXRpb24gb2YgY29uZmlndXJhdGlvbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBidW5kbGVMb2NhdGlvbiA9IHNyWzBdLmdldEJ1bmRsZSgpLmdldExvY2F0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBjb25maWcuZ2V0QnVuZGxlTG9jYXRpb24oKSA9PSBudWxsICkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJpbmQgdG8gdGhlIGxvY2F0aW9uIG9mIHRoZSBzZXJ2aWNlIGlmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVuYm91bmQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLnNldEJ1bmRsZUxvY2F0aW9uKCBidW5kbGVMb2NhdGlvbiApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICggIWJ1bmRsZUxvY2F0aW9uLmVxdWFscyggY29uZmlnLmdldEJ1bmRsZUxvY2F0aW9uKCkgKSApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25maWd1cmF0aW9uIGlzIGJvdW5kIHRvIGFub3RoZXIgYnVuZGxlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZyggTG9nU2VydmljZS5MT0dfRVJST1IsICJDb25maWd1cmF0aW9uICIgKyBjb25maWcuZ2V0UGlkKCkgKyAiIGJlbG9uZ3MgdG8gYnVuZGxlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgY29uZmlnLmdldEJ1bmRsZUxvY2F0aW9uKCkgKyAiIGJ1dCB3YXMgcmVxdWVzdGVkIGZvciBidW5kbGUgIiArIGJ1bmRsZUxvY2F0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3J2LnVwZGF0ZWQoIGNvbmZpZy5nZXRQcm9wZXJ0aWVzKCkgKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsbHkKKyAgICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBidW5kbGVDb250ZXh0LnVuZ2V0U2VydmljZSggc3JbMF0gKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBTZXJ2aWNlUmVmZXJlbmNlW10gc3IgPSBidW5kbGVDb250ZXh0LmdldFNlcnZpY2VSZWZlcmVuY2VzKCBNYW5hZ2VkU2VydmljZUZhY3RvcnkuY2xhc3MuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgIigiICsgQ29uc3RhbnRzLlNFUlZJQ0VfUElEICsgIj0iICsgY29uZmlnLmdldEZhY3RvcnlQaWQoKSArICIpIiApOworICAgICAgICAgICAgICAgICAgICBpZiAoIHNyICE9IG51bGwgJiYgc3IubGVuZ3RoID4gMCApCisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIE1hbmFnZWRTZXJ2aWNlRmFjdG9yeSBzcnYgPSAoIE1hbmFnZWRTZXJ2aWNlRmFjdG9yeSApIGJ1bmRsZUNvbnRleHQuZ2V0U2VydmljZSggc3JbMF0gKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeQorICAgICAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJpbmQgdGhlIGNvbmZpZ3VyYXRpb24sIGZhaWwgaWYgYm91bmQgdG8gYW5vdGhlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1bmRsZSAhIQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGJ1bmRsZSBsb2NhdGlvbiBvZiBjb25maWd1cmF0aW9uCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGJ1bmRsZUxvY2F0aW9uID0gc3JbMF0uZ2V0QnVuZGxlKCkuZ2V0TG9jYXRpb24oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGNvbmZpZy5nZXRCdW5kbGVMb2NhdGlvbigpID09IG51bGwgKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmluZCB0byB0aGUgbG9jYXRpb24gb2YgdGhlIHNlcnZpY2UgaWYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdW5ib3VuZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcuc2V0QnVuZGxlTG9jYXRpb24oIGJ1bmRsZUxvY2F0aW9uICk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCAhYnVuZGxlTG9jYXRpb24uZXF1YWxzKCBjb25maWcuZ2V0QnVuZGxlTG9jYXRpb24oKSApICkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbmZpZ3VyYXRpb24gaXMgYm91bmQgdG8gYW5vdGhlciBidW5kbGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgIkNvbmZpZ3VyYXRpb24gIiArIGNvbmZpZy5nZXRQaWQoKSArICIgKGZhY3RvcnkgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBjb25maWcuZ2V0RmFjdG9yeVBpZCgpICsgIikgYmVsb25ncyB0byBidW5kbGUgIiArIGNvbmZpZy5nZXRCdW5kbGVMb2NhdGlvbigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgYnV0IHdhcyByZXF1ZXN0ZWQgZm9yIGJ1bmRsZSAiICsgYnVuZGxlTG9jYXRpb24sIG51bGwgKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNydi51cGRhdGVkKCBjb25maWcuZ2V0UGlkKCksIGNvbmZpZy5nZXRQcm9wZXJ0aWVzKCkgKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsbHkKKyAgICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBidW5kbGVDb250ZXh0LnVuZ2V0U2VydmljZSggc3JbMF0gKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhdGNoICggQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBjZSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgaWYgKCBjZS5nZXRQcm9wZXJ0eSgpICE9IG51bGwgKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgbG9nKCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgIlVwZGF0aW5nIGNvbmZpZ3VyYXRpb24gcHJvcGVydHkgIiArIGNlLmdldFByb3BlcnR5KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBjYXVzZWQgYSBwcm9ibGVtOiAiICsgY2UuZ2V0UmVhc29uKCksIGNlICk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIGxvZyggTG9nU2VydmljZS5MT0dfRVJST1IsICJVcGRhdGluZyBjb25maWd1cmF0aW9uIGNhdXNlZCBhIHByb2JsZW06ICIgKyBjZS5nZXRSZWFzb24oKSwgY2UgKTsKKworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhdGNoICggVGhyb3dhYmxlIHQgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGxvZyggTG9nU2VydmljZS5MT0dfRVJST1IsICJVbmV4cGVjdGVkIHByb2JsZW0gdXBkYXRpbmcgY29uZmlndXJhdGlvbiIsIHQgKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZmlyZUNvbmZpZ3VyYXRpb25FdmVudCggQ29uZmlndXJhdGlvbkV2ZW50LkNNX1VQREFURUQsIGNvbmZpZyApOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBEZWxldGVDb25maWd1cmF0aW9uIGltcGxlbWVudHMgUnVubmFibGUKKyAgICB7CisgICAgICAgIHByaXZhdGUgQ29uZmlndXJhdGlvbkltcGwgY29uZmlnOworCisKKyAgICAgICAgRGVsZXRlQ29uZmlndXJhdGlvbiggQ29uZmlndXJhdGlvbkltcGwgY29uZmlnICkKKyAgICAgICAgeworICAgICAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7CisgICAgICAgIH0KKworCisgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpCisgICAgICAgIHsKKyAgICAgICAgICAgIHRyeQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGlmICggY29uZmlnLmdldEZhY3RvcnlQaWQoKSA9PSBudWxsICkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIFNlcnZpY2VSZWZlcmVuY2VbXSBzciA9IGJ1bmRsZUNvbnRleHQuZ2V0U2VydmljZVJlZmVyZW5jZXMoIE1hbmFnZWRTZXJ2aWNlLmNsYXNzLmdldE5hbWUoKSwgIigiCisgICAgICAgICAgICAgICAgICAgICAgICArIENvbnN0YW50cy5TRVJWSUNFX1BJRCArICI9IiArIGNvbmZpZy5nZXRQaWQoKSArICIpIiApOworICAgICAgICAgICAgICAgICAgICBpZiAoIHNyICE9IG51bGwgJiYgc3IubGVuZ3RoID4gMCApCisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIE1hbmFnZWRTZXJ2aWNlIHNydiA9ICggTWFuYWdlZFNlcnZpY2UgKSBidW5kbGVDb250ZXh0LmdldFNlcnZpY2UoIHNyWzBdICk7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkKKyAgICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcnYudXBkYXRlZCggbnVsbCApOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxseQorICAgICAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1bmRsZUNvbnRleHQudW5nZXRTZXJ2aWNlKCBzclswXSApOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgcGlkIGZyb20gdGhlIGZhY3RvcnkKKyAgICAgICAgICAgICAgICAgICAgRmFjdG9yeSBmYWN0b3J5ID0gZ2V0RmFjdG9yeSggY29uZmlnLmdldEZhY3RvcnlQaWQoKSApOworICAgICAgICAgICAgICAgICAgICBmYWN0b3J5LnJlbW92ZVBJRCggY29uZmlnLmdldFBpZCgpICk7CisgICAgICAgICAgICAgICAgICAgIGZhY3Rvcnkuc3RvcmUoKTsKKworICAgICAgICAgICAgICAgICAgICBTZXJ2aWNlUmVmZXJlbmNlW10gc3IgPSBidW5kbGVDb250ZXh0LmdldFNlcnZpY2VSZWZlcmVuY2VzKCBNYW5hZ2VkU2VydmljZUZhY3RvcnkuY2xhc3MuZ2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgIigiICsgQ29uc3RhbnRzLlNFUlZJQ0VfUElEICsgIj0iICsgY29uZmlnLmdldEZhY3RvcnlQaWQoKSArICIpIiApOworICAgICAgICAgICAgICAgICAgICBpZiAoIHNyICE9IG51bGwgJiYgc3IubGVuZ3RoID4gMCApCisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIE1hbmFnZWRTZXJ2aWNlRmFjdG9yeSBzcnYgPSAoIE1hbmFnZWRTZXJ2aWNlRmFjdG9yeSApIGJ1bmRsZUNvbnRleHQuZ2V0U2VydmljZSggc3JbMF0gKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeQorICAgICAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNydi5kZWxldGVkKCBjb25maWcuZ2V0UGlkKCkgKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsbHkKKyAgICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBidW5kbGVDb250ZXh0LnVuZ2V0U2VydmljZSggc3JbMF0gKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhdGNoICggQ29uZmlndXJhdGlvbkV4Y2VwdGlvbiBjZSApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgaWYgKCBjZS5nZXRQcm9wZXJ0eSgpICE9IG51bGwgKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgbG9nKCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgIlVwZGF0aW5nIGNvbmZpZ3VyYXRpb24gcHJvcGVydHkgIiArIGNlLmdldFByb3BlcnR5KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBjYXVzZWQgYSBwcm9ibGVtOiAiICsgY2UuZ2V0UmVhc29uKCksIGNlICk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIGxvZyggTG9nU2VydmljZS5MT0dfRVJST1IsICJVcGRhdGluZyBjb25maWd1cmF0aW9uIGNhdXNlZCBhIHByb2JsZW06ICIgKyBjZS5nZXRSZWFzb24oKSwgY2UgKTsKKworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhdGNoICggVGhyb3dhYmxlIHQgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGxvZyggTG9nU2VydmljZS5MT0dfRVJST1IsICJVbmV4cGVjdGVkIHByb2JsZW0gdXBkYXRpbmcgY29uZmlndXJhdGlvbiIsIHQgKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZmlyZUNvbmZpZ3VyYXRpb25FdmVudCggQ29uZmlndXJhdGlvbkV2ZW50LkNNX0RFTEVURUQsIGNvbmZpZyApOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBGaXJlQ29uZmlndXJhdGlvbkV2ZW50IGltcGxlbWVudHMgUnVubmFibGUKKyAgICB7CisgICAgICAgIHByaXZhdGUgaW50IHR5cGU7CisKKyAgICAgICAgcHJpdmF0ZSBDb25maWd1cmF0aW9uSW1wbCBjb25maWc7CisKKworICAgICAgICBGaXJlQ29uZmlndXJhdGlvbkV2ZW50KCBpbnQgdHlwZSwgQ29uZmlndXJhdGlvbkltcGwgY29uZmlnICkKKyAgICAgICAgeworICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKKyAgICAgICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnOworICAgICAgICB9CisKKworICAgICAgICBwdWJsaWMgdm9pZCBydW4oKQorICAgICAgICB7CisgICAgICAgICAgICAvLyBnZXQgdGhlIGxpc3RlbmVycworICAgICAgICAgICAgU2VydmljZVJlZmVyZW5jZVtdIHNycyA9IGNvbmZpZ3VyYXRpb25MaXN0ZW5lclRyYWNrZXIuZ2V0U2VydmljZVJlZmVyZW5jZXMoKTsKKyAgICAgICAgICAgIGlmICggc3JzID09IG51bGwgfHwgc3JzLmxlbmd0aCA9PSAwICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIENvbmZpZ3VyYXRpb25FdmVudCBldmVudCA9IG5ldyBDb25maWd1cmF0aW9uRXZlbnQoIGNvbmZpZ3VyYXRpb25BZG1pblJlZmVyZW5jZSwgdHlwZSwgY29uZmlnCisgICAgICAgICAgICAgICAgLmdldEZhY3RvcnlQaWQoKSwgY29uZmlnLmdldFBpZCgpICk7CisKKyAgICAgICAgICAgIGZvciAoIGludCBpID0gMDsgaSA8IHNycy5sZW5ndGg7IGkrKyApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgQ29uZmlndXJhdGlvbkxpc3RlbmVyIGNsID0gKCBDb25maWd1cmF0aW9uTGlzdGVuZXIgKSBjb25maWd1cmF0aW9uTGlzdGVuZXJUcmFja2VyLmdldFNlcnZpY2UoIHNyc1tpXSApOworICAgICAgICAgICAgICAgIHRyeQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgY2wuY29uZmlndXJhdGlvbkV2ZW50KCBldmVudCApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjYXRjaCAoIFRocm93YWJsZSB0ICkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIGxvZyggTG9nU2VydmljZS5MT0dfRVJST1IsICJVbmV4cGVjdGVkIHByb2JsZW0gZGVsaXZlcnkgY29uZmlndXJhdGlvbiBldmVudCB0byAiICsgc3JzW2ldLCB0ICk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdE1hbmFnZWRTZXJ2aWNlVHJhY2tlciBleHRlbmRzIFNlcnZpY2VUcmFja2VyCisgICAgeworICAgICAgICBBYnN0cmFjdE1hbmFnZWRTZXJ2aWNlVHJhY2tlciggU3RyaW5nIGNsYXNzTmFtZSApCisgICAgICAgIHsKKyAgICAgICAgICAgIHN1cGVyKCBidW5kbGVDb250ZXh0LCBjbGFzc05hbWUsIG51bGwgKTsKKyAgICAgICAgICAgIG9wZW4oKTsKKyAgICAgICAgfQorCisKKyAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlZFNlcnZpY2UoIFNlcnZpY2VSZWZlcmVuY2UgcmVmZXJlbmNlLCBPYmplY3Qgc2VydmljZSApCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgd2UgY2FuIHRha2UgYmFjayB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QKKyAgICAgICAgICAgIFN0cmluZyBwaWQgPSAoIFN0cmluZyApIHJlZmVyZW5jZS5nZXRQcm9wZXJ0eSggQ29uc3RhbnRzLlNFUlZJQ0VfUElEICk7CisgICAgICAgICAgICBpZiAoIHBpZCAhPSBudWxsICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBDb25maWd1cmF0aW9uSW1wbCBjZmcgPSBnZXRDYWNoZWRDb25maWd1cmF0aW9uKCBwaWQgKTsKKyAgICAgICAgICAgICAgICBpZiAoIGNmZyAhPSBudWxsICYmIHJlZmVyZW5jZS5lcXVhbHMoIGNmZy5nZXRTZXJ2aWNlUmVmZXJlbmNlKCkgKSApCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICBjZmcuc2V0U2VydmljZVJlZmVyZW5jZSggbnVsbCApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3VwZXIucmVtb3ZlZFNlcnZpY2UoIHJlZmVyZW5jZSwgc2VydmljZSApOworICAgICAgICB9CisgICAgfQorCisgICAgcHJpdmF0ZSBjbGFzcyBNYW5hZ2VkU2VydmljZVRyYWNrZXIgZXh0ZW5kcyBBYnN0cmFjdE1hbmFnZWRTZXJ2aWNlVHJhY2tlcgorICAgIHsKKyAgICAgICAgTWFuYWdlZFNlcnZpY2VUcmFja2VyKCkKKyAgICAgICAgeworICAgICAgICAgICAgc3VwZXIoIE1hbmFnZWRTZXJ2aWNlLmNsYXNzLmdldE5hbWUoKSApOworICAgICAgICB9CisKKworICAgICAgICBwdWJsaWMgT2JqZWN0IGFkZGluZ1NlcnZpY2UoIFNlcnZpY2VSZWZlcmVuY2UgcmVmZXJlbmNlICkKKyAgICAgICAgeworICAgICAgICAgICAgTWFuYWdlZFNlcnZpY2Ugc2VydmljZSA9ICggTWFuYWdlZFNlcnZpY2UgKSBzdXBlci5hZGRpbmdTZXJ2aWNlKCByZWZlcmVuY2UgKTsKKworICAgICAgICAgICAgLy8gY29uZmlndXJlIHRoZSBtYW5hZ2VkIHNlcnZpY2UKKyAgICAgICAgICAgIGlmICggc2VydmljZSAhPSBudWxsICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBjb25maWd1cmUoIHJlZmVyZW5jZSwgc2VydmljZSApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gc2VydmljZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgY2xhc3MgTWFuYWdlZFNlcnZpY2VGYWN0b3J5VHJhY2tlciBleHRlbmRzIEFic3RyYWN0TWFuYWdlZFNlcnZpY2VUcmFja2VyCisgICAgeworICAgICAgICBNYW5hZ2VkU2VydmljZUZhY3RvcnlUcmFja2VyKCkKKyAgICAgICAgeworICAgICAgICAgICAgc3VwZXIoIE1hbmFnZWRTZXJ2aWNlRmFjdG9yeS5jbGFzcy5nZXROYW1lKCkgKTsKKyAgICAgICAgfQorCisKKyAgICAgICAgcHVibGljIE9iamVjdCBhZGRpbmdTZXJ2aWNlKCBTZXJ2aWNlUmVmZXJlbmNlIHJlZmVyZW5jZSApCisgICAgICAgIHsKKyAgICAgICAgICAgIE1hbmFnZWRTZXJ2aWNlRmFjdG9yeSBzZXJ2aWNlID0gKCBNYW5hZ2VkU2VydmljZUZhY3RvcnkgKSBzdXBlci5hZGRpbmdTZXJ2aWNlKCByZWZlcmVuY2UgKTsKKworICAgICAgICAgICAgLy8gY29uZmlndXJlIHRoZSBtYW5hZ2VkIHNlcnZpY2UKKyAgICAgICAgICAgIGlmICggc2VydmljZSAhPSBudWxsICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBjb25maWd1cmUoIHJlZmVyZW5jZSwgc2VydmljZSApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gc2VydmljZTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL0ZhY3RvcnkuamF2YSBiL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL0ZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOGU5OGVmCi0tLSAvZGV2L251bGwKKysrIGIvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ltcGwvRmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsMTg1IEBACisvKiAKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5mZWxpeC5jbS5pbXBsOworCisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5EaWN0aW9uYXJ5OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXguY20uUGVyc2lzdGVuY2VNYW5hZ2VyOworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbkFkbWluOworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UubG9nLkxvZ1NlcnZpY2U7CisKKworLyoqCisgKiBUaGUgPGNvZGU+RmFjdG9yeTwvY29kZT4gY2xhc3MgaXMgdXNlZCB0byBtYW5hZ2UgbWFwcGluZ3MgYmV0d2VlbiBmYWN0b3J5IFBJRHMKKyAqIHRoZSBjb25maWd1cmF0aW9uIFBJRCBiZWxvbmdpbmcgdG8gaXQuCisgKgorICogQGF1dGhvciBmbWVzY2hiZQorICovCitjbGFzcyBGYWN0b3J5Cit7CisKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBGQUNUT1JZX1BJRF9MSVNUID0gImZhY3RvcnkucGlkTGlzdCI7CisKKyAgICAvLyB0aGUgcGVyc2lzdGVuY2UgbWFuYWdlciBzdG9yaW5nIHRoaXMgZmFjdG9yeSBtYXBwaW5nCisgICAgcHJpdmF0ZSBQZXJzaXN0ZW5jZU1hbmFnZXIgcGVyc2lzdGVuY2VNYW5hZ2VyOworICAgIAorICAgIC8vIHRoZSBmYWN0b3J5IFBJRCBvZiB0aGlzIGZhY3RvcnkKKyAgICBwcml2YXRlIFN0cmluZyBmYWN0b3J5UGlkOworICAgIAorICAgIC8vIHRoZSBidW5kbGUgbG9jYXRpb24gdG8gd2hpY2ggZmFjdG9yeSBQSUQgbWFwcGluZyBpcyBib3VuZCAKKyAgICBwcml2YXRlIFN0cmluZyBidW5kbGVMb2NhdGlvbjsKKyAgICAKKyAgICAvLyB0aGUgc2V0IG9mIGNvbmZpZ3VyYXRpb24gUElEcyBiZWxvbmdpbmcgdG8gdGhpcyBmYWN0b3J5CisgICAgcHJpdmF0ZSBTZXQgcGlkczsKKworCisgICAgc3RhdGljIGJvb2xlYW4gZXhpc3RzKCBQZXJzaXN0ZW5jZU1hbmFnZXIgcGVyc2lzdGVuY2VNYW5hZ2VyLCBTdHJpbmcgZmFjdG9yeVBpZCApCisgICAgeworICAgICAgICByZXR1cm4gcGVyc2lzdGVuY2VNYW5hZ2VyLmV4aXN0cyggZmFjdG9yeVBpZFRvSWRlbnRpZmllciggZmFjdG9yeVBpZCApICk7CisgICAgfQorCisKKyAgICBzdGF0aWMgRmFjdG9yeSBsb2FkKCBQZXJzaXN0ZW5jZU1hbmFnZXIgcGVyc2lzdGVuY2VNYW5hZ2VyLCBTdHJpbmcgZmFjdG9yeVBpZCApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgRGljdGlvbmFyeSBkaWN0ID0gcGVyc2lzdGVuY2VNYW5hZ2VyLmxvYWQoIGZhY3RvcnlQaWRUb0lkZW50aWZpZXIoIGZhY3RvcnlQaWQgKSApOworICAgICAgICByZXR1cm4gbmV3IEZhY3RvcnkoIHBlcnNpc3RlbmNlTWFuYWdlciwgZmFjdG9yeVBpZCwgZGljdCApOworICAgIH0KKworCisgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGZhY3RvcnlQaWRUb0lkZW50aWZpZXIoIFN0cmluZyBmYWN0b3J5UGlkICkKKyAgICB7CisgICAgICAgIHJldHVybiBmYWN0b3J5UGlkICsgIi5mYWN0b3J5IjsKKyAgICB9CisKKworICAgIEZhY3RvcnkoIFBlcnNpc3RlbmNlTWFuYWdlciBwZXJzaXN0ZW5jZU1hbmFnZXIsIFN0cmluZyBmYWN0b3J5UGlkICkKKyAgICB7CisgICAgICAgIHRoaXMucGVyc2lzdGVuY2VNYW5hZ2VyID0gcGVyc2lzdGVuY2VNYW5hZ2VyOworICAgICAgICB0aGlzLmZhY3RvcnlQaWQgPSBmYWN0b3J5UGlkOworICAgICAgICB0aGlzLnBpZHMgPSBuZXcgSGFzaFNldCgpOworICAgIH0KKworCisgICAgRmFjdG9yeSggUGVyc2lzdGVuY2VNYW5hZ2VyIHBlcnNpc3RlbmNlTWFuYWdlciwgU3RyaW5nIGZhY3RvcnlQaWQsIERpY3Rpb25hcnkgcHJvcHMgKQorICAgIHsKKyAgICAgICAgdGhpcyggcGVyc2lzdGVuY2VNYW5hZ2VyLCBmYWN0b3J5UGlkICk7CisKKyAgICAgICAgLy8gc2V0IGJ1bmRsZSBsb2NhdGlvbgorICAgICAgICBzZXRCdW5kbGVMb2NhdGlvbiggKCBTdHJpbmcgKSBwcm9wcy5nZXQoIENvbmZpZ3VyYXRpb25BZG1pbi5TRVJWSUNFX0JVTkRMRUxPQ0FUSU9OICkgKTsKKworICAgICAgICAvLyBzZXQgcGlkcworICAgICAgICBTdHJpbmdbXSBwaWRMaXN0ID0gKCBTdHJpbmdbXSApIHByb3BzLmdldCggRkFDVE9SWV9QSURfTElTVCApOworICAgICAgICBpZiAoIHBpZExpc3QgIT0gbnVsbCApCisgICAgICAgIHsKKyAgICAgICAgICAgIGZvciAoIGludCBpID0gMDsgaSA8IHBpZExpc3QubGVuZ3RoOyBpKysgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGFkZFBJRCggcGlkTGlzdFtpXSApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisKKyAgICBQZXJzaXN0ZW5jZU1hbmFnZXIgZ2V0UGVyc2lzdGVuY2VNYW5hZ2VyKCkKKyAgICB7CisgICAgICAgIHJldHVybiBwZXJzaXN0ZW5jZU1hbmFnZXI7CisgICAgfQorCisKKyAgICBTdHJpbmcgZ2V0RmFjdG9yeVBpZCgpCisgICAgeworICAgICAgICByZXR1cm4gZmFjdG9yeVBpZDsKKyAgICB9CisKKworICAgIFN0cmluZyBnZXRCdW5kbGVMb2NhdGlvbigpCisgICAgeworICAgICAgICByZXR1cm4gYnVuZGxlTG9jYXRpb247CisgICAgfQorCisKKyAgICB2b2lkIHNldEJ1bmRsZUxvY2F0aW9uKCBTdHJpbmcgYnVuZGxlTG9jYXRpb24gKQorICAgIHsKKyAgICAgICAgdGhpcy5idW5kbGVMb2NhdGlvbiA9IGJ1bmRsZUxvY2F0aW9uOworICAgICAgICAKKyAgICAgICAgLy8gMTA0LjE1LjIuOCBUaGUgYnVuZGxlIGxvY2F0aW9uIHdpbGwgYmUgc2V0IHBlcnNpc3RlbnRseQorICAgICAgICBzdG9yZVNpbGVudGx5KCk7CisgICAgfQorCisKKyAgICBTZXQgZ2V0UElEcygpCisgICAgeworICAgICAgICByZXR1cm4gbmV3IEhhc2hTZXQoIHBpZHMgKTsKKyAgICB9CisKKworICAgIGJvb2xlYW4gYWRkUElEKCBTdHJpbmcgcGlkICkKKyAgICB7CisgICAgICAgIHJldHVybiBwaWRzLmFkZCggcGlkICk7CisgICAgfQorCisKKyAgICBib29sZWFuIHJlbW92ZVBJRCggU3RyaW5nIHBpZCApCisgICAgeworICAgICAgICByZXR1cm4gcGlkcy5yZW1vdmUoIHBpZCApOworICAgIH0KKworCisgICAgdm9pZCBzdG9yZSgpIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgSGFzaHRhYmxlIHByb3BzID0gbmV3IEhhc2h0YWJsZSgpOworCisgICAgICAgIGlmICggYnVuZGxlTG9jYXRpb24gIT0gbnVsbCApCisgICAgICAgIHsKKyAgICAgICAgICAgIHByb3BzLnB1dCggQ29uZmlndXJhdGlvbkFkbWluLlNFUlZJQ0VfQlVORExFTE9DQVRJT04sIGdldEJ1bmRsZUxvY2F0aW9uKCkgKTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICggIXBpZHMuaXNFbXB0eSgpICkKKyAgICAgICAgeworICAgICAgICAgICAgcHJvcHMucHV0KCBGQUNUT1JZX1BJRF9MSVNULCBwaWRzLnRvQXJyYXkoIG5ldyBTdHJpbmdbcGlkcy5zaXplKCldICkgKTsKKyAgICAgICAgfQorCisgICAgICAgIFN0cmluZyBpZCA9IGZhY3RvcnlQaWRUb0lkZW50aWZpZXIoIGdldEZhY3RvcnlQaWQoKSApOworICAgICAgICBpZiAoIHByb3BzLmlzRW1wdHkoKSApCisgICAgICAgIHsKKyAgICAgICAgICAgIHBlcnNpc3RlbmNlTWFuYWdlci5kZWxldGUoIGlkICk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgICBwZXJzaXN0ZW5jZU1hbmFnZXIuc3RvcmUoIGlkLCBwcm9wcyApOworICAgICAgICB9CisgICAgfQorICAgIAorICAgIHZvaWQgc3RvcmVTaWxlbnRseSgpCisgICAgeworICAgICAgICB0cnkKKyAgICAgICAgeworICAgICAgICAgICAgc3RvcmUoKTsKKyAgICAgICAgfQorICAgICAgICBjYXRjaCAoIElPRXhjZXB0aW9uIGlvZSApCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIHNob3VsZCBhY3R1YWxseSBsb2cgdGhpcyBwcm9ibGVtCisgICAgICAgICAgICAvLyBjb25maWd1cmF0aW9uTWFuYWdlci5sb2coIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCAiUGVyc2lzdGluZyBuZXcgYnVuZGxlIGxvY2F0aW9uIGZhaWxlZCIsIGlvZSApOworICAgICAgICB9CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ltcGwvUGVyc2lzdGVuY2VNYW5hZ2VyUHJveHkuamF2YSBiL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL1BlcnNpc3RlbmNlTWFuYWdlclByb3h5LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjRlZTMxNQotLS0gL2Rldi9udWxsCisrKyBiL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL1BlcnNpc3RlbmNlTWFuYWdlclByb3h5LmphdmEKQEAgLTAsMCArMSwxMjAgQEAKKy8qIAorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmZlbGl4LmNtLmltcGw7CisKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkRpY3Rpb25hcnk7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworCitpbXBvcnQgb3JnLmFwYWNoZS5mZWxpeC5jbS5QZXJzaXN0ZW5jZU1hbmFnZXI7CisKKworLyoqCisgKiBUaGUgPGNvZGU+UGVyc2lzdGVuY2VNYW5hZ2VyUHJveHk8L2NvZGU+IFRPRE8KKyAqCisgKiBAYXV0aG9yIGZtZXNjaGJlCisgKi8KK2NsYXNzIFBlcnNpc3RlbmNlTWFuYWdlclByb3h5IGltcGxlbWVudHMgUGVyc2lzdGVuY2VNYW5hZ2VyCit7CisKKyAgICBwcml2YXRlIFBlcnNpc3RlbmNlTWFuYWdlciBkZWxlZ2F0ZWU7CisKKworICAgIFBlcnNpc3RlbmNlTWFuYWdlclByb3h5KCBQZXJzaXN0ZW5jZU1hbmFnZXIgZGVsZWdhdGVlICkKKyAgICB7CisgICAgICAgIHNldFBlcnNpc3RlbmNlTWFuYWdlciggZGVsZWdhdGVlICk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gcGlkCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5mZWxpeC5jbS5QZXJzaXN0ZW5jZU1hbmFnZXIjZGVsZXRlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgZGVsZXRlKCBTdHJpbmcgcGlkICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBjaGVja0RlbGVnYXRlZSgpOworICAgICAgICBkZWxlZ2F0ZWUuZGVsZXRlKCBwaWQgKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEBwYXJhbSBwaWQKKyAgICAgKiBAcmV0dXJuCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmZlbGl4LmNtLlBlcnNpc3RlbmNlTWFuYWdlciNleGlzdHMoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoIFN0cmluZyBwaWQgKQorICAgIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlZSAhPSBudWxsICYmIGRlbGVnYXRlZS5leGlzdHMoIHBpZCApOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQHJldHVybgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuZmVsaXguY20uUGVyc2lzdGVuY2VNYW5hZ2VyI2dldERpY3Rpb25hcmllcygpCisgICAgICovCisgICAgcHVibGljIEVudW1lcmF0aW9uIGdldERpY3Rpb25hcmllcygpIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgY2hlY2tEZWxlZ2F0ZWUoKTsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlZS5nZXREaWN0aW9uYXJpZXMoKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEBwYXJhbSBwaWQKKyAgICAgKiBAcmV0dXJuCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5mZWxpeC5jbS5QZXJzaXN0ZW5jZU1hbmFnZXIjbG9hZChqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBEaWN0aW9uYXJ5IGxvYWQoIFN0cmluZyBwaWQgKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIGNoZWNrRGVsZWdhdGVlKCk7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZWUubG9hZCggcGlkICk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBAcGFyYW0gcGlkCisgICAgICogQHBhcmFtIHByb3BlcnRpZXMKKyAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAgICogQHNlZSBvcmcuYXBhY2hlLmZlbGl4LmNtLlBlcnNpc3RlbmNlTWFuYWdlciNzdG9yZShqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLnV0aWwuRGljdGlvbmFyeSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzdG9yZSggU3RyaW5nIHBpZCwgRGljdGlvbmFyeSBwcm9wZXJ0aWVzICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBjaGVja0RlbGVnYXRlZSgpOworICAgICAgICBkZWxlZ2F0ZWUuc3RvcmUoIHBpZCwgcHJvcGVydGllcyApOworICAgIH0KKworCisgICAgdm9pZCBzZXRQZXJzaXN0ZW5jZU1hbmFnZXIoIFBlcnNpc3RlbmNlTWFuYWdlciBkZWxlZ2F0ZWUgKQorICAgIHsKKyAgICAgICAgdGhpcy5kZWxlZ2F0ZWUgPSBkZWxlZ2F0ZWU7CisgICAgfQorCisKKyAgICB2b2lkIGNoZWNrRGVsZWdhdGVlKCkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBpZiAoIGRlbGVnYXRlZSA9PSBudWxsICkKKyAgICAgICAgeworICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCAiUGVyc2lzdGVuY2VNYW5hZ2VyIG5vdCB2YWxpZCIgKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL1JhbmtpbmdDb21wYXJhdG9yLmphdmEgYi9jb25maWdhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvZmVsaXgvY20vaW1wbC9SYW5raW5nQ29tcGFyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY1NzE1NGEKLS0tIC9kZXYvbnVsbAorKysgYi9jb25maWdhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvZmVsaXgvY20vaW1wbC9SYW5raW5nQ29tcGFyYXRvci5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKy8qIAorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmZlbGl4LmNtLmltcGw7CisKKworaW1wb3J0IGphdmEudXRpbC5Db21wYXJhdG9yOworCitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkNvbnN0YW50czsKK2ltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuU2VydmljZVJlZmVyZW5jZTsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNtLkNvbmZpZ3VyYXRpb25QbHVnaW47CisKKworLyoqCisgKiBUaGUgPGNvZGU+UmFua2luZ0NvbXBhcmF0b3I8L2NvZGU+IFRPRE8KKyAqCisgKiBAYXV0aG9yIGZtZXNjaGJlCisgKi8KK3B1YmxpYyBjbGFzcyBSYW5raW5nQ29tcGFyYXRvciBpbXBsZW1lbnRzIENvbXBhcmF0b3IKK3sKKworICAgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBuYXR1cmFsT3JkZXI7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgcmFua1Byb3BlcnR5OworCisKKyAgICBwdWJsaWMgUmFua2luZ0NvbXBhcmF0b3IoYm9vbGVhbiBuYXR1cmFsT3JkZXIpCisgICAgeworICAgICAgICB0aGlzKCBuYXR1cmFsT3JkZXIsIENvbnN0YW50cy5TRVJWSUNFX1JBTktJTkcgKTsKKyAgICB9CisKKworICAgIHB1YmxpYyBSYW5raW5nQ29tcGFyYXRvciggYm9vbGVhbiBuYXR1cmFsT3JkZXIsIFN0cmluZyByYW5rUHJvcGVydHkgKQorICAgIHsKKyAgICAgICAgdGhpcy5uYXR1cmFsT3JkZXIgPSBuYXR1cmFsT3JkZXI7CisgICAgICAgIHRoaXMucmFua1Byb3BlcnR5ID0gcmFua1Byb3BlcnR5OworICAgIH0KKworCisgICAgcHVibGljIGludCBjb21wYXJlKCBPYmplY3Qgb2JqMSwgT2JqZWN0IG9iajIgKQorICAgIHsKKyAgICAgICAgaWYgKCBvYmoxLmVxdWFscyggb2JqMiApICkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpbnQgcmFuazEgPSBnZXRJbnQoICggU2VydmljZVJlZmVyZW5jZSApIG9iajEsIHJhbmtQcm9wZXJ0eSApOworICAgICAgICBpbnQgcmFuazIgPSBnZXRJbnQoICggU2VydmljZVJlZmVyZW5jZSApIG9iajIsIHJhbmtQcm9wZXJ0eSApOworCisgICAgICAgIC8vIHVzZSBzZXJ2aWNlIGlkLCBpZiByYW5raW5ncyBhcmUgZXF1YWwKKyAgICAgICAgaWYgKCByYW5rMSA9PSByYW5rMiApCisgICAgICAgIHsKKyAgICAgICAgICAgIHJhbmsxID0gZ2V0SW50KCAoIFNlcnZpY2VSZWZlcmVuY2UgKSBvYmoxLCBDb25zdGFudHMuU0VSVklDRV9JRCApOworICAgICAgICAgICAgcmFuazIgPSBnZXRJbnQoICggU2VydmljZVJlZmVyZW5jZSApIG9iajIsIENvbnN0YW50cy5TRVJWSUNFX0lEICk7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIHJhbmsxID09IHJhbmsyICkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoIG5hdHVyYWxPcmRlciAmJiByYW5rMSA+IHJhbmsyKQorICAgICAgICB7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgcHJpdmF0ZSBpbnQgZ2V0SW50KCBTZXJ2aWNlUmVmZXJlbmNlIHNyLCBTdHJpbmcgcHJvcGVydHkgKQorICAgIHsKKyAgICAgICAgT2JqZWN0IHJhbmtPYmogPSBzci5nZXRQcm9wZXJ0eSggcHJvcGVydHkgKTsKKyAgICAgICAgaWYgKCByYW5rT2JqIGluc3RhbmNlb2YgSW50ZWdlciApCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldHVybiAoICggSW50ZWdlciApIHJhbmtPYmogKS5pbnRWYWx1ZSgpOworICAgICAgICB9CisKKyAgICAgICAgLy8gbnVsbCBvciBub3QgYW4gaW50ZWdlcgorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL1VwZGF0ZVRocmVhZC5qYXZhIGIvY29uZmlnYWRtaW4vc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ltcGwvVXBkYXRlVGhyZWFkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWE1ZjQ3ZAotLS0gL2Rldi9udWxsCisrKyBiL2NvbmZpZ2FkbWluL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9pbXBsL1VwZGF0ZVRocmVhZC5qYXZhCkBAIC0wLDAgKzEsMTE5IEBACisvKiAKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5mZWxpeC5jbS5pbXBsOworCisKK2ltcG9ydCBqYXZhLnV0aWwuTGlua2VkTGlzdDsKKworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UubG9nLkxvZ1NlcnZpY2U7CisKKworLyoqCisgKiBUaGUgPGNvZGU+VXBkYXRlVGhyZWFkPC9jb2RlPiBpcyB0aGUgdGhyZWFkIHVzZWQgdG8gdXBkYXRlIG1hbmFnZWQgc2VydmljZXMKKyAqIGFuZCBtYW5hZ2VkIHNlcnZpY2UgZmFjdG9yaWVzIGFzIHdlbGwgYXMgdG8gc2VuZCBjb25maWd1cmF0aW9uIGV2ZW50cy4KKyAqCisgKiBAYXV0aG9yIGZtZXNjaGJlCisgKi8KK3B1YmxpYyBjbGFzcyBVcGRhdGVUaHJlYWQgZXh0ZW5kcyBUaHJlYWQKK3sKKworICAgIC8vIHRoZSBjb25maWd1cmF0aW9uIG1hbmFnZXIgb24gd2hvc2UgYmVoYWxmIHRoaXMgdGhyZWFkIGlzIHN0YXJ0ZWQKKyAgICAvLyAodGhpcyBpcyBtYWlubHkgdXNlZCBmb3IgbG9nZ2luZykKKyAgICBwcml2YXRlIENvbmZpZ3VyYXRpb25NYW5hZ2VyIGNvbmZpZ3VyYXRpb25NYW5hZ2VyOworICAgIAorICAgIC8vIHRoZSBxdWV1ZSBvZiBSdW5uYWJsZSBpbnN0YW5jZXMgIHRvIGJlIHJ1bgorICAgIHByaXZhdGUgTGlua2VkTGlzdCB1cGRhdGVUYXNrczsKKworCisgICAgcHVibGljIFVwZGF0ZVRocmVhZCggQ29uZmlndXJhdGlvbk1hbmFnZXIgY29uZmlndXJhdGlvbk1hbmFnZXIgKQorICAgIHsKKyAgICAgICAgc3VwZXIoICJDb25maWd1cmF0aW9uIFVwZGF0ZXIiICk7CisKKyAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uTWFuYWdlciA9IGNvbmZpZ3VyYXRpb25NYW5hZ2VyOworICAgICAgICB0aGlzLnVwZGF0ZVRhc2tzID0gbmV3IExpbmtlZExpc3QoKTsKKyAgICB9CisKKworICAgIC8vIHdhaXRzIG9uIFJ1bm5hYmxlIGluc3RhbmNlcyBjb21pbmcgaW50byB0aGUgcXVldWUuIEFzIGluc3RhbmNlcyBjb21lCisgICAgLy8gaW4sIHRoaXMgbWV0aG9kIGNhbGxzIHRoZSBSdW5uYWJsZS5ydW4gbWV0aG9kLCBsb2dzIGFueSBleGNlcHRpb24KKyAgICAvLyBoYXBwZW5pbmcgYW5kIGtlZXBzIG9uIHdhaXRpbmcgZm9yIHRoZSBuZXh0IFJ1bm5hYmxlLiBJZiB0aGUgUnVubmFibGUKKyAgICAvLyB0YWtlbiBmcm9tIHRoZSBxdWV1ZSBpcyB0aGlzIHRocmVhZCBpbnN0YW5jZSBpdHNlbGYsIHRoZSB0aHJlYWQKKyAgICAvLyB0ZXJtaW5hdGVzLgorICAgIHB1YmxpYyB2b2lkIHJ1bigpCisgICAgeworICAgICAgICBmb3IgKCA7OyApCisgICAgICAgIHsKKyAgICAgICAgICAgIFJ1bm5hYmxlIHRhc2s7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKCB1cGRhdGVUYXNrcyApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgd2hpbGUgKCB1cGRhdGVUYXNrcy5pc0VtcHR5KCkgKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5CisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZVRhc2tzLndhaXQoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBjYXRjaCAoIEludGVycnVwdGVkRXhjZXB0aW9uIGllICkKKyAgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG9uJ3QgY2FyZQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgdGFzayA9ICggUnVubmFibGUgKSB1cGRhdGVUYXNrcy5yZW1vdmVGaXJzdCgpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyByZXR1cm4gaWYgdGhlIHRhc2sgaXMgdGhpcyB0aHJlYWQgaXRzZWxmCisgICAgICAgICAgICBpZiAoIHRhc2sgPT0gdGhpcyApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBvdGhlcndpc2UgZXhlY3V0ZSB0aGUgdGFzaywgbG9nIGFueSBpc3N1ZXMKKyAgICAgICAgICAgIHRyeQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHRhc2sucnVuKCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXRjaCAoIFRocm93YWJsZSB0ICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uTWFuYWdlci5sb2coIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCAiVW5leHBlY3RlZCBwcm9ibGVtIGV4ZWN1dGluZyB0YXNrIiwgdCApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisKKyAgICAvLyBjYXVzZSB0aGlzIHRocmVhZCB0byB0ZXJtaW5hdGUgYnkgYWRkaW5nIHRoaXMgdGhyZWFkIHRvIHRoZSBlbmQKKyAgICAvLyBvZiB0aGUgcXVldWUKKyAgICB2b2lkIHRlcm1pbmF0ZSgpCisgICAgeworICAgICAgICBzY2hlZHVsZSggdGhpcyApOworICAgIH0KKworCisgICAgLy8gcXVldWUgdGhlIGdpdmVuIHJ1bm5hYmxlIHRvIGJlIHJ1biBhcyBzb29uIGFzIHBvc3NpYmxlCisgICAgdm9pZCBzY2hlZHVsZSggUnVubmFibGUgdXBkYXRlICkKKyAgICB7CisgICAgICAgIHN5bmNocm9uaXplZCAoIHVwZGF0ZVRhc2tzICkKKyAgICAgICAgeworICAgICAgICAgICAgLy8gYXBwZW5kIHRvIHRoZSB0YXNrIHF1ZXVlCisgICAgICAgICAgICB1cGRhdGVUYXNrcy5hZGQoIHVwZGF0ZSApOworICAgICAgICAgICAgCisgICAgICAgICAgICAvLyBub3RpZnkgdGhlIHdhaXRpbmcgdGhyZWFkCisgICAgICAgICAgICB1cGRhdGVUYXNrcy5ub3RpZnlBbGwoKTsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL2NvbmZpZ2FkbWluL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9Nb2NrQnVuZGxlQ29udGV4dC5qYXZhIGIvY29uZmlnYWRtaW4vc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL01vY2tCdW5kbGVDb250ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWIxZGJmZgotLS0gL2Rldi9udWxsCisrKyBiL2NvbmZpZ2FkbWluL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9Nb2NrQnVuZGxlQ29udGV4dC5qYXZhCkBAIC0wLDAgKzEsMjYwIEBACisvKgorICogJFVybDogJAorICogJElkJAorICoKKyAqIENvcHlyaWdodCAxOTk3LTIwMDUgRGF5IE1hbmFnZW1lbnQgQUcKKyAqIEJhcmZ1ZXNzZXJwbGF0eiA2LCA0MDAxIEJhc2VsLCBTd2l0emVybGFuZAorICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqCisgKiBUaGlzIHNvZnR3YXJlIGlzIHRoZSBjb25maWRlbnRpYWwgYW5kIHByb3ByaWV0YXJ5IGluZm9ybWF0aW9uIG9mCisgKiBEYXkgTWFuYWdlbWVudCBBRywgKCJDb25maWRlbnRpYWwgSW5mb3JtYXRpb24iKS4gWW91IHNoYWxsIG5vdAorICogZGlzY2xvc2Ugc3VjaCBDb25maWRlbnRpYWwgSW5mb3JtYXRpb24gYW5kIHNoYWxsIHVzZSBpdCBvbmx5IGluCisgKiBhY2NvcmRhbmNlIHdpdGggdGhlIHRlcm1zIG9mIHRoZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgZW50ZXJlZCBpbnRvCisgKiB3aXRoIERheS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmZlbGl4LmNtOworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkRpY3Rpb25hcnk7CisKK2ltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlOworaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVDb250ZXh0OworaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVFeGNlcHRpb247CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUxpc3RlbmVyOworaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5GaWx0ZXI7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkZyYW1ld29ya0xpc3RlbmVyOworaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5JbnZhbGlkU3ludGF4RXhjZXB0aW9uOworaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5TZXJ2aWNlTGlzdGVuZXI7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLlNlcnZpY2VSZWZlcmVuY2U7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLlNlcnZpY2VSZWdpc3RyYXRpb247CisKKy8qKgorICogVGhlIDxjb2RlPk1vY2tCdW5kbGVDb250ZXh0PC9jb2RlPiBUT0RPCisgKgorICogQGF1dGhvciBmbWVzY2hiZQorICogQHZlcnNpb24gJFJldjokLCAkRGF0ZTokCisgKi8KK3B1YmxpYyBjbGFzcyBNb2NrQnVuZGxlQ29udGV4dCBpbXBsZW1lbnRzIEJ1bmRsZUNvbnRleHQKK3sKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVDb250ZXh0I2FkZEJ1bmRsZUxpc3RlbmVyKG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVMaXN0ZW5lcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRCdW5kbGVMaXN0ZW5lciggQnVuZGxlTGlzdGVuZXIgYXJnMCApCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVDb250ZXh0I2FkZEZyYW1ld29ya0xpc3RlbmVyKG9yZy5vc2dpLmZyYW1ld29yay5GcmFtZXdvcmtMaXN0ZW5lcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRGcmFtZXdvcmtMaXN0ZW5lciggRnJhbWV3b3JrTGlzdGVuZXIgYXJnMCApCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVDb250ZXh0I2FkZFNlcnZpY2VMaXN0ZW5lcihvcmcub3NnaS5mcmFtZXdvcmsuU2VydmljZUxpc3RlbmVyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGFkZFNlcnZpY2VMaXN0ZW5lciggU2VydmljZUxpc3RlbmVyIGFyZzAgKQorICAgIHsKKyAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorCisgICAgfQorCisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlQ29udGV4dCNhZGRTZXJ2aWNlTGlzdGVuZXIob3JnLm9zZ2kuZnJhbWV3b3JrLlNlcnZpY2VMaXN0ZW5lciwgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBhZGRTZXJ2aWNlTGlzdGVuZXIoIFNlcnZpY2VMaXN0ZW5lciBhcmcwLCBTdHJpbmcgYXJnMSApIHRocm93cyBJbnZhbGlkU3ludGF4RXhjZXB0aW9uCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVDb250ZXh0I2NyZWF0ZUZpbHRlcihqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBGaWx0ZXIgY3JlYXRlRmlsdGVyKCBTdHJpbmcgYXJnMCApIHRocm93cyBJbnZhbGlkU3ludGF4RXhjZXB0aW9uCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQjZ2V0QWxsU2VydmljZVJlZmVyZW5jZXMoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgU2VydmljZVJlZmVyZW5jZVtdIGdldEFsbFNlcnZpY2VSZWZlcmVuY2VzKCBTdHJpbmcgYXJnMCwgU3RyaW5nIGFyZzEgKSB0aHJvd3MgSW52YWxpZFN5bnRheEV4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVDb250ZXh0I2dldEJ1bmRsZSgpCisgICAgICovCisgICAgcHVibGljIEJ1bmRsZSBnZXRCdW5kbGUoKQorICAgIHsKKyAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVDb250ZXh0I2dldEJ1bmRsZShsb25nKQorICAgICAqLworICAgIHB1YmxpYyBCdW5kbGUgZ2V0QnVuZGxlKCBsb25nIGFyZzAgKQorICAgIHsKKyAgICAgICAgLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVDb250ZXh0I2dldEJ1bmRsZXMoKQorICAgICAqLworICAgIHB1YmxpYyBCdW5kbGVbXSBnZXRCdW5kbGVzKCkKKyAgICB7CisgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlQ29udGV4dCNnZXREYXRhRmlsZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBGaWxlIGdldERhdGFGaWxlKCBTdHJpbmcgYXJnMCApCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQjZ2V0UHJvcGVydHkoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgU3RyaW5nIGdldFByb3BlcnR5KCBTdHJpbmcgYXJnMCApCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQjZ2V0U2VydmljZShvcmcub3NnaS5mcmFtZXdvcmsuU2VydmljZVJlZmVyZW5jZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IGdldFNlcnZpY2UoIFNlcnZpY2VSZWZlcmVuY2UgYXJnMCApCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQjZ2V0U2VydmljZVJlZmVyZW5jZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBTZXJ2aWNlUmVmZXJlbmNlIGdldFNlcnZpY2VSZWZlcmVuY2UoIFN0cmluZyBhcmcwICkKKyAgICB7CisgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlQ29udGV4dCNnZXRTZXJ2aWNlUmVmZXJlbmNlcyhqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBTZXJ2aWNlUmVmZXJlbmNlW10gZ2V0U2VydmljZVJlZmVyZW5jZXMoIFN0cmluZyBhcmcwLCBTdHJpbmcgYXJnMSApIHRocm93cyBJbnZhbGlkU3ludGF4RXhjZXB0aW9uCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQjaW5zdGFsbEJ1bmRsZShqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBCdW5kbGUgaW5zdGFsbEJ1bmRsZSggU3RyaW5nIGFyZzAgKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQjaW5zdGFsbEJ1bmRsZShqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmlvLklucHV0U3RyZWFtKQorICAgICAqLworICAgIHB1YmxpYyBCdW5kbGUgaW5zdGFsbEJ1bmRsZSggU3RyaW5nIGFyZzAsIElucHV0U3RyZWFtIGFyZzEgKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQjcmVnaXN0ZXJTZXJ2aWNlKGphdmEubGFuZy5TdHJpbmdbXSwgamF2YS5sYW5nLk9iamVjdCwgamF2YS51dGlsLkRpY3Rpb25hcnkpCisgICAgICovCisgICAgcHVibGljIFNlcnZpY2VSZWdpc3RyYXRpb24gcmVnaXN0ZXJTZXJ2aWNlKCBTdHJpbmdbXSBhcmcwLCBPYmplY3QgYXJnMSwgRGljdGlvbmFyeSBhcmcyICkKKyAgICB7CisgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisKKyAgICAvKiAobm9uLUphdmFkb2MpCisgICAgICogQHNlZSBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlQ29udGV4dCNyZWdpc3RlclNlcnZpY2UoamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLk9iamVjdCwgamF2YS51dGlsLkRpY3Rpb25hcnkpCisgICAgICovCisgICAgcHVibGljIFNlcnZpY2VSZWdpc3RyYXRpb24gcmVnaXN0ZXJTZXJ2aWNlKCBTdHJpbmcgYXJnMCwgT2JqZWN0IGFyZzEsIERpY3Rpb25hcnkgYXJnMiApCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQjcmVtb3ZlQnVuZGxlTGlzdGVuZXIob3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUxpc3RlbmVyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUJ1bmRsZUxpc3RlbmVyKCBCdW5kbGVMaXN0ZW5lciBhcmcwICkKKyAgICB7CisgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQjcmVtb3ZlRnJhbWV3b3JrTGlzdGVuZXIob3JnLm9zZ2kuZnJhbWV3b3JrLkZyYW1ld29ya0xpc3RlbmVyKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJlbW92ZUZyYW1ld29ya0xpc3RlbmVyKCBGcmFtZXdvcmtMaXN0ZW5lciBhcmcwICkKKyAgICB7CisgICAgICAgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKKworICAgIH0KKworCisgICAgLyogKG5vbi1KYXZhZG9jKQorICAgICAqIEBzZWUgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQjcmVtb3ZlU2VydmljZUxpc3RlbmVyKG9yZy5vc2dpLmZyYW1ld29yay5TZXJ2aWNlTGlzdGVuZXIpCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVtb3ZlU2VydmljZUxpc3RlbmVyKCBTZXJ2aWNlTGlzdGVuZXIgYXJnMCApCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisKKyAgICB9CisKKworICAgIC8qIChub24tSmF2YWRvYykKKyAgICAgKiBAc2VlIG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVDb250ZXh0I3VuZ2V0U2VydmljZShvcmcub3NnaS5mcmFtZXdvcmsuU2VydmljZVJlZmVyZW5jZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiB1bmdldFNlcnZpY2UoIFNlcnZpY2VSZWZlcmVuY2UgYXJnMCApCisgICAgeworICAgICAgICAvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKK30KZGlmZiAtLWdpdCBhL2NvbmZpZ2FkbWluL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9maWxlL0ZpbGVOYW1lVGVzdC5qYXZhIGIvY29uZmlnYWRtaW4vc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ZpbGUvRmlsZU5hbWVUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjAxMGE1MAotLS0gL2Rldi9udWxsCisrKyBiL2NvbmZpZ2FkbWluL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9maWxlL0ZpbGVOYW1lVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA0IEBACisvKgorICogJFVybDogJAorICogJElkJAorICoKKyAqIENvcHlyaWdodCAxOTk3LTIwMDUgRGF5IE1hbmFnZW1lbnQgQUcKKyAqIEJhcmZ1ZXNzZXJwbGF0eiA2LCA0MDAxIEJhc2VsLCBTd2l0emVybGFuZAorICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKyAqCisgKiBUaGlzIHNvZnR3YXJlIGlzIHRoZSBjb25maWRlbnRpYWwgYW5kIHByb3ByaWV0YXJ5IGluZm9ybWF0aW9uIG9mCisgKiBEYXkgTWFuYWdlbWVudCBBRywgKCJDb25maWRlbnRpYWwgSW5mb3JtYXRpb24iKS4gWW91IHNoYWxsIG5vdAorICogZGlzY2xvc2Ugc3VjaCBDb25maWRlbnRpYWwgSW5mb3JtYXRpb24gYW5kIHNoYWxsIHVzZSBpdCBvbmx5IGluCisgKiBhY2NvcmRhbmNlIHdpdGggdGhlIHRlcm1zIG9mIHRoZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgZW50ZXJlZCBpbnRvCisgKiB3aXRoIERheS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLmZlbGl4LmNtLmZpbGU7CisKKworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQml0U2V0OworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisKK3B1YmxpYyBjbGFzcyBGaWxlTmFtZVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZQoreworCisgICAgcHVibGljIHZvaWQgdGVzdFBpZFBsYWluKCkKKyAgICB7CisgICAgICAgIGFzc2VydEVxdWFscyggInBsYWluIiwgZW5jb2RlUGF0aCggInBsYWluIiApICk7CisgICAgICAgIGFzc2VydEVxdWFscyggInBsYWluIiArIEZpbGUuc2VwYXJhdG9yQ2hhciArICJwYXRoIiwgZW5jb2RlUGF0aCggInBsYWluLnBhdGgiICkgKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCAiZW5jb2QlMDBlOCIsIGVuY29kZVBhdGgoICJlbmNvZOgiICkgKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKCAiZW5jb2QlMDBlOCIgKyBGaWxlLnNlcGFyYXRvckNoYXIgKyAicGF0aCIsIGVuY29kZVBhdGgoICJlbmNvZOgvcGF0aCIgKSApOworICAgICAgICBhc3NlcnRFcXVhbHMoICJlbmNvZGUiICsgRmlsZS5zZXBhcmF0b3JDaGFyICsgIiUxMjM0IiArIEZpbGUuc2VwYXJhdG9yQ2hhciArICJwYXRoIiwgZW5jb2RlUGF0aCggImVuY29kZS9cdTEyMzQvcGF0aCIgKSApOworICAgICAgICBhc3NlcnRFcXVhbHMoICJlbmNvZGUiICsgRmlsZS5zZXBhcmF0b3JDaGFyICsgIiAlMDAyNSAiICsgRmlsZS5zZXBhcmF0b3JDaGFyICsgInBhdGgiLCBlbmNvZGVQYXRoKCAiZW5jb2RlLyAlIC9wYXRoIiApICk7CisgICAgfQorCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQml0U2V0IFZBTElEX1BBVEhfQ0hBUlM7CisKKyAgICBzdGF0aWMKKyAgICB7CisgICAgICAgIFZBTElEX1BBVEhfQ0hBUlMgPSBuZXcgQml0U2V0KCk7CisKKyAgICAgICAgZm9yICggaW50IGkgPSAnYSc7IGkgPD0gJ3onOyBpKysgKQorICAgICAgICB7CisgICAgICAgICAgICBWQUxJRF9QQVRIX0NIQVJTLnNldCggaSApOworICAgICAgICB9CisgICAgICAgIGZvciAoIGludCBpID0gJ0EnOyBpIDw9ICdaJzsgaSsrICkKKyAgICAgICAgeworICAgICAgICAgICAgVkFMSURfUEFUSF9DSEFSUy5zZXQoIGkgKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKCBpbnQgaSA9ICcwJzsgaSA8PSAnOSc7IGkrKyApCisgICAgICAgIHsKKyAgICAgICAgICAgIFZBTElEX1BBVEhfQ0hBUlMuc2V0KCBpICk7CisgICAgICAgIH0KKyAgICAgICAgVkFMSURfUEFUSF9DSEFSUy5zZXQoIEZpbGUuc2VwYXJhdG9yQ2hhciApOworICAgICAgICBWQUxJRF9QQVRIX0NIQVJTLnNldCggJyAnICk7CisgICAgICAgIFZBTElEX1BBVEhfQ0hBUlMuc2V0KCAnLScgKTsKKyAgICAgICAgVkFMSURfUEFUSF9DSEFSUy5zZXQoICdfJyApOworICAgIH0KKworCisgICAgcHJpdmF0ZSBTdHJpbmcgZW5jb2RlUGF0aCggU3RyaW5nIHBpZCApCisgICAgeworICAgICAgICAvLyByZXBsYWNlIGRvdHMgYnkgRmlsZS5zZXBhcmF0b3JDaGFyCisgICAgICAgIHBpZCA9IHBpZC5yZXBsYWNlKCAnLicsIEZpbGUuc2VwYXJhdG9yQ2hhciApOworCisgICAgICAgIC8vIHJlcGxhY2Ugc2xhc2ggYnkgRmlsZS5zZXBhcmF0b3JDaGFyIGlmIGRpZmZlcmVudAorICAgICAgICBpZiAoRmlsZS5zZXBhcmF0b3JDaGFyICE9ICcvJykgeworICAgICAgICAgICAgcGlkID0gcGlkLnJlcGxhY2UoICcvJywgRmlsZS5zZXBhcmF0b3JDaGFyICk7CisgICAgICAgIH0KKworICAgICAgICAvLyBzY2FuIGZvciBmaXJzdCBub24tdmFsaWQgY2hhcmFjdGVyIChpZiBhbnkpCisgICAgICAgIGludCBmaXJzdCA9IDA7CisgICAgICAgIHdoaWxlICggZmlyc3QgPCBwaWQubGVuZ3RoKCkgJiYgVkFMSURfUEFUSF9DSEFSUy5nZXQoIHBpZC5jaGFyQXQoIGZpcnN0ICkgKSApCisgICAgICAgIHsKKyAgICAgICAgICAgIGZpcnN0Kys7CisgICAgICAgIH0KKworICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHdlIGV4aGF1c3RlZAorICAgICAgICBpZiAoIGZpcnN0IDwgcGlkLmxlbmd0aCgpICkKKyAgICAgICAgeworICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoIHBpZC5zdWJzdHJpbmcoIDAsIGZpcnN0ICkgKTsKKworICAgICAgICAgICAgZm9yICggaW50IGkgPSBmaXJzdDsgaSA8IHBpZC5sZW5ndGgoKTsgaSsrICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBjaGFyIGMgPSBwaWQuY2hhckF0KCBpICk7CisgICAgICAgICAgICAgICAgaWYgKCBWQUxJRF9QQVRIX0NIQVJTLmdldCggYyApICkKKyAgICAgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoIGMgKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbCA9ICIwMDAiICsgSW50ZWdlci50b0hleFN0cmluZyggYyApOworICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAnJScgKTsKKyAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCggdmFsLnN1YnN0cmluZyggdmFsLmxlbmd0aCgpIC0gNCApICk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgCisgICAgICAgICAgICByZXR1cm4gYnVmLnRvU3RyaW5nKCk7CisgICAgICAgIH0KKyAgICAgICAgCisgICAgICAgIHJldHVybiBwaWQ7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvY29uZmlnYWRtaW4vc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL2ZlbGl4L2NtL2ZpbGUvRmlsZVBlcnNpc3RlbmNlTWFuYWdlclRlc3QuamF2YSBiL2NvbmZpZ2FkbWluL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9maWxlL0ZpbGVQZXJzaXN0ZW5jZU1hbmFnZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmVmZmE1YQotLS0gL2Rldi9udWxsCisrKyBiL2NvbmZpZ2FkbWluL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9mZWxpeC9jbS9maWxlL0ZpbGVQZXJzaXN0ZW5jZU1hbmFnZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxNzcgQEAKKy8qCisgKiAkVXJsOiAkCisgKiAkSWQkCisgKgorICogQ29weXJpZ2h0IDE5OTctMjAwNSBEYXkgTWFuYWdlbWVudCBBRworICogQmFyZnVlc3NlcnBsYXR6IDYsIDQwMDEgQmFzZWwsIFN3aXR6ZXJsYW5kCisgKiBBbGwgUmlnaHRzIFJlc2VydmVkLgorICoKKyAqIFRoaXMgc29mdHdhcmUgaXMgdGhlIGNvbmZpZGVudGlhbCBhbmQgcHJvcHJpZXRhcnkgaW5mb3JtYXRpb24gb2YKKyAqIERheSBNYW5hZ2VtZW50IEFHLCAoIkNvbmZpZGVudGlhbCBJbmZvcm1hdGlvbiIpLiBZb3Ugc2hhbGwgbm90CisgKiBkaXNjbG9zZSBzdWNoIENvbmZpZGVudGlhbCBJbmZvcm1hdGlvbiBhbmQgc2hhbGwgdXNlIGl0IG9ubHkgaW4KKyAqIGFjY29yZGFuY2Ugd2l0aCB0aGUgdGVybXMgb2YgdGhlIGxpY2Vuc2UgYWdyZWVtZW50IHlvdSBlbnRlcmVkIGludG8KKyAqIHdpdGggRGF5LgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuZmVsaXguY20uZmlsZTsKKworCitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuQXJyYXk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuRGljdGlvbmFyeTsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2h0YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOworCitpbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlOworCisKKy8qKgorICogVGhlIDxjb2RlPkZpbGVQZXJzaXN0ZW5jZU1hbmFnZXJUZXN0PC9jb2RlPiBUT0RPCisgKgorICogQGF1dGhvciBmbWVzY2hiZQorICogQHZlcnNpb24gJFJldjokLCAkRGF0ZTokCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlUGVyc2lzdGVuY2VNYW5hZ2VyVGVzdCBleHRlbmRzIFRlc3RDYXNlCit7CisgICAgcHJpdmF0ZSBGaWxlIGZpbGUgPSBuZXcgRmlsZSggU3lzdGVtLmdldFByb3BlcnR5KCAiamF2YS5pby50bXBkaXIiICksICJjb25maWciICk7CisKKyAgICBwcml2YXRlIEZpbGVQZXJzaXN0ZW5jZU1hbmFnZXIgZnBtOworCisKKyAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24KKyAgICB7CisgICAgICAgIHN1cGVyLnNldFVwKCk7CisKKyAgICAgICAgZnBtID0gbmV3IEZpbGVQZXJzaXN0ZW5jZU1hbmFnZXIoIGZpbGUuZ2V0QWJzb2x1dGVQYXRoKCkgKTsKKyAgICB9CisKKworICAgIHByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgRmlsZVtdIGNoaWxkcmVuID0gZmlsZS5saXN0RmlsZXMoKTsKKyAgICAgICAgZm9yICggaW50IGkgPSAwOyBjaGlsZHJlbiAhPSBudWxsICYmIGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKyApCisgICAgICAgIHsKKyAgICAgICAgICAgIGNoaWxkcmVuW2ldLmRlbGV0ZSgpOworICAgICAgICB9CisgICAgICAgIGZpbGUuZGVsZXRlKCk7CisKKyAgICAgICAgc3VwZXIudGVhckRvd24oKTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RDcmVhdGVEaXIoKQorICAgIHsKKyAgICAgICAgYXNzZXJ0VHJ1ZSggZmlsZS5pc0RpcmVjdG9yeSgpICk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0U2ltcGxlKCkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBjaGVjayggIlN0cmluZyIsICJTdHJpbmcgVmFsdWUiICk7CisgICAgICAgIGNoZWNrKCAiSW50ZWdlciIsIG5ldyBJbnRlZ2VyKCAyICkgKTsKKyAgICAgICAgY2hlY2soICJMb25nIiwgbmV3IExvbmcoIDIgKSApOworICAgICAgICBjaGVjayggIkZsb2F0IiwgbmV3IEZsb2F0KCAyICkgKTsKKyAgICAgICAgY2hlY2soICJEb3VibGUiLCBuZXcgRG91YmxlKCAyICkgKTsKKyAgICAgICAgY2hlY2soICJCeXRlIiwgbmV3IEJ5dGUoICggYnl0ZSApIDIgKSApOworICAgICAgICBjaGVjayggIlNob3J0IiwgbmV3IFNob3J0KCAoIHNob3J0ICkgMiApICk7CisgICAgICAgIGNoZWNrKCAiQ2hhcmFjdGVyIiwgbmV3IENoYXJhY3RlciggJ2EnICkgKTsKKyAgICAgICAgY2hlY2soICJCb29sZWFuIiwgQm9vbGVhbi5UUlVFICk7CisgICAgfQorCisKKyAgICBwdWJsaWMgdm9pZCB0ZXN0UXVvdGluZygpIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgY2hlY2soICJRdW90aW5nU2VwYXJhdG9ycyIsICJcXCgpW117fS4sPSIgKTsKKyAgICAgICAgY2hlY2soICJRdW90aW5nV2VsbEtub3duIiwgIkJTUDpcYiwgVEFCOlx0LCBMRjpcbiwgRkY6XGYsIENSOlxyIiApOworICAgICAgICBjaGVjayggIlF1b3RpbmdDb250cm9sIiwgbmV3IFN0cmluZyggbmV3IGNoYXJbXQorICAgICAgICAgICAgeyA1LCAxMCwgMzIsIDY0IH0gKSApOworICAgIH0KKworCisgICAgcHVibGljIHZvaWQgdGVzdEFycmF5KCkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBjaGVjayggIlN0cmluZ0FycmF5IiwgbmV3IFN0cmluZ1tdCisgICAgICAgICAgICB7ICJvbmUiLCAidHdvIiwgInRocmVlIiB9ICk7CisgICAgICAgIGNoZWNrKCAiSW50QXJyYXkiLCBuZXcgaW50W10KKyAgICAgICAgICAgIHsgMCwgMSwgMiB9ICk7CisgICAgICAgIGNoZWNrKCAiSW50ZWdlckFycmF5IiwgbmV3IEludGVnZXJbXQorICAgICAgICAgICAgeyBuZXcgSW50ZWdlciggMCApLCBuZXcgSW50ZWdlciggMSApLCBuZXcgSW50ZWdlciggMiApIH0gKTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RWZWN0b3IoKSB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICB7CisgICAgICAgIGNoZWNrKCAiU3RyaW5nVmVjdG9yIiwgbmV3IFZlY3RvciggQXJyYXlzLmFzTGlzdCggbmV3IFN0cmluZ1tdCisgICAgICAgICAgICB7ICJvbmUiLCAidHdvIiwgInRocmVlIiB9ICkgKSApOworICAgICAgICBjaGVjayggIkludGVnZXJWZWN0b3IiLCBuZXcgVmVjdG9yKCBBcnJheXMuYXNMaXN0KCBuZXcgSW50ZWdlcltdCisgICAgICAgICAgICB7IG5ldyBJbnRlZ2VyKCAwICksIG5ldyBJbnRlZ2VyKCAxICksIG5ldyBJbnRlZ2VyKCAyICkgfSApICkgKTsKKyAgICB9CisKKworICAgIHB1YmxpYyB2b2lkIHRlc3RNdWx0aVZhbHVlKCkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBEaWN0aW9uYXJ5IHByb3BzID0gbmV3IEhhc2h0YWJsZSgpOworICAgICAgICBwcm9wcy5wdXQoICJTdHJpbmciLCAiU3RyaW5nIFZhbHVlIiApOworICAgICAgICBwcm9wcy5wdXQoICJJbnRlZ2VyIiwgbmV3IEludGVnZXIoIDIgKSApOworICAgICAgICBwcm9wcy5wdXQoICJMb25nIiwgbmV3IExvbmcoIDIgKSApOworICAgICAgICBwcm9wcy5wdXQoICJGbG9hdCIsIG5ldyBGbG9hdCggMiApICk7CisgICAgICAgIHByb3BzLnB1dCggIkRvdWJsZSIsIG5ldyBEb3VibGUoIDIgKSApOworICAgICAgICBwcm9wcy5wdXQoICJCeXRlIiwgbmV3IEJ5dGUoICggYnl0ZSApIDIgKSApOworICAgICAgICBwcm9wcy5wdXQoICJTaG9ydCIsIG5ldyBTaG9ydCggKCBzaG9ydCApIDIgKSApOworICAgICAgICBwcm9wcy5wdXQoICJDaGFyYWN0ZXIiLCBuZXcgQ2hhcmFjdGVyKCAnYScgKSApOworICAgICAgICBwcm9wcy5wdXQoICJCb29sZWFuIiwgQm9vbGVhbi5UUlVFICk7CisgICAgICAgIHByb3BzLnB1dCggIkFycmF5IiwgbmV3IGJvb2xlYW5bXQorICAgICAgICAgICAgeyB0cnVlLCBmYWxzZSB9ICk7CisKKyAgICAgICAgY2hlY2soICJNdWx0aVZhbHVlIiwgcHJvcHMgKTsKKyAgICB9CisKKworICAgIHByaXZhdGUgdm9pZCBjaGVjayggU3RyaW5nIG5hbWUsIE9iamVjdCB2YWx1ZSApIHRocm93cyBJT0V4Y2VwdGlvbgorICAgIHsKKyAgICAgICAgRGljdGlvbmFyeSBwcm9wcyA9IG5ldyBIYXNodGFibGUoKTsKKyAgICAgICAgcHJvcHMucHV0KCBuYW1lLCB2YWx1ZSApOworCisgICAgICAgIGNoZWNrKCBuYW1lLCBwcm9wcyApOworICAgIH0KKworCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrKCBTdHJpbmcgcGlkLCBEaWN0aW9uYXJ5IHByb3BzICkgdGhyb3dzIElPRXhjZXB0aW9uCisgICAgeworICAgICAgICBmcG0uc3RvcmUoIHBpZCwgcHJvcHMgKTsKKworICAgICAgICBhc3NlcnRUcnVlKCBuZXcgRmlsZSggZmlsZSwgcGlkICsgIi5jb25maWciICkuZXhpc3RzKCkgKTsKKworICAgICAgICBEaWN0aW9uYXJ5IGxvYWRlZCA9IGZwbS5sb2FkKCBwaWQgKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCggbG9hZGVkICk7CisgICAgICAgIGFzc2VydEVxdWFscyggcHJvcHMuc2l6ZSgpLCBsb2FkZWQuc2l6ZSgpICk7CisKKyAgICAgICAgZm9yICggRW51bWVyYXRpb24gcGUgPSBwcm9wcy5rZXlzKCk7IHBlLmhhc01vcmVFbGVtZW50cygpOyApCisgICAgICAgIHsKKyAgICAgICAgICAgIFN0cmluZyBrZXkgPSAoIFN0cmluZyApIHBlLm5leHRFbGVtZW50KCk7CisgICAgICAgICAgICBjaGVja1ZhbHVlcyggcHJvcHMuZ2V0KCBrZXkgKSwgbG9hZGVkLmdldCgga2V5ICkgKTsKKyAgICAgICAgfQorICAgIH0KKworCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrVmFsdWVzKCBPYmplY3QgdmFsdWUxLCBPYmplY3QgdmFsdWUyICkKKyAgICB7CisgICAgICAgIGFzc2VydE5vdE51bGwoIHZhbHVlMiApOworICAgICAgICBpZiAoIHZhbHVlMS5nZXRDbGFzcygpLmlzQXJyYXkoKSApCisgICAgICAgIHsKKyAgICAgICAgICAgIGFzc2VydFRydWUoIHZhbHVlMi5nZXRDbGFzcygpLmlzQXJyYXkoKSApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCB2YWx1ZTEuZ2V0Q2xhc3MoKS5nZXRDb21wb25lbnRUeXBlKCksIHZhbHVlMi5nZXRDbGFzcygpLmdldENvbXBvbmVudFR5cGUoKSApOworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCBBcnJheS5nZXRMZW5ndGgoIHZhbHVlMSApLCBBcnJheS5nZXRMZW5ndGgoIHZhbHVlMiApICk7CisgICAgICAgICAgICBmb3IgKCBpbnQgaSA9IDA7IGkgPCBBcnJheS5nZXRMZW5ndGgoIHZhbHVlMSApOyBpKysgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyggQXJyYXkuZ2V0KCB2YWx1ZTEsIGkgKSwgQXJyYXkuZ2V0KCB2YWx1ZTIsIGkgKSApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKCB2YWx1ZTEsIHZhbHVlMiApOworICAgICAgICB9CisgICAgfQorfQo=