ZGlmZiAtLWdpdCBhL0xJQ0VOU0UgYi9MSUNFTlNFCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2NDU2OTUKLS0tIC9kZXYvbnVsbAorKysgYi9MSUNFTlNFCkBAIC0wLDAgKzEsMjAyIEBACisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCisgICAgICAgICAgICAgICAgICAgICAgICAgICBWZXJzaW9uIDIuMCwgSmFudWFyeSAyMDA0CisgICAgICAgICAgICAgICAgICAgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvCisKKyAgIFRFUk1TIEFORCBDT05ESVRJT05TIEZPUiBVU0UsIFJFUFJPRFVDVElPTiwgQU5EIERJU1RSSUJVVElPTgorCisgICAxLiBEZWZpbml0aW9ucy4KKworICAgICAgIkxpY2Vuc2UiIHNoYWxsIG1lYW4gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwKKyAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgorCisgICAgICAiTGljZW5zb3IiIHNoYWxsIG1lYW4gdGhlIGNvcHlyaWdodCBvd25lciBvciBlbnRpdHkgYXV0aG9yaXplZCBieQorICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgorCisgICAgICAiTGVnYWwgRW50aXR5IiBzaGFsbCBtZWFuIHRoZSB1bmlvbiBvZiB0aGUgYWN0aW5nIGVudGl0eSBhbmQgYWxsCisgICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCisgICAgICBjb250cm9sIHdpdGggdGhhdCBlbnRpdHkuIEZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBkZWZpbml0aW9uLAorICAgICAgImNvbnRyb2wiIG1lYW5zIChpKSB0aGUgcG93ZXIsIGRpcmVjdCBvciBpbmRpcmVjdCwgdG8gY2F1c2UgdGhlCisgICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgorICAgICAgb3RoZXJ3aXNlLCBvciAoaWkpIG93bmVyc2hpcCBvZiBmaWZ0eSBwZXJjZW50ICg1MCUpIG9yIG1vcmUgb2YgdGhlCisgICAgICBvdXRzdGFuZGluZyBzaGFyZXMsIG9yIChpaWkpIGJlbmVmaWNpYWwgb3duZXJzaGlwIG9mIHN1Y2ggZW50aXR5LgorCisgICAgICAiWW91IiAob3IgIllvdXIiKSBzaGFsbCBtZWFuIGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5CisgICAgICBleGVyY2lzaW5nIHBlcm1pc3Npb25zIGdyYW50ZWQgYnkgdGhpcyBMaWNlbnNlLgorCisgICAgICAiU291cmNlIiBmb3JtIHNoYWxsIG1lYW4gdGhlIHByZWZlcnJlZCBmb3JtIGZvciBtYWtpbmcgbW9kaWZpY2F0aW9ucywKKyAgICAgIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gc29mdHdhcmUgc291cmNlIGNvZGUsIGRvY3VtZW50YXRpb24KKyAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCisKKyAgICAgICJPYmplY3QiIGZvcm0gc2hhbGwgbWVhbiBhbnkgZm9ybSByZXN1bHRpbmcgZnJvbSBtZWNoYW5pY2FsCisgICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CisgICAgICBub3QgbGltaXRlZCB0byBjb21waWxlZCBvYmplY3QgY29kZSwgZ2VuZXJhdGVkIGRvY3VtZW50YXRpb24sCisgICAgICBhbmQgY29udmVyc2lvbnMgdG8gb3RoZXIgbWVkaWEgdHlwZXMuCisKKyAgICAgICJXb3JrIiBzaGFsbCBtZWFuIHRoZSB3b3JrIG9mIGF1dGhvcnNoaXAsIHdoZXRoZXIgaW4gU291cmNlIG9yCisgICAgICBPYmplY3QgZm9ybSwgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIExpY2Vuc2UsIGFzIGluZGljYXRlZCBieSBhCisgICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKKyAgICAgIChhbiBleGFtcGxlIGlzIHByb3ZpZGVkIGluIHRoZSBBcHBlbmRpeCBiZWxvdykuCisKKyAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKKyAgICAgIGZvcm0sIHRoYXQgaXMgYmFzZWQgb24gKG9yIGRlcml2ZWQgZnJvbSkgdGhlIFdvcmsgYW5kIGZvciB3aGljaCB0aGUKKyAgICAgIGVkaXRvcmlhbCByZXZpc2lvbnMsIGFubm90YXRpb25zLCBlbGFib3JhdGlvbnMsIG9yIG90aGVyIG1vZGlmaWNhdGlvbnMKKyAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCisgICAgICBvZiB0aGlzIExpY2Vuc2UsIERlcml2YXRpdmUgV29ya3Mgc2hhbGwgbm90IGluY2x1ZGUgd29ya3MgdGhhdCByZW1haW4KKyAgICAgIHNlcGFyYWJsZSBmcm9tLCBvciBtZXJlbHkgbGluayAob3IgYmluZCBieSBuYW1lKSB0byB0aGUgaW50ZXJmYWNlcyBvZiwKKyAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCisKKyAgICAgICJDb250cmlidXRpb24iIHNoYWxsIG1lYW4gYW55IHdvcmsgb2YgYXV0aG9yc2hpcCwgaW5jbHVkaW5nCisgICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCisgICAgICB0byB0aGF0IFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLCB0aGF0IGlzIGludGVudGlvbmFsbHkKKyAgICAgIHN1Ym1pdHRlZCB0byBMaWNlbnNvciBmb3IgaW5jbHVzaW9uIGluIHRoZSBXb3JrIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIKKyAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgorICAgICAgdGhlIGNvcHlyaWdodCBvd25lci4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sICJzdWJtaXR0ZWQiCisgICAgICBtZWFucyBhbnkgZm9ybSBvZiBlbGVjdHJvbmljLCB2ZXJiYWwsIG9yIHdyaXR0ZW4gY29tbXVuaWNhdGlvbiBzZW50CisgICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bworICAgICAgY29tbXVuaWNhdGlvbiBvbiBlbGVjdHJvbmljIG1haWxpbmcgbGlzdHMsIHNvdXJjZSBjb2RlIGNvbnRyb2wgc3lzdGVtcywKKyAgICAgIGFuZCBpc3N1ZSB0cmFja2luZyBzeXN0ZW1zIHRoYXQgYXJlIG1hbmFnZWQgYnksIG9yIG9uIGJlaGFsZiBvZiwgdGhlCisgICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKKyAgICAgIGV4Y2x1ZGluZyBjb21tdW5pY2F0aW9uIHRoYXQgaXMgY29uc3BpY3VvdXNseSBtYXJrZWQgb3Igb3RoZXJ3aXNlCisgICAgICBkZXNpZ25hdGVkIGluIHdyaXRpbmcgYnkgdGhlIGNvcHlyaWdodCBvd25lciBhcyAiTm90IGEgQ29udHJpYnV0aW9uLiIKKworICAgICAgIkNvbnRyaWJ1dG9yIiBzaGFsbCBtZWFuIExpY2Vuc29yIGFuZCBhbnkgaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKKyAgICAgIG9uIGJlaGFsZiBvZiB3aG9tIGEgQ29udHJpYnV0aW9uIGhhcyBiZWVuIHJlY2VpdmVkIGJ5IExpY2Vuc29yIGFuZAorICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCisKKyAgIDIuIEdyYW50IG9mIENvcHlyaWdodCBMaWNlbnNlLiBTdWJqZWN0IHRvIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZgorICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAorICAgICAgd29ybGR3aWRlLCBub24tZXhjbHVzaXZlLCBuby1jaGFyZ2UsIHJveWFsdHktZnJlZSwgaXJyZXZvY2FibGUKKyAgICAgIGNvcHlyaWdodCBsaWNlbnNlIHRvIHJlcHJvZHVjZSwgcHJlcGFyZSBEZXJpdmF0aXZlIFdvcmtzIG9mLAorICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCisgICAgICBXb3JrIGFuZCBzdWNoIERlcml2YXRpdmUgV29ya3MgaW4gU291cmNlIG9yIE9iamVjdCBmb3JtLgorCisgICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgZWFjaCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIHRvIFlvdSBhIHBlcnBldHVhbCwKKyAgICAgIHdvcmxkd2lkZSwgbm9uLWV4Y2x1c2l2ZSwgbm8tY2hhcmdlLCByb3lhbHR5LWZyZWUsIGlycmV2b2NhYmxlCisgICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKKyAgICAgIHVzZSwgb2ZmZXIgdG8gc2VsbCwgc2VsbCwgaW1wb3J0LCBhbmQgb3RoZXJ3aXNlIHRyYW5zZmVyIHRoZSBXb3JrLAorICAgICAgd2hlcmUgc3VjaCBsaWNlbnNlIGFwcGxpZXMgb25seSB0byB0aG9zZSBwYXRlbnQgY2xhaW1zIGxpY2Vuc2FibGUKKyAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCisgICAgICBDb250cmlidXRpb24ocykgYWxvbmUgb3IgYnkgY29tYmluYXRpb24gb2YgdGhlaXIgQ29udHJpYnV0aW9uKHMpCisgICAgICB3aXRoIHRoZSBXb3JrIHRvIHdoaWNoIHN1Y2ggQ29udHJpYnV0aW9uKHMpIHdhcyBzdWJtaXR0ZWQuIElmIFlvdQorICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKKyAgICAgIGNyb3NzLWNsYWltIG9yIGNvdW50ZXJjbGFpbSBpbiBhIGxhd3N1aXQpIGFsbGVnaW5nIHRoYXQgdGhlIFdvcmsKKyAgICAgIG9yIGEgQ29udHJpYnV0aW9uIGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsgY29uc3RpdHV0ZXMgZGlyZWN0CisgICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCisgICAgICBncmFudGVkIHRvIFlvdSB1bmRlciB0aGlzIExpY2Vuc2UgZm9yIHRoYXQgV29yayBzaGFsbCB0ZXJtaW5hdGUKKyAgICAgIGFzIG9mIHRoZSBkYXRlIHN1Y2ggbGl0aWdhdGlvbiBpcyBmaWxlZC4KKworICAgNC4gUmVkaXN0cmlidXRpb24uIFlvdSBtYXkgcmVwcm9kdWNlIGFuZCBkaXN0cmlidXRlIGNvcGllcyBvZiB0aGUKKyAgICAgIFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mIGluIGFueSBtZWRpdW0sIHdpdGggb3Igd2l0aG91dAorICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKKyAgICAgIG1lZXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgorCisgICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgorICAgICAgICAgIERlcml2YXRpdmUgV29ya3MgYSBjb3B5IG9mIHRoaXMgTGljZW5zZTsgYW5kCisKKyAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKKyAgICAgICAgICBzdGF0aW5nIHRoYXQgWW91IGNoYW5nZWQgdGhlIGZpbGVzOyBhbmQKKworICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCisgICAgICAgICAgdGhhdCBZb3UgZGlzdHJpYnV0ZSwgYWxsIGNvcHlyaWdodCwgcGF0ZW50LCB0cmFkZW1hcmssIGFuZAorICAgICAgICAgIGF0dHJpYnV0aW9uIG5vdGljZXMgZnJvbSB0aGUgU291cmNlIGZvcm0gb2YgdGhlIFdvcmssCisgICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgorICAgICAgICAgIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyBhbmQKKworICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCisgICAgICAgICAgZGlzdHJpYnV0aW9uLCB0aGVuIGFueSBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUgbXVzdAorICAgICAgICAgIGluY2x1ZGUgYSByZWFkYWJsZSBjb3B5IG9mIHRoZSBhdHRyaWJ1dGlvbiBub3RpY2VzIGNvbnRhaW5lZAorICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAorICAgICAgICAgIHBlcnRhaW4gdG8gYW55IHBhcnQgb2YgdGhlIERlcml2YXRpdmUgV29ya3MsIGluIGF0IGxlYXN0IG9uZQorICAgICAgICAgIG9mIHRoZSBmb2xsb3dpbmcgcGxhY2VzOiB3aXRoaW4gYSBOT1RJQ0UgdGV4dCBmaWxlIGRpc3RyaWJ1dGVkCisgICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgorICAgICAgICAgIGRvY3VtZW50YXRpb24sIGlmIHByb3ZpZGVkIGFsb25nIHdpdGggdGhlIERlcml2YXRpdmUgV29ya3M7IG9yLAorICAgICAgICAgIHdpdGhpbiBhIGRpc3BsYXkgZ2VuZXJhdGVkIGJ5IHRoZSBEZXJpdmF0aXZlIFdvcmtzLCBpZiBhbmQKKyAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKKyAgICAgICAgICBvZiB0aGUgTk9USUNFIGZpbGUgYXJlIGZvciBpbmZvcm1hdGlvbmFsIHB1cnBvc2VzIG9ubHkgYW5kCisgICAgICAgICAgZG8gbm90IG1vZGlmeSB0aGUgTGljZW5zZS4gWW91IG1heSBhZGQgWW91ciBvd24gYXR0cmlidXRpb24KKyAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQorICAgICAgICAgIG9yIGFzIGFuIGFkZGVuZHVtIHRvIHRoZSBOT1RJQ0UgdGV4dCBmcm9tIHRoZSBXb3JrLCBwcm92aWRlZAorICAgICAgICAgIHRoYXQgc3VjaCBhZGRpdGlvbmFsIGF0dHJpYnV0aW9uIG5vdGljZXMgY2Fubm90IGJlIGNvbnN0cnVlZAorICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KKworICAgICAgWW91IG1heSBhZGQgWW91ciBvd24gY29weXJpZ2h0IHN0YXRlbWVudCB0byBZb3VyIG1vZGlmaWNhdGlvbnMgYW5kCisgICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCisgICAgICBmb3IgdXNlLCByZXByb2R1Y3Rpb24sIG9yIGRpc3RyaWJ1dGlvbiBvZiBZb3VyIG1vZGlmaWNhdGlvbnMsIG9yCisgICAgICBmb3IgYW55IHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBhcyBhIHdob2xlLCBwcm92aWRlZCBZb3VyIHVzZSwKKyAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAorICAgICAgdGhlIGNvbmRpdGlvbnMgc3RhdGVkIGluIHRoaXMgTGljZW5zZS4KKworICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAorICAgICAgYW55IENvbnRyaWJ1dGlvbiBpbnRlbnRpb25hbGx5IHN1Ym1pdHRlZCBmb3IgaW5jbHVzaW9uIGluIHRoZSBXb3JrCisgICAgICBieSBZb3UgdG8gdGhlIExpY2Vuc29yIHNoYWxsIGJlIHVuZGVyIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZgorICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCisgICAgICBOb3R3aXRoc3RhbmRpbmcgdGhlIGFib3ZlLCBub3RoaW5nIGhlcmVpbiBzaGFsbCBzdXBlcnNlZGUgb3IgbW9kaWZ5CisgICAgICB0aGUgdGVybXMgb2YgYW55IHNlcGFyYXRlIGxpY2Vuc2UgYWdyZWVtZW50IHlvdSBtYXkgaGF2ZSBleGVjdXRlZAorICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgorCisgICA2LiBUcmFkZW1hcmtzLiBUaGlzIExpY2Vuc2UgZG9lcyBub3QgZ3JhbnQgcGVybWlzc2lvbiB0byB1c2UgdGhlIHRyYWRlCisgICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCisgICAgICBleGNlcHQgYXMgcmVxdWlyZWQgZm9yIHJlYXNvbmFibGUgYW5kIGN1c3RvbWFyeSB1c2UgaW4gZGVzY3JpYmluZyB0aGUKKyAgICAgIG9yaWdpbiBvZiB0aGUgV29yayBhbmQgcmVwcm9kdWNpbmcgdGhlIGNvbnRlbnQgb2YgdGhlIE5PVElDRSBmaWxlLgorCisgICA3LiBEaXNjbGFpbWVyIG9mIFdhcnJhbnR5LiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IKKyAgICAgIGFncmVlZCB0byBpbiB3cml0aW5nLCBMaWNlbnNvciBwcm92aWRlcyB0aGUgV29yayAoYW5kIGVhY2gKKyAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yCisgICAgICBpbXBsaWVkLCBpbmNsdWRpbmcsIHdpdGhvdXQgbGltaXRhdGlvbiwgYW55IHdhcnJhbnRpZXMgb3IgY29uZGl0aW9ucworICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQorICAgICAgUEFSVElDVUxBUiBQVVJQT1NFLiBZb3UgYXJlIHNvbGVseSByZXNwb25zaWJsZSBmb3IgZGV0ZXJtaW5pbmcgdGhlCisgICAgICBhcHByb3ByaWF0ZW5lc3Mgb2YgdXNpbmcgb3IgcmVkaXN0cmlidXRpbmcgdGhlIFdvcmsgYW5kIGFzc3VtZSBhbnkKKyAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KKworICAgOC4gTGltaXRhdGlvbiBvZiBMaWFiaWxpdHkuIEluIG5vIGV2ZW50IGFuZCB1bmRlciBubyBsZWdhbCB0aGVvcnksCisgICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKKyAgICAgIHVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyAoc3VjaCBhcyBkZWxpYmVyYXRlIGFuZCBncm9zc2x5CisgICAgICBuZWdsaWdlbnQgYWN0cykgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNoYWxsIGFueSBDb250cmlidXRvciBiZQorICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAorICAgICAgaW5jaWRlbnRhbCwgb3IgY29uc2VxdWVudGlhbCBkYW1hZ2VzIG9mIGFueSBjaGFyYWN0ZXIgYXJpc2luZyBhcyBhCisgICAgICByZXN1bHQgb2YgdGhpcyBMaWNlbnNlIG9yIG91dCBvZiB0aGUgdXNlIG9yIGluYWJpbGl0eSB0byB1c2UgdGhlCisgICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCisgICAgICB3b3JrIHN0b3BwYWdlLCBjb21wdXRlciBmYWlsdXJlIG9yIG1hbGZ1bmN0aW9uLCBvciBhbnkgYW5kIGFsbAorICAgICAgb3RoZXIgY29tbWVyY2lhbCBkYW1hZ2VzIG9yIGxvc3NlcyksIGV2ZW4gaWYgc3VjaCBDb250cmlidXRvcgorICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgorCisgICA5LiBBY2NlcHRpbmcgV2FycmFudHkgb3IgQWRkaXRpb25hbCBMaWFiaWxpdHkuIFdoaWxlIHJlZGlzdHJpYnV0aW5nCisgICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAorICAgICAgYW5kIGNoYXJnZSBhIGZlZSBmb3IsIGFjY2VwdGFuY2Ugb2Ygc3VwcG9ydCwgd2FycmFudHksIGluZGVtbml0eSwKKyAgICAgIG9yIG90aGVyIGxpYWJpbGl0eSBvYmxpZ2F0aW9ucyBhbmQvb3IgcmlnaHRzIGNvbnNpc3RlbnQgd2l0aCB0aGlzCisgICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQorICAgICAgb24gWW91ciBvd24gYmVoYWxmIGFuZCBvbiBZb3VyIHNvbGUgcmVzcG9uc2liaWxpdHksIG5vdCBvbiBiZWhhbGYKKyAgICAgIG9mIGFueSBvdGhlciBDb250cmlidXRvciwgYW5kIG9ubHkgaWYgWW91IGFncmVlIHRvIGluZGVtbmlmeSwKKyAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQorICAgICAgaW5jdXJyZWQgYnksIG9yIGNsYWltcyBhc3NlcnRlZCBhZ2FpbnN0LCBzdWNoIENvbnRyaWJ1dG9yIGJ5IHJlYXNvbgorICAgICAgb2YgeW91ciBhY2NlcHRpbmcgYW55IHN1Y2ggd2FycmFudHkgb3IgYWRkaXRpb25hbCBsaWFiaWxpdHkuCisKKyAgIEVORCBPRiBURVJNUyBBTkQgQ09ORElUSU9OUworCisgICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCisKKyAgICAgIFRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmssIGF0dGFjaCB0aGUgZm9sbG93aW5nCisgICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCisgICAgICByZXBsYWNlZCB3aXRoIHlvdXIgb3duIGlkZW50aWZ5aW5nIGluZm9ybWF0aW9uLiAoRG9uJ3QgaW5jbHVkZQorICAgICAgdGhlIGJyYWNrZXRzISkgIFRoZSB0ZXh0IHNob3VsZCBiZSBlbmNsb3NlZCBpbiB0aGUgYXBwcm9wcmlhdGUKKyAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQorICAgICAgZmlsZSBvciBjbGFzcyBuYW1lIGFuZCBkZXNjcmlwdGlvbiBvZiBwdXJwb3NlIGJlIGluY2x1ZGVkIG9uIHRoZQorICAgICAgc2FtZSAicHJpbnRlZCBwYWdlIiBhcyB0aGUgY29weXJpZ2h0IG5vdGljZSBmb3IgZWFzaWVyCisgICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCisKKyAgIENvcHlyaWdodCBbeXl5eV0gW25hbWUgb2YgY29weXJpZ2h0IG93bmVyXQorCisgICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorCisgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAgIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAgIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAgIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgpkaWZmIC0tZ2l0IGEvTk9USUNFIGIvTk9USUNFCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyYTc5MmEKLS0tIC9kZXYvbnVsbAorKysgYi9OT1RJQ0UKQEAgLTAsMCArMSw4IEBACitBcGFjaGUgU2xpbmcgRXZlbnQKK0NvcHlyaWdodCAyMDA4LTIwMDkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCisKK0FwYWNoZSBTbGluZyBpcyBiYXNlZCBvbiBzb3VyY2UgY29kZSBvcmlnaW5hbGx5IGRldmVsb3BlZCAKK2J5IERheSBTb2Z0d2FyZSAoaHR0cDovL3d3dy5kYXkuY29tLykuCisKK1RoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYXQKK1RoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuCmRpZmYgLS1naXQgYS9SRUFETUUudHh0IGIvUkVBRE1FLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYzVlOWY4Ci0tLSAvZGV2L251bGwKKysrIGIvUkVBRE1FLnR4dApAQCAtMCwwICsxLDM5IEBACitBcGFjaGUgU2xpbmcgRXZlbnQKKworVGhpcyBidW5kbGUgcHJvdmlkZXMgYWRkaXRpb25hbCBmZWF0dXJlcyBmb3IgZXZlbnQgaGFuZGxpbmcsIGxpa2UgcmVwbGljYXRpb24KK2V2ZW50cyBpbiBhIGNsdXN0ZXIsIHByb3ZpZGluZyB0aGUgc3VwcG9ydCBmb3IgdGltZWQgZXZlbnRzIGFuZCBqb2JzLgorCisKK0Rpc2NsYWltZXIKKz09PT09PT09PT0KK0FwYWNoZSBTbGluZyBpcyBhbiBlZmZvcnQgdW5kZXJnb2luZyBpbmN1YmF0aW9uIGF0IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSwKK3Nwb25zb3JlZCBieSB0aGUgQXBhY2hlIEphY2tyYWJiaXQgUE1DLiBJbmN1YmF0aW9uIGlzIHJlcXVpcmVkIG9mIGFsbCBuZXdseSBhY2NlcHRlZAorcHJvamVjdHMgdW50aWwgYSBmdXJ0aGVyIHJldmlldyBpbmRpY2F0ZXMgdGhhdCB0aGUgaW5mcmFzdHJ1Y3R1cmUsIGNvbW11bmljYXRpb25zLAorYW5kIGRlY2lzaW9uIG1ha2luZyBwcm9jZXNzIGhhdmUgc3RhYmlsaXplZCBpbiBhIG1hbm5lciBjb25zaXN0ZW50IHdpdGggb3RoZXIKK3N1Y2Nlc3NmdWwgQVNGIHByb2plY3RzLiBXaGlsZSBpbmN1YmF0aW9uIHN0YXR1cyBpcyBub3QgbmVjZXNzYXJpbHkgYSByZWZsZWN0aW9uIG9mCit0aGUgY29tcGxldGVuZXNzIG9yIHN0YWJpbGl0eSBvZiB0aGUgY29kZSwgaXQgZG9lcyBpbmRpY2F0ZSB0aGF0IHRoZSBwcm9qZWN0IGhhcyB5ZXQKK3RvIGJlIGZ1bGx5IGVuZG9yc2VkIGJ5IHRoZSBBU0YuCisKK0dldHRpbmcgU3RhcnRlZAorPT09PT09PT09PT09PT09CisKK1RoaXMgY29tcG9uZW50IHVzZXMgYSBNYXZlbiAyIChodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy8pIGJ1aWxkCitlbnZpcm9ubWVudC4gSXQgcmVxdWlyZXMgYSBKYXZhIDUgSkRLIChvciBoaWdoZXIpIGFuZCBNYXZlbiAoaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvKQorMi4wLjcgb3IgbGF0ZXIuIFdlIHJlY29tbWVuZCB0byB1c2UgdGhlIGxhdGVzdCBNYXZlbiB2ZXJzaW9uLgorCitJZiB5b3UgaGF2ZSBNYXZlbiAyIGluc3RhbGxlZCwgeW91IGNhbiBjb21waWxlIGFuZAorcGFja2FnZSB0aGUgamFyIHVzaW5nIHRoZSBmb2xsb3dpbmcgY29tbWFuZDoKKworICAgIG12biBwYWNrYWdlCisKK1NlZSB0aGUgTWF2ZW4gMiBkb2N1bWVudGF0aW9uIGZvciBvdGhlciBidWlsZCBmZWF0dXJlcy4KKworVGhlIGxhdGVzdCBzb3VyY2UgY29kZSBmb3IgdGhpcyBjb21wb25lbnQgaXMgYXZhaWxhYmxlIGluIHRoZQorU3VidmVyc2lvbiAoaHR0cDovL3N1YnZlcnNpb24udGlncmlzLm9yZy8pIHNvdXJjZSByZXBvc2l0b3J5IG9mCit0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uIElmIHlvdSBoYXZlIFN1YnZlcnNpb24gaW5zdGFsbGVkLAoreW91IGNhbiBjaGVja291dCB0aGUgbGF0ZXN0IHNvdXJjZSB1c2luZyB0aGUgZm9sbG93aW5nIGNvbW1hbmQ6CisKKyAgICBzdm4gY2hlY2tvdXQgaHR0cDovL3N2bi5hcGFjaGUub3JnL3JlcG9zL2FzZi9pbmN1YmF0b3Ivc2xpbmcvdHJ1bmsvZXh0ZW5zaW9ucy9ldmVudAorCitTZWUgdGhlIFN1YnZlcnNpb24gZG9jdW1lbnRhdGlvbiBmb3Igb3RoZXIgc291cmNlIGNvbnRyb2wgZmVhdHVyZXMuCisKZGlmZiAtLWdpdCBhL3BvbS54bWwgYi9wb20ueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2YzVlYTYKLS0tIC9kZXYvbnVsbAorKysgYi9wb20ueG1sCkBAIC0wLDAgKzEsMTUxIEBACis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJJU08tODg1OS0xIj8+Cis8IS0tCisgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAgb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisKKyAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAgdW5kZXIgdGhlIExpY2Vuc2UuCistLT4KKzxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL21hdmVuLXY0XzBfMC54c2QiPgorCisgICAgPG1vZGVsVmVyc2lvbj40LjAuMDwvbW9kZWxWZXJzaW9uPgorICAgIDxwYXJlbnQ+CisgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUuc2xpbmc8L2dyb3VwSWQ+CisgICAgICAgIDxhcnRpZmFjdElkPnNsaW5nPC9hcnRpZmFjdElkPgorICAgICAgICA8dmVyc2lvbj41LWluY3ViYXRvcjwvdmVyc2lvbj4KKyAgICAgICAgPHJlbGF0aXZlUGF0aD4uLi8uLi8uLi9wYXJlbnQvcG9tLnhtbDwvcmVsYXRpdmVQYXRoPgorICAgIDwvcGFyZW50PgorCisgICAgPGFydGlmYWN0SWQ+b3JnLmFwYWNoZS5zbGluZy5ldmVudDwvYXJ0aWZhY3RJZD4KKyAgICA8cGFja2FnaW5nPmJ1bmRsZTwvcGFja2FnaW5nPgorICAgIDx2ZXJzaW9uPjIuMC40LWluY3ViYXRvcjwvdmVyc2lvbj4KKworICAgIDxuYW1lPkFwYWNoZSBTbGluZyBFdmVudCBTdXBwb3J0PC9uYW1lPgorICAgIDxkZXNjcmlwdGlvbj4KKyAgICAgICAgU3VwcG9ydCBmb3IgZXZlbnRpbmcuCisgICAgPC9kZXNjcmlwdGlvbj4KKworICAgIDxzY20+CisgICAgICAgIDxjb25uZWN0aW9uPnNjbTpzdm46aHR0cDovL3N2bi5hcGFjaGUub3JnL3JlcG9zL2FzZi9pbmN1YmF0b3Ivc2xpbmcvdGFncy9vcmcuYXBhY2hlLnNsaW5nLmV2ZW50LTIuMC40LWluY3ViYXRvcjwvY29ubmVjdGlvbj4KKyAgICAgICAgPGRldmVsb3BlckNvbm5lY3Rpb24+c2NtOnN2bjpodHRwczovL3N2bi5hcGFjaGUub3JnL3JlcG9zL2FzZi9pbmN1YmF0b3Ivc2xpbmcvdGFncy9vcmcuYXBhY2hlLnNsaW5nLmV2ZW50LTIuMC40LWluY3ViYXRvcjwvZGV2ZWxvcGVyQ29ubmVjdGlvbj4KKyAgICAgICAgPHVybD5odHRwOi8vc3ZuLmFwYWNoZS5vcmcvdmlld3ZjL2luY3ViYXRvci9zbGluZy90YWdzL29yZy5hcGFjaGUuc2xpbmcuZXZlbnQtMi4wLjQtaW5jdWJhdG9yPC91cmw+CisgICAgPC9zY20+CisKKyAgICA8YnVpbGQ+CisgICAgICAgIDxwbHVnaW5zPgorICAgICAgICAgICAgPHBsdWdpbj4KKyAgICAgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLmZlbGl4PC9ncm91cElkPgorICAgICAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLXNjci1wbHVnaW48L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8L3BsdWdpbj4KKyAgICAgICAgICAgIDxwbHVnaW4+CisgICAgICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5mZWxpeDwvZ3JvdXBJZD4KKyAgICAgICAgICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1idW5kbGUtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgICAgIDxleHRlbnNpb25zPnRydWU8L2V4dGVuc2lvbnM+CisgICAgICAgICAgICAgICAgPGNvbmZpZ3VyYXRpb24+CisgICAgICAgICAgICAgICAgICAgIDxpbnN0cnVjdGlvbnM+CisgICAgICAgICAgICAgICAgICAgICAgICA8RXhwb3J0LVBhY2thZ2U+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLmFwYWNoZS5zbGluZy5ldmVudDt2ZXJzaW9uPSR7cG9tLnZlcnNpb259CisgICAgICAgICAgICAgICAgICAgICAgICA8L0V4cG9ydC1QYWNrYWdlPgorICAgICAgICAgICAgICAgICAgICAgICAgPFByaXZhdGUtUGFja2FnZT4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LmltcGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLmFwYWNoZS5qYWNrcmFiYml0LnV0aWwKKyAgICAgICAgICAgICAgICAgICAgICAgIDwvUHJpdmF0ZS1QYWNrYWdlPgorICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBXZSBuZWVkIHRoZSBkeW5hbWljIGltcG9ydCBhcyBldmVudHMgY2FuIGNvbnRhaW4gYW55IGNsYXNzZXMgLS0+CisgICAgICAgICAgICAgICAgICAgICAgICA8RHluYW1pY0ltcG9ydC1QYWNrYWdlPio8L0R5bmFtaWNJbXBvcnQtUGFja2FnZT4KKyAgICAgICAgICAgICAgICAgICAgICAgIDxTbGluZy1Ob2RldHlwZXM+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0xJTkctSU5GL25vZGV0eXBlcy9ldmVudC5jbmQKKyAgICAgICAgICAgICAgICAgICAgICAgIDwvU2xpbmctTm9kZXR5cGVzPgorICAgICAgICAgICAgICAgICAgICAgICAgPFNsaW5nLU5hbWVzcGFjZXM+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2xpbmdldmVudD1odHRwOi8vc2xpbmcuYXBhY2hlLm9yZy9qY3IvZXZlbnQvMS4wCisgICAgICAgICAgICAgICAgICAgICAgICA8L1NsaW5nLU5hbWVzcGFjZXM+CisgICAgICAgICAgICAgICAgICAgIDwvaW5zdHJ1Y3Rpb25zPgorICAgICAgICAgICAgICAgIDwvY29uZmlndXJhdGlvbj4KKyAgICAgICAgICAgIDwvcGx1Z2luPgorICAgICAgICA8L3BsdWdpbnM+CisgICAgPC9idWlsZD4KKyAgICA8cmVwb3J0aW5nPgorICAgICAgICA8cGx1Z2lucz4KKyAgICAgICAgICAgIDxwbHVnaW4+CisgICAgICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5tYXZlbi5wbHVnaW5zPC9ncm91cElkPgorICAgICAgICAgICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWphdmFkb2MtcGx1Z2luPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgICAgIDxjb25maWd1cmF0aW9uPgorICAgICAgICAgICAgICAgICAgICA8ZXhjbHVkZVBhY2thZ2VOYW1lcz4KKyAgICAgICAgICAgICAgICAgICAgICAgIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbAorICAgICAgICAgICAgICAgICAgICA8L2V4Y2x1ZGVQYWNrYWdlTmFtZXM+CisgICAgICAgICAgICAgICAgPC9jb25maWd1cmF0aW9uPgorICAgICAgICAgICAgPC9wbHVnaW4+CisgICAgICAgIDwvcGx1Z2lucz4KKyAgICA8L3JlcG9ydGluZz4KKyAgICA8ZGVwZW5kZW5jaWVzPgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUuZmVsaXg8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5vcmcub3NnaS5jb3JlPC9hcnRpZmFjdElkPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5mZWxpeDwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm9yZy5vc2dpLmNvbXBlbmRpdW08L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5qYXZheC5qY3I8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5qY3I8L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLnNsaW5nPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+b3JnLmFwYWNoZS5zbGluZy5hcGk8L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4yLjAuMi1pbmN1YmF0b3I8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLnNsaW5nPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+b3JnLmFwYWNoZS5zbGluZy5lbmdpbmU8L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4yLjAuMi1pbmN1YmF0b3I8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLnNsaW5nPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+b3JnLmFwYWNoZS5zbGluZy5qY3IuYXBpPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+Mi4wLjItaW5jdWJhdG9yPC92ZXJzaW9uPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5zbGluZzwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm9yZy5hcGFjaGUuc2xpbmcuamNyLnJlc291cmNlPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+Mi4wLjQtaW5jdWJhdG9yPC92ZXJzaW9uPgorICAgICAgICA8L2RlcGVuZGVuY3k+CisgICAgICAgIDxkZXBlbmRlbmN5PgorICAgICAgICAgICAgPGdyb3VwSWQ+b3JnLmFwYWNoZS5zbGluZzwvZ3JvdXBJZD4KKyAgICAgICAgICAgIDxhcnRpZmFjdElkPm9yZy5hcGFjaGUuc2xpbmcuY29tbW9ucy5zY2hlZHVsZXI8L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4yLjAuMi1pbmN1YmF0b3I8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLnNsaW5nPC9ncm91cElkPgorICAgICAgICAgICAgPGFydGlmYWN0SWQ+b3JnLmFwYWNoZS5zbGluZy5jb21tb25zLnRocmVhZHM8L2FydGlmYWN0SWQ+CisgICAgICAgICAgICA8dmVyc2lvbj4yLjAuMi1pbmN1YmF0b3I8L3ZlcnNpb24+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuc2xmNGo8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5zbGY0ai1hcGk8L2FydGlmYWN0SWQ+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPGRlcGVuZGVuY3k+CisgICAgICAgICAgICA8Z3JvdXBJZD5vcmcuYXBhY2hlLmphY2tyYWJiaXQ8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5qYWNrcmFiYml0LWpjci1jb21tb25zPC9hcnRpZmFjdElkPgorICAgICAgICAgICAgPHZlcnNpb24+MS40LjI8L3ZlcnNpb24+CisgICAgICAgICAgICA8c2NvcGU+Y29tcGlsZTwvc2NvcGU+CisgICAgICAgIDwvZGVwZW5kZW5jeT4KKyAgICAgICAgPCEtLSBUZXN0aW5nIC0tPgorICAgICAgICA8ZGVwZW5kZW5jeT4KKyAgICAgICAgICAgIDxncm91cElkPm9yZy5hcGFjaGUuc2xpbmc8L2dyb3VwSWQ+CisgICAgICAgICAgICA8YXJ0aWZhY3RJZD5vcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMudGVzdGluZzwvYXJ0aWZhY3RJZD4KKyAgICAgICAgICAgIDx2ZXJzaW9uPjIuMC40LWluY3ViYXRvcjwvdmVyc2lvbj4KKyAgICAgICAgICAgIDxzY29wZT50ZXN0PC9zY29wZT4KKyAgICAgICAgPC9kZXBlbmRlbmN5PgorICAgIDwvZGVwZW5kZW5jaWVzPgorPC9wcm9qZWN0PgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L0V2ZW50UHJvcGVydGllc01hcC5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L0V2ZW50UHJvcGVydGllc01hcC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2OWRjNGIKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvRXZlbnRQcm9wZXJ0aWVzTWFwLmphdmEKQEAgLTAsMCArMSwxOTMgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkRpY3Rpb25hcnk7CitpbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKKworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuZXZlbnQuRXZlbnQ7CisKKy8qKgorICogQW4gaW1wbGVtZW50YXRpb24gb2YgYSBtYXAgdGhhdCBoZWxwcyBpbiBkZWFsaW5nIHdpdGggcHJvcGVydGllcworICogb2YgYW4gT1NHaSBldmVudC4KKyAqIFRoaXMgbWFwIGltcGxlbWVudHMgYm90aCwgdGhlIG1hcCBhbmQgdGhlIGRpY3Rpb25hcnkgaW50ZXJmYWNlcy4KKyAqLworcHVibGljIGNsYXNzIEV2ZW50UHJvcGVydGllc01hcAorICAgIGV4dGVuZHMgRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4KKyAgICBpbXBsZW1lbnRzIE1hcDxTdHJpbmcsIE9iamVjdD4sIFNlcmlhbGl6YWJsZSB7CisKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIE9iamVjdD4gZGVsZWdhdGVlOworCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbmV3IG1hcCBvdXQgb2YgYW4gZXZlbnQgb2JqZWN0LgorICAgICAqIFRoZSByZXN1bHRpbmcgbWFwIGlzIG1vZGlmaWFibGUuIEJ1dCBhbnkgbW9kaWZpY2F0aW9uIGhhcworICAgICAqIG5vIGluZmx1ZW5jZSBvbiB0aGUgb3JpZ2luYWwgcHJvcGVydGllcyBvZiB0aGUgZXZlbnQhCisgICAgICogQHBhcmFtIGV2ZW50IFRoZSBldmVudCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIEV2ZW50UHJvcGVydGllc01hcChmaW5hbCBFdmVudCBldmVudCkgeworICAgICAgICAvLyBjcmVhdGUgYSBtYXAgb3V0IG9mIHRoZSBldmVudCBwcm9wZXJ0aWVzCisgICAgICAgIGZpbmFsIE1hcDxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIE9iamVjdD4oKTsKKyAgICAgICAgaWYgKCBldmVudC5nZXRQcm9wZXJ0eU5hbWVzKCkgIT0gbnVsbCApIHsKKyAgICAgICAgICAgIGZvcihmaW5hbCBTdHJpbmcga2V5IDogZXZlbnQuZ2V0UHJvcGVydHlOYW1lcygpICkgeworICAgICAgICAgICAgICAgIHByb3BzLnB1dChrZXksIGV2ZW50LmdldFByb3BlcnR5KGtleSkpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMuZGVsZWdhdGVlID0gcHJvcHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbmV3IG1hcCBvdXQgb2YgYW5vdGhlciBtYXAuCisgICAgICogQHBhcmFtIHByb3BzIFRoZSBwcm9wZXJ0aWVzIG1hcCBvYmplY3QuCisgICAgICovCisgICAgcHVibGljIEV2ZW50UHJvcGVydGllc01hcChmaW5hbCBNYXA8U3RyaW5nLCBPYmplY3Q+IHByb3BzKSB7CisgICAgICAgIHRoaXMuZGVsZWdhdGVlID0gcHJvcHM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQ29uc3RydWN0IGEgbmV3IG1hcC4KKyAgICAgKi8KKyAgICBwdWJsaWMgRXZlbnRQcm9wZXJ0aWVzTWFwKCkgeworICAgICAgICB0aGlzLmRlbGVnYXRlZSA9IG5ldyBIYXNoTWFwPFN0cmluZywgT2JqZWN0PigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS51dGlsLk1hcCNjbGVhcigpCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2xlYXIoKSB7CisgICAgICAgIGRlbGVnYXRlZS5jbGVhcigpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS51dGlsLk1hcCNjb250YWluc0tleShqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlZS5jb250YWluc0tleShrZXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS51dGlsLk1hcCNjb250YWluc1ZhbHVlKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlZS5jb250YWluc1ZhbHVlKHZhbHVlKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEudXRpbC5NYXAjZW50cnlTZXQoKQorICAgICAqLworICAgIHB1YmxpYyBTZXQ8amF2YS51dGlsLk1hcC5FbnRyeTxTdHJpbmcsIE9iamVjdD4+IGVudHJ5U2V0KCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGVlLmVudHJ5U2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I2VxdWFscyhqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgeworICAgICAgICByZXR1cm4gZGVsZWdhdGVlLmVxdWFscyhvKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEudXRpbC5EaWN0aW9uYXJ5I2dldChqYXZhLmxhbmcuT2JqZWN0KQorICAgICAqLworICAgIHB1YmxpYyBPYmplY3QgZ2V0KE9iamVjdCBrZXkpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlZS5nZXQoa2V5KTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjaGFzaENvZGUoKQorICAgICAqLworICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZWUuaGFzaENvZGUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEudXRpbC5EaWN0aW9uYXJ5I2lzRW1wdHkoKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZWUuaXNFbXB0eSgpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS51dGlsLk1hcCNrZXlTZXQoKQorICAgICAqLworICAgIHB1YmxpYyBTZXQ8U3RyaW5nPiBrZXlTZXQoKSB7CisgICAgICAgIHJldHVybiBkZWxlZ2F0ZWUua2V5U2V0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnV0aWwuRGljdGlvbmFyeSNwdXQoamF2YS5sYW5nLk9iamVjdCwgamF2YS5sYW5nLk9iamVjdCkKKyAgICAgKi8KKyAgICBwdWJsaWMgT2JqZWN0IHB1dChTdHJpbmcga2V5LCBPYmplY3QgdmFsdWUpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlZS5wdXQoa2V5LCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZhLnV0aWwuTWFwI3B1dEFsbChqYXZhLnV0aWwuTWFwKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHB1dEFsbChNYXA8PyBleHRlbmRzIFN0cmluZywgPyBleHRlbmRzIE9iamVjdD4gdCkgeworICAgICAgICBkZWxlZ2F0ZWUucHV0QWxsKHQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS51dGlsLkRpY3Rpb25hcnkjcmVtb3ZlKGphdmEubGFuZy5PYmplY3QpCisgICAgICovCisgICAgcHVibGljIE9iamVjdCByZW1vdmUoT2JqZWN0IGtleSkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGVlLnJlbW92ZShrZXkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS51dGlsLkRpY3Rpb25hcnkjc2l6ZSgpCisgICAgICovCisgICAgcHVibGljIGludCBzaXplKCkgeworICAgICAgICByZXR1cm4gZGVsZWdhdGVlLnNpemUoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEudXRpbC5NYXAjdmFsdWVzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxPYmplY3Q+IHZhbHVlcygpIHsKKyAgICAgICAgcmV0dXJuIGRlbGVnYXRlZS52YWx1ZXMoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIGphdmEudXRpbC5EaWN0aW9uYXJ5I2VsZW1lbnRzKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgRW51bWVyYXRpb248T2JqZWN0PiBlbGVtZW50cygpIHsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVudW1lcmF0aW9uKHRoaXMudmFsdWVzKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS51dGlsLkRpY3Rpb25hcnkja2V5cygpCisgICAgICovCisgICAgcHVibGljIEVudW1lcmF0aW9uPFN0cmluZz4ga2V5cygpIHsKKyAgICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVudW1lcmF0aW9uKHRoaXMua2V5U2V0KCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YS5sYW5nLk9iamVjdCN0b1N0cmluZygpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZGVsZWdhdGVlLnRvU3RyaW5nKCk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L0V2ZW50VXRpbC5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L0V2ZW50VXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwM2QxOGUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvRXZlbnRVdGlsLmphdmEKQEAgLTAsMCArMSw2MTUgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PYmplY3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk9iamVjdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5EaWN0aW9uYXJ5OworaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCitpbXBvcnQgamF2YXguamNyLk5vZGU7CitpbXBvcnQgamF2YXguamNyLlByb3BlcnR5OworaW1wb3J0IGphdmF4Lmpjci5Qcm9wZXJ0eUl0ZXJhdG9yOworaW1wb3J0IGphdmF4Lmpjci5Qcm9wZXJ0eVR5cGU7CitpbXBvcnQgamF2YXguamNyLlJlcG9zaXRvcnlFeGNlcHRpb247CitpbXBvcnQgamF2YXguamNyLlZhbHVlOworaW1wb3J0IGphdmF4Lmpjci5WYWx1ZUZhY3Rvcnk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmphY2tyYWJiaXQudXRpbC5JU085MDc1OworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuRXZlbnRVdGlsLkpvYlN0YXR1c05vdGlmaWVyLk5vdGlmaWVyQ29udGV4dDsKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LmltcGwuQWJzdHJhY3RSZXBvc2l0b3J5RXZlbnRIYW5kbGVyOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbC5Kb2JFdmVudEhhbmRsZXI7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudDsKK2ltcG9ydCBvcmcuc2xmNGouTG9nZ2VyRmFjdG9yeTsKKworLyoqCisgKiBUaGUgPGNvZGU+RXZlbnRVdGlsPC9jb2RlPiBjbGFzcyBpcyBhbiB1dGlsaXR5IGNsYXNzIGZvcgorICogY2x1c3RlcmVkIGVudmlyb25tZW50cy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEV2ZW50VXRpbCB7CisKKyAgICAvKiogVGhpcyBldmVudCBwcm9wZXJ0eSBpbmRpY2F0ZXMsIGlmIHRoZSBldmVudCBzaG91bGQgYmUgZGlzdHJpYnV0ZWQgaW4gdGhlIGNsdXN0ZXIgKGRlZmF1bHQgZmFsc2UpLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX0RJU1RSSUJVVEUgPSAiZXZlbnQuZGlzdHJpYnV0ZSI7CisKKyAgICAvKiogVGhpcyBldmVudCBwcm9wZXJ0eSBzcGVjaWZpZXMgdGhlIGFwcGxpY2F0aW9uIG5vZGUuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPUEVSVFlfQVBQTElDQVRJT04gPSAiZXZlbnQuYXBwbGljYXRpb24iOworCisgICAgLyoqCisgICAgICogSm9iIEhhbmRsaW5nCisgICAgICovCisKKyAgICAvKiogVGhlIGpvYiB0b3BpYyBwcm9wZXJ0eS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWV9KT0JfVE9QSUMgPSAiZXZlbnQuam9iLnRvcGljIjsKKworICAgIC8qKiBUaGUgcHJvcGVydHkgZm9yIHRoZSB1bmlxdWUgZXZlbnQgaWQuIFZhbHVlIGlzIG9mIHR5cGUgU3RyaW5nLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX0pPQl9JRCA9ICJldmVudC5qb2IuaWQiOworCisgICAgLyoqIFRoZSBwcm9wZXJ0eSB0byBzZXQgaWYgYSBqb2IgY2FuIGJlIHJ1biBwYXJhbGxlbCB0byBhbnkgb3RoZXIgam9iLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX0pPQl9QQVJBTExFTCA9ICJldmVudC5qb2IucGFyYWxsZWwiOworCisgICAgLyoqIFRoZSBwcm9wZXJ0eSB0byBzZXQgaWYgYSBqb2Igc2hvdWxkIG9ubHkgYmUgcnVuIG9uIHRoZSBzYW1lIGFwcCBpdCBoYXMgYmVlbiBjcmVhdGVkLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX0pPQl9SVU5fTE9DQUwgPSAiZXZlbnQuam9iLnJ1bi5sb2NhbCI7CisKKyAgICAvKiogVGhlIHByb3BlcnR5IHRvIHRyYWNrIHRoZSByZXRyeSBjb3VudCBmb3Igam9icy4gVmFsdWUgaXMgb2YgdHlwZSBJbnRlZ2VyLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX0pPQl9SRVRSWV9DT1VOVCA9ICJldmVudC5qb2IucmV0cnljb3VudCI7CisKKyAgICAvKiogVGhlIHByb3BlcnR5IHRvIGZvciBzZXR0aW5nIHRoZSBtYXhpbXVtIG51bWJlciBvZiByZXRyaWVzLiBWYWx1ZSBpcyBvZiB0eXBlIEludGVnZXIuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPUEVSVFlfSk9CX1JFVFJJRVMgPSAiZXZlbnQuam9iLnJldHJpZXMiOworCisgICAgLyoqIFRoZSBwcm9wZXJ0eSB0byBzZXQgYSByZXRyeSBkZWxheS4gVmFsdWUgaXMgb2YgdHlwZSBMb25nIGFuZCBzcGVjaWZpZXMgbWlsbGlzZWNvbmRzLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX0pPQl9SRVRSWV9ERUxBWSA9ICJldmVudC5qb2IucmV0cnlkZWxheSI7CisKKyAgICAvKiogVGhlIHByb3BlcnR5IHRvIHNldCB0byBwdXQgdGhlIGpvYnMgaW50byBhIHNlcGFyYXRlIGpvYiBxdWV1ZS4gVGhpcyBwcm9wZXJ0eQorICAgICAqIHNwY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBqb2IgcXVldWUuIElmIHRoZSBqb2IgcXVldWUgZG9lcyBub3QgZXhpc3RzIHlldAorICAgICAqIGEgbmV3IHF1ZXVlIGlzIGNyZWF0ZWQuCisgICAgICogSWYgYSBqb2IgcXVldWUgaXMgdXNlZCwgdGhlIGpvYnMgYXJlIG5ldmVyIGV4ZWN1dGVkIGluIHBhcmFsbGVsIGZyb20gdGhpcyBxdWV1ZSEKKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWV9KT0JfUVVFVUVfTkFNRSA9ICJldmVudC5qb2IucXVldWVuYW1lIjsKKworICAgIC8qKiBJZiB0aGlzIHByb3BlcnR5IGlzIHNldCB3aXRoIGFueSB2YWx1ZSwgdGhlIHF1ZXVlIHByb2Nlc3NlcyB0aGUgam9icyBpbiB0aGUgc2FtZQorICAgICAqIG9yZGVyIGFzIHRoZXkgaGF2ZSBhcnJpdmVkLgorICAgICAqIFRoaXMgcHJvcGVydHkgaGFzIG9ubHkgYW4gZWZmZWN0IGlmIHtAbGluayAjUFJPUEVSVFlfSk9CX1FVRVVFX05BTUV9IGlzIHNwZWNpZmllZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWV9KT0JfUVVFVUVfT1JERVJFRCA9ICJldmVudC5qb2IucXVldWVvcmRlcmVkIjsKKworICAgIC8qKiBUaGUgdG9waWMgZm9yIGpvYnMuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVE9QSUNfSk9CID0gIm9yZy9hcGFjaGUvc2xpbmcvZXZlbnQvam9iIjsKKworICAgIC8qKgorICAgICAqIFRpbWVkIEV2ZW50cworICAgICAqLworCisgICAgLyoqIFRoZSB0b3BpYyBmb3IgdGltZWQgZXZlbnRzLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRPUElDX1RJTUVEX0VWRU5UID0gIm9yZy9hcGFjaGUvc2xpbmcvZXZlbnQvdGltZWQiOworCisgICAgLyoqIFRoZSByZWFsIHRvcGljIG9mIHRoZSBldmVudC4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWV9USU1FRF9FVkVOVF9UT1BJQyA9ICJldmVudC50b3BpYy50aW1lZCI7CisKKyAgICAvKiogVGhlIHByb3BlcnR5IGZvciB0aGUgdW5pcXVlIGV2ZW50IGlkLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX1RJTUVEX0VWRU5UX0lEID0gImV2ZW50LnRpbWVkLmlkIjsKKworICAgIC8qKiBUaGUgc2NoZWR1bGVyIGV4cHJlc3Npb24gZm9yIHRoZSB0aW1lZCBldmVudC4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWV9USU1FRF9FVkVOVF9TQ0hFRFVMRSA9ICJldmVudC50aW1lZC5zY2hlZHVsZXIiOworCisgICAgLyoqIFRoZSBwZXJpb2QgZm9yIHRoZSB0aW1lZCBldmVudC4gKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWV9USU1FRF9FVkVOVF9QRVJJT0QgPSAiZXZlbnQudGltZWQucGVyaW9kIjsKKworICAgIC8qKiBUaGUgZGF0ZSBmb3IgdGhlIHRpbWVkIGV2ZW50LiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX1RJTUVEX0VWRU5UX0RBVEUgPSAiZXZlbnQudGltZWQuZGF0ZSI7CisKKyAgICAvKioKKyAgICAgKiBVdGlsaXR5IE1ldGhvZHMKKyAgICAgKi8KKworICAgIC8qKgorICAgICAqIENyZWF0ZSBhIGRpc3RyaWJ1dGFibGUgZXZlbnQuCisgICAgICogQSBkaXN0cmlidXRhYmxlIGV2ZW50IGlzIGRpc3RyaWJ1dGVkIGFjcm9zcyB0aGUgY2x1c3Rlci4KKyAgICAgKiBAcGFyYW0gdG9waWMKKyAgICAgKiBAcGFyYW0gcHJvcGVydGllcworICAgICAqIEByZXR1cm4gQW4gT1NHaSBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIEV2ZW50IGNyZWF0ZURpc3RyaWJ1dGFibGVFdmVudChTdHJpbmcgdG9waWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcGVydGllcykgeworICAgICAgICBmaW5hbCBEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBuZXdQcm9wZXJ0aWVzOworICAgICAgICAvLyBjcmVhdGUgYSBuZXcgZGljdGlvbmFyeQorICAgICAgICBuZXdQcm9wZXJ0aWVzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKKyAgICAgICAgaWYgKCBwcm9wZXJ0aWVzICE9IG51bGwgKSB7CisgICAgICAgICAgICBmaW5hbCBFbnVtZXJhdGlvbjxTdHJpbmc+IGUgPSBwcm9wZXJ0aWVzLmtleXMoKTsKKyAgICAgICAgICAgIHdoaWxlICggZS5oYXNNb3JlRWxlbWVudHMoKSApIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcga2V5ID0gZS5uZXh0RWxlbWVudCgpOworICAgICAgICAgICAgICAgIG5ld1Byb3BlcnRpZXMucHV0KGtleSwgcHJvcGVydGllcy5nZXQoa2V5KSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gZm9yIG5vdyB0aGUgdmFsdWUgaGFzIG5vIG1lYW5pbmcsIHNvIHdlIGp1c3QgcHV0IGFuIGVtcHR5IHN0cmluZyBpbiBpdC4KKyAgICAgICAgbmV3UHJvcGVydGllcy5wdXQoUFJPUEVSVFlfRElTVFJJQlVURSwgIiIpOworICAgICAgICByZXR1cm4gbmV3IEV2ZW50KHRvcGljLCBuZXdQcm9wZXJ0aWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTaG91bGQgdGhpcyBldmVudCBiZSBkaXN0cmlidXRlZCBpbiB0aGUgY2x1c3Rlcj8KKyAgICAgKiBAcGFyYW0gZXZlbnQKKyAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBldmVudCBzaG91bGQgYmUgZGlzdHJpYnV0ZWQuCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIHNob3VsZERpc3RyaWJ1dGUoRXZlbnQgZXZlbnQpIHsKKyAgICAgICAgcmV0dXJuIGV2ZW50LmdldFByb3BlcnR5KFBST1BFUlRZX0RJU1RSSUJVVEUpICE9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogSXMgdGhpcyBhIGxvY2FsIGV2ZW50PworICAgICAqIEBwYXJhbSBldmVudAorICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhpcyBpcyBhIGxvY2FsIGV2ZW50CisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzTG9jYWwoRXZlbnQgZXZlbnQpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGFwcElkID0gZ2V0QXBwbGljYXRpb25JZChldmVudCk7CisgICAgICAgIHJldHVybiBhcHBJZCA9PSBudWxsIHx8IGFwcElkLmVxdWFscyhBYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXIuQVBQTElDQVRJT05fSUQpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgYXBwbGljYXRpb24gaWQgdGhlIGV2ZW50IHdhcyBjcmVhdGVkIGF0LgorICAgICAqIEBwYXJhbSBldmVudAorICAgICAqIEByZXR1cm4gVGhlIGFwcGxpY2F0aW9uIGlkIG9yIG51bGwgaWYgdGhlIGV2ZW50IGhhcyBiZWVuIGNyZWF0ZWQgbG9jYWxseS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRBcHBsaWNhdGlvbklkKEV2ZW50IGV2ZW50KSB7CisgICAgICAgIHJldHVybiAoU3RyaW5nKWV2ZW50LmdldFByb3BlcnR5KFBST1BFUlRZX0FQUExJQ0FUSU9OKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJcyB0aGlzIGEgam9iIGV2ZW50PworICAgICAqIFRoaXMgbWV0aG9kIGNoZWNrcyBpZiB0aGUgZXZlbnQgY29udGFpbnMgdGhlIHtAbGluayAjUFJPUEVSVFlfSk9CX1RPUElDfQorICAgICAqIHByb3BlcnR5LgorICAgICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgdG8gY2hlY2suCisgICAgICogQHJldHVybiA8Y29kZT50cnVlPjwvY29kZT4gaWYgdGhpcyBpcyBhIGpvYiBldmVudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNKb2JFdmVudChFdmVudCBldmVudCkgeworICAgICAgICByZXR1cm4gZXZlbnQuZ2V0UHJvcGVydHkoUFJPUEVSVFlfSk9CX1RPUElDKSAhPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIHRoaXMgYSBqb2IgZXZlbnQgYW5kIHJldHVybiB0aGUgbm90aWZpZXIgY29udGV4dC4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgZXZlbnQgaXMgYSBqb2IgZXZlbnQgYnV0IGRvZXMgbm90IGhhdmUgYSBub3RpZmllciBjb250ZXh0LgorICAgICAqLworICAgIHByaXZhdGUgc3RhdGljIEpvYlN0YXR1c05vdGlmaWVyLk5vdGlmaWVyQ29udGV4dCBnZXROb3RpZmllckNvbnRleHQoZmluYWwgRXZlbnQgam9iKSB7CisgICAgICAgIC8vIGNoZWNrIGlmIHRoaXMgaXMgYSBqb2IgZXZlbnQKKyAgICAgICAgaWYgKCAhaXNKb2JFdmVudChqb2IpICkgeworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgSm9iU3RhdHVzTm90aWZpZXIuTm90aWZpZXJDb250ZXh0IGN0eCA9IChOb3RpZmllckNvbnRleHQpIGpvYi5nZXRQcm9wZXJ0eShKb2JTdGF0dXNOb3RpZmllci5DT05URVhUX1BST1BFUlRZX05BTUUpOworICAgICAgICBpZiAoIGN0eCA9PSBudWxsICkgeworICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSm9iU3RhdHVzTm90aWZpZXIgY29udGV4dCBpcyBub3QgYXZhaWxhYmxlIGluIGV2ZW50IHByb3BlcnRpZXMuIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGN0eDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3RpZnkgYSBmaW5pc2hlZCBqb2IuCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gSWYgdGhlIGV2ZW50IGlzIGEgam9iIGV2ZW50IGJ1dCBkb2VzIG5vdCBoYXZlIGEgbm90aWZpZXIgY29udGV4dC4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgZmluaXNoZWRKb2IoRXZlbnQgam9iKSB7CisgICAgICAgIGZpbmFsIEpvYlN0YXR1c05vdGlmaWVyLk5vdGlmaWVyQ29udGV4dCBjdHggPSBnZXROb3RpZmllckNvbnRleHQoam9iKTsKKyAgICAgICAgaWYgKCBjdHggIT0gbnVsbCApIHsKKyAgICAgICAgICAgIGN0eC5ub3RpZmllci5maW5pc2hlZEpvYihqb2IsIGN0eC5ldmVudE5vZGVQYXRoLCBmYWxzZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBOb3RpZnkgYSBmYWlsZWQgam9iLgorICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGpvYiBoYXMgYmVlbiByZXNjaGVkdWxlZCwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KKyAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBJZiB0aGUgZXZlbnQgaXMgYSBqb2IgZXZlbnQgYnV0IGRvZXMgbm90IGhhdmUgYSBub3RpZmllciBjb250ZXh0LgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiByZXNjaGVkdWxlSm9iKEV2ZW50IGpvYikgeworICAgICAgICBmaW5hbCBKb2JTdGF0dXNOb3RpZmllci5Ob3RpZmllckNvbnRleHQgY3R4ID0gZ2V0Tm90aWZpZXJDb250ZXh0KGpvYik7CisgICAgICAgIGlmICggY3R4ICE9IG51bGwgKSB7CisgICAgICAgICAgIHJldHVybiBjdHgubm90aWZpZXIuZmluaXNoZWRKb2Ioam9iLCBjdHguZXZlbnROb2RlUGF0aCwgdHJ1ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFByb2Nlc3MgYSBqb2IgaW4gdGhlIGJhY2tncm91bmQgYW5kIG5vdGlmeSBpdHMgc3VjY2Vzcy4KKyAgICAgKiBUaGlzIG1ldGhvZCBhbHNvIHNlbmRzIGFuIGFja25vd2xlZGdlIG1lc3NhZ2UgdG8gdGhlIGpvYiBldmVudCBoYW5kbGVyLgorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBwcm9jZXNzSm9iKGZpbmFsIEV2ZW50IGpvYiwgZmluYWwgSm9iUHJvY2Vzc29yIHByb2Nlc3NvcikgeworICAgICAgICAvLyBmaXJzdCBjaGVjayBmb3IgYSBub3RpZmllciBjb250ZXh0IHRvIHNlbmQgYW4gYWNrbm93bGVkZ2UKKyAgICAgICAgYm9vbGVhbiBub3RpZnkgPSB0cnVlOworICAgICAgICBmaW5hbCBKb2JTdGF0dXNOb3RpZmllci5Ob3RpZmllckNvbnRleHQgY3R4ID0gZ2V0Tm90aWZpZXJDb250ZXh0KGpvYik7CisgICAgICAgIGlmICggY3R4ICE9IG51bGwgKSB7CisgICAgICAgICAgICBpZiAoICFjdHgubm90aWZpZXIuc2VuZEFja25vd2xlZGdlKGpvYiwgY3R4LmV2ZW50Tm9kZVBhdGgpICkgeworICAgICAgICAgICAgICAgIC8vIGlmIHdlIGRvbid0IGdldCBhbiBhY2ssIHNvbWVvbmUgZWxzZSBpcyBhbHJlYWR5IHByb2Nlc3NpbmcgdGhpcyBqb2IuCisgICAgICAgICAgICAgICAgLy8gd2UgcHJvY2VzcyBidXQgZG8gbm90IG5vdGlmeSB0aGUgam9iIGV2ZW50IGhhbmRsZXIuCisgICAgICAgICAgICAgICAgTG9nZ2VyRmFjdG9yeS5nZXRMb2dnZXIoRXZlbnRVdGlsLmNsYXNzKS5pbmZvKCJTb21lb25lIGVsc2UgaXMgYWxyZWFkeSBwcm9jZXNzaW5nIGpvYiB7fS4iLCBqb2IpOworICAgICAgICAgICAgICAgIG5vdGlmeSA9IGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZpbmFsIGJvb2xlYW4gbm90aWZ5UmVzdWx0ID0gbm90aWZ5OworCisgICAgICAgIGZpbmFsIFJ1bm5hYmxlIHRhc2sgPSBuZXcgUnVubmFibGUoKSB7CisKKyAgICAgICAgICAgIC8qKgorICAgICAgICAgICAgICogQHNlZSBqYXZhLmxhbmcuUnVubmFibGUjcnVuKCkKKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIGJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcHJvY2Vzc29yLnByb2Nlc3Moam9iKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgICAgICAgICBMb2dnZXJGYWN0b3J5LmdldExvZ2dlcihFdmVudFV0aWwuY2xhc3MpLmVycm9yKCJVbmhhbmRsZWQgZXJyb3Igb2NjdXJlZCBpbiBqb2IgcHJvY2Vzc29yICIgKyB0LmdldE1lc3NhZ2UoKSArICIgd2hpbGUgcHJvY2Vzc2luZyBqb2IgIiArIGpvYiwgdCk7CisgICAgICAgICAgICAgICAgICAgIC8vIHdlIGRvbid0IHJlc2NoZWR1bGUgaWYgYW4gZXhjZXB0aW9uIG9jY3VycworICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0cnVlOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgIGlmICggbm90aWZ5UmVzdWx0ICkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCByZXN1bHQgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXZlbnRVdGlsLmZpbmlzaGVkSm9iKGpvYik7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV2ZW50VXRpbC5yZXNjaGVkdWxlSm9iKGpvYik7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgfTsKKyAgICAgICAgLy8gY2hlY2sgaWYgdGhlIGpvYiBoYW5kbGVyIHRocmVhZCBwb29sIGlzIGF2YWlsYWJsZQorICAgICAgICBpZiAoIEpvYkV2ZW50SGFuZGxlci5KT0JfVEhSRUFEX1BPT0wgIT0gbnVsbCApIHsKKyAgICAgICAgICAgIEpvYkV2ZW50SGFuZGxlci5KT0JfVEhSRUFEX1BPT0wuZXhlY3V0ZSh0YXNrKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGlmIHdlIGRvbid0IGhhdmUgYSB0aHJlYWQgcG9vbCwgd2UgY3JlYXRlIHRoZSB0aHJlYWQgZGlyZWN0bHkKKyAgICAgICAgICAgIC8vICh0aGlzIHNob3VsZCBuZXZlciBoYXBwZW4gZm9yIGpvYnMsIGJ1dCBpcyBhIHNhZmUgZmFsbGJhY2sgYW5kCisgICAgICAgICAgICAvLyBhbGxvd3MgdG8gY2FsbCB0aGlzIG1ldGhvZCBmb3Igb3RoZXIgYmFja2dyb3VuZCBwcm9jZXNzaW5nLgorICAgICAgICAgICAgbmV3IFRocmVhZCh0YXNrKS5zdGFydCgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBpcyBhIHByaXZhdGUgaW50ZXJmYWNlIHdoaWNoIGlzIG9ubHkgcHVibGljIGZvciBpbXBvcnQgcmVhc29ucy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIGludGVyZmFjZSBKb2JTdGF0dXNOb3RpZmllciB7CisKKyAgICAgICAgU3RyaW5nIENPTlRFWFRfUFJPUEVSVFlfTkFNRSA9IEpvYlN0YXR1c05vdGlmaWVyLmNsYXNzLmdldE5hbWUoKTsKKworICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5vdGlmaWVyQ29udGV4dCB7CisgICAgICAgICAgICBwdWJsaWMgZmluYWwgSm9iU3RhdHVzTm90aWZpZXIgbm90aWZpZXI7CisgICAgICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGV2ZW50Tm9kZVBhdGg7CisKKyAgICAgICAgICAgIHB1YmxpYyBOb3RpZmllckNvbnRleHQoSm9iU3RhdHVzTm90aWZpZXIgbiwgU3RyaW5nIHBhdGgpIHsKKyAgICAgICAgICAgICAgICB0aGlzLm5vdGlmaWVyID0gbjsKKyAgICAgICAgICAgICAgICB0aGlzLmV2ZW50Tm9kZVBhdGggPSBwYXRoOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyoqCisgICAgICAgICAqIFNlbmQgYW4gYWNrbm93bGVkZ2UgbWVzc2FnZSB0aGF0IHNvbWVvbmUgaXMgcHJvY2Vzc2luZyB0aGUgam9iLgorICAgICAgICAgKiBAcGFyYW0gam9iIFRoZSBqb2IuCisgICAgICAgICAqIEBwYXJhbSBldmVudE5vZGVQYXRoIFRoZSBzdG9yYWdlIG5vZGUgaW4gdGhlIHJlcG9zaXRvcnkuCisgICAgICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGFjayBpcyBvaywgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZSAoZS5nLiBpZgorICAgICAgICAgKiAgIHNvbWVvbmUgZWxzZSBhbHJlYWR5IHNlbmQgYW4gYWNrIGZvciB0aGlzIGpvYi4KKyAgICAgICAgICovCisgICAgICAgIGJvb2xlYW4gc2VuZEFja25vd2xlZGdlKEV2ZW50IGpvYiwgU3RyaW5nIGV2ZW50Tm9kZVBhdGgpOworCisgICAgICAgIC8qKgorICAgICAgICAgKiBOb3RpZnkgdGhhdCB0aGUgam9iIGlzIGZpbmlzaGVkLgorICAgICAgICAgKiBJZiB0aGUgam9iIGlzIG5vdCByZXNjaGVkdWxlZCwgYSByZXR1cm4gdmFsdWUgb2YgPGNvZGU+ZmFsc2U8L2NvZGU+IGluZGljYXRlcyBhbiBlcnJvcgorICAgICAgICAgKiBkdXJpbmcgdGhlIHByb2Nlc3NpbmcuIElmIHRoZSBqb2Igc2hvdWxkIGJlIHJlc2NoZWR1bGVkLCA8Y29kZT50cnVlPC9jb2RlPiBpbmRpY2F0ZXMKKyAgICAgICAgICogdGhhdCB0aGUgam9iIGNvdWxkIGJlIHJlc2NoZWR1bGVkLiBJZiBhbiBlcnJvciBvY2N1cnMgb3IgdGhlIG51bWJlciBvZiByZXRyaWVzIGlzCisgICAgICAgICAqIGV4Y2VlZGVkLCA8Y29kZT5mYWxzZTwvY29kZT4gd2lsbCBiZSByZXR1cm5lZC4KKyAgICAgICAgICogQHBhcmFtIGpvYiBUaGUgam9iLgorICAgICAgICAgKiBAcGFyYW0gZXZlbnROb2RlUGF0aCBUaGUgc3RvcmFnZSBub2RlIGluIHRoZSByZXBvc2l0b3J5LgorICAgICAgICAgKiBAcGFyYW0gcmVzY2hlZHVsZSBTaG91bGQgdGhlIGV2ZW50IGJlIHJlc2NoZWR1bGVkPworICAgICAgICAgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIGV2ZXJ5dGhpbmcgd2VudCBmaW5lLCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgorICAgICAgICAgKi8KKyAgICAgICAgYm9vbGVhbiBmaW5pc2hlZEpvYihFdmVudCBqb2IsIFN0cmluZyBldmVudE5vZGVQYXRoLCBib29sZWFuIHJlc2NoZWR1bGUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBhbGwgamF2YSBwcm9wZXJ0aWVzIGFzIHByb3BlcnRpZXMgdG8gdGhlIG5vZGUuCisgICAgICogSWYgdGhlIG5hbWUgYW5kIHRoZSB2YWx1ZSBvZiBhIG1hcCBlbnRyeSBjYW4gZWFzaWx5IGNvbnZlcnRlZCBpbnRvCisgICAgICogYSByZXBvc2l0b3J5IHByb3BlcnR5LCBpdCBpcyBkaXJlY3RseSBhZGRlZC4gQWxsIG90aGVyIGphdmEKKyAgICAgKiBwcm9wZXJ0aWVzIGFyZSBzdG9yZWQgaW4gb25lIGJpbmFyeSBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHdoZXJlIGFsbCBwcm9wZXJ0aWVzIGFyZSBhZGRlZCB0bworICAgICAqIEBwYXJhbSBwcm9wZXJ0aWVzIFRoZSBtYXAgb2YgcHJvcGVydGllcy4KKyAgICAgKiBAcGFyYW0gaWdub3JlUHJvcHMgb3B0aW9uYWwgbGlzdCBvZiBwcm9wZXJ0eSB3aGljaCBzaG91bGQgYmUgaWdub3JlZAorICAgICAqIEBwYXJhbSBiaW5Qcm9wZXJ0eU5hbWUgVGhlIG5hbWUgb2YgdGhlIGJpbmFyeSBwcm9wZXJ0eS4KKyAgICAgKiBAdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYWRkUHJvcGVydGllcyhmaW5hbCBOb2RlIG5vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWFwPFN0cmluZywgT2JqZWN0PiBwcm9wZXJ0aWVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZ1tdIGlnbm9yZVByb3BzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBiaW5Qcm9wZXJ0eU5hbWUpCisgICAgdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24geworICAgICAgICBhZGRQcm9wZXJ0aWVzKG5vZGUsIG5ldyBFdmVudFByb3BlcnRpZXNNYXAocHJvcGVydGllcyksIGlnbm9yZVByb3BzLCBiaW5Qcm9wZXJ0eU5hbWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBhbGwgamF2YSBwcm9wZXJ0aWVzIGFzIHByb3BlcnRpZXMgdG8gdGhlIG5vZGUuCisgICAgICogSWYgdGhlIG5hbWUgYW5kIHRoZSB2YWx1ZSBvZiBhIG1hcCBlbnRyeSBjYW4gZWFzaWx5IGNvbnZlcnRlZCBpbnRvCisgICAgICogYSByZXBvc2l0b3J5IHByb3BlcnR5LCBpdCBpcyBkaXJlY3RseSBhZGRlZC4gQWxsIG90aGVyIGphdmEKKyAgICAgKiBwcm9wZXJ0aWVzIGFyZSBzdG9yZWQgaW4gb25lIGJpbmFyeSBwcm9wZXJ0eS4KKyAgICAgKgorICAgICAqIEBwYXJhbSBub2RlIFRoZSBub2RlIHdoZXJlIGFsbCBwcm9wZXJ0aWVzIGFyZSBhZGRlZCB0bworICAgICAqIEBwYXJhbSBwcm9wZXJ0aWVzIFRoZSBtYXAgb2YgcHJvcGVydGllcy4KKyAgICAgKiBAcGFyYW0gaWdub3JlUHJvcHMgb3B0aW9uYWwgbGlzdCBvZiBwcm9wZXJ0eSB3aGljaCBzaG91bGQgYmUgaWdub3JlZAorICAgICAqIEBwYXJhbSBiaW5Qcm9wZXJ0eU5hbWUgVGhlIG5hbWUgb2YgdGhlIGJpbmFyeSBwcm9wZXJ0eS4KKyAgICAgKiBAdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIHZvaWQgYWRkUHJvcGVydGllcyhmaW5hbCBOb2RlIG5vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgRXZlbnRQcm9wZXJ0aWVzTWFwIHByb3BlcnRpZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nW10gaWdub3JlUHJvcHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGJpblByb3BlcnR5TmFtZSkKKyAgICB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIGlmICggcHJvcGVydGllcyAhPSBudWxsICkgeworICAgICAgICAgICAgZmluYWwgTGlzdDxTdHJpbmc+IGlnbm9yZVByb3BMaXN0ID0gKGlnbm9yZVByb3BzID09IG51bGwgPyBudWxsIDogQXJyYXlzLmFzTGlzdChpZ25vcmVQcm9wcykpOworICAgICAgICAgICAgLy8gY2hlY2sgd2hpY2ggcHJvcHMgd2UgY2FuIHdyaXRlIGRpcmVjdGx5IGFuZAorICAgICAgICAgICAgLy8gd2hpY2ggd2UgbmVlZCB0byB3cml0ZSBhcyBhIGJpbmFyeSBibG9iCisgICAgICAgICAgICBmaW5hbCBMaXN0PFN0cmluZz4gcHJvcHNBc0Jsb2IgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKKworICAgICAgICAgICAgZmluYWwgSXRlcmF0b3I8TWFwLkVudHJ5PFN0cmluZywgT2JqZWN0Pj4gaSA9IHByb3BlcnRpZXMuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICAgICAgd2hpbGUgKCBpLmhhc05leHQoKSApIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBNYXAuRW50cnk8U3RyaW5nLCBPYmplY3Q+IGN1cnJlbnQgPSBpLm5leHQoKTsKKworICAgICAgICAgICAgICAgIGlmIChpZ25vcmVQcm9wTGlzdCA9PSBudWxsIHx8ICFpZ25vcmVQcm9wTGlzdC5jb250YWlucyhjdXJyZW50LmdldEtleSgpKSApIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gc2FuaXR5IGNoZWNrCisgICAgICAgICAgICAgICAgICAgIGlmICggY3VycmVudC5nZXRWYWx1ZSgpICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoICFzZXRQcm9wZXJ0eShjdXJyZW50LmdldEtleSgpLCBjdXJyZW50LmdldFZhbHVlKCksIG5vZGUpICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BzQXNCbG9iLmFkZChjdXJyZW50LmdldEtleSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHdyaXRlIHRoZSByZW1haW5pbmcgcHJvcGVydGllcyBhcyBhIGJsb2IKKyAgICAgICAgICAgIGlmICggcHJvcHNBc0Jsb2Iuc2l6ZSgpID4gMCApIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0T3V0cHV0U3RyZWFtIG9vcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0oYmFvcyk7CisgICAgICAgICAgICAgICAgICAgIG9vcy53cml0ZUludChwcm9wc0FzQmxvYi5zaXplKCkpOworICAgICAgICAgICAgICAgICAgICBmb3IoZmluYWwgU3RyaW5nIHByb3BOYW1lIDogcHJvcHNBc0Jsb2IpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIG9vcy53cml0ZU9iamVjdChwcm9wTmFtZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9vcy53cml0ZU9iamVjdChwcm9wZXJ0aWVzLmdldChwcm9wTmFtZSkpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlcG9zaXRvcnlFeGNlcHRpb24oIlVuYWJsZSB0byBzZXJpYWxpemUgcHJvcGVydHkgIiArIHByb3BOYW1lLCBpb2UpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIG9vcy5jbG9zZSgpOworICAgICAgICAgICAgICAgICAgICBub2RlLnNldFByb3BlcnR5KGJpblByb3BlcnR5TmFtZSwgbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJhb3MudG9CeXRlQXJyYXkoKSkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmVwb3NpdG9yeUV4Y2VwdGlvbigiVW5hYmxlIHRvIHNlcmlhbGl6ZSBwcm9wZXJ0aWVzICIgKyBwcm9wZXJ0aWVzLCBpb2UpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFJlYWQgcHJvcGVydGllcyBmcm9tIGEgcmVwb3NpdG9yeSBub2RlIGFuZCBjcmVhdGUgYSBwcm9wZXJ0eSBtYXAuCisgICAgICogQHRocm93cyBSZXBvc2l0b3J5RXhjZXB0aW9uCisgICAgICogQHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uCisgICAgICovCisgICAgcHVibGljIHN0YXRpYyBFdmVudFByb3BlcnRpZXNNYXAgcmVhZFByb3BlcnRpZXMoZmluYWwgTm9kZSBub2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBiaW5Qcm9wZXJ0eU5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nW10gaWdub3JlUHJlZml4ZXMpCisgICAgdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24geworICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBPYmplY3Q+IHByb3BlcnRpZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIE9iamVjdD4oKTsKKworICAgICAgICAvLyBjaGVjayB0aGUgcHJvcGVydGllcyBibG9iCisgICAgICAgIGlmICggbm9kZS5oYXNQcm9wZXJ0eShiaW5Qcm9wZXJ0eU5hbWUpICkgeworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3RJbnB1dFN0cmVhbSBvaXMgPSBuZXcgT2JqZWN0SW5wdXRTdHJlYW0obm9kZS5nZXRQcm9wZXJ0eShiaW5Qcm9wZXJ0eU5hbWUpLmdldFN0cmVhbSgpKTsKKyAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gb2lzLnJlYWRJbnQoKTsKKyAgICAgICAgICAgICAgICBmb3IoaW50IGk9MDtpPGxlbmd0aDtpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGtleSA9IChTdHJpbmcpb2lzLnJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IHZhbHVlID0gb2lzLnJlYWRPYmplY3QoKTsKKyAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllcy5wdXQoa2V5LCB2YWx1ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JbnZhbGlkQ2xhc3NFeGNlcHRpb24gaWNlKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENsYXNzTm90Rm91bmRFeGNlcHRpb24oIkZvdW5kIGludmFsaWQgY2xhc3MuIiwgaWNlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgICAgICAgICAgIHRocm93IG5ldyBSZXBvc2l0b3J5RXhjZXB0aW9uKCJVbmFibGUgdG8gZGVzZXJpYWxpemUgZXZlbnQgcHJvcGVydGllcy4iLCBpb2UpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIG5vdyBhbGwgcHJvcGVydGllcyB0aGF0IGhhdmUgYmVlbiBzZXQgZGlyZWN0bHkKKyAgICAgICAgZmluYWwgUHJvcGVydHlJdGVyYXRvciBwSSA9IG5vZGUuZ2V0UHJvcGVydGllcygpOworICAgICAgICB3aGlsZSAoIHBJLmhhc05leHQoKSApIHsKKyAgICAgICAgICAgIGZpbmFsIFByb3BlcnR5IHAgPSBwSS5uZXh0UHJvcGVydHkoKTsKKyAgICAgICAgICAgIGJvb2xlYW4gaWdub3JlID0gcC5nZXROYW1lKCkuc3RhcnRzV2l0aCgiamNyOiIpOworICAgICAgICAgICAgaWYgKCAhaWdub3JlICYmIGlnbm9yZVByZWZpeGVzICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gMDsKKyAgICAgICAgICAgICAgICB3aGlsZSAoICFpZ25vcmUgJiYgaW5kZXggPCBpZ25vcmVQcmVmaXhlcy5sZW5ndGggKSB7CisgICAgICAgICAgICAgICAgICAgIGlnbm9yZSA9IHAuZ2V0TmFtZSgpLnN0YXJ0c1dpdGgoaWdub3JlUHJlZml4ZXNbaW5kZXhdKTsKKyAgICAgICAgICAgICAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoICFpZ25vcmUgKSB7CisgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5hbWUgPSBJU085MDc1LmRlY29kZShwLmdldE5hbWUoKSk7CisgICAgICAgICAgICAgICAgaWYgKCBwLmdldERlZmluaXRpb24oKS5pc011bHRpcGxlKCkgKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFZhbHVlW10gdmFsdWVzID0gcC5nZXRWYWx1ZXMoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCB2YWx1ZXMubGVuZ3RoID4gMCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldCBmaXJzdCB2YWx1ZQorICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0IGZpcnN0T2JqZWN0ID0gZ2V0UHJvcGVydHlWYWx1ZSh2YWx1ZXNbMF0pOworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgT2JqZWN0W10gYXJyYXk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGZpcnN0T2JqZWN0IGluc3RhbmNlb2YgQm9vbGVhbiApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheSA9IG5ldyBCb29sZWFuW3ZhbHVlcy5sZW5ndGhdOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICggZmlyc3RPYmplY3QgaW5zdGFuY2VvZiBDYWxlbmRhciApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheSA9IG5ldyBDYWxlbmRhclt2YWx1ZXMubGVuZ3RoXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIGZpcnN0T2JqZWN0IGluc3RhbmNlb2YgRG91YmxlICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5ID0gbmV3IERvdWJsZVt2YWx1ZXMubGVuZ3RoXTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIGZpcnN0T2JqZWN0IGluc3RhbmNlb2YgTG9uZyApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheSA9IG5ldyBMb25nW3ZhbHVlcy5sZW5ndGhdOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheSA9IG5ldyBTdHJpbmdbdmFsdWVzLmxlbmd0aF07CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBhcnJheVswXSA9IGZpcnN0T2JqZWN0OworICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICggaW5kZXggPCB2YWx1ZXMubGVuZ3RoICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5W2luZGV4XSA9IGdldFByb3BlcnR5VmFsdWUodmFsdWVzW2luZGV4XSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXMucHV0KG5hbWUsIGFycmF5KTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFZhbHVlIHZhbHVlID0gcC5nZXRWYWx1ZSgpOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBPYmplY3QgbyA9IGdldFByb3BlcnR5VmFsdWUodmFsdWUpOworICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzLnB1dChuYW1lLCBvKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBFdmVudFByb3BlcnRpZXNNYXAocHJvcGVydGllcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBjb252ZXJ0ZWQgcmVwb3NpdG9yeSBwcm9wZXJ0eSBuYW1lCisgICAgICogQHBhcmFtIG5hbWUgVGhlIGphdmEgb2JqZWN0IHByb3BlcnR5IG5hbWUKKyAgICAgKiBAcmV0dXJuIFRoZSBjb252ZXJ0ZWQgbmFtZSBvciBudWxsIGlmIG5vdCBwb3NzaWJsZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXROb2RlUHJvcGVydHlOYW1lKGZpbmFsIFN0cmluZyBuYW1lKSB7CisgICAgICAgIC8vIGlmIG5hbWUgY29udGFpbnMgYSBjb2xvbiwgd2UgY2FuJ3Qgc2V0IGl0IGFzIGEgcHJvcGVydHkKKyAgICAgICAgaWYgKCBuYW1lLmluZGV4T2YoJzonKSAhPSAtMSApIHsKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICB9CisgICAgICAgIHJldHVybiBJU085MDc1LmVuY29kZShuYW1lKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIGNvbnZlcnRlZCByZXBvc2l0b3J5IHByb3BlcnR5IHZhbHVlCisgICAgICogQHBhcmFtIHZhbHVlRmFjdG9yeSBUaGUgdmFsdWUgZmFjdG9yeQorICAgICAqIEBwYXJhbSBldmVudFZhbHVlIFRoZSBldmVudCB2YWx1ZQorICAgICAqIEByZXR1cm4gVGhlIGNvbnZlcnRlZCB2YWx1ZSBvciBudWxsIGlmIG5vdCBwb3NzaWJsZQorICAgICAqLworICAgIHB1YmxpYyBzdGF0aWMgVmFsdWUgZ2V0Tm9kZVByb3BlcnR5VmFsdWUoZmluYWwgVmFsdWVGYWN0b3J5IHZhbHVlRmFjdG9yeSwgZmluYWwgT2JqZWN0IGV2ZW50VmFsdWUpIHsKKyAgICAgICAgZmluYWwgVmFsdWUgdmFsOworICAgICAgICBpZiAoZXZlbnRWYWx1ZSBpbnN0YW5jZW9mIENhbGVuZGFyKSB7CisgICAgICAgICAgICB2YWwgPSB2YWx1ZUZhY3RvcnkuY3JlYXRlVmFsdWUoKENhbGVuZGFyKWV2ZW50VmFsdWUpOworICAgICAgICB9IGVsc2UgaWYgKGV2ZW50VmFsdWUgaW5zdGFuY2VvZiBMb25nKSB7CisgICAgICAgICAgICB2YWwgPSB2YWx1ZUZhY3RvcnkuY3JlYXRlVmFsdWUoKExvbmcpZXZlbnRWYWx1ZSk7CisgICAgICAgIH0gZWxzZSBpZiAoZXZlbnRWYWx1ZSBpbnN0YW5jZW9mIERvdWJsZSkgeworICAgICAgICAgICAgdmFsID0gdmFsdWVGYWN0b3J5LmNyZWF0ZVZhbHVlKCgoRG91YmxlKWV2ZW50VmFsdWUpLmRvdWJsZVZhbHVlKCkpOworICAgICAgICB9IGVsc2UgaWYgKGV2ZW50VmFsdWUgaW5zdGFuY2VvZiBCb29sZWFuKSB7CisgICAgICAgICAgICB2YWwgPSB2YWx1ZUZhY3RvcnkuY3JlYXRlVmFsdWUoKEJvb2xlYW4pIGV2ZW50VmFsdWUpOworICAgICAgICB9IGVsc2UgaWYgKGV2ZW50VmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpIHsKKyAgICAgICAgICAgIHZhbCA9IHZhbHVlRmFjdG9yeS5jcmVhdGVWYWx1ZSgoU3RyaW5nKWV2ZW50VmFsdWUpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgdmFsID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdmFsOworICAgIH0KKworICAgIC8qKgorICAgICAqIENvbnZlcnQgdGhlIHZhbHVlIGJhY2sgdG8gYW4gb2JqZWN0LgorICAgICAqIEBwYXJhbSB2YWx1ZQorICAgICAqIEByZXR1cm4KKyAgICAgKiBAdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBPYmplY3QgZ2V0UHJvcGVydHlWYWx1ZShmaW5hbCBWYWx1ZSB2YWx1ZSkKKyAgICB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIE9iamVjdCBvOworICAgICAgICBzd2l0Y2ggKHZhbHVlLmdldFR5cGUoKSkgeworICAgICAgICAgICAgY2FzZSBQcm9wZXJ0eVR5cGUuQk9PTEVBTjoKKyAgICAgICAgICAgICAgICBvID0gdmFsdWUuZ2V0Qm9vbGVhbigpOyBicmVhazsKKyAgICAgICAgICAgIGNhc2UgUHJvcGVydHlUeXBlLkRBVEU6CisgICAgICAgICAgICAgICAgbyA9IHZhbHVlLmdldERhdGUoKTsgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFByb3BlcnR5VHlwZS5ET1VCTEU6CisgICAgICAgICAgICAgICAgbyA9IHZhbHVlLmdldERvdWJsZSgpOyBicmVhazsKKyAgICAgICAgICAgIGNhc2UgUHJvcGVydHlUeXBlLkxPTkc6CisgICAgICAgICAgICAgICAgbyA9IHZhbHVlLmdldExvbmcoKTsgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFByb3BlcnR5VHlwZS5TVFJJTkc6CisgICAgICAgICAgICAgICAgbyA9IHZhbHVlLmdldFN0cmluZygpOyBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6IC8vIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiAtIHdlIGNvbnZlcnQgdG8gYSBzdHJpbmcuLi4KKyAgICAgICAgICAgICAgICBvID0gdmFsdWUuZ2V0U3RyaW5nKCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG87CisgICAgfQorCisgICAgLyoqCisgICAgICogVHJ5IHRvIHNldCB0aGUgamF2YSBwcm9wZXJ0eSBhcyBhIHByb3BlcnR5IG9mIHRoZSBub2RlLgorICAgICAqIEBwYXJhbSBuYW1lCisgICAgICogQHBhcmFtIHZhbHVlCisgICAgICogQHBhcmFtIG5vZGUKKyAgICAgKiBAcmV0dXJuCisgICAgICogQHRocm93cyBSZXBvc2l0b3J5RXhjZXB0aW9uCisgICAgICovCisgICAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBzZXRQcm9wZXJ0eShTdHJpbmcgbmFtZSwgT2JqZWN0IHZhbHVlLCBOb2RlIG5vZGUpCisgICAgdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24geworICAgICAgICBmaW5hbCBTdHJpbmcgcHJvcE5hbWUgPSBnZXROb2RlUHJvcGVydHlOYW1lKG5hbWUpOworICAgICAgICBpZiAoIHByb3BOYW1lID09IG51bGwgKSB7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgVmFsdWVGYWN0b3J5IGZhYyA9IG5vZGUuZ2V0U2Vzc2lvbigpLmdldFZhbHVlRmFjdG9yeSgpOworICAgICAgICAvLyBjaGVjayBmb3IgbXVsdGkgdmFsdWUKKyAgICAgICAgaWYgKCB2YWx1ZS5nZXRDbGFzcygpLmlzQXJyYXkoKSApIHsKKyAgICAgICAgICAgIGZpbmFsIE9iamVjdFtdIGFycmF5ID0gKE9iamVjdFtdKXZhbHVlOworICAgICAgICAgICAgLy8gbm93IHdlIHRyeSB0byBjb252ZXJ0IGVhY2ggdmFsdWUKKyAgICAgICAgICAgIC8vIGFuZCBjaGVjayBpZiBhbGwgY29udmVydGVkIHZhbHVlcyBoYXZlIHRoZSBzYW1lIHR5cGUKKyAgICAgICAgICAgIGZpbmFsIFZhbHVlW10gdmFsdWVzID0gbmV3IFZhbHVlW2FycmF5Lmxlbmd0aF07CisgICAgICAgICAgICBpbnQgaW5kZXggPSAwOworICAgICAgICAgICAgZm9yKGZpbmFsIE9iamVjdCB2IDogYXJyYXkgKSB7CisgICAgICAgICAgICAgICAgdmFsdWVzW2luZGV4XSA9IGdldE5vZGVQcm9wZXJ0eVZhbHVlKGZhYywgdik7CisgICAgICAgICAgICAgICAgaWYgKCB2YWx1ZXNbaW5kZXhdID09IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKCBpbmRleCA+IDAgJiYgIXZhbHVlc1tpbmRleC0xXS5nZXRDbGFzcygpLmVxdWFscyh2YWx1ZXNbaW5kZXhdLmdldENsYXNzKCkpICkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGluZGV4Kys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBub2RlLnNldFByb3BlcnR5KHByb3BOYW1lLCB2YWx1ZXMpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgVmFsdWUgdmFsID0gZ2V0Tm9kZVByb3BlcnR5VmFsdWUoZmFjLCB2YWx1ZSk7CisgICAgICAgIGlmICggdmFsICE9IG51bGwgKSB7CisgICAgICAgICAgICBub2RlLnNldFByb3BlcnR5KHByb3BOYW1lLCB2YWwpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEltcHJvdmVkIHRvU3RyaW5nIG1ldGhvZCBmb3IgYW4gRXZlbnQuCisgICAgICogVGhpcyBtZXRob2QgcHJpbnRzIG91dCB0aGUgZXZlbnQgdG9waWMgYW5kIGFsbCBvZiB0aGUgcHJvcGVydGllcy4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b1N0cmluZyhmaW5hbCBFdmVudCBlKSB7CisgICAgICAgIGlmICggZSA9PSBudWxsICkgeworICAgICAgICAgICAgcmV0dXJuICI8bnVsbD4iOworICAgICAgICB9CisgICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBidWZmZXIgPW5ldyBTdHJpbmdCdWZmZXIoZS5nZXRDbGFzcygpLmdldE5hbWUoKSk7CisgICAgICAgIGJ1ZmZlci5hcHBlbmQoIiBbdG9waWM9Iik7CisgICAgICAgIGJ1ZmZlci5hcHBlbmQoZS5nZXRUb3BpYygpKTsKKyAgICAgICAgYnVmZmVyLmFwcGVuZCgiLCBwcm9wZXJ0aWVzPSIpOworICAgICAgICBmaW5hbCBTdHJpbmdbXSBuYW1lcyA9IGUuZ2V0UHJvcGVydHlOYW1lcygpOworICAgICAgICBpZiAoIG5hbWVzICE9IG51bGwgKSB7CisgICAgICAgICAgICBmb3IoaW50IGk9MDtpPG5hbWVzLmxlbmd0aDtpKyspIHsKKyAgICAgICAgICAgICAgICBpZiAoIGk+MCkgeworICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIsIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQobmFtZXNbaV0pOworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJz0nKTsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGUuZ2V0UHJvcGVydHkobmFtZXNbaV0pKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBidWZmZXIuYXBwZW5kKCJdIik7CisgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvSm9iUHJvY2Vzc29yLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvSm9iUHJvY2Vzc29yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGY0MTBiYwotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9Kb2JQcm9jZXNzb3IuamF2YQpAQCAtMCwwICsxLDM4IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50OworCitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudDsKKworLyoqCisgKiBBIGpvYiBwcm9jZXNzb3IgcHJvY2Vzc2VzIGEgam9iIGluIHRoZSBiYWNrZ3JvdW5kLgorICogSXQgaXMgdXNlZCBieSB7QGxpbmsgRXZlbnRVdGlsI3Byb2Nlc3NKb2IoRXZlbnQsIEpvYlByb2Nlc3Nvcil9LgorICovCitwdWJsaWMgaW50ZXJmYWNlIEpvYlByb2Nlc3NvciB7CisKKyAgICAvKioKKyAgICAgKiBFeGVjdXRlIHRoZSBqb2IuCisgICAgICogSWYgdGhlIGpvYiBmYWlscyB3aXRoIGEgdGhyb3duIGV4Y2VwdGlvbi90aHJvd2FibGUsIHRoZSBwcm9jZXNzIHdpbGwgbm90IGJlIHJlc2NoZWR1bGVkLgorICAgICAqCisgICAgICogQHBhcmFtIGpvYiBUaGUgZXZlbnQgY29udGFpbmluZyB0aGUgam9iIGRlc2NyaXB0aW9uLgorICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgam9iIGNvdWxkIGJlIGZpbmlzaGVkIChlaXRoZXIgc3VjY2Vzc2Z1bCBvciBieSBhbiBlcnJvcikuCisgICAgICogICAgICAgICBSZXR1cm4gZmFsc2UgaWYgdGhlIGpvYiBzaG91bGQgYmUgcmVzY2hlZHVsZWQuCisgICAgICovCisgICAgYm9vbGVhbiBwcm9jZXNzKEV2ZW50IGpvYik7Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvSm9iU3RhdHVzUHJvdmlkZXIuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9Kb2JTdGF0dXNQcm92aWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4MzAzMjMKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvSm9iU3RhdHVzUHJvdmlkZXIuamF2YQpAQCAtMCwwICsxLDExMSBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5zbGluZy5ldmVudDsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5NYXA7CisKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmV2ZW50LkV2ZW50OworCisvKioKKyAqIFRoaXMgc2VydmljZSBwcm92aWRlcyB0aGUgY3VycmVudCBqb2IgcHJvY2Vzc2luZyBzdGF0dXMuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgSm9iU3RhdHVzUHJvdmlkZXIgeworCisgICAgLyoqCisgICAgICogVGhpcyBpcyBhIHVuaXF1ZSBpZGVudGlmZXIgd2hpY2ggY2FuIGJlIHVzZWQgdG8gY2FuY2VsIHRoZSBqb2IuCisgICAgICovCisgICAgU3RyaW5nIFBST1BFUlRZX0VWRU5UX0lEID0gInNsaW5nZXZlbnQ6ZXZlbnRJZCI7CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNnZXRTY2hlZHVsZWRKb2JzKFN0cmluZyl9IGluc3RlYWQuCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBDb2xsZWN0aW9uPEV2ZW50PiBzY2hlZHVsZWRKb2JzKFN0cmluZyB0b3BpYyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBsaXN0IG9mIGN1cnJlbnRseSBzY2hlZHVsZGVkIGpvYnMuCisgICAgICogQHBhcmFtIHRvcGljIFRvcGljIGNhbiBiZSB1c2VkIGFzIGEgZmlsdGVyLCBpZiBpdCBpcyBub24tbnVsbCwgb25seSBqb2JzIHdpdGggdGhpcyB0b3BpYyB3aWxsIGJlIHJldHVybmVkLgorICAgICAqIEByZXR1cm4gQSBub24gbnVsbCBjb2xsZWN0aW9uLgorICAgICAqLworICAgIENvbGxlY3Rpb248RXZlbnQ+IGdldFNjaGVkdWxlZEpvYnMoU3RyaW5nIHRvcGljKTsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgam9icyB3aGljaCBhcmUgY3VycmVudGx5IGluIHByb2Nlc3NpbmcuIElmIHRoZXJlIGFyZSBzZXZlcmFsIGFwcGxpY2F0aW9uIG5vZGVzCisgICAgICogaW4gdGhlIGNsdXN0ZXIsIHRoZXJlIGNvdWxkIGJlIG1vcmUgdGhhbiBvbmUgam9iIGluIHByb2Nlc3NpbmcKKyAgICAgKiBAcGFyYW0gdG9waWMgVG9waWMgY2FuIGJlIHVzZWQgYXMgYSBmaWx0ZXIsIGlmIGl0IGlzIG5vbi1udWxsLCBvbmx5IGpvYnMgd2l0aCB0aGlzIHRvcGljIHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICogQHJldHVybiBBIG5vbiBudWxsIGNvbGxlY3Rpb24uCisgICAgICovCisgICAgQ29sbGVjdGlvbjxFdmVudD4gZ2V0Q3VycmVudEpvYnMoU3RyaW5nIHRvcGljKTsKKworICAgIC8qKgorICAgICAqIFJldHVybiBhIGxpc3Qgb2YgY3VycmVudGx5IHNjaGVkdWxkZWQgam9icy4KKyAgICAgKiBAcGFyYW0gdG9waWMgVG9waWMgY2FuIGJlIHVzZWQgYXMgYSBmaWx0ZXIsIGlmIGl0IGlzIG5vbi1udWxsLCBvbmx5IGpvYnMgd2l0aCB0aGlzIHRvcGljIHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICogQHBhcmFtIGZpbHRlclByb3BzIEEgbGlzdCBvZiBmaWx0ZXIgcHJvcGVydHkgbWFwcy4gRWFjaCBtYXAgYWN0cyBsaWtlIGEgdGVtcGxhdGUuIFRoZSBzZWFyY2hlZCBqb2IKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgbXVzdCBtYXRjaCB0aGUgdGVtcGxhdGUgKEFORCBxdWVyeSkuIEJ5IHByb3ZpZGluZyBzZXZlcmFsIG1hcHMsIGRpZmZlcmVudCBmaWx0ZXJzCisgICAgICogICAgICAgICAgICAgICAgICAgIGFyZSBwb3NzaWJsZSAoT1IgcXVlcnkpLgorICAgICAqIEByZXR1cm4gQSBub24gbnVsbCBjb2xsZWN0aW9uLgorICAgICAqLworICAgIENvbGxlY3Rpb248RXZlbnQ+IGdldFNjaGVkdWxlZEpvYnMoU3RyaW5nIHRvcGljLCBNYXA8U3RyaW5nLCBPYmplY3Q+Li4uIGZpbHRlclByb3BzKTsKKworICAgIC8qKgorICAgICAqIFJldHVybiB0aGUgam9icyB3aGljaCBhcmUgY3VycmVudGx5IGluIHByb2Nlc3NpbmcuIElmIHRoZXJlIGFyZSBzZXZlcmFsIGFwcGxpY2F0aW9uIG5vZGVzCisgICAgICogaW4gdGhlIGNsdXN0ZXIsIHRoZXJlIGNvdWxkIGJlIG1vcmUgdGhhbiBvbmUgam9iIGluIHByb2Nlc3NpbmcKKyAgICAgKiBAcGFyYW0gdG9waWMgVG9waWMgY2FuIGJlIHVzZWQgYXMgYSBmaWx0ZXIsIGlmIGl0IGlzIG5vbi1udWxsLCBvbmx5IGpvYnMgd2l0aCB0aGlzIHRvcGljIHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICogQHBhcmFtIGZpbHRlclByb3BzIEEgbGlzdCBvZiBmaWx0ZXIgcHJvcGVydHkgbWFwcy4gRWFjaCBtYXAgYWN0cyBsaWtlIGEgdGVtcGxhdGUuIFRoZSBzZWFyY2hlZCBqb2IKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgbXVzdCBtYXRjaCB0aGUgdGVtcGxhdGUgKEFORCBxdWVyeSkuIEJ5IHByb3ZpZGluZyBzZXZlcmFsIG1hcHMsIGRpZmZlcmVudCBmaWx0ZXJzCisgICAgICogICAgICAgICAgICAgICAgICAgIGFyZSBwb3NzaWJsZSAoT1IgcXVlcnkpLgorICAgICAqIEByZXR1cm4gQSBub24gbnVsbCBjb2xsZWN0aW9uLgorICAgICAqLworICAgIENvbGxlY3Rpb248RXZlbnQ+IGdldEN1cnJlbnRKb2JzKFN0cmluZyB0b3BpYywgTWFwPFN0cmluZywgT2JqZWN0Pi4uLiBmaWx0ZXJQcm9wcyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYWxsIGpvYnMgZWl0aGVyIHJ1bm5pbmcgb3Igc2NoZWR1bGVkLgorICAgICAqIFRoaXMgaXMgYWN0dWFsbHkgYSBjb252ZW5pZW5jZSBtZXRob2QgYW5kIGNvbGxlY3RzIHRoZSByZXN1bHRzIGZyb20ge0BsaW5rICNnZXRTY2hlZHVsZWRKb2JzKFN0cmluZywgTWFwLi4uKX0KKyAgICAgKiBhbmQge0BsaW5rICNnZXRDdXJyZW50Sm9icyhTdHJpbmcsIE1hcC4uLil9CisgICAgICogQHBhcmFtIHRvcGljIFRvcGljIGNhbiBiZSB1c2VkIGFzIGEgZmlsdGVyLCBpZiBpdCBpcyBub24tbnVsbCwgb25seSBqb2JzIHdpdGggdGhpcyB0b3BpYyB3aWxsIGJlIHJldHVybmVkLgorICAgICAqIEBwYXJhbSBmaWx0ZXJQcm9wcyBBIGxpc3Qgb2YgZmlsdGVyIHByb3BlcnR5IG1hcHMuIEVhY2ggbWFwIGFjdHMgbGlrZSBhIHRlbXBsYXRlLiBUaGUgc2VhcmNoZWQgam9iCisgICAgICogICAgICAgICAgICAgICAgICAgIG11c3QgbWF0Y2ggdGhlIHRlbXBsYXRlIChBTkQgcXVlcnkpLiBCeSBwcm92aWRpbmcgc2V2ZXJhbCBtYXBzLCBkaWZmZXJlbnQgZmlsdGVycworICAgICAqICAgICAgICAgICAgICAgICAgICBhcmUgcG9zc2libGUgKE9SIHF1ZXJ5KS4KKyAgICAgKiBAcmV0dXJuIEEgbm9uIG51bGwgY29sbGVjdGlvbi4KKyAgICAgKi8KKyAgICBDb2xsZWN0aW9uPEV2ZW50PiBnZXRBbGxKb2JzKFN0cmluZyB0b3BpYywgTWFwPFN0cmluZywgT2JqZWN0Pi4uLiBmaWx0ZXJQcm9wcyk7CisKKyAgICAvKioKKyAgICAgKiBDYW5jZWwgdGhpcyBqb2IuCisgICAgICogQHBhcmFtIGpvYklkIFRoZSB1bmlxdWUgaWRlbnRpZmVyIGFzIGZvdW5kIGluIHRoZSBwcm9wZXJ0eSB7QGxpbmsgI1BST1BFUlRZX0VWRU5UX0lEfS4KKyAgICAgKi8KKyAgICB2b2lkIGNhbmNlbEpvYihTdHJpbmcgam9iSWQpOworCisgICAgLyoqCisgICAgICogQ2FuY2VsIHRoaXMgam9iLgorICAgICAqIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIGlmIHRoZSB0b3BpYyBhbmQgdGhlIHByb3ZpZGVkIGpvYiBpZCBpcyBrbm93bi4KKyAgICAgKiBAcGFyYW0gdG9waWMgVGhlIGpvYiB0b3BpYyBhcyBwdXQgaW50byB0aGUgcHJvcGVydHkge0BsaW5rIEV2ZW50VXRpbCNQUk9QRVJUWV9KT0JfVE9QSUN9LgorICAgICAqIEBwYXJhbSBqb2JJZCBUaGUgdW5pcXVlIGlkZW50aWZlciBhcyBwdXQgaW50byB0aGUgcHJvcGVydHkge0BsaW5rIEV2ZW50VXRpbCNQUk9QRVJUWV9KT0JfSUR9LgorICAgICAqLworICAgIHZvaWQgY2FuY2VsSm9iKFN0cmluZyB0b3BpYywgU3RyaW5nIGpvYklkKTsKKworICAgIC8qKgorICAgICAqIFdha2UgdXAgdGhlIG5hbWVkIGpvYiBxdWV1ZS4KKyAgICAgKiBJZiBhIGpvYiBmYWlsZWQsIHRoZSBqb2IgcXVldWUgd2FpdHMgKHNsZWVwcykgZm9yIGEgY29uZmlndXJlZCB0aW1lLiBCeSBjYWxsaW5nIHRoaXMKKyAgICAgKiBtZXRob2QsIHRoZSBqb2IgcXVldWUgY2FuIGJlIHdva2VuIHVwIGFuZCBmb3JjZSBhbiBpbW1lZGlhdGUgcmVwcm9jZXNzaW5nLgorICAgICAqIEBwYXJhbSBqb2JRdWV1ZU5hbWUgVGhlIG5hbWUgb2YgdGhlIHF1ZXVlLgorICAgICAqLworICAgIHZvaWQgd2FrZVVwSm9iUXVldWUoZmluYWwgU3RyaW5nIGpvYlF1ZXVlTmFtZSk7Cit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvVGhyZWFkUG9vbC5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L1RocmVhZFBvb2wuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xY2NhMmMyCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L1RocmVhZFBvb2wuamF2YQpAQCAtMCwwICsxLDMwIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCisgKiBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlIGRpc3RyaWJ1dGVkIHdpdGgKKyAqIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4KKyAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCisgKiAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aAorICogdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQ7CisKKy8qKgorICogVGhlIGV2ZW50aW5nIHRocmVhZCBwb29sIGlzIGEgc3BlY2lhbCB0aHJlYWQgcG9vbCB1c2VkIGZvciB0aGUgZXZlbnRpbmcuCisgKiBUaGUgZXZlbnRpbmcgdXNlcyBhIHNlcnZpY2UgcmVnaXN0ZXJlZCBhcyB0aGlzIGludGVyZmFjZS4KKyAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGlzIGEgY29uZmlndXJhYmxlIHBvb2wgcmVnaXN0ZXJlZCB3aXRoCisgKiBjb21tb25zIHRocmVhZHMuCisgKgorICogQHZlcnNpb24gJElkJAorICovCitwdWJsaWMgaW50ZXJmYWNlIFRocmVhZFBvb2wgZXh0ZW5kcyBvcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMudGhyZWFkcy5UaHJlYWRQb29sIHsKKworICAgIC8vIHRoaXMgaXMganVzdCBhIG1hcmtlciBpbnRlcmZhY2UKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9UaW1lZEV2ZW50U3RhdHVzUHJvdmlkZXIuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9UaW1lZEV2ZW50U3RhdHVzUHJvdmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYjkzMWFlCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L1RpbWVkRXZlbnRTdGF0dXNQcm92aWRlci5qYXZhCkBAIC0wLDAgKzEsNTcgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQ7CisKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudDsKKworLyoqCisgKiBUaGlzIHNlcnZpY2UgcHJvdmlkZXMgdGhlIGN1cnJlbnQgdGltZWQgZXZlbnRzIHN0YXR1cy4KKyAqLworcHVibGljIGludGVyZmFjZSBUaW1lZEV2ZW50U3RhdHVzUHJvdmlkZXIgeworCisgICAgLyoqCisgICAgICogVGhpcyBpcyBhIHVuaXF1ZSBpZGVudGlmZXIgd2hpY2ggY2FuIGJlIHVzZWQgdG8gY2FuY2VsIHRoZSBqb2IuCisgICAgICovCisgICAgU3RyaW5nIFBST1BFUlRZX0VWRU5UX0lEID0gInNsaW5nZXZlbnQ6ZXZlbnRJZCI7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gYSBsaXN0IG9mIGN1cnJlbnRseSBzY2hlZHVsZGVkIGV2ZW50cy4KKyAgICAgKiBAcGFyYW0gdG9waWMgVG9waWMgY2FuIGJlIHVzZWQgYXMgYSBmaWx0ZXIsIGlmIGl0IGlzIG5vbi1udWxsLCBvbmx5IGpvYnMgd2l0aCB0aGlzIHRvcGljIHdpbGwgYmUgcmV0dXJuZWQuCisgICAgICogQHBhcmFtIGZpbHRlclByb3BzIEEgbGlzdCBvZiBmaWx0ZXIgcHJvcGVydHkgbWFwcy4gRWFjaCBtYXAgYWN0cyBsaWtlIGEgdGVtcGxhdGUuIFRoZSBzZWFyY2hlZCBldmVudAorICAgICAqICAgICAgICAgICAgICAgICAgICBtdXN0IG1hdGNoIHRoZSB0ZW1wbGF0ZSAoQU5EIHF1ZXJ5KS4gQnkgcHJvdmlkaW5nIHNldmVyYWwgbWFwcywgZGlmZmVyZW50IGZpbHRlcnMKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgYXJlIHBvc3NpYmxlIChPUiBxdWVyeSkuCisgICAgICogQHJldHVybiBBIG5vbiBudWxsIGNvbGxlY3Rpb24uCisgICAgICovCisgICAgQ29sbGVjdGlvbjxFdmVudD4gZ2V0U2NoZWR1bGVkRXZlbnRzKFN0cmluZyB0b3BpYywgTWFwPFN0cmluZywgT2JqZWN0Pi4uLiBmaWx0ZXJQcm9wcyk7CisKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIHNjaGVkdWxlZCBldmVudCB3aXRoIHRoZSBnaXZlbiBpZC4KKyAgICAgKiBAcmV0dXJuIFRoZSBzY2hlZHVsZWQgZXZlbnQgb3IgbnVsbC4KKyAgICAgKi8KKyAgICBFdmVudCBnZXRTY2hlZHVsZWRFdmVudChTdHJpbmcgdG9waWMsIFN0cmluZyBldmVudElkLCBTdHJpbmcgam9iSWQpOworCisgICAgLyoqCisgICAgICogQ2FuY2VsIHRoaXMgdGltZWQgZXZlbnQuCisgICAgICogQHBhcmFtIGpvYklkIFRoZSB1bmlxdWUgaWRlbnRpZmVyIGFzIGZvdW5kIGluIHRoZSBwcm9wZXJ0eSB7QGxpbmsgI1BST1BFUlRZX0VWRU5UX0lEfS4KKyAgICAgKi8KKyAgICB2b2lkIGNhbmNlbFRpbWVkRXZlbnQoU3RyaW5nIGpvYklkKTsKK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL0Fic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L2ltcGwvQWJzdHJhY3RSZXBvc2l0b3J5RXZlbnRIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDc1NDU4NAotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL0Fic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsMzQ2IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LmltcGw7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuRGljdGlvbmFyeTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5CbG9ja2luZ1F1ZXVlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkxpbmtlZEJsb2NraW5nUXVldWU7CisKK2ltcG9ydCBqYXZheC5qY3IuTm9kZTsKK2ltcG9ydCBqYXZheC5qY3IuUmVwb3NpdG9yeUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5qY3IuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5qY3Iub2JzZXJ2YXRpb24uRXZlbnRMaXN0ZW5lcjsKKworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuY29tbW9ucy5vc2dpLk9zZ2lVdGlsOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuZW5naW5lLlNsaW5nU2V0dGluZ3NTZXJ2aWNlOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuRXZlbnRQcm9wZXJ0aWVzTWFwOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuRXZlbnRVdGlsOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuSm9iU3RhdHVzUHJvdmlkZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5UaHJlYWRQb29sOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuamNyLmFwaS5TbGluZ1JlcG9zaXRvcnk7CitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5qY3IucmVzb3VyY2UuSmNyUmVzb3VyY2VVdGlsOworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudENvbnRleHQ7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudDsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmV2ZW50LkV2ZW50QWRtaW47CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudEhhbmRsZXI7CitpbXBvcnQgb3JnLnNsZjRqLkxvZ2dlcjsKK2ltcG9ydCBvcmcuc2xmNGouTG9nZ2VyRmFjdG9yeTsKKworLyoqCisgKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBhbGwgZXZlbnQgaGFuZGxlcnMgaW4gdGhpcyBwYWNrYWdlLgorICoKKyAqIEBzY3IuY29tcG9uZW50IGFic3RyYWN0PSJ0cnVlIiBtZXRhdHlwZT0ibm8iCisgKiBAc2NyLnNlcnZpY2UgaW50ZXJmYWNlPSJvcmcub3NnaS5zZXJ2aWNlLmV2ZW50LkV2ZW50SGFuZGxlciIKKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlcgorICAgIGltcGxlbWVudHMgRXZlbnRIYW5kbGVyLCBFdmVudExpc3RlbmVyIHsKKworICAgIC8qKiBEZWZhdWx0IGxvZy4gKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgTG9nZ2VyIGxvZ2dlciA9IExvZ2dlckZhY3RvcnkuZ2V0TG9nZ2VyKHRoaXMuZ2V0Q2xhc3MoKSk7CisKKyAgICAvKiogQHNjci5wcm9wZXJ0eSB2YWx1ZVJlZj0iREVGQVVMVF9QUk9QRVJUWV9SRVBPX1BBVEgiICovCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09ORklHX1BST1BFUlRZX1JFUE9fUEFUSCA9ICJyZXBvc2l0b3J5LnBhdGgiOworCisgICAgLyoqIERlZmF1bHQgcGF0aCBmb3IgdGhlIHtAbGluayAjQ09ORklHX1BST1BFUlRZX1JFUE9fUEFUSH0gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9QUk9QRVJUWV9SRVBPX1BBVEggPSAiL3NsaW5nL2V2ZW50cyI7CisKKyAgICAvKiogQHNjci5yZWZlcmVuY2UgKi8KKyAgICBwcm90ZWN0ZWQgU2xpbmdSZXBvc2l0b3J5IHJlcG9zaXRvcnk7CisKKyAgICAvKiogQHNjci5yZWZlcmVuY2UgKi8KKyAgICBwcm90ZWN0ZWQgRXZlbnRBZG1pbiBldmVudEFkbWluOworCisgICAgLyoqIE91ciBhcHBsaWNhdGlvbiBpZC4gKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGFwcGxpY2F0aW9uSWQ7CisKKyAgICAvKiogVGhlIHJlcG9zaXRvcnkgc2Vzc2lvbiB0byB3cml0ZSBpbnRvIHRoZSByZXBvc2l0b3J5LiAqLworICAgIHByb3RlY3RlZCBTZXNzaW9uIHdyaXRlclNlc3Npb247CisKKyAgICAvKiogVGhlIHBhdGggaW4gdGhlIHJlcG9zaXRvcnkuICovCisgICAgcHJvdGVjdGVkIFN0cmluZyByZXBvc2l0b3J5UGF0aDsKKworICAgIC8qKiBJcyB0aGUgYmFja2dyb3VuZCB0YXNrIHN0aWxsIHJ1bm5pbmc/ICovCisgICAgcHJvdGVjdGVkIGJvb2xlYW4gcnVubmluZzsKKworICAgIC8qKiBBIGxvY2FsIHF1ZXVlIGZvciBzZXJpYWxpc2luZyB0aGUgZXZlbnQgcHJvY2Vzc2luZy4gKi8KKyAgICBwcm90ZWN0ZWQgZmluYWwgQmxvY2tpbmdRdWV1ZTxFdmVudEluZm8+IHF1ZXVlID0gbmV3IExpbmtlZEJsb2NraW5nUXVldWU8RXZlbnRJbmZvPigpOworCisgICAgLyoqIEEgbG9jYWwgcXVldWUgZm9yIHdyaXRpbmcgcmVjZWl2ZWQgZXZlbnRzIGludG8gdGhlIHJlcG9zaXRvcnkuICovCisgICAgcHJvdGVjdGVkIGZpbmFsIEJsb2NraW5nUXVldWU8RXZlbnQ+IHdyaXRlUXVldWUgPSBuZXcgTGlua2VkQmxvY2tpbmdRdWV1ZTxFdmVudD4oKTsKKworICAgIC8qKgorICAgICAqIE91ciB0aHJlYWQgcG9vbC4KKyAgICAgKiBAc2NyLnJlZmVyZW5jZSAqLworICAgIHByb3RlY3RlZCBUaHJlYWRQb29sIHRocmVhZFBvb2w7CisKKyAgICAvKiogQHNjci5yZWZlcmVuY2UKKyAgICAgKiAgU2xpbmcgc2V0dGluZ3Mgc2VydmljZS4gKi8KKyAgICBwcm90ZWN0ZWQgU2xpbmdTZXR0aW5nc1NlcnZpY2Ugc2V0dGluZ3NTZXJ2aWNlOworCisgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgQVBQTElDQVRJT05fSUQ7CisKKyAgICAvKiogTGlzdCBvZiBpZ25vcmVkIHByb3BlcnRpZXMgdG8gd3JpdGUgdG8gdGhlIHJlcG9zaXRvcnkuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gSUdOT1JFX1BST1BFUlRJRVMgPSBuZXcgU3RyaW5nW10geworICAgICAgICBFdmVudFV0aWwuUFJPUEVSVFlfRElTVFJJQlVURSwKKyAgICAgICAgRXZlbnRVdGlsLlBST1BFUlRZX0FQUExJQ0FUSU9OLAorICAgICAgICBKb2JTdGF0dXNQcm92aWRlci5QUk9QRVJUWV9FVkVOVF9JRCwKKyAgICAgICAgRXZlbnRVdGlsLkpvYlN0YXR1c05vdGlmaWVyLkNPTlRFWFRfUFJPUEVSVFlfTkFNRQorICAgIH07CisKKyAgICAvKiogTGlzdCBvZiBpZ25vcmVkIHByZWZpeGVzIHRvIHJlYWQgZnJvbSB0aGUgcmVwb3NpdG9yeS4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBJR05PUkVfUFJFRklYRVMgPSBuZXcgU3RyaW5nW10geworICAgICAgICBFdmVudEhlbHBlci5FVkVOVF9QUkVGSVgKKyAgICB9OworCisgICAgLyoqCisgICAgICogQWN0aXZhdGUgdGhpcyBjb21wb25lbnQuCisgICAgICogQHBhcmFtIGNvbnRleHQKKyAgICAgKiBAdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBhY3RpdmF0ZShmaW5hbCBDb21wb25lbnRDb250ZXh0IGNvbnRleHQpCisgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMuYXBwbGljYXRpb25JZCA9IHRoaXMuc2V0dGluZ3NTZXJ2aWNlLmdldFNsaW5nSWQoKTsKKyAgICAgICAgQVBQTElDQVRJT05fSUQgPSB0aGlzLmFwcGxpY2F0aW9uSWQ7CisgICAgICAgIHRoaXMucmVwb3NpdG9yeVBhdGggPSBPc2dpVXRpbC50b1N0cmluZyhjb250ZXh0LmdldFByb3BlcnRpZXMoKS5nZXQoCisgICAgICAgICAgICBDT05GSUdfUFJPUEVSVFlfUkVQT19QQVRIKSwgREVGQVVMVF9QUk9QRVJUWV9SRVBPX1BBVEgpOworCisgICAgICAgIHRoaXMucnVubmluZyA9IHRydWU7CisgICAgICAgIC8vIHN0YXJ0IHdyaXRlciB0aHJlYWQKKyAgICAgICAgdGhpcy50aHJlYWRQb29sLmV4ZWN1dGUobmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXJ0V3JpdGVyU2Vzc2lvbigpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSBpcyBub3RoaW5nIHdlIGNhbiBkbyBleGNlcHQgbG9nIQorICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoIkVycm9yIGR1cmluZyBzZXNzaW9uIHN0YXJ0aW5nLiIsIGUpOworICAgICAgICAgICAgICAgICAgICBydW5uaW5nID0gZmFsc2U7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NXcml0ZVF1ZXVlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCJXcml0ZXIgdGhyZWFkIHN0b3BwZWQgd2l0aCBleGNlcHRpb246ICIgKyB0LmdldE1lc3NhZ2UoKSwgdCk7CisgICAgICAgICAgICAgICAgICAgIHJ1bm5pbmcgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgc3RvcFdyaXRlclNlc3Npb24oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgICAgICAgIHRoaXMudGhyZWFkUG9vbC5leGVjdXRlKG5ldyBSdW5uYWJsZSgpIHsKKyAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBydW5JbkJhY2tncm91bmQoKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoIkJhY2tncm91bmQgdGhyZWFkIHN0b3BwZWQgd2l0aCBleGNlcHRpb246ICIgKyB0LmdldE1lc3NhZ2UoKSwgdCk7CisgICAgICAgICAgICAgICAgICAgIHJ1bm5pbmcgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0pOworICAgIH0KKworICAgIHByb3RlY3RlZCBhYnN0cmFjdCB2b2lkIHJ1bkluQmFja2dyb3VuZCgpIHRocm93cyBSZXBvc2l0b3J5RXhjZXB0aW9uOworCisgICAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgcHJvY2Vzc1dyaXRlUXVldWUoKTsKKworICAgIC8qKgorICAgICAqIERlYWN0aXZhdGUgdGhpcyBjb21wb25lbnQuCisgICAgICogQHBhcmFtIGNvbnRleHQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBkZWFjdGl2YXRlKGZpbmFsIENvbXBvbmVudENvbnRleHQgY29udGV4dCkgeworICAgICAgICAvLyBzdG9wIGJhY2tncm91bmQgdGhyZWFkcyBieSBwdXR0aW5nIGVtcHR5IG9iamVjdHMgaW50byB0aGUgcXVldWUKKyAgICAgICAgdGhpcy5ydW5uaW5nID0gZmFsc2U7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICB0aGlzLndyaXRlUXVldWUucHV0KG5ldyBFdmVudCgic29tZSIsIG51bGwpKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhpcy5pZ25vcmVFeGNlcHRpb24oZSk7CisgICAgICAgIH0KKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHRoaXMucXVldWUucHV0KG5ldyBFdmVudEluZm8oKSk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ3JlYXRlIGEgbmV3IHNlc3Npb24uCisgICAgICogQHJldHVybgorICAgICAqIEB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCBTZXNzaW9uIGNyZWF0ZVNlc3Npb24oKQorICAgIHRocm93cyBSZXBvc2l0b3J5RXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU2xpbmdSZXBvc2l0b3J5IHJlcG8gPSB0aGlzLnJlcG9zaXRvcnk7CisgICAgICAgIGlmICggcmVwbyA9PSBudWxsICkgeworICAgICAgICAgICAgdGhyb3cgbmV3IFJlcG9zaXRvcnlFeGNlcHRpb24oIlJlcG9zaXRvcnkgaXMgY3VycmVudGx5IG5vdCBhdmFpbGFibGUuIik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlcG8ubG9naW5BZG1pbmlzdHJhdGl2ZShudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTdGFydCB0aGUgcmVwb3NpdG9yeSBzZXNzaW9uIGFuZCBhZGQgdGhpcyBoYW5kbGVyIGFzIGFuIG9ic2VydmVyCisgICAgICogZm9yIG5ldyBldmVudHMgY3JlYXRlZCBvbiBvdGhlciBub2Rlcy4KKyAgICAgKiBAdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzdGFydFdyaXRlclNlc3Npb24oKSB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMud3JpdGVyU2Vzc2lvbiA9IHRoaXMuY3JlYXRlU2Vzc2lvbigpOworICAgICAgICBpZiAoIHRoaXMucmVwb3NpdG9yeVBhdGggIT0gbnVsbCApIHsKKyAgICAgICAgICAgIHRoaXMuZW5zdXJlUmVwb3NpdG9yeVBhdGgoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIFN0b3AgdGhlIHNlc3Npb24uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgc3RvcFdyaXRlclNlc3Npb24oKSB7CisgICAgICAgIGlmICggdGhpcy53cml0ZXJTZXNzaW9uICE9IG51bGwgKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRoaXMud3JpdGVyU2Vzc2lvbi5nZXRXb3Jrc3BhY2UoKS5nZXRPYnNlcnZhdGlvbk1hbmFnZXIoKS5yZW1vdmVFdmVudExpc3RlbmVyKHRoaXMpOworICAgICAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gd2UganVzdCBpZ25vcmUgaXQKKyAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci53YXJuKCJVbmFibGUgdG8gcmVtb3ZlIGV2ZW50IGxpc3RlbmVyLiIsIGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdGhpcy53cml0ZXJTZXNzaW9uLmxvZ291dCgpOworICAgICAgICAgICAgdGhpcy53cml0ZXJTZXNzaW9uID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENoZWNrIGlmIHRoZSByZXBvc2l0b3J5IHBhdGggYWxyZWFkeSBleGlzdHMuIElmIG5vdCwgY3JlYXRlIGl0LgorICAgICAqLworICAgIHByb3RlY3RlZCBOb2RlIGVuc3VyZVJlcG9zaXRvcnlQYXRoKCkKKyAgICB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIGZpbmFsIE5vZGUgbm9kZSA9IEpjclJlc291cmNlVXRpbC5jcmVhdGVQYXRoKHRoaXMucmVwb3NpdG9yeVBhdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV2ZW50SGVscGVyLk5PREVUWVBFX0ZPTERFUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXZlbnRIZWxwZXIuTk9ERVRZUEVfT1JERVJFRF9GT0xERVIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud3JpdGVyU2Vzc2lvbiwgdHJ1ZSk7CisKKyAgICAgICAgcmV0dXJuIG5vZGU7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBub2RlIHR5cGUgZm9yIHRoZSBldmVudC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldEV2ZW50Tm9kZVR5cGUoKSB7CisgICAgICAgIHJldHVybiBFdmVudEhlbHBlci5FVkVOVF9OT0RFX1RZUEU7CisgICAgfQorCisgICAgLyoqCisgICAgICogV3JpdGUgYW4gZXZlbnQgdG8gdGhlIHJlcG9zaXRvcnkuCisgICAgICogQHBhcmFtIGUgVGhlIGV2ZW50CisgICAgICogQHBhcmFtIHN1Z2dlc3ROYW1lIEEgc3VnZ2VzdCBuYW1lL3BhdGggZm9yIHRoZSBub2RlLgorICAgICAqIEB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgTm9kZSB3cml0ZUV2ZW50KEV2ZW50IGUsIFN0cmluZyBzdWdnZXN0ZWROYW1lKQorICAgIHRocm93cyBSZXBvc2l0b3J5RXhjZXB0aW9uIHsKKyAgICAgICAgLy8gY3JlYXRlIG5ldyBub2RlIHdpdGggbmFtZSBvZiB0b3BpYworICAgICAgICBmaW5hbCBOb2RlIHJvb3ROb2RlID0gdGhpcy5lbnN1cmVSZXBvc2l0b3J5UGF0aCgpOworCisgICAgICAgIGZpbmFsIFN0cmluZyBub2RlVHlwZSA9IHRoaXMuZ2V0RXZlbnROb2RlVHlwZSgpOworICAgICAgICBmaW5hbCBTdHJpbmcgbm9kZU5hbWU7CisgICAgICAgIGlmICggc3VnZ2VzdGVkTmFtZSAhPSBudWxsICkgeworICAgICAgICAgICAgbm9kZU5hbWUgPSBzdWdnZXN0ZWROYW1lOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmluYWwgQ2FsZW5kYXIgbm93ID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgICAgIGZpbmFsIGludCBzZXBQb3MgPSBub2RlVHlwZS5pbmRleE9mKCc6Jyk7CisgICAgICAgICAgICBub2RlTmFtZSA9IG5vZGVUeXBlLnN1YnN0cmluZyhzZXBQb3MrMSkgKyAiLSIgKyB0aGlzLmFwcGxpY2F0aW9uSWQgKyAiLSIgKyBub3cuZ2V0VGltZSgpLmdldFRpbWUoKTsKKyAgICAgICAgfQorICAgICAgICBmaW5hbCBOb2RlIGV2ZW50Tm9kZSA9IEpjclJlc291cmNlVXRpbC5jcmVhdGVQYXRoKHJvb3ROb2RlLAorICAgICAgICAgICAgICAgIG5vZGVOYW1lLAorICAgICAgICAgICAgICAgIEV2ZW50SGVscGVyLk5PREVUWVBFX0ZPTERFUiwKKyAgICAgICAgICAgICAgICBub2RlVHlwZSwgZmFsc2UpOworCisgICAgICAgIGV2ZW50Tm9kZS5zZXRQcm9wZXJ0eShFdmVudEhlbHBlci5OT0RFX1BST1BFUlRZX0NSRUFURUQsIENhbGVuZGFyLmdldEluc3RhbmNlKCkpOworICAgICAgICBldmVudE5vZGUuc2V0UHJvcGVydHkoRXZlbnRIZWxwZXIuTk9ERV9QUk9QRVJUWV9UT1BJQywgZS5nZXRUb3BpYygpKTsKKyAgICAgICAgZXZlbnROb2RlLnNldFByb3BlcnR5KEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfQVBQTElDQVRJT04sIHRoaXMuYXBwbGljYXRpb25JZCk7CisKKyAgICAgICAgRXZlbnRVdGlsLmFkZFByb3BlcnRpZXMoZXZlbnROb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRXZlbnRQcm9wZXJ0aWVzTWFwKGUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJR05PUkVfUFJPUEVSVElFUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXZlbnRIZWxwZXIuTk9ERV9QUk9QRVJUWV9QUk9QRVJUSUVTKTsKKyAgICAgICAgdGhpcy5hZGROb2RlUHJvcGVydGllcyhldmVudE5vZGUsIGUpOworICAgICAgICByb290Tm9kZS5zYXZlKCk7CisKKyAgICAgICAgcmV0dXJuIGV2ZW50Tm9kZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBSZWFkIGFuIGV2ZW50IGZyb20gdGhlIHJlcG9zaXRvcnkuCisgICAgICogQHJldHVybgorICAgICAqIEB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbgorICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICAgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgRXZlbnQgcmVhZEV2ZW50KE5vZGUgZXZlbnROb2RlKQorICAgIHRocm93cyBSZXBvc2l0b3J5RXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIHRvcGljID0gZXZlbnROb2RlLmdldFByb3BlcnR5KEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfVE9QSUMpLmdldFN0cmluZygpOworICAgICAgICBmaW5hbCBFdmVudFByb3BlcnRpZXNNYXAgZXZlbnRQcm9wcyA9IEV2ZW50VXRpbC5yZWFkUHJvcGVydGllcyhldmVudE5vZGUsCisgICAgICAgICAgICAgICAgRXZlbnRIZWxwZXIuTk9ERV9QUk9QRVJUWV9QUk9QRVJUSUVTLAorICAgICAgICAgICAgICAgIElHTk9SRV9QUkVGSVhFUyk7CisKKyAgICAgICAgZXZlbnRQcm9wcy5wdXQoSm9iU3RhdHVzUHJvdmlkZXIuUFJPUEVSVFlfRVZFTlRfSUQsIGV2ZW50Tm9kZS5nZXRQYXRoKCkpOworICAgICAgICB0aGlzLmFkZEV2ZW50UHJvcGVydGllcyhldmVudE5vZGUsIGV2ZW50UHJvcHMpOworICAgICAgICB0cnkgeworICAgICAgICAgICAgZmluYWwgRXZlbnQgZXZlbnQgPSBuZXcgRXZlbnQodG9waWMsIGV2ZW50UHJvcHMpOworICAgICAgICAgICAgcmV0dXJuIGV2ZW50OworICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7CisgICAgICAgICAgICAvLyB0aGlzIGV4Y2VwdGlvbiBvY2N1cnMgaWYgdGhlIHRvcGljIGlzIG5vdCBjb3JyZWN0IChpdCBzaG91bGQgbmV2ZXIgaGFwcGVuLAorICAgICAgICAgICAgLy8gYnV0IHlvdSBuZXZlciBrbm93KQorICAgICAgICAgICAgdGhyb3cgbmV3IFJlcG9zaXRvcnlFeGNlcHRpb24oIlVuYWJsZSB0byByZWFkIGV2ZW50OiAiICsgaWFlLmdldE1lc3NhZ2UoKSwgaWFlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEFkZCBwcm9wZXJ0aWVzIGZyb20gdGhlIG5vZGUgdG8gdGhlIGV2ZW50IHByb3BlcnRpZXMuCisgICAgICogQHBhcmFtIGV2ZW50Tm9kZSBUaGUgcmVwb3NpdG9yeSBub2RlLgorICAgICAqIEBwYXJhbSBwcm9wZXJ0aWVzIFRoZSBldmVudCBwcm9wZXJ0aWVzLgorICAgICAqIEB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGFkZEV2ZW50UHJvcGVydGllcyhOb2RlIGV2ZW50Tm9kZSwgRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcGVydGllcykKKyAgICB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIC8vIG5vdGhpbmcgdG8gZG8KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGQgcHJvcGVydGllcyB3aGVuIHN0b3JpbmcgZXZlbnQgaW4gcmVwb3NpdG9yeS4KKyAgICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgZW5oYW5jZWQgYnkgc3ViIGNsYXNzZXMuCisgICAgICogQHBhcmFtIGV2ZW50Tm9kZQorICAgICAqIEBwYXJhbSBldmVudAorICAgICAqIEB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGFkZE5vZGVQcm9wZXJ0aWVzKE5vZGUgZXZlbnROb2RlLCBFdmVudCBldmVudCkKKyAgICB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIC8vIG5vdGhpbmcgdG8gZG8gaGVyZQorICAgIH0KKworICAgIC8qKgorICAgICAqIEhlbHBlciBtZXRob2Qgd2hpY2gganVzdCBsb2dzIHRoZSBleGNlcHRpb24gaW4gZGVidWcgbW9kZS4KKyAgICAgKiBAcGFyYW0gZQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGlnbm9yZUV4Y2VwdGlvbihFeGNlcHRpb24gZSkgeworICAgICAgICBpZiAoIHRoaXMubG9nZ2VyLmlzRGVidWdFbmFibGVkKCkgKSB7CisgICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZygiSWdub3JlIGV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCksIGUpOworICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBjbGFzcyBFdmVudEluZm8geworICAgICAgICBwdWJsaWMgU3RyaW5nIG5vZGVQYXRoOworICAgICAgICBwdWJsaWMgRXZlbnQgZXZlbnQ7CisgICAgfQorCit9CmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvaW1wbC9EaXN0cmlidXRpbmdFdmVudEhhbmRsZXIuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL0Rpc3RyaWJ1dGluZ0V2ZW50SGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRlMDc1NzEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvaW1wbC9EaXN0cmlidXRpbmdFdmVudEhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDI0MiBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5zbGluZy5ldmVudC5pbXBsOworCitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5EaWN0aW9uYXJ5OworCitpbXBvcnQgamF2YXguamNyLk5vZGU7CitpbXBvcnQgamF2YXguamNyLk5vZGVJdGVyYXRvcjsKK2ltcG9ydCBqYXZheC5qY3IuUmVwb3NpdG9yeUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5qY3IuU2Vzc2lvbjsKK2ltcG9ydCBqYXZheC5qY3Iub2JzZXJ2YXRpb24uRXZlbnRJdGVyYXRvcjsKK2ltcG9ydCBqYXZheC5qY3IucXVlcnkuUXVlcnk7CisKK2ltcG9ydCBvcmcuYXBhY2hlLmphY2tyYWJiaXQudXRpbC5JU084NjAxOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuY29tbW9ucy5vc2dpLk9zZ2lVdGlsOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuRXZlbnRVdGlsOworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudENvbnRleHQ7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudDsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmV2ZW50LkV2ZW50QWRtaW47CisKKy8qKgorICogVGhpcyBldmVudCBoYW5kbGVyIGRpc3RyaWJ1dGVzIGV2ZW50cyBhY3Jvc3MgYW4gYXBwbGljYXRpb24gY2x1c3Rlci4KKyAqIEBzY3IuY29tcG9uZW50IGluaGVyaXQ9InRydWUiIGxhYmVsPSIlZGlzdC5ldmVudHMubmFtZSIgZGVzY3JpcHRpb249IiVkaXN0LmV2ZW50cy5kZXNjcmlwdGlvbiIKKyAqIEBzY3IucHJvcGVydHkgbmFtZT0iZXZlbnQudG9waWNzIiB2YWx1ZT0iKiIgcHJpdmF0ZT0idHJ1ZSIKKyAqIEBzY3IucHJvcGVydHkgbmFtZT0iZXZlbnQuZmlsdGVyIiB2YWx1ZT0iKGV2ZW50LmRpc3RyaWJ1dGU9KikiIHByaXZhdGU9InRydWUiCisgKiBAc2NyLnByb3BlcnR5IG5hbWU9InJlcG9zaXRvcnkucGF0aCIgdmFsdWU9Ii92YXIvZXZlbnRpbmcvZGlzdHJpYnV0aW9uIiBwcml2YXRlPSJ0cnVlIgorICoKKyAqIFdlIHNjaGVkdWxlIHRoaXMgZXZlbnQgaGFuZGxlciB0byBydW4gaW4gdGhlIGJhY2tncm91bmQgYW5kIGNsZWFuIHVwCisgKiBvYnNvbGV0ZSBldmVudHMuCisgKiBAc2NyLnNlcnZpY2UgaW50ZXJmYWNlPSJqYXZhLmxhbmcuUnVubmFibGUiCisgKiBAc2NyLnByb3BlcnR5IG5hbWU9InNjaGVkdWxlci5wZXJpb2QiIHZhbHVlPSIxODAwIiB0eXBlPSJMb25nIgorICogQHNjci5wcm9wZXJ0eSBuYW1lPSJzY2hlZHVsZXIuY29uY3VycmVudCIgdmFsdWU9ImZhbHNlIiB0eXBlPSJCb29sZWFuIiBwcml2YXRlPSJ0cnVlIgorICovCitwdWJsaWMgY2xhc3MgRGlzdHJpYnV0aW5nRXZlbnRIYW5kbGVyCisgICAgZXh0ZW5kcyBBYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXIKKyAgICBpbXBsZW1lbnRzIFJ1bm5hYmxlIHsKKworICAgIC8qKiBEZWZhdWx0IGNsZWFuIHVwIHRpbWUgaXMgMTUgbWludXRlcy4gKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0NMRUFOVVBfUEVSSU9EID0gMTU7CisKKyAgICAvKiogQHNjci5wcm9wZXJ0eSB2YWx1ZVJlZj0iREVGQVVMVF9DTEVBTlVQX1BFUklPRCIgdHlwZT0iSW50ZWdlciIgKi8KKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBDT05GSUdfUFJPUEVSVFlfQ0xFQU5VUF9QRVJJT0QgPSAiY2xlYW51cC5wZXJpb2QiOworCisgICAgLyoqIFdlIHJlbW92ZSBldmVyeXRoaW5nIHdoaWNoIGlzIG9sZGVyIHRoYW4gMTVtaW4gYnkgZGVmYXVsdC4gKi8KKyAgICBwcm90ZWN0ZWQgaW50IGNsZWFudXBQZXJpb2QgPSBERUZBVUxUX0NMRUFOVVBfUEVSSU9EOworCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LmltcGwuQWJzdHJhY3RSZXBvc2l0b3J5RXZlbnRIYW5kbGVyI2FjdGl2YXRlKG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudENvbnRleHQpCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgYWN0aXZhdGUoQ29tcG9uZW50Q29udGV4dCBjb250ZXh0KQorICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgZmluYWwgRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBjb250ZXh0LmdldFByb3BlcnRpZXMoKTsKKyAgICAgICAgdGhpcy5jbGVhbnVwUGVyaW9kID0gT3NnaVV0aWwudG9JbnRlZ2VyKHByb3BzLmdldChDT05GSUdfUFJPUEVSVFlfQ0xFQU5VUF9QRVJJT0QpLCBERUZBVUxUX0NMRUFOVVBfUEVSSU9EKTsKKyAgICAgICAgc3VwZXIuYWN0aXZhdGUoY29udGV4dCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBxdWVyeSBzdHJpbmcgZm9yIHRoZSBjbGVhbiB1cC4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldENsZWFuVXBRdWVyeVN0cmluZygpIHsKKyAgICAgICAgZmluYWwgQ2FsZW5kYXIgZGVsZXRlQmVmb3JlID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgZGVsZXRlQmVmb3JlLmFkZChDYWxlbmRhci5NSU5VVEUsIC10aGlzLmNsZWFudXBQZXJpb2QpOworICAgICAgICBmaW5hbCBTdHJpbmcgZGF0ZVN0cmluZyA9IElTTzg2MDEuZm9ybWF0KGRlbGV0ZUJlZm9yZSk7CisKKyAgICAgICAgZmluYWwgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoIi9qY3I6cm9vdCIpOworICAgICAgICBidWZmZXIuYXBwZW5kKHRoaXMucmVwb3NpdG9yeVBhdGgpOworICAgICAgICBidWZmZXIuYXBwZW5kKCIvL2VsZW1lbnQoKiwgIik7CisgICAgICAgIGJ1ZmZlci5hcHBlbmQoZ2V0RXZlbnROb2RlVHlwZSgpKTsKKyAgICAgICAgYnVmZmVyLmFwcGVuZCgiKVtAIik7CisgICAgICAgIGJ1ZmZlci5hcHBlbmQoRXZlbnRIZWxwZXIuTk9ERV9QUk9QRVJUWV9DUkVBVEVEKTsKKyAgICAgICAgYnVmZmVyLmFwcGVuZCgiIDwgeHM6ZGF0ZVRpbWUoJyIpOworICAgICAgICBidWZmZXIuYXBwZW5kKGRhdGVTdHJpbmcpOworICAgICAgICBidWZmZXIuYXBwZW5kKCInKV0iKTsKKworICAgICAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgaXMgaW52b2tlZCBwZXJpb2RpY2FsbHkuCisgICAgICogQHNlZSBqYXZhLmxhbmcuUnVubmFibGUjcnVuKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgIGlmICggdGhpcy5jbGVhbnVwUGVyaW9kID4gMCApIHsKKyAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKCJDbGVhbmluZyB1cCByZXBvc2l0b3J5LCByZW1vdmluZyBhbGwgZW50cmllcyBvbGRlciB0aGFuIHt9IG1pbnV0ZXMuIiwgdGhpcy5jbGVhbnVwUGVyaW9kKTsKKworICAgICAgICAgICAgZmluYWwgU3RyaW5nIHF1ZXJ5U3RyaW5nID0gdGhpcy5nZXRDbGVhblVwUXVlcnlTdHJpbmcoKTsKKyAgICAgICAgICAgIC8vIHdlIGNyZWF0ZSBhbiBvd24gc2Vzc2lvbiBmb3IgY29uY3VycmVuY3kgaXNzdWVzCisgICAgICAgICAgICBTZXNzaW9uIHMgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzID0gdGhpcy5jcmVhdGVTZXNzaW9uKCk7CisgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBwYXJlbnROb2RlID0gKE5vZGUpcy5nZXRJdGVtKHRoaXMucmVwb3NpdG9yeVBhdGgpOworICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygiRXhlY3V0aW5nIHF1ZXJ5IHt9IiwgcXVlcnlTdHJpbmcpOworICAgICAgICAgICAgICAgIGZpbmFsIFF1ZXJ5IHEgPSBzLmdldFdvcmtzcGFjZSgpLmdldFF1ZXJ5TWFuYWdlcigpLmNyZWF0ZVF1ZXJ5KHF1ZXJ5U3RyaW5nLCBRdWVyeS5YUEFUSCk7CisgICAgICAgICAgICAgICAgZmluYWwgTm9kZUl0ZXJhdG9yIGl0ZXIgPSBxLmV4ZWN1dGUoKS5nZXROb2RlcygpOworICAgICAgICAgICAgICAgIGludCBjb3VudCA9IDA7CisgICAgICAgICAgICAgICAgd2hpbGUgKCBpdGVyLmhhc05leHQoKSApIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBldmVudE5vZGUgPSBpdGVyLm5leHROb2RlKCk7CisgICAgICAgICAgICAgICAgICAgIGV2ZW50Tm9kZS5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5zYXZlKCk7CisgICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCJSZW1vdmVkIHt9IGVudHJpZXMgZnJvbSB0aGUgcmVwb3NpdG9yeS4iLCBjb3VudCk7CisKKyAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIGluIHRoZSBjYXNlIG9mIGFuIGVycm9yLCB3ZSBqdXN0IGxvZyB0aGlzIGFzIGEgd2FybmluZworICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLndhcm4oIkV4Y2VwdGlvbiBkdXJpbmcgcmVwb3NpdG9yeSBjbGVhbnVwLiIsIGUpOworICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICBpZiAoIHMgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgcy5sb2dvdXQoKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbC5BYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXIjcHJvY2Vzc1dyaXRlUXVldWUoKQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NXcml0ZVF1ZXVlKCkgeworICAgICAgICB3aGlsZSAoIHRoaXMucnVubmluZyApIHsKKyAgICAgICAgICAgIC8vIHNvIGxldCdzIHdhaXQvZ2V0IHRoZSBuZXh0IGpvYiBmcm9tIHRoZSBxdWV1ZQorICAgICAgICAgICAgRXZlbnQgZXZlbnQgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBldmVudCA9IHRoaXMud3JpdGVRdWV1ZS50YWtlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gd2UgaWdub3JlIHRoaXMKKyAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICggZXZlbnQgIT0gbnVsbCAmJiB0aGlzLnJ1bm5pbmcgKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy53cml0ZUV2ZW50KGV2ZW50LCBudWxsKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcigiRXhjZXB0aW9uIGR1cmluZyB3cml0aW5nIHRoZSBldmVudCB0byB0aGUgcmVwb3NpdG9yeS4iLCBlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbC5BYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXIjcnVuSW5CYWNrZ3JvdW5kKCkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBydW5JbkJhY2tncm91bmQoKSB7CisgICAgICAgIHdoaWxlICggdGhpcy5ydW5uaW5nICkgeworICAgICAgICAgICAgLy8gc28gbGV0J3Mgd2FpdC9nZXQgdGhlIG5leHQgam9iIGZyb20gdGhlIHF1ZXVlCisgICAgICAgICAgICBFdmVudEluZm8gaW5mbyA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGluZm8gPSB0aGlzLnF1ZXVlLnRha2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhpcworICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCBpbmZvICE9IG51bGwgJiYgdGhpcy5ydW5uaW5nICkgeworICAgICAgICAgICAgICAgIGlmICggaW5mby5ub2RlUGF0aCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgIFNlc3Npb24gc2Vzc2lvbiA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uID0gdGhpcy5jcmVhdGVTZXNzaW9uKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIGV2ZW50Tm9kZSA9IChOb2RlKXNlc3Npb24uZ2V0SXRlbShpbmZvLm5vZGVQYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEV2ZW50QWRtaW4gbG9jYWxFQSA9IHRoaXMuZXZlbnRBZG1pbjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICggbG9jYWxFQSAhPSBudWxsICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsRUEucG9zdEV2ZW50KHRoaXMucmVhZEV2ZW50KGV2ZW50Tm9kZSkpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcigiVW5hYmxlIHRvIHBvc3QgZXZlbnQgYXMgbm8gZXZlbnQgYWRtaW4gaXMgYXZhaWxhYmxlLiIpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCJFeGNlcHRpb24gZHVyaW5nIHJlYWRpbmcgdGhlIGV2ZW50IGZyb20gdGhlIHJlcG9zaXRvcnkuIiwgZXgpOworICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBzZXNzaW9uICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5sb2dvdXQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudEhhbmRsZXIjaGFuZGxlRXZlbnQob3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBoYW5kbGVFdmVudChmaW5hbCBFdmVudCBldmVudCkgeworICAgICAgICB0cnkgeworICAgICAgICAgICAgdGhpcy53cml0ZVF1ZXVlLnB1dChldmVudCk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhpcworICAgICAgICAgICAgdGhpcy5pZ25vcmVFeGNlcHRpb24oZXgpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBqYXZheC5qY3Iub2JzZXJ2YXRpb24uRXZlbnRMaXN0ZW5lciNvbkV2ZW50KGphdmF4Lmpjci5vYnNlcnZhdGlvbi5FdmVudEl0ZXJhdG9yKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIG9uRXZlbnQoZmluYWwgRXZlbnRJdGVyYXRvciBpdGVyYXRvcikgeworICAgICAgICB3aGlsZSAoIGl0ZXJhdG9yLmhhc05leHQoKSApIHsKKyAgICAgICAgICAgIGZpbmFsIGphdmF4Lmpjci5vYnNlcnZhdGlvbi5FdmVudCBldmVudCA9IGl0ZXJhdG9yLm5leHRFdmVudCgpOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBmaW5hbCBFdmVudEluZm8gaW5mbyA9IG5ldyBFdmVudEluZm8oKTsKKyAgICAgICAgICAgICAgICBpbmZvLm5vZGVQYXRoID0gZXZlbnQuZ2V0UGF0aCgpOworICAgICAgICAgICAgICAgIHRoaXMucXVldWUucHV0KGluZm8pOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhpcworICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGV4KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcigiRXhjZXB0aW9uIGR1cmluZyByZWFkaW5nIHRoZSBldmVudCBmcm9tIHRoZSByZXBvc2l0b3J5LiIsIGV4KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5pbXBsLkFic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlciNhZGRFdmVudFByb3BlcnRpZXMoamF2YXguamNyLk5vZGUsIGphdmEudXRpbC5EaWN0aW9uYXJ5KQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGFkZEV2ZW50UHJvcGVydGllcyhOb2RlIGV2ZW50Tm9kZSwgRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcGVydGllcykKKyAgICB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLmFkZEV2ZW50UHJvcGVydGllcyhldmVudE5vZGUsIHByb3BlcnRpZXMpOworICAgICAgICBwcm9wZXJ0aWVzLnB1dChFdmVudFV0aWwuUFJPUEVSVFlfQVBQTElDQVRJT04sIGV2ZW50Tm9kZS5nZXRQcm9wZXJ0eShFdmVudEhlbHBlci5OT0RFX1BST1BFUlRZX0FQUExJQ0FUSU9OKS5nZXRTdHJpbmcoKSk7CisgICAgfQorCisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbC5BYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXIjc3RhcnRXcml0ZXJTZXNzaW9uKCkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzdGFydFdyaXRlclNlc3Npb24oKSB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnN0YXJ0V3JpdGVyU2Vzc2lvbigpOworICAgICAgICB0aGlzLndyaXRlclNlc3Npb24uZ2V0V29ya3NwYWNlKCkuZ2V0T2JzZXJ2YXRpb25NYW5hZ2VyKCkKKyAgICAgICAgICAgIC5hZGRFdmVudExpc3RlbmVyKHRoaXMsIGphdmF4Lmpjci5vYnNlcnZhdGlvbi5FdmVudC5OT0RFX0FEREVELCB0aGlzLnJlcG9zaXRvcnlQYXRoLCB0cnVlLCBudWxsLCBuZXcgU3RyaW5nW10ge3RoaXMuZ2V0RXZlbnROb2RlVHlwZSgpfSwgdHJ1ZSk7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L2ltcGwvRXZlbnRIZWxwZXIuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL0V2ZW50SGVscGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjVhMzg2YgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL0V2ZW50SGVscGVyLmphdmEKQEAgLTAsMCArMSw5NCBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5zbGluZy5ldmVudC5pbXBsOworCisKKy8qKgorICogSGVscGVyIGNsYXNzIGRlZmluaW5nIHNvbWUgY29uc3RhbnRzIGFuZCB1dGlsaXR5IG1ldGhvZHMuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBFdmVudEhlbHBlciB7CisKKyAgICAvKiogVGhlIG5hbWUgb2YgdGhlIHRocmVhZCBwb29sIGZvciB0aGUgZXZlbnRpbmcgc3R1ZmYuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEhSRUFEX1BPT0xfTkFNRSA9ICJTTElOR19FVkVOVElORyI7CisKKyAgICAvKiogVGhlIG5hbWVzcGFjZSBwcmVmaXguICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVZFTlRfUFJFRklYID0gInNsaW5nZXZlbnQ6IjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfUFJPUEVSVFlfVE9QSUMgPSAic2xpbmdldmVudDp0b3BpYyI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERV9QUk9QRVJUWV9BUFBMSUNBVElPTiA9ICJzbGluZ2V2ZW50OmFwcGxpY2F0aW9uIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX1BST1BFUlRZX0NSRUFURUQgPSAic2xpbmdldmVudDpjcmVhdGVkIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX1BST1BFUlRZX1BST1BFUlRJRVMgPSAic2xpbmdldmVudDpwcm9wZXJ0aWVzIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX1BST1BFUlRZX1BST0NFU1NPUiA9ICJzbGluZ2V2ZW50OnByb2Nlc3NvciI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTk9ERV9QUk9QRVJUWV9KT0JJRCA9ICJzbGluZ2V2ZW50OmlkIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFX1BST1BFUlRZX0ZJTklTSEVEID0gInNsaW5nZXZlbnQ6ZmluaXNoZWQiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfUFJPUEVSVFlfVEVfRVhQUkVTU0lPTiA9ICJzbGluZ2V2ZW50OmV4cHJlc3Npb24iOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfUFJPUEVSVFlfVEVfREFURSA9ICJzbGluZ2V2ZW50OmRhdGUiOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVfUFJPUEVSVFlfVEVfUEVSSU9EID0gInNsaW5nZXZlbnQ6cGVyaW9kIjsKKworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVWRU5UX05PREVfVFlQRSA9ICJzbGluZ2V2ZW50OkV2ZW50IjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBKT0JfTk9ERV9UWVBFID0gInNsaW5nZXZlbnQ6Sm9iIjsKKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUSU1FRF9FVkVOVF9OT0RFX1RZUEUgPSAic2xpbmdldmVudDpUaW1lZEV2ZW50IjsKKworICAgIC8qKiBUaGUgbm9kZXR5cGUgZm9yIG5ld2x5IGNyZWF0ZWQgaW50ZXJtZWRpYXRlIGZvbGRlcnMgKi8KKyAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT0RFVFlQRV9GT0xERVIgPSAic2xpbmc6Rm9sZGVyIjsKKworICAgIC8qKiBUaGUgbm9kZXR5cGUgZm9yIG5ld2x5IGNyZWF0ZWQgZm9sZGVycyAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE5PREVUWVBFX09SREVSRURfRk9MREVSID0gInNsaW5nOk9yZGVyZWRGb2xkZXIiOworCisgICAgLyoqIEFsbG93ZWQgY2hhcmFjdGVycyBmb3IgYSBub2RlIG5hbWUgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxMT1dFRF9DSEFSUyA9ICJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiBhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODlfLC4tKyojIaQkJSYoKT1bXT8iOworICAgIC8qKiBSZXBsYWNlbWVudCBjaGFyYWN0ZXJzIGZvciB1bmFsbG93ZWQgY2hhcmFjdGVycyBpbiBhIG5vZGUgbmFtZSAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgUkVQTEFDRU1FTlRfQ0hBUiA9ICdfJzsKKworICAgIC8qKgorICAgICAqIEZpbHRlciB0aGUgbm9kZSBuYW1lIGZvciBub3QgYWxsb3dlZCBjaGFyYWN0ZXJzIGFuZCByZXBsYWNlIHRoZW0uCisgICAgICogQHBhcmFtIG5vZGVOYW1lIFRoZSBzdWdnZXN0ZWQgbm9kZSBuYW1lLgorICAgICAqIEByZXR1cm4gVGhlIGZpbHRlcmVkIG5vZGUgbmFtZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBmaWx0ZXIoZmluYWwgU3RyaW5nIG5vZGVOYW1lKSB7CisgICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBzYiAgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisgICAgICAgIGNoYXIgbGFzdEFkZGVkID0gMDsKKworICAgICAgICBmb3IoaW50IGk9MDsgaSA8IG5vZGVOYW1lLmxlbmd0aCgpOyBpKyspIHsKKyAgICAgICAgICAgIGZpbmFsIGNoYXIgYyA9IG5vZGVOYW1lLmNoYXJBdChpKTsKKyAgICAgICAgICAgIGNoYXIgdG9BZGQgPSBjOworCisgICAgICAgICAgICBpZiAoQUxMT1dFRF9DSEFSUy5pbmRleE9mKGMpIDwgMCkgeworICAgICAgICAgICAgICAgIGlmIChsYXN0QWRkZWQgPT0gUkVQTEFDRU1FTlRfQ0hBUikgeworICAgICAgICAgICAgICAgICAgICAvLyBkbyBub3QgYWRkIHNldmVyYWwgXyBpbiBhIHJvdworICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdG9BZGQgPSBSRVBMQUNFTUVOVF9DSEFSOworCisgICAgICAgICAgICB9IGVsc2UgaWYoaSA9PSAwICYmIENoYXJhY3Rlci5pc0RpZ2l0KGMpKSB7CisgICAgICAgICAgICAgICAgc2IuYXBwZW5kKFJFUExBQ0VNRU5UX0NIQVIpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzYi5hcHBlbmQodG9BZGQpOworICAgICAgICAgICAgbGFzdEFkZGVkID0gdG9BZGQ7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc2IubGVuZ3RoKCk9PTApIHsKKyAgICAgICAgICAgIHNiLmFwcGVuZChSRVBMQUNFTUVOVF9DSEFSKTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L2ltcGwvRXZlbnRpbmdUaHJlYWRQb29sLmphdmEgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvaW1wbC9FdmVudGluZ1RocmVhZFBvb2wuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYTlmOTFhCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L2ltcGwvRXZlbnRpbmdUaHJlYWRQb29sLmphdmEKQEAgLTAsMCArMSwxMTAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbDsKKworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuY29tbW9ucy5vc2dpLk9zZ2lVdGlsOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuY29tbW9ucy50aHJlYWRzLlRocmVhZFBvb2xDb25maWc7CitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5jb21tb25zLnRocmVhZHMuVGhyZWFkUG9vbE1hbmFnZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5UaHJlYWRQb29sOworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudENvbnRleHQ7CisKKworLyoqCisgKiBUaGUgY29uZmlndXJhYmxlIGV2ZW50aW5nIHRocmVhZCBwb29sLgorICogQHNjci5jb21wb25lbnQgbGFiZWw9IiVldmVudC5wb29sLm5hbWUiIGRlc2NyaXB0aW9uPSIlZXZlbnQucG9vbC5kZXNjcmlwdGlvbiIKKyAqIEBzY3Iuc2VydmljZSBpbnRlcmZhY2U9Im9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuVGhyZWFkUG9vbCIKKyAqCisgKiBAc2NyLnByb3BlcnR5IG5hbWVSZWY9IlBST1BFUlRZX01JTl9QT09MX1NJWkUiIHZhbHVlUmVmPSJERUZBVUxUX01JTl9QT09MX1NJWkUiCisgKiBAc2NyLnByb3BlcnR5IG5hbWVSZWY9IlBST1BFUlRZX01BWF9QT09MX1NJWkUiIHZhbHVlUmVmPSJERUZBVUxUX01BWF9QT09MX1NJWkUiCisgKiBAc2NyLnByb3BlcnR5IG5hbWVSZWY9IlBST1BFUlRZX1FVRVVFTF9TSVpFIiB2YWx1ZVJlZj0iREVGQVVMVF9RVUVVRV9TSVpFIgorICovCitwdWJsaWMgY2xhc3MgRXZlbnRpbmdUaHJlYWRQb29sIGltcGxlbWVudHMgVGhyZWFkUG9vbCB7CisKKyAgICAvKiogQHNjci5yZWZlcmVuY2UgKi8KKyAgICBwcm90ZWN0ZWQgVGhyZWFkUG9vbE1hbmFnZXIgdGhyZWFkUG9vbE1hbmFnZXI7CisKKyAgICAvKiogVGhlIHJlYWwgdGhyZWFkIHBvb2wgdXNlZC4gKi8KKyAgICBwcml2YXRlIG9yZy5hcGFjaGUuc2xpbmcuY29tbW9ucy50aHJlYWRzLlRocmVhZFBvb2wgdGhyZWFkUG9vbDsKKworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QRVJUWV9NSU5fUE9PTF9TSVpFID0gIm1pblBvb2xTaXplIjsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPUEVSVFlfTUFYX1BPT0xfU0laRSA9ICJtYXhQb29sU2l6ZSI7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBST1BFUlRZX1FVRVVFTF9TSVpFID0gInF1ZXVlU2l6ZSI7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9NSU5fUE9PTF9TSVpFID0gMjA7IC8vIHRoaXMgaXMgc3VmZmljaWVudCBmb3IgYWxsIHRocmVhZHMgKyBhcHByb3ggMTAgam9iIHF1ZXVlcworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX01BWF9QT09MX1NJWkUgPSAzMDsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9RVUVVRV9TSVpFID0gNTA7IC8vIHF1ZXVlIHVwdG8gNTAgdGhyZWFkcworCisgICAgLyoqCisgICAgICogQWN0aXZhdGUgdGhpcyBjb21wb25lbnQuCisgICAgICogQHBhcmFtIGNvbnRleHQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBhY3RpdmF0ZShmaW5hbCBDb21wb25lbnRDb250ZXh0IGN0eCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIC8vIHN0YXJ0IGJhY2tncm91bmQgdGhyZWFkcworICAgICAgICBpZiAoIHRoaXMudGhyZWFkUG9vbE1hbmFnZXIgPT0gbnVsbCApIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIk5vIFRocmVhZFBvb2xNYW5hZ2VyIGZvdW5kLiIpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIFRocmVhZFBvb2xDb25maWcgY29uZmlnID0gbmV3IFRocmVhZFBvb2xDb25maWcoKTsKKyAgICAgICAgY29uZmlnLnNldE1pblBvb2xTaXplKE9zZ2lVdGlsLnRvSW50ZWdlcihjdHguZ2V0UHJvcGVydGllcygpLmdldChQUk9QRVJUWV9NSU5fUE9PTF9TSVpFKSwgREVGQVVMVF9NSU5fUE9PTF9TSVpFKSk7CisgICAgICAgIGNvbmZpZy5zZXRNYXhQb29sU2l6ZShPc2dpVXRpbC50b0ludGVnZXIoY3R4LmdldFByb3BlcnRpZXMoKS5nZXQoUFJPUEVSVFlfTUFYX1BPT0xfU0laRSksIERFRkFVTFRfTUFYX1BPT0xfU0laRSkpOworICAgICAgICBjb25maWcuc2V0UXVldWVTaXplKE9zZ2lVdGlsLnRvSW50ZWdlcihjdHguZ2V0UHJvcGVydGllcygpLmdldChQUk9QRVJUWV9RVUVVRUxfU0laRSksIERFRkFVTFRfUVVFVUVfU0laRSkpOworICAgICAgICBjb25maWcuc2V0U2h1dGRvd25HcmFjZWZ1bCh0cnVlKTsKKyAgICAgICAgdGhyZWFkUG9vbE1hbmFnZXIuY3JlYXRlKEV2ZW50SGVscGVyLlRIUkVBRF9QT09MX05BTUUsIGNvbmZpZyk7CisKKyAgICAgICAgdGhpcy50aHJlYWRQb29sID0gdGhyZWFkUG9vbE1hbmFnZXIuZ2V0KEV2ZW50SGVscGVyLlRIUkVBRF9QT09MX05BTUUpOworICAgICAgICBpZiAoIHRoaXMudGhyZWFkUG9vbCA9PSBudWxsICkgeworICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiTm8gdGhyZWFkIHBvb2wgd2l0aCBuYW1lICIgKyBFdmVudEhlbHBlci5USFJFQURfUE9PTF9OQU1FICsgIiBmb3VuZC4iKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIERlYWN0aXZhdGUgdGhpcyBjb21wb25lbnQuCisgICAgICogQHBhcmFtIGNvbnRleHQKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBkZWFjdGl2YXRlKGZpbmFsIENvbXBvbmVudENvbnRleHQgY29udGV4dCkgeworICAgICAgICB0aGlzLnRocmVhZFBvb2wgPSBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5jb21tb25zLnRocmVhZHMuVGhyZWFkUG9vbCNleGVjdXRlKGphdmEubGFuZy5SdW5uYWJsZSkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBleGVjdXRlKFJ1bm5hYmxlIHJ1bm5hYmxlKSB7CisgICAgICAgIHRocmVhZFBvb2wuZXhlY3V0ZShydW5uYWJsZSk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMudGhyZWFkcy5UaHJlYWRQb29sI2dldENvbmZpZ3VyYXRpb24oKQorICAgICAqLworICAgIHB1YmxpYyBUaHJlYWRQb29sQ29uZmlnIGdldENvbmZpZ3VyYXRpb24oKSB7CisgICAgICAgIHJldHVybiB0aHJlYWRQb29sLmdldENvbmZpZ3VyYXRpb24oKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuY29tbW9ucy50aHJlYWRzLlRocmVhZFBvb2wjZ2V0TmFtZSgpCisgICAgICovCisgICAgcHVibGljIFN0cmluZyBnZXROYW1lKCkgeworICAgICAgICByZXR1cm4gdGhyZWFkUG9vbC5nZXROYW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMudGhyZWFkcy5UaHJlYWRQb29sI3NodXRkb3duKCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHsKKyAgICAgICAgdGhyZWFkUG9vbC5zaHV0ZG93bigpOworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL0pvYkJsb2NraW5nUXVldWUuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL0pvYkJsb2NraW5nUXVldWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44OWE2YmMzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L2ltcGwvSm9iQmxvY2tpbmdRdWV1ZS5qYXZhCkBAIC0wLDAgKzEsMTE3IEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LmltcGw7CisKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5MaW5rZWRCbG9ja2luZ1F1ZXVlOworCitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5pbXBsLkFic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlci5FdmVudEluZm87CisKKy8qKgorICogVGhlIGpvYiBibG9ja2luZyBxdWV1ZSBleHRlbmRzIHRoZSBibG9ja2luZyBxdWV1ZSBieSBzb21lCisgKiBmdW5jdGlvbmFsaXR5IGZvciB0aGUgam9iIGV2ZW50IGhhbmRsaW5nLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgSm9iQmxvY2tpbmdRdWV1ZSBleHRlbmRzIExpbmtlZEJsb2NraW5nUXVldWU8RXZlbnRJbmZvPiB7CisKKyAgICBwcml2YXRlIEV2ZW50SW5mbyBldmVudEluZm87CisKKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdCBsb2NrID0gbmV3IE9iamVjdCgpOworCisgICAgcHJpdmF0ZSBib29sZWFuIGlzV2FpdGluZyA9IGZhbHNlOworCisgICAgcHJpdmF0ZSBib29sZWFuIG1hcmtGb3JDbGVhblVwID0gZmFsc2U7CisKKyAgICBwcml2YXRlIGJvb2xlYW4gZmluaXNoZWQgPSBmYWxzZTsKKworICAgIHByaXZhdGUgYm9vbGVhbiBpc1NsZWVwaW5nID0gZmFsc2U7CisKKyAgICBwcml2YXRlIFN0cmluZyBzY2hlZHVsZXJKb2JOYW1lOworICAgIHByaXZhdGUgVGhyZWFkIHNsZWVwaW5nVGhyZWFkOworCisgICAgcHVibGljIEV2ZW50SW5mbyB3YWl0Rm9yRmluaXNoKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5pc1dhaXRpbmcgPSB0cnVlOworICAgICAgICB0aGlzLm1hcmtGb3JDbGVhblVwID0gZmFsc2U7CisgICAgICAgIHRoaXMubG9jay53YWl0KCk7CisgICAgICAgIHRoaXMuaXNXYWl0aW5nID0gZmFsc2U7CisgICAgICAgIGZpbmFsIEV2ZW50SW5mbyBvYmplY3QgPSB0aGlzLmV2ZW50SW5mbzsKKyAgICAgICAgdGhpcy5ldmVudEluZm8gPSBudWxsOworICAgICAgICByZXR1cm4gb2JqZWN0OworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIG1hcmtGb3JDbGVhblVwKCkgeworICAgICAgICBpZiAoICF0aGlzLmlzV2FpdGluZyApIHsKKyAgICAgICAgICAgIHRoaXMubWFya0ZvckNsZWFuVXAgPSB0cnVlOworICAgICAgICB9CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNNYXJrZWRGb3JDbGVhblVwKCkgeworICAgICAgICByZXR1cm4gIXRoaXMuaXNXYWl0aW5nICYmIHRoaXMubWFya0ZvckNsZWFuVXA7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgbm90aWZ5RmluaXNoKEV2ZW50SW5mbyBpKSB7CisgICAgICAgIHRoaXMuZXZlbnRJbmZvID0gaTsKKyAgICAgICAgdGhpcy5sb2NrLm5vdGlmeSgpOworICAgIH0KKworICAgIHB1YmxpYyBPYmplY3QgZ2V0TG9jaygpIHsKKyAgICAgICAgcmV0dXJuIGxvY2s7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNXYWl0aW5nKCkgeworICAgICAgICByZXR1cm4gdGhpcy5pc1dhaXRpbmc7CisgICAgfQorCisgICAgcHVibGljIGJvb2xlYW4gaXNGaW5pc2hlZCgpIHsKKyAgICAgICAgcmV0dXJuIGZpbmlzaGVkOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldEZpbmlzaGVkKGJvb2xlYW4gZmxhZykgeworICAgICAgICB0aGlzLmZpbmlzaGVkID0gZmxhZzsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTbGVlcGluZyhib29sZWFuIGZsYWcpIHsKKyAgICAgICAgdGhpcy5pc1NsZWVwaW5nID0gZmxhZzsKKyAgICAgICAgaWYgKCAhZmxhZyApIHsKKyAgICAgICAgICAgIHRoaXMuc2NoZWR1bGVySm9iTmFtZSA9IG51bGw7CisgICAgICAgICAgICB0aGlzLnNsZWVwaW5nVGhyZWFkID0gbnVsbDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHNldFNsZWVwaW5nKGJvb2xlYW4gZmxhZywgU3RyaW5nIHNjaGVkdWxlckpvYk5hbWUpIHsKKyAgICAgICAgdGhpcy5zY2hlZHVsZXJKb2JOYW1lID0gc2NoZWR1bGVySm9iTmFtZTsKKyAgICAgICAgdGhpcy5zZXRTbGVlcGluZyhmbGFnKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBzZXRTbGVlcGluZyhib29sZWFuIGZsYWcsIFRocmVhZCBzbGVlcGluZ1RocmVhZCkgeworICAgICAgICB0aGlzLnNsZWVwaW5nVGhyZWFkID0gc2xlZXBpbmdUaHJlYWQ7CisgICAgICAgIHRoaXMuc2V0U2xlZXBpbmcoZmxhZyk7CisgICAgfQorCisgICAgcHVibGljIFN0cmluZyBnZXRTY2hlZHVsZXJKb2JOYW1lKCkgeworICAgICAgICByZXR1cm4gdGhpcy5zY2hlZHVsZXJKb2JOYW1lOworICAgIH0KKworICAgIHB1YmxpYyBUaHJlYWQgZ2V0U2xlZXBpbmdUaHJlYWQoKSB7CisgICAgICAgIHJldHVybiB0aGlzLnNsZWVwaW5nVGhyZWFkOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzU2xlZXBpbmcoKSB7CisgICAgICAgIHJldHVybiB0aGlzLmlzU2xlZXBpbmc7CisgICAgfQorfQorCmRpZmYgLS1naXQgYS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvaW1wbC9Kb2JFdmVudEhhbmRsZXIuamF2YSBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL0pvYkV2ZW50SGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhOWIxODcKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvaW1wbC9Kb2JFdmVudEhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDE1MTAgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbDsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGphdmEudXRpbC5EYXRlOworaW1wb3J0IGphdmEudXRpbC5EaWN0aW9uYXJ5OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLlVVSUQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQmxvY2tpbmdRdWV1ZTsKKworaW1wb3J0IGphdmF4Lmpjci5JdGVtOworaW1wb3J0IGphdmF4Lmpjci5JdGVtRXhpc3RzRXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lmpjci5Ob2RlOworaW1wb3J0IGphdmF4Lmpjci5Ob2RlSXRlcmF0b3I7CitpbXBvcnQgamF2YXguamNyLlJlcG9zaXRvcnlFeGNlcHRpb247CitpbXBvcnQgamF2YXguamNyLlNlc3Npb247CitpbXBvcnQgamF2YXguamNyLlZhbHVlOworaW1wb3J0IGphdmF4Lmpjci5vYnNlcnZhdGlvbi5FdmVudEl0ZXJhdG9yOworaW1wb3J0IGphdmF4Lmpjci5xdWVyeS5RdWVyeTsKK2ltcG9ydCBqYXZheC5qY3IucXVlcnkuUXVlcnlNYW5hZ2VyOworCitpbXBvcnQgb3JnLmFwYWNoZS5qYWNrcmFiYml0LnV0aWwuSVNPODYwMTsKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMub3NnaS5Pc2dpVXRpbDsKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMuc2NoZWR1bGVyLlNjaGVkdWxlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMudGhyZWFkcy5UaHJlYWRQb29sOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuRXZlbnRQcm9wZXJ0aWVzTWFwOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuRXZlbnRVdGlsOworaW1wb3J0IG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuSm9iU3RhdHVzUHJvdmlkZXI7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkNvbnN0YW50czsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC5Db21wb25lbnRDb25zdGFudHM7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50Q29udGV4dDsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmV2ZW50LkV2ZW50OworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuZXZlbnQuRXZlbnRBZG1pbjsKKworCisvKioKKyAqIEFuIGV2ZW50IGhhbmRsZXIgZm9yIHNwZWNpYWwgam9iIGV2ZW50cy4KKyAqCisgKiBAc2NyLmNvbXBvbmVudCBsYWJlbD0iJWpvYi5ldmVudHMubmFtZSIgZGVzY3JpcHRpb249IiVqb2IuZXZlbnRzLmRlc2NyaXB0aW9uIiBpbW1lZGlhdGU9InRydWUiCisgKiBAc2NyLnNlcnZpY2UgaW50ZXJmYWNlPSJvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LkpvYlN0YXR1c1Byb3ZpZGVyIgorICogQHNjci5wcm9wZXJ0eSBuYW1lPSJldmVudC50b3BpY3MiIHJlZlZhbHVlcz0iRXZlbnRVdGlsLlRPUElDX0pPQiIKKyAqICAgICAgICAgICAgICAgdmFsdWVzLnVwZGF0ZWQ9Im9yZy9vc2dpL2ZyYW1ld29yay9CdW5kbGVFdmVudC9VUERBVEVEIgorICogICAgICAgICAgICAgICB2YWx1ZXMuc3RhcnRlZD0ib3JnL29zZ2kvZnJhbWV3b3JrL0J1bmRsZUV2ZW50L1NUQVJURUQiCisgKiAgICAgICAgICAgICAgIHByaXZhdGU9InRydWUiCisgKiBAc2NyLnByb3BlcnR5IG5hbWU9InJlcG9zaXRvcnkucGF0aCIgdmFsdWU9Ii92YXIvZXZlbnRpbmcvam9icyIgcHJpdmF0ZT0idHJ1ZSIKKyAqIFdlIHNjaGVkdWxlIHRoaXMgZXZlbnQgaGFuZGxlciB0byBydW4gaW4gdGhlIGJhY2tncm91bmQgYW5kIGNsZWFuIHVwCisgKiBvYnNvbGV0ZSBldmVudHMuCisgKiBAc2NyLnNlcnZpY2UgaW50ZXJmYWNlPSJqYXZhLmxhbmcuUnVubmFibGUiCisgKiBAc2NyLnByb3BlcnR5IG5hbWU9InNjaGVkdWxlci5wZXJpb2QiIHZhbHVlPSIzMDAiIHR5cGU9IkxvbmciIGxhYmVsPSIlam9ic2NoZWR1bGVyLnBlcmlvZC5uYW1lIiBkZXNjcmlwdGlvbj0iJWpvYnNjaGVkdWxlci5wZXJpb2QuZGVzY3JpcHRpb24iCisgKiBAc2NyLnByb3BlcnR5IG5hbWU9InNjaGVkdWxlci5jb25jdXJyZW50IiB2YWx1ZT0iZmFsc2UiIHR5cGU9IkJvb2xlYW4iIHByaXZhdGU9InRydWUiCisgKi8KK3B1YmxpYyBjbGFzcyBKb2JFdmVudEhhbmRsZXIKKyAgICBleHRlbmRzIEFic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlcgorICAgIGltcGxlbWVudHMgRXZlbnRVdGlsLkpvYlN0YXR1c05vdGlmaWVyLCBKb2JTdGF0dXNQcm92aWRlciwgUnVubmFibGUgeworCisgICAgLyoqIEEgbWFwIGZvciBrZWVwaW5nIHRyYWNrIG9mIGN1cnJlbnRseSBwcm9jZXNzZWQgam9iIHRvcGljcy4gKi8KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIEJvb2xlYW4+IHByb2Nlc3NpbmdNYXAgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIEJvb2xlYW4+KCk7CisKKyAgICAvKiogQSBtYXAgZm9yIHRoZSBkaWZmZXJlbnQgam9iIHF1ZXVlcy4gKi8KKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIEpvYkJsb2NraW5nUXVldWU+IGpvYlF1ZXVlcyA9IG5ldyBIYXNoTWFwPFN0cmluZywgSm9iQmxvY2tpbmdRdWV1ZT4oKTsKKworICAgIC8qKiBEZWZhdWx0IHNsZWVwIHRpbWUuICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBERUZBVUxUX1NMRUVQX1RJTUUgPSAzMDsKKworICAgIC8qKiBAc2NyLnByb3BlcnR5IHZhbHVlUmVmPSJERUZBVUxUX1NMRUVQX1RJTUUiICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIENPTkZJR19QUk9QRVJUWV9TTEVFUF9USU1FID0gInNsZWVwLnRpbWUiOworCisgICAgLyoqIERlZmF1bHQgbnVtYmVyIG9mIGpvYiByZXRyaWVzLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX01BWF9KT0JfUkVUUklFUyA9IDEwOworCisgICAgLyoqIEBzY3IucHJvcGVydHkgdmFsdWVSZWY9IkRFRkFVTFRfTUFYX0pPQl9SRVRSSUVTIiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDT05GSUdfUFJPUEVSVFlfTUFYX0pPQl9SRVRSSUVTID0gIm1heC5qb2IucmV0cmllcyI7CisKKyAgICAvKiogRGVmYXVsdCBudW1iZXIgb2Ygc2Vjb25kcyB0byB3YWl0IGZvciBhbiBhY2suICovCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBERUZBVUxUX1dBSVRfRk9SX0FDSyA9IDkwOyAvLyBieSBkZWZhdWx0IHdlIHdhaXQgOTAgc2VjcworCisgICAgLyoqIEBzY3IucHJvcGVydHkgdmFsdWVSZWY9IkRFRkFVTFRfTUFYSU1VTV9QQVJBTExFTF9KT0JTIiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDT05GSUdfUFJPUEVSVFlfTUFYSU1VTV9QQVJBTExFTF9KT0JTID0gIm1heC5wYXJhbGxlbC5qb2JzIjsKKworICAgIC8qKiBEZWZhdWx0IG51Ym1lciBvZiBwYXJhbGxlbCBqb2JzLiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgREVGQVVMVF9NQVhJTVVNX1BBUkFMTEVMX0pPQlMgPSAxNTsKKworICAgIC8qKiBAc2NyLnByb3BlcnR5IHZhbHVlUmVmPSJERUZBVUxUX1dBSVRfRk9SX0FDSyIgKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09ORklHX1BST1BFUlRZX1dBSVRfRk9SX0FDSyA9ICJ3YWl0LmZvci5hY2siOworCisgICAgLyoqIFdlIGNoZWNrIGV2ZXJ5IDMwIHNlY3MgYnkgZGVmYXVsdC4gKi8KKyAgICBwcml2YXRlIGxvbmcgc2xlZXBUaW1lOworCisgICAgLyoqIEhvdyBvZnRlbiBzaG91bGQgYSBqb2IgYmUgcmV0cmllZCBieSBkZWZhdWx0LiAqLworICAgIHByaXZhdGUgaW50IG1heEpvYlJldHJpZXM7CisKKyAgICAvKiogSG93IGxvbmcgZG8gd2Ugd2FpdCBmb3IgYW4gYWNrIChpbiBtcykgKi8KKyAgICBwcml2YXRlIGxvbmcgd2FpdEZvckFja01zOworCisgICAgLyoqIE1heGltdW0gcGFyYWxsZWwgcnVubmluZyBqb2JzIGZvciBhIHNpbmdsZSBxdWV1ZS4gKi8KKyAgICBwcml2YXRlIGxvbmcgbWF4aW11bVBhcmFsbGVsSm9iczsKKworICAgIC8qKiBCYWNrZ3JvdW5kIHNlc3Npb24uICovCisgICAgcHJpdmF0ZSBTZXNzaW9uIGJhY2tncm91bmRTZXNzaW9uOworCisgICAgLyoqIFVubG9hZGVkIGpvYnMuICovCisgICAgcHJpdmF0ZSBTZXQ8U3RyaW5nPnVubG9hZGVkSm9icyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKworICAgIC8qKiBMaXN0IG9mIGRlbGV0ZWQgam9icy4gKi8KKyAgICBwcml2YXRlIFNldDxTdHJpbmc+ZGVsZXRlZEpvYnMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisKKyAgICAvKiogRGVmYXVsdCBjbGVhbiB1cCB0aW1lIGlzIDUgbWludXRlcy4gKi8KKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9DTEVBTlVQX1BFUklPRCA9IDU7CisKKyAgICAvKiogQHNjci5wcm9wZXJ0eSB2YWx1ZVJlZj0iREVGQVVMVF9DTEVBTlVQX1BFUklPRCIgdHlwZT0iSW50ZWdlciIgbGFiZWw9IiVqb2JjbGVhbnVwLnBlcmlvZC5uYW1lIiBkZXNjcmlwdGlvbj0iJWpvYmNsZWFudXAucGVyaW9kLmRlc2NyaXB0aW9uIiAqLworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDT05GSUdfUFJPUEVSVFlfQ0xFQU5VUF9QRVJJT0QgPSAiY2xlYW51cC5wZXJpb2QiOworCisgICAgLyoqIFdlIHJlbW92ZSBldmVyeXRoaW5nIHdoaWNoIGlzIG9sZGVyIHRoYW4gNSBtaW4gYnkgZGVmYXVsdC4gKi8KKyAgICBwcml2YXRlIGludCBjbGVhbnVwUGVyaW9kID0gREVGQVVMVF9DTEVBTlVQX1BFUklPRDsKKworICAgIC8qKiBUaGUgc2NoZWR1bGVyIGZvciByZXNjaGVkdWxpbmcgam9icy4gQHNjci5yZWZlcmVuY2UgKi8KKyAgICBwcml2YXRlIFNjaGVkdWxlciBzY2hlZHVsZXI7CisKKyAgICAvKiogT3VyIGNvbXBvbmVudCBjb250ZXh0LiAqLworICAgIHByaXZhdGUgQ29tcG9uZW50Q29udGV4dCBjb21wb25lbnRDb250ZXh0OworCisgICAgLyoqIFRoZSBtYXAgb2YgZXZlbnRzIHdlJ3JlIGN1cnJlbnRseSBwcm9jZXNzaW5nLiAqLworICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgU3RhcnRlZEpvYkluZm8+IHByb2Nlc3NpbmdFdmVudHNMaXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdGFydGVkSm9iSW5mbz4oKTsKKworICAgIHB1YmxpYyBzdGF0aWMgVGhyZWFkUG9vbCBKT0JfVEhSRUFEX1BPT0w7CisKKyAgICAvKiogU3luYyBsb2NrICovCisgICAgcHJpdmF0ZSBmaW5hbCBPYmplY3Qgd3JpdGVMb2NrID0gbmV3IE9iamVjdCgpOworCisgICAgLyoqIFN5bmMgbG9jayAqLworICAgIHByaXZhdGUgZmluYWwgT2JqZWN0IGJhY2tncm91bmRMb2NrID0gbmV3IE9iamVjdCgpOworCisgICAgLyoqIE51bWJlciBvZiBwYXJhbGxlbCBqb2JzIGZvciB0aGUgbWFpbiBxdWV1ZS4gKi8KKyAgICBwcml2YXRlIGxvbmcgcGFyYWxsZWxKb2JDb3VudDsKKworICAgIC8qKgorICAgICAqIEFjdGl2YXRlIHRoaXMgY29tcG9uZW50LgorICAgICAqIEBwYXJhbSBjb250ZXh0CisgICAgICogQHRocm93cyBSZXBvc2l0b3J5RXhjZXB0aW9uCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgYWN0aXZhdGUoZmluYWwgQ29tcG9uZW50Q29udGV4dCBjb250ZXh0KQorICAgIHRocm93cyBFeGNlcHRpb24geworICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKKyAgICAgICAgZmluYWwgRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBjb250ZXh0LmdldFByb3BlcnRpZXMoKTsKKyAgICAgICAgdGhpcy5jbGVhbnVwUGVyaW9kID0gT3NnaVV0aWwudG9JbnRlZ2VyKHByb3BzLmdldChDT05GSUdfUFJPUEVSVFlfQ0xFQU5VUF9QRVJJT0QpLCBERUZBVUxUX0NMRUFOVVBfUEVSSU9EKTsKKyAgICAgICAgdGhpcy5zbGVlcFRpbWUgPSBPc2dpVXRpbC50b0xvbmcocHJvcHMuZ2V0KENPTkZJR19QUk9QRVJUWV9TTEVFUF9USU1FKSwgREVGQVVMVF9TTEVFUF9USU1FKTsKKyAgICAgICAgdGhpcy5tYXhKb2JSZXRyaWVzID0gT3NnaVV0aWwudG9JbnRlZ2VyKHByb3BzLmdldChDT05GSUdfUFJPUEVSVFlfTUFYX0pPQl9SRVRSSUVTKSwgREVGQVVMVF9NQVhfSk9CX1JFVFJJRVMpOworICAgICAgICB0aGlzLndhaXRGb3JBY2tNcyA9IE9zZ2lVdGlsLnRvTG9uZyhwcm9wcy5nZXQoQ09ORklHX1BST1BFUlRZX1dBSVRfRk9SX0FDSyksIERFRkFVTFRfV0FJVF9GT1JfQUNLKSAqIDEwMDA7CisgICAgICAgIHRoaXMubWF4aW11bVBhcmFsbGVsSm9icyA9IE9zZ2lVdGlsLnRvTG9uZyhwcm9wcy5nZXQoQ09ORklHX1BST1BFUlRZX01BWElNVU1fUEFSQUxMRUxfSk9CUyksIERFRkFVTFRfTUFYSU1VTV9QQVJBTExFTF9KT0JTKTsKKyAgICAgICAgdGhpcy5jb21wb25lbnRDb250ZXh0ID0gY29udGV4dDsKKyAgICAgICAgc3VwZXIuYWN0aXZhdGUoY29udGV4dCk7CisgICAgICAgIEpPQl9USFJFQURfUE9PTCA9IHRoaXMudGhyZWFkUG9vbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbC5BYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXIjZGVhY3RpdmF0ZShvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC5Db21wb25lbnRDb250ZXh0KQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGRlYWN0aXZhdGUoZmluYWwgQ29tcG9uZW50Q29udGV4dCBjb250ZXh0KSB7CisgICAgICAgIHN1cGVyLmRlYWN0aXZhdGUoY29udGV4dCk7CisgICAgICAgIHN5bmNocm9uaXplZCAoIHRoaXMuam9iUXVldWVzICkgeworICAgICAgICAgICAgZmluYWwgSXRlcmF0b3I8Sm9iQmxvY2tpbmdRdWV1ZT4gaSA9IHRoaXMuam9iUXVldWVzLnZhbHVlcygpLml0ZXJhdG9yKCk7CisgICAgICAgICAgICB3aGlsZSAoIGkuaGFzTmV4dCgpICkgeworICAgICAgICAgICAgICAgIGZpbmFsIEpvYkJsb2NraW5nUXVldWUgamJxID0gaS5uZXh0KCk7CisgICAgICAgICAgICAgICAgLy8gd2FrZSB1cCBxZXVlCisgICAgICAgICAgICAgICAgaWYgKCBqYnEuaXNXYWl0aW5nKCkgKSB7CisgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoIGpicS5nZXRMb2NrKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGpicS5ub3RpZnlGaW5pc2gobnVsbCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gY29udGludWUgcXVldWUgcHJvY2Vzc2luZworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGpicS5wdXQobmV3IEV2ZW50SW5mbygpKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoIHRoaXMuYmFja2dyb3VuZFNlc3Npb24gIT0gbnVsbCApIHsKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoIHRoaXMuYmFja2dyb3VuZExvY2sgKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5iYWNrZ3JvdW5kU2Vzc2lvbi5nZXRXb3Jrc3BhY2UoKS5nZXRPYnNlcnZhdGlvbk1hbmFnZXIoKS5yZW1vdmVFdmVudExpc3RlbmVyKHRoaXMpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyB3ZSBqdXN0IGlnbm9yZSBpdAorICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci53YXJuKCJVbmFibGUgdG8gcmVtb3ZlIGV2ZW50IGxpc3RlbmVyLiIsIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0aGlzLmJhY2tncm91bmRTZXNzaW9uLmxvZ291dCgpOworICAgICAgICAgICAgICAgIHRoaXMuYmFja2dyb3VuZFNlc3Npb24gPSBudWxsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHRoaXMuY29tcG9uZW50Q29udGV4dCA9IG51bGw7CisgICAgICAgIEpPQl9USFJFQURfUE9PTCA9IG51bGw7CisgICAgfQorCisgICAgLyoqCisgICAgICogUmV0dXJuIHRoZSBxdWVyeSBzdHJpbmcgZm9yIHRoZSBjbGVhbiB1cC4KKyAgICAgKi8KKyAgICBwcml2YXRlIFN0cmluZyBnZXRDbGVhblVwUXVlcnlTdHJpbmcoKSB7CisgICAgICAgIGZpbmFsIENhbGVuZGFyIGRlbGV0ZUJlZm9yZSA9IENhbGVuZGFyLmdldEluc3RhbmNlKCk7CisgICAgICAgIGRlbGV0ZUJlZm9yZS5hZGQoQ2FsZW5kYXIuTUlOVVRFLCAtdGhpcy5jbGVhbnVwUGVyaW9kKTsKKyAgICAgICAgZmluYWwgU3RyaW5nIGRhdGVTdHJpbmcgPSBJU084NjAxLmZvcm1hdChkZWxldGVCZWZvcmUpOworCisgICAgICAgIGZpbmFsIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCIvamNyOnJvb3QiKTsKKyAgICAgICAgYnVmZmVyLmFwcGVuZCh0aGlzLnJlcG9zaXRvcnlQYXRoKTsKKyAgICAgICAgYnVmZmVyLmFwcGVuZCgiLy9lbGVtZW50KCosICIpOworICAgICAgICBidWZmZXIuYXBwZW5kKGdldEV2ZW50Tm9kZVR5cGUoKSk7CisgICAgICAgIGJ1ZmZlci5hcHBlbmQoIilbQCIpOworICAgICAgICBidWZmZXIuYXBwZW5kKEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfRklOSVNIRUQpOworICAgICAgICBidWZmZXIuYXBwZW5kKCIgPCB4czpkYXRlVGltZSgnIik7CisgICAgICAgIGJ1ZmZlci5hcHBlbmQoZGF0ZVN0cmluZyk7CisgICAgICAgIGJ1ZmZlci5hcHBlbmQoIicpXSIpOworCisgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIG1ldGhvZCBpcyBpbnZva2VkIHBlcmlvZGljYWxseS4KKyAgICAgKiBAc2VlIGphdmEubGFuZy5SdW5uYWJsZSNydW4oKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgaWYgKCB0aGlzLnJ1bm5pbmcgKSB7CisgICAgICAgICAgICAvLyBjaGVjayBmb3Igam9icyB0aGF0IHdlcmUgc3RhcnRlZCBidXQgbmV2ZXIgZ290IGFuIGFrbm93bGVkZ2UKKyAgICAgICAgICAgIGZpbmFsIGxvbmcgdG9vT2xkID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSB0aGlzLndhaXRGb3JBY2tNczsKKyAgICAgICAgICAgIC8vIHRvIGtlZXAgdGhlIHN5bmNocm9uaXplZCBibG9jayBhcyBmYXN0IGFzIHBvc3NpYmxlIHdlIGp1c3Qgc3RvcmUgdGhlCisgICAgICAgICAgICAvLyBqb2JzIHRvIGJlIHJlbW92ZWQgaW4gYSBuZXcgbGlzdCBhbmQgcHJvY2VzcyB0aGlzIGxpc3QgYWZ0ZXJ3YXJkcworICAgICAgICAgICAgZmluYWwgTGlzdDxTdGFydGVkSm9iSW5mbz4gcmVzdGFydEpvYnMgPSBuZXcgQXJyYXlMaXN0PFN0YXJ0ZWRKb2JJbmZvPigpOworICAgICAgICAgICAgc3luY2hyb25pemVkICggdGhpcy5wcm9jZXNzaW5nRXZlbnRzTGlzdCApIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBJdGVyYXRvcjxNYXAuRW50cnk8U3RyaW5nLCBTdGFydGVkSm9iSW5mbz4+IGkgPSB0aGlzLnByb2Nlc3NpbmdFdmVudHNMaXN0LmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgICAgICB3aGlsZSAoIGkuaGFzTmV4dCgpICkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBNYXAuRW50cnk8U3RyaW5nLCBTdGFydGVkSm9iSW5mbz4gZW50cnkgPSBpLm5leHQoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCBlbnRyeS5nZXRWYWx1ZSgpLnN0YXJ0ZWQgPD0gdG9vT2xkICkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmVzdGFydEpvYnMuYWRkKGVudHJ5LmdldFZhbHVlKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gcmVtb3ZlIG9ic29sZXRlIGpvYnMgZnJvbSB0aGUgcmVwb3NpdG9yeQorICAgICAgICAgICAgaWYgKCB0aGlzLmNsZWFudXBQZXJpb2QgPiAwICkgeworICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKCJDbGVhbmluZyB1cCByZXBvc2l0b3J5LCByZW1vdmluZyBhbGwgZmluaXNoZWQgam9icyBvbGRlciB0aGFuIHt9IG1pbnV0ZXMuIiwgdGhpcy5jbGVhbnVwUGVyaW9kKTsKKworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBxdWVyeVN0cmluZyA9IHRoaXMuZ2V0Q2xlYW5VcFF1ZXJ5U3RyaW5nKCk7CisgICAgICAgICAgICAgICAgLy8gd2UgY3JlYXRlIGFuIG93biBzZXNzaW9uIGZvciBjb25jdXJyZW5jeSBpc3N1ZXMKKyAgICAgICAgICAgICAgICBTZXNzaW9uIHMgPSBudWxsOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHMgPSB0aGlzLmNyZWF0ZVNlc3Npb24oKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBwYXJlbnROb2RlID0gKE5vZGUpcy5nZXRJdGVtKHRoaXMucmVwb3NpdG9yeVBhdGgpOworICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoIkV4ZWN1dGluZyBxdWVyeSB7fSIsIHF1ZXJ5U3RyaW5nKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgUXVlcnkgcSA9IHMuZ2V0V29ya3NwYWNlKCkuZ2V0UXVlcnlNYW5hZ2VyKCkuY3JlYXRlUXVlcnkocXVlcnlTdHJpbmcsIFF1ZXJ5LlhQQVRIKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgTm9kZUl0ZXJhdG9yIGl0ZXIgPSBxLmV4ZWN1dGUoKS5nZXROb2RlcygpOworICAgICAgICAgICAgICAgICAgICBpbnQgY291bnQgPSAwOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoIGl0ZXIuaGFzTmV4dCgpICkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBldmVudE5vZGUgPSBpdGVyLm5leHROb2RlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBldmVudE5vZGUucmVtb3ZlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUuc2F2ZSgpOworICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoIlJlbW92ZWQge30gZW50cmllcyBmcm9tIHRoZSByZXBvc2l0b3J5LiIsIGNvdW50KTsKKworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBpbiB0aGUgY2FzZSBvZiBhbiBlcnJvciwgd2UganVzdCBsb2cgdGhpcyBhcyBhIHdhcm5pbmcKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIud2FybigiRXhjZXB0aW9uIGR1cmluZyByZXBvc2l0b3J5IGNsZWFudXAuIiwgZSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCBzICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBzLmxvZ291dCgpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gcmVzdGFydCBqb2JzIGlzIG5vdyBhIGxpc3Qgb2YgcG90ZW50aWFsIGNhbmRpZGF0ZXMsIHdlIG5vdyBoYXZlIHRvIGNoZWNrCisgICAgICAgICAgICAvLyBlYWNoIGNhbmRpZGF0ZSBzZXBhcmF0ZWx5IGFnYWluIQorICAgICAgICAgICAgaWYgKCByZXN0YXJ0Sm9icy5zaXplKCkgPiAwICkgeworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCg1MDApOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gd2UganVzdCBpZ25vcmUgdGhpcworICAgICAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZpbmFsIEl0ZXJhdG9yPFN0YXJ0ZWRKb2JJbmZvPiBqb2JJdGVyID0gcmVzdGFydEpvYnMuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgIHdoaWxlICggam9iSXRlci5oYXNOZXh0KCkgKSB7CisgICAgICAgICAgICAgICAgZmluYWwgU3RhcnRlZEpvYkluZm8gaW5mbyA9IGpvYkl0ZXIubmV4dCgpOworICAgICAgICAgICAgICAgIGJvb2xlYW4gcHJvY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoIHRoaXMucHJvY2Vzc2luZ0V2ZW50c0xpc3QgKSB7CisgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MgPSB0aGlzLnByb2Nlc3NpbmdFdmVudHNMaXN0LnJlbW92ZShpbmZvLm5vZGVQYXRoKSAhPSBudWxsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoIHByb2Nlc3MgKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmluZm8oIk5vIGFja25vd2xlZGdlIHJlY2VpdmVkIGZvciBqb2Ige30gc3RvcmVkIGF0IHt9LiBSZXF1ZXVlaW5nIGpvYi4iLCBpbmZvLmV2ZW50LCBpbmZvLm5vZGVQYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5maW5pc2hlZEpvYihpbmZvLmV2ZW50LCBpbmZvLm5vZGVQYXRoLCB0cnVlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIGNoZWNrIGZvciBpZGxlIHRocmVhZHMKKyAgICAgICAgICAgIHN5bmNocm9uaXplZCAoIHRoaXMuam9iUXVldWVzICkgeworICAgICAgICAgICAgICAgIGZpbmFsIEl0ZXJhdG9yPE1hcC5FbnRyeTxTdHJpbmcsIEpvYkJsb2NraW5nUXVldWU+PiBpID0gdGhpcy5qb2JRdWV1ZXMuZW50cnlTZXQoKS5pdGVyYXRvcigpOworICAgICAgICAgICAgICAgIHdoaWxlICggaS5oYXNOZXh0KCkgKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIE1hcC5FbnRyeTxTdHJpbmcsIEpvYkJsb2NraW5nUXVldWU+IGN1cnJlbnQgPSBpLm5leHQoKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgSm9iQmxvY2tpbmdRdWV1ZSBqYnEgPSBjdXJyZW50LmdldFZhbHVlKCk7CisgICAgICAgICAgICAgICAgICAgIGlmICggamJxLnNpemUoKSA9PSAwICkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBqYnEuaXNNYXJrZWRGb3JDbGVhblVwKCkgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHRvIGZpbmlzaGVkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgamJxLnNldEZpbmlzaGVkKHRydWUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdha2UgdXAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqYnEucHV0KG5ldyBFdmVudEluZm8oKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaS5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFyayB0byBiZSByZW1vdmVkIGR1cmluZyBuZXh0IGN5Y2xlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgamJxLm1hcmtGb3JDbGVhblVwKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbC5BYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXIjcHJvY2Vzc1dyaXRlUXVldWUoKQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHByb2Nlc3NXcml0ZVF1ZXVlKCkgeworICAgICAgICB3aGlsZSAoIHRoaXMucnVubmluZyApIHsKKyAgICAgICAgICAgIC8vIHNvIGxldCdzIHdhaXQvZ2V0IHRoZSBuZXh0IGpvYiBmcm9tIHRoZSBxdWV1ZQorICAgICAgICAgICAgRXZlbnQgZXZlbnQgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBldmVudCA9IHRoaXMud3JpdGVRdWV1ZS50YWtlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gd2UgaWdub3JlIHRoaXMKKyAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICggZXZlbnQgIT0gbnVsbCAmJiB0aGlzLnJ1bm5pbmcgKSB7CisgICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCJQZXJzaXN0aW5nIGpvYiB7fSIsIGV2ZW50KTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLndyaXRlclNlc3Npb24ucmVmcmVzaChmYWxzZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgICAgICAgICAvLyB3ZSBqdXN0IGlnbm9yZSB0aGlzCisgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKHJlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmluYWwgRXZlbnRJbmZvIGluZm8gPSBuZXcgRXZlbnRJbmZvKCk7CisgICAgICAgICAgICAgICAgaW5mby5ldmVudCA9IGV2ZW50OworICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBqb2JJZCA9IChTdHJpbmcpZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9JRCk7CisgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGpvYlRvcGljID0gKFN0cmluZylldmVudC5nZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1RPUElDKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbm9kZVBhdGggPSB0aGlzLmdldE5vZGVQYXRoKGpvYlRvcGljLCBqb2JJZCk7CisKKyAgICAgICAgICAgICAgICAvLyBpZiB0aGUgam9iIGhhcyBubyBqb2IgaWQsIHdlIGNhbiBqdXN0IHdyaXRlIHRoZSBqb2IgdG8gdGhlIHJlcG8gYW5kIGRvbid0CisgICAgICAgICAgICAgICAgLy8gbmVlZCBsb2NraW5nCisgICAgICAgICAgICAgICAgaWYgKCBqb2JJZCA9PSBudWxsICkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBldmVudE5vZGUgPSB0aGlzLndyaXRlRXZlbnQoZXZlbnQsIG5vZGVQYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGluZm8ubm9kZVBhdGggPSBldmVudE5vZGUuZ2V0UGF0aCgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIHJlICkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmcsIHNvIGxldCdzIGxvZyBpdAorICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoIkV4Y2VwdGlvbiBkdXJpbmcgd3JpdGluZyBuZXcgam9iICciICsgRXZlbnRVdGlsLnRvU3RyaW5nKGV2ZW50KSArICInIHRvIHJlcG9zaXRvcnkgYXQgIiArIG5vZGVQYXRoLCByZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gbGV0J3MgZmlyc3Qgc2VhcmNoIGZvciBhbiBleGlzdGluZyBub2RlIHdpdGggdGhlIHNhbWUgaWQKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgcGFyZW50Tm9kZSA9IHRoaXMuZW5zdXJlUmVwb3NpdG9yeVBhdGgoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUgZm91bmROb2RlID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICggcGFyZW50Tm9kZS5oYXNOb2RlKG5vZGVQYXRoKSApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3VuZE5vZGUgPSBwYXJlbnROb2RlLmdldE5vZGUobm9kZVBhdGgpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBmb3VuZE5vZGUgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgbm9kZSBpcyBsb2NrZWQsIHNvbWVvbmUgZWxzZSB3YXMgcXVpY2tlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB3ZSBkb24ndCBoYXZlIHRvIHByb2Nlc3MgdGhpcyBqb2IKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoICFmb3VuZE5vZGUuaXNMb2NrZWQoKSApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm9kZSBpcyBhbHJlYWR5IGluIHJlcG9zaXRvcnksIHNvIGlmIG5vdCBmaW5pc2hlZCB3ZSBqdXN0IHVzZSBpdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UgaXQgaGFzIGFscmVhZHkgYmVlbiBwcm9jZXNzZWQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIWZvdW5kTm9kZS5oYXNQcm9wZXJ0eShFdmVudEhlbHBlci5OT0RFX1BST1BFUlRZX0ZJTklTSEVEKSApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLm5vZGVQYXRoID0gZm91bmROb2RlLmdldFBhdGgoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgYW55dGhpbmcgZ29lcyB3cm9uZywgaXQgbWVhbnMgdGhhdCAoaG9wZWZ1bGx5KSBzb21lb25lCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlbHNlIGlzIHByb2Nlc3NpbmcgdGhpcyBub2RlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIG5vdyB3cml0ZSB0aGUgZXZlbnQgaW50byB0aGUgcmVwb3NpdG9yeQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgZXZlbnROb2RlID0gdGhpcy53cml0ZUV2ZW50KGV2ZW50LCBub2RlUGF0aCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8ubm9kZVBhdGggPSBldmVudE5vZGUuZ2V0UGF0aCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEl0ZW1FeGlzdHNFeGNlcHRpb24gaWVlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNvbWVvbmUgZWxzZSBkaWQgYWxyZWFkeSB3cml0ZSB0aGlzIG5vZGUgaW4gdGhlIG1lYW50aW1lCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdGhpbmcgdG8gZG8gZm9yIHVzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIHJlICkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmcsIHNvIGxldCdzIGxvZyBpdAorICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoIkV4Y2VwdGlvbiBkdXJpbmcgd3JpdGluZyBuZXcgam9iICciICsgZXZlbnQgKyAiJyB0byByZXBvc2l0b3J5IGF0ICIgKyBub2RlUGF0aCwgcmUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIGlmIHdlIHdlcmUgYWJsZSB0byB3cml0ZSB0aGUgZXZlbnQgaW50byB0aGUgcmVwb3NpdG9yeQorICAgICAgICAgICAgICAgIC8vIHdlIHdpbGwgcXVldWUgaXQgZm9yIHByb2Nlc3NpbmcKKyAgICAgICAgICAgICAgICBpZiAoIGluZm8ubm9kZVBhdGggIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucXVldWUucHV0KGluZm8pOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHNob3VsZCBuZXZlciBoYXBwZW4KKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogVGhpcyBtZXRob2QgcnVucyBpbiB0aGUgYmFja2dyb3VuZCBhbmQgcHJvY2Vzc2VzIHRoZSBsb2NhbCBxdWV1ZS4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBydW5JbkJhY2tncm91bmQoKSB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIHRoaXMuYmFja2dyb3VuZFNlc3Npb24gPSB0aGlzLmNyZWF0ZVNlc3Npb24oKTsKKyAgICAgICAgdGhpcy5iYWNrZ3JvdW5kU2Vzc2lvbi5nZXRXb3Jrc3BhY2UoKS5nZXRPYnNlcnZhdGlvbk1hbmFnZXIoKQorICAgICAgICAgICAgICAgIC5hZGRFdmVudExpc3RlbmVyKHRoaXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamF2YXguamNyLm9ic2VydmF0aW9uLkV2ZW50LlBST1BFUlRZX1JFTU9WRUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxqYXZheC5qY3Iub2JzZXJ2YXRpb24uRXZlbnQuTk9ERV9SRU1PVkVELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVwb3NpdG9yeVBhdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7dGhpcy5nZXRFdmVudE5vZGVUeXBlKCl9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpOworICAgICAgICAvLyBnaXZlIHRoZSBzeXN0ZW0gc29tZSB0aW1lIHRvIHN0YXJ0CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBUaHJlYWQuc2xlZXAoMTAwMCAqIDMwKTsgLy8gMzAgc2VjcworICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorICAgICAgICAvLyBsb2FkIHVucHJvY2Vzc2VkIGpvYnMgZnJvbSByZXBvc2l0b3J5CisgICAgICAgIGlmICggdGhpcy5ydW5uaW5nICkgeworICAgICAgICAgICAgdGhpcy5sb2FkSm9icygpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZmluYWwgQ29tcG9uZW50Q29udGV4dCBjdHggPSB0aGlzLmNvbXBvbmVudENvbnRleHQ7CisgICAgICAgICAgICAvLyBkZWFjdGl2YXRlCisgICAgICAgICAgICBpZiAoIGN0eCAhPSBudWxsICkgeworICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCJEZWFjdGl2YXRpbmcgY29tcG9uZW50IHt9IGR1ZSB0byBlcnJvcnMgZHVyaW5nIHN0YXJ0dXAuIiwgY3R4LmdldFByb3BlcnRpZXMoKS5nZXQoQ29uc3RhbnRzLlNFUlZJQ0VfSUQpKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbmFtZSA9IChTdHJpbmcpIGNvbXBvbmVudENvbnRleHQuZ2V0UHJvcGVydGllcygpLmdldCgKKyAgICAgICAgICAgICAgICAgICAgQ29tcG9uZW50Q29uc3RhbnRzLkNPTVBPTkVOVF9OQU1FKTsKKyAgICAgICAgICAgICAgICBjdHguZGlzYWJsZUNvbXBvbmVudChuYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB3aGlsZSAoIHRoaXMucnVubmluZyApIHsKKyAgICAgICAgICAgIC8vIHNvIGxldCdzIHdhaXQvZ2V0IHRoZSBuZXh0IGpvYiBmcm9tIHRoZSBxdWV1ZQorICAgICAgICAgICAgRXZlbnRJbmZvIGluZm8gPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpbmZvID0gdGhpcy5xdWV1ZS50YWtlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gd2UgaWdub3JlIHRoaXMKKyAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgaWYgKCBpbmZvICE9IG51bGwgJiYgdGhpcy5ydW5uaW5nICkgeworICAgICAgICAgICAgICAgIC8vIGNoZWNrIGZvciBsb2NhbCBvbmx5IGpvYnMgYW5kIHJlbW92ZSB0aGVtIGZyb20gdGhlIHF1ZXVlIGlmIHRoZXkncmUgbWVhbnQKKyAgICAgICAgICAgICAgICAvLyBmb3IgYW5vdGhlciBhcHBsaWNhdGlvbiBub2RlCisgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGFwcElkID0gKFN0cmluZylpbmZvLmV2ZW50LmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9BUFBMSUNBVElPTik7CisgICAgICAgICAgICAgICAgaWYgKCBpbmZvLmV2ZW50LmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUlVOX0xPQ0FMKSAhPSBudWxsCisgICAgICAgICAgICAgICAgICAgICYmIGFwcElkICE9IG51bGwgJiYgIXRoaXMuYXBwbGljYXRpb25JZC5lcXVhbHMoYXBwSWQpICkgeworICAgICAgICAgICAgICAgICAgICBpbmZvID0gbnVsbDsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiB3ZSBzaG91bGQgcHV0IHRoaXMgaW50byBhIHNlcGFyYXRlIHF1ZXVlCisgICAgICAgICAgICAgICAgaWYgKCBpbmZvICE9IG51bGwgJiYgaW5mby5ldmVudC5nZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1FVRVVFX05BTUUpICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBxdWV1ZU5hbWUgPSAoU3RyaW5nKWluZm8uZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9RVUVVRV9OQU1FKTsKKyAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICggdGhpcy5qb2JRdWV1ZXMgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBCbG9ja2luZ1F1ZXVlPEV2ZW50SW5mbz4gam9iUXVldWUgPSB0aGlzLmpvYlF1ZXVlcy5nZXQocXVldWVOYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICggam9iUXVldWUgPT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBKb2JCbG9ja2luZ1F1ZXVlIGpxID0gbmV3IEpvYkJsb2NraW5nUXVldWUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2JRdWV1ZSA9IGpxOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuam9iUXVldWVzLnB1dChxdWV1ZU5hbWUsIGpxKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdGFydCBiYWNrZ3JvdW5kIHRocmVhZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGhyZWFkUG9vbC5leGVjdXRlKG5ldyBSdW5uYWJsZSgpIHsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKioKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQHNlZSBqYXZhLmxhbmcuUnVubmFibGUjcnVuKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICggcnVubmluZyAmJiAhanEuaXNGaW5pc2hlZCgpICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCJTdGFydGluZyBqb2IgcXVldWUge30iLCBxdWV1ZU5hbWUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bkpvYlF1ZXVlKHF1ZXVlTmFtZSwganEpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcigiSm9iIHF1ZXVlIHN0b3BwZWQgd2l0aCBleGNlcHRpb246ICIgKyB0LmdldE1lc3NhZ2UoKSArICIuIFJlc3RhcnRpbmcuIiwgdCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgam9iUXVldWUucHV0KGluZm8pOworICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIGRvbid0IHByb2Nlc3MgdGhpcyBoZXJlCisgICAgICAgICAgICAgICAgICAgIGluZm8gPSBudWxsOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIGlmIHdlIHN0aWxsIGhhdmUgYSBqb2IsIHByb2Nlc3MgaXQKKyAgICAgICAgICAgICAgICBpZiAoIGluZm8gIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5leGVjdXRlSm9iKGluZm8sIG51bGwpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEV4ZWN1dGUgYSBqb2IgcXVldWUKKyAgICAgKiBAcGFyYW0gcXVldWVOYW1lIFRoZSBuYW1lIG9mIHRoZSBqb2IgcXVldWUKKyAgICAgKiBAcGFyYW0gam9iUXVldWUgVGhlIGpvYiBxdWV1ZQorICAgICAqLworICAgIHByaXZhdGUgdm9pZCBydW5Kb2JRdWV1ZShmaW5hbCBTdHJpbmcgcXVldWVOYW1lLCBmaW5hbCBKb2JCbG9ja2luZ1F1ZXVlIGpvYlF1ZXVlKSB7CisgICAgICAgIEV2ZW50SW5mbyBpbmZvID0gbnVsbDsKKyAgICAgICAgd2hpbGUgKCB0aGlzLnJ1bm5pbmcgJiYgIWpvYlF1ZXVlLmlzRmluaXNoZWQoKSApIHsKKyAgICAgICAgICAgIGlmICggaW5mbyA9PSBudWxsICkgeworICAgICAgICAgICAgICAgIC8vIHNvIGxldCdzIHdhaXQvZ2V0IHRoZSBuZXh0IGpvYiBmcm9tIHRoZSBxdWV1ZQorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGluZm8gPSBqb2JRdWV1ZS50YWtlKCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhpcworICAgICAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICggaW5mbyAhPSBudWxsICYmIHRoaXMucnVubmluZyAmJiAham9iUXVldWUuaXNGaW5pc2hlZCgpICkgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoIGpvYlF1ZXVlLmdldExvY2soKSkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBFdmVudEluZm8gcHJvY2Vzc0luZm8gPSBpbmZvOworICAgICAgICAgICAgICAgICAgICBpbmZvID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCB0aGlzLmV4ZWN1dGVKb2IocHJvY2Vzc0luZm8sIGpvYlF1ZXVlKSApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIEV2ZW50SW5mbyBuZXdJbmZvID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5mbyA9IGpvYlF1ZXVlLndhaXRGb3JGaW5pc2goKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHdlIGhhdmUgYW4gaW5mbywgdGhpcyBpcyBhIHJlc2NoZWR1bGUKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICggbmV3SW5mbyAhPSBudWxsICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEV2ZW50SW5mbyBuZXdFdmVudEluZm8gPSBuZXdJbmZvOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEV2ZW50IGpvYiA9IG5ld0luZm8uZXZlbnQ7CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpcyB0aGlzIGFuIG9yZGVyZWQgcXVldWU/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgYm9vbGVhbiBvcmRlcmVkUXVldWUgPSBqb2IuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9RVUVVRV9PUkRFUkVEKSAhPSBudWxsOworCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBvcmRlcmVkUXVldWUgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGp1c3Qgc2xlZXAgZm9yIHRoZSBkZWxheSB0aW1lIC0gaWYgbm9uZSwgd2UgY29udGludWUgYW5kIHJldHJ5CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgam9iIGFnYWluCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggam9iLmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUkVUUllfREVMQVkpICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBsb25nIGRlbGF5ID0gKExvbmcpam9iLmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUkVUUllfREVMQVkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgam9iUXVldWUuc2V0U2xlZXBpbmcodHJ1ZSwgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcChkZWxheSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pZ25vcmVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpvYlF1ZXVlLnNldFNsZWVwaW5nKGZhbHNlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvID0gbmV3SW5mbzsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWxheSByZXNjaGVkdWxpbmc/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggam9iLmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUkVUUllfREVMQVkpICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBsb25nIGRlbGF5ID0gKExvbmcpam9iLmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUkVUUllfREVMQVkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgRGF0ZSBmaXJlRGF0ZSA9IG5ldyBEYXRlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJlRGF0ZS5zZXRUaW1lKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgZGVsYXkpOworCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgc2NoZWR1bGVySm9iTmFtZSA9ICJXYWl0aW5nOiIgKyBxdWV1ZU5hbWU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBSdW5uYWJsZSB0ID0gbmV3IFJ1bm5hYmxlKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgam9iUXVldWUuc2V0U2xlZXBpbmcodHJ1ZSwgc2NoZWR1bGVySm9iTmFtZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2JRdWV1ZS5wdXQobmV3RXZlbnRJbmZvKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2JRdWV1ZS5zZXRTbGVlcGluZyhmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjaGVkdWxlci5maXJlSm9iQXQoc2NoZWR1bGVySm9iTmFtZSwgdCwgbnVsbCwgZmlyZURhdGUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhlIGV4Y2VwdGlvbiBhbmQganVzdCBwdXQgYmFjayB0aGUgam9iIGluIHRoZSBxdWV1ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0LnJ1bigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHV0IGRpcmVjdGx5IGludG8gcXVldWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgam9iUXVldWUucHV0KG5ld0luZm8pOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2VzcyBhIGpvYgorICAgICAqLworICAgIHByaXZhdGUgYm9vbGVhbiBleGVjdXRlSm9iKGZpbmFsIEV2ZW50SW5mbyBpbmZvLCBmaW5hbCBCbG9ja2luZ1F1ZXVlPEV2ZW50SW5mbz4gam9iUXVldWUpIHsKKyAgICAgICAgYm9vbGVhbiBwdXRiYWNrID0gZmFsc2U7CisgICAgICAgIGJvb2xlYW4gd2FpdCA9IGZhbHNlOworICAgICAgICBzeW5jaHJvbml6ZWQgKHRoaXMuYmFja2dyb3VuZExvY2spIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdGhpcy5iYWNrZ3JvdW5kU2Vzc2lvbi5yZWZyZXNoKGZhbHNlKTsKKyAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiB0aGUgbm9kZSBzdGlsbCBleGlzdHMKKyAgICAgICAgICAgICAgICBpZiAoIHRoaXMuYmFja2dyb3VuZFNlc3Npb24uaXRlbUV4aXN0cyhpbmZvLm5vZGVQYXRoKQorICAgICAgICAgICAgICAgICAgICAgJiYgIXRoaXMuYmFja2dyb3VuZFNlc3Npb24uaXRlbUV4aXN0cyhpbmZvLm5vZGVQYXRoICsgIi8iICsgRXZlbnRIZWxwZXIuTk9ERV9QUk9QRVJUWV9GSU5JU0hFRCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgRXZlbnQgZXZlbnQgPSBpbmZvLmV2ZW50OworICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgam9iVG9waWMgPSAoU3RyaW5nKWV2ZW50LmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfVE9QSUMpOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBib29sZWFuIHBhcmFsbGVsUHJvY2Vzc2luZyA9IGV2ZW50LmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUVVFVUVfTkFNRSkgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGV2ZW50LmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUEFSQUxMRUwpICE9IG51bGw7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaG93IHdlIGNhbiBwcm9jZXNzIHRoaXMgam9iCisgICAgICAgICAgICAgICAgICAgIC8vIGlmIHBhcmFsbGVsIHByb2Nlc3NpbmcgaXMgYWxsb3dlZCwgd2UgY2FuIGp1c3QgcHJvY2VzcworICAgICAgICAgICAgICAgICAgICAvLyBpZiBub3Qgd2Ugc2hvdWxkIGNoZWNrIGlmIGFueSBvdGhlciBqb2Igd2l0aCB0aGUgc2FtZSB0b3BpYyBpcyBjdXJyZW50bHkgcnVubmluZworICAgICAgICAgICAgICAgICAgICBib29sZWFuIHByb2Nlc3MgPSBwYXJhbGxlbFByb2Nlc3Npbmc7CisgICAgICAgICAgICAgICAgICAgIGlmICggIXBhcmFsbGVsUHJvY2Vzc2luZyApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoIHRoaXMucHJvY2Vzc2luZ01hcCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBCb29sZWFuIHZhbHVlID0gdGhpcy5wcm9jZXNzaW5nTWFwLmdldChqb2JUb3BpYyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCB2YWx1ZSA9PSBudWxsIHx8ICF2YWx1ZS5ib29sZWFuVmFsdWUoKSApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzaW5nTWFwLnB1dChqb2JUb3BpYywgQm9vbGVhbi5UUlVFKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2VzcyA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBudW1iZXIgb2YgcGFyYWxsZWwgam9icyBmb3IgbWFpbiBxdWV1ZQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBqb2JRdWV1ZSA9PSBudWxsICYmIHRoaXMucGFyYWxsZWxKb2JDb3VudCA+PSB0aGlzLm1heGltdW1QYXJhbGxlbEpvYnMgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2VzcyA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhaXQgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmICggcHJvY2VzcyApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gdW5sb2NrID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBldmVudE5vZGUgPSAoTm9kZSkgdGhpcy5iYWNrZ3JvdW5kU2Vzc2lvbi5nZXRJdGVtKGluZm8ubm9kZVBhdGgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIWV2ZW50Tm9kZS5pc0xvY2tlZCgpICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsb2NrIG5vZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Tm9kZS5sb2NrKGZhbHNlLCB0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbG9jayBmYWlsZWQgd2hpY2ggbWVhbnMgdGhhdCB0aGUgbm9kZSBpcyBsb2NrZWQgYnkgc29tZW9uZSBlbHNlLCBzbyB3ZSBkb24ndCBoYXZlIHRvIHJlcXVldWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHByb2Nlc3MgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxvY2sgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc0pvYihpbmZvLmV2ZW50LCBldmVudE5vZGUsIGpvYlF1ZXVlID09IG51bGwpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCB1bmxvY2sgJiYgIXBhcmFsbGVsUHJvY2Vzc2luZyApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICggdGhpcy5wcm9jZXNzaW5nTWFwICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzaW5nTWFwLnB1dChqb2JUb3BpYywgQm9vbGVhbi5GQUxTRSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIHRoZSBub2RlIGlzIGluIHByb2Nlc3Npbmcgb3IgYWxyZWFkeSBmaW5pc2hlZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgZXZlbnROb2RlID0gKE5vZGUpIHRoaXMuYmFja2dyb3VuZFNlc3Npb24uZ2V0SXRlbShpbmZvLm5vZGVQYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoICFldmVudE5vZGUuaXNMb2NrZWQoKSAmJiAhZXZlbnROb2RlLmhhc1Byb3BlcnR5KEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfRklOSVNIRUQpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1dGJhY2sgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKHJlKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisgICAgICAgIC8vIGlmIHRoaXMgaXMgdGhlIG1haW4gcXVldWUgYW5kIHdlIGhhdmUgcmVhY2hlZCB0aGUgbWF4IG51bWJlciBvZiBwYXJhbGxlbCBqb2JzCisgICAgICAgIC8vIHdlIHdhaXQgYSBsaXR0bGUgYml0IGJlZm9yZSBjb250aW51aW5nCisgICAgICAgIGlmICggd2FpdCApIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgVGhyZWFkLnNsZWVwKHNsZWVwVGltZSAqIDEwMDApOworICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKKyAgICAgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgICAgICAgICBpZ25vcmVFeGNlcHRpb24oaWUpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8vIGlmIHdlIGhhdmUgdG8gcHV0IGJhY2sgdGhlIGpvYiwgd2UgZG8gaXQgbm93CisgICAgICAgIGlmICggcHV0YmFjayApIHsKKyAgICAgICAgICAgIGZpbmFsIEV2ZW50SW5mbyBlSW5mbyA9IGluZm87CisgICAgICAgICAgICBmaW5hbCBEYXRlIGZpcmVEYXRlID0gbmV3IERhdGUoKTsKKyAgICAgICAgICAgIGZpcmVEYXRlLnNldFRpbWUoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgKyB0aGlzLnNsZWVwVGltZSAqIDEwMDApOworCisgICAgICAgICAgICAgICAgLy8gd2UgcHV0IGl0IGJhY2sgaW50byB0aGUgcXVldWUgYWZ0ZXIgYSBzcGVjaWZpYyB0aW1lCisgICAgICAgICAgICBmaW5hbCBSdW5uYWJsZSByID0gbmV3IFJ1bm5hYmxlKCkgeworCisgICAgICAgICAgICAgICAgLyoqCisgICAgICAgICAgICAgICAgICogQHNlZSBqYXZhLmxhbmcuUnVubmFibGUjcnVuKCkKKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBxdWV1ZS5wdXQoZUluZm8pOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgfTsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgdGhpcy5zY2hlZHVsZXIuZmlyZUpvYkF0KG51bGwsIHIsIG51bGwsIGZpcmVEYXRlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gd2UgaWdub3JlIHRoZSBleGNlcHRpb24KKyAgICAgICAgICAgICAgICBpZ25vcmVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgLy8gdGhlbiB3YWl0IGZvciB0aGUgdGltZSBhbmQgcmVhZGQgdGhlIGpvYgorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcChzbGVlcFRpbWUgKiAxMDAwKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUKKyAgICAgICAgICAgICAgICAgICAgaWdub3JlRXhjZXB0aW9uKGllKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgci5ydW4oKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmVuZ2luZS5ldmVudC5pbXBsLkpvYlBlcnNpc3RlbmNlSGFuZGxlciNnZXRFdmVudE5vZGVUeXBlKCkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgU3RyaW5nIGdldEV2ZW50Tm9kZVR5cGUoKSB7CisgICAgICAgIHJldHVybiBFdmVudEhlbHBlci5KT0JfTk9ERV9UWVBFOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudEhhbmRsZXIjaGFuZGxlRXZlbnQob3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudCkKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBoYW5kbGVFdmVudChmaW5hbCBFdmVudCBldmVudCkgeworICAgICAgICBsb2dnZXIuZGVidWcoIlJlY2VpdmluZyBldmVudCB7fSIsIGV2ZW50KTsKKyAgICAgICAgLy8gd2UgaWdub3JlIHJlbW90ZSBqb2IgZXZlbnRzCisgICAgICAgIGlmICggRXZlbnRVdGlsLmlzTG9jYWwoZXZlbnQpICkgeworICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGJ1bmRsZSBldmVudAorICAgICAgICAgICAgaWYgKCBldmVudC5nZXRUb3BpYygpLmVxdWFscyhFdmVudFV0aWwuVE9QSUNfSk9CKSkgeworICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygiSGFuZGxpbmcgbG9jYWwgam9iIHt9IiwgZXZlbnQpOworICAgICAgICAgICAgICAgIC8vIGpvYiBldmVudAorICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBqb2JUb3BpYyA9IChTdHJpbmcpZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9UT1BJQyk7CisKKyAgICAgICAgICAgICAgICAvLyAgam9iIHRvcGljIG11c3QgYmUgc2V0LCBvdGhlcndpc2Ugd2UgaWdub3JlIHRoaXMgZXZlbnQhCisgICAgICAgICAgICAgICAgaWYgKCBqb2JUb3BpYyAhPSBudWxsICkgeworICAgICAgICAgICAgICAgICAgICAvLyBxdWV1ZSB0aGUgZXZlbnQgaW4gb3JkZXIgdG8gcmVzcG9uZCBxdWlja2x5CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndyaXRlUXVldWUucHV0KGV2ZW50KTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuCisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLndhcm4oIkV2ZW50IGRvZXMgbm90IGNvbnRhaW4gam9iIHRvcGljOiB7fSIsIGV2ZW50KTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLy8gYnVuZGxlIGV2ZW50IHN0YXJ0ZWQgb3IgdXBkYXRlZAorICAgICAgICAgICAgICAgIGJvb2xlYW4gZG9JdCA9IGZhbHNlOworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoIHRoaXMudW5sb2FkZWRKb2JzICkgeworICAgICAgICAgICAgICAgICAgICBpZiAoIHRoaXMudW5sb2FkZWRKb2JzLnNpemUoKSA+IDAgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkb0l0ID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoIGRvSXQgKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFJ1bm5hYmxlIHQgPSBuZXcgUnVubmFibGUoKSB7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKHVubG9hZGVkSm9icykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXNzaW9uIHMgPSBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTZXQ8U3RyaW5nPiBuZXdVbmxvYWRlZEpvYnMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1VubG9hZGVkSm9icy5hZGRBbGwodW5sb2FkZWRKb2JzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBjcmVhdGVTZXNzaW9uKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IoU3RyaW5nIHBhdGggOiB1bmxvYWRlZEpvYnMgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3VW5sb2FkZWRKb2JzLnJlbW92ZShwYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHMuaXRlbUV4aXN0cyhwYXRoKSApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgZXZlbnROb2RlID0gKE5vZGUpIHMuZ2V0SXRlbShwYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIWV2ZW50Tm9kZS5pc0xvY2tlZCgpICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEV2ZW50SW5mbyBpbmZvID0gbmV3IEV2ZW50SW5mbygpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLmV2ZW50ID0gcmVhZEV2ZW50KGV2ZW50Tm9kZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8ubm9kZVBhdGggPSBwYXRoOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVldWUucHV0KGluZm8pOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhpcyBleGNlcHRpb24gYXMgdGhpcyBzaG91bGQgbmV2ZXIgb2NjdXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdVbmxvYWRlZEpvYnMuYWRkKHBhdGgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVFeGNlcHRpb24oY25mZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhpcyBhbmQgcmVhZGQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3VW5sb2FkZWRKb2JzLmFkZChwYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWdub3JlRXhjZXB0aW9uKHJlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVuYWJsZSB0byBjcmVhdGUgc2Vzc2lvbiwgc28gd2UgdHJ5IGl0IGFnYWluIG5leHQgdGltZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWdub3JlRXhjZXB0aW9uKHJlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggcyAhPSBudWxsICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMubG9nb3V0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxvYWRlZEpvYnMuY2xlYXIoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubG9hZGVkSm9icy5hZGRBbGwobmV3VW5sb2FkZWRKb2JzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICB9OworICAgICAgICAgICAgICAgICAgICB0aGlzLnRocmVhZFBvb2wuZXhlY3V0ZSh0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSB1bmlxdWUgbm9kZSBwYXRoIChmb2xkZXIgYW5kIG5hbWUpIGZvciB0aGUgam9iLgorICAgICAqLworICAgIHByaXZhdGUgU3RyaW5nIGdldE5vZGVQYXRoKGZpbmFsIFN0cmluZyBqb2JUb3BpYywgZmluYWwgU3RyaW5nIGpvYklkKSB7CisgICAgICAgIGlmICggam9iSWQgIT0gbnVsbCApIHsKKyAgICAgICAgICAgIHJldHVybiBqb2JUb3BpYy5yZXBsYWNlKCcvJywgJy4nKSArICIvIiArIEV2ZW50SGVscGVyLmZpbHRlcihqb2JJZCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGpvYlRvcGljLnJlcGxhY2UoJy8nLCAnLicpICsgIi9Kb2IgIiArIFVVSUQucmFuZG9tVVVJRCgpLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogUHJvY2VzcyBhIGpvYiBhbmQgdW5sb2NrIHRoZSBub2RlIGluIHRoZSByZXBvc2l0b3J5LgorICAgICAqIEBwYXJhbSBldmVudCBUaGUgb3JpZ2luYWwgZXZlbnQuCisgICAgICogQHBhcmFtIGV2ZW50Tm9kZSBUaGUgbm9kZSBpbiB0aGUgcmVwb3NpdG9yeSB3aGVyZSB0aGUgam9iIGlzIHN0b3JlZC4KKyAgICAgKiBAcGFyYW0gaXNNYWluUXVldWUgSXMgdGhpcyB0aGUgbWFpbiBxdWV1ZT8KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgcHJvY2Vzc0pvYihFdmVudCBldmVudCwgTm9kZSBldmVudE5vZGUsIGJvb2xlYW4gaXNNYWluUXVldWUpICB7CisgICAgICAgIGZpbmFsIGJvb2xlYW4gcGFyYWxsZWxQcm9jZXNzaW5nID0gZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9RVUVVRV9OQU1FKSAhPSBudWxsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9QQVJBTExFTCkgIT0gbnVsbDsKKyAgICAgICAgZmluYWwgU3RyaW5nIGpvYlRvcGljID0gKFN0cmluZylldmVudC5nZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1RPUElDKTsKKyAgICAgICAgYm9vbGVhbiB1bmxvY2sgPSB0cnVlOworICAgICAgICB0cnkgeworICAgICAgICAgICAgaWYgKCBpc01haW5RdWV1ZSAmJiAhcGFyYWxsZWxQcm9jZXNzaW5nICkgeworICAgICAgICAgICAgICAgIHRoaXMucGFyYWxsZWxKb2JDb3VudCsrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5vZGVQYXRoID0gZXZlbnROb2RlLmdldFBhdGgoKTsKKyAgICAgICAgICAgIGZpbmFsIEV2ZW50IGpvYkV2ZW50ID0gdGhpcy5nZXRKb2JFdmVudChldmVudCwgbm9kZVBhdGgpOworICAgICAgICAgICAgZXZlbnROb2RlLnNldFByb3BlcnR5KEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfUFJPQ0VTU09SLCB0aGlzLmFwcGxpY2F0aW9uSWQpOworICAgICAgICAgICAgZXZlbnROb2RlLnNhdmUoKTsKKyAgICAgICAgICAgIGZpbmFsIEV2ZW50QWRtaW4gbG9jYWxFQSA9IHRoaXMuZXZlbnRBZG1pbjsKKyAgICAgICAgICAgIGlmICggbG9jYWxFQSAhPSBudWxsICkgeworICAgICAgICAgICAgICAgIGZpbmFsIFN0YXJ0ZWRKb2JJbmZvIGpvYkluZm8gPSBuZXcgU3RhcnRlZEpvYkluZm8oam9iRXZlbnQsIG5vZGVQYXRoLCBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisgICAgICAgICAgICAgICAgLy8gbGV0J3MgYWRkIHRoZSBldmVudCB0byBvdXIgcHJvY2Vzc2luZyBsaXN0CisgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICggdGhpcy5wcm9jZXNzaW5nRXZlbnRzTGlzdCApIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzaW5nRXZlbnRzTGlzdC5wdXQobm9kZVBhdGgsIGpvYkluZm8pOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgYXN5bmMgZGVsaXZlcnksIG90aGVyd2lzZSB3ZSBtaWdodCBjcmVhdGUgYSBkZWFkbG9jaworICAgICAgICAgICAgICAgIC8vIGFzIHRoaXMgbWV0aG9kIHJ1bnMgaW5zaWRlIGEgc3luY2hyb25pemVkIGJsb2NrIGFuZCB0aGUgZmluaXNoZWRKb2IKKyAgICAgICAgICAgICAgICAvLyBtZXRob2QgYXMgd2VsbCEKKyAgICAgICAgICAgICAgICBsb2NhbEVBLnBvc3RFdmVudChqb2JFdmVudCk7CisgICAgICAgICAgICAgICAgLy8gZG8gbm90IHVubG9jayBpZiBzZW5kaW5nIHdhcyBzdWNjZXNzZnVsCisgICAgICAgICAgICAgICAgdW5sb2NrID0gZmFsc2U7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCJKb2IgZXZlbnQgY2FuJ3QgYmUgc2VudCBhcyBubyBldmVudCBhZG1pbiBpcyBhdmFpbGFibGUuIik7CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgIC8vIGlmIGFuIGV4Y2VwdGlvbiBvY2N1cnMsIHdlIGp1c3QgbG9nCisgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcigiRXhjZXB0aW9uIGR1cmluZyBqb2IgcHJvY2Vzc2luZy4iLCByZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoIHVubG9jayApIHsKKyAgICAgICAgICAgICAgICBpZiAoIGlzTWFpblF1ZXVlICYmICFwYXJhbGxlbFByb2Nlc3NpbmcgKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMucGFyYWxsZWxKb2JDb3VudC0tOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoICFwYXJhbGxlbFByb2Nlc3NpbmcgKSB7CisgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoIHRoaXMucHJvY2Vzc2luZ01hcCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc2luZ01hcC5wdXQoam9iVG9waWMsIEJvb2xlYW4uRkFMU0UpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIHVubG9jayBub2RlCisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgZXZlbnROb2RlLnVubG9jaygpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBpZiB1bmxvY2sgZmFpbHMsIHdlIHNpbGVudGx5IGlnbm9yZSB0aGlzCisgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIENyZWF0ZSB0aGUgcmVhbCBqb2IgZXZlbnQuCisgICAgICogVGhpcyBnZW5lcmF0ZXMgYSBuZXcgZXZlbnQgb2JqZWN0IHdpdGggdGhlIHNhbWUgcHJvcGVydGllcywgYnV0IHdpdGggdGhlCisgICAgICoge0BsaW5rIEV2ZW50VXRpbCNQUk9QRVJUWV9KT0JfVE9QSUN9IHRvcGljLgorICAgICAqIEBwYXJhbSBlIFRoZSBqb2IgZXZlbnQuCisgICAgICogQHJldHVybiBUaGUgcmVhbCBqb2IgZXZlbnQuCisgICAgICovCisgICAgcHJpdmF0ZSBFdmVudCBnZXRKb2JFdmVudChFdmVudCBlLCBTdHJpbmcgbm9kZVBhdGgpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIGV2ZW50VG9waWMgPSAoU3RyaW5nKWUuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9UT1BJQyk7CisgICAgICAgIGZpbmFsIERpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IHByb3BlcnRpZXMgPSBuZXcgRXZlbnRQcm9wZXJ0aWVzTWFwKGUpOworICAgICAgICAvLyBwdXQgcHJvcGVydGllcyBmb3IgZmluaXNoZWQgam9iIGNhbGxiYWNrCisgICAgICAgIHByb3BlcnRpZXMucHV0KEV2ZW50VXRpbC5Kb2JTdGF0dXNOb3RpZmllci5DT05URVhUX1BST1BFUlRZX05BTUUsCisgICAgICAgICAgICAgICAgbmV3IEV2ZW50VXRpbC5Kb2JTdGF0dXNOb3RpZmllci5Ob3RpZmllckNvbnRleHQodGhpcywgbm9kZVBhdGgpKTsKKyAgICAgICAgcmV0dXJuIG5ldyBFdmVudChldmVudFRvcGljLCBwcm9wZXJ0aWVzKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuZW5naW5lLmV2ZW50LmltcGwuSm9iUGVyc2lzdGVuY2VIYW5kbGVyI2FkZE5vZGVQcm9wZXJ0aWVzKGphdmF4Lmpjci5Ob2RlLCBvcmcub3NnaS5zZXJ2aWNlLmV2ZW50LkV2ZW50KQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGFkZE5vZGVQcm9wZXJ0aWVzKE5vZGUgZXZlbnROb2RlLCBFdmVudCBldmVudCkKKyAgICB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLmFkZE5vZGVQcm9wZXJ0aWVzKGV2ZW50Tm9kZSwgZXZlbnQpOworICAgICAgICBldmVudE5vZGUuc2V0UHJvcGVydHkoRXZlbnRIZWxwZXIuTk9ERV9QUk9QRVJUWV9UT1BJQywgKFN0cmluZylldmVudC5nZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1RPUElDKSk7CisgICAgICAgIGZpbmFsIFN0cmluZyBqb2JJZCA9IChTdHJpbmcpZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9JRCk7CisgICAgICAgIGlmICggam9iSWQgIT0gbnVsbCApIHsKKyAgICAgICAgICAgIGV2ZW50Tm9kZS5zZXRQcm9wZXJ0eShFdmVudEhlbHBlci5OT0RFX1BST1BFUlRZX0pPQklELCBqb2JJZCk7CisgICAgICAgIH0KKyAgICAgICAgZmluYWwgbG9uZyByZXRyeUNvdW50ID0gT3NnaVV0aWwudG9Mb25nKGV2ZW50LmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUkVUUllfQ09VTlQpLCAwKTsKKyAgICAgICAgZmluYWwgbG9uZyByZXRyaWVzID0gT3NnaVV0aWwudG9Mb25nKGV2ZW50LmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUkVUUklFUyksIHRoaXMubWF4Sm9iUmV0cmllcyk7CisgICAgICAgIGV2ZW50Tm9kZS5zZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1JFVFJZX0NPVU5ULCByZXRyeUNvdW50KTsKKyAgICAgICAgZXZlbnROb2RlLnNldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUkVUUklFUywgcmV0cmllcyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LmltcGwuQWJzdHJhY3RSZXBvc2l0b3J5RXZlbnRIYW5kbGVyI2FkZEV2ZW50UHJvcGVydGllcyhqYXZheC5qY3IuTm9kZSwgamF2YS51dGlsLkRpY3Rpb25hcnkpCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgYWRkRXZlbnRQcm9wZXJ0aWVzKE5vZGUgZXZlbnROb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBwcm9wZXJ0aWVzKQorICAgIHRocm93cyBSZXBvc2l0b3J5RXhjZXB0aW9uIHsKKyAgICAgICAgc3VwZXIuYWRkRXZlbnRQcm9wZXJ0aWVzKGV2ZW50Tm9kZSwgcHJvcGVydGllcyk7CisgICAgICAgIC8vIGNvbnZlcnQgdG8gaW50ZWdlcnMgKGpjciBvbmx5IHN1cHBvcnRzIGxvbmcpCisgICAgICAgIGlmICggcHJvcGVydGllcy5nZXQoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9SRVRSSUVTKSAhPSBudWxsICkgeworICAgICAgICAgICAgcHJvcGVydGllcy5wdXQoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9SRVRSSUVTLCBJbnRlZ2VyLnZhbHVlT2YocHJvcGVydGllcy5nZXQoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9SRVRSSUVTKS50b1N0cmluZygpKSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCBwcm9wZXJ0aWVzLmdldChFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1JFVFJZX0NPVU5UKSAhPSBudWxsICkgeworICAgICAgICAgICAgcHJvcGVydGllcy5wdXQoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9SRVRSWV9DT1VOVCwgSW50ZWdlci52YWx1ZU9mKHByb3BlcnRpZXMuZ2V0KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUkVUUllfQ09VTlQpLnRvU3RyaW5nKCkpKTsKKyAgICAgICAgfQorICAgICAgICAvLyBhZGQgYXBwbGljYXRpb24gaWQKKyAgICAgICAgcHJvcGVydGllcy5wdXQoRXZlbnRVdGlsLlBST1BFUlRZX0FQUExJQ0FUSU9OLCBldmVudE5vZGUuZ2V0UHJvcGVydHkoRXZlbnRIZWxwZXIuTk9ERV9QUk9QRVJUWV9BUFBMSUNBVElPTikuZ2V0U3RyaW5nKCkpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YXguamNyLm9ic2VydmF0aW9uLkV2ZW50TGlzdGVuZXIjb25FdmVudChqYXZheC5qY3Iub2JzZXJ2YXRpb24uRXZlbnRJdGVyYXRvcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBvbkV2ZW50KEV2ZW50SXRlcmF0b3IgaXRlcikgeworICAgICAgICAvLyB3ZSBjcmVhdGUgYW4gb3duIHNlc3Npb24gaGVyZQorICAgICAgICBTZXNzaW9uIHMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcyA9IHRoaXMuY3JlYXRlU2Vzc2lvbigpOworICAgICAgICAgICAgd2hpbGUgKCBpdGVyLmhhc05leHQoKSApIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBqYXZheC5qY3Iub2JzZXJ2YXRpb24uRXZlbnQgZXZlbnQgPSBpdGVyLm5leHRFdmVudCgpOworICAgICAgICAgICAgICAgIGlmICggZXZlbnQuZ2V0VHlwZSgpID09IGphdmF4Lmpjci5vYnNlcnZhdGlvbi5FdmVudC5QUk9QRVJUWV9DSEFOR0VECisgICAgICAgICAgICAgICAgICAgfHwgZXZlbnQuZ2V0VHlwZSgpID09IGphdmF4Lmpjci5vYnNlcnZhdGlvbi5FdmVudC5QUk9QRVJUWV9SRU1PVkVEKSB7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJvcFBhdGggPSBldmVudC5nZXRQYXRoKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcG9zID0gcHJvcFBhdGgubGFzdEluZGV4T2YoJy8nKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBub2RlUGF0aCA9IHByb3BQYXRoLnN1YnN0cmluZygwLCBwb3MpOworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByb3BlcnR5TmFtZSA9IHByb3BQYXRoLnN1YnN0cmluZyhwb3MrMSk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGFyZSBvbmx5IGludGVyZXN0ZWQgaW4gdW5sb2NrcworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAiamNyOmxvY2tPd25lciIuZXF1YWxzKHByb3BlcnR5TmFtZSkgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBkb05vdFByb2Nlc3MgPSBmYWxzZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKCB0aGlzLmRlbGV0ZWRKb2JzICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb05vdFByb2Nlc3MgPSB0aGlzLmRlbGV0ZWRKb2JzLnJlbW92ZShub2RlUGF0aCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIWRvTm90UHJvY2VzcyApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBldmVudE5vZGUgPSAoTm9kZSkgcy5nZXRJdGVtKG5vZGVQYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAhZXZlbnROb2RlLmlzTG9ja2VkKCkgJiYgIWV2ZW50Tm9kZS5oYXNQcm9wZXJ0eShFdmVudEhlbHBlci5OT0RFX1BST1BFUlRZX0ZJTklTSEVEKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBFdmVudEluZm8gaW5mbyA9IG5ldyBFdmVudEluZm8oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLmV2ZW50ID0gdGhpcy5yZWFkRXZlbnQoZXZlbnROb2RlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLm5vZGVQYXRoID0gbm9kZVBhdGg7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5xdWV1ZS5wdXQoaW5mbyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhpcyBleGNlcHRpb24gYXMgdGhpcyBzaG91bGQgbmV2ZXIgb2NjdXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pZ25vcmVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RvcmUgcGF0aCBmb3IgbGF6eSBsb2FkaW5nCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICggdGhpcy51bmxvYWRlZEpvYnMgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudW5sb2FkZWRKb2JzLmFkZChub2RlUGF0aCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGNuZmUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcigiRXhjZXB0aW9uIGR1cmluZyBqY3IgZXZlbnQgcHJvY2Vzc2luZy4iLCByZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCJVbmFibGUgdG8gY3JlYXRlIGEgc2Vzc2lvbi4iLCByZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoIHMgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICBzLmxvZ291dCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZCBhbGwgYWN0aXZlIGpvYnMgZnJvbSB0aGUgcmVwb3NpdG9yeS4KKyAgICAgKiBAdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIHZvaWQgbG9hZEpvYnMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBRdWVyeU1hbmFnZXIgcU1hbmFnZXIgPSB0aGlzLmJhY2tncm91bmRTZXNzaW9uLmdldFdvcmtzcGFjZSgpLmdldFF1ZXJ5TWFuYWdlcigpOworICAgICAgICAgICAgZmluYWwgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoIi9qY3I6cm9vdCIpOworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCh0aGlzLnJlcG9zaXRvcnlQYXRoKTsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIi8vZWxlbWVudCgqLCAiKTsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQodGhpcy5nZXRFdmVudE5vZGVUeXBlKCkpOworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiKSBvcmRlciBieSBAIik7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfQ1JFQVRFRCk7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIgYXNjZW5kaW5nIik7CisgICAgICAgICAgICBmaW5hbCBRdWVyeSBxID0gcU1hbmFnZXIuY3JlYXRlUXVlcnkoYnVmZmVyLnRvU3RyaW5nKCksIFF1ZXJ5LlhQQVRIKTsKKyAgICAgICAgICAgIGZpbmFsIE5vZGVJdGVyYXRvciByZXN1bHQgPSBxLmV4ZWN1dGUoKS5nZXROb2RlcygpOworICAgICAgICAgICAgd2hpbGUgKCByZXN1bHQuaGFzTmV4dCgpICkgeworICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgZXZlbnROb2RlID0gcmVzdWx0Lm5leHROb2RlKCk7CisgICAgICAgICAgICAgICAgaWYgKCAhZXZlbnROb2RlLmlzTG9ja2VkKCkgJiYgIWV2ZW50Tm9kZS5oYXNQcm9wZXJ0eShFdmVudEhlbHBlci5OT0RFX1BST1BFUlRZX0ZJTklTSEVEKSkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbm9kZVBhdGggPSBldmVudE5vZGUuZ2V0UGF0aCgpOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgRXZlbnQgZXZlbnQgPSB0aGlzLnJlYWRFdmVudChldmVudE5vZGUpOworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgRXZlbnRJbmZvIGluZm8gPSBuZXcgRXZlbnRJbmZvKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLmV2ZW50ID0gZXZlbnQ7CisgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLm5vZGVQYXRoID0gbm9kZVBhdGg7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucXVldWUucHV0KGluZm8pOworICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGlnbm9yZSB0aGlzIGV4Y2VwdGlvbiBhcyB0aGlzIHNob3VsZCBuZXZlciBvY2N1cgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN0b3JlIHBhdGggZm9yIGxhenkgbG9hZGluZworICAgICAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICggdGhpcy51bmxvYWRlZEpvYnMgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51bmxvYWRlZEpvYnMuYWRkKG5vZGVQYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGNuZmUpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcigiVW5hYmxlIHRvIGxvYWQgc3RvcmVkIGpvYiBmcm9tICIgKyBub2RlUGF0aCwgcmUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcigiRXhjZXB0aW9uIGR1cmluZyBpbml0aWFsIGxvYWRpbmcgb2Ygc3RvcmVkIGpvYnMuIiwgcmUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LkV2ZW50VXRpbC5Kb2JTdGF0dXNOb3RpZmllciNzZW5kQWNrbm93bGVkZ2Uob3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudCwgamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgYm9vbGVhbiBzZW5kQWNrbm93bGVkZ2UoRXZlbnQgam9iLCBTdHJpbmcgZXZlbnROb2RlUGF0aCkgeworICAgICAgICBzeW5jaHJvbml6ZWQgKCB0aGlzLnByb2Nlc3NpbmdFdmVudHNMaXN0ICkgeworICAgICAgICAgICAgLy8gaWYgdGhlIGV2ZW50IGlzIHN0aWxsIGluIHRoZSBwcm9jZXNzaW5nIGxpc3QsIHdlIGNvbmZpcm0gdGhlIGFjaworICAgICAgICAgICAgZmluYWwgT2JqZWN0IGFjayA9IHRoaXMucHJvY2Vzc2luZ0V2ZW50c0xpc3QucmVtb3ZlKGV2ZW50Tm9kZVBhdGgpOworICAgICAgICAgICAgcmV0dXJuIGFjayAhPSBudWxsOworICAgICAgICB9CisKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBUaGlzIGlzIGEgbm90aWZpY2F0aW9uIGZyb20gdGhlIGNvbXBvbmVudCB3aGljaCBwcm9jZXNzZWQgdGhlIGpvYi4KKyAgICAgKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5FdmVudFV0aWwuSm9iU3RhdHVzTm90aWZpZXIjZmluaXNoZWRKb2Iob3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudCwgU3RyaW5nLCBib29sZWFuKQorICAgICAqLworICAgIHB1YmxpYyBib29sZWFuIGZpbmlzaGVkSm9iKEV2ZW50IGpvYiwgU3RyaW5nIGV2ZW50Tm9kZVBhdGgsIGJvb2xlYW4gc2hvdWxkUmVzY2hlZHVsZSkgeworICAgICAgICAvLyBsZXQncyByZW1vdmUgdGhlIGV2ZW50IGZyb20gb3VyIHByb2Nlc3NpbmcgbGlzdAorICAgICAgICAvLyB0aGlzIGlzIGp1c3QgYSBzYW5pdHkgY2hlY2ssIGFzIHVzdWFsbHkgdGhlIGpvYiBzaG91bGQgaGF2ZSBiZWVuCisgICAgICAgIC8vIHJlbW92ZWQgZHVyaW5nIHNlbmRBY2tub3dsZWRnZS4KKyAgICAgICAgc3luY2hyb25pemVkICggdGhpcy5wcm9jZXNzaW5nRXZlbnRzTGlzdCApIHsKKyAgICAgICAgICAgIHRoaXMucHJvY2Vzc2luZ0V2ZW50c0xpc3QucmVtb3ZlKGV2ZW50Tm9kZVBhdGgpOworICAgICAgICB9CisKKyAgICAgICAgYm9vbGVhbiByZXNjaGVkdWxlID0gc2hvdWxkUmVzY2hlZHVsZTsKKyAgICAgICAgaWYgKCBzaG91bGRSZXNjaGVkdWxlICkgeworICAgICAgICAgICAgLy8gY2hlY2sgaWYgd2UgZXhjZWVkZWQgdGhlIG51bWJlciBvZiByZXRyaWVzCisgICAgICAgICAgICBpbnQgcmV0cmllcyA9IHRoaXMubWF4Sm9iUmV0cmllczsKKyAgICAgICAgICAgIGlmICggam9iLmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUkVUUklFUykgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICByZXRyaWVzID0gKEludGVnZXIpIGpvYi5nZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1JFVFJJRVMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaW50IHJldHJ5Q291bnQgPSAwOworICAgICAgICAgICAgaWYgKCBqb2IuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9SRVRSWV9DT1VOVCkgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICByZXRyeUNvdW50ID0gKEludGVnZXIpam9iLmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUkVUUllfQ09VTlQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0cnlDb3VudCsrOworICAgICAgICAgICAgaWYgKCByZXRyaWVzICE9IC0xICYmIHJldHJ5Q291bnQgPiByZXRyaWVzICkgeworICAgICAgICAgICAgICAgIHJlc2NoZWR1bGUgPSBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICggcmVzY2hlZHVsZSApIHsKKyAgICAgICAgICAgICAgICAvLyB1cGRhdGUgZXZlbnQgd2l0aCByZXRyeSBjb3VudCBhbmQgcmV0cmllcworICAgICAgICAgICAgICAgIGZpbmFsIERpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IG5ld1Byb3BlcnRpZXMgPSBuZXcgRXZlbnRQcm9wZXJ0aWVzTWFwKGpvYik7CisgICAgICAgICAgICAgICAgbmV3UHJvcGVydGllcy5wdXQoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9SRVRSWV9DT1VOVCwgcmV0cnlDb3VudCk7CisgICAgICAgICAgICAgICAgbmV3UHJvcGVydGllcy5wdXQoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9SRVRSSUVTLCByZXRyaWVzKTsKKyAgICAgICAgICAgICAgICBqb2IgPSBuZXcgRXZlbnQoam9iLmdldFRvcGljKCksIG5ld1Byb3BlcnRpZXMpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZpbmFsIGJvb2xlYW4gcGFyYWxsZWxQcm9jZXNzaW5nID0gam9iLmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUVVFVUVfTkFNRSkgIT0gbnVsbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGpvYi5nZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1BBUkFMTEVMKSAhPSBudWxsOworICAgICAgICBFdmVudEluZm8gcHV0YmFjayA9IG51bGw7CisgICAgICAgIC8vIHdlIGhhdmUgdG8gdXNlIHRoZSBzYW1lIHNlc3Npb24gZm9yIHVubG9ja2luZyB0aGF0IHdlIHVzZWQgZm9yIGxvY2tpbmchCisgICAgICAgIHN5bmNocm9uaXplZCAoIHRoaXMuYmFja2dyb3VuZExvY2sgKSB7CisgICAgICAgICAgICAvLyB3ZSBtaWdodCBnZXQgaGVyZSBhc255YyB3aGlsZSB0aGlzIHNlcnZpY2UgaGFzIGFscmVhZHkgYmVlbiBzaHV0ZG93biEKKyAgICAgICAgICAgIGlmICggdGhpcy5iYWNrZ3JvdW5kU2Vzc2lvbiA9PSBudWxsICkgeworICAgICAgICAgICAgICAgIC8vIHdlIGNhbiBvbmx5IHJldHVybiBmYWxzZSBoZXJlCisgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0aGlzLmJhY2tncm91bmRTZXNzaW9uLnJlZnJlc2goZmFsc2UpOworICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIHRoZSBqb2IgaGFzIGJlZW4gY2FuY2VsbGVkCisgICAgICAgICAgICAgICAgaWYgKCAhdGhpcy5iYWNrZ3JvdW5kU2Vzc2lvbi5pdGVtRXhpc3RzKGV2ZW50Tm9kZVBhdGgpICkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBldmVudE5vZGUgPSAoTm9kZSkgdGhpcy5iYWNrZ3JvdW5kU2Vzc2lvbi5nZXRJdGVtKGV2ZW50Tm9kZVBhdGgpOworICAgICAgICAgICAgICAgIGJvb2xlYW4gdW5sb2NrID0gdHJ1ZTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBpZiAoICFyZXNjaGVkdWxlICkgeworICAgICAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICggdGhpcy5kZWxldGVkSm9icyApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlbGV0ZWRKb2JzLmFkZChldmVudE5vZGVQYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVubG9jayBub2RlCisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Tm9kZS51bmxvY2soKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHVubG9jayBmYWlscywgd2Ugc2lsZW50bHkgaWdub3JlIHRoaXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHVubG9jayA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIGpvYklkID0gKFN0cmluZylqb2IuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9JRCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGpvYklkID09IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIG5vZGUgZnJvbSByZXBvc2l0b3J5IGlmIG5vIGpvYiBpcyBzZXQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIHBhcmVudE5vZGUgPSBldmVudE5vZGUuZ2V0UGFyZW50KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnROb2RlLnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUuc2F2ZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudE5vZGUuc2V0UHJvcGVydHkoRXZlbnRIZWxwZXIuTk9ERV9QUk9QRVJUWV9GSU5JU0hFRCwgQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnROb2RlLnNhdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gaWYgYW4gZXhjZXB0aW9uIG9jY3Vycywgd2UganVzdCBsb2cKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoIkV4Y2VwdGlvbiBkdXJpbmcgam9iIGZpbmlzaGluZy4iLCByZSk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCAhcGFyYWxsZWxQcm9jZXNzaW5nKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgam9iVG9waWMgPSAoU3RyaW5nKWpvYi5nZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1RPUElDKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoIHRoaXMucHJvY2Vzc2luZ01hcCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NpbmdNYXAucHV0KGpvYlRvcGljLCBCb29sZWFuLkZBTFNFKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICggam9iLmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUVVFVUVfTkFNRSkgPT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmFsbGVsSm9iQ291bnQtLTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoIHVubG9jayApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoIHRoaXMuZGVsZXRlZEpvYnMgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWxldGVkSm9icy5hZGQoZXZlbnROb2RlUGF0aCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAvLyB1bmxvY2sgbm9kZQorICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudE5vZGUudW5sb2NrKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB1bmxvY2sgZmFpbHMsIHdlIHNpbGVudGx5IGlnbm9yZSB0aGlzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pZ25vcmVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKCByZXNjaGVkdWxlICkgeworICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgcmV0cnkgY291bnQgYW5kIHJldHJpZXMgaW4gdGhlIHJlcG9zaXRvcnkKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Tm9kZS5zZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1JFVFJJRVMsIChJbnRlZ2VyKWpvYi5nZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1JFVFJJRVMpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Tm9kZS5zZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1JFVFJZX0NPVU5ULCAoSW50ZWdlcilqb2IuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9SRVRSWV9DT1VOVCkpOworICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnROb2RlLnNhdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgYW4gZXhjZXB0aW9uIG9jY3Vycywgd2UganVzdCBsb2cKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCJFeGNlcHRpb24gZHVyaW5nIGpvYiB1cGRhdGluZyBqb2IgcmVzY2hlZHVsaW5nIGluZm9ybWF0aW9uLiIsIHJlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBmaW5hbCBFdmVudEluZm8gaW5mbyA9IG5ldyBFdmVudEluZm8oKTsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGluZm8uZXZlbnQgPSBqb2I7CisgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLm5vZGVQYXRoID0gZXZlbnROb2RlLmdldFBhdGgoKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHNob3VsZCBuZXZlciBoYXBwZW4KKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYW4gb3duIGpvYiBxdWV1ZSwgd2Ugc2ltcGx5IHNpZ25hbCB0aGUgcXVldWUgdG8gY29udGludWUKKyAgICAgICAgICAgICAgICAgICAgLy8gaXQgd2lsbCBwaWNrIHVwIHRoZSBldmVudCBhbmQgZWl0aGVyIHJlc2NoZWR1bGUgb3Igd2FpdAorICAgICAgICAgICAgICAgICAgICBpZiAoIGpvYi5nZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1FVRVVFX05BTUUpICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBrbm93IHRoZSBxdWV1ZSBleGlzdHMKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpvYkJsb2NraW5nUXVldWUgam9iUXVldWU7CisgICAgICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKCB0aGlzLmpvYlF1ZXVlcyApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2JRdWV1ZSA9IHRoaXMuam9iUXVldWVzLmdldChqb2IuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9RVUVVRV9OQU1FKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKCBqb2JRdWV1ZS5nZXRMb2NrKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2JRdWV1ZS5ub3RpZnlGaW5pc2goaW5mbyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlbGF5IHJlc2NoZWR1bGluZz8KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmICggam9iLmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9KT0JfUkVUUllfREVMQVkpICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHV0YmFjayA9IGluZm87CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHB1dCBkaXJlY3RseSBpbnRvIHF1ZXVlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVldWUucHV0KGluZm8pOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYW4gb3duIGpvYiBxdWV1ZSwgd2Ugc2ltcGx5IHNpZ25hbCB0aGUgcXVldWUgdG8gY29udGludWUKKyAgICAgICAgICAgICAgICAgICAgLy8gaXQgd2lsbCBwaWNrIHVwIHRoZSBldmVudCBhbmQgY29udGludWUgd2l0aCB0aGUgbmV4dCBldmVudAorICAgICAgICAgICAgICAgICAgICBpZiAoIGpvYi5nZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfSk9CX1FVRVVFX05BTUUpICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBrbm93IHRoZSBxdWV1ZSBleGlzdHMKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEpvYkJsb2NraW5nUXVldWUgam9iUXVldWU7CisgICAgICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKCB0aGlzLmpvYlF1ZXVlcyApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2JRdWV1ZSA9IHRoaXMuam9iUXVldWVzLmdldChqb2IuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9RVUVVRV9OQU1FKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKCBqb2JRdWV1ZS5nZXRMb2NrKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2JRdWV1ZS5ub3RpZnlGaW5pc2gobnVsbCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoIlVuYWJsZSB0byBjcmVhdGUgbmV3IHNlc3Npb24uIiwgcmUpOworICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoIHB1dGJhY2sgIT0gbnVsbCApIHsKKyAgICAgICAgICAgIGZpbmFsIEV2ZW50SW5mbyBpbmZvID0gcHV0YmFjazsKKyAgICAgICAgICAgIGZpbmFsIGxvbmcgZGVsYXkgPSAoTG9uZylqb2IuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9SRVRSWV9ERUxBWSk7CisgICAgICAgICAgICBmaW5hbCBEYXRlIGZpcmVEYXRlID0gbmV3IERhdGUoKTsKKyAgICAgICAgICAgIGZpcmVEYXRlLnNldFRpbWUoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgKyBkZWxheSk7CisKKyAgICAgICAgICAgIGZpbmFsIFJ1bm5hYmxlIHQgPSBuZXcgUnVubmFibGUoKSB7CisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgcXVldWUucHV0KGluZm8pOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHNob3VsZCBuZXZlciBoYXBwZW4KKyAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH07CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHRoaXMuc2NoZWR1bGVyLmZpcmVKb2JBdChudWxsLCB0LCBudWxsLCBmaXJlRGF0ZSk7CisgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIC8vIHdlIGlnbm9yZSB0aGUgZXhjZXB0aW9uIGFuZCBqdXN0IHB1dCBiYWNrIHRoZSBqb2IgaW4gdGhlIHF1ZXVlCisgICAgICAgICAgICAgICAgaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIHQucnVuKCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKCAhc2hvdWxkUmVzY2hlZHVsZSApIHsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXNjaGVkdWxlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNlYXJjaCBmb3Igam9iIG5vZGVzCisgICAgICogQHBhcmFtIHRvcGljIFRoZSBqb2IgdG9waWMKKyAgICAgKiBAcGFyYW0gZmlsdGVyUHJvcHMgb3B0aW9uYWwgZmlsdGVyIHByb3BzCisgICAgICogQHBhcmFtIGxvY2tlZCBvbmx5IGFjdGl2ZSBqb2JzPworICAgICAqIEByZXR1cm4KKyAgICAgKiBAdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24KKyAgICAgKi8KKyAgICBwcml2YXRlIENvbGxlY3Rpb248RXZlbnQ+IHF1ZXJ5Sm9icyhmaW5hbCBTdHJpbmcgdG9waWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgQm9vbGVhbiBsb2NrZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWFwPFN0cmluZywgT2JqZWN0Pi4uLiBmaWx0ZXJQcm9wcykgIHsKKyAgICAgICAgLy8gd2UgY3JlYXRlIGEgbmV3IHNlc3Npb24KKyAgICAgICAgU2Vzc2lvbiBzID0gbnVsbDsKKyAgICAgICAgZmluYWwgTGlzdDxFdmVudD4gam9icyA9IG5ldyBBcnJheUxpc3Q8RXZlbnQ+KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzID0gdGhpcy5jcmVhdGVTZXNzaW9uKCk7CisgICAgICAgICAgICBmaW5hbCBRdWVyeU1hbmFnZXIgcU1hbmFnZXIgPSBzLmdldFdvcmtzcGFjZSgpLmdldFF1ZXJ5TWFuYWdlcigpOworICAgICAgICAgICAgZmluYWwgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoIi9qY3I6cm9vdCIpOworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCh0aGlzLnJlcG9zaXRvcnlQYXRoKTsKKyAgICAgICAgICAgIGlmICggdG9waWMgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcvJyk7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCh0b3BpYy5yZXBsYWNlKCcvJywgJy4nKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIvL2VsZW1lbnQoKiwgIik7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHRoaXMuZ2V0RXZlbnROb2RlVHlwZSgpKTsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIikgW25vdChAIik7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfRklOSVNIRUQpOworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiKSIpOworICAgICAgICAgICAgaWYgKCBsb2NrZWQgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICBpZiAoIGxvY2tlZCApIHsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiIGFuZCBAamNyOmxvY2tPd25lciIpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIiBhbmQgbm90KEBqY3I6bG9ja093bmVyKSIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICggZmlsdGVyUHJvcHMgIT0gbnVsbCAmJiBmaWx0ZXJQcm9wcy5sZW5ndGggPiAwICkgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIiBhbmQgKCIpOworICAgICAgICAgICAgICAgIGludCBpbmRleCA9IDA7CisgICAgICAgICAgICAgICAgZm9yIChNYXA8U3RyaW5nLE9iamVjdD4gdGVtcGxhdGUgOiBmaWx0ZXJQcm9wcykgeworICAgICAgICAgICAgICAgICAgICBpZiAoIGluZGV4ID4gMCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIiBvciAiKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcoJyk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIEl0ZXJhdG9yPE1hcC5FbnRyeTxTdHJpbmcsIE9iamVjdD4+IGkgPSB0ZW1wbGF0ZS5lbnRyeVNldCgpLml0ZXJhdG9yKCk7CisgICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gZmlyc3QgPSB0cnVlOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoIGkuaGFzTmV4dCgpICkgeworICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWFwLkVudHJ5PFN0cmluZywgT2JqZWN0PiBjdXJyZW50ID0gaS5uZXh0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBwcm9wIG5hbWUgZmlyc3QKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBwcm9wTmFtZSA9IEV2ZW50VXRpbC5nZXROb2RlUHJvcGVydHlOYW1lKGN1cnJlbnQuZ2V0S2V5KCkpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBwcm9wTmFtZSAhPSBudWxsICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHZhbHVlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgVmFsdWUgdmFsdWUgPSBFdmVudFV0aWwuZ2V0Tm9kZVByb3BlcnR5VmFsdWUocy5nZXRWYWx1ZUZhY3RvcnkoKSwgY3VycmVudC5nZXRWYWx1ZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHZhbHVlICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggZmlyc3QgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnQCcpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiIGFuZCBAIik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChwcm9wTmFtZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIiA9ICciKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChjdXJyZW50LmdldFZhbHVlKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCInIik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJyknKTsKKyAgICAgICAgICAgICAgICAgICAgaW5kZXgrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnKScpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiXSIpOworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiIG9yZGVyIGJ5IEAiKTsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoRXZlbnRIZWxwZXIuTk9ERV9QUk9QRVJUWV9DUkVBVEVEKTsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIiBhc2NlbmRpbmciKTsKKyAgICAgICAgICAgIGZpbmFsIFN0cmluZyBxdWVyeVN0cmluZyA9IGJ1ZmZlci50b1N0cmluZygpOworICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCJFeGVjdXRpbmcgam9iIHF1ZXJ5IHt9LiIsIHF1ZXJ5U3RyaW5nKTsKKworICAgICAgICAgICAgZmluYWwgUXVlcnkgcSA9IHFNYW5hZ2VyLmNyZWF0ZVF1ZXJ5KHF1ZXJ5U3RyaW5nLCBRdWVyeS5YUEFUSCk7CisgICAgICAgICAgICBmaW5hbCBOb2RlSXRlcmF0b3IgaXRlciA9IHEuZXhlY3V0ZSgpLmdldE5vZGVzKCk7CisgICAgICAgICAgICB3aGlsZSAoIGl0ZXIuaGFzTmV4dCgpICkgeworICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgZXZlbnROb2RlID0gaXRlci5uZXh0Tm9kZSgpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIEV2ZW50IGV2ZW50ID0gdGhpcy5yZWFkRXZlbnQoZXZlbnROb2RlKTsKKyAgICAgICAgICAgICAgICAgICAgam9icy5hZGQoZXZlbnQpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkgeworICAgICAgICAgICAgICAgICAgICAvLyBpbiB0aGUgY2FzZSBvZiBhIGNsYXNzIG5vdCBmb3VuZCBleGNlcHRpb24gd2UganVzdCBpZ25vcmUgdGhlIGV4Y2VwdGlvbgorICAgICAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihjbmZlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgLy8gaW4gdGhlIGNhc2Ugb2YgYW4gZXJyb3IsIHdlIHJldHVybiBhbiBlbXB0eSBsaXN0CisgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICggcyAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcy5sb2dvdXQoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gam9iczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuSm9iU3RhdHVzUHJvdmlkZXIjZ2V0Q3VycmVudEpvYnMoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxFdmVudD4gZ2V0Q3VycmVudEpvYnMoU3RyaW5nIHRvcGljKSB7CisgICAgICAgIHJldHVybiB0aGlzLmdldEN1cnJlbnRKb2JzKHRvcGljLCAoTWFwPFN0cmluZywgT2JqZWN0PltdKW51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFRoaXMgaXMgZGVwcmVjYXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxFdmVudD4gc2NoZWR1bGVkSm9icyhTdHJpbmcgdG9waWMpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U2NoZWR1bGVkSm9icyh0b3BpYyk7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LkpvYlN0YXR1c1Byb3ZpZGVyI2dldFNjaGVkdWxlZEpvYnMoamF2YS5sYW5nLlN0cmluZykKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxFdmVudD4gZ2V0U2NoZWR1bGVkSm9icyhTdHJpbmcgdG9waWMpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U2NoZWR1bGVkSm9icyh0b3BpYywgKE1hcDxTdHJpbmcsIE9iamVjdD5bXSludWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuSm9iU3RhdHVzUHJvdmlkZXIjZ2V0Q3VycmVudEpvYnMoamF2YS5sYW5nLlN0cmluZywgamF2YS51dGlsLk1hcC4uLikKKyAgICAgKi8KKyAgICBwdWJsaWMgQ29sbGVjdGlvbjxFdmVudD4gZ2V0Q3VycmVudEpvYnMoU3RyaW5nIHRvcGljLCBNYXA8U3RyaW5nLCBPYmplY3Q+Li4uIGZpbHRlclByb3BzKSB7CisgICAgICAgIHJldHVybiB0aGlzLnF1ZXJ5Sm9icyh0b3BpYywgdHJ1ZSwgZmlsdGVyUHJvcHMpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5Kb2JTdGF0dXNQcm92aWRlciNnZXRTY2hlZHVsZWRKb2JzKGphdmEubGFuZy5TdHJpbmcsIGphdmEudXRpbC5NYXAuLi4pCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248RXZlbnQ+IGdldFNjaGVkdWxlZEpvYnMoU3RyaW5nIHRvcGljLCBNYXA8U3RyaW5nLCBPYmplY3Q+Li4uIGZpbHRlclByb3BzKSB7CisgICAgICAgIHJldHVybiB0aGlzLnF1ZXJ5Sm9icyh0b3BpYywgZmFsc2UsIGZpbHRlclByb3BzKTsKKyAgICB9CisKKworICAgIC8qKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5Kb2JTdGF0dXNQcm92aWRlciNnZXRBbGxKb2JzKGphdmEubGFuZy5TdHJpbmcsIGphdmEudXRpbC5NYXAuLi4pCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248RXZlbnQ+IGdldEFsbEpvYnMoU3RyaW5nIHRvcGljLCBNYXA8U3RyaW5nLCBPYmplY3Q+Li4uIGZpbHRlclByb3BzKSB7CisgICAgICAgIHJldHVybiB0aGlzLnF1ZXJ5Sm9icyh0b3BpYywgbnVsbCwgZmlsdGVyUHJvcHMpOworICAgIH0KKworCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LkpvYlN0YXR1c1Byb3ZpZGVyI2NhbmNlbEpvYihqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyB2b2lkIGNhbmNlbEpvYihTdHJpbmcgdG9waWMsIFN0cmluZyBqb2JJZCkgeworICAgICAgICBpZiAoIGpvYklkICE9IG51bGwgJiYgdG9waWMgIT0gbnVsbCApIHsKKyAgICAgICAgICAgIHRoaXMuY2FuY2VsSm9iKHRoaXMuZ2V0Tm9kZVBhdGgodG9waWMsIGpvYklkKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuSm9iU3RhdHVzUHJvdmlkZXIjY2FuY2VsSm9iKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2FuY2VsSm9iKFN0cmluZyBqb2JJZCkgeworICAgICAgICBpZiAoIGpvYklkICE9IG51bGwgKSB7CisgICAgICAgICAgICBzeW5jaHJvbml6ZWQgKCB0aGlzLndyaXRlTG9jayApIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLndyaXRlclNlc3Npb24ucmVmcmVzaChmYWxzZSk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBpZiAoIHRoaXMud3JpdGVyU2Vzc2lvbi5pdGVtRXhpc3RzKGpvYklkKSApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEl0ZW0gaXRlbSA9IHRoaXMud3JpdGVyU2Vzc2lvbi5nZXRJdGVtKGpvYklkKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgcGFyZW50Tm9kZSA9IGl0ZW0uZ2V0UGFyZW50KCk7CisgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5zYXZlKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoIkVycm9yIGR1cmluZyBjYW5jZWxsaW5nIGpvYiBhdCAiICsgam9iSWQsIGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LkpvYlN0YXR1c1Byb3ZpZGVyI3dha2VVcEpvYlF1ZXVlKGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgd2FrZVVwSm9iUXVldWUoU3RyaW5nIGpvYlF1ZXVlTmFtZSkgeworICAgICAgICBpZiAoIGpvYlF1ZXVlTmFtZSAhPSBudWxsICkgeworICAgICAgICAgICAgc3luY2hyb25pemVkICggdGhpcy5qb2JRdWV1ZXMgKSB7CisgICAgICAgICAgICAgICAgZmluYWwgSm9iQmxvY2tpbmdRdWV1ZSBxdWV1ZSA9IHRoaXMuam9iUXVldWVzLmdldChqb2JRdWV1ZU5hbWUpOworICAgICAgICAgICAgICAgIGlmICggcXVldWUgIT0gbnVsbCAmJiBxdWV1ZS5pc1NsZWVwaW5nKCkgKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBzY2hlZHVsZXJKb2JOYW1lID0gcXVldWUuZ2V0U2NoZWR1bGVySm9iTmFtZSgpOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBUaHJlYWQgdGhyZWFkID0gcXVldWUuZ2V0U2xlZXBpbmdUaHJlYWQoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCBzY2hlZHVsZXJKb2JOYW1lICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjaGVkdWxlci5yZW1vdmVKb2Ioc2NoZWR1bGVySm9iTmFtZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKCB0aHJlYWQgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRocmVhZC5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3RhcnRlZEpvYkluZm8geworICAgICAgICBwdWJsaWMgZmluYWwgRXZlbnQgZXZlbnQ7CisgICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgbm9kZVBhdGg7CisgICAgICAgIHB1YmxpYyBmaW5hbCBsb25nICBzdGFydGVkOworCisgICAgICAgIHB1YmxpYyBTdGFydGVkSm9iSW5mbyhmaW5hbCBFdmVudCBlLCBmaW5hbCBTdHJpbmcgcGF0aCwgZmluYWwgbG9uZyBzdGFydGVkKSB7CisgICAgICAgICAgICB0aGlzLmV2ZW50ID0gZTsKKyAgICAgICAgICAgIHRoaXMubm9kZVBhdGggPSBwYXRoOworICAgICAgICAgICAgdGhpcy5zdGFydGVkID0gc3RhcnRlZDsKKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL1RpbWVkSm9iSGFuZGxlci5qYXZhIGIvc3JjL21haW4vamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L2ltcGwvVGltZWRKb2JIYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmQ1NDA3MQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL1RpbWVkSm9iSGFuZGxlci5qYXZhCkBAIC0wLDAgKzEsNzgyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LmltcGw7CisKK2ltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuRGF0ZTsKK2ltcG9ydCBqYXZhLnV0aWwuRGljdGlvbmFyeTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOworaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5Ob1N1Y2hFbGVtZW50RXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKK2ltcG9ydCBqYXZheC5qY3IuSXRlbTsKK2ltcG9ydCBqYXZheC5qY3IuTm9kZTsKK2ltcG9ydCBqYXZheC5qY3IuTm9kZUl0ZXJhdG9yOworaW1wb3J0IGphdmF4Lmpjci5SZXBvc2l0b3J5RXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lmpjci5TZXNzaW9uOworaW1wb3J0IGphdmF4Lmpjci5WYWx1ZTsKK2ltcG9ydCBqYXZheC5qY3IubG9jay5Mb2NrOworaW1wb3J0IGphdmF4Lmpjci5sb2NrLkxvY2tFeGNlcHRpb247CitpbXBvcnQgamF2YXguamNyLm9ic2VydmF0aW9uLkV2ZW50SXRlcmF0b3I7CitpbXBvcnQgamF2YXguamNyLnF1ZXJ5LlF1ZXJ5OworaW1wb3J0IGphdmF4Lmpjci5xdWVyeS5RdWVyeU1hbmFnZXI7CisKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMuc2NoZWR1bGVyLkpvYjsKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMuc2NoZWR1bGVyLkpvYkNvbnRleHQ7CitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5jb21tb25zLnNjaGVkdWxlci5TY2hlZHVsZXI7CitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5FdmVudFV0aWw7CitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5UaW1lZEV2ZW50U3RhdHVzUHJvdmlkZXI7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudDsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmV2ZW50LkV2ZW50QWRtaW47CisKKworLyoqCisgKiBBbiBldmVudCBoYW5kbGVyIGZvciB0aW1lZCBldmVudHMuCisgKgorICogQHNjci5jb21wb25lbnQgbWV0YXR5cGU9Im5vIgorICogQHNjci5zZXJ2aWNlIGludGVyZmFjZT0iVGltZWRFdmVudFN0YXR1c1Byb3ZpZGVyIgorICogQHNjci5wcm9wZXJ0eSBuYW1lPSJldmVudC50b3BpY3MiIHJlZlZhbHVlcz0iRXZlbnRVdGlsLlRPUElDX1RJTUVEX0VWRU5UIgorICogICAgICAgICAgICAgICB2YWx1ZXMudXBkYXRlZD0ib3JnL29zZ2kvZnJhbWV3b3JrL0J1bmRsZUV2ZW50L1VQREFURUQiCisgKiAgICAgICAgICAgICAgIHZhbHVlcy5zdGFydGVkPSJvcmcvb3NnaS9mcmFtZXdvcmsvQnVuZGxlRXZlbnQvU1RBUlRFRCIKKyAqIEBzY3IucHJvcGVydHkgbmFtZT0icmVwb3NpdG9yeS5wYXRoIiB2YWx1ZT0iL3Zhci9ldmVudGluZy90aW1lZC1qb2JzIgorICovCitwdWJsaWMgY2xhc3MgVGltZWRKb2JIYW5kbGVyCisgICAgZXh0ZW5kcyBBYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXIKKyAgICBpbXBsZW1lbnRzIEpvYiwgVGltZWRFdmVudFN0YXR1c1Byb3ZpZGVyIHsKKworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nIEpPQl9UT1BJQyA9ICJ0b3BpYyI7CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBKT0JfQ09ORklHID0gImNvbmZpZyI7CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBKT0JfU0NIRURVTEVfSU5GTyA9ICJpbmZvIjsKKworICAgIC8qKiBAc2NyLnJlZmVyZW5jZSAqLworICAgIHByb3RlY3RlZCBTY2hlZHVsZXIgc2NoZWR1bGVyOworCisgICAgLyoqIFVubG9hZGVkIGV2ZW50cy4gKi8KKyAgICBwcm90ZWN0ZWQgU2V0PFN0cmluZz51bmxvYWRlZEV2ZW50cyA9IG5ldyBIYXNoU2V0PFN0cmluZz4oKTsKKworICAgIC8qKiBTeW5jIGxvY2sgKi8KKyAgICBwcml2YXRlIGZpbmFsIE9iamVjdCB3cml0ZUxvY2sgPSBuZXcgT2JqZWN0KCk7CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbC5BYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXIjc3RhcnRXcml0ZXJTZXNzaW9uKCkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBzdGFydFdyaXRlclNlc3Npb24oKSB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIHN1cGVyLnN0YXJ0V3JpdGVyU2Vzc2lvbigpOworICAgICAgICAvLyBsb2FkIHRpbWVkIGV2ZW50cyBmcm9tIHJlcG9zaXRvcnkKKyAgICAgICAgdGhpcy5sb2FkRXZlbnRzKCk7CisgICAgICAgIHRoaXMud3JpdGVyU2Vzc2lvbi5nZXRXb3Jrc3BhY2UoKS5nZXRPYnNlcnZhdGlvbk1hbmFnZXIoKQorICAgICAgICAgICAgLmFkZEV2ZW50TGlzdGVuZXIodGhpcywgamF2YXguamNyLm9ic2VydmF0aW9uLkV2ZW50LlBST1BFUlRZX0NIQU5HRUR8amF2YXguamNyLm9ic2VydmF0aW9uLkV2ZW50LlBST1BFUlRZX1JFTU9WRUQsIHRoaXMucmVwb3NpdG9yeVBhdGgsIHRydWUsIG51bGwsIG51bGwsIHRydWUpOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5pbXBsLkFic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlciNwcm9jZXNzV3JpdGVRdWV1ZSgpCisgICAgICovCisgICAgcHJvdGVjdGVkIHZvaWQgcHJvY2Vzc1dyaXRlUXVldWUoKSB7CisgICAgICAgIHdoaWxlICggdGhpcy5ydW5uaW5nICkgeworICAgICAgICAgICAgRXZlbnQgZXZlbnQgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBldmVudCA9IHRoaXMud3JpdGVRdWV1ZS50YWtlKCk7CisgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgLy8gd2UgaWdub3JlIHRoaXMKKyAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICggdGhpcy5ydW5uaW5nICYmIGV2ZW50ICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgU2NoZWR1bGVJbmZvIHNjaGVkdWxlSW5mbyA9IG51bGw7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgc2NoZWR1bGVJbmZvID0gbmV3IFNjaGVkdWxlSW5mbyhldmVudCk7CisgICAgICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihpYWUuZ2V0TWVzc2FnZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKCBzY2hlZHVsZUluZm8gIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgRXZlbnRJbmZvIGluZm8gPSBuZXcgRXZlbnRJbmZvKCk7CisgICAgICAgICAgICAgICAgICAgIGluZm8uZXZlbnQgPSBldmVudDsKKworICAgICAgICAgICAgICAgICAgICAvLyB3cml0ZSBldmVudCBhbmQgdXBkYXRlIHBhdGgKKyAgICAgICAgICAgICAgICAgICAgLy8gaWYgc29tZXRoaW5nIHdlbnQgd3Jvbmcgd2UgZ2V0IHRoZSBub2RlIHBhdGggYW5kIHJlc2NoZWR1bGUKKyAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICggdGhpcy53cml0ZUxvY2sgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLm5vZGVQYXRoID0gdGhpcy5wZXJzaXN0RXZlbnQoaW5mby5ldmVudCwgc2NoZWR1bGVJbmZvKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBpZiAoIGluZm8ubm9kZVBhdGggIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5xdWV1ZS5wdXQoaW5mbyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLCBzbyB3ZSBpZ25vcmUgaXQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5pbXBsLkFic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlciNydW5JbkJhY2tncm91bmQoKQorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIHJ1bkluQmFja2dyb3VuZCgpIHsKKyAgICAgICAgd2hpbGUgKCB0aGlzLnJ1bm5pbmcgKSB7CisgICAgICAgICAgICAvLyBzbyBsZXQncyB3YWl0L2dldCB0aGUgbmV4dCBpbmZvIGZyb20gdGhlIHF1ZXVlCisgICAgICAgICAgICBFdmVudEluZm8gaW5mbyA9IG51bGw7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIGluZm8gPSB0aGlzLnF1ZXVlLnRha2UoKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhpcworICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCBpbmZvICE9IG51bGwgJiYgdGhpcy5ydW5uaW5nICkgeworICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAoIHRoaXMud3JpdGVMb2NrICkgeworICAgICAgICAgICAgICAgICAgICBTY2hlZHVsZUluZm8gc2NoZWR1bGVJbmZvID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVkdWxlSW5mbyA9IG5ldyBTY2hlZHVsZUluZm8oaW5mby5ldmVudCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKGlhZS5nZXRNZXNzYWdlKCkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmICggc2NoZWR1bGVJbmZvICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud3JpdGVyU2Vzc2lvbi5yZWZyZXNoKHRydWUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggdGhpcy53cml0ZXJTZXNzaW9uLml0ZW1FeGlzdHMoaW5mby5ub2RlUGF0aCkgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgZXZlbnROb2RlID0gKE5vZGUpIHRoaXMud3JpdGVyU2Vzc2lvbi5nZXRJdGVtKGluZm8ubm9kZVBhdGgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoICFldmVudE5vZGUuaXNMb2NrZWQoKSApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvY2sgbm9kZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9jayBsb2NrID0gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jayA9IGV2ZW50Tm9kZS5sb2NrKGZhbHNlLCB0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsb2NrIGZhaWxlZCB3aGljaCBtZWFucyB0aGF0IHRoZSBub2RlIGlzIGxvY2tlZCBieSBzb21lb25lIGVsc2UsIHNvIHdlIGRvbid0IGhhdmUgdG8gcmVxdWV1ZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBsb2NrICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgc29tZXRoaW5nIHdlbnQgd3JvbmcsIHdlIHJlc2NoZWR1bGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoICF0aGlzLnByb2Nlc3NFdmVudChpbmZvLmV2ZW50LCBzY2hlZHVsZUluZm8pICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5xdWV1ZS5wdXQoaW5mbyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiwgc28gd2UgaWdub3JlIGl0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgcHJvdGVjdGVkIFN0cmluZyBwZXJzaXN0RXZlbnQoZmluYWwgRXZlbnQgZXZlbnQsIGZpbmFsIFNjaGVkdWxlSW5mbyBzY2hlZHVsZUluZm8pIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIC8vIGdldCBwYXJlbnQgbm9kZQorICAgICAgICAgICAgZmluYWwgTm9kZSBwYXJlbnROb2RlID0gdGhpcy5lbnN1cmVSZXBvc2l0b3J5UGF0aCgpOworICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5vZGVOYW1lID0gc2NoZWR1bGVJbmZvLmpvYklkOworICAgICAgICAgICAgLy8gaXMgdGhlcmUgYWxyZWFkeSBhIG5vZGU/CisgICAgICAgICAgICBmaW5hbCBOb2RlIGZvdW5kTm9kZSA9IHBhcmVudE5vZGUuaGFzTm9kZShub2RlTmFtZSkgPyBwYXJlbnROb2RlLmdldE5vZGUobm9kZU5hbWUpIDogbnVsbDsKKyAgICAgICAgICAgIExvY2sgbG9jayA9IG51bGw7CisgICAgICAgICAgICBpZiAoIHNjaGVkdWxlSW5mby5pc1N0b3BFdmVudCgpICkgeworICAgICAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYSBzdG9wIGV2ZW50LCB3ZSBzaG91bGQgcmVtb3ZlIHRoZSBub2RlIGZyb20gdGhlIHJlcG9zaXRvcnkKKyAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyBub2RlIHNvbWVvbmUgZWxzZSB3YXMgZmFzdGVyIGFuZCB3ZSBjYW4gaWdub3JlIHRoaXMKKyAgICAgICAgICAgICAgICBpZiAoIGZvdW5kTm9kZSAhPSBudWxsICkgeworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgZm91bmROb2RlLnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5zYXZlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKExvY2tFeGNlcHRpb24gbGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHNvbWVvbmUgZWxzZSBoYXMgdGhlIGxvY2sgdGhpcyBpcyBmaW5lCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLy8gc3RvcCB0aGUgc2NoZWR1bGVyCisgICAgICAgICAgICAgICAgcHJvY2Vzc0V2ZW50KGV2ZW50LCBzY2hlZHVsZUluZm8pOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbHJlYWR5IGEgbm9kZSwgaXQgbWVhbnMgd2UgbXVzdCBoYW5kbGUgYW4gdXBkYXRlCisgICAgICAgICAgICAgICAgaWYgKCBmb3VuZE5vZGUgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kTm9kZS5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUuc2F2ZSgpOworICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChMb2NrRXhjZXB0aW9uIGxlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBzb21lb25lIGVsc2UgaGFzIHRoZSBsb2NrIHRoaXMgaXMgZmluZQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBhIHN0b3AgZXZlbnQKKyAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0V2ZW50KGV2ZW50LCBzY2hlZHVsZUluZm8uZ2V0U3RvcEluZm8oKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8vIHdlIG9ubHkgd3JpdGUgdGhlIGV2ZW50IGlmIHRoaXMgaXMgYSBsb2NhbCBvbmUKKyAgICAgICAgICAgICAgICBpZiAoIEV2ZW50VXRpbC5pc0xvY2FsKGV2ZW50KSApIHsKKworICAgICAgICAgICAgICAgICAgICAvLyB3cml0ZSBldmVudCB0byByZXBvc2l0b3J5LCBsb2NrIGl0IGFuZCBzY2hlZHVsZSB0aGUgZXZlbnQKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBldmVudE5vZGUgPSB3cml0ZUV2ZW50KGV2ZW50LCBub2RlTmFtZSk7CisgICAgICAgICAgICAgICAgICAgIGxvY2sgPSBldmVudE5vZGUubG9jayhmYWxzZSwgdHJ1ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoIGxvY2sgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAvLyBpZiBzb21ldGhpbmcgd2VudCB3cm9uZywgd2UgcmVzY2hlZHVsZQorICAgICAgICAgICAgICAgIGlmICggIXRoaXMucHJvY2Vzc0V2ZW50KGV2ZW50LCBzY2hlZHVsZUluZm8pICkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcGF0aCA9IGxvY2suZ2V0Tm9kZSgpLmdldFBhdGgoKTsKKyAgICAgICAgICAgICAgICAgICAgbG9jay5nZXROb2RlKCkudW5sb2NrKCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXRoOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSApIHsKKyAgICAgICAgICAgIC8vIHNvbWV0aGluZyB3ZW50IHdyb25nLCBzbyBsZXQncyBsb2cgaXQKKyAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCJFeGNlcHRpb24gZHVyaW5nIHdyaXRpbmcgbmV3IGpvYiB0byByZXBvc2l0b3J5LiIsIHJlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBQcm9jZXNzIHRoZSBldmVudC4KKyAgICAgKiBJZiBhIHNjaGVkdWxlciBpcyBhdmFpbGFibGUsIGEgam9iIGlzIHNjaGVkdWxlZCBvciBzdG9wcGVkLgorICAgICAqIEBwYXJhbSBldmVudCBUaGUgaW5jb21taW5nIGV2ZW50LgorICAgICAqIEByZXR1cm4KKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgYm9vbGVhbiBwcm9jZXNzRXZlbnQoZmluYWwgRXZlbnQgZXZlbnQsIGZpbmFsIFNjaGVkdWxlSW5mbyBzY2hlZHVsZUluZm8pIHsKKyAgICAgICAgZmluYWwgU2NoZWR1bGVyIGxvY2FsU2NoZWR1bGVyID0gdGhpcy5zY2hlZHVsZXI7CisgICAgICAgIGlmICggbG9jYWxTY2hlZHVsZXIgIT0gbnVsbCApIHsKKyAgICAgICAgICAgIC8vIGlzIHRoaXMgYSBzdG9wIGV2ZW50PworICAgICAgICAgICAgaWYgKCBzY2hlZHVsZUluZm8uaXNTdG9wRXZlbnQoKSApIHsKKyAgICAgICAgICAgICAgICBpZiAoIHRoaXMubG9nZ2VyLmlzRGVidWdFbmFibGVkKCkgKSB7CisgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKCJTdG9wcGluZyB0aW1lZCBldmVudCAiICsgZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX1RJTUVEX0VWRU5UX1RPUElDKSArICIoIiArIHNjaGVkdWxlSW5mby5qb2JJZCArICIpIik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGxvY2FsU2NoZWR1bGVyLnJlbW92ZUpvYihzY2hlZHVsZUluZm8uam9iSWQpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24gbnNlZSkgeworICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGNhbiBoYXBwZW4gaWYgdGhlIGpvYiBpcyBzY2hlZHVsZWQgb24gYW5vdGhlciBub2RlCisgICAgICAgICAgICAgICAgICAgIC8vIHNvIHdlIGNhbiBqdXN0IGlnbm9yZSB0aGlzCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gd2UgaWdub3JlIHJlbW90ZSBqb2IgZXZlbnRzCisgICAgICAgICAgICBpZiAoICFFdmVudFV0aWwuaXNMb2NhbChldmVudCkgKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8vIENyZWF0ZSBjb25maWd1cmF0aW9uIGZvciBzY2hlZHVsZWQgam9iCisgICAgICAgICAgICBmaW5hbCBNYXA8U3RyaW5nLCBTZXJpYWxpemFibGU+IGNvbmZpZyA9IG5ldyBIYXNoTWFwPFN0cmluZywgU2VyaWFsaXphYmxlPigpOworICAgICAgICAgICAgLy8gY29weSBwcm9wZXJ0aWVzCisgICAgICAgICAgICBmaW5hbCBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+IHByb3BlcnRpZXMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOworICAgICAgICAgICAgY29uZmlnLnB1dChKT0JfVE9QSUMsIChTdHJpbmcpZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX1RJTUVEX0VWRU5UX1RPUElDKSk7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmdbXSBuYW1lcyA9IGV2ZW50LmdldFByb3BlcnR5TmFtZXMoKTsKKyAgICAgICAgICAgIGlmICggbmFtZXMgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICBmb3IoaW50IGk9MDsgaTxuYW1lcy5sZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzLnB1dChuYW1lc1tpXSwgZXZlbnQuZ2V0UHJvcGVydHkobmFtZXNbaV0pKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb25maWcucHV0KEpPQl9DT05GSUcsIHByb3BlcnRpZXMpOworICAgICAgICAgICAgY29uZmlnLnB1dChKT0JfU0NIRURVTEVfSU5GTywgc2NoZWR1bGVJbmZvKTsKKworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBpZiAoIHNjaGVkdWxlSW5mby5leHByZXNzaW9uICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICggdGhpcy5sb2dnZXIuaXNEZWJ1Z0VuYWJsZWQoKSApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKCJBZGRpbmcgdGltZWQgZXZlbnQgIiArIGNvbmZpZy5nZXQoSk9CX1RPUElDKSArICIoIiArIHNjaGVkdWxlSW5mby5qb2JJZCArICIpIiArICIgd2l0aCBjcm9uIGV4cHJlc3Npb24gIiArIHNjaGVkdWxlSW5mby5leHByZXNzaW9uKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBsb2NhbFNjaGVkdWxlci5hZGRKb2Ioc2NoZWR1bGVJbmZvLmpvYklkLCB0aGlzLCBjb25maWcsIHNjaGVkdWxlSW5mby5leHByZXNzaW9uLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmICggc2NoZWR1bGVJbmZvLnBlcmlvZCAhPSBudWxsICkgeworICAgICAgICAgICAgICAgICAgICBpZiAoIHRoaXMubG9nZ2VyLmlzRGVidWdFbmFibGVkKCkgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZygiQWRkaW5nIHRpbWVkIGV2ZW50ICIgKyBjb25maWcuZ2V0KEpPQl9UT1BJQykgKyAiKCIgKyBzY2hlZHVsZUluZm8uam9iSWQgKyAiKSIgKyAiIHdpdGggcGVyaW9kICIgKyBzY2hlZHVsZUluZm8ucGVyaW9kKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBsb2NhbFNjaGVkdWxlci5hZGRQZXJpb2RpY0pvYihzY2hlZHVsZUluZm8uam9iSWQsIHRoaXMsIGNvbmZpZywgc2NoZWR1bGVJbmZvLnBlcmlvZCwgZmFsc2UpOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHRoZW4gaXQgbXVzdCBiZSBkYXRlCisgICAgICAgICAgICAgICAgICAgIGlmICggdGhpcy5sb2dnZXIuaXNEZWJ1Z0VuYWJsZWQoKSApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKCJBZGRpbmcgdGltZWQgZXZlbnQgIiArIGNvbmZpZy5nZXQoSk9CX1RPUElDKSArICIoIiArIHNjaGVkdWxlSW5mby5qb2JJZCArICIpIiArICIgd2l0aCBkYXRlICIgKyBzY2hlZHVsZUluZm8uZGF0ZSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgbG9jYWxTY2hlZHVsZXIuZmlyZUpvYkF0KHNjaGVkdWxlSW5mby5qb2JJZCwgdGhpcywgY29uZmlnLCBzY2hlZHVsZUluZm8uZGF0ZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCJObyBzY2hlZHVsZXIgYXZhaWxhYmxlIHRvIHN0YXJ0IHRpbWVkIGV2ZW50ICIgKyBldmVudCk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgamF2YXguamNyLm9ic2VydmF0aW9uLkV2ZW50TGlzdGVuZXIjb25FdmVudChqYXZheC5qY3Iub2JzZXJ2YXRpb24uRXZlbnRJdGVyYXRvcikKKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBvbkV2ZW50KEV2ZW50SXRlcmF0b3IgaXRlcikgeworICAgICAgICAvLyB3ZSBjcmVhdGUgYW4gb3duIHNlc3Npb24gaGVyZQorICAgICAgICBTZXNzaW9uIHMgPSBudWxsOworICAgICAgICB0cnkgeworICAgICAgICAgICAgcyA9IHRoaXMuY3JlYXRlU2Vzc2lvbigpOworICAgICAgICAgICAgd2hpbGUgKCBpdGVyLmhhc05leHQoKSApIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBqYXZheC5qY3Iub2JzZXJ2YXRpb24uRXZlbnQgZXZlbnQgPSBpdGVyLm5leHRFdmVudCgpOworICAgICAgICAgICAgICAgIGlmICggZXZlbnQuZ2V0VHlwZSgpID09IGphdmF4Lmpjci5vYnNlcnZhdGlvbi5FdmVudC5QUk9QRVJUWV9DSEFOR0VECisgICAgICAgICAgICAgICAgICAgIHx8IGV2ZW50LmdldFR5cGUoKSA9PSBqYXZheC5qY3Iub2JzZXJ2YXRpb24uRXZlbnQuUFJPUEVSVFlfUkVNT1ZFRCkgeworCisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBwcm9wUGF0aCA9IGV2ZW50LmdldFBhdGgoKTsKKyAgICAgICAgICAgICAgICAgICAgaW50IHBvcyA9IHByb3BQYXRoLmxhc3RJbmRleE9mKCcvJyk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBub2RlUGF0aCA9IHByb3BQYXRoLnN1YnN0cmluZygwLCBwb3MpOworICAgICAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcHJvcGVydHlOYW1lID0gcHJvcFBhdGguc3Vic3RyaW5nKHBvcysxKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gd2UgYXJlIG9ubHkgaW50ZXJlc3RlZCBpbiB1bmxvY2tzCisgICAgICAgICAgICAgICAgICAgIGlmICggImpjcjpsb2NrT3duZXIiLmVxdWFscyhwcm9wZXJ0eU5hbWUpICkgeworICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIGV2ZW50Tm9kZSA9IChOb2RlKSBzLmdldEl0ZW0obm9kZVBhdGgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIWV2ZW50Tm9kZS5pc0xvY2tlZCgpICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgRXZlbnRJbmZvIGluZm8gPSBuZXcgRXZlbnRJbmZvKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLmV2ZW50ID0gdGhpcy5yZWFkRXZlbnQoZXZlbnROb2RlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8ubm9kZVBhdGggPW5vZGVQYXRoOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnF1ZXVlLnB1dChpbmZvKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhpcyBleGNlcHRpb24gYXMgdGhpcyBzaG91bGQgbmV2ZXIgb2NjdXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBjbmZlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgaXQgdG8gdGhlIHVubG9hZGVkIHNldAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICh1bmxvYWRlZEV2ZW50cykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudW5sb2FkZWRFdmVudHMuYWRkKG5vZGVQYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKGNuZmUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCJFeGNlcHRpb24gZHVyaW5nIGpjciBldmVudCBwcm9jZXNzaW5nLiIsIHJlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoIlVuYWJsZSB0byBjcmVhdGUgYSBzZXNzaW9uLiIsIHJlKTsKKyAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgIGlmICggcyAhPSBudWxsICkgeworICAgICAgICAgICAgICAgIHMubG9nb3V0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuZXZlbnQuRXZlbnRIYW5kbGVyI2hhbmRsZUV2ZW50KG9yZy5vc2dpLnNlcnZpY2UuZXZlbnQuRXZlbnQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgaGFuZGxlRXZlbnQoRXZlbnQgZXZlbnQpIHsKKyAgICAgICAgaWYgKCBldmVudC5nZXRUb3BpYygpLmVxdWFscyhFdmVudFV0aWwuVE9QSUNfVElNRURfRVZFTlQpICkgeworICAgICAgICAgICAgLy8gcXVldWUgdGhlIGV2ZW50IGluIG9yZGVyIHRvIHJlc3BvbmQgcXVpY2tseQorICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICB0aGlzLndyaXRlUXVldWUucHV0KGV2ZW50KTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyB0aGlzIHNob3VsZCBuZXZlciBoYXBwZW4KKyAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8vIGJ1bmRsZSBldmVudCBzdGFydGVkIG9yIHVwZGF0ZWQKKyAgICAgICAgICAgIGJvb2xlYW4gZG9JdCA9IGZhbHNlOworICAgICAgICAgICAgc3luY2hyb25pemVkICggdGhpcy51bmxvYWRlZEV2ZW50cyApIHsKKyAgICAgICAgICAgICAgICBpZiAoIHRoaXMudW5sb2FkZWRFdmVudHMuc2l6ZSgpID4gMCApIHsKKyAgICAgICAgICAgICAgICAgICAgZG9JdCA9IHRydWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCBkb0l0ICkgeworICAgICAgICAgICAgICAgIGZpbmFsIFJ1bm5hYmxlIHQgPSBuZXcgUnVubmFibGUoKSB7CisKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgc3luY2hyb25pemVkICh1bmxvYWRlZEV2ZW50cykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlc3Npb24gcyA9IG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU2V0PFN0cmluZz4gbmV3VW5sb2FkZWRFdmVudHMgPSBuZXcgSGFzaFNldDxTdHJpbmc+KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3VW5sb2FkZWRFdmVudHMuYWRkQWxsKHVubG9hZGVkRXZlbnRzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gY3JlYXRlU2Vzc2lvbigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IoU3RyaW5nIHBhdGggOiB1bmxvYWRlZEV2ZW50cyApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1VubG9hZGVkRXZlbnRzLnJlbW92ZShwYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBzLml0ZW1FeGlzdHMocGF0aCkgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgZXZlbnROb2RlID0gKE5vZGUpIHMuZ2V0SXRlbShwYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAhZXZlbnROb2RlLmlzTG9ja2VkKCkgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsIEV2ZW50SW5mbyBpbmZvID0gbmV3IEV2ZW50SW5mbygpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8uZXZlbnQgPSByZWFkRXZlbnQoZXZlbnROb2RlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLm5vZGVQYXRoID0gcGF0aDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWV1ZS5wdXQoaW5mbyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhpcyBleGNlcHRpb24gYXMgdGhpcyBzaG91bGQgbmV2ZXIgb2NjdXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWdub3JlRXhjZXB0aW9uKGUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1VubG9hZGVkRXZlbnRzLmFkZChwYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVFeGNlcHRpb24oY25mZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgaWdub3JlIHRoaXMgYW5kIHJlYWRkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3VW5sb2FkZWRFdmVudHMuYWRkKHBhdGgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZUV4Y2VwdGlvbihyZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVuYWJsZSB0byBjcmVhdGUgc2Vzc2lvbiwgc28gd2UgdHJ5IGl0IGFnYWluIG5leHQgdGltZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZ25vcmVFeGNlcHRpb24ocmUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggcyAhPSBudWxsICkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5sb2dvdXQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxvYWRlZEV2ZW50cy5jbGVhcigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxvYWRlZEV2ZW50cy5hZGRBbGwobmV3VW5sb2FkZWRFdmVudHMpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgfTsKKyAgICAgICAgICAgICAgICB0aGlzLnRocmVhZFBvb2wuZXhlY3V0ZSh0KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5jb21tb25zLnNjaGVkdWxlci5Kb2IjZXhlY3V0ZShvcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMuc2NoZWR1bGVyLkpvYkNvbnRleHQpCisgICAgICovCisgICAgcHVibGljIHZvaWQgZXhlY3V0ZShKb2JDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIHRvcGljID0gKFN0cmluZykgY29udGV4dC5nZXRDb25maWd1cmF0aW9uKCkuZ2V0KEpPQl9UT1BJQyk7CisgICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgICAgICBmaW5hbCBEaWN0aW9uYXJ5PE9iamVjdCwgT2JqZWN0PiBwcm9wZXJ0aWVzID0gKERpY3Rpb25hcnk8T2JqZWN0LCBPYmplY3Q+KSBjb250ZXh0LmdldENvbmZpZ3VyYXRpb24oKS5nZXQoSk9CX0NPTkZJRyk7CisgICAgICAgIGZpbmFsIEV2ZW50QWRtaW4gZWEgPSB0aGlzLmV2ZW50QWRtaW47CisgICAgICAgIGlmICggZWEgIT0gbnVsbCApIHsKKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgZWEucG9zdEV2ZW50KG5ldyBFdmVudCh0b3BpYywgcHJvcGVydGllcykpOworICAgICAgICAgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgeworICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCJTY2hlZHVsZWQgZXZlbnQgaGFzIGlsbGVnYWwgdG9waWM6ICIgKyB0b3BpYywgaWFlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHRoaXMubG9nZ2VyLndhcm4oIlVuYWJsZSB0byBzZW5kIHRpbWVkIGV2ZW50IGFzIG5vIGV2ZW50IGFkbWluIHNlcnZpY2UgaXMgYXZhaWxhYmxlLiIpOworICAgICAgICB9CisgICAgICAgIGZpbmFsIFNjaGVkdWxlSW5mbyBpbmZvID0gKFNjaGVkdWxlSW5mbykgY29udGV4dC5nZXRDb25maWd1cmF0aW9uKCkuZ2V0KEpPQl9TQ0hFRFVMRV9JTkZPKTsKKyAgICAgICAgLy8gaXMgdGhpcyBqb2Igc2NoZWR1bGVkIGZvciBhIHNwZWNpZmljIGRhdGU/CisgICAgICAgIGlmICggaW5mby5kYXRlICE9IG51bGwgKSB7CisgICAgICAgICAgICAvLyB3ZSBjYW4gcmVtb3ZlIGl0IGZyb20gdGhlIHJlcG9zaXRvcnkKKyAgICAgICAgICAgIC8vIHdlIGNyZWF0ZSBhbiBvd24gc2Vzc2lvbiBoZXJlCisgICAgICAgICAgICBTZXNzaW9uIHMgPSBudWxsOworICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBzID0gdGhpcy5jcmVhdGVTZXNzaW9uKCk7CisgICAgICAgICAgICAgICAgaWYgKCBzLml0ZW1FeGlzdHModGhpcy5yZXBvc2l0b3J5UGF0aCkgKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgcGFyZW50Tm9kZSA9IChOb2RlKXMuZ2V0SXRlbSh0aGlzLnJlcG9zaXRvcnlQYXRoKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIG5vZGVOYW1lID0gaW5mby5qb2JJZDsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBldmVudE5vZGUgPSBwYXJlbnROb2RlLmhhc05vZGUobm9kZU5hbWUpID8gcGFyZW50Tm9kZS5nZXROb2RlKG5vZGVOYW1lKSA6IG51bGw7CisgICAgICAgICAgICAgICAgICAgIGlmICggZXZlbnROb2RlICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Tm9kZS5yZW1vdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlLnNhdmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBpZ25vcmUgdGhlIGV4Y2VwdGlvbiBpZiByZW1vdmluZyBmYWlscworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZUV4Y2VwdGlvbihyZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIHJlKSB7CisgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoIlVuYWJsZSB0byBjcmVhdGUgYSBzZXNzaW9uLiIsIHJlKTsKKyAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgaWYgKCBzICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgIHMubG9nb3V0KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogTG9hZCBhbGwgYWN0aXZlIHRpbWVkIGV2ZW50cyBmcm9tIHRoZSByZXBvc2l0b3J5LgorICAgICAqIEB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbgorICAgICAqLworICAgIHByb3RlY3RlZCB2b2lkIGxvYWRFdmVudHMoKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBmaW5hbCBRdWVyeU1hbmFnZXIgcU1hbmFnZXIgPSB0aGlzLndyaXRlclNlc3Npb24uZ2V0V29ya3NwYWNlKCkuZ2V0UXVlcnlNYW5hZ2VyKCk7CisgICAgICAgICAgICBmaW5hbCBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigiL2pjcjpyb290Iik7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHRoaXMucmVwb3NpdG9yeVBhdGgpOworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiLy9lbGVtZW50KCosICIpOworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCh0aGlzLmdldEV2ZW50Tm9kZVR5cGUoKSk7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIpIik7CisgICAgICAgICAgICBmaW5hbCBRdWVyeSBxID0gcU1hbmFnZXIuY3JlYXRlUXVlcnkoYnVmZmVyLnRvU3RyaW5nKCksIFF1ZXJ5LlhQQVRIKTsKKyAgICAgICAgICAgIGZpbmFsIE5vZGVJdGVyYXRvciByZXN1bHQgPSBxLmV4ZWN1dGUoKS5nZXROb2RlcygpOworICAgICAgICAgICAgd2hpbGUgKCByZXN1bHQuaGFzTmV4dCgpICkgeworICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgZXZlbnROb2RlID0gcmVzdWx0Lm5leHROb2RlKCk7CisgICAgICAgICAgICAgICAgaWYgKCAhZXZlbnROb2RlLmlzTG9ja2VkKCkgKSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsIFN0cmluZyBub2RlUGF0aCA9IGV2ZW50Tm9kZS5nZXRQYXRoKCk7CisgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBFdmVudCBldmVudCA9IHRoaXMucmVhZEV2ZW50KGV2ZW50Tm9kZSk7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBFdmVudEluZm8gaW5mbyA9IG5ldyBFdmVudEluZm8oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGluZm8uZXZlbnQgPSBldmVudDsKKyAgICAgICAgICAgICAgICAgICAgICAgIGluZm8ubm9kZVBhdGggPSBub2RlUGF0aDsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5xdWV1ZS5wdXQoaW5mbyk7CisgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgaWdub3JlIHRoaXMgZXhjZXB0aW9uIGFzIHRoaXMgc2hvdWxkIG5ldmVyIG9jY3VyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pZ25vcmVFeGNlcHRpb24oZSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSB1bmxvYWRlZCBzZXQKKyAgICAgICAgICAgICAgICAgICAgICAgIHN5bmNocm9uaXplZCAodW5sb2FkZWRFdmVudHMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVubG9hZGVkRXZlbnRzLmFkZChub2RlUGF0aCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlnbm9yZUV4Y2VwdGlvbihjbmZlKTsKKyAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgcmVhZGluZyBhbiBldmVudCBmYWlscywgd2UgaWdub3JlIHRoaXMKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlRXhjZXB0aW9uKHJlKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoIkV4Y2VwdGlvbiBkdXJpbmcgaW5pdGlhbCBsb2FkaW5nIG9mIHN0b3JlZCB0aW1lZCBldmVudHMuIiwgcmUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmVuZ2luZS5ldmVudC5pbXBsLkpvYlBlcnNpc3RlbmNlSGFuZGxlciNhZGROb2RlUHJvcGVydGllcyhqYXZheC5qY3IuTm9kZSwgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudCkKKyAgICAgKi8KKyAgICBwcm90ZWN0ZWQgdm9pZCBhZGROb2RlUHJvcGVydGllcyhOb2RlIGV2ZW50Tm9kZSwgRXZlbnQgZXZlbnQpCisgICAgdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24geworICAgICAgICBzdXBlci5hZGROb2RlUHJvcGVydGllcyhldmVudE5vZGUsIGV2ZW50KTsKKyAgICAgICAgZXZlbnROb2RlLnNldFByb3BlcnR5KEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfVE9QSUMsIChTdHJpbmcpZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX1RJTUVEX0VWRU5UX1RPUElDKSk7CisgICAgICAgIGZpbmFsIFNjaGVkdWxlSW5mbyBpbmZvID0gbmV3IFNjaGVkdWxlSW5mbyhldmVudCk7CisgICAgICAgIGlmICggaW5mby5kYXRlICE9IG51bGwgKSB7CisgICAgICAgICAgICBmaW5hbCBDYWxlbmRhciBjID0gQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKTsKKyAgICAgICAgICAgIGMuc2V0VGltZShpbmZvLmRhdGUpOworICAgICAgICAgICAgZXZlbnROb2RlLnNldFByb3BlcnR5KEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfVEVfREFURSwgYyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCBpbmZvLmV4cHJlc3Npb24gIT0gbnVsbCApIHsKKyAgICAgICAgICAgIGV2ZW50Tm9kZS5zZXRQcm9wZXJ0eShFdmVudEhlbHBlci5OT0RFX1BST1BFUlRZX1RFX0VYUFJFU1NJT04sIGluZm8uZXhwcmVzc2lvbik7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCBpbmZvLnBlcmlvZCAhPSBudWxsICkgeworICAgICAgICAgICAgZXZlbnROb2RlLnNldFByb3BlcnR5KEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfVEVfUEVSSU9ELCBpbmZvLnBlcmlvZC5sb25nVmFsdWUoKSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAc2VlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbC5BYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXIjZ2V0RXZlbnROb2RlVHlwZSgpCisgICAgICovCisgICAgcHJvdGVjdGVkIFN0cmluZyBnZXRFdmVudE5vZGVUeXBlKCkgeworICAgICAgICByZXR1cm4gRXZlbnRIZWxwZXIuVElNRURfRVZFTlRfTk9ERV9UWVBFOworICAgIH0KKworICAgIHByb3RlY3RlZCBzdGF0aWMgZmluYWwgY2xhc3MgU2NoZWR1bGVJbmZvIGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKKworICAgICAgICBwdWJsaWMgZmluYWwgU3RyaW5nIGV4cHJlc3Npb247CisgICAgICAgIHB1YmxpYyBmaW5hbCBMb25nICAgcGVyaW9kOworICAgICAgICBwdWJsaWMgZmluYWwgRGF0ZSAgIGRhdGU7CisgICAgICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgam9iSWQ7CisKKyAgICAgICAgcHVibGljIFNjaGVkdWxlSW5mbyhmaW5hbCBFdmVudCBldmVudCkKKyAgICAgICAgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7CisgICAgICAgICAgICAvLyBsZXQncyBzZWUgaWYgYSBzY2hlZHVsZSBpbmZvcm1hdGlvbiBpcyBzcGVjaWZpZWQgb3IgaWYgdGhlIGpvYiBzaG91bGQgYmUgc3RvcHBlZAorICAgICAgICAgICAgdGhpcy5leHByZXNzaW9uID0gKFN0cmluZykgZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX1RJTUVEX0VWRU5UX1NDSEVEVUxFKTsKKyAgICAgICAgICAgIHRoaXMucGVyaW9kID0gKExvbmcpIGV2ZW50LmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9USU1FRF9FVkVOVF9QRVJJT0QpOworICAgICAgICAgICAgdGhpcy5kYXRlID0gKERhdGUpIGV2ZW50LmdldFByb3BlcnR5KEV2ZW50VXRpbC5QUk9QRVJUWV9USU1FRF9FVkVOVF9EQVRFKTsKKyAgICAgICAgICAgIGludCBjb3VudCA9IDA7CisgICAgICAgICAgICBpZiAoIHRoaXMuZXhwcmVzc2lvbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICggdGhpcy5wZXJpb2QgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCB0aGlzLmRhdGUgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCBjb3VudCA+IDEgKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiT25seSBvbmUgY29uZmlndXJhdGlvbiBwcm9wZXJ0eSBmcm9tICIgKyBFdmVudFV0aWwuUFJPUEVSVFlfVElNRURfRVZFTlRfU0NIRURVTEUgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCAiICsgRXZlbnRVdGlsLlBST1BFUlRZX1RJTUVEX0VWRU5UX1BFUklPRCArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIsIG9yICIgKyBFdmVudFV0aWwuUFJPUEVSVFlfVElNRURfRVZFTlRfREFURSArICIgc2hvdWxkIGJlIHVzZWQuIik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvLyB3ZSBjcmVhdGUgYSBqb2IgaWQgY29uc2lzdGluZyBvZiB0aGUgcmVhbCBldmVudCB0b3BpYyBhbmQgYW4gKG9wdGlvbmFsKSBpZAorICAgICAgICAgICAgLy8gaWYgdGhlIGV2ZW50IGNvbnRhaW5zIGEgdGltZWQgZXZlbnQgaWQgb3IgYSBqb2IgaWQgd2UnbGwgYXBwZW5kIHRoYXQgdG8gdGhlIG5hbWUKKyAgICAgICAgICAgIFN0cmluZyB0b3BpYyA9IChTdHJpbmcpZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX1RJTUVEX0VWRU5UX1RPUElDKTsKKyAgICAgICAgICAgIGlmICggdG9waWMgPT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJUaW1lZCBldmVudCBkb2VzIG5vdCBjb250YWluIHJlcXVpcmVkIHByb3BlcnR5ICIgKyBFdmVudFV0aWwuUFJPUEVSVFlfVElNRURfRVZFTlRfVE9QSUMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgU3RyaW5nIGlkID0gKFN0cmluZylldmVudC5nZXRQcm9wZXJ0eShFdmVudFV0aWwuUFJPUEVSVFlfVElNRURfRVZFTlRfSUQpOworICAgICAgICAgICAgU3RyaW5nIGpJZCA9IChTdHJpbmcpZXZlbnQuZ2V0UHJvcGVydHkoRXZlbnRVdGlsLlBST1BFUlRZX0pPQl9JRCk7CisKKyAgICAgICAgICAgIC8vdGhpcy5qb2JJZCA9IGdldEpvYklkKHRvcGljLCBpZCwgaklkKTsKKyAgICAgICAgICAgIHRoaXMuam9iSWQgPSBnZXRKb2JJZCh0b3BpYywgaWQsIGpJZCk7CisgICAgICAgIH0KKworICAgICAgICBwcml2YXRlIFNjaGVkdWxlSW5mbyhTdHJpbmcgam9iSWQpIHsKKyAgICAgICAgICAgIHRoaXMuZXhwcmVzc2lvbiA9IG51bGw7CisgICAgICAgICAgICB0aGlzLnBlcmlvZCA9IG51bGw7CisgICAgICAgICAgICB0aGlzLmRhdGUgPSBudWxsOworICAgICAgICAgICAgdGhpcy5qb2JJZCA9IGpvYklkOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIFNjaGVkdWxlSW5mbyBnZXRTdG9wSW5mbygpIHsKKyAgICAgICAgICAgIHJldHVybiBuZXcgU2NoZWR1bGVJbmZvKHRoaXMuam9iSWQpOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIGJvb2xlYW4gaXNTdG9wRXZlbnQoKSB7CisgICAgICAgICAgICByZXR1cm4gdGhpcy5leHByZXNzaW9uID09IG51bGwgJiYgdGhpcy5wZXJpb2QgPT0gbnVsbCAmJiB0aGlzLmRhdGUgPT0gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEpvYklkKFN0cmluZyB0b3BpYywgU3RyaW5nIHRpbWVkRXZlbnRJZCwgU3RyaW5nIGpvYklkKSB7CisgICAgICAgICAgICByZXR1cm4gdG9waWMucmVwbGFjZSgnLycsICcuJykgKyAiL1RpbWVkRXZlbnQgIiArICh0aW1lZEV2ZW50SWQgIT0gbnVsbCA/IEV2ZW50SGVscGVyLmZpbHRlcih0aW1lZEV2ZW50SWQpIDogIiIpICsgJ18nICsgKGpvYklkICE9IG51bGwgPyBFdmVudEhlbHBlci5maWx0ZXIoam9iSWQpIDogIiIpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LlRpbWVkRXZlbnRTdGF0dXNQcm92aWRlciNnZXRTY2hlZHVsZWRFdmVudChqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nKQorICAgICAqLworICAgIHB1YmxpYyBFdmVudCBnZXRTY2hlZHVsZWRFdmVudChTdHJpbmcgdG9waWMsIFN0cmluZyBldmVudElkLCBTdHJpbmcgam9iSWQpIHsKKyAgICAgICAgU2Vzc2lvbiBzID0gbnVsbDsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIHMgPSB0aGlzLmNyZWF0ZVNlc3Npb24oKTsKKyAgICAgICAgICAgIGlmICggcy5pdGVtRXhpc3RzKHRoaXMucmVwb3NpdG9yeVBhdGgpICkgeworICAgICAgICAgICAgICAgIGZpbmFsIE5vZGUgcGFyZW50Tm9kZSA9IChOb2RlKXMuZ2V0SXRlbSh0aGlzLnJlcG9zaXRvcnlQYXRoKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBTdHJpbmcgbm9kZU5hbWUgPSBTY2hlZHVsZUluZm8uZ2V0Sm9iSWQodG9waWMsIGV2ZW50SWQsIGpvYklkKTsKKyAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIGV2ZW50Tm9kZSA9IHBhcmVudE5vZGUuaGFzTm9kZShub2RlTmFtZSkgPyBwYXJlbnROb2RlLmdldE5vZGUobm9kZU5hbWUpIDogbnVsbDsKKyAgICAgICAgICAgICAgICBpZiAoIGV2ZW50Tm9kZSAhPSBudWxsICkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZWFkRXZlbnQoZXZlbnROb2RlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0gY2F0Y2ggKFJlcG9zaXRvcnlFeGNlcHRpb24gcmUpIHsKKyAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCJVbmFibGUgdG8gY3JlYXRlIGEgc2Vzc2lvbi4iLCByZSk7CisgICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgdGhpcy5pZ25vcmVFeGNlcHRpb24oZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoIHMgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICBzLmxvZ291dCgpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHJldHVybiBudWxsOworICAgIH0KKworICAgIC8qKgorICAgICAqIEBzZWUgb3JnLmFwYWNoZS5zbGluZy5ldmVudC5UaW1lZEV2ZW50U3RhdHVzUHJvdmlkZXIjZ2V0U2NoZWR1bGVkRXZlbnRzKGphdmEubGFuZy5TdHJpbmcsIGphdmEudXRpbC5NYXAuLi4pCisgICAgICovCisgICAgcHVibGljIENvbGxlY3Rpb248RXZlbnQ+IGdldFNjaGVkdWxlZEV2ZW50cyhTdHJpbmcgdG9waWMsIE1hcDxTdHJpbmcsIE9iamVjdD4uLi4gZmlsdGVyUHJvcHMpIHsKKyAgICAgICAgLy8gd2UgY3JlYXRlIGEgbmV3IHNlc3Npb24KKyAgICAgICAgU2Vzc2lvbiBzID0gbnVsbDsKKyAgICAgICAgZmluYWwgTGlzdDxFdmVudD4gam9icyA9IG5ldyBBcnJheUxpc3Q8RXZlbnQ+KCk7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgICBzID0gdGhpcy5jcmVhdGVTZXNzaW9uKCk7CisgICAgICAgICAgICBmaW5hbCBRdWVyeU1hbmFnZXIgcU1hbmFnZXIgPSBzLmdldFdvcmtzcGFjZSgpLmdldFF1ZXJ5TWFuYWdlcigpOworICAgICAgICAgICAgZmluYWwgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoIi9qY3I6cm9vdCIpOworICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCh0aGlzLnJlcG9zaXRvcnlQYXRoKTsKKyAgICAgICAgICAgIGlmICggdG9waWMgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCcvJyk7CisgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCh0b3BpYy5yZXBsYWNlKCcvJywgJy4nKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIvL2VsZW1lbnQoKiwgIik7CisgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHRoaXMuZ2V0RXZlbnROb2RlVHlwZSgpKTsKKyAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIikiKTsKKyAgICAgICAgICAgIGlmICggZmlsdGVyUHJvcHMgIT0gbnVsbCAmJiBmaWx0ZXJQcm9wcy5sZW5ndGggPiAwICkgeworICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIiBbIik7CisgICAgICAgICAgICAgICAgaW50IGluZGV4ID0gMDsKKyAgICAgICAgICAgICAgICBmb3IgKE1hcDxTdHJpbmcsT2JqZWN0PiB0ZW1wbGF0ZSA6IGZpbHRlclByb3BzKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICggaW5kZXggPiAwICkgeworICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiIG9yICIpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoJygnKTsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgSXRlcmF0b3I8TWFwLkVudHJ5PFN0cmluZywgT2JqZWN0Pj4gaSA9IHRlbXBsYXRlLmVudHJ5U2V0KCkuaXRlcmF0b3IoKTsKKyAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBmaXJzdCA9IHRydWU7CisgICAgICAgICAgICAgICAgICAgIHdoaWxlICggaS5oYXNOZXh0KCkgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBNYXAuRW50cnk8U3RyaW5nLCBPYmplY3Q+IGN1cnJlbnQgPSBpLm5leHQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIHByb3AgbmFtZSBmaXJzdAorICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgU3RyaW5nIHByb3BOYW1lID0gRXZlbnRVdGlsLmdldE5vZGVQcm9wZXJ0eU5hbWUoY3VycmVudC5nZXRLZXkoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHByb3BOYW1lICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgdmFsdWUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBWYWx1ZSB2YWx1ZSA9IEV2ZW50VXRpbC5nZXROb2RlUHJvcGVydHlWYWx1ZShzLmdldFZhbHVlRmFjdG9yeSgpLCBjdXJyZW50LmdldFZhbHVlKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggdmFsdWUgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBmaXJzdCApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCdAJyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCIgYW5kIEAiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKHByb3BOYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgiID0gJyIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGN1cnJlbnQuZ2V0VmFsdWUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIiciKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZCgnKScpOworICAgICAgICAgICAgICAgICAgICBpbmRleCsrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKCddJyk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmaW5hbCBTdHJpbmcgcXVlcnlTdHJpbmcgPSBidWZmZXIudG9TdHJpbmcoKTsKKyAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygiRXhlY3V0aW5nIGpvYiBxdWVyeSB7fS4iLCBxdWVyeVN0cmluZyk7CisKKyAgICAgICAgICAgIGZpbmFsIFF1ZXJ5IHEgPSBxTWFuYWdlci5jcmVhdGVRdWVyeShxdWVyeVN0cmluZywgUXVlcnkuWFBBVEgpOworICAgICAgICAgICAgZmluYWwgTm9kZUl0ZXJhdG9yIGl0ZXIgPSBxLmV4ZWN1dGUoKS5nZXROb2RlcygpOworICAgICAgICAgICAgd2hpbGUgKCBpdGVyLmhhc05leHQoKSApIHsKKyAgICAgICAgICAgICAgICBmaW5hbCBOb2RlIGV2ZW50Tm9kZSA9IGl0ZXIubmV4dE5vZGUoKTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICBmaW5hbCBFdmVudCBldmVudCA9IHRoaXMucmVhZEV2ZW50KGV2ZW50Tm9kZSk7CisgICAgICAgICAgICAgICAgICAgIGpvYnMuYWRkKGV2ZW50KTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGNuZmUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gaW4gdGhlIGNhc2Ugb2YgYSBjbGFzcyBub3QgZm91bmQgZXhjZXB0aW9uIHdlIGp1c3QgaWdub3JlIHRoZSBleGNlcHRpb24KKyAgICAgICAgICAgICAgICAgICAgdGhpcy5pZ25vcmVFeGNlcHRpb24oY25mZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGNhdGNoIChSZXBvc2l0b3J5RXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIC8vIGluIHRoZSBjYXNlIG9mIGFuIGVycm9yLCB3ZSByZXR1cm4gYW4gZW1wdHkgbGlzdAorICAgICAgICAgICAgdGhpcy5pZ25vcmVFeGNlcHRpb24oZSk7CisgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICBpZiAoIHMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIHMubG9nb3V0KCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIGpvYnM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQHNlZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LlRpbWVkRXZlbnRTdGF0dXNQcm92aWRlciNjYW5jZWxUaW1lZEV2ZW50KGphdmEubGFuZy5TdHJpbmcpCisgICAgICovCisgICAgcHVibGljIHZvaWQgY2FuY2VsVGltZWRFdmVudChTdHJpbmcgam9iSWQpIHsKKyAgICAgICAgc3luY2hyb25pemVkICggdGhpcy53cml0ZUxvY2sgKSB7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIC8vIGlzIHRoZXJlIGEgbm9kZT8KKyAgICAgICAgICAgICAgICBmaW5hbCBJdGVtIGZvdW5kTm9kZSA9IHRoaXMud3JpdGVyU2Vzc2lvbi5pdGVtRXhpc3RzKGpvYklkKSA/IHRoaXMud3JpdGVyU2Vzc2lvbi5nZXRJdGVtKGpvYklkKSA6IG51bGw7CisgICAgICAgICAgICAgICAgLy8gd2Ugc2hvdWxkIHJlbW92ZSB0aGUgbm9kZSBmcm9tIHRoZSByZXBvc2l0b3J5CisgICAgICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMgbm8gbm9kZSBzb21lb25lIGVsc2Ugd2FzIGZhc3RlciBhbmQgd2UgY2FuIGlnbm9yZSB0aGlzCisgICAgICAgICAgICAgICAgaWYgKCBmb3VuZE5vZGUgIT0gbnVsbCApIHsKKyAgICAgICAgICAgICAgICAgICAgZmluYWwgTm9kZSBwYXJlbnROb2RlID0gZm91bmROb2RlLmdldFBhcmVudCgpOworICAgICAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgICAgICAgZm91bmROb2RlLnJlbW92ZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5zYXZlKCk7CisgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKExvY2tFeGNlcHRpb24gbGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHNvbWVvbmUgZWxzZSBoYXMgdGhlIGxvY2sgdGhpcyBpcyBmaW5lCisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IGNhdGNoICggUmVwb3NpdG9yeUV4Y2VwdGlvbiByZSkgeworICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKCJVbmFibGUgdG8gY2FuY2VsIHRpbWVkIGV2ZW50OiAiICsgam9iSWQsIHJlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIHN0b3AgdGhlIHNjaGVkdWxlcgorICAgICAgICAgICAgaWYgKCB0aGlzLmxvZ2dlci5pc0RlYnVnRW5hYmxlZCgpICkgeworICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKCJTdG9wcGluZyB0aW1lZCBldmVudCAiICsgam9iSWQpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZmluYWwgU2NoZWR1bGVyIGxvY2FsU2NoZWR1bGVyID0gdGhpcy5zY2hlZHVsZXI7CisgICAgICAgICAgICBpZiAoIGxvY2FsU2NoZWR1bGVyICE9IG51bGwgKSB7CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgbG9jYWxTY2hlZHVsZXIucmVtb3ZlSm9iKGpvYklkKTsKKyAgICAgICAgICAgICAgICB9IGNhdGNoIChOb1N1Y2hFbGVtZW50RXhjZXB0aW9uIG5zZWUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBjYW4gaGFwcGVuIGlmIHRoZSBqb2IgaXMgc2NoZWR1bGVkIG9uIGFub3RoZXIgbm9kZQorICAgICAgICAgICAgICAgICAgICAvLyBzbyB3ZSBjYW4ganVzdCBpZ25vcmUgdGhpcworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9ESVNDTEFJTUVSIGIvc3JjL21haW4vcmVzb3VyY2VzL01FVEEtSU5GL0RJU0NMQUlNRVIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA4NTBjMgotLS0gL2Rldi9udWxsCisrKyBiL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9ESVNDTEFJTUVSCkBAIC0wLDAgKzEsNyBAQAorQXBhY2hlIFNsaW5nIGlzIGFuIGVmZm9ydCB1bmRlcmdvaW5nIGluY3ViYXRpb24gYXQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpLAorc3BvbnNvcmVkIGJ5IHRoZSBBcGFjaGUgSmFja3JhYmJpdCBQTUMuIEluY3ViYXRpb24gaXMgcmVxdWlyZWQgb2YgYWxsIG5ld2x5IGFjY2VwdGVkCitwcm9qZWN0cyB1bnRpbCBhIGZ1cnRoZXIgcmV2aWV3IGluZGljYXRlcyB0aGF0IHRoZSBpbmZyYXN0cnVjdHVyZSwgY29tbXVuaWNhdGlvbnMsCithbmQgZGVjaXNpb24gbWFraW5nIHByb2Nlc3MgaGF2ZSBzdGFiaWxpemVkIGluIGEgbWFubmVyIGNvbnNpc3RlbnQgd2l0aCBvdGhlcgorc3VjY2Vzc2Z1bCBBU0YgcHJvamVjdHMuIFdoaWxlIGluY3ViYXRpb24gc3RhdHVzIGlzIG5vdCBuZWNlc3NhcmlseSBhIHJlZmxlY3Rpb24gb2YKK3RoZSBjb21wbGV0ZW5lc3Mgb3Igc3RhYmlsaXR5IG9mIHRoZSBjb2RlLCBpdCBkb2VzIGluZGljYXRlIHRoYXQgdGhlIHByb2plY3QgaGFzIHlldAordG8gYmUgZnVsbHkgZW5kb3JzZWQgYnkgdGhlIEFTRi4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvTElDRU5TRSBiL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9MSUNFTlNFCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2NDU2OTUKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvTElDRU5TRQpAQCAtMCwwICsxLDIwMiBAQAorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcGFjaGUgTGljZW5zZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiAyLjAsIEphbnVhcnkgMjAwNAorICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLworCisgICBURVJNUyBBTkQgQ09ORElUSU9OUyBGT1IgVVNFLCBSRVBST0RVQ1RJT04sIEFORCBESVNUUklCVVRJT04KKworICAgMS4gRGVmaW5pdGlvbnMuCisKKyAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCisgICAgICBhbmQgZGlzdHJpYnV0aW9uIGFzIGRlZmluZWQgYnkgU2VjdGlvbnMgMSB0aHJvdWdoIDkgb2YgdGhpcyBkb2N1bWVudC4KKworICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIgdGhhdCBpcyBncmFudGluZyB0aGUgTGljZW5zZS4KKworICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAorICAgICAgb3RoZXIgZW50aXRpZXMgdGhhdCBjb250cm9sLCBhcmUgY29udHJvbGxlZCBieSwgb3IgYXJlIHVuZGVyIGNvbW1vbgorICAgICAgY29udHJvbCB3aXRoIHRoYXQgZW50aXR5LiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwKKyAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQorICAgICAgZGlyZWN0aW9uIG9yIG1hbmFnZW1lbnQgb2Ygc3VjaCBlbnRpdHksIHdoZXRoZXIgYnkgY29udHJhY3Qgb3IKKyAgICAgIG90aGVyd2lzZSwgb3IgKGlpKSBvd25lcnNoaXAgb2YgZmlmdHkgcGVyY2VudCAoNTAlKSBvciBtb3JlIG9mIHRoZQorICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KKworICAgICAgIllvdSIgKG9yICJZb3VyIikgc2hhbGwgbWVhbiBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQorICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KKworICAgICAgIlNvdXJjZSIgZm9ybSBzaGFsbCBtZWFuIHRoZSBwcmVmZXJyZWQgZm9ybSBmb3IgbWFraW5nIG1vZGlmaWNhdGlvbnMsCisgICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCisgICAgICBzb3VyY2UsIGFuZCBjb25maWd1cmF0aW9uIGZpbGVzLgorCisgICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAorICAgICAgdHJhbnNmb3JtYXRpb24gb3IgdHJhbnNsYXRpb24gb2YgYSBTb3VyY2UgZm9ybSwgaW5jbHVkaW5nIGJ1dAorICAgICAgbm90IGxpbWl0ZWQgdG8gY29tcGlsZWQgb2JqZWN0IGNvZGUsIGdlbmVyYXRlZCBkb2N1bWVudGF0aW9uLAorICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgorCisgICAgICAiV29yayIgc2hhbGwgbWVhbiB0aGUgd29yayBvZiBhdXRob3JzaGlwLCB3aGV0aGVyIGluIFNvdXJjZSBvcgorICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQorICAgICAgY29weXJpZ2h0IG5vdGljZSB0aGF0IGlzIGluY2x1ZGVkIGluIG9yIGF0dGFjaGVkIHRvIHRoZSB3b3JrCisgICAgICAoYW4gZXhhbXBsZSBpcyBwcm92aWRlZCBpbiB0aGUgQXBwZW5kaXggYmVsb3cpLgorCisgICAgICAiRGVyaXZhdGl2ZSBXb3JrcyIgc2hhbGwgbWVhbiBhbnkgd29yaywgd2hldGhlciBpbiBTb3VyY2Ugb3IgT2JqZWN0CisgICAgICBmb3JtLCB0aGF0IGlzIGJhc2VkIG9uIChvciBkZXJpdmVkIGZyb20pIHRoZSBXb3JrIGFuZCBmb3Igd2hpY2ggdGhlCisgICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCisgICAgICByZXByZXNlbnQsIGFzIGEgd2hvbGUsIGFuIG9yaWdpbmFsIHdvcmsgb2YgYXV0aG9yc2hpcC4gRm9yIHRoZSBwdXJwb3NlcworICAgICAgb2YgdGhpcyBMaWNlbnNlLCBEZXJpdmF0aXZlIFdvcmtzIHNoYWxsIG5vdCBpbmNsdWRlIHdvcmtzIHRoYXQgcmVtYWluCisgICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCisgICAgICB0aGUgV29yayBhbmQgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLgorCisgICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZworICAgICAgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhlIFdvcmsgYW5kIGFueSBtb2RpZmljYXRpb25zIG9yIGFkZGl0aW9ucworICAgICAgdG8gdGhhdCBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiwgdGhhdCBpcyBpbnRlbnRpb25hbGx5CisgICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCisgICAgICBvciBieSBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eSBhdXRob3JpemVkIHRvIHN1Ym1pdCBvbiBiZWhhbGYgb2YKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIuIEZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBkZWZpbml0aW9uLCAic3VibWl0dGVkIgorICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAorICAgICAgdG8gdGhlIExpY2Vuc29yIG9yIGl0cyByZXByZXNlbnRhdGl2ZXMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8KKyAgICAgIGNvbW11bmljYXRpb24gb24gZWxlY3Ryb25pYyBtYWlsaW5nIGxpc3RzLCBzb3VyY2UgY29kZSBjb250cm9sIHN5c3RlbXMsCisgICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQorICAgICAgTGljZW5zb3IgZm9yIHRoZSBwdXJwb3NlIG9mIGRpc2N1c3NpbmcgYW5kIGltcHJvdmluZyB0aGUgV29yaywgYnV0CisgICAgICBleGNsdWRpbmcgY29tbXVuaWNhdGlvbiB0aGF0IGlzIGNvbnNwaWN1b3VzbHkgbWFya2VkIG9yIG90aGVyd2lzZQorICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCisKKyAgICAgICJDb250cmlidXRvciIgc2hhbGwgbWVhbiBMaWNlbnNvciBhbmQgYW55IGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5CisgICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKKyAgICAgIHN1YnNlcXVlbnRseSBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrLgorCisgICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgZWFjaCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIHRvIFlvdSBhIHBlcnBldHVhbCwKKyAgICAgIHdvcmxkd2lkZSwgbm9uLWV4Y2x1c2l2ZSwgbm8tY2hhcmdlLCByb3lhbHR5LWZyZWUsIGlycmV2b2NhYmxlCisgICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKKyAgICAgIHB1YmxpY2x5IGRpc3BsYXksIHB1YmxpY2x5IHBlcmZvcm0sIHN1YmxpY2Vuc2UsIGFuZCBkaXN0cmlidXRlIHRoZQorICAgICAgV29yayBhbmQgc3VjaCBEZXJpdmF0aXZlIFdvcmtzIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybS4KKworICAgMy4gR3JhbnQgb2YgUGF0ZW50IExpY2Vuc2UuIFN1YmplY3QgdG8gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCisgICAgICB0aGlzIExpY2Vuc2UsIGVhY2ggQ29udHJpYnV0b3IgaGVyZWJ5IGdyYW50cyB0byBZb3UgYSBwZXJwZXR1YWwsCisgICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQorICAgICAgKGV4Y2VwdCBhcyBzdGF0ZWQgaW4gdGhpcyBzZWN0aW9uKSBwYXRlbnQgbGljZW5zZSB0byBtYWtlLCBoYXZlIG1hZGUsCisgICAgICB1c2UsIG9mZmVyIHRvIHNlbGwsIHNlbGwsIGltcG9ydCwgYW5kIG90aGVyd2lzZSB0cmFuc2ZlciB0aGUgV29yaywKKyAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCisgICAgICBieSBzdWNoIENvbnRyaWJ1dG9yIHRoYXQgYXJlIG5lY2Vzc2FyaWx5IGluZnJpbmdlZCBieSB0aGVpcgorICAgICAgQ29udHJpYnV0aW9uKHMpIGFsb25lIG9yIGJ5IGNvbWJpbmF0aW9uIG9mIHRoZWlyIENvbnRyaWJ1dGlvbihzKQorICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKKyAgICAgIGluc3RpdHV0ZSBwYXRlbnQgbGl0aWdhdGlvbiBhZ2FpbnN0IGFueSBlbnRpdHkgKGluY2x1ZGluZyBhCisgICAgICBjcm9zcy1jbGFpbSBvciBjb3VudGVyY2xhaW0gaW4gYSBsYXdzdWl0KSBhbGxlZ2luZyB0aGF0IHRoZSBXb3JrCisgICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAorICAgICAgb3IgY29udHJpYnV0b3J5IHBhdGVudCBpbmZyaW5nZW1lbnQsIHRoZW4gYW55IHBhdGVudCBsaWNlbnNlcworICAgICAgZ3JhbnRlZCB0byBZb3UgdW5kZXIgdGhpcyBMaWNlbnNlIGZvciB0aGF0IFdvcmsgc2hhbGwgdGVybWluYXRlCisgICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCisKKyAgIDQuIFJlZGlzdHJpYnV0aW9uLiBZb3UgbWF5IHJlcHJvZHVjZSBhbmQgZGlzdHJpYnV0ZSBjb3BpZXMgb2YgdGhlCisgICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKKyAgICAgIG1vZGlmaWNhdGlvbnMsIGFuZCBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0sIHByb3ZpZGVkIHRoYXQgWW91CisgICAgICBtZWV0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKworICAgICAgKGEpIFlvdSBtdXN0IGdpdmUgYW55IG90aGVyIHJlY2lwaWVudHMgb2YgdGhlIFdvcmsgb3IKKyAgICAgICAgICBEZXJpdmF0aXZlIFdvcmtzIGEgY29weSBvZiB0aGlzIExpY2Vuc2U7IGFuZAorCisgICAgICAoYikgWW91IG11c3QgY2F1c2UgYW55IG1vZGlmaWVkIGZpbGVzIHRvIGNhcnJ5IHByb21pbmVudCBub3RpY2VzCisgICAgICAgICAgc3RhdGluZyB0aGF0IFlvdSBjaGFuZ2VkIHRoZSBmaWxlczsgYW5kCisKKyAgICAgIChjKSBZb3UgbXVzdCByZXRhaW4sIGluIHRoZSBTb3VyY2UgZm9ybSBvZiBhbnkgRGVyaXZhdGl2ZSBXb3JrcworICAgICAgICAgIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsbCBjb3B5cmlnaHQsIHBhdGVudCwgdHJhZGVtYXJrLCBhbmQKKyAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAorICAgICAgICAgIGV4Y2x1ZGluZyB0aG9zZSBub3RpY2VzIHRoYXQgZG8gbm90IHBlcnRhaW4gdG8gYW55IHBhcnQgb2YKKyAgICAgICAgICB0aGUgRGVyaXZhdGl2ZSBXb3JrczsgYW5kCisKKyAgICAgIChkKSBJZiB0aGUgV29yayBpbmNsdWRlcyBhICJOT1RJQ0UiIHRleHQgZmlsZSBhcyBwYXJ0IG9mIGl0cworICAgICAgICAgIGRpc3RyaWJ1dGlvbiwgdGhlbiBhbnkgRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlIG11c3QKKyAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKKyAgICAgICAgICB3aXRoaW4gc3VjaCBOT1RJQ0UgZmlsZSwgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QKKyAgICAgICAgICBwZXJ0YWluIHRvIGFueSBwYXJ0IG9mIHRoZSBEZXJpdmF0aXZlIFdvcmtzLCBpbiBhdCBsZWFzdCBvbmUKKyAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAorICAgICAgICAgIGFzIHBhcnQgb2YgdGhlIERlcml2YXRpdmUgV29ya3M7IHdpdGhpbiB0aGUgU291cmNlIGZvcm0gb3IKKyAgICAgICAgICBkb2N1bWVudGF0aW9uLCBpZiBwcm92aWRlZCBhbG9uZyB3aXRoIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyBvciwKKyAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCisgICAgICAgICAgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBub3RpY2VzIG5vcm1hbGx5IGFwcGVhci4gVGhlIGNvbnRlbnRzCisgICAgICAgICAgb2YgdGhlIE5PVElDRSBmaWxlIGFyZSBmb3IgaW5mb3JtYXRpb25hbCBwdXJwb3NlcyBvbmx5IGFuZAorICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCisgICAgICAgICAgbm90aWNlcyB3aXRoaW4gRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbG9uZ3NpZGUKKyAgICAgICAgICBvciBhcyBhbiBhZGRlbmR1bSB0byB0aGUgTk9USUNFIHRleHQgZnJvbSB0aGUgV29yaywgcHJvdmlkZWQKKyAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKKyAgICAgICAgICBhcyBtb2RpZnlpbmcgdGhlIExpY2Vuc2UuCisKKyAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAorICAgICAgbWF5IHByb3ZpZGUgYWRkaXRpb25hbCBvciBkaWZmZXJlbnQgbGljZW5zZSB0ZXJtcyBhbmQgY29uZGl0aW9ucworICAgICAgZm9yIHVzZSwgcmVwcm9kdWN0aW9uLCBvciBkaXN0cmlidXRpb24gb2YgWW91ciBtb2RpZmljYXRpb25zLCBvcgorICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCisgICAgICByZXByb2R1Y3Rpb24sIGFuZCBkaXN0cmlidXRpb24gb2YgdGhlIFdvcmsgb3RoZXJ3aXNlIGNvbXBsaWVzIHdpdGgKKyAgICAgIHRoZSBjb25kaXRpb25zIHN0YXRlZCBpbiB0aGlzIExpY2Vuc2UuCisKKyAgIDUuIFN1Ym1pc3Npb24gb2YgQ29udHJpYnV0aW9ucy4gVW5sZXNzIFlvdSBleHBsaWNpdGx5IHN0YXRlIG90aGVyd2lzZSwKKyAgICAgIGFueSBDb250cmlidXRpb24gaW50ZW50aW9uYWxseSBzdWJtaXR0ZWQgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yaworICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgd2l0aG91dCBhbnkgYWRkaXRpb25hbCB0ZXJtcyBvciBjb25kaXRpb25zLgorICAgICAgTm90d2l0aHN0YW5kaW5nIHRoZSBhYm92ZSwgbm90aGluZyBoZXJlaW4gc2hhbGwgc3VwZXJzZWRlIG9yIG1vZGlmeQorICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKKyAgICAgIHdpdGggTGljZW5zb3IgcmVnYXJkaW5nIHN1Y2ggQ29udHJpYnV0aW9ucy4KKworICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQorICAgICAgbmFtZXMsIHRyYWRlbWFya3MsIHNlcnZpY2UgbWFya3MsIG9yIHByb2R1Y3QgbmFtZXMgb2YgdGhlIExpY2Vuc29yLAorICAgICAgZXhjZXB0IGFzIHJlcXVpcmVkIGZvciByZWFzb25hYmxlIGFuZCBjdXN0b21hcnkgdXNlIGluIGRlc2NyaWJpbmcgdGhlCisgICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KKworICAgNy4gRGlzY2xhaW1lciBvZiBXYXJyYW50eS4gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yCisgICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCisgICAgICBDb250cmlidXRvciBwcm92aWRlcyBpdHMgQ29udHJpYnV0aW9ucykgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgICAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvcgorICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKKyAgICAgIG9mIFRJVExFLCBOT04tSU5GUklOR0VNRU5ULCBNRVJDSEFOVEFCSUxJVFksIG9yIEZJVE5FU1MgRk9SIEEKKyAgICAgIFBBUlRJQ1VMQVIgUFVSUE9TRS4gWW91IGFyZSBzb2xlbHkgcmVzcG9uc2libGUgZm9yIGRldGVybWluaW5nIHRoZQorICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CisgICAgICByaXNrcyBhc3NvY2lhdGVkIHdpdGggWW91ciBleGVyY2lzZSBvZiBwZXJtaXNzaW9ucyB1bmRlciB0aGlzIExpY2Vuc2UuCisKKyAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAorICAgICAgd2hldGhlciBpbiB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGNvbnRyYWN0LCBvciBvdGhlcndpc2UsCisgICAgICB1bmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgKHN1Y2ggYXMgZGVsaWJlcmF0ZSBhbmQgZ3Jvc3NseQorICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKKyAgICAgIGxpYWJsZSB0byBZb3UgZm9yIGRhbWFnZXMsIGluY2x1ZGluZyBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgc3BlY2lhbCwKKyAgICAgIGluY2lkZW50YWwsIG9yIGNvbnNlcXVlbnRpYWwgZGFtYWdlcyBvZiBhbnkgY2hhcmFjdGVyIGFyaXNpbmcgYXMgYQorICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQorICAgICAgV29yayAoaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBkYW1hZ2VzIGZvciBsb3NzIG9mIGdvb2R3aWxsLAorICAgICAgd29yayBzdG9wcGFnZSwgY29tcHV0ZXIgZmFpbHVyZSBvciBtYWxmdW5jdGlvbiwgb3IgYW55IGFuZCBhbGwKKyAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKKyAgICAgIGhhcyBiZWVuIGFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlcy4KKworICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZworICAgICAgdGhlIFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLCBZb3UgbWF5IGNob29zZSB0byBvZmZlciwKKyAgICAgIGFuZCBjaGFyZ2UgYSBmZWUgZm9yLCBhY2NlcHRhbmNlIG9mIHN1cHBvcnQsIHdhcnJhbnR5LCBpbmRlbW5pdHksCisgICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcworICAgICAgTGljZW5zZS4gSG93ZXZlciwgaW4gYWNjZXB0aW5nIHN1Y2ggb2JsaWdhdGlvbnMsIFlvdSBtYXkgYWN0IG9ubHkKKyAgICAgIG9uIFlvdXIgb3duIGJlaGFsZiBhbmQgb24gWW91ciBzb2xlIHJlc3BvbnNpYmlsaXR5LCBub3Qgb24gYmVoYWxmCisgICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCisgICAgICBkZWZlbmQsIGFuZCBob2xkIGVhY2ggQ29udHJpYnV0b3IgaGFybWxlc3MgZm9yIGFueSBsaWFiaWxpdHkKKyAgICAgIGluY3VycmVkIGJ5LCBvciBjbGFpbXMgYXNzZXJ0ZWQgYWdhaW5zdCwgc3VjaCBDb250cmlidXRvciBieSByZWFzb24KKyAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgorCisgICBFTkQgT0YgVEVSTVMgQU5EIENPTkRJVElPTlMKKworICAgQVBQRU5ESVg6IEhvdyB0byBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLgorCisgICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZworICAgICAgYm9pbGVycGxhdGUgbm90aWNlLCB3aXRoIHRoZSBmaWVsZHMgZW5jbG9zZWQgYnkgYnJhY2tldHMgIltdIgorICAgICAgcmVwbGFjZWQgd2l0aCB5b3VyIG93biBpZGVudGlmeWluZyBpbmZvcm1hdGlvbi4gKERvbid0IGluY2x1ZGUKKyAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCisgICAgICBjb21tZW50IHN5bnRheCBmb3IgdGhlIGZpbGUgZm9ybWF0LiBXZSBhbHNvIHJlY29tbWVuZCB0aGF0IGEKKyAgICAgIGZpbGUgb3IgY2xhc3MgbmFtZSBhbmQgZGVzY3JpcHRpb24gb2YgcHVycG9zZSBiZSBpbmNsdWRlZCBvbiB0aGUKKyAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgorICAgICAgaWRlbnRpZmljYXRpb24gd2l0aGluIHRoaXJkLXBhcnR5IGFyY2hpdmVzLgorCisgICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KKworICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL3Jlc291cmNlcy9NRVRBLUlORi9OT1RJQ0UgYi9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvTk9USUNFCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyYTc5MmEKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvbWFpbi9yZXNvdXJjZXMvTUVUQS1JTkYvTk9USUNFCkBAIC0wLDAgKzEsOCBAQAorQXBhY2hlIFNsaW5nIEV2ZW50CitDb3B5cmlnaHQgMjAwOC0yMDA5IFRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbgorCitBcGFjaGUgU2xpbmcgaXMgYmFzZWQgb24gc291cmNlIGNvZGUgb3JpZ2luYWxseSBkZXZlbG9wZWQgCitieSBEYXkgU29mdHdhcmUgKGh0dHA6Ly93d3cuZGF5LmNvbS8pLgorCitUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGF0CitUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLgpkaWZmIC0tZ2l0IGEvc3JjL21haW4vcmVzb3VyY2VzL09TR0ktSU5GL21ldGF0eXBlL21ldGF0eXBlLnByb3BlcnRpZXMgYi9zcmMvbWFpbi9yZXNvdXJjZXMvT1NHSS1JTkYvbWV0YXR5cGUvbWV0YXR5cGUucHJvcGVydGllcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kM2ExNGFkCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vcmVzb3VyY2VzL09TR0ktSU5GL21ldGF0eXBlL21ldGF0eXBlLnByb3BlcnRpZXMKQEAgLTAsMCArMSwxMTEgQEAKKyMKKyMgIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyMgIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorIyAgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyMgIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyMgIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyMgICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyMgIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyMgIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisjICAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyMgIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorIyAgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworIyAgdW5kZXIgdGhlIExpY2Vuc2UuCisjCisKKyMKKyMgVGhpcyBmaWxlIGNvbnRhaW5zIGxvY2FsaXphdGlvbiBzdHJpbmdzIGZvciBjb25maWd1cmF0aW9uIGxhYmVscyBhbmQKKyMgZGVzY3JpcHRpb25zIGFzIHVzZWQgaW4gdGhlIG1ldGF0eXBlLnhtbCBkZXNjcmlwdG9yIGdlbmVyYXRlZCBieSB0aGUKKyMgdGhlIFNDUiBwbHVnaW4KKworIworIyBEaXN0cmlidXRpbmcgRXZlbnQgSGFuZGxlcgorZGlzdC5ldmVudHMubmFtZSA9IEFwYWNoZSBTbGluZyBEaXN0cmlidXRpbmcgRXZlbnQgSGFuZGxlciAKK2Rpc3QuZXZlbnRzLmRlc2NyaXB0aW9uID0gRGlzdHJpYnV0ZXMgbG9jYWwgT1NHaSBFdmVudCBBZG1pbiBldmVudHMgdG8gXAorIG90aGVyIG5vZGVzIG9mIHRoZSBzYW1lIGNsdXN0ZXIuIFRoZSBldmVudHMgYXJlIHdyaXR0ZW4gdG8gdGhlIEpDUiBcCisgcmVwb3NpdG9yeSBmb3IgZGlzdHJpYnV0aW9uIHRvIG90aGVyIG5vZGVzIHdoaWxlIGV2ZW50cyB3cml0dGVuIHRvIHRoZSBcCisgcmVwb3NpdG9yeSBhcmUgcGlja2VkIHVwIGFuZCBkaXN0cmlidXRlZCBsb2NhbGx5IHRocm91Z2ggdGhlIE9TR2kgRXZlbnQgQWRtaW4gXAorIFNlcnZpY2UuICAgCisKKyMKKyMgSm9iIEV2ZW50IEhhbmRsZXIKK2pvYi5ldmVudHMubmFtZSA9IEFwYWNoZSBTbGluZyBKb2IgRXZlbnQgSGFuZGxlciAKK2pvYi5ldmVudHMuZGVzY3JpcHRpb24gPSBNYW5hZ2VzIGpvYiBzY2hlZHVsaW5nIG9uIGEgc2luZ2xlIHN5c3RlbSBhcyB3ZWxsIFwKKyBhcyBvbiBhIGNsdXN0ZXIuIEEgSm9iIHJ1bnMgb25seSBvbiBhIHNpbmdsZSBjbHVzdGVyIG5vZGUuIFwKKyBUaGUgcmVzcGVjdGl2ZSBzY2hlZHVsaW5nIGlzIHBlcnNpc3RlZCBpbiB0aGUgcmVwb3NpdG9yeSBhbmQgZGlzdHJpYnV0ZWQgXAorIGFtb25nc3QgdGhlIGNsdXN0ZXIgbm9kZXMgdGhyb3VnaCByZXBvc2l0b3J5IGV2ZW50cy4gVGhlIGpvYnMgYXJlIHN0YXJ0ZWQgXAorIGxvY2FsbHkgb24gYSBzaW5nbGUgY2x1c3RlciBub2RlIHRocm91Z2ggdGhlIE9TR2kgRXZlbnQgQWRtaW4uCisKK3NsZWVwLnRpbWUubmFtZSA9IFJldHJ5IEludGVydmFsCitzbGVlcC50aW1lLmRlc2NyaXB0aW9uID0gVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gc2xlZXAgYmV0d2VlbiB0d28gXAorIGNvbnNlY3V0aXZlIHJldHJpZXMgb2YgYSBqb2Igd2hpY2ggZmFpbGVkIGFuZCB3YXMgc2V0IHRvIGJlIHJldHJpZWQuIFRoZSBcCisgZGVmYXVsdCB2YWx1ZSBpcyAzMCBzZWNvbmRzLiBUaGlzIHZhbHVlIGlzIG9ubHkgcmVsZXZhbnQgaWYgdGhlcmUgaXMgYSBzaW5nbGUgXAorIGZhaWxlZCBqb2IgaW4gdGhlIHF1ZXVlLiBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgZmFpbGVkIGpvYnMsIGVhY2ggam9iIGlzIFwKKyByZXRyaWVkIGluIHR1cm4gd2l0aG91dCBhbiBpbnRlcnZlbmluZyBkZWxheS4KKyAKK21heC5qb2IucmV0cmllcy5uYW1lID0gTWF4aW11bSBSZXRyaWVzCittYXguam9iLnJldHJpZXMuZGVzY3JpcHRpb24gPSBUaGUgbWF4aW11bSBudW1iZXIgb2YgdGltZXMgYSBmYWlsZWQgam9iIHNsYXRlZCBcCisgZm9yIHJldHJpZXMgaXMgYWN0dWFsbHkgcmV0cmllZC4gSWYgYSBqb2IgaGFzIGJlZW4gcmV0cmllZCB0aGlzIG51bWJlciBvZiBcCisgdGltZXMgYW5kIHN0aWxsIGZhaWxzLCBpdCBpcyBub3QgcmVzY2hlZHVsZWQgYW5kIGFzc3VtZWQgdG8gaGF2ZSBmYWlsZWQuIFRoZSBcCisgZGVmYXVsdCB2YWx1ZSBpcyAxMC4KKworam9ic2NoZWR1bGVyLnBlcmlvZC5uYW1lID0gRXZlbnQgQ2xlYW51cCBJbnRlcm5hbAoram9ic2NoZWR1bGVyLnBlcmlvZC5kZXNjcmlwdGlvbiA9IEludGVydmFsIGluIHNlY29uZHMgaW4gd2hpY2ggam9icyBvbGRlciB0aGFuIFwKKyBhIHNwZWNpZmljIGFnZSAoc2VlIEV2ZW50IENsZWFudXAgQWdlKSBhcmUgcHVyZ2VkIGZyb20gdGhlIHJlcG9zaXRvcnkuIFwKKyBUaGUgZGVmYXVsdCB2YWx1ZSBpcyA1IG1pbnV0ZXMgKDMwMCBzZWNvbmRzKS4KKworam9iY2xlYW51cC5wZXJpb2QubmFtZSA9IEV2ZW50IENsZWFudXAgQWdlCitqb2JjbGVhbnVwLnBlcmlvZC5kZXNjcmlwdGlvbiA9IFRoZSBtYXhpbXVtIGFnZSBpbiBtaW51dGVzIG9mIHBlcnNpc3RlZCBqb2IgdG8gXAorIGJlIHB1cmdlZCBmcm9tIHRoZSByZXBvc2l0b3J5IGR1cmluZyB0aGUgY2xlYW51cCBydW4uIFRoZSBkZWZhdWx0IGlzIDUgXAorIG1pbnV0ZXMuIE5vdGUgdGhhdCB0aGlzIHNldHRpbmcgZGVmaW5lcyB0aGUgbWluaW11bSB0aW1lIGFuIGV2ZW50IHJlbWFpbnMgXAorIGluIHRoZSByZXBvc2l0b3J5LiAKKword2FpdC5mb3IuYWNrLm5hbWUgPSBBY2tub3dsZWRnZSBXYWl0aW5nIFRpbWUKK3dhaXQuZm9yLmFjay5kZXNjcmlwdGlvbiA9IElmIGEgc2VydmljZSBpcyBwcm9jZXNzaW5nIGEgam9iLCBpdCBhY2tub3dsZWRnZXMgdGhpcyBcCisgYnkgc2VuZGluZyBhIG1lc3NhZ2UgdG8gdGhlIEpvYiBFdmVudCBIYW5kbGVyLiBJZiB0aGUgSm9iIEV2ZW50IEhhbmRsZXIgZG9lcyBub3QgXAorIHJlY2VpdmUgc3VjaCBhIG1lc3NhZ2UgaW4gdGhlIGNvbmZpZ3VyZWQgdGltZSwgaXQgcmVzY2hlZHVsZXMgdGhlIGpvYi4gVGhlIGNvbmZpZ3VyZWQgXAorIHRpbWUgaXMgaW4gc2Vjb25kcyAoZGVmYXVsdCBpcyA5MCBzZWNzKS4KKworbWF4LnBhcmFsbGVsLmpvYnMubmFtZSA9IE1heGltdW0gUGFyYWxsZWwgSm9icworbWF4LnBhcmFsbGVsLmpvYnMuZGVzY3JpcHRpb24gPSBUaGUgbWF4aW11bSBudW1iZXIgb2YgcGFyYWxsZWwgam9icyBzdGFydGVkIGZvciB0aGUgbWFpbiBcCisgcXVldWUuCisKKworIworIyBFdmVudCBQb29sCitldmVudC5wb29sLm5hbWUgPSBBcGFjaGUgU2xpbmcgRXZlbnQgVGhyZWFkIFBvb2wgCitldmVudC5wb29sLmRlc2NyaXB0aW9uID0gVGhpcyBpcyB0aGUgdGhyZWFkIHBvb2wgdXNlZCBieSB0aGUgQXBhY2hlIFNsaW5nIGV2ZW50aW5nIHN1cHBvcnQuCisKK21pblBvb2xTaXplLm5hbWUgPSBNaW4gUG9vbCBTaXplCittaW5Qb29sU2l6ZS5kZXNjcmlwdGlvbiA9IFRoZSBtaW5pbXVtIHBvb2wgc2l6ZS4gVGhlIG1pbmltdW0gcG9vbCBzaXplIHNob3VsZCBiZSBcCisgaGlnaGVyIHRoYW4gMjAuIEFwcHJveCAxMCB0aHJlYWRzIGFyZSBpbiB1c2UgYnkgdGhlIHN5c3RlbSwgc28gYSBwb29sIHNpemUgb2YgMjAgXAorIGFsbG93cyB0byBwcm9jZXNzIDEwIGV2ZW50cyBpbiBwYXJhbGxlbC4KKworbWF4UG9vbFNpemUubmFtZSA9IE1heCBQb29sIFNpemUKK21heFBvb2xTaXplLmRlc2NyaXB0aW9uID0gVGhlIG1heGltdW0gcG9vbCBzaXplLiBUaGUgbWF4aW11bSBwb29sIHNpemUgc2hvdWxkIGJlIGhpZ2hlciB0aGFuIFwKKyB0aGUgbWluaW11bSBwb29sIHNpemUuCisKK3F1ZXVlU2l6ZS5uYW1lID0gUXVldWUgU2l6ZQorcXVldWVTaXplLmRlc2NyaXB0aW9uID0gVGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgdGhyZWFkIHF1ZXVlIGlmIHRoZSBwb29sIGlzIGV4aGF1c3RlZC4KKworIworIyBTaGFyZWQgbGFiZWxzCitzY2hlZHVsZXIucGVyaW9kLm5hbWUgPSBFdmVudCBDbGVhbnVwIEludGVybmFsCitzY2hlZHVsZXIucGVyaW9kLmRlc2NyaXB0aW9uID0gSW50ZXJ2YWwgaW4gc2Vjb25kcyBpbiB3aGljaCBldmVudHMgb2xkZXIgdGhhbiBcCisgYSBzcGVjaWZpYyBhZ2UgKHNlZSBFdmVudCBDbGVhbnVwIEFnZSkgYXJlIHB1cmdlZCBmcm9tIHRoZSByZXBvc2l0b3J5LiBcCisgVGhlIGRlZmF1bHQgdmFsdWUgaXMgMzAgbWludXRlcyAoMTgwMCBzZWNvbmRzKS4KKworY2xlYW51cC5wZXJpb2QubmFtZSA9IEV2ZW50IENsZWFudXAgQWdlCitjbGVhbnVwLnBlcmlvZC5kZXNjcmlwdGlvbiA9IFRoZSBtYXhpbXVtIGFnZSBpbiBtaW51dGVzIG9mIHBlcnNpc3RlZCBldmVudHMgdG8gXAorIGJlIHB1cmdlZCBmcm9tIHRoZSByZXBvc2l0b3J5IGR1cmluZyB0aGUgY2xlYW51cCBydW4uIFRoZSBkZWZhdWx0IGlzIDE1IFwKKyBtaW51dGVzLiBOb3RlIHRoYXQgdGhpcyBzZXR0aW5nIGRlZmluZXMgdGhlIG1pbmltdW0gdGltZSBhbiBldmVudCByZW1haW5zIFwKKyBpbiB0aGUgcmVwb3NpdG9yeS4gCisgCityZXBvc2l0b3J5LnBhdGgubmFtZSA9IFBlcnNpc3RlbnQgRXZlbnQgTG9jYXRpb24KK3JlcG9zaXRvcnkucGF0aC5kZXNjcmlwdGlvbiA9IEFic29sdXRlIFBhdGggb2YgdGhlIFJlcG9zaXRvcnkgbG9jYXRpb24gd2hlcmUgXAorIGV2ZW50cyBhcmUgcGVyc2lzdGVkIHRvIGJlIHBpY2tlZCB1cCBieSB0aGUgZXZlbnQgZGlzdHJpYnV0aW9uIG1lY2hhbmlzbS4gXAorIFRoZSBkZWZhdWx0IHZhbHVlIGlzICIvc2xpbmcvZXZlbnRzIi4KZGlmZiAtLWdpdCBhL3NyYy9tYWluL3Jlc291cmNlcy9TTElORy1JTkYvbm9kZXR5cGVzL2V2ZW50LmNuZCBiL3NyYy9tYWluL3Jlc291cmNlcy9TTElORy1JTkYvbm9kZXR5cGVzL2V2ZW50LmNuZApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MmVjMjEzCi0tLSAvZGV2L251bGwKKysrIGIvc3JjL21haW4vcmVzb3VyY2VzL1NMSU5HLUlORi9ub2RldHlwZXMvZXZlbnQuY25kCkBAIC0wLDAgKzEsNDIgQEAKKy8vDQorLy8gIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUNCisvLyAgb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlDQorLy8gIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uDQorLy8gIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUNCisvLyAgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQ0KKy8vICAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlDQorLy8gIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQNCisvLw0KKy8vICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wDQorLy8NCisvLyAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLA0KKy8vICBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbg0KKy8vICAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkNCisvLyAgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlDQorLy8gIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMNCisvLyAgdW5kZXIgdGhlIExpY2Vuc2UuDQorLy8NCisNCis8c2xpbmdldmVudD0naHR0cDovL3NsaW5nLmFwYWNoZS5vcmcvamNyL2V2ZW50LzEuMCc+DQorPG50PSdodHRwOi8vd3d3LmpjcC5vcmcvamNyL250LzEuMCc+DQorPG1peD0naHR0cDovL3d3dy5qY3Aub3JnL2pjci9taXgvMS4wJz4NCisNCitbc2xpbmdldmVudDpFdmVudF0gPiBudDp1bnN0cnVjdHVyZWQsIG50OmhpZXJhcmNoeU5vZGUNCisgIC0gc2xpbmdldmVudDp0b3BpYyAoc3RyaW5nKQ0KKyAgLSBzbGluZ2V2ZW50OmFwcGxpY2F0aW9uIChzdHJpbmcpDQorICAtIHNsaW5nZXZlbnQ6Y3JlYXRlZCAoZGF0ZSkNCisgIC0gc2xpbmdldmVudDpwcm9wZXJ0aWVzIChiaW5hcnkpDQorICANCitbc2xpbmdldmVudDpKb2JdID4gc2xpbmdldmVudDpFdmVudCwgbWl4OmxvY2thYmxlDQorICAtIHNsaW5nZXZlbnQ6cHJvY2Vzc29yIChzdHJpbmcpDQorICAtIHNsaW5nZXZlbnQ6aWQgKHN0cmluZykNCisgIC0gc2xpbmdldmVudDpmaW5pc2hlZCAoZGF0ZSkNCisgDQorW3NsaW5nZXZlbnQ6VGltZWRFdmVudF0gPiBzbGluZ2V2ZW50OkV2ZW50LCBtaXg6bG9ja2FibGUNCisgIC0gc2xpbmdldmVudDpwcm9jZXNzb3IgKHN0cmluZykNCisgIC0gc2xpbmdldmVudDppZCAoc3RyaW5nKQ0KKyAgLSBzbGluZ2V2ZW50OmV4cHJlc3Npb24gKHN0cmluZykNCisgIC0gc2xpbmdldmVudDpkYXRlIChkYXRlKQ0KKyAgLSBzbGluZ2V2ZW50OnBlcmlvZCAobG9uZykNCisNCisgIA0KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9FdmVudFV0aWxUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvRXZlbnRVdGlsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI1NWUyMjkKLS0tIC9kZXYvbnVsbAorKysgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvRXZlbnRVdGlsVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQyIEBACisvKgorICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQorICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCisgKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgorICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQorICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQorICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQorICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAorICogc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4KKyAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQorICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCisgKiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCisgKiB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50OworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEZhbHNlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CisKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5DYWxlbmRhcjsKK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKKworaW1wb3J0IGphdmF4Lmpjci5Qcm9wZXJ0eVR5cGU7CitpbXBvcnQgamF2YXguamNyLlJlcG9zaXRvcnlFeGNlcHRpb247CitpbXBvcnQgamF2YXguamNyLlZhbHVlOworaW1wb3J0IGphdmF4Lmpjci5WYWx1ZUZhY3Rvcnk7CitpbXBvcnQgamF2YXguamNyLlZhbHVlRm9ybWF0RXhjZXB0aW9uOworCitpbXBvcnQgb3JnLmptb2NrLkV4cGVjdGF0aW9uczsKK2ltcG9ydCBvcmcuam1vY2suTW9ja2VyeTsKK2ltcG9ydCBvcmcuam1vY2suaW50ZWdyYXRpb24uanVuaXQ0LkpNb2NrOworaW1wb3J0IG9yZy5qbW9jay5pbnRlZ3JhdGlvbi5qdW5pdDQuSlVuaXQ0TW9ja2VyeTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudDsKKworLyoqCisgKiBUZXN0cyBmb3IgdGhlIEV2ZW50VXRpbCB1dGlsaXR5IG1ldGhvZHMuCisgKi8KK0BSdW5XaXRoKEpNb2NrLmNsYXNzKQorcHVibGljIGNsYXNzIEV2ZW50VXRpbFRlc3QgeworCisgICAgcHJvdGVjdGVkIE1vY2tlcnkgY29udGV4dDsKKworICAgIHB1YmxpYyBFdmVudFV0aWxUZXN0KCkgeworICAgICAgICB0aGlzLmNvbnRleHQgPSBuZXcgSlVuaXQ0TW9ja2VyeSgpOworICAgIH0KKworICAgIEBUZXN0IHB1YmxpYyB2b2lkIHRlc3REaXN0cmlidXRlRmxhZygpIHsKKyAgICAgICAgZmluYWwgRXZlbnQgZGlzdHJpYnV0YWJsZUV2ZW50ID0gRXZlbnRVdGlsLmNyZWF0ZURpc3RyaWJ1dGFibGVFdmVudCgic29tZS90b3BpYyIsIG51bGwpOworICAgICAgICBhc3NlcnRUcnVlKEV2ZW50VXRpbC5zaG91bGREaXN0cmlidXRlKGRpc3RyaWJ1dGFibGVFdmVudCkpOworICAgICAgICBmaW5hbCBFdmVudCBub25EaXN0cmlidXRhYmxlRXZlbnQgPSBuZXcgRXZlbnQoImFub3RoZXIvdG9waWMiLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0RmFsc2UoRXZlbnRVdGlsLnNob3VsZERpc3RyaWJ1dGUobm9uRGlzdHJpYnV0YWJsZUV2ZW50KSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgdGVzdExvY2FsRmxhZygpIHsKKyAgICAgICAgZmluYWwgRXZlbnQgbG9jYWxFdmVudCA9IG5ldyBFdmVudCgibG9jYWwvZXZlbnQiLCBudWxsKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShFdmVudFV0aWwuaXNMb2NhbChsb2NhbEV2ZW50KSk7CisgICAgICAgIGZpbmFsIFByb3BlcnRpZXMgcHJvcHMgPSBuZXcgUHJvcGVydGllcygpOworICAgICAgICBwcm9wcy5wdXQoRXZlbnRVdGlsLlBST1BFUlRZX0FQUExJQ0FUSU9OLCAiYXBwbGljYXRpb24xIik7CisgICAgICAgIGZpbmFsIEV2ZW50IHJlbW90ZUV2ZW50ID0gbmV3IEV2ZW50KCJyZW1vdGUvZXZlbnQiLCBwcm9wcyk7CisgICAgICAgIGFzc2VydEZhbHNlKEV2ZW50VXRpbC5pc0xvY2FsKHJlbW90ZUV2ZW50KSk7CisgICAgfQorCisgICAgQFRlc3QgcHVibGljIHZvaWQgdGVzdEdldE5vZGVQcm9wZXJ0eVZhbHVlKCkgeworICAgICAgICBmaW5hbCBWYWx1ZUZhY3RvcnkgZmFjdG9yeSA9IHRoaXMuY29udGV4dC5tb2NrKFZhbHVlRmFjdG9yeS5jbGFzcyk7CisgICAgICAgIHRoaXMuY29udGV4dC5jaGVja2luZyhuZXcgRXhwZWN0YXRpb25zKCkge3sKKyAgICAgICAgICAgIGFsbG93aW5nKGZhY3RvcnkpLmNyZWF0ZVZhbHVlKHRydWUpOworICAgICAgICAgICAgd2lsbChyZXR1cm5WYWx1ZShuZXcgVmFsdWVJbXBsKFByb3BlcnR5VHlwZS5CT09MRUFOKSkpOworICAgICAgICAgICAgYWxsb3dpbmcoZmFjdG9yeSkuY3JlYXRlVmFsdWUoZmFsc2UpOworICAgICAgICAgICAgd2lsbChyZXR1cm5WYWx1ZShuZXcgVmFsdWVJbXBsKFByb3BlcnR5VHlwZS5CT09MRUFOKSkpOworICAgICAgICAgICAgYWxsb3dpbmcoZmFjdG9yeSkuY3JlYXRlVmFsdWUod2l0aChhbnkoTG9uZy5jbGFzcykpKTsKKyAgICAgICAgICAgIHdpbGwocmV0dXJuVmFsdWUobmV3IFZhbHVlSW1wbChQcm9wZXJ0eVR5cGUuTE9ORykpKTsKKyAgICAgICAgICAgIGFsbG93aW5nKGZhY3RvcnkpLmNyZWF0ZVZhbHVlKHdpdGgoYW55KFN0cmluZy5jbGFzcykpKTsKKyAgICAgICAgICAgIHdpbGwocmV0dXJuVmFsdWUobmV3IFZhbHVlSW1wbChQcm9wZXJ0eVR5cGUuU1RSSU5HKSkpOworICAgICAgICAgICAgYWxsb3dpbmcoZmFjdG9yeSkuY3JlYXRlVmFsdWUod2l0aChhbnkoQ2FsZW5kYXIuY2xhc3MpKSk7CisgICAgICAgICAgICB3aWxsKHJldHVyblZhbHVlKG5ldyBWYWx1ZUltcGwoUHJvcGVydHlUeXBlLkRBVEUpKSk7CisgICAgICAgIH19KTsKKyAgICAgICAgLy8gYm9vbGVhbgorICAgICAgICBhc3NlcnRFcXVhbHMoUHJvcGVydHlUeXBlLkJPT0xFQU4sIEV2ZW50VXRpbC5nZXROb2RlUHJvcGVydHlWYWx1ZShmYWN0b3J5LCB0cnVlKS5nZXRUeXBlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoUHJvcGVydHlUeXBlLkJPT0xFQU4sIEV2ZW50VXRpbC5nZXROb2RlUHJvcGVydHlWYWx1ZShmYWN0b3J5LCBmYWxzZSkuZ2V0VHlwZSgpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKFByb3BlcnR5VHlwZS5CT09MRUFOLCBFdmVudFV0aWwuZ2V0Tm9kZVByb3BlcnR5VmFsdWUoZmFjdG9yeSwgQm9vbGVhbi5UUlVFKS5nZXRUeXBlKCkpOworICAgICAgICBhc3NlcnRFcXVhbHMoUHJvcGVydHlUeXBlLkJPT0xFQU4sIEV2ZW50VXRpbC5nZXROb2RlUHJvcGVydHlWYWx1ZShmYWN0b3J5LCBCb29sZWFuLkZBTFNFKS5nZXRUeXBlKCkpOworICAgICAgICAvLyBsb25nCisgICAgICAgIGFzc2VydEVxdWFscyhQcm9wZXJ0eVR5cGUuTE9ORywgRXZlbnRVdGlsLmdldE5vZGVQcm9wZXJ0eVZhbHVlKGZhY3RvcnksIChsb25nKTUpLmdldFR5cGUoKSk7CisgICAgICAgIC8vIGludCA9IG5vdCBwb3NzaWJsZQorICAgICAgICBhc3NlcnRFcXVhbHMobnVsbCwgRXZlbnRVdGlsLmdldE5vZGVQcm9wZXJ0eVZhbHVlKGZhY3RvcnksIDUpKTsKKyAgICAgICAgLy8gc3RyaW5nCisgICAgICAgIGFzc2VydEVxdWFscyhQcm9wZXJ0eVR5cGUuU1RSSU5HLCBFdmVudFV0aWwuZ2V0Tm9kZVByb3BlcnR5VmFsdWUoZmFjdG9yeSwgInNvbWV0aGluZyIpLmdldFR5cGUoKSk7CisgICAgICAgIC8vIGNhbGVuZGFyCisgICAgICAgIGFzc2VydEVxdWFscyhQcm9wZXJ0eVR5cGUuREFURSwgRXZlbnRVdGlsLmdldE5vZGVQcm9wZXJ0eVZhbHVlKGZhY3RvcnksIENhbGVuZGFyLmdldEluc3RhbmNlKCkpLmdldFR5cGUoKSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgY2xhc3MgVmFsdWVJbXBsIGltcGxlbWVudHMgVmFsdWUgeworCisgICAgICAgIHByaXZhdGUgZmluYWwgaW50IHR5cGU7CisKKyAgICAgICAgcHVibGljIFZhbHVlSW1wbChpbnQgdHlwZSkgeworICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBib29sZWFuIGdldEJvb2xlYW4oKSB0aHJvd3MgVmFsdWVGb3JtYXRFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgSWxsZWdhbFN0YXRlRXhjZXB0aW9uLCBSZXBvc2l0b3J5RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBDYWxlbmRhciBnZXREYXRlKCkgdGhyb3dzIFZhbHVlRm9ybWF0RXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiwgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0RG91YmxlKCkgdGhyb3dzIFZhbHVlRm9ybWF0RXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiwgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBsb25nIGdldExvbmcoKSB0aHJvd3MgVmFsdWVGb3JtYXRFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgSWxsZWdhbFN0YXRlRXhjZXB0aW9uLCBSZXBvc2l0b3J5RXhjZXB0aW9uIHsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIElucHV0U3RyZWFtIGdldFN0cmVhbSgpIHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U3RyaW5nKCkgdGhyb3dzIFZhbHVlRm9ybWF0RXhjZXB0aW9uLAorICAgICAgICAgICAgICAgIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiwgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBpbnQgZ2V0VHlwZSgpIHsKKyAgICAgICAgICAgIHJldHVybiB0aGlzLnR5cGU7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvaW1wbC9BYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXJUZXN0LmphdmEgYi9zcmMvdGVzdC9qYXZhL29yZy9hcGFjaGUvc2xpbmcvZXZlbnQvaW1wbC9BYnN0cmFjdFJlcG9zaXRvcnlFdmVudEhhbmRsZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmIwZDgwMQotLS0gL2Rldi9udWxsCisrKyBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL0Fic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlclRlc3QuamF2YQpAQCAtMCwwICsxLDE3NyBAQAorLyoKKyAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKKyAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQorICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KKyAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKKyAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKKyAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKKyAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKKyAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCisgKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKKyAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQorICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucworICogdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2Ugb3JnLmFwYWNoZS5zbGluZy5ldmVudC5pbXBsOworCitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE5vdE51bGw7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VHJ1ZTsKKworaW1wb3J0IGphdmEudXRpbC5EaWN0aW9uYXJ5OworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CisKK2ltcG9ydCBqYXZheC5qY3IuTm9kZTsKK2ltcG9ydCBqYXZheC5qY3IuTm9kZUl0ZXJhdG9yOworaW1wb3J0IGphdmF4Lmpjci5SZXBvc2l0b3J5RXhjZXB0aW9uOworaW1wb3J0IGphdmF4Lmpjci5TZXNzaW9uOworaW1wb3J0IGphdmF4Lmpjci5vYnNlcnZhdGlvbi5FdmVudExpc3RlbmVySXRlcmF0b3I7CisKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmNvbW1vbnMudGVzdGluZy5qY3IuUmVwb3NpdG9yeVV0aWw7CitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5jb21tb25zLnRocmVhZHMuVGhyZWFkUG9vbENvbmZpZzsKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmVuZ2luZS5TbGluZ1NldHRpbmdzU2VydmljZTsKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LlRocmVhZFBvb2w7CitpbXBvcnQgb3JnLmFwYWNoZS5zbGluZy5qY3IuYXBpLlNsaW5nUmVwb3NpdG9yeTsKK2ltcG9ydCBvcmcuam1vY2suRXhwZWN0YXRpb25zOworaW1wb3J0IG9yZy5qbW9jay5Nb2NrZXJ5OworaW1wb3J0IG9yZy5qbW9jay5pbnRlZ3JhdGlvbi5qdW5pdDQuSk1vY2s7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVDb250ZXh0OworaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudENvbnRleHQ7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudDsKK2ltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmV2ZW50LkV2ZW50QWRtaW47CisKK0BSdW5XaXRoKEpNb2NrLmNsYXNzKQorcHVibGljIGFic3RyYWN0IGNsYXNzIEFic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlclRlc3QgeworCisgICAgcHJvdGVjdGVkIEFic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlciBoYW5kbGVyOworCisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVQT19QQVRIID0gIi90ZXN0L2V2ZW50cyI7CisgICAgcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0xJTkdfSUQgPSAiNDcxMSI7CisKKyAgICBwcm90ZWN0ZWQgc3RhdGljIFNlc3Npb24gc2Vzc2lvbjsKKworICAgIHByb3RlY3RlZCBhYnN0cmFjdCBNb2NrZXJ5IGdldE1vY2tlcnkoKTsKKworICAgIHByb3RlY3RlZCBEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBnZXRDb21wb25lbnRDb25maWcoKSB7CisgICAgICAgIGZpbmFsIERpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IGNvbmZpZyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CisgICAgICAgIGNvbmZpZy5wdXQoQWJzdHJhY3RSZXBvc2l0b3J5RXZlbnRIYW5kbGVyLkNPTkZJR19QUk9QRVJUWV9SRVBPX1BBVEgsIFJFUE9fUEFUSCk7CisKKyAgICAgICAgcmV0dXJuIGNvbmZpZzsKKyAgICB9CisKKyAgICBAb3JnLmp1bml0LkJlZm9yZUNsYXNzIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXR1cFJlcG9zaXRvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgUmVwb3NpdG9yeVV0aWwuc3RhcnRSZXBvc2l0b3J5KCk7CisgICAgICAgIGZpbmFsIFNsaW5nUmVwb3NpdG9yeSByZXBvc2l0b3J5ID0gUmVwb3NpdG9yeVV0aWwuZ2V0UmVwb3NpdG9yeSgpOworICAgICAgICBzZXNzaW9uID0gcmVwb3NpdG9yeS5sb2dpbkFkbWluaXN0cmF0aXZlKHJlcG9zaXRvcnkuZ2V0RGVmYXVsdFdvcmtzcGFjZSgpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShSZXBvc2l0b3J5VXRpbC5yZWdpc3Rlck5vZGVUeXBlKHNlc3Npb24sIERpc3RyaWJ1dGluZ0V2ZW50SGFuZGxlci5jbGFzcy5nZXRSZXNvdXJjZUFzU3RyZWFtKCIvU0xJTkctSU5GL25vZGV0eXBlcy9ldmVudC5jbmQiKSkpOworICAgICAgICBhc3NlcnRUcnVlKFJlcG9zaXRvcnlVdGlsLnJlZ2lzdGVyTm9kZVR5cGUoc2Vzc2lvbiwgRGlzdHJpYnV0aW5nRXZlbnRIYW5kbGVyLmNsYXNzLmdldFJlc291cmNlQXNTdHJlYW0oIi9TTElORy1JTkYvbm9kZXR5cGVzL2ZvbGRlci5jbmQiKSkpOworICAgIH0KKworICAgIEBvcmcuanVuaXQuQWZ0ZXJDbGFzcyBwdWJsaWMgc3RhdGljIHZvaWQgc2h1dGRvd25SZXBvc2l0b3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgICAgIFJlcG9zaXRvcnlVdGlsLnN0b3BSZXBvc2l0b3J5KCk7CisgICAgfQorCisgICAgQG9yZy5qdW5pdC5CZWZvcmUgcHVibGljIHZvaWQgc2V0dXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgdGhpcy5oYW5kbGVyLnJlcG9zaXRvcnkgPSBSZXBvc2l0b3J5VXRpbC5nZXRSZXBvc2l0b3J5KCk7CisKKyAgICAgICAgLy8gdGhlIGV2ZW50IGFkbWluCisgICAgICAgIGZpbmFsIEV2ZW50QWRtaW4gZXZlbnRBZG1pbiA9IHRoaXMuZ2V0TW9ja2VyeSgpLm1vY2soRXZlbnRBZG1pbi5jbGFzcyk7CisgICAgICAgIHRoaXMuaGFuZGxlci5ldmVudEFkbWluID0gZXZlbnRBZG1pbjsKKyAgICAgICAgdGhpcy5nZXRNb2NrZXJ5KCkuY2hlY2tpbmcobmV3IEV4cGVjdGF0aW9ucygpIHt7CisgICAgICAgICAgICBhbGxvd2luZyhldmVudEFkbWluKS5wb3N0RXZlbnQod2l0aChhbnkoRXZlbnQuY2xhc3MpKSk7CisgICAgICAgICAgICBhbGxvd2luZyhldmVudEFkbWluKS5zZW5kRXZlbnQod2l0aChhbnkoRXZlbnQuY2xhc3MpKSk7CisgICAgICAgIH19KTsKKworICAgICAgICAvLyBzbGluZyBzZXR0aW5ncyBzZXJ2aWNlCisgICAgICAgIHRoaXMuaGFuZGxlci5zZXR0aW5nc1NlcnZpY2UgPSBuZXcgU2xpbmdTZXR0aW5nc1NlcnZpY2UoKSB7CisgICAgICAgICAgICBwdWJsaWMgU3RyaW5nIGdldFNsaW5nSWQoKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIFNMSU5HX0lEOworICAgICAgICAgICAgfQorICAgICAgICB9OworCisgICAgICAgIC8vIHdlIG5lZWQgYSB0aHJlYWQgcG9vbAorICAgICAgICB0aGlzLmhhbmRsZXIudGhyZWFkUG9vbCA9IG5ldyBUaHJlYWRQb29sSW1wbCgpOworCisgICAgICAgIC8vIGxldHMgc2V0IHVwIHRoZSBidW5kbGUgY29udGV4dAorICAgICAgICBmaW5hbCBCdW5kbGVDb250ZXh0IGJ1bmRsZUNvbnRleHQgPSB0aGlzLmdldE1vY2tlcnkoKS5tb2NrKEJ1bmRsZUNvbnRleHQuY2xhc3MpOworCisgICAgICAgIC8vIGxldHMgc2V0IHVwIHRoZSBjb21wb25lbnQgY29uZmlndXJhdGlvbgorICAgICAgICBmaW5hbCBEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBjb21wb25lbnRDb25maWcgPSB0aGlzLmdldENvbXBvbmVudENvbmZpZygpOworCisgICAgICAgIC8vIGxldHMgc2V0IHVwIHRoZSBjb21wbmVudCBjb250ZXh0CisgICAgICAgIGZpbmFsIENvbXBvbmVudENvbnRleHQgY29tcG9uZW50Q29udGV4dCA9IHRoaXMuZ2V0TW9ja2VyeSgpLm1vY2soQ29tcG9uZW50Q29udGV4dC5jbGFzcyk7CisgICAgICAgIHRoaXMuZ2V0TW9ja2VyeSgpLmNoZWNraW5nKG5ldyBFeHBlY3RhdGlvbnMoKSB7eworICAgICAgICAgICAgYWxsb3dpbmcoY29tcG9uZW50Q29udGV4dCkuZ2V0QnVuZGxlQ29udGV4dCgpOworICAgICAgICAgICAgd2lsbChyZXR1cm5WYWx1ZShidW5kbGVDb250ZXh0KSk7CisgICAgICAgICAgICBhbGxvd2luZyhjb21wb25lbnRDb250ZXh0KS5nZXRQcm9wZXJ0aWVzKCk7CisgICAgICAgICAgICB3aWxsKHJldHVyblZhbHVlKGNvbXBvbmVudENvbmZpZykpOworICAgICAgICB9fSk7CisKKyAgICAgICAgdGhpcy5oYW5kbGVyLmFjdGl2YXRlKGNvbXBvbmVudENvbnRleHQpOworICAgICAgICAvLyB0aGUgc2Vzc2lvbiBpcyBpbml0aWFsaXplZCBpbiB0aGUgYmFja2dyb3VuZCwgc28gbGV0J3Mgc2xlZXAgc29tZSBzZWNvbmRzCisgICAgICAgIFRocmVhZC5zbGVlcCgyICogMTAwMCk7CisgICAgfQorCisgICAgQG9yZy5qdW5pdC5BZnRlciBwdWJsaWMgdm9pZCBzaHV0ZG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgICAgICAvLyBkZWxldGUgYWxsIGNoaWxkIG5vZGVzIHRvIGdldCBhIGNsZWFuIHJlcG9zaXRvcnkgYWdhaW4KKyAgICAgICAgZmluYWwgTm9kZSByb290Tm9kZSA9IChOb2RlKSBzZXNzaW9uLmdldEl0ZW0odGhpcy5oYW5kbGVyLnJlcG9zaXRvcnlQYXRoKTsKKyAgICAgICAgZmluYWwgTm9kZUl0ZXJhdG9yIGl0ZXIgPSByb290Tm9kZS5nZXROb2RlcygpOworICAgICAgICB3aGlsZSAoIGl0ZXIuaGFzTmV4dCgpICkgeworICAgICAgICAgICAgZmluYWwgTm9kZSBjaGlsZCA9IGl0ZXIubmV4dE5vZGUoKTsKKyAgICAgICAgICAgIGNoaWxkLnJlbW92ZSgpOworICAgICAgICB9CisgICAgICAgIHJvb3ROb2RlLnNhdmUoKTsKKyAgICAgICAgLy8gbGV0cyBzZXQgdXAgdGhlIGJ1bmRsZSBjb250ZXh0IHdpdGggdGhlIHNsaW5nIGlkCisgICAgICAgIGZpbmFsIEJ1bmRsZUNvbnRleHQgYnVuZGxlQ29udGV4dCA9IHRoaXMuZ2V0TW9ja2VyeSgpLm1vY2soQnVuZGxlQ29udGV4dC5jbGFzcyk7CisKKyAgICAgICAgZmluYWwgQ29tcG9uZW50Q29udGV4dCBjb21wb25lbnRDb250ZXh0ID0gdGhpcy5nZXRNb2NrZXJ5KCkubW9jayhDb21wb25lbnRDb250ZXh0LmNsYXNzKTsKKyAgICAgICAgdGhpcy5nZXRNb2NrZXJ5KCkuY2hlY2tpbmcobmV3IEV4cGVjdGF0aW9ucygpIHt7CisgICAgICAgICAgICBhbGxvd2luZyhjb21wb25lbnRDb250ZXh0KS5nZXRCdW5kbGVDb250ZXh0KCk7CisgICAgICAgICAgICB3aWxsKHJldHVyblZhbHVlKGJ1bmRsZUNvbnRleHQpKTsKKyAgICAgICAgfX0pOworICAgICAgICB0aGlzLmhhbmRsZXIuZGVhY3RpdmF0ZShjb21wb25lbnRDb250ZXh0KTsKKyAgICB9CisKKyAgICBAb3JnLmp1bml0LlRlc3QgcHVibGljIHZvaWQgdGVzdFNldHVwKCkgdGhyb3dzIFJlcG9zaXRvcnlFeGNlcHRpb24geworICAgICAgICBhc3NlcnRFcXVhbHModGhpcy5oYW5kbGVyLmFwcGxpY2F0aW9uSWQsIFNMSU5HX0lEKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKHRoaXMuaGFuZGxlci5yZXBvc2l0b3J5UGF0aCwgUkVQT19QQVRIKTsKKyAgICAgICAgYXNzZXJ0Tm90TnVsbCh0aGlzLmhhbmRsZXIud3JpdGVyU2Vzc2lvbik7CisgICAgICAgIGZpbmFsIEV2ZW50TGlzdGVuZXJJdGVyYXRvciBpdGVyID0gdGhpcy5oYW5kbGVyLndyaXRlclNlc3Npb24uZ2V0V29ya3NwYWNlKCkuZ2V0T2JzZXJ2YXRpb25NYW5hZ2VyKCkuZ2V0UmVnaXN0ZXJlZEV2ZW50TGlzdGVuZXJzKCk7CisgICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKKyAgICAgICAgd2hpbGUgKCAhZm91bmQgJiYgaXRlci5oYXNOZXh0KCkgKSB7CisgICAgICAgICAgICBmaW5hbCBqYXZheC5qY3Iub2JzZXJ2YXRpb24uRXZlbnRMaXN0ZW5lciBsaXN0ZW5lciA9IGl0ZXIubmV4dEV2ZW50TGlzdGVuZXIoKTsKKyAgICAgICAgICAgIGZvdW5kID0gKGxpc3RlbmVyID09IHRoaXMuaGFuZGxlcik7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0VHJ1ZSgiSGFuZGxlciBpcyBub3QgcmVnaXN0ZXJlZCBhcyBldmVudCBsaXN0ZW5lci4iLCBmb3VuZCk7CisgICAgfQorCisgICAgQG9yZy5qdW5pdC5UZXN0IHB1YmxpYyB2b2lkIHRlc3RQYXRoQ3JlYXRpb24oKSB0aHJvd3MgUmVwb3NpdG9yeUV4Y2VwdGlvbiB7CisgICAgICAgIGFzc2VydFRydWUoc2Vzc2lvbi5pdGVtRXhpc3RzKFJFUE9fUEFUSCkpOworICAgIH0KKworICAgIGZpbmFsIGNsYXNzIFRocmVhZFBvb2xJbXBsIGltcGxlbWVudHMgVGhyZWFkUG9vbCB7CisKKyAgICAgICAgcHVibGljIHZvaWQgZXhlY3V0ZShSdW5uYWJsZSBydW5uYWJsZSkgeworICAgICAgICAgICAgZmluYWwgVGhyZWFkIHQgPSBuZXcgVGhyZWFkKHJ1bm5hYmxlKTsKKyAgICAgICAgICAgIHQuc3RhcnQoKTsKKyAgICAgICAgfQorCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKKyAgICAgICAgICAgIHJldHVybiBFdmVudEhlbHBlci5USFJFQURfUE9PTF9OQU1FOworICAgICAgICB9CisKKyAgICAgICAgcHVibGljIHZvaWQgc2h1dGRvd24oKSB7CisgICAgICAgICAgICAvLyBub3RoaW5nIHRvIGRvCisgICAgICAgIH0KKworICAgICAgICBwdWJsaWMgVGhyZWFkUG9vbENvbmZpZyBnZXRDb25maWd1cmF0aW9uKCkgeworICAgICAgICAgICAgcmV0dXJuIG5ldyBUaHJlYWRQb29sQ29uZmlnKCk7CisgICAgICAgIH0KKworICAgIH0KK30KZGlmZiAtLWdpdCBhL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL0Rpc3RyaWJ1dGluZ0V2ZW50SGFuZGxlclRlc3QuamF2YSBiL3NyYy90ZXN0L2phdmEvb3JnL2FwYWNoZS9zbGluZy9ldmVudC9pbXBsL0Rpc3RyaWJ1dGluZ0V2ZW50SGFuZGxlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YWQ5NmQ0Ci0tLSAvZGV2L251bGwKKysrIGIvc3JjL3Rlc3QvamF2YS9vcmcvYXBhY2hlL3NsaW5nL2V2ZW50L2ltcGwvRGlzdHJpYnV0aW5nRXZlbnRIYW5kbGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsODkgQEAKKy8qCisgKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCisgKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKKyAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCisgKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCisgKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCisgKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCisgKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCisgKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgorICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCisgKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKKyAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKKyAqIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIG9yZy5hcGFjaGUuc2xpbmcuZXZlbnQuaW1wbDsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydEVxdWFsczsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworCitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5EaWN0aW9uYXJ5OworaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CisKK2ltcG9ydCBqYXZheC5qY3IuTm9kZTsKK2ltcG9ydCBqYXZheC5qY3IuTm9kZUl0ZXJhdG9yOworCitpbXBvcnQgb3JnLmFwYWNoZS5qYWNrcmFiYml0LnV0aWwuSVNPOTA3NTsKK2ltcG9ydCBvcmcuYXBhY2hlLnNsaW5nLmV2ZW50LkV2ZW50VXRpbDsKK2ltcG9ydCBvcmcuam1vY2suTW9ja2VyeTsKK2ltcG9ydCBvcmcuam1vY2suaW50ZWdyYXRpb24uanVuaXQ0LkpNb2NrOworaW1wb3J0IG9yZy5qbW9jay5pbnRlZ3JhdGlvbi5qdW5pdDQuSlVuaXQ0TW9ja2VyeTsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5ldmVudC5FdmVudDsKKworQFJ1bldpdGgoSk1vY2suY2xhc3MpCitwdWJsaWMgY2xhc3MgRGlzdHJpYnV0aW5nRXZlbnRIYW5kbGVyVGVzdCBleHRlbmRzIEFic3RyYWN0UmVwb3NpdG9yeUV2ZW50SGFuZGxlclRlc3QgeworCisgICAgcHJvdGVjdGVkIE1vY2tlcnkgY29udGV4dDsKKworICAgIHB1YmxpYyBEaXN0cmlidXRpbmdFdmVudEhhbmRsZXJUZXN0KCkgeworICAgICAgICB0aGlzLmhhbmRsZXIgPSBuZXcgRGlzdHJpYnV0aW5nRXZlbnRIYW5kbGVyKCk7CisgICAgICAgIHRoaXMuY29udGV4dCA9IG5ldyBKVW5pdDRNb2NrZXJ5KCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVjdGVkIE1vY2tlcnkgZ2V0TW9ja2VyeSgpIHsKKyAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dDsKKyAgICB9CisKKyAgICBAb3JnLmp1bml0LlRlc3QgcHVibGljIHZvaWQgdGVzdFdyaXRlRXZlbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIHRvcGljID0gIndyaXRlL2V2ZW50L3Rlc3QiOworICAgICAgICBmaW5hbCBEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CisgICAgICAgIHByb3BzLnB1dCgiYSBwcm9wZXJ0eSIsICJzb21lIHZhbHVlIik7CisgICAgICAgIGZpbmFsIEV2ZW50IGUgPSBuZXcgRXZlbnQodG9waWMsIHByb3BzKTsKKyAgICAgICAgdGhpcy5oYW5kbGVyLndyaXRlRXZlbnQoZSwgbnVsbCk7CisKKyAgICAgICAgZmluYWwgTm9kZSByb290Tm9kZSA9IChOb2RlKSBzZXNzaW9uLmdldEl0ZW0odGhpcy5oYW5kbGVyLnJlcG9zaXRvcnlQYXRoKTsKKyAgICAgICAgZmluYWwgTm9kZUl0ZXJhdG9yIGl0ZXIgPSByb290Tm9kZS5nZXROb2RlcygpOworICAgICAgICBpdGVyLmhhc05leHQoKTsKKyAgICAgICAgZmluYWwgTm9kZSBldmVudE5vZGUgPSBpdGVyLm5leHROb2RlKCk7CisgICAgICAgIGFzc2VydEVxdWFscyh0b3BpYywgZXZlbnROb2RlLmdldFByb3BlcnR5KEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfVE9QSUMpLmdldFN0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0RXF1YWxzKGhhbmRsZXIuYXBwbGljYXRpb25JZCwgZXZlbnROb2RlLmdldFByb3BlcnR5KEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfQVBQTElDQVRJT04pLmdldFN0cmluZygpKTsKKyAgICAgICAgYXNzZXJ0VHJ1ZShDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmNvbXBhcmVUbyhldmVudE5vZGUuZ2V0UHJvcGVydHkoRXZlbnRIZWxwZXIuTk9ERV9QUk9QRVJUWV9DUkVBVEVEKS5nZXREYXRlKCkpID49IDApOworICAgICAgICAvLyBhcyBhIHN0YXJ0aW5nIHBvaW50IHdlIGp1c3QgY2hlY2sgaWYgdGhlIHByb3BlcnRpZXMgcHJvcGVydHkgZXhpc3RzCisgICAgICAgIGFzc2VydFRydWUoZXZlbnROb2RlLmhhc1Byb3BlcnR5KElTTzkwNzUuZW5jb2RlKCJhIHByb3BlcnR5IikpKTsKKyAgICB9CisKKyAgICBAb3JnLmp1bml0LlRlc3QgcHVibGljIHZvaWQgdGVzdFdyaXRlRXZlbnRQbHVzQXBwSWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgICAgZmluYWwgU3RyaW5nIHRvcGljID0gIndyaXRlL2V2ZW50L3Rlc3QiOworICAgICAgICBmaW5hbCBEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CisgICAgICAgIHByb3BzLnB1dCgiYSBwcm9wZXJ0eSIsICJzb21lIHZhbHVlIik7CisgICAgICAgIC8vIG5vdyB3ZSBjaGVjayBpZiB0aGUgYXBwbGljYXRpb24gaWQgaXMgaGFuZGxlZCBjb3JyZWN0bHkKKyAgICAgICAgcHJvcHMucHV0KEV2ZW50VXRpbC5QUk9QRVJUWV9BUFBMSUNBVElPTiwgImZvbyIpOworICAgICAgICB0aGlzLmhhbmRsZXIud3JpdGVFdmVudChuZXcgRXZlbnQodG9waWMsIHByb3BzKSwgbnVsbCk7CisgICAgICAgIGZpbmFsIE5vZGUgcm9vdE5vZGUgPSAoTm9kZSkgc2Vzc2lvbi5nZXRJdGVtKHRoaXMuaGFuZGxlci5yZXBvc2l0b3J5UGF0aCk7CisgICAgICAgIGZpbmFsIE5vZGVJdGVyYXRvciBpdGVyID0gcm9vdE5vZGUuZ2V0Tm9kZXMoKTsKKyAgICAgICAgaXRlci5oYXNOZXh0KCk7CisgICAgICAgIGZpbmFsIE5vZGUgZXZlbnROb2RlID0gaXRlci5uZXh0Tm9kZSgpOworICAgICAgICBhc3NlcnRFcXVhbHModG9waWMsIGV2ZW50Tm9kZS5nZXRQcm9wZXJ0eShFdmVudEhlbHBlci5OT0RFX1BST1BFUlRZX1RPUElDKS5nZXRTdHJpbmcoKSk7CisgICAgICAgIGFzc2VydEVxdWFscyhoYW5kbGVyLmFwcGxpY2F0aW9uSWQsIGV2ZW50Tm9kZS5nZXRQcm9wZXJ0eShFdmVudEhlbHBlci5OT0RFX1BST1BFUlRZX0FQUExJQ0FUSU9OKS5nZXRTdHJpbmcoKSk7CisgICAgICAgIGFzc2VydFRydWUoQ2FsZW5kYXIuZ2V0SW5zdGFuY2UoKS5jb21wYXJlVG8oZXZlbnROb2RlLmdldFByb3BlcnR5KEV2ZW50SGVscGVyLk5PREVfUFJPUEVSVFlfQ1JFQVRFRCkuZ2V0RGF0ZSgpKSA+PSAwKTsKKyAgICAgICAgLy8gYXMgYSBzdGFydGluZyBwb2ludCB3ZSBqdXN0IGNoZWNrIGlmIHRoZSBwcm9wZXJ0aWVzIHByb3BlcnR5IGV4aXN0cworICAgICAgICBhc3NlcnRUcnVlKGV2ZW50Tm9kZS5oYXNQcm9wZXJ0eShJU085MDc1LmVuY29kZSgiYSBwcm9wZXJ0eSIpKSk7CisgICAgfQorfQo=