LyoKKiBDb3B5cmlnaHQgqSB7MTk5Ny0xOTk5fSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqCiogRmlsZSBNU0dGTVQuSAoqCiogTW9kaWZpY2F0aW9uIEhpc3Rvcnk6CioKKiAgIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogICAwMi8xOS85NyAgICBhbGl1ICAgICAgICBDb252ZXJ0ZWQgZnJvbSBqYXZhLgoqICAgMDMvMjAvOTcgICAgaGVsZW5hICAgICAgRmluaXNoZWQgZmlyc3QgY3V0IG9mIGltcGxlbWVudGF0aW9uLgoqICAgIDA3LzIyLzk4ICAgIHN0ZXBoZW4gICAgICAgIFJlbW92ZWQgb3BlcmF0b3IhPSAoZGVmaW5lZCBpbiBGb3JtYXQpCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vIFRoaXMgZmlsZSB3YXMgZ2VuZXJhdGVkIGZyb20gdGhlIGphdmEgc291cmNlIGZpbGUgTWVzc2FnZUZvcm1hdC5qYXZhCi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAKI2lmbmRlZiBNU0dGTVRfSAojZGVmaW5lIE1TR0ZNVF9ICiAKI2luY2x1ZGUgInVuaWNvZGUvdXR5cGVzLmgiCiNpbmNsdWRlICJ1bmljb2RlL2Zvcm1hdC5oIgojaW5jbHVkZSAidW5pY29kZS9sb2NpZC5oIgpjbGFzcyBOdW1iZXJGb3JtYXQ7CgovKioKICogUHJvdmlkZXMgbWVhbnMgdG8gcHJvZHVjZSBjb25jYXRlbmF0ZWQgbWVzc2FnZXMgaW4gbGFuZ3VhZ2UtbmV1dHJhbCB3YXkuCiAqIFVzZSB0aGlzIGZvciBhbGwgY29uY2F0ZW5hdGlvbnMgdGhhdCBzaG93IHVwIHRvIGVuZCB1c2Vycy4KICogPFA+CiAqIFRha2VzIGEgc2V0IG9mIG9iamVjdHMsIGZvcm1hdHMgdGhlbSwgdGhlbiBpbnNlcnRzIHRoZSBmb3JtYXR0ZWQKICogc3RyaW5ncyBpbnRvIHRoZSBwYXR0ZXJuIGF0IHRoZSBhcHByb3ByaWF0ZSBwbGFjZXMuCiAqIDxQPgogKiBIZXJlIGFyZSBzb21lIGV4YW1wbGVzIG9mIHVzYWdlOgogKiBFeGFtcGxlIDE6CiAqIDxwcmU+CiAqIC4gICAgVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwogKiAuICAgIEdyZWdvcmlhbkNhbGVuZGFyIGNhbChzdWNjZXNzKTsKICogLiAgICBGb3JtYXR0YWJsZSBhcmd1bWVudHNbXSA9IHsKICogLiAgICAgICAgN0wsCiAqIC4gICAgICAgIEZvcm1hdHRhYmxlKCAoRGF0ZSkgY2FsLmdldFRpbWUoc3VjY2VzcyksIEZvcm1hdHRhYmxlOjprSXNEYXRlKSwKICogLiAgICAgICAgImEgZGlzdHVyYmFuY2UgaW4gdGhlIEZvcmNlIgogKiAuICAgIH07CiAqIC4gICAgCiAqIC4gICAgVW5pY29kZVN0cmluZyByZXN1bHQ7CiAqIC4gICAgTWVzc2FnZUZvcm1hdDo6Zm9ybWF0KAogKiAuICAgICAgICAgIkF0IHsxLHRpbWV9IG9uIHsxLGRhdGV9LCB0aGVyZSB3YXMgezJ9IG9uIHBsYW5ldCB7MCxudW1iZXJ9LiIsCiAqIC4gICAgICAgICBhcmd1bWVudHMsIDMsIHJlc3VsdCwgc3VjY2VzcyApOwogKiAuICAgIAogKiAuICAgIGNvdXQgJmx0OyZsdDsgInJlc3VsdDogIiAmbHQ7Jmx0OyByZXN1bHQgJmx0OyZsdDsgZW5kbDsKICogLiAgICAvLyZsdDtvdXRwdXQ+OiBBdCA0OjM0OjIwIFBNIG9uIDIzLU1hci05OCwgdGhlcmUgd2FzIGEgZGlzdHVyYmFuY2UKICogLiAgICAvLyAgICAgICAgICAgICBpbiB0aGUgRm9yY2Ugb24gcGxhbmV0IDcuCiAqIDwvcHJlPiAgCiAqIFR5cGljYWxseSwgdGhlIG1lc3NhZ2UgZm9ybWF0IHdpbGwgY29tZSBmcm9tIHJlc291cmNlcywgYW5kIHRoZQogKiBhcmd1bWVudHMgd2lsbCBiZSBkeW5hbWljYWxseSBzZXQgYXQgcnVudGltZS4KICogPFA+CiAqIEV4YW1wbGUgMjoKICogPHByZT4KICogLiAgICBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwogKiAuICAgIEZvcm1hdHRhYmxlIHRlc3RBcmdzW10gPSB7M0wsICJNeURpc2sifTsKICogLiAgIAogKiAuICAgIE1lc3NhZ2VGb3JtYXQqIGZvcm0gPSBuZXcgTWVzc2FnZUZvcm1hdCgKICogLiAgICAgICAgIlRoZSBkaXNrIFwiezF9XCIgY29udGFpbnMgezB9IGZpbGUocykuIiwgc3VjY2VzcyApOwogKiAuICAgICAgICAKICogLiAgICBVbmljb2RlU3RyaW5nIHN0cmluZzsKICogLiAgICBGaWVsZFBvc2l0aW9uIGZwb3MgPSAwOwogKiAuICAgIGNvdXQgJmx0OyZsdDsgImZvcm1hdDogIiAmbHQ7Jmx0OyBmb3JtLT5mb3JtYXQodGVzdEFyZ3MsIDIsIHN0cmluZywgZnBvcywgc3VjY2VzcyApICZsdDsmbHQ7IGVuZGw7CiAqIC4KICogLiAgICAvLyBvdXRwdXQsIHdpdGggZGlmZmVyZW50IHRlc3RBcmdzOgogKiAuICAgIC8vIG91dHB1dDogVGhlIGRpc2sgIk15RGlzayIgY29udGFpbnMgMCBmaWxlKHMpLgogKiAuICAgIC8vIG91dHB1dDogVGhlIGRpc2sgIk15RGlzayIgY29udGFpbnMgMSBmaWxlKHMpLgogKiAuICAgIC8vIG91dHB1dDogVGhlIGRpc2sgIk15RGlzayIgY29udGFpbnMgMSwyNzMgZmlsZShzKS4KICogLiAgICBkZSBsZXRlIGZvcm07CiAqICA8L3ByZT4KICoKICogIFRoZSBwYXR0ZXJuIGlzIG9mIHRoZSBmb2xsb3dpbmcgZm9ybS4gIExlZ2VuZDoKICogIDxwcmU+CiAqIC4gICAgICB7b3B0aW9uYWwgaXRlbX0KICogLiAgICAgIChncm91cCB0aGF0IG1heSBiZSByZXBlYXRlZCkqCiAqICA8L3ByZT4KICogIERvIG5vdCBjb25mdXNlIG9wdGlvbmFsIGl0ZW1zIHdpdGggaXRlbXMgaW5zaWRlIHF1b3RlcyBicmFjZXMsIHN1Y2gKICogIGFzIHRoaXM6ICJ7Ii4gIFF1b3RlZCBicmFjZXMgYXJlIGxpdGVyYWxzLgogKiAgPHByZT4KICogLiAgICAgIG1lc3NhZ2VGb3JtYXRQYXR0ZXJuIDo9IHN0cmluZyAoICJ7IiBtZXNzYWdlRm9ybWF0RWxlbWVudCAifSIgc3RyaW5nICkqCiAqIC4gICAgICAgCiAqIC4gICAgICBtZXNzYWdlRm9ybWF0RWxlbWVudCA6PSBhcmd1bWVudCB7ICIsIiBlbGVtZW50Rm9ybWF0IH0KICogLiAgICAgICAKICogLiAgICAgIGVsZW1lbnRGb3JtYXQgOj0gInRpbWUiIHsgIiwiIGRhdGV0aW1lU3R5bGUgfQogKiAuICAgICAgICAgICAgICAgICAgICAgfCAiZGF0ZSIgeyAiLCIgZGF0ZXRpbWVTdHlsZSB9CiAqIC4gICAgICAgICAgICAgICAgICAgICB8ICJudW1iZXIiIHsgIiwiIG51bWJlclN0eWxlIH0KICogLiAgICAgICAgICAgICAgICAgICAgIHwgImNob2ljZSIgIiwiIGNob2ljZVN0eWxlCiAqIC4gIAogKiAuICAgICAgZGF0ZXRpbWVTdHlsZSA6PSAic2hvcnQiCiAqIC4gICAgICAgICAgICAgICAgICAgICB8ICJtZWRpdW0iCiAqIC4gICAgICAgICAgICAgICAgICAgICB8ICJsb25nIgogKiAuICAgICAgICAgICAgICAgICAgICAgfCAiZnVsbCIKICogLiAgICAgICAgICAgICAgICAgICAgIHwgZGF0ZUZvcm1hdFBhdHRlcm4KICogLgogKiAuICAgICAgbnVtYmVyU3R5bGUgOj0gICAiY3VycmVuY3kiCiAqIC4gICAgICAgICAgICAgICAgICAgICB8ICJwZXJjZW50IgogKiAuICAgICAgICAgICAgICAgICAgICAgfCAiaW50ZWdlciIKICogLiAgICAgICAgICAgICAgICAgICAgIHwgbnVtYmVyRm9ybWF0UGF0dGVybgogKiAuIAogKiAuICAgICAgY2hvaWNlU3R5bGUgOj0gICBjaG9pY2VGb3JtYXRQYXR0ZXJuCiAqIDwvcHJlPgogKiBJZiB0aGVyZSBpcyBubyBlbGVtZW50Rm9ybWF0LCB0aGVuIHRoZSBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLAogKiB3aGljaCBpcyBzdWJzdGl0dXRlZC4gSWYgdGhlcmUgaXMgbm8gZGF0ZVRpbWVTdHlsZSBvciBudW1iZXJTdHlsZSwKICogdGhlbiB0aGUgZGVmYXVsdCBmb3JtYXQgaXMgdXNlZCAoZS5nLiAgTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCksCiAqIERhdGVGb3JtYXQuZ2V0RGVmYXVsdFRpbWUoKSBvciBEYXRlRm9ybWF0LmdldERlZmF1bHREYXRlKCkuIEZvcgogKiBhIENob2ljZUZvcm1hdCwgdGhlIHBhdHRlcm4gbXVzdCBhbHdheXMgYmUgc3BlY2lmaWVkLCBzaW5jZSB0aGVyZQogKiBpcyBubyBkZWZhdWx0LgogKiA8UD4KICogSW4gc3RyaW5ncywgc2luZ2xlIHF1b3RlcyBjYW4gYmUgdXNlZCB0byBxdW90ZSB0aGUgInsiIHNpZ24gaWYKICogbmVjZXNzYXJ5LiBBIHJlYWwgc2luZ2xlIHF1b3RlIGlzIHJlcHJlc2VudGVkIGJ5ICcnLiAgSW5zaWRlIGEKICogbWVzc2FnZUZvcm1hdEVsZW1lbnQsIHF1b3RlcyBhcmUgW25vdF0gcmVtb3ZlZC4gRm9yIGV4YW1wbGUsCiAqIHsxLG51bWJlciwkJyMnLCMjfSB3aWxsIHByb2R1Y2UgYSBudW1iZXIgZm9ybWF0IHdpdGggdGhlIHBvdW5kLXNpZ24KICogcXVvdGVkLCB3aXRoIGEgcmVzdWx0IHN1Y2ggYXM6ICIkIzMxLDQ1Ii4KICogPFA+CiAqIElmIGEgcGF0dGVybiBpcyB1c2VkLCB0aGVuIHVucXVvdGVkIGJyYWNlcyBpbiB0aGUgcGF0dGVybiwgaWYgYW55LAogKiBtdXN0IG1hdGNoOiB0aGF0IGlzLCAiYWIgezB9IGRlIiBhbmQgImFiICd9JyBkZSIgYXJlIG9rLCBidXQgImFiCiAqIHswJ30nIGRlIiBhbmQgImFiIH0gZGUiIGFyZSBub3QuCiAqIDxQPgogKiBUaGUgYXJndW1lbnQgaXMgYSBudW1iZXIgZnJvbSAwIHRvIDksIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZQogKiBhcmd1bWVudHMgcHJlc2VudGVkIGluIGFuIGFycmF5IHRvIGJlIGZvcm1hdHRlZC4KICogPFA+CiAqIEl0IGlzIG9rIHRvIGhhdmUgdW51c2VkIGFyZ3VtZW50cyBpbiB0aGUgYXJyYXkuICBXaXRoIG1pc3NpbmcKICogYXJndW1lbnRzIG9yIGFyZ3VtZW50cyB0aGF0IGFyZSBub3Qgb2YgdGhlIHJpZ2h0IGNsYXNzIGZvciB0aGUKICogc3BlY2lmaWVkIGZvcm1hdCwgYSBmYWlsaW5nIFVFcnJvckNvZGUgcmVzdWx0IGlzIHNldC4KICogPFA+CiAqIEZvciBtb3JlIHNvcGhpc3RpY2F0ZWQgcGF0dGVybnMsIHlvdSBjYW4gdXNlIGEgQ2hvaWNlRm9ybWF0IHRvIGdldAogKiBvdXRwdXQgc3VjaCBhczoKICogPHByZT4KICogLiAgICBVRXJyb3JDb2RlIHN1Y2Nlc3MgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgTWVzc2FnZUZvcm1hdCogZm9ybSA9IG5ldyBNZXNzYWdlRm9ybWF0KCJUaGUgZGlzayBcInsxfVwiIGNvbnRhaW5zIHswfS4iLCBzdWNjZXNzKTsKICogLiAgICBkb3VibGUgZmlsZWxpbWl0c1tdID0gezAsMSwyfTsKICogLiAgICBVbmljb2RlU3RyaW5nIGZpbGVwYXJ0W10gPSB7Im5vIGZpbGVzIiwib25lIGZpbGUiLCJ7MCxudW1iZXJ9IGZpbGVzIn07CiAqIC4gICAgQ2hvaWNlRm9ybWF0KiBmaWxlZm9ybSA9IG5ldyBDaG9pY2VGb3JtYXQoZmlsZWxpbWl0cywgZmlsZXBhcnQsIDMpOwogKiAuICAgIGZvcm0tPnNldEZvcm1hdCgxLCAqZmlsZWZvcm0pOyAvLyBOT1QgemVybywgc2VlIGJlbG93CiAqIC4gICAgCiAqIC4gICAgRm9ybWF0dGFibGUgdGVzdEFyZ3NbXSA9IHsxMjczTCwgIk15RGlzayJ9OwogKiAuICAgICAKICogLiAgICBVbmljb2RlU3RyaW5nIHN0cmluZzsKICogLiAgICBGaWVsZFBvc2l0aW9uIGZwb3MgPSAwOwogKiAuICAgIGNvdXQgJmx0OyZsdDsgZm9ybS0+Zm9ybWF0KHRlc3RBcmdzLCAyLCBzdHJpbmcsIGZwb3MsIHN1Y2Nlc3MpICZsdDsmbHQ7IGVuZGw7CiAqIC4gICAgCiAqIC4gICAgLy8gb3V0cHV0LCB3aXRoIGRpZmZlcmVudCB0ZXN0QXJncwogKiAuICAgIC8vIG91dHB1dDogVGhlIGRpc2sgIk15RGlzayIgY29udGFpbnMgbm8gZmlsZXMuCiAqIC4gICAgLy8gb3V0cHV0OiBUaGUgZGlzayAiTXlEaXNrIiBjb250YWlucyBvbmUgZmlsZS4KICogLiAgICAvLyBvdXRwdXQ6IFRoZSBkaXNrICJNeURpc2siIGNvbnRhaW5zIDEsMjczIGZpbGVzLgogKiA8L3ByZT4KICogWW91IGNhbiBlaXRoZXIgZG8gdGhpcyBwcm9ncmFtbWF0aWNhbGx5LCBhcyBpbiB0aGUgYWJvdmUgZXhhbXBsZSwKICogb3IgYnkgdXNpbmcgYSBwYXR0ZXJuIChzZWUgQ2hvaWNlRm9ybWF0IGZvciBtb3JlIGluZm9ybWF0aW9uKSBhcyBpbjoKICogPHByZT4KICogLiAgIGZvcm0tPmFwcGx5UGF0dGVybigKICogLiAgICAgIlRoZXJlIHswLGNob2ljZSwwI2FyZSBubyBmaWxlc3wxI2lzIG9uZSBmaWxlfDEmbHQ7YXJlIHswLG51bWJlcixpbnRlZ2VyfSBmaWxlc30uIik7CiAqIDwvcHJlPgogKiA8UD4KICogW05vdGU6XSBBcyB3ZSBzZWUgYWJvdmUsIHRoZSBzdHJpbmcgcHJvZHVjZWQgYnkgYSBDaG9pY2VGb3JtYXQgaW4KICogTWVzc2FnZUZvcm1hdCBpcyB0cmVhdGVkIHNwZWNpYWxseTsgb2NjdXJhbmNlcyBvZiAneycgYXJlIHVzZWQgdG8KICogaW5kaWNhdGVkIHN1YmZvcm1hdHMsIGFuZCBjYXVzZSByZWN1cnNpb24uICBJZiB5b3UgY3JlYXRlIGJvdGggYQogKiBNZXNzYWdlRm9ybWF0IGFuZCBDaG9pY2VGb3JtYXQgcHJvZ3JhbW1hdGljYWxseSAoaW5zdGVhZCBvZiB1c2luZwogKiB0aGUgc3RyaW5nIHBhdHRlcm5zKSwgdGhlbiBiZSBjYXJlZnVsIG5vdCB0byBwcm9kdWNlIGEgZm9ybWF0IHRoYXQKICogcmVjdXJzZXMgb24gaXRzZWxmLCB3aGljaCB3aWxsIGNhdXNlIGFuIGluZmluaXRlIGxvb3AuCiAqIDxQPgogKiBbTm90ZTpdIEZvcm1hdHMgYXJlIG51bWJlcmVkIGJ5IG9yZGVyIG9mIHZhcmlhYmxlIGluIHRoZSBzdHJpbmcuCiAqIFRoaXMgaXMgW25vdF0gdGhlIHNhbWUgYXMgdGhlIGFyZ3VtZW50IG51bWJlcmluZyEKICogPHByZT4KICogLiAgIEZvciBleGFtcGxlOiB3aXRoICJhYmN7Mn1kZWZ7M31naGl7MH0uLi4iLAogKiAuICAgCiAqIC4gICBmb3JtYXQwIGFmZmVjdHMgdGhlIGZpcnN0IHZhcmlhYmxlIHsyfQogKiAuICAgZm9ybWF0MSBhZmZlY3RzIHRoZSBzZWNvbmQgdmFyaWFibGUgezN9CiAqIC4gICBmb3JtYXQyIGFmZmVjdHMgdGhlIHNlY29uZCB2YXJpYWJsZSB7MH0KICogPC9wcmU+CiAqIGFuZCBzbyBvbi4KICovCmNsYXNzIFVfSTE4Tl9BUEkgTWVzc2FnZUZvcm1hdCA6IHB1YmxpYyBGb3JtYXQgewpwdWJsaWM6CiAgICBlbnVtIEVGb3JtYXROdW1iZXIgeyBrTWF4Rm9ybWF0ID0gMTAgfTsKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgbmV3IE1lc3NhZ2VGb3JtYXQgdXNpbmcgdGhlIGdpdmVuIHBhdHRlcm4uCiAgICAgKgogICAgICogQHBhcmFtIHBhdHRlcm4gICBQYXR0ZXJuIHVzZWQgdG8gY29uc3RydWN0IG9iamVjdC4KICAgICAqIEBwYXJhbSBzdGF0dXMgICAgT3V0cHV0IHBhcmFtIHRvIHJlY2VpdmUgc3VjY2VzcyBjb2RlLiAgSWYgdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgIHBhdHRlcm4gY2Fubm90IGJlIHBhcnNlZCwgc2V0IHRvIGZhaWx1cmUgY29kZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgTWVzc2FnZUZvcm1hdChjb25zdCBVbmljb2RlU3RyaW5nJiBwYXR0ZXJuLAogICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0b3IgdGhhdCBhbGxvd3MgbG9jYWxlIHNwZWNpZmljYXRpb24uCiAgICAgKiBAcGFyYW0gcGF0dGVybiAgIFBhdHRlcm4gdXNlZCB0byBjb25zdHJ1Y3Qgb2JqZWN0LgogICAgICogQHBhcmFtIG5ld0xvY2FsZSBUaGUgbG9jYWxlIHRvIHVzZSBmb3IgZm9ybWF0dGluZyBkYXRlcyBhbmQgbnVtYmVycy4KICAgICAqIEBwYXJhbSBzdGF0dXMgICAgT3V0cHV0IHBhcmFtIHRvIHJlY2VpdmUgc3VjY2VzcyBjb2RlLiAgSWYgdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgIHBhdHRlcm4gY2Fubm90IGJlIHBhcnNlZCwgc2V0IHRvIGZhaWx1cmUgY29kZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgTWVzc2FnZUZvcm1hdChjb25zdCBVbmljb2RlU3RyaW5nJiBwYXR0ZXJuLAogICAgICAgICAgICAgICAgICBjb25zdCBMb2NhbGUmIG5ld0xvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3VjY2Vzcyk7CgogICAgLyoqCiAgICAgKiBDb3B5IGNvbnN0cnVjdG9yLgogICAgICogQHN0YWJsZQogICAgICovCiAgICBNZXNzYWdlRm9ybWF0KGNvbnN0IE1lc3NhZ2VGb3JtYXQmKTsKCiAgICAvKioKICAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIGNvbnN0IE1lc3NhZ2VGb3JtYXQmIG9wZXJhdG9yPShjb25zdCBNZXNzYWdlRm9ybWF0Jik7CgogICAgLyoqCiAgICAgKiBEZXN0cnVjdG9yLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIH5NZXNzYWdlRm9ybWF0KCk7CgogICAgLyoqCiAgICAgKiBDbG9uZSB0aGlzIEZvcm1hdCBvYmplY3QgcG9seW1vcnBoaWNhbGx5LiBUaGUgY2FsbGVyIG93bnMgdGhlCiAgICAgKiByZXN1bHQgYW5kIHNob3VsZCBkZWxldGUgaXQgd2hlbiBkb25lLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIEZvcm1hdCogY2xvbmUodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gRm9ybWF0IG9iamVjdHMgYXJlIHNlbWFudGljYWxseSBlcXVhbC4KICAgICAqIE9iamVjdHMgb2YgZGlmZmVyZW50IHN1YmNsYXNzZXMgYXJlIGNvbnNpZGVyZWQgdW5lcXVhbC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBib29sX3Qgb3BlcmF0b3I9PShjb25zdCBGb3JtYXQmIG90aGVyKSBjb25zdDsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIGxvY2FsZS4gVGhpcyBsb2NhbGUgaXMgdXNlZCBmb3IgZmV0Y2hpbmcgZGVmYXVsdCBudW1iZXIgb3IgZGF0ZQogICAgICogZm9ybWF0IGluZm9ybWF0aW9uLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0TG9jYWxlKGNvbnN0IExvY2FsZSYgdGhlTG9jYWxlKTsKCiAgICAvKioKICAgICAqIEdldHMgdGhlIGxvY2FsZS4gVGhpcyBsb2NhbGUgaXMgdXNlZCBmb3IgZmV0Y2hpbmcgZGVmYXVsdCBudW1iZXIgb3IgZGF0ZQogICAgICogZm9ybWF0IGluZm9ybWF0aW9uLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIGNvbnN0IExvY2FsZSYgZ2V0TG9jYWxlKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogQXBwbHkgdGhlIGdpdmVuIHBhdHRlcm4gc3RyaW5nIHRvIHRoaXMgbWVzc2FnZSBmb3JtYXQuCiAgICAgKgogICAgICogQHBhcmFtIHBhdHRlcm4gICBUaGUgcGF0dGVybiB0byBiZSBhcHBsaWVkLgogICAgICogQHBhcmFtIHN0YXR1cyAgICBPdXRwdXQgcGFyYW0gc2V0IHRvIHN1Y2Nlc3MvZmFpbHVyZSBjb2RlIG9uCiAgICAgKiAgICAgICAgICAgICAgICAgIGV4aXQuIElmIHRoZSBwYXR0ZXJuIGlzIGludmFsaWQsIHRoaXMgd2lsbCBiZQogICAgICogICAgICAgICAgICAgICAgICBzZXQgdG8gYSBmYWlsdXJlIHJlc3VsdC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGFwcGx5UGF0dGVybihjb25zdCBVbmljb2RlU3RyaW5nJiBwYXR0ZXJuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgcGF0dGVybi4gU2VlIHRoZSBjbGFzcyBkZXNjcmlwdGlvbi4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBVbmljb2RlU3RyaW5nJiB0b1BhdHRlcm4oVW5pY29kZVN0cmluZyYgcmVzdWx0KSBjb25zdDsKCiAgICAvKioKICAgICAqIFNldHMgZm9ybWF0cyB0byB1c2Ugb24gcGFyYW1ldGVycy4KICAgICAqIFNlZSB0aGUgY2xhc3MgZGVzY3JpcHRpb24gYWJvdXQgZm9ybWF0IG51bWJlcmluZy4KICAgICAqIFRoZSBjYWxsZXIgc2hvdWxkIG5vdCBkZWxldGUgdGhlIEZvcm1hdCBvYmplY3RzIGFmdGVyIHRoaXMgY2FsbC4KICAgICAqIEBkcmFmdCBIU1lTOiBwb3NzaWJsZSBzZW1hbnRpYyBjaGFuZ2Ugb24gbGltaXRhdGlvbiBvZiB0aGUgc2l6ZSBvZiBhcnJheQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgYWRvcHRGb3JtYXRzKEZvcm1hdCoqIGZvcm1hdHNUb0Fkb3B0LCBpbnQzMl90IGNvdW50KTsKCiAgICAvKioKICAgICAqIFNldHMgZm9ybWF0cyB0byB1c2Ugb24gcGFyYW1ldGVycy4KICAgICAqIFNlZSB0aGUgY2xhc3MgZGVzY3JpcHRpb24gYWJvdXQgZm9ybWF0IG51bWJlcmluZy4KICAgICAqIEBkcmFmdCBIU1lTOiBwb3NzaWJsZSBzZW1hbnRpYyBjaGFuZ2Ugb24gbGltaXRhdGlvbiBvZiB0aGUgc2l6ZSBvZiBhcnJheQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0Rm9ybWF0cyhjb25zdCBGb3JtYXQqKiBuZXdGb3JtYXRzLGludDMyX3QgY250KTsKCgogICAgLyoqCiAgICAgKiBTZXRzIGZvcm1hdHMgaW5kaXZpZHVhbGx5IHRvIHVzZSBvbiBwYXJhbWV0ZXJzLgogICAgICogU2VlIHRoZSBjbGFzcyBkZXNjcmlwdGlvbiBhYm91dCBmb3JtYXQgbnVtYmVyaW5nLgogICAgICogVGhlIGNhbGxlciBzaG91bGQgbm90IGRlbGV0ZSB0aGUgRm9ybWF0IG9iamVjdCBhZnRlciB0aGlzIGNhbGwuCiAgICAgKiBAZHJhZnQgSFNZUzogcG9zc2libGUgc2VtYW50aWMgY2hhbmdlIG9uIGxpbWl0YXRpb24gb2YgdGhlIHNpemUgb2YgYXJyYXkKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGFkb3B0Rm9ybWF0KGludDMyX3QgZm9ybWF0TnVtYmVyLCBGb3JtYXQqIGZvcm1hdFRvQWRvcHQpOwoKICAgIC8qKgogICAgICogU2V0cyBmb3JtYXRzIGluZGl2aWR1YWxseSB0byB1c2Ugb24gcGFyYW1ldGVycy4KICAgICAqIFNlZSB0aGUgY2xhc3MgZGVzY3JpcHRpb24gYWJvdXQgZm9ybWF0IG51bWJlcmluZy4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHNldEZvcm1hdChpbnQzMl90IHZhcmlhYmxlLCBjb25zdCBGb3JtYXQmIG5ld0Zvcm1hdCk7CgoKICAgIC8qKgogICAgICogR2V0cyBmb3JtYXRzIHRoYXQgd2VyZSBzZXQgd2l0aCBzZXRGb3JtYXRzLgogICAgICogU2VlIHRoZSBjbGFzcyBkZXNjcmlwdGlvbiBhYm91dCBmb3JtYXQgbnVtYmVyaW5nLgogICAgICogQGRyYWZ0IEhTWVM6IHBvc3NpYmxlIHNlbWFudGljIGNoYW5nZSBvbiBsaW1pdGF0aW9uIG9mIHRoZSBzaXplIG9mIGFycmF5CiAgICAgKi8KICAgIHZpcnR1YWwgY29uc3QgRm9ybWF0KiogZ2V0Rm9ybWF0cyhpbnQzMl90JiBjb3VudCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHBhdHRlcm4gd2l0aCBmb3JtYXR0ZWQgb2JqZWN0cy4gIERvZXMgbm90IHRha2Ugb3duZXJzaGlwCiAgICAgKiBvZiB0aGUgRm9ybWF0dGFibGUqIGFycmF5OyBqdXN0IHJlYWRzIGl0IGFuZCB1c2VzIGl0IHRvIGdlbmVyYXRlCiAgICAgKiB0aGUgZm9ybWF0IHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gc291cmNlICAgIEFuIGFycmF5IG9mIG9iamVjdHMgdG8gYmUgZm9ybWF0dGVkICYgc3Vic3RpdHV0ZWQuCiAgICAgKiBAcGFyYW0gcmVzdWx0ICAgIFdoZXJlIHRleHQgaXMgYXBwZW5kZWQuCiAgICAgKiBAcGFyYW0gaWdub3JlICAgIE5vIHVzZWZ1bCBzdGF0dXMgaXMgcmV0dXJuZWQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIFVuaWNvZGVTdHJpbmcmIGZvcm1hdCggIGNvbnN0IEZvcm1hdHRhYmxlKiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGRQb3NpdGlvbiYgaWdub3JlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3VjY2VzcykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBDb252ZW5pZW5jZSByb3V0aW5lLiAgQXZvaWRzIGV4cGxpY2l0IGNyZWF0aW9uIG9mCiAgICAgKiBNZXNzYWdlRm9ybWF0LCBidXQgZG9lc24ndCBhbGxvdyBmdXR1cmUgb3B0aW1pemF0aW9ucy4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgc3RhdGljIFVuaWNvZGVTdHJpbmcmIGZvcm1hdCggICBjb25zdCBVbmljb2RlU3RyaW5nJiBwYXR0ZXJuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBGb3JtYXR0YWJsZSogYXJndW1lbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiByZXN1bHQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdWNjZXNzKTsKCiAgICAvKioKICAgICAqIEZvcm1hdCBhbiBvYmplY3QgdG8gcHJvZHVjZSBhIG1lc3NhZ2UuICBUaGlzIG1ldGhvZCBoYW5kbGVzCiAgICAgKiBGb3JtYXR0YWJsZSBvYmplY3RzIG9mIHR5cGUga0FycmF5LiBJZiB0aGUgRm9ybWF0dGFibGUKICAgICAqIG9iamVjdCB0eXBlIGlzIG5vdCBvZiB0eXBlIGtBcnJheSwgdGhlbiBpdCByZXR1cm5zIGEgZmFpbGluZwogICAgICogVUVycm9yQ29kZS4KICAgICAqCiAgICAgKiBAcGFyYW0gb2JqICAgICAgICAgICBUaGUgb2JqZWN0IHRvIGZvcm1hdAogICAgICogQHBhcmFtIHRvQXBwZW5kVG8gICAgV2hlcmUgdGhlIHRleHQgaXMgdG8gYmUgYXBwZW5kZWQKICAgICAqIEBwYXJhbSBwb3MgICAgICAgICAgIE9uIGlucHV0OiBhbiBhbGlnbm1lbnQgZmllbGQsIGlmIGRlc2lyZWQuCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBPbiBvdXRwdXQ6IHRoZSBvZmZzZXRzIG9mIHRoZSBhbGlnbm1lbnQgZmllbGQuCiAgICAgKiBAcGFyYW0gc3RhdHVzICAgICAgICBPdXRwdXQgcGFyYW0gZmlsbGVkIHdpdGggc3VjY2Vzcy9mYWlsdXJlIHN0YXR1cy4KICAgICAqIEByZXR1cm4gICAgICAgICAgICAgIFRoZSB2YWx1ZSBwYXNzZWQgaW4gYXMgdG9BcHBlbmRUbyAodGhpcyBhbGxvd3MgY2hhaW5pbmcsCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBhcyB3aXRoIFVuaWNvZGVTdHJpbmc6OmFwcGVuZCgpKQogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIFVuaWNvZGVTdHJpbmcmIGZvcm1hdChjb25zdCBGb3JtYXR0YWJsZSYgb2JqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgdG9BcHBlbmRUbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkUG9zaXRpb24mIHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZWRlY2xhcmVkIEZvcm1hdCBtZXRob2QuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIFVuaWNvZGVTdHJpbmcmIGZvcm1hdChjb25zdCBGb3JtYXR0YWJsZSYgb2JqLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIHJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAgIC8qKgogICAgICogUGFyc2VzIHRoZSBzdHJpbmcuCiAgICAgKiA8UD4KICAgICAqIENhdmVhdHM6IFRoZSBwYXJzZSBtYXkgZmFpbCBpbiBhIG51bWJlciBvZiBjaXJjdW1zdGFuY2VzLiAgRm9yCiAgICAgKiBleGFtcGxlOgogICAgICogPFA+CiAgICAgKiBJZiBvbmUgb2YgdGhlIGFyZ3VtZW50cyBkb2VzIG5vdCBvY2N1ciBpbiB0aGUgcGF0dGVybi4KICAgICAqIDxQPgogICAgICogSWYgdGhlIGZvcm1hdCBvZiBhbiBhcmd1bWVudCBpcyBsb3NlcyBpbmZvcm1hdGlvbiwgc3VjaCBhcyB3aXRoCiAgICAgKiBhIGNob2ljZSBmb3JtYXQgd2hlcmUgYSBsYXJnZSBudW1iZXIgZm9ybWF0cyB0byAibWFueSIuCiAgICAgKiA8UD4KICAgICAqIERvZXMgbm90IHlldCBoYW5kbGUgcmVjdXJzaW9uICh3aGVyZSB0aGUgc3Vic3RpdHV0ZWQgc3RyaW5ncwogICAgICogY29udGFpbiB7bn0gcmVmZXJlbmNlcy4pCiAgICAgKiA8UD4KICAgICAqIFdpbGwgbm90IGFsd2F5cyBmaW5kIGEgbWF0Y2ggKG9yIHRoZSBjb3JyZWN0IG1hdGNoKSBpZiBzb21lCiAgICAgKiBwYXJ0IG9mIHRoZSBwYXJzZSBpcyBhbWJpZ3VvdXMuICBGb3IgZXhhbXBsZSwgaWYgdGhlIHBhdHRlcm4KICAgICAqICJ7MX0sezJ9IiBpcyB1c2VkIHdpdGggdGhlIHN0cmluZyBhcmd1bWVudHMgeyJhLGIiLCAiYyJ9LCBpdAogICAgICogd2lsbCBmb3JtYXQgYXMgImEsYixjIi4gIFdoZW4gdGhlIHJlc3VsdCBpcyBwYXJzZWQsIGl0IHdpbGwKICAgICAqIHJldHVybiB7ImEiLCAiYixjIn0uCiAgICAgKiA8UD4KICAgICAqIElmIGEgc2luZ2xlIGFyZ3VtZW50IGlzIGZvcm1hdHRlZCB0d2ljZSBpbiB0aGUgc3RyaW5nLCB0aGVuIHRoZQogICAgICogbGF0ZXIgcGFyc2Ugd2lucy4KICAgICAqCiAgICAgKiBAcGFyYW0gc291cmNlICAgIFN0cmluZyB0byBiZSBwYXJzZWQuCiAgICAgKiBAcGFyYW0gc3RhdHVzICAgIE9uIGlucHV0LCBzdGFydGluZyBwb3NpdGlvbiBmb3IgcGFyc2UuIE9uIG91dHB1dCwKICAgICAqICAgICAgICAgICAgICAgICAgZmluYWwgcG9zaXRpb24gYWZ0ZXIgcGFyc2UuCiAgICAgKiBAcGFyYW0gY291bnQgICAgIE91dHB1dCBwYXJhbSB0byByZWNlaXZlIHNpemUgb2YgcmV0dXJuZWQgYXJyYXkuCiAgICAgKiBAcmVzdWx0ICAgICAgICAgIEFycmF5IG9mIEZvcm1hdHRhYmxlIG9iamVjdHMsIHdpdGggbGVuZ3RoCiAgICAgKiAgICAgICAgICAgICAgICAgICdjb3VudCcsIG93bmVkIGJ5IHRoZSBjYWxsZXIuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgRm9ybWF0dGFibGUqIHBhcnNlKCBjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFyc2VQb3NpdGlvbiYgc3RhdHVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QmIGNvdW50KSBjb25zdDsKCiAgICAvKioKICAgICAqIFBhcnNlcyB0aGUgc3RyaW5nLiBEb2VzIG5vdCB5ZXQgaGFuZGxlIHJlY3Vyc2lvbiAod2hlcmUKICAgICAqIHRoZSBzdWJzdGl0dXRlZCBzdHJpbmdzIGNvbnRhaW4ge259IHJlZmVyZW5jZXMuKQogICAgICoKICAgICAqIEBwYXJhbSBzb3VyY2UgICAgU3RyaW5nIHRvIGJlIHBhcnNlZC4KICAgICAqIEBwYXJhbSBjb3VudCAgICAgT3V0cHV0IHBhcmFtIHRvIHJlY2VpdmUgc2l6ZSBvZiByZXR1cm5lZCBhcnJheS4KICAgICAqIEBwYXJhbSBzdGF0dXMgICAgT3V0cHV0IHBhcmFtIHRvIHJlY2VpdmUgc3VjY2Vzcy9lcnJvciBjb2RlLgogICAgICogQHJlc3VsdCAgICAgICAgICBBcnJheSBvZiBGb3JtYXR0YWJsZSBvYmplY3RzLCB3aXRoIGxlbmd0aAogICAgICogICAgICAgICAgICAgICAgICAnY291bnQnLCBvd25lZCBieSB0aGUgY2FsbGVyLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIEZvcm1hdHRhYmxlKiBwYXJzZSggY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QmIGNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBQYXJzZSBhIHN0cmluZyB0byBwcm9kdWNlIGFuIG9iamVjdC4gIFRoaXMgbWV0aG9kcyBoYW5kbGVzCiAgICAgKiBwYXJzaW5nIG9mIG1lc3NhZ2Ugc3RyaW5ncyBpbnRvIGFycmF5cyBvZiBGb3JtYXR0YWJsZSBvYmplY3RzLgogICAgICogRG9lcyBub3QgeWV0IGhhbmRsZSByZWN1cnNpb24gKHdoZXJlIHRoZSBzdWJzdGl0dXRlZCBzdHJpbmdzCiAgICAgKiBjb250YWluICVuIHJlZmVyZW5jZXMuKQogICAgICogPFA+CiAgICAgKiBCZWZvcmUgY2FsbGluZywgc2V0IHBhcnNlX3Bvcy5pbmRleCB0byB0aGUgb2Zmc2V0IHlvdSB3YW50IHRvCiAgICAgKiBzdGFydCBwYXJzaW5nIGF0IGluIHRoZSBzb3VyY2UuIEFmdGVyIGNhbGxpbmcsIHBhcnNlX3Bvcy5pbmRleAogICAgICogaXMgdGhlIGVuZCBvZiB0aGUgdGV4dCB5b3UgcGFyc2VkLiAgSWYgZXJyb3Igb2NjdXJzLCBpbmRleCBpcwogICAgICogdW5jaGFuZ2VkLgogICAgICogPFA+CiAgICAgKiBXaGVuIHBhcnNpbmcsIGxlYWRpbmcgd2hpdGVzcGFjZSBpcyBkaXNjYXJkZWQgKHdpdGggc3VjY2Vzc2Z1bAogICAgICogcGFyc2UpLCB3aGlsZSB0cmFpbGluZyB3aGl0ZXNwYWNlIGlzIGxlZnQgYXMgaXMuCiAgICAgKiA8UD4KICAgICAqIFNlZSBGb3JtYXQ6OnBhcnNlT2JqZWN0KCkgZm9yIG1vcmUuCiAgICAgKgogICAgICogQHBhcmFtIHNvdXJjZSAgICBUaGUgc3RyaW5nIHRvIGJlIHBhcnNlZCBpbnRvIGFuIG9iamVjdC4KICAgICAqIEBwYXJhbSByZXN1bHQgICAgRm9ybWF0dGFibGUgdG8gYmUgc2V0IHRvIHRoZSBwYXJzZSByZXN1bHQuCiAgICAgKiAgICAgICAgICAgICAgICAgIElmIHBhcnNlIGZhaWxzLCByZXR1cm4gY29udGVudHMgYXJlIHVuZGVmaW5lZC4KICAgICAqIEBwYXJhbSBwYXJzZV9wb3MgVGhlIHBvc2l0aW9uIHRvIHN0YXJ0IHBhcnNpbmcgYXQuIFVwb24gcmV0dXJuCiAgICAgKiAgICAgICAgICAgICAgICAgIHRoaXMgcGFyYW0gaXMgc2V0IHRvIHRoZSBwb3NpdGlvbiBhZnRlciB0aGUKICAgICAqICAgICAgICAgICAgICAgICAgbGFzdCBjaGFyYWN0ZXIgc3VjY2Vzc2Z1bGx5IHBhcnNlZC4gSWYgdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgIHNvdXJjZSBpcyBub3QgcGFyc2VkIHN1Y2Nlc3NmdWxseSwgdGhpcyBwYXJhbQogICAgICogICAgICAgICAgICAgICAgICB3aWxsIHJlbWFpbiB1bmNoYW5nZWQuCiAgICAgKiBAcmV0dXJuICAgICAgICAgIEEgbmV3bHkgY3JlYXRlZCBGb3JtYXR0YWJsZSogb2JqZWN0LCBvciBOVUxMCiAgICAgKiAgICAgICAgICAgICAgICAgIG9uIGZhaWx1cmUuICBUaGUgY2FsbGVyIG93bnMgdGhpcyBhbmQgc2hvdWxkCiAgICAgKiAgICAgICAgICAgICAgICAgIGRlbGV0ZSBpdCB3aGVuIGRvbmUuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBwYXJzZU9iamVjdChjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybWF0dGFibGUmIHJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJzZVBvc2l0aW9uJiBwYXJzZV9wb3MpIGNvbnN0OwoKcHVibGljOgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgdW5pcXVlIGNsYXNzIElEIFBPTFlNT1JQSElDQUxMWS4gIFB1cmUgdmlydHVhbCBvdmVycmlkZS4KICAgICAqIFRoaXMgbWV0aG9kIGlzIHRvIGltcGxlbWVudCBhIHNpbXBsZSB2ZXJzaW9uIG9mIFJUVEksIHNpbmNlIG5vdCBhbGwKICAgICAqIEMrKyBjb21waWxlcnMgc3VwcG9ydCBnZW51aW5lIFJUVEkuICBQb2x5bW9ycGhpYyBvcGVyYXRvcj09KCkgYW5kCiAgICAgKiBjbG9uZSgpIG1ldGhvZHMgY2FsbCB0aGlzIG1ldGhvZC4KICAgICAqCiAgICAgKiBAcmV0dXJuICAgICAgICAgIFRoZSBjbGFzcyBJRCBmb3IgdGhpcyBvYmplY3QuIEFsbCBvYmplY3RzIG9mIGEKICAgICAqICAgICAgICAgICAgICAgICAgZ2l2ZW4gY2xhc3MgaGF2ZSB0aGUgc2FtZSBjbGFzcyBJRC4gIE9iamVjdHMgb2YKICAgICAqICAgICAgICAgICAgICAgICAgb3RoZXIgY2xhc3NlcyBoYXZlIGRpZmZlcmVudCBjbGFzcyBJRHMuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgVUNsYXNzSUQgZ2V0RHluYW1pY0NsYXNzSUQodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGNsYXNzIElEIGZvciB0aGlzIGNsYXNzLiAgVGhpcyBpcyB1c2VmdWwgb25seSBmb3IKICAgICAqIGNvbXBhcmluZyB0byBhIHJldHVybiB2YWx1ZSBmcm9tIGdldER5bmFtaWNDbGFzc0lEKCkuICBGb3IgZXhhbXBsZToKICAgICAqIDxwcmU+CiAgICAgKiAuICAgQmFzZSogcG9seW1vcnBoaWNfcG9pbnRlciA9IGNyZWF0ZVBvbHltb3JwaGljT2JqZWN0KCk7CiAgICAgKiAuICAgaWYgKHBvbHltb3JwaGljX3BvaW50ZXItPmdldER5bmFtaWNDbGFzc0lEKCkgPT0KICAgICAqIC4gICAgICBEZXJpdmVkOjpnZXRTdGF0aWNDbGFzc0lEKCkpIC4uLgogICAgICogPC9wcmU+CiAgICAgKiBAcmV0dXJuICAgICAgICAgIFRoZSBjbGFzcyBJRCBmb3IgYWxsIG9iamVjdHMgb2YgdGhpcyBjbGFzcy4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgc3RhdGljIFVDbGFzc0lEIGdldFN0YXRpY0NsYXNzSUQodm9pZCkgeyByZXR1cm4gKFVDbGFzc0lEKSZmZ0NsYXNzSUQ7IH0KCnByaXZhdGU6CiAgICBzdGF0aWMgY2hhciBmZ0NsYXNzSUQ7CiAgICBzdGF0aWMgTnVtYmVyRm9ybWF0KiBmZ051bWJlckZvcm1hdDsKCiAgICAvLyBmZ051bWJlckZvcm1hdCBpcyBoZWxkIGluIGEgY2FjaGUgb2Ygb25lLgoKICAgIHN0YXRpYyBOdW1iZXJGb3JtYXQqIGdldE51bWJlckZvcm1hdChVRXJyb3JDb2RlICZzdGF0dXMpOyAvLyBjYWxsIHRoaXMgZnVuY3Rpb24gdG8gJ2NoZWNrIG91dCcgYSBudW1iZXJmb3JtYXQgZnJvbSB0aGUgY2FjaGUuCiAgICBzdGF0aWMgdm9pZCAgICAgICAgICByZWxlYXNlTnVtYmVyRm9ybWF0KE51bWJlckZvcm1hdCAqYWRvcHQpOyAvLyBjYWxsIHRoaXMgZnVuY3Rpb24gdG8gJ3JldHVybicgdGhlIG51bWJlciBmb3JtYXQgdG8gdGhlIGNhY2hlLgoKICAgIExvY2FsZSAgICAgICAgICAgICAgICAgZkxvY2FsZTsKICAgIFVuaWNvZGVTdHJpbmcgICAgICAgICBmUGF0dGVybjsKICAgIC8vIGxhdGVyLCBhbGxvdyBtb3JlIHRoYW4gdGVuIGl0ZW1zCiAgICBGb3JtYXQgICAgICAgICAgICAgICAgICpmRm9ybWF0c1trTWF4Rm9ybWF0XTsKICAgIGludDMyX3QgICAgICAgICAgICAgKmZPZmZzZXRzOwogICAgaW50MzJfdCAgICAgICAgICAgICBmQ291bnQ7CiAgICBpbnQzMl90ICAgICAgICAgICAgICpmQXJndW1lbnROdW1iZXJzOwogICAgaW50MzJfdCAgICAgICAgICAgICBmTWF4T2Zmc2V0OwogICAgCiAgICAvKioKICAgICAqIEludGVybmFsIHJvdXRpbmUgdXNlZCBieSBmb3JtYXQuCiAgICAgKiBAcGFyYW0gcmVjdXJzaW9uUHJvdGVjdGlvbiBJbml0aWFsbHkgemVyby4gQml0cyAwLi45IGFyZSB1c2VkIHRvIGluZGljYXRlCiAgICAgKiB0aGF0IGEgcGFyYW1ldGVyIGhhcyBhbHJlYWR5IGJlZW4gc2VlbiwgdG8gYXZvaWQgcmVjdXJzaW9uLiAgQ3VycmVudGx5CiAgICAgKiB1bnVzZWQuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBpbnQzMl90ICAgICAgICAgZmdMaXN0TGVuZ3RoOwogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgICAgIGZnVHlwZUxpc3RbXTsKICAgIHN0YXRpYyBjb25zdCBVbmljb2RlU3RyaW5nICAgICBmZ01vZGlmaWVyTGlzdFtdOwogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgICAgIGZnRGF0ZU1vZGlmaWVyTGlzdFtdOwoKICAgIC8qKiAKICAgICAqIEZpbmRzIHRoZSB3b3JkIHMsIGluIHRoZSBrZXl3b3JkIGxpc3QgYW5kIHJldHVybnMgdGhlIGxvY2F0ZWQgaW5kZXguCiAgICAgKiBAcGFyYW0gcyB0aGUga2V5d29yZCB0byBiZSBzZWFyY2hlZCBmb3IuCiAgICAgKiBAcGFyYW0gbGlzdCB0aGUgbGlzdCBvZiBrZXl3b3JkcyB0byBiZSBzZWFyY2hlZCB3aXRoLgogICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxpc3Qgd2hpY2ggbWF0Y2hlcyB0aGUga2V5d29yZCBzLgogICAgICovCiAgICBzdGF0aWMgaW50MzJfdCBmaW5kS2V5d29yZCggY29uc3QgVW5pY29kZVN0cmluZyYgcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nKiBsaXN0KTsKCiAgICAvKioKICAgICAqIEZvcm1hdHMgdGhlIGFycmF5IG9mIGFyZ3VtZW50cyBhbmQgY29waWVzIHRoZSByZXN1bHQgaW50byB0aGUgcmVzdWx0IGJ1ZmZlciwKICAgICAqIHVwZGF0ZXMgdGhlIGZpZWxkIHBvc2l0aW9uLgogICAgICogQHBhcmFtIGFyZ3VtZW50cyB0aGUgZm9ybWF0dGFibGUgb2JqZWN0cyBhcnJheS4KICAgICAqIEBwYXJhbSBjbnQgdGhlIGFycmF5IGNvdW50LgogICAgICogQHBhcmFtIHN0YXR1cyBmaWVsZCBwb3NpdGlvbiBzdGF0dXMuCiAgICAgKiBAcGFyYW0gcmVjdXJzaW9uUHJvdGVjdGlvbiBJbml0aWFsbHkgemVyby4gQml0cyAwLi45IGFyZSB1c2VkIHRvIGluZGljYXRlCiAgICAgKiB0aGF0IGEgcGFyYW1ldGVyIGhhcyBhbHJlYWR5IGJlZW4gc2VlbiwgdG8gYXZvaWQgcmVjdXJzaW9uLiAgQ3VycmVudGx5CiAgICAgKiB1bnVzZWQuCiAgICAgKiBAcGFyYW0gc3VjY2VzcyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKi8KICAgIFVuaWNvZGVTdHJpbmcmICBmb3JtYXQoIGNvbnN0IEZvcm1hdHRhYmxlKiBhcmd1bWVudHMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBjbnQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgcmVzdWx0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpZWxkUG9zaXRpb24mIHN0YXR1cywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHJlY3Vyc2lvblByb3RlY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdWNjZXNzKSBjb25zdDsKCiAgICAvKioKICAgICAqIENoZWNrcyB0aGUgc2VnbWVudHMgZm9yIHRoZSBjbG9zZXN0IG1hdGNoZWQgZm9ybWF0IGluc3RhbmNlIGFuZAogICAgICogdXBkYXRlcyB0aGUgZm9ybWF0IGFycmF5IHdpdGggdGhlIG5ldyBmb3JtYXQgaW5zdGFuY2UuCiAgICAgKiBAcGFyYW0gcG9zaXRpb24gdGhlIGxhc3QgcHJvY2Vzc2VkIG9mZnNldCBpbiB0aGUgcGF0dGVybiAKICAgICAqIEBwYXJhbSBvZmZzZXROdW1iZXIgdGhlIG9mZnNldCBudW1iZXIgb2YgdGhlIGxhc3QgcHJvY2Vzc2VkIHNlZ21lbnQKICAgICAqIEBwYXJhbSBzZWdtZW50cyB0aGUgc3RyaW5nIHRoYXQgY29udGFpbnMgdGhlIHBhcnNlZCBwYXR0ZXJuIHNlZ21lbnRzLgogICAgICogQHBhcmFtIHN1Y2Nlc3MgdGhlIGVycm9yIGNvZGUKICAgICAqLwogICAgdm9pZCAgICAgICAgICAgIG1ha2VGb3JtYXQoIGludDMyX3QgcG9zaXRpb24sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgb2Zmc2V0TnVtYmVyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nKiBzZWdtZW50cywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3VjY2Vzcyk7CgogICAgLyoqCiAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgdGhhdCBvdWdodCB0byBiZSBpbiBOdW1iZXJGb3JtYXQKICAgICAqLwogICAgTnVtYmVyRm9ybWF0KiBjcmVhdGVJbnRlZ2VyRm9ybWF0KGNvbnN0IExvY2FsZSYgbG9jYWxlLCBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAgIC8qKgogICAgICogQ2hlY2tzIHRoZSByYW5nZSBvZiB0aGUgc291cmNlIHRleHQgdG8gcXVvdGUgdGhlIHNwZWNpYWwKICAgICAqIGNoYXJhY3RlcnMsIHsgYW5kICcgYW5kIGNvcHkgdG8gdGFyZ2V0IGJ1ZmZlci4KICAgICAqIEBwYXJhbSBzb3VyY2UKICAgICAqIEBwYXJhbSBzdGFydCB0aGUgdGV4dCBvZmZzZXQgdG8gc3RhcnQgdGhlIHByb2Nlc3Mgb2YgaW4gdGhlIHNvdXJjZSBzdHJpbmcKICAgICAqIEBwYXJhbSBlbmQgdGhlIHRleHQgb2Zmc2V0IHRvIGVuZCB0aGUgcHJvY2VzcyBvZiBpbiB0aGUgc291cmNlIHN0cmluZwogICAgICogQHBhcmFtIHRhcmdldCB0aGUgcmVzdWx0IGJ1ZmZlcgogICAgICovCiAgICBzdGF0aWMgdm9pZCBjb3B5QW5kRml4UXVvdGVzKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwgaW50MzJfdCBzdGFydCwgaW50MzJfdCBlbmQsIFVuaWNvZGVTdHJpbmcmIHRhcmdldCk7CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhIHN0cmluZyB0byBhbiBpbnRlZ2VyIHZhbHVlIHVzaW5nIGEgZGVmYXVsdCBOdW1iZXJGb3JtYXQgb2JqZWN0CiAgICAgKiB3aGljaCBpcyBzdGF0aWMgKHNoYXJlZCBieSBhbGwgTWVzc2FnZUZvcm1hdCBpbnN0YW5jZXMpLiAgVGhpcyByZXBsYWNlcwogICAgICogYSBjYWxsIHRvIHd0b2koKS4KICAgICAqIEBwYXJhbSBzdHJpbmcgdGhlIHNvdXJjZSBzdHJpbmcgdG8gY29udmVydCB3aXRoCiAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlLgogICAgICogQHJldHVybiB0aGUgY29udmVydGVkIG51bWJlci4KICAgICAqLwogICAgc3RhdGljIGludDMyX3Qgc3RvaShjb25zdCBVbmljb2RlU3RyaW5nJiBzdHJpbmcsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBDb252ZXJ0cyBhbiBpbnRlZ2VyIHZhbHVlIHRvIGEgc3RyaW5nIHVzaW5nIGEgZGVmYXVsdCBOdW1iZXJGb3JtYXQgb2JqZWN0CiAgICAgKiB3aGljaCBpcyBzdGF0aWMgKHNoYXJlZCBieSBhbGwgTWVzc2FnZUZvcm1hdCBpbnN0YW5jZXMpLiAgVGhpcyByZXBsYWNlcwogICAgICogYSBjYWxsIHRvIHd0b2koKS4KICAgICAqIEBwYXJhbSBpIHRoZSBpbnRlZ2VyIHRvIGZvcm1hdAogICAgICogQHBhcmFtIHN0cmluZyB0aGUgZGVzdGluYXRpb24gc3RyaW5nCiAgICAgKiBAcmV0dXJuIGEgcmVmZXJlbmNlIHRvIHN0cmluZy4KICAgICAqLwogICAgc3RhdGljIFVuaWNvZGVTdHJpbmcmIGl0b3MoaW50MzJfdCBpLCBVbmljb2RlU3RyaW5nJiBzdHJpbmcpOwp9OwogCmlubGluZSBVQ2xhc3NJRCAKTWVzc2FnZUZvcm1hdDo6Z2V0RHluYW1pY0NsYXNzSUQoKSBjb25zdAp7IAogICAgcmV0dXJuIE1lc3NhZ2VGb3JtYXQ6OmdldFN0YXRpY0NsYXNzSUQoKTsgCn0KCmlubGluZSBVbmljb2RlU3RyaW5nJgpNZXNzYWdlRm9ybWF0Ojpmb3JtYXQoY29uc3QgRm9ybWF0dGFibGUmIG9iaiwKICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIHJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QgewogICAgcmV0dXJuIEZvcm1hdDo6Zm9ybWF0KG9iaiwgcmVzdWx0LCBzdGF0dXMpOwp9CgojZW5kaWYgLy8gX01TR0ZNVAovL2VvZgo=