LyoKICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQogKgogKiBDb3B5cmlnaHQgKGMpIDE5OTkgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgQWxsIHJpZ2h0cwogKiByZXNlcnZlZC4KICoKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwogKiBhcmUgbWV0OgogKgogKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAqCiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbgogKiAgICB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCiAqICAgIGRpc3RyaWJ1dGlvbi4KICoKICogMy4gVGhlIGVuZC11c2VyIGRvY3VtZW50YXRpb24gaW5jbHVkZWQgd2l0aCB0aGUgcmVkaXN0cmlidXRpb24sIGlmCiAqICAgIGFueSwgbXVzdCBpbmNsdWRlIHRoZSBmb2xsb3dpbmcgYWNrbm93bGVnZW1lbnQ6CiAqICAgICAgICJUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZQogKiAgICAgICAgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKGh0dHA6Ly93d3cuYXBhY2hlLm9yZy8pLiIKICogICAgQWx0ZXJuYXRlbHksIHRoaXMgYWNrbm93bGVnZW1lbnQgbWF5IGFwcGVhciBpbiB0aGUgc29mdHdhcmUgaXRzZWxmLAogKiAgICBpZiBhbmQgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBhY2tub3dsZWdlbWVudHMgbm9ybWFsbHkgYXBwZWFyLgogKgogKiA0LiBUaGUgbmFtZXMgIlRoZSBKYWthcnRhIFByb2plY3QiLCAiVG9tY2F0IiwgYW5kICJBcGFjaGUgU29mdHdhcmUKICogICAgRm91bmRhdGlvbiIgbXVzdCBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZAogKiAgICBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uIEZvciB3cml0dGVuCiAqICAgIHBlcm1pc3Npb24sIHBsZWFzZSBjb250YWN0IGFwYWNoZUBhcGFjaGUub3JnLgogKgogKiA1LiBQcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSBtYXkgbm90IGJlIGNhbGxlZCAiQXBhY2hlIgogKiAgICBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lcyB3aXRob3V0IHByaW9yIHdyaXR0ZW4KICogICAgcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIEdyb3VwLgogKgogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECiAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCiAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAogKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCiAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAogKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCiAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCiAqIGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQogKiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCiAqLwpwYWNrYWdlIG9yZy5hcGFjaGUudG9vbHMuYW50LnRhc2tkZWZzLm9wdGlvbmFsOwoKCgoKCgppbXBvcnQgamF2YS5pby5GaWxlOwppbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsKaW1wb3J0IGphdmEudXRpbC5EYXRlOwppbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC5CdWlsZEV2ZW50OwppbXBvcnQgb3JnLmFwYWNoZS50b29scy5hbnQuQnVpbGRFeGNlcHRpb247CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC5CdWlsZExpc3RlbmVyOwppbXBvcnQgb3JnLmFwYWNoZS50b29scy5hbnQuRGlyZWN0b3J5U2Nhbm5lcjsKaW1wb3J0IG9yZy5hcGFjaGUudG9vbHMuYW50LlByb2plY3Q7CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC50YXNrZGVmcy5KYXZhOwppbXBvcnQgb3JnLmFwYWNoZS50b29scy5hbnQudGFza2RlZnMuSmF2YWM7CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC50YXNrZGVmcy5NYXRjaGluZ1Rhc2s7CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC50YXNrZGVmcy5Na2RpcjsKaW1wb3J0IG9yZy5hcGFjaGUudG9vbHMuYW50LnRhc2tkZWZzLmNvbXBpbGVycy5EZWZhdWx0Q29tcGlsZXJBZGFwdGVyOwppbXBvcnQgb3JnLmFwYWNoZS50b29scy5hbnQudHlwZXMuRmlsZVNldDsKaW1wb3J0IG9yZy5hcGFjaGUudG9vbHMuYW50LnR5cGVzLlBhdGg7CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC50eXBlcy5SZWZlcmVuY2U7CgovKioKICogSW5zdHJ1bWVudHMgSmF2YSBjbGFzc2VzIHdpdGggPGEgaHJlZj0iaHR0cDovL3d3dy5yZWxpYWJsZS1zeXN0ZW1zLmNvbS90b29scy8iPmlDb250cmFjdDwvYT4KICogREJDIHByZXByb2Nlc3Nvci4KICogPGJyLz4KICogVGhlIHRhc2sgY2FuIGdlbmVyYXRlIGEgcHJvcGVydGllcyBmaWxlIGZvciA8YSBocmVmPSJodHRwOi8vaGplbS5zb2wubm8vaGVsbGVzb3kvaWNvbnRyb2wuaHRtbCI+aUNvbnRyb2w8L2E+LAogKiBhIGdyYXBoaWNhbCB1c2VyIGludGVyZmFjZSB0aGF0IGxldHMgeW91IHR1cm4gb24vb2ZmIGFzc2VydGlvbnMuIGlDb250cm9sIGdlbmVyYXRlcyBhIGNvbnRyb2wgZmlsZSB0aGF0IHlvdSBjYW4gcmVmZXIgdG8KICogZnJvbSB0aGlzIHRhc2sgdXNpbmcgdGhlIGNvbnRyb2xmaWxlIGF0dHJpYnV0ZS4KICogPHAvPgogKiBUaGFua3MgdG8gUmFpbmVyIFNjaG1pdHogZm9yIGVuaGFuY2VtZW50cyBhbmQgY29tbWVudHMuCiAqCiAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmFzbGFrLmhlbGxlc295QGJla2subm8iPkFzbGFrIEhlbGxlc/h5PC9hPgogKgogKiA8cC8+CiAqIDx0YWJsZSBib3JkZXI9IjEiIGNlbGxwYWRkaW5nPSIyIiBjZWxsc3BhY2luZz0iMCI+CiAqICAgPHRyPgogKiAgICAgPHRkIHZhbGlnbj0idG9wIj48Yj5BdHRyaWJ1dGU8L2I+PC90ZD4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+PGI+RGVzY3JpcHRpb248L2I+PC90ZD4KICogICAgIDx0ZCBhbGlnbj0iY2VudGVyIiB2YWxpZ249InRvcCI+PGI+UmVxdWlyZWQ8L2I+PC90ZD4KICogICA8L3RyPgogKiAgIDx0cj4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+c3JjZGlyPC90ZD4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+TG9jYXRpb24gb2YgdGhlIGphdmEgZmlsZXMuPC90ZD4KICogICAgIDx0ZCB2YWxpZ249InRvcCIgYWxpZ249ImNlbnRlciI+WWVzPC90ZD4KICogICA8L3RyPgogKiAgIDx0cj4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+aW5zdHJ1bWVudGRpcjwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPkluZGljYXRlcyB3aGVyZSB0aGUgaW5zdHJ1bWVudGVkIHNvdXJjZSBmaWxlcyBzaG91bGQgZ28uPC90ZD4KICogICAgIDx0ZCB2YWxpZ249InRvcCIgYWxpZ249ImNlbnRlciI+WWVzPC90ZD4KICogICA8L3RyPgogKiAgIDx0cj4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+cmVwb3NpdG9yeWRpcjwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPkluZGljYXRlcyB3aGVyZSB0aGUgcmVwb3NpdG9yeSBzb3VyY2UgZmlsZXMgc2hvdWxkIGdvLjwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiIGFsaWduPSJjZW50ZXIiPlllczwvdGQ+CiAqICAgPC90cj4KICogICA8dHI+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPmJ1aWxkZGlyPC90ZD4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+SW5kaWNhdGVzIHdoZXJlIHRoZSBjb21waWxlZCBpbnN0cnVtZW50ZWQgY2xhc3NlcyBzaG91bGQgZ28uCiAqICAgICAgIERlZmF1bHRzIHRvIHRoZSB2YWx1ZSBvZiBpbnN0cnVtZW50ZGlyLgogKiAgICAgICA8L3A+CiAqICAgICAgIDxlbT5OT1RFOjwvZW0+IERvbid0IHVzZSB0aGUgc2FtZSBkaXJlY3RvcnkgZm9yIGNvbXBpbGVkIGluc3RydW1lbnRlZCBjbGFzc2VzCiAqICAgICAgIGFuZCB1bmluc3RydW1lbnRlZCBjbGFzc2VzLiBJdCB3aWxsIGJyZWFrIHRoZSBkZXBlbmRlbmN5IGNoZWNraW5nLiAoQ2xhc3NlcyB3aWxsCiAqICAgICAgIG5vdCBiZSByZWluc3RydW1lbnRlZCBpZiB5b3UgY2hhbmdlIHRoZW0pLjwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiIGFsaWduPSJjZW50ZXIiPk5vPC90ZD4KICogICA8L3RyPgogKiAgIDx0cj4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+cmVwb3NpdG9yeWJ1aWxkZGlyPC90ZD4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+SW5kaWNhdGVzIHdoZXJlIHRoZSBjb21waWxlZCByZXBvc2l0b3J5IGNsYXNzZXMgc2hvdWxkIGdvLgogKiAgICAgICBEZWZhdWx0cyB0byB0aGUgdmFsdWUgb2YgcmVwb3NpdG9yeWRpci48L3RkPgogKiAgICAgPHRkIHZhbGlnbj0idG9wIiBhbGlnbj0iY2VudGVyIj5ObzwvdGQ+CiAqICAgPC90cj4KICogICA8dHI+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPnByZTwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPkluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0byBpbnN0cnVtZW50IGZvciBwcmVjb25kaXRpb25zLgogKiAgICAgICBEZWZhdWx0cyB0byA8Y29kZT50cnVlPC9jb2RlPiB1bmxlc3MgY29udHJvbGZpbGUgaXMgc3BlY2lmaWVkLCBpbiB3aGljaCBjYXNlIGl0CiAqICAgICAgIGRlZmF1bHRzIHRvIDxjb2RlPmZhbHNlPC9jb2RlPi48L3RkPgogKiAgICAgPHRkIHZhbGlnbj0idG9wIiBhbGlnbj0iY2VudGVyIj5ObzwvdGQ+CiAqICAgPC90cj4KICogICA8dHI+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPnBvc3Q8L3RkPgogKiAgICAgPHRkIHZhbGlnbj0idG9wIj5JbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdG8gaW5zdHJ1bWVudCBmb3IgcG9zdGNvbmRpdGlvbnMuCiAqICAgICAgIERlZmF1bHRzIHRvIDxjb2RlPnRydWU8L2NvZGU+IHVubGVzcyBjb250cm9sZmlsZSBpcyBzcGVjaWZpZWQsIGluIHdoaWNoIGNhc2UgaXQKICogICAgICAgZGVmYXVsdHMgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LjwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiIGFsaWduPSJjZW50ZXIiPk5vPC90ZD4KICogICA8L3RyPgogKiAgIDx0cj4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+aW52YXJpYW50PC90ZD4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+SW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRvIGluc3RydW1lbnQgZm9yIGludmFyaWFudHMuCiAqICAgICAgIERlZmF1bHRzIHRvIDxjb2RlPnRydWU8L2NvZGU+IHVubGVzcyBjb250cm9sZmlsZSBpcyBzcGVjaWZpZWQsIGluIHdoaWNoIGNhc2UgaXQKICogICAgICAgZGVmYXVsdHMgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LjwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiIGFsaWduPSJjZW50ZXIiPk5vPC90ZD4KICogICA8L3RyPgogKiAgIDx0cj4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+ZmFpbHRocm93YWJsZTwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPlRoZSBmdWxsIG5hbWUgb2YgdGhlIFRocm93YWJsZSAoRXhjZXB0aW9uKSB0aGF0IHNob3VsZCBiZQogKiAgICAgICB0aHJvd24gd2hlbiBhbiBhc3NlcnRpb24gaXMgdmlvbGF0ZWQuIERlZmF1bHRzIHRvIDxjb2RlPmphdmEubGFuZy5FcnJvcjwvY29kZT48L3RkPgogKiAgICAgPHRkIHZhbGlnbj0idG9wIiBhbGlnbj0iY2VudGVyIj5ObzwvdGQ+CiAqICAgPC90cj4KICogICA8dHI+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPnZlcmJvc2l0eTwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPkluZGljYXRlcyB0aGUgdmVyYm9zaXR5IGxldmVsIG9mIGlDb250cmFjdC4gQW55IGNvbWJpbmF0aW9uCiAqICAgICAgIG9mIDxjb2RlPmVycm9yKix3YXJuaW5nKixub3RlKixpbmZvKixwcm9ncmVzcyosZGVidWcqPC9jb2RlPiAoY29tbWEgc2VwYXJhdGVkKSBjYW4gYmUKICogICAgICAgdXNlZC4gRGVmYXVsdHMgdG8gPGNvZGU+ZXJyb3IqPC9jb2RlPjwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiIGFsaWduPSJjZW50ZXIiPk5vPC90ZD4KICogICA8L3RyPgogKiAgIDx0cj4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+cXVpZXQ8L3RkPgogKiAgICAgPHRkIHZhbGlnbj0idG9wIj5JbmRpY2F0ZXMgaWYgaUNvbnRyYWN0IHNob3VsZCBiZSBxdWlldC4gVHVybiBpdCBvZmYgaWYgbWFueSB5b3VyIGNsYXNzZXMgZXh0ZW5kIHVuaW5zdHJ1bWVudGVkIGNsYXNzZXMKICogICAgIGFuZCB5b3UgZG9uJ3Qgd2FudCB3YXJuaW5ncyBhYm91dCB0aGlzLiBEZWZhdWx0cyB0byA8Y29kZT5mYWxzZTwvY29kZT48L3RkPgogKiAgICAgPHRkIHZhbGlnbj0idG9wIiBhbGlnbj0iY2VudGVyIj5ObzwvdGQ+CiAqICAgPC90cj4KICogICA8dHI+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPnVwZGF0ZWljb250cm9sPC90ZD4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+SWYgc2V0IHRvIHRydWUsIGl0IGluZGljYXRlcyB0aGF0IHRoZSBwcm9wZXJ0aWVzIGZpbGUgZm9yCiAqICAgICAgIGlDb250cm9sIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBzaG91bGQgYmUgdXBkYXRlZCAob3IgY3JlYXRlZCBpZiBpdCBkb2Vzbid0IGV4aXN0KS4KICogICAgICAgRGVmYXVsdHMgdG8gPGNvZGU+ZmFsc2U8L2NvZGU+LjwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiIGFsaWduPSJjZW50ZXIiPk5vPC90ZD4KICogICA8L3RyPgogKiAgIDx0cj4KICogICAgIDx0ZCB2YWxpZ249InRvcCI+Y29udHJvbGZpbGU8L3RkPgogKiAgICAgPHRkIHZhbGlnbj0idG9wIj5UaGUgbmFtZSBvZiB0aGUgY29udHJvbCBmaWxlIHRvIHBhc3MgdG8gaUNvbnRyYWN0LiBDb25zaWRlciB1c2luZyBpQ29udHJvbCB0byBnZW5lcmF0ZSB0aGUgZmlsZS4KICogICAgICAgRGVmYXVsdCBpcyBub3QgdG8gcGFzcyBhIGZpbGUuIDwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiIGFsaWduPSJjZW50ZXIiPk9ubHkgaWYgPGNvZGU+dXBkYXRlaWNvbnRyb2w9dHJ1ZTwvY29kZT48L3RkPgogKiAgIDwvdHI+CiAqICAgPHRyPgogKiAgICAgPHRkIHZhbGlnbj0idG9wIj5jbGFzc2RpcjwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPkluZGljYXRlcyB3aGVyZSBjb21waWxlZCAodW5pc3RydW1lbnRlZCkgY2xhc3NlcyBhcmUgbG9jYXRlZC4KICogICAgICAgVGhpcyBpcyByZXF1aXJlZCBpbiBvcmRlciB0byBwcm9wZXJseSB1cGRhdGUgdGhlIGljb250cm9sLnByb3BlcnRpZXMgZmlsZSwgbm90CiAqICAgICAgIGZvciBpbnN0cnVtZW50YXRpb24uPC90ZD4KICogICAgIDx0ZCB2YWxpZ249InRvcCIgYWxpZ249ImNlbnRlciI+T25seSBpZiA8Y29kZT51cGRhdGVpY29udHJvbD10cnVlPC9jb2RlPjwvdGQ+CiAqICAgPC90cj4KICogICA8dHI+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiPnRhcmdldHM8L3RkPgogKiAgICAgPHRkIHZhbGlnbj0idG9wIj5OYW1lIG9mIHRoZSBmaWxlIHRoYXQgd2lsbCBiZSBnZW5lcmF0ZWQgYnkgdGhpcyB0YXNrLCB3aGljaCBsaXN0cyBhbGwgdGhlCiAqICAgICAgICBjbGFzc2VzIHRoYXQgaUNvbnRyYWN0IHdpbGwgaW5zdHJ1bWVudC4gSWYgc3BlY2lmaWVkLCB0aGUgZmlsZSB3aWxsIG5vdCBiZSBkZWxldGVkIGFmdGVyIGV4ZWN1dGlvbi4KICogICAgICAgIElmIG5vdCBzcGVjaWZpZWQsIGEgZmlsZSB3aWxsIHN0aWxsIGJlIGNyZWF0ZWQsIGJ1dCBpdCB3aWxsIGJlIGRlbGV0ZWQgYWZ0ZXIgZXhlY3V0aW9uLjwvdGQ+CiAqICAgICA8dGQgdmFsaWduPSJ0b3AiIGFsaWduPSJjZW50ZXIiPk5vPC90ZD4KICogICA8L3RyPgogKiA8L3RhYmxlPgogKgogKiA8cC8+CiAqIDxiPk5vdGU6PC9iPiBpQ29udHJhY3Qgd2lsbCB1c2UgdGhlIGphdmEgY29tcGlsZXIgaW5kaWNhdGVkIGJ5IHRoZSBwcm9qZWN0J3MKICogPGNvZGU+YnVpbGQuY29tcGlsZXI8L2NvZGU+IHByb3BlcnR5LiBTZWUgZG9jdW1lbnRhdGlvbiBvZiB0aGUgSmF2YWMgdGFzayBmb3IKICogbW9yZSBpbmZvcm1hdGlvbi4KICogPHAvPgogKiBOZXN0ZWQgaW5jbHVkZXMgYW5kIGV4Y2x1ZGVzIGFyZSBhbHNvIHN1cHBvcnRlZC4KICoKICogPHA+PGI+RXhhbXBsZTo8L2I+PC9wPgogKiA8cHJlPgogKiAmbHQ7aWNvbnRyYWN0CiAqICAgIHNyY2Rpcj0iJHtidWlsZC5zcmN9IgogKiAgICBpbnN0cnVtZW50ZGlyPSIke2J1aWxkLmluc3RydW1lbnR9IgogKiAgICByZXBvc2l0b3J5ZGlyPSIke2J1aWxkLnJlcG9zaXRvcnl9IgogKiAgICBidWlsZGRpcj0iJHtidWlsZC5pbnN0cmNsYXNzZXN9IgogKiAgICB1cGRhdGVpY29udHJvbD0idHJ1ZSIKICogICAgY2xhc3NkaXI9IiR7YnVpbGQuY2xhc3Nlc30iCiAqICAgIGNvbnRyb2xmaWxlPSJjb250cm9sIgogKiAgICB0YXJnZXRzPSJ0YXJnZXRzIgogKiAgICB2ZXJib3NpdHk9ImVycm9yKix3YXJuaW5nKiIKICogICAgcXVpZXQ9InRydWUiCiAqID4KICogICAgJmx0O2NsYXNzcGF0aCByZWZpZD0iY29tcGlsZS1jbGFzc3BhdGgiLz4KICogJmx0Oy9pY29udHJhY3Q+CiAqIDwvcHJlPgogKgogKi8KcHVibGljIGNsYXNzIElDb250cmFjdCBleHRlbmRzIE1hdGNoaW5nVGFzayB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElDT05UUk9MX1BST1BFUlRJRVNfSEVBREVSID0KICAgICAgICAiIFlvdSBtaWdodCB3YW50IHRvIHNldCBjbGFzc1Jvb3QgdG8gcG9pbnQgdG8geW91ciBub3JtYWwgY29tcGlsYXRpb24gY2xhc3Mgcm9vdCBkaXJlY3RvcnkuIjsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUNPTlRST0xfUFJPUEVSVElFU19NRVNTQUdFID0KICAgICAgICAiWW91IHNob3VsZCBwcm9iYWJseSBtb2RpZnkgaWNvbnRyb2wucHJvcGVydGllcycgY2xhc3NSb290IHRvIHdoZXJlIGNvbWlsZWQgKHVuaW5zdHJ1bWVudGVkKSBjbGFzc2VzIGdvLiI7CgogICAgLyoqIFwgb24gd2luZG93cywgLyBvbiBsaW51eC91bml4ICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgcHMgPSBTeXN0ZW0uZ2V0UHJvcGVydHkoICJwYXRoLnNlcGFyYXRvciIgKTsKCiAgICAvKiogY29tcGlsZXIgdG8gdXNlIGZvciBpbnN0cnVtZW5hdGlvbiAqLwogICAgcHJpdmF0ZSBTdHJpbmcgaWNDb21waWxlciA9ICJqYXZhYyI7CgogICAgLyoqIHRlbXBvcmFyeSBmaWxlIHdpdGggZmlsZSBuYW1lcyBvZiBhbGwgamF2YSBmaWxlcyB0byBiZSBpbnN0cnVtZW50ZWQgKi8KICAgIHByaXZhdGUgRmlsZSB0YXJnZXRzID0gbnVsbDsKCiAgICAvKiogd2lsbCBiZSBzZXQgdG8gdHJ1ZSBpZiBhbnkgb2YgdGhlIHNvdXJjYSBmaWxlcyBhcmUgbmV3ZXIgdGhhbiB0aGUgaW5zdHJ1bWVudGVkIGZpbGVzICovCiAgICBwcml2YXRlIGJvb2xlYW4gZGlydHkgPSBmYWxzZTsKCiAgICAvKiogc2V0IHRvIHRydWUgaWYgdGhlIGlDb250cmFjdCBqYXIgaXMgbWlzc2luZyAqLwogICAgcHJpdmF0ZSBib29sZWFuIGlDb250cmFjdE1pc3NpbmcgPSBmYWxzZTsKCiAgICAvKiogc291cmNlIGZpbGUgcm9vdCAqLwogICAgcHJpdmF0ZSBGaWxlIHNyY0RpciA9IG51bGw7CgogICAgLyoqIGluc3RydW1lbnRhdGlvbiBzcmMgcm9vdCAqLwogICAgcHJpdmF0ZSBGaWxlIGluc3RydW1lbnREaXIgPSBudWxsOwoKICAgIC8qKiBpbnN0cnVtZW50YXRpb24gYnVpbGQgcm9vdCAqLwogICAgcHJpdmF0ZSBGaWxlIGJ1aWxkRGlyID0gbnVsbDsKCiAgICAvKiogcmVwb3NpdG9yeSBzcmMgcm9vdCAqLwogICAgcHJpdmF0ZSBGaWxlIHJlcG9zaXRvcnlEaXIgPSBudWxsOwoKICAgIC8qKiByZXBvc2l0b3J5IGJ1aWxkIHJvb3QgKi8KICAgIHByaXZhdGUgRmlsZSByZXBCdWlsZERpciA9IG51bGw7CgogICAgLyoqIGNsYXNzcGF0aCAqLwogICAgcHJpdmF0ZSBQYXRoIGNsYXNzcGF0aCA9IG51bGw7CgogICAgLyoqIFRoZSBjbGFzcyBvZiB0aGUgVGhyb3dhYmxlIHRvIGJlIHRocm93biBvbiBmYWlsZWQgYXNzZXJ0aW9ucyAqLwogICAgcHJpdmF0ZSBTdHJpbmcgZmFpbFRocm93YWJsZSA9ICJqYXZhLmxhbmcuRXJyb3IiOwoKICAgIC8qKiBUaGUgLXYgb3B0aW9uICovCiAgICBwcml2YXRlIFN0cmluZyB2ZXJib3NpdHkgPSAiZXJyb3IqIjsKCiAgICAvKiogVGhlIC1xIG9wdGlvbiAqLwogICAgcHJpdmF0ZSBib29sZWFuIHF1aWV0ID0gZmFsc2U7CgogICAgLyoqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0byB1c2UgaW50ZXJuYWwgY29tcGlsYXRpb24gKi8KICAgIHByaXZhdGUgYm9vbGVhbiBpbnRlcm5hbGNvbXBpbGF0aW9uID0gZmFsc2U7CgogICAgLyoqIFRoZSAtbSBvcHRpb24gKi8KICAgIHByaXZhdGUgRmlsZSBjb250cm9sRmlsZSA9IG51bGw7CgogICAgLyoqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0byBpbnN0cnVtZW50IGZvciBwcmVjb25kaXRpb25zICovCiAgICBwcml2YXRlIGJvb2xlYW4gcHJlID0gdHJ1ZTsKICAgIHByaXZhdGUgYm9vbGVhbiBwcmVNb2RpZmllZCA9IGZhbHNlOwoKICAgIC8qKiBJbmRpY2F0ZXMgd2hldGhlciBvciBub3QgdG8gaW5zdHJ1bWVudCBmb3IgcG9zdGNvbmRpdGlvbnMgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBwb3N0ID0gdHJ1ZTsKICAgIHByaXZhdGUgYm9vbGVhbiBwb3N0TW9kaWZpZWQgPSBmYWxzZTsKCiAgICAvKiogSW5kaWNhdGVzIHdoZXRoZXIgb3Igbm90IHRvIGluc3RydW1lbnQgZm9yIGludmFyaWFudHMgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBpbnZhcmlhbnQgPSB0cnVlOwogICAgcHJpdmF0ZSBib29sZWFuIGludmFyaWFudE1vZGlmaWVkID0gZmFsc2U7CgogICAgLyoqIEluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0byBpbnN0cnVtZW50IGFsbCBmaWxlcyByZWdhcmRsZXNzIG9mIHRpbWVzdGFtcCAqLwogICAgLy8gY2FuJ3QgYmUgZXhwbGljaXRseSBzZXQsIGlzIHNldCBpZiBjb250cm9sIGZpbGUgZXhpc3RzIGFuZCBpcyBuZXdlciB0aGFuIGFueSBzb3VyY2UgZmlsZQogICAgcHJpdmF0ZSBib29sZWFuIGluc3RydW1lbnRhbGwgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIEluZGljYXRlcyB0aGUgbmFtZSBvZiBhIHByb3BlcnRpZXMgZmlsZSAoaW50ZW50aW9uYWxseSBmb3IgaUNvbnRyb2wpIHdoZXJlIHRoZSBjbGFzc3BhdGgKICAgICAqIHByb3BlcnR5IHNob3VsZCBiZSB1cGRhdGVkLgogICAgICovCiAgICBwcml2YXRlIGJvb2xlYW4gdXBkYXRlSWNvbnRyb2wgPSBmYWxzZTsKCiAgICAvKioKICAgICAqIFJlZ3VsYXIgY29tcGlsYXRpb24gY2xhc3Mgcm9vdAogICAgICovCiAgICBwcml2YXRlIEZpbGUgY2xhc3NEaXIgPSBudWxsOwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgc291cmNlIGRpcmVjdG9yeQogICAgICoKICAgICAqIEBwYXJhbSBzcmNEaXIgdGhlIHNvdXJjZSBkaXJlY3RvcnkKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0U3JjZGlyKCBGaWxlIHNyY0RpciApIHsKICAgICAgICB0aGlzLnNyY0RpciA9IHNyY0RpcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNsYXNzIGRpcmVjdG9yeSAodW5pbnN0cnVtZW50ZWQgY2xhc3NlcykKICAgICAqCiAgICAgKiBAcGFyYW0gc3JjRGlyIHRoZSBzb3VyY2UgZGlyZWN0b3J5CiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldENsYXNzZGlyKCBGaWxlIGNsYXNzRGlyICkgewogICAgICAgIHRoaXMuY2xhc3NEaXIgPSBjbGFzc0RpcjsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGluc3RydW1lbnRhdGlvbiBkaXJlY3RvcnkKICAgICAqCiAgICAgKiBAcGFyYW0gaW5zdHJ1bWVudERpciB0aGUgc291cmNlIGRpcmVjdG9yeQogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRJbnN0cnVtZW50ZGlyKCBGaWxlIGluc3RydW1lbnREaXIgKSB7CiAgICAgICAgdGhpcy5pbnN0cnVtZW50RGlyID0gaW5zdHJ1bWVudERpcjsKICAgICAgICBpZiAoIHRoaXMuYnVpbGREaXIgPT0gbnVsbCApIHsKICAgICAgICAgICAgc2V0QnVpbGRkaXIoIGluc3RydW1lbnREaXIgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBidWlsZCBkaXJlY3RvcnkgZm9yIGluc3RydW1lbnRlZCBjbGFzc2VzCiAgICAgKgogICAgICogQHBhcmFtIGJ1aWxkRGlyIHRoZSBidWlsZCBkaXJlY3RvcnkKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0QnVpbGRkaXIoIEZpbGUgYnVpbGREaXIgKSB7CiAgICAgICAgdGhpcy5idWlsZERpciA9IGJ1aWxkRGlyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgYnVpbGQgZGlyZWN0b3J5IGZvciByZXBvc2l0b3J5IGNsYXNzZXMKICAgICAqCiAgICAgKiBAcGFyYW0gcmVwb3NpdG9yeURpciB0aGUgc291cmNlIGRpcmVjdG9yeQogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRSZXBvc2l0b3J5ZGlyKCBGaWxlIHJlcG9zaXRvcnlEaXIgKSB7CiAgICAgICAgdGhpcy5yZXBvc2l0b3J5RGlyID0gcmVwb3NpdG9yeURpcjsKICAgICAgICBpZiggdGhpcy5yZXBCdWlsZERpciA9PSBudWxsICkgewogICAgICAgICAgICBzZXRSZXBidWlsZGRpciggcmVwb3NpdG9yeURpciApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGJ1aWxkIGRpcmVjdG9yeSBmb3IgaW5zdHJ1bWVudGVkIGNsYXNzZXMKICAgICAqCiAgICAgKiBAcGFyYW0gYnVpbGREaXIgdGhlIGJ1aWxkIGRpcmVjdG9yeQogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRSZXBidWlsZGRpciggRmlsZSByZXBCdWlsZERpciApIHsKICAgICAgICB0aGlzLnJlcEJ1aWxkRGlyID0gcmVwQnVpbGREaXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBUdXJucyBvbi9vZmYgcHJlY29uZGl0aW9uIGluc3RydW1lbnRhdGlvbgogICAgICoKICAgICAqIEBwYXJhbSBwcmUgdHJ1ZSB0dXJucyBpdCBvbgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRQcmUoIGJvb2xlYW4gcHJlICkgewogICAgICAgIHRoaXMucHJlID0gcHJlOwogICAgICAgIHByZU1vZGlmaWVkID0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFR1cm5zIG9uL29mZiBwb3N0Y29uZGl0aW9uIGluc3RydW1lbnRhdGlvbgogICAgICoKICAgICAqIEBwYXJhbSBwb3N0IHRydWUgdHVybnMgaXQgb24KICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0UG9zdCggYm9vbGVhbiBwb3N0ICkgewogICAgICAgIHRoaXMucG9zdCA9IHBvc3Q7CiAgICAgICAgcG9zdE1vZGlmaWVkID0gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFR1cm5zIG9uL29mZiBpbnZhcmlhbnQgaW5zdHJ1bWVudGF0aW9uCiAgICAgKgogICAgICogQHBhcmFtIGludmFyaWFudCB0cnVlIHR1cm5zIGl0IG9uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldEludmFyaWFudCggYm9vbGVhbiBpbnZhcmlhbnQgKSB7CiAgICAgICAgdGhpcy5pbnZhcmlhbnQgPSBpbnZhcmlhbnQ7CiAgICAgICAgaW52YXJpYW50TW9kaWZpZWQgPSB0cnVlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgVGhyb3dhYmxlIChFeGNlcHRpb24pIHRvIGJlIHRocm93biBvbiBhc3NlcnRpb24gdmlvbGF0aW9uCiAgICAgKgogICAgICogQHBhcmFtIGNsYXp6IHRoZSBmdWxseSBxdWFsaWZpZWQgVGhyb3dhYmxlIGNsYXNzIG5hbWUKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0RmFpbHRocm93YWJsZSggU3RyaW5nIGNsYXp6ICkgewogICAgICAgIHRoaXMuZmFpbFRocm93YWJsZSA9IGNsYXp6OwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgdmVyYm9zaXR5IGxldmVsIG9mIGlDb250cmFjdC4gQW55IGNvbWJpbmF0aW9uIG9mCiAgICAgKiBlcnJvciosd2FybmluZyosbm90ZSosaW5mbyoscHJvZ3Jlc3MqLGRlYnVnKiAoY29tbWEgc2VwYXJhdGVkKQogICAgICogY2FuIGJlIHVzZWQuIERlZmF1bHRzIHRvIGVycm9yKix3YXJuaW5nKgogICAgICoKICAgICAqIEBwYXJhbSB2ZXJib3NpdHkgdmVyYm9zaXR5IGxldmVsCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldFZlcmJvc2l0eSggU3RyaW5nIHZlcmJvc2l0eSApIHsKICAgICAgICB0aGlzLnZlcmJvc2l0eSA9IHZlcmJvc2l0eTsKICAgIH0KCiAgICAvKioKICAgICAqIFRlbGxzIGlDb250cmFjdCB0byBiZSBxdWlldC4KICAgICAqCiAgICAgKiBAcGFyYW0gcXVpZXQgdHJ1ZSBpZiBpQ29udHJhY3Qgc2hvdWxkIGJlIHF1aWV0LgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRRdWlldCggYm9vbGVhbiBxdWlldCApIHsKICAgICAgICB0aGlzLnF1aWV0ID0gcXVpZXQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBmaWxlIHdoZXJlIHRhcmdldHMgd2lsbCBiZSB3cml0dGVuLgogICAgICogVGhhdCBpcyB0aGUgZmlsZSB0aGF0IHRlbGxzIGlDb250cmFjdCB3aGF0IGZpbGVzIHRvIHByb2Nlc3MuCiAgICAgKgogICAgICogQHBhcmFtIHRhcmdldHMgdGhlIHRhcmdldHMgZmlsZSBuYW1lCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldFRhcmdldHMoIEZpbGUgdGFyZ2V0cyApIHsKICAgICAgICB0aGlzLnRhcmdldHMgPSB0YXJnZXRzOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyB0aGUgY29udHJvbCBmaWxlIHRvIHBhc3MgdG8gaUNvbnRyYWN0LgogICAgICoKICAgICAqIEBwYXJhbSBjb250cm9sRmlsZSB0aGUgY29udHJvbCBmaWxlCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldENvbnRyb2xmaWxlKCBGaWxlIGNvbnRyb2xGaWxlICkgewogICAgICAgIGlmKCAhY29udHJvbEZpbGUuZXhpc3RzKCkgKSB7CiAgICAgICAgICAgIGxvZyggIldBUk5JTkc6IENvbnRyb2wgZmlsZSAiICsgY29udHJvbEZpbGUuZ2V0QWJzb2x1dGVQYXRoKCkgKyAiIGRvZXNuJ3QgZXhpc3QuIGlDb250cmFjdCB3aWxsIGJlIHJ1biB3aXRob3V0IGNvbnRyb2wgZmlsZS4iICk7CiAgICAgICAgfQogICAgICAgIHRoaXMuY29udHJvbEZpbGUgPSBjb250cm9sRmlsZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNsYXNzcGF0aCB0byBiZSB1c2VkIGZvciBpbnZvY2F0aW9uIG9mIGlDb250cmFjdC4KICAgICAqCiAgICAgKiBAcGF0aCB0aGUgY2xhc3NwYXRoCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldENsYXNzcGF0aCggUGF0aCBwYXRoICkgewogICAgICAgIGNyZWF0ZUNsYXNzcGF0aCgpLmFwcGVuZCggcGF0aCApOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5lc3RlZCBjbGFzc3BhdGggZWxlbWVudAogICAgICoKICAgICAqIEByZXR1cm4gdGhlIG5lc3RlZCBjbGFzc3BhdGggZWxlbWVudAogICAgICovCiAgICBwdWJsaWMgUGF0aCBjcmVhdGVDbGFzc3BhdGgoKSB7CiAgICAgICAgaWYgKGNsYXNzcGF0aCA9PSBudWxsKSB7CiAgICAgICAgICAgIGNsYXNzcGF0aCA9IG5ldyBQYXRoKCBnZXRQcm9qZWN0KCkgKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNsYXNzcGF0aDsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgYSByZWZlcmVuY2UgdG8gYSBjbGFzc3BhdGggZGVmaW5lZCBlbHNld2hlcmUuCiAgICAgKgogICAgICogQHBhcmFtIHJlZmVyZW5jZSByZWZlcmVuY2VkIGNsYXNzcGF0aAogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRDbGFzc3BhdGhSZWYoIFJlZmVyZW5jZSByZWZlcmVuY2UgKSB7CiAgICAgICAgY3JlYXRlQ2xhc3NwYXRoKCkuc2V0UmVmaWQoIHJlZmVyZW5jZSApOwogICAgfQoKICAgIC8qKgogICAgICogRGVjaWRlcyB3aGV0aGVyIG9yIG5vdCB0byB1cGRhdGUgaUNvbnRyb2wgcHJvcGVydGllcyBmaWxlCiAgICAgKgogICAgICogQHBhcmFtIHVwZGF0ZUljb250cm9sIHRydWUgaWYgaUNvbnRyb2wgcHJvcGVydGllcyBmaWxlIHNob3VsZCBiZSB1cGRhdGVkCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldFVwZGF0ZWljb250cm9sKCBib29sZWFuIHVwZGF0ZUljb250cm9sICkgewogICAgICAgIHRoaXMudXBkYXRlSWNvbnRyb2wgPSB1cGRhdGVJY29udHJvbDsKICAgIH0KCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIHRoZSB0YXNrCiAgICAgKgogICAgICogQGV4Y2VwdGlvbiBCdWlsZEV4Y2VwdGlvbiBpZiB0aGUgaW5zdHJ1bWVudGF0aW9uIGZhaWxzCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGV4ZWN1dGUoKSB0aHJvd3MgQnVpbGRFeGNlcHRpb24gewogICAgICAgIHByZWNvbmRpdGlvbnMoKTsKICAgICAgICBzY2FuKCk7CiAgICAgICAgaWYoIGRpcnR5ICkgewoKICAgICAgICAgICAgLy8gdHVybiBvZmYgYXNzZXJ0aW9ucyBpZiB3ZSdyZSB1c2luZyBjb250cm9sZmlsZSwgdW5sZXNzIHRoZXkgYXJlIG5vdCBleHBsaWNpdGx5IHNldC4KICAgICAgICAgICAgYm9vbGVhbiB1c2VDb250cm9sRmlsZSA9IChjb250cm9sRmlsZSAhPSBudWxsKSAmJiBjb250cm9sRmlsZS5leGlzdHMoKTsKICAgICAgICAgICAgaWYoIHVzZUNvbnRyb2xGaWxlICYmICFwcmVNb2RpZmllZCApIHsKICAgICAgICAgICAgICAgIHByZSA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKCB1c2VDb250cm9sRmlsZSAmJiAhcG9zdE1vZGlmaWVkICkgewogICAgICAgICAgICAgICAgcG9zdCA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKCB1c2VDb250cm9sRmlsZSAmJiAhaW52YXJpYW50TW9kaWZpZWQgKSB7CiAgICAgICAgICAgICAgICBpbnZhcmlhbnQgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBpc3N1ZSB3YXJuaW5nIGlmIHByZSxwb3N0IG9yIGludmFyaWFudCBpcyB1c2VkIHRvZ2V0aGVyIHdpdGggY29udHJvbGZpbGUKICAgICAgICAgICAgaWYoICggcHJlIHx8IHBvc3QgfHwgaW52YXJpYW50ICkgJiYgY29udHJvbEZpbGUgIT0gbnVsbCApIHsKICAgICAgICAgICAgICAgIGxvZyggIldBUk5JTkc6IHNwZWNpZnlpbmcgcHJlLHBvc3Qgb3IgaW52YXJpYW50IHdpbGwgb3ZlcnJpZGUgY29udHJvbCBmaWxlIHNldHRpbmdzIiApOwogICAgICAgICAgICB9CgoKCiAgICAgICAgICAgIC8vIFdlIHdhbnQgdG8gYmUgbm90aWZpZWQgaWYgaUNvbnRyYWN0IGphciBpcyBtaXNzaW5nLiBUaGlzIG1ha2VzIGxpZmUgZWFzaWVyIGZvciB0aGUgdXNlcgogICAgICAgICAgICAvLyB3aG8gZGlkbid0IHVuZGVyc3RhbmQgdGhhdCBpQ29udHJhY3QgaXMgYSBzZXBhcmF0ZSBsaWJyYXJ5IChkdWghKQogICAgICAgICAgICBnZXRQcm9qZWN0KCkuYWRkQnVpbGRMaXN0ZW5lciggbmV3IElDb250cmFjdFByZXNlbmNlRGV0ZWN0b3IoKSApOwoKICAgICAgICAgICAgLy8gUHJlcGFyZSB0aGUgZGlyZWN0b3JpZXMgZm9yIGlDb250cmFjdC4gaUNvbnRyYWN0IHdpbGwgbWFrZSB0aGVtIGlmIHRoZXkKICAgICAgICAgICAgLy8gZG9uJ3QgZXhpc3QsIGJ1dCBmb3Igc29tZSByZWFzb24gSSBkb24ndCBrbm93LCBpdCB3aWxsIGNvbXBsYWluIGFib3V0IHRoZSBSRVAgZmlsZXMKICAgICAgICAgICAgLy8gYWZ0ZXJ3YXJkcwogICAgICAgICAgICBNa2RpciBta2RpciA9IChNa2RpcikgcHJvamVjdC5jcmVhdGVUYXNrKCAibWtkaXIiICk7CiAgICAgICAgICAgIG1rZGlyLnNldERpciggaW5zdHJ1bWVudERpciApOwogICAgICAgICAgICBta2Rpci5leGVjdXRlKCk7CiAgICAgICAgICAgIG1rZGlyLnNldERpciggYnVpbGREaXIgKTsKICAgICAgICAgICAgbWtkaXIuZXhlY3V0ZSgpOwogICAgICAgICAgICBta2Rpci5zZXREaXIoIHJlcG9zaXRvcnlEaXIgKTsKICAgICAgICAgICAgbWtkaXIuZXhlY3V0ZSgpOwoKICAgICAgICAgICAgLy8gU2V0IHRoZSBjbGFzc3BhdGggdGhhdCBpcyBuZWVkZWQgZm9yIHJlZ3VsYXIgSmF2YWMgY29tcGlsYXRpb24KICAgICAgICAgICAgUGF0aCBiYXNlQ2xhc3NwYXRoID0gY3JlYXRlQ2xhc3NwYXRoKCk7CgogICAgICAgICAgICAvLyBNaWdodCBuZWVkIHRvIGFkZCB0aGUgY29yZSBjbGFzc2VzIGlmIHdlJ3JlIG5vdCB1c2luZyBTdW4ncyBKYXZhYyAobGlrZSBKaWtlcykKICAgICAgICAgICAgU3RyaW5nIGNvbXBpbGVyID0gcHJvamVjdC5nZXRQcm9wZXJ0eSgiYnVpbGQuY29tcGlsZXIiKTsKICAgICAgICAgICAgQ2xhc3NwYXRoSGVscGVyIGNsYXNzcGF0aEhlbHBlciA9IG5ldyBDbGFzc3BhdGhIZWxwZXIoIGNvbXBpbGVyICk7CiAgICAgICAgICAgIGNsYXNzcGF0aEhlbHBlci5tb2RpZnkoIGJhc2VDbGFzc3BhdGggKTsKCiAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgY2xhc3NwYXRoIHJlcXVpcmVkIHRvIGNvbXBpbGUgdGhlIHNvdXJjZWZpbGVzIEJFRk9SRSBpbnN0cnVtZW50YXRpb24KICAgICAgICAgICAgUGF0aCBiZWZvcmVJbnN0cnVtZW50YXRpb25DbGFzc3BhdGggPSAoKFBhdGgpIGJhc2VDbGFzc3BhdGguY2xvbmUoKSk7CiAgICAgICAgICAgIGJlZm9yZUluc3RydW1lbnRhdGlvbkNsYXNzcGF0aC5hcHBlbmQoIG5ldyBQYXRoKCBnZXRQcm9qZWN0KCksIHNyY0Rpci5nZXRBYnNvbHV0ZVBhdGgoKSApICk7CgogICAgICAgICAgICAvLyBDcmVhdGUgdGhlIGNsYXNzcGF0aCByZXF1aXJlZCB0byBjb21waWxlIHRoZSBzb3VyY2VmaWxlcyBBRlRFUiBpbnN0cnVtZW50YXRpb24KICAgICAgICAgICAgUGF0aCBhZnRlckluc3RydW1lbnRhdGlvbkNsYXNzcGF0aCA9ICgoUGF0aCkgYmFzZUNsYXNzcGF0aC5jbG9uZSgpKTsKICAgICAgICAgICAgYWZ0ZXJJbnN0cnVtZW50YXRpb25DbGFzc3BhdGguYXBwZW5kKCBuZXcgUGF0aCggZ2V0UHJvamVjdCgpLCBpbnN0cnVtZW50RGlyLmdldEFic29sdXRlUGF0aCgpICkgKTsKICAgICAgICAgICAgYWZ0ZXJJbnN0cnVtZW50YXRpb25DbGFzc3BhdGguYXBwZW5kKCBuZXcgUGF0aCggZ2V0UHJvamVjdCgpLCByZXBvc2l0b3J5RGlyLmdldEFic29sdXRlUGF0aCgpICkgKTsKICAgICAgICAgICAgYWZ0ZXJJbnN0cnVtZW50YXRpb25DbGFzc3BhdGguYXBwZW5kKCBuZXcgUGF0aCggZ2V0UHJvamVjdCgpLCBzcmNEaXIuZ2V0QWJzb2x1dGVQYXRoKCkgKSApOwogICAgICAgICAgICBhZnRlckluc3RydW1lbnRhdGlvbkNsYXNzcGF0aC5hcHBlbmQoIG5ldyBQYXRoKCBnZXRQcm9qZWN0KCksIGJ1aWxkRGlyLmdldEFic29sdXRlUGF0aCgpICkgKTsKCiAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgY2xhc3NwYXRoIHJlcXVpcmVkIHRvIGF1dG9tYXRpY2FsbHkgY29tcGlsZSB0aGUgcmVwb3NpdG9yeSBmaWxlcwogICAgICAgICAgICBQYXRoIHJlcG9zaXRvcnlDbGFzc3BhdGggPSAoKFBhdGgpIGJhc2VDbGFzc3BhdGguY2xvbmUoKSk7CiAgICAgICAgICAgIHJlcG9zaXRvcnlDbGFzc3BhdGguYXBwZW5kKCBuZXcgUGF0aCggZ2V0UHJvamVjdCgpLCBpbnN0cnVtZW50RGlyLmdldEFic29sdXRlUGF0aCgpICkgKTsKICAgICAgICAgICAgcmVwb3NpdG9yeUNsYXNzcGF0aC5hcHBlbmQoIG5ldyBQYXRoKCBnZXRQcm9qZWN0KCksIHNyY0Rpci5nZXRBYnNvbHV0ZVBhdGgoKSApICk7CiAgICAgICAgICAgIHJlcG9zaXRvcnlDbGFzc3BhdGguYXBwZW5kKCBuZXcgUGF0aCggZ2V0UHJvamVjdCgpLCByZXBvc2l0b3J5RGlyLmdldEFic29sdXRlUGF0aCgpICkgKTsKICAgICAgICAgICAgcmVwb3NpdG9yeUNsYXNzcGF0aC5hcHBlbmQoIG5ldyBQYXRoKCBnZXRQcm9qZWN0KCksIGJ1aWxkRGlyLmdldEFic29sdXRlUGF0aCgpICkgKTsKCiAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgY2xhc3NwYXRoIHJlcXVpcmVkIGZvciBpQ29udHJhY3QgaXRzZWxmCiAgICAgICAgICAgIFBhdGggaUNvbnRyYWN0Q2xhc3NwYXRoID0gKChQYXRoKSBiYXNlQ2xhc3NwYXRoLmNsb25lKCkpOwogICAgICAgICAgICBpQ29udHJhY3RDbGFzc3BhdGguYXBwZW5kKCBuZXcgUGF0aCggZ2V0UHJvamVjdCgpLCBTeXN0ZW0uZ2V0UHJvcGVydHkoICJqYXZhLmhvbWUiICkgKyBGaWxlLnNlcGFyYXRvciArICIuLiIgKyBGaWxlLnNlcGFyYXRvciArICJsaWIiICsgRmlsZS5zZXBhcmF0b3IgKyAidG9vbHMuamFyIiApICk7CiAgICAgICAgICAgIGlDb250cmFjdENsYXNzcGF0aC5hcHBlbmQoIG5ldyBQYXRoKCBnZXRQcm9qZWN0KCksIHNyY0Rpci5nZXRBYnNvbHV0ZVBhdGgoKSApICk7CiAgICAgICAgICAgIGlDb250cmFjdENsYXNzcGF0aC5hcHBlbmQoIG5ldyBQYXRoKCBnZXRQcm9qZWN0KCksIHJlcG9zaXRvcnlEaXIuZ2V0QWJzb2x1dGVQYXRoKCkgKSApOwogICAgICAgICAgICBpQ29udHJhY3RDbGFzc3BhdGguYXBwZW5kKCBuZXcgUGF0aCggZ2V0UHJvamVjdCgpLCBpbnN0cnVtZW50RGlyLmdldEFic29sdXRlUGF0aCgpICkgKTsKICAgICAgICAgICAgaUNvbnRyYWN0Q2xhc3NwYXRoLmFwcGVuZCggbmV3IFBhdGgoIGdldFByb2plY3QoKSwgYnVpbGREaXIuZ2V0QWJzb2x1dGVQYXRoKCkgKSApOwoKICAgICAgICAgICAgLy8gQ3JlYXRlIGEgZm9ya2VkIGphdmEgcHJvY2VzcwogICAgICAgICAgICBKYXZhIGlDb250cmFjdCA9IChKYXZhKSBwcm9qZWN0LmNyZWF0ZVRhc2soICJqYXZhIiApOwogICAgICAgICAgICBpQ29udHJhY3Quc2V0VGFza05hbWUoIGdldFRhc2tOYW1lKCkgKTsKICAgICAgICAgICAgaUNvbnRyYWN0LnNldEZvcmsoIHRydWUgKTsKICAgICAgICAgICAgaUNvbnRyYWN0LnNldENsYXNzbmFtZSggImNvbS5yZWxpYWJsZXN5c3RlbXMuaUNvbnRyYWN0LlRvb2wiICk7CiAgICAgICAgICAgIGlDb250cmFjdC5zZXRDbGFzc3BhdGgoIGlDb250cmFjdENsYXNzcGF0aCApOwoKICAgICAgICAgICAgLy8gQnVpbGQgdGhlIGFyZ3VtZW50cyB0byBpQ29udHJhY3QKICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGFyZ3MgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CiAgICAgICAgICAgIGFyZ3MuYXBwZW5kKCBkaXJlY3RpdmVTdHJpbmcoKSApOwogICAgICAgICAgICBhcmdzLmFwcGVuZCggIi12IiApLmFwcGVuZCggdmVyYm9zaXR5ICkuYXBwZW5kKCAiICIgKTsKICAgICAgICAgICAgYXJncy5hcHBlbmQoICItYiIgKS5hcHBlbmQoICJcIiIgKS5hcHBlbmQoIGljQ29tcGlsZXIgKS5hcHBlbmQoICIgLWNsYXNzcGF0aCAiICkuYXBwZW5kKCBiZWZvcmVJbnN0cnVtZW50YXRpb25DbGFzc3BhdGggKS5hcHBlbmQoICJcIiAiICk7CiAgICAgICAgICAgIGFyZ3MuYXBwZW5kKCAiLWMiICkuYXBwZW5kKCAiXCIiICkuYXBwZW5kKCBpY0NvbXBpbGVyICkuYXBwZW5kKCAiIC1jbGFzc3BhdGggIiApLmFwcGVuZCggYWZ0ZXJJbnN0cnVtZW50YXRpb25DbGFzc3BhdGggKS5hcHBlbmQoICIgLWQgIiApLmFwcGVuZCggYnVpbGREaXIgKS5hcHBlbmQoICJcIiAiICk7CiAgICAgICAgICAgIGFyZ3MuYXBwZW5kKCAiLW4iICkuYXBwZW5kKCAiXCIiICkuYXBwZW5kKCBpY0NvbXBpbGVyICkuYXBwZW5kKCAiIC1jbGFzc3BhdGggIiApLmFwcGVuZCggcmVwb3NpdG9yeUNsYXNzcGF0aCApLmFwcGVuZCggIlwiICIgKTsKICAgICAgICAgICAgYXJncy5hcHBlbmQoICItZCIgKS5hcHBlbmQoIGZhaWxUaHJvd2FibGUgKS5hcHBlbmQoICIgIiApOwogICAgICAgICAgICBhcmdzLmFwcGVuZCggIi1vIiApLmFwcGVuZCggaW5zdHJ1bWVudERpciApLmFwcGVuZCggRmlsZS5zZXBhcmF0b3IgKS5hcHBlbmQoICJAcCIgKS5hcHBlbmQoIEZpbGUuc2VwYXJhdG9yICkuYXBwZW5kKCAiQGYuQGUgIiApOwogICAgICAgICAgICBhcmdzLmFwcGVuZCggIi1rIiApLmFwcGVuZCggcmVwb3NpdG9yeURpciApLmFwcGVuZCggRmlsZS5zZXBhcmF0b3IgKS5hcHBlbmQoICJAcCAiICk7CiAgICAgICAgICAgIGFyZ3MuYXBwZW5kKCBxdWlldCA/ICItcSAiIDogIiIgKTsKICAgICAgICAgICAgYXJncy5hcHBlbmQoIGluc3RydW1lbnRhbGwgPyAiLWEgIiA6ICIiICk7IC8vIHJlaW5zdHJ1bWVudCBldmVyeXRoaW5nIGlmIGNvbnRyb2xGaWxlIGV4aXN0cyBhbmQgaXMgbmV3ZXIgdGhhbiBhbnkgY2xhc3MKICAgICAgICAgICAgYXJncy5hcHBlbmQoICJAIiApLmFwcGVuZCggdGFyZ2V0cy5nZXRBYnNvbHV0ZVBhdGgoKSApOwogICAgICAgICAgICBpQ29udHJhY3QuY3JlYXRlQXJnKCkuc2V0TGluZSggYXJncy50b1N0cmluZygpICk7CgovL1N5c3RlbS5vdXQucHJpbnRsbiggIkpBVkEgLWNsYXNzcGF0aCAiICsgaUNvbnRyYWN0Q2xhc3NwYXRoICsgIiBjb20ucmVsaWFibGVzeXN0ZW1zLmlDb250cmFjdC5Ub29sICIgKyBhcmdzLnRvU3RyaW5nKCkgKTsKCiAgICAgICAgICAgIC8vIHVwZGF0ZSBpQ29udHJvbFByb3BlcnRpZXMgaWYgaXQncyBzZXQuCiAgICAgICAgICAgIGlmKCB1cGRhdGVJY29udHJvbCApIHsKICAgICAgICAgICAgICAgIFByb3BlcnRpZXMgaUNvbnRyb2xQcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CiAgICAgICAgICAgICAgICB0cnkgeyAvLyB0byByZWFkIGV4aXN0aW5nIHByb3BlcnRpZXNmaWxlCiAgICAgICAgICAgICAgICAgICAgaUNvbnRyb2xQcm9wcy5sb2FkKCBuZXcgRmlsZUlucHV0U3RyZWFtKCAiaWNvbnRyb2wucHJvcGVydGllcyIgKSApOwogICAgICAgICAgICAgICAgfSBjYXRjaCggSU9FeGNlcHRpb24gZSApIHsKICAgICAgICAgICAgICAgICAgICBsb2coICJGaWxlIGljb250cm9sLnByb3BlcnRpZXMgbm90IGZvdW5kLiBUaGF0J3Mgb2suIFdyaXRpbmcgYSBkZWZhdWx0IG9uZS4iICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpQ29udHJvbFByb3BzLnNldFByb3BlcnR5KCAic291cmNlUm9vdCIsIHNyY0Rpci5nZXRBYnNvbHV0ZVBhdGgoKSApOwogICAgICAgICAgICAgICAgaUNvbnRyb2xQcm9wcy5zZXRQcm9wZXJ0eSggImNsYXNzUm9vdCIsIGNsYXNzRGlyLmdldEFic29sdXRlUGF0aCgpICk7CiAgICAgICAgICAgICAgICBpQ29udHJvbFByb3BzLnNldFByb3BlcnR5KCAiY2xhc3NwYXRoIiwgYWZ0ZXJJbnN0cnVtZW50YXRpb25DbGFzc3BhdGgudG9TdHJpbmcoKSApOwogICAgICAgICAgICAgICAgaUNvbnRyb2xQcm9wcy5zZXRQcm9wZXJ0eSggImNvbnRyb2xGaWxlIiwgY29udHJvbEZpbGUuZ2V0QWJzb2x1dGVQYXRoKCkgKTsKICAgICAgICAgICAgICAgIGlDb250cm9sUHJvcHMuc2V0UHJvcGVydHkoICJ0YXJnZXRzRmlsZSIsIHRhcmdldHMuZ2V0QWJzb2x1dGVQYXRoKCkgKTsKCiAgICAgICAgICAgICAgICB0cnkgeyAvLyB0byByZWFkIGV4aXN0aW5nIHByb3BlcnRpZXNmaWxlCiAgICAgICAgICAgICAgICAgICAgaUNvbnRyb2xQcm9wcy5zdG9yZSggbmV3IEZpbGVPdXRwdXRTdHJlYW0oICJpY29udHJvbC5wcm9wZXJ0aWVzIiApLCBJQ09OVFJPTF9QUk9QRVJUSUVTX0hFQURFUiApOwogICAgICAgICAgICAgICAgICAgIGxvZyggIlVwZGF0ZWQgaWNvbnRyb2wucHJvcGVydGllcyIgKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2goIElPRXhjZXB0aW9uIGUgKSB7CiAgICAgICAgICAgICAgICAgICAgbG9nKCAiQ291bGRuJ3Qgd3JpdGUgaWNvbnRyb2wucHJvcGVydGllcy4iICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGRvIGl0IQogICAgICAgICAgICBpbnQgcmVzdWx0ID0gaUNvbnRyYWN0LmV4ZWN1dGVKYXZhKCk7CiAgICAgICAgICAgIGlmKCByZXN1bHQgIT0gMCApIHsKICAgICAgICAgICAgICAgIGlmKCBpQ29udHJhY3RNaXNzaW5nICkgewogICAgICAgICAgICAgICAgICAgIGxvZyggImlDb250cmFjdCBjYW4ndCBiZSBmb3VuZCBvbiB5b3VyIGNsYXNzcGF0aC4gWW91ciBjbGFzc3BhdGggaXM6IiApOwogICAgICAgICAgICAgICAgICAgIGxvZyggY2xhc3NwYXRoLnRvU3RyaW5nKCkgKTsKICAgICAgICAgICAgICAgICAgICBsb2coICJJZiB5b3UgZG9uJ3QgaGF2ZSB0aGUgaUNvbnRyYWN0IGphciwgZ28gZ2V0IGl0IGF0IGh0dHA6Ly93d3cucmVsaWFibGUtc3lzdGVtcy5jb20vdG9vbHMvIiApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEJ1aWxkRXhjZXB0aW9uKCAiaUNvbnRyYWN0IGluc3RydW1lbnRhdGlvbiBmYWlsZWQuIENvZGU9IiArIHJlc3VsdCApOwogICAgICAgICAgICB9CgogICAgICAgIH0gZWxzZSB7IC8vIG5vdCBkaXJ0eQogICAgICAgICAgICAvL2xvZyggIk5vdGhpbmcgdG8gZG8uIEV2ZXJ5dGhpbmcgdXAgdG8gZGF0ZS4iICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2tzIHRoYXQgdGhlIHJlcXVpcmVkIGF0dHJpYnV0ZXMgYXJlIHNldC4KICAgICAqLwogICAgcHJpdmF0ZSB2b2lkIHByZWNvbmRpdGlvbnMoKSB0aHJvd3MgQnVpbGRFeGNlcHRpb24gewogICAgICAgIGlmIChzcmNEaXIgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQnVpbGRFeGNlcHRpb24oICJzcmNkaXIgYXR0cmlidXRlIG11c3QgYmUgc2V0ISIsIGxvY2F0aW9uICk7CiAgICAgICAgfQogICAgICAgIGlmICghc3JjRGlyLmV4aXN0cygpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBCdWlsZEV4Y2VwdGlvbiggInNyY2RpciBcIiIgKyBzcmNEaXIuZ2V0UGF0aCgpICsgIlwiIGRvZXMgbm90IGV4aXN0ISIsIGxvY2F0aW9uICk7CiAgICAgICAgfQogICAgICAgIGlmIChpbnN0cnVtZW50RGlyID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEJ1aWxkRXhjZXB0aW9uKCAiaW5zdHJ1bWVudGRpciBhdHRyaWJ1dGUgbXVzdCBiZSBzZXQhIiwgbG9jYXRpb24gKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcG9zaXRvcnlEaXIgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQnVpbGRFeGNlcHRpb24oICJyZXBvc2l0b3J5ZGlyIGF0dHJpYnV0ZSBtdXN0IGJlIHNldCEiLCBsb2NhdGlvbiApOwogICAgICAgIH0KICAgICAgICBpZiAodXBkYXRlSWNvbnRyb2wgPT0gdHJ1ZSAmJiBjbGFzc0RpciA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBCdWlsZEV4Y2VwdGlvbiggImNsYXNzZGlyIGF0dHJpYnV0ZSBtdXN0IGJlIHNwZWNpZmllZCB3aGVuIHVwZGF0ZWljb250cm9sPXRydWUhIiwgbG9jYXRpb24gKTsKICAgICAgICB9CiAgICAgICAgaWYoIHVwZGF0ZUljb250cm9sID09IHRydWUgJiYgY29udHJvbEZpbGUgPT0gbnVsbCApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEJ1aWxkRXhjZXB0aW9uKCAiY29udHJvbGZpbGUgYXR0cmlidXRlIG11c3QgYmUgc3BlY2lmaWVkIHdoZW4gdXBkYXRlaWNvbnRyb2w9dHJ1ZSEiLCBsb2NhdGlvbiApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFZlcmlmaWVzIHdoZXRoZXIgYW55IG9mIHRoZSBzb3VyY2UgZmlsZXMgaGF2ZSBjaGFuZ2VkLiBEb25lIGJ5IGNvbXBhcmluZyBkYXRlIG9mIHNvdXJjZS9jbGFzcyBmaWxlcy4KICAgICAqIFRoZSB3aG9sZSBsb3QgaXMgImRpcnR5IiBpZiBhdCBsZWFzdCBvbmUgc291cmNlIGZpbGUgb3IgdGhlIGNvbnRyb2wgZmlsZSBpcyBuZXdlciB0aGFuIHRoZSBpbnN0cnVtZW50ZWQKICAgICAqIGZpbGVzLiBJZiBub3QgZGlydHksIGlDb250cmFjdCB3aWxsIG5vdCBiZSBleGVjdXRlZC4KICAgICAqIDxici8+CiAgICAgKiBBbHNvIGNyZWF0ZXMgYSB0ZW1wb3JhcnkgZmlsZSB3aXRoIGEgbGlzdCBvZiB0aGUgc291cmNlIGZpbGVzLCB0aGF0IHdpbGwgYmUgZGVsZXRlZCB1cG9uIGV4aXQuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBzY2FuKCkgdGhyb3dzIEJ1aWxkRXhjZXB0aW9uIHsKICAgICAgICBsb25nIG5vdyA9IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7CgogICAgICAgIERpcmVjdG9yeVNjYW5uZXIgZHMgPSBudWxsOwoKICAgICAgICBkcyA9IGdldERpcmVjdG9yeVNjYW5uZXIoIHNyY0RpciApOwogICAgICAgIFN0cmluZ1tdIGZpbGVzID0gZHMuZ2V0SW5jbHVkZWRGaWxlcygpOwoKICAgICAgICBGaWxlT3V0cHV0U3RyZWFtIHRhcmdldE91dHB1dFN0cmVhbSA9IG51bGw7CiAgICAgICAgUHJpbnRTdHJlYW0gdGFyZ2V0UHJpbnRlciA9IG51bGw7CiAgICAgICAgYm9vbGVhbiB3cml0ZVRhcmdldHMgPSBmYWxzZTsKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiggdGFyZ2V0cyA9PSBudWxsICkgewogICAgICAgICAgICAgICAgdGFyZ2V0cyA9IG5ldyBGaWxlKCAidGFyZ2V0cyIgKTsKICAgICAgICAgICAgICAgIGxvZyggIldhcm5pbmc6IHRhcmdldHMgZmlsZSBub3Qgc3BlY2lmaWVkLiBnZW5lcmF0aW5nIGZpbGU6ICIgKyB0YXJnZXRzLmdldE5hbWUoKSApOwogICAgICAgICAgICAgICAgd3JpdGVUYXJnZXRzID0gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIGlmKCAhdGFyZ2V0cy5leGlzdHMoKSApIHsKICAgICAgICAgICAgICAgIGxvZyggIlNwZWNpZmllZCB0YXJnZXRzIGZpbGUgZG9lc24ndCBleGlzdC4gZ2VuZXJhdGluZyBmaWxlOiAiICsgdGFyZ2V0cy5nZXROYW1lKCkgKTsKICAgICAgICAgICAgICAgIHdyaXRlVGFyZ2V0cyA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoIHdyaXRlVGFyZ2V0cyApIHsKICAgICAgICAgICAgICAgIGxvZyggIllvdSBzaG91bGQgY29uc2lkZXIgdXNpbmcgaUNvbnRyb2wgdG8gY3JlYXRlIGEgdGFyZ2V0IGZpbGUuIiApOwogICAgICAgICAgICAgICAgdGFyZ2V0T3V0cHV0U3RyZWFtID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oIHRhcmdldHMgKTsKICAgICAgICAgICAgICAgIHRhcmdldFByaW50ZXIgPSBuZXcgUHJpbnRTdHJlYW0oIHRhcmdldE91dHB1dFN0cmVhbSApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKysgKSB7CiAgICAgICAgICAgICAgICBGaWxlIHNyY0ZpbGUgPSBuZXcgRmlsZShzcmNEaXIsIGZpbGVzW2ldKTsKICAgICAgICAgICAgICAgIGlmIChmaWxlc1tpXS5lbmRzV2l0aCgiLmphdmEiKSkgewogICAgICAgICAgICAgICAgICAgIC8vIHByaW50IHRoZSB0YXJnZXQsIHdoaWxlIHdlJ3JlIGF0IGhlcmUuIChPbmx5IGlmIGdlbmVyYXRldGFyZ2V0PXRydWUpLgogICAgICAgICAgICAgICAgICAgIGlmKCB0YXJnZXRQcmludGVyICE9IG51bGwgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFByaW50ZXIucHJpbnRsbiggc3JjRmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBGaWxlIGNsYXNzRmlsZSA9IG5ldyBGaWxlKCBidWlsZERpciwgZmlsZXNbaV0uc3Vic3RyaW5nKCAwLCBmaWxlc1tpXS5pbmRleE9mKCAiLmphdmEiICkgKSArICIuY2xhc3MiICk7CgogICAgICAgICAgICAgICAgICAgIGlmIChzcmNGaWxlLmxhc3RNb2RpZmllZCgpID4gbm93KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZygiV2FybmluZzogZmlsZSBtb2RpZmllZCBpbiB0aGUgZnV0dXJlOiAiICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzW2ldLCBQcm9qZWN0Lk1TR19XQVJOKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICghY2xhc3NGaWxlLmV4aXN0cygpIHx8IHNyY0ZpbGUubGFzdE1vZGlmaWVkKCkgPiBjbGFzc0ZpbGUubGFzdE1vZGlmaWVkKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9sb2coICJGb3VuZCBhIGZpbGUgbmV3ZXIgdGhhbiB0aGUgaW5zdHJ1bWVudERpciBjbGFzcyBmaWxlOiAiICsgc3JjRmlsZS5nZXRQYXRoKCkgKyAiIG5ld2VyIHRoYW4gIiArIGNsYXNzRmlsZS5nZXRQYXRoKCkgKyAiLiBSdW5uaW5nIGlDb250cmFjdCBhZ2Fpbi4uLiIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGlydHkgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiggdGFyZ2V0UHJpbnRlciAhPSBudWxsICkgewogICAgICAgICAgICAgICAgdGFyZ2V0UHJpbnRlci5mbHVzaCgpOwogICAgICAgICAgICAgICAgdGFyZ2V0UHJpbnRlci5jbG9zZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCggSU9FeGNlcHRpb24gZSApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEJ1aWxkRXhjZXB0aW9uKCAiQ291bGQgbm90IGNyZWF0ZSB0YXJnZXQgZmlsZToiICsgZS5nZXRNZXNzYWdlKCkgKTsKICAgICAgICB9CgogICAgICAgIC8vIGFsc28sIGNoZWNrIGNvbnRyb2xGaWxlIHRpbWVzdGFtcAogICAgICAgIGxvbmcgY29udHJvbEZpbGVUaW1lID0gLTE7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYoIGNvbnRyb2xGaWxlICE9IG51bGwgKSB7CiAgICAgICAgICAgICAgICBpZiggY29udHJvbEZpbGUuZXhpc3RzKCkgJiYgYnVpbGREaXIuZXhpc3RzKCkgKSB7CiAgICAgICAgICAgICAgICAgICAgY29udHJvbEZpbGVUaW1lID0gY29udHJvbEZpbGUubGFzdE1vZGlmaWVkKCk7CiAgICAgICAgICAgICAgICAgICAgZHMgPSBnZXREaXJlY3RvcnlTY2FubmVyKCBidWlsZERpciApOwogICAgICAgICAgICAgICAgICAgIGZpbGVzID0gZHMuZ2V0SW5jbHVkZWRGaWxlcygpOwogICAgICAgICAgICAgICAgICAgIGZvciggaW50IGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKysgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEZpbGUgc3JjRmlsZSA9IG5ldyBGaWxlKCBzcmNEaXIsIGZpbGVzW2ldICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBmaWxlc1tpXS5lbmRzV2l0aCggIi5jbGFzcyIgKSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBjb250cm9sRmlsZVRpbWUgPiBzcmNGaWxlLmxhc3RNb2RpZmllZCgpICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCAhZGlydHkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZyggIkNvbnRyb2wgZmlsZSAiICsgY29udHJvbEZpbGUuZ2V0QWJzb2x1dGVQYXRoKCkgKyAiIGhhcyBiZWVuIHVwZGF0ZWQuIEluc3RydW1lbnRpbmcgYWxsIGZpbGVzLi4uIiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJ0eSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdHJ1bWVudGFsbCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoKCBUaHJvd2FibGUgdCApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEJ1aWxkRXhjZXB0aW9uKCAiR290IGFuIGludGVyZXN0aW5nIGV4Y2VwdGlvbjoiICsgdC5nZXRNZXNzYWdlKCkgKTsKICAgICAgICB9CiAgICB9CgoKICAgIC8qKgogICAgICogQ3JlYXRlcyB0aGUgLW0gb3B0aW9uIGJhc2VkIG9uIHRoZSB2YWx1ZXMgb2YgY29udHJvbEZpbGUsIHByZSwgcG9zdCBhbmQgaW52YXJpYW50LgogICAgICovCiAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBkaXJlY3RpdmVTdHJpbmcoKSB7CiAgICAgICAgU3RyaW5nQnVmZmVyIHNiID0gbmV3IFN0cmluZ0J1ZmZlcigpOwogICAgICAgIGJvb2xlYW4gY29tbWEgPSBmYWxzZTsKCiAgICAgICAgYm9vbGVhbiB1c2VDb250cm9sRmlsZSA9IChjb250cm9sRmlsZSAhPSBudWxsKSAmJiBjb250cm9sRmlsZS5leGlzdHMoKTsKICAgICAgICBpZiggdXNlQ29udHJvbEZpbGUgfHwgcHJlIHx8IHBvc3QgfHwgaW52YXJpYW50ICkgewogICAgICAgICAgICBzYi5hcHBlbmQoICItbSIgKTsKICAgICAgICB9CiAgICAgICAgaWYoIHVzZUNvbnRyb2xGaWxlICkgewogICAgICAgICAgICBzYi5hcHBlbmQoICJAIiApLmFwcGVuZCggY29udHJvbEZpbGUgKTsKICAgICAgICAgICAgY29tbWEgPSB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiggcHJlICkgewogICAgICAgICAgICBpZiggY29tbWEgKSB7CiAgICAgICAgICAgICAgICBzYi5hcHBlbmQoICIsIiApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNiLmFwcGVuZCggInByZSIgKTsKICAgICAgICAgICAgY29tbWEgPSB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiggcG9zdCApIHsKICAgICAgICAgICAgaWYoIGNvbW1hICkgewogICAgICAgICAgICAgICAgc2IuYXBwZW5kKCAiLCIgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzYi5hcHBlbmQoICJwb3N0IiApOwogICAgICAgICAgICBjb21tYSA9IHRydWU7CiAgICAgICAgfQogICAgICAgIGlmKCBpbnZhcmlhbnQgKSB7CiAgICAgICAgICAgIGlmKCBjb21tYSApIHsKICAgICAgICAgICAgICAgIHNiLmFwcGVuZCggIiwiICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2IuYXBwZW5kKCAiaW52IiApOwogICAgICAgIH0KICAgICAgICBzYi5hcHBlbmQoICIgIiApOwogICAgICAgIHJldHVybiBzYi50b1N0cmluZygpOwogICAgfQoKICAgIC8qKgogICAgICogQnVpbGRMaXN0ZW5lciB0aGF0IHNldHMgdGhlIGlDb250cmFjdE1pc3NpbmcgZmxhZyB0byB0cnVlIGlmIGEKICAgICAqIG1lc3NhZ2UgYWJvdXQgbWlzc2luZyBpQ29udHJhY3QgaXMgbWlzc2luZy4gVXNlZCB0byBpbmRpY2F0ZQogICAgICogYSBtb3JlIHZlcmJvc2UgZXJyb3IgdG8gdGhlIHVzZXIsIHdpdGggYWR2aWNlIGFib3V0IGhvdyB0byBzb2x2ZQogICAgICogdGhlIHByb2JsZW0KICAgICAqLwogICAgcHJpdmF0ZSBjbGFzcyBJQ29udHJhY3RQcmVzZW5jZURldGVjdG9yIGltcGxlbWVudHMgQnVpbGRMaXN0ZW5lciB7CiAgICAgICAgcHVibGljIHZvaWQgYnVpbGRGaW5pc2hlZChCdWlsZEV2ZW50IGV2ZW50KSB7fQogICAgICAgIHB1YmxpYyB2b2lkIGJ1aWxkU3RhcnRlZChCdWlsZEV2ZW50IGV2ZW50KSB7fQogICAgICAgIHB1YmxpYyB2b2lkIG1lc3NhZ2VMb2dnZWQoQnVpbGRFdmVudCBldmVudCkgewogICAgICAgICAgICBpZiggImphdmEubGFuZy5Ob0NsYXNzRGVmRm91bmRFcnJvcjogY29tL3JlbGlhYmxlc3lzdGVtcy9pQ29udHJhY3QvVG9vbCIuZXF1YWxzKCBldmVudC5nZXRNZXNzYWdlKCkgKSApIHsKICAgICAgICAgICAgICAgIGlDb250cmFjdE1pc3NpbmcgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIHRhcmdldEZpbmlzaGVkKEJ1aWxkRXZlbnQgZXZlbnQpIHt9CiAgICAgICAgcHVibGljIHZvaWQgdGFyZ2V0U3RhcnRlZChCdWlsZEV2ZW50IGV2ZW50KSB7fQogICAgICAgIHB1YmxpYyB2b2lkIHRhc2tGaW5pc2hlZChCdWlsZEV2ZW50IGV2ZW50KSB7fQogICAgICAgIHB1YmxpYyB2b2lkIHRhc2tTdGFydGVkKEJ1aWxkRXZlbnQgZXZlbnQpIHt9CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGlzIGNsYXNzIGlzIGEgaGVscGVyIHRvIHNldCBjb3JyZWN0IGNsYXNzcGF0aCBmb3Igb3RoZXIgY29tcGlsZXJzLCBsaWtlIEppa2VzLgogICAgICogSXQgcmV1c2VzIHRoZSBsb2dpYyBmcm9tIERlZmF1bHRDb21waWxlckFkYXB0ZXIsIHdoaWNoIGlzIHByb3RlY3RlZCwgc28gd2UgaGF2ZQogICAgICogdG8gc3ViY2xhc3MgaXQuCiAgICAgKi8KICAgIHByaXZhdGUgY2xhc3MgQ2xhc3NwYXRoSGVscGVyIGV4dGVuZHMgRGVmYXVsdENvbXBpbGVyQWRhcHRlciB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgY29tcGlsZXI7CiAgICAgICAgcHVibGljIENsYXNzcGF0aEhlbHBlciggU3RyaW5nIGNvbXBpbGVyICkgewogICAgICAgICAgICBzdXBlcigpOwogICAgICAgICAgICB0aGlzLmNvbXBpbGVyID0gY29tcGlsZXI7CiAgICAgICAgfQoKICAgICAgICAvLyBtYWtlIGl0IHB1YmxpYwogICAgICAgIHB1YmxpYyB2b2lkIG1vZGlmeSggUGF0aCBwYXRoICkgewogICAgICAgICAgICAvLyBkZXBlbmRpbmcgb24gd2hhdCBjb21waWxlciB0byB1c2UsIHNldCB0aGUgaW5jbHVkZUphdmFSdW50aW1lIGZsYWcKICAgICAgICAgICAgaWYoICJqaWtlcyIuZXF1YWxzKCBjb21waWxlciApICkgewogICAgICAgICAgICAgICAgaWNDb21waWxlciA9IGNvbXBpbGVyOwogICAgICAgICAgICAgICAgaW5jbHVkZUphdmFSdW50aW1lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHBhdGguYXBwZW5kKCBnZXRDb21waWxlQ2xhc3NwYXRoKCkgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gZHVtbXkgaW1wbGVtZW50YXRpb24uIE5ldmVyIGNhbGxlZAogICAgICAgIHB1YmxpYyB2b2lkIHNldEphdmFjKCBKYXZhYyBqYXZhYyApIHt9CiAgICAgICAgcHVibGljIGJvb2xlYW4gZXhlY3V0ZSgpIHsgcmV0dXJuIHRydWU7IH0KICAgIH0KfQo=