LyoKKiBDb3B5cmlnaHQgqSB7MTk5Ny0xOTk5fSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqCiogRmlsZSBOVU1GTVQuSAoqCiogTW9kaWZpY2F0aW9uIEhpc3Rvcnk6CioKKiAgIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogICAwMi8xOS85NyAgICBhbGl1ICAgICAgICBDb252ZXJ0ZWQgZnJvbSBqYXZhLgoqICAgMDMvMTgvOTcgICAgY2xodWFuZyAgICAgVXBkYXRlZCBwZXIgQysrIGltcGxlbWVudGF0aW9uLgoqICAgMDQvMTcvOTcgICAgYWxpdSAgICAgICAgQ2hhbmdlZCBEaWdpdENvdW50IHRvIGludCBwZXIgY29kZSByZXZpZXcuCiogICAgMDcvMjAvOTggICAgc3RlcGhlbiAgICAgICAgSkRLIDEuMiBzeW5jIHVwLiBBZGRlZCBzY2llbnRpZmljIHN1cHBvcnQuCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hhbmdlZCBuYW1pbmcgY29udmVudGlvbnMgdG8gbWF0Y2ggQysrIGd1aWRlbGluZXMKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXJlY2F0ZWQgSmF2YSBzdHlsZSBjb25zdGFudHMgKGVnLCBJTlRFR0VSX0ZJRUxEKQoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwogCiNpZm5kZWYgTlVNRk1UX0gKI2RlZmluZSBOVU1GTVRfSAogCgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW5pc3RyLmgiCiNpbmNsdWRlICJ1bmljb2RlL2Zvcm1hdC5oIgoKY2xhc3MgTG9jYWxlOwoKLyoqCiAqIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIGFsbCBudW1iZXIgZm9ybWF0cy4gIFByb3ZpZGVzIGludGVyZmFjZSBmb3IKICogZm9ybWF0dGluZyBhbmQgcGFyc2luZyBhIG51bWJlci4gIEFsc28gcHJvdmlkZXMgbWV0aG9kcyBmb3IKICogZGV0ZXJtaW5pbmcgd2hpY2ggbG9jYWxlcyBoYXZlIG51bWJlciBmb3JtYXRzLCBhbmQgd2hhdCB0aGVpciBuYW1lcwogKiBhcmUuCiAqIDxQPgogKiBOdW1iZXJGb3JtYXQgaGVscHMgeW91IHRvIGZvcm1hdCBhbmQgcGFyc2UgbnVtYmVycyBmb3IgYW55IGxvY2FsZS4KICogWW91ciBjb2RlIGNhbiBiZSBjb21wbGV0ZWx5IGluZGVwZW5kZW50IG9mIHRoZSBsb2NhbGUgY29udmVudGlvbnMKICogZm9yIGRlY2ltYWwgcG9pbnRzLCB0aG91c2FuZHMtc2VwYXJhdG9ycywgb3IgZXZlbiB0aGUgcGFydGljdWxhcgogKiBkZWNpbWFsIGRpZ2l0cyB1c2VkLCBvciB3aGV0aGVyIHRoZSBudW1iZXIgZm9ybWF0IGlzIGV2ZW4gZGVjaW1hbC4KICogPFA+CiAqIFRvIGZvcm1hdCBhIG51bWJlciBmb3IgdGhlIGN1cnJlbnQgTG9jYWxlLCB1c2Ugb25lIG9mIHRoZSBzdGF0aWMKICogZmFjdG9yeSBtZXRob2RzOgogKiA8cHJlPgogKiAuICAgZG91YmxlIG15TnVtYmVyID0gNy4wOwogKiAuICAgVW5pY29kZVN0cmluZyBteVN0cmluZzsKICogLiAgIFVFcnJvckNvZGUgc3VjY2VzcyA9IFVfWkVST19FUlJPUjsKICogLiAgIE51bWJlckZvcm1hdCogbmYgPSBOdW1iZXJGb3JtYXQ6OmNyZWF0ZUluc3RhbmNlKHN1Y2Nlc3MpCiAqIC4gICBuZi0+Zm9ybWF0KG15TnVtYmVyLCBteVN0cmluZyk7CiAqIC4gICBjb3V0ICZsdDsmbHQ7ICIgRXhhbXBsZSAxOiAiICZsdDsmbHQ7IG15U3RyaW5nICZsdDsmbHQ7IGVuZGw7CiAqIDwvcHJlPgogKiBJZiB5b3UgYXJlIGZvcm1hdHRpbmcgbXVsdGlwbGUgbnVtYmVycywgaXQgaXMgbW9yZSBlZmZpY2llbnQgdG8gZ2V0CiAqIHRoZSBmb3JtYXQgYW5kIHVzZSBpdCBtdWx0aXBsZSB0aW1lcyBzbyB0aGF0IHRoZSBzeXN0ZW0gZG9lc24ndAogKiBoYXZlIHRvIGZldGNoIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbG9jYWwgbGFuZ3VhZ2UgYW5kIGNvdW50cnkKICogY29udmVudGlvbnMgbXVsdGlwbGUgdGltZXMuCiAqIDxwcmU+CiAqIC4gICAgVW5pY29kZVN0cmluZyBteVN0cmluZzsKICogLiAgICBVRXJyb3JDb2RlIHN1Y2Nlc3MgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgbmYgPSBOdW1iZXJGb3JtYXQ6OmNyZWF0ZUluc3RhbmNlKCBzdWNjZXNzICk7CiAqIC4gICAgaW50MzJfdCBhW10gPSB7IDEyMywgMzMzMywgLTEyMzQ1NjcgfTsKICogLiAgICBjb25zdCBpbnQzMl90IGFfbGVuID0gc2l6ZW9mKGEpIC8gc2l6ZW9mKGFbMF0pOwogKiAuICAgIG15U3RyaW5nLnJlbW92ZSgpOwogKiAuICAgIGZvciAoaW50MzJfdCBpID0gMDsgaSA8IGFfbGVuOyBpKyspIHsKICogLiAgICAgICAgbmYtPmZvcm1hdChhW2ldLCBteVN0cmluZyk7CiAqIC4gICAgICAgIG15U3RyaW5nICs9ICIgOyAiOwogKiAuICAgIH0KICogLiAgICBjb3V0ICZsdDsmbHQ7ICIgRXhhbXBsZSAyOiAiICZsdDsmbHQ7IG15U3RyaW5nICZsdDsmbHQ7IGVuZGw7CiAqIDwvcHJlPgogKiBUbyBmb3JtYXQgYSBudW1iZXIgZm9yIGEgZGlmZmVyZW50IExvY2FsZSwgc3BlY2lmeSBpdCBpbiB0aGUKICogY2FsbCB0byBjcmVhdGVJbnN0YW5jZSgpLgogKiA8cHJlPgogKiAuICAgIG5mID0gTnVtYmVyRm9ybWF0OjpjcmVhdGVJbnN0YW5jZSggTG9jYWxlOjpGUkVOQ0gsIHN1Y2Nlc3MgKTsKICogPC9wcmU+CiAqIFlvdSBjYW4gdXNlIGEgTnVtYmVyRm9ybWF0IHRvIHBhcnNlIGFsc28uCiAqIDxwcmU+CiAqIC4gICBVRXJyb3JDb2RlIHN1Y2Nlc3M7CiAqIC4gICBGb3JtYXR0YWJsZSByZXN1bHQoLTk5OSk7ICAvLyBpbml0aWFsaXplZCB3aXRoIGVycm9yIGNvZGUKICogLiAgIG5mLT5wYXJzZShteVN0cmluZywgcmVzdWx0LCBzdWNjZXNzKTsKICogPC9wcmU+CiAqIFVzZSBjcmVhdGVJbnN0YW5jZSB0byBnZXQgdGhlIG5vcm1hbCBudW1iZXIgZm9ybWF0IGZvciB0aGF0IGNvdW50cnkuCiAqIFRoZXJlIGFyZSBvdGhlciBzdGF0aWMgZmFjdG9yeSBtZXRob2RzIGF2YWlsYWJsZS4gIFVzZSBnZXRDdXJyZW5jeQogKiB0byBnZXQgdGhlIGN1cnJlbmN5IG51bWJlciBmb3JtYXQgZm9yIHRoYXQgY291bnRyeS4gIFVzZSBnZXRQZXJjZW50CiAqIHRvIGdldCBhIGZvcm1hdCBmb3IgZGlzcGxheWluZyBwZXJjZW50YWdlcy4gV2l0aCB0aGlzIGZvcm1hdCwgYQogKiBmcmFjdGlvbiBmcm9tIDAuNTMgaXMgZGlzcGxheWVkIGFzIDUzJS4KICogPFA+CiAqIFlvdSBjYW4gYWxzbyBjb250cm9sIHRoZSBkaXNwbGF5IG9mIG51bWJlcnMgd2l0aCBzdWNoIG1ldGhvZHMgYXMKICogZ2V0TWluaW11bUZyYWN0aW9uRGlnaXRzLiAgSWYgeW91IHdhbnQgZXZlbiBtb3JlIGNvbnRyb2wgb3ZlciB0aGUKICogZm9ybWF0IG9yIHBhcnNpbmcsIG9yIHdhbnQgdG8gZ2l2ZSB5b3VyIHVzZXJzIG1vcmUgY29udHJvbCwgeW91IGNhbgogKiB0cnkgY2FzdGluZyB0aGUgTnVtYmVyRm9ybWF0IHlvdSBnZXQgZnJvbSB0aGUgZmFjdG9yeSBtZXRob2RzIHRvIGEKICogRGVjaW1hbE51bWJlckZvcm1hdC4gVGhpcyB3aWxsIHdvcmsgZm9yIHRoZSB2YXN0IG1ham9yaXR5IG9mCiAqIGNvdW50cmllczsganVzdCByZW1lbWJlciB0byBwdXQgaXQgaW4gYSB0cnkgYmxvY2sgaW4gY2FzZSB5b3UKICogZW5jb3VudGVyIGFuIHVudXN1YWwgb25lLgogKiA8UD4KICogWW91IGNhbiBhbHNvIHVzZSBmb3JtcyBvZiB0aGUgcGFyc2UgYW5kIGZvcm1hdCBtZXRob2RzIHdpdGgKICogUGFyc2VQb3NpdGlvbiBhbmQgRmllbGRQb3NpdGlvbiB0byBhbGxvdyB5b3UgdG86CiAqIDx1bCB0eXBlPXJvdW5kPgogKiAgIDxsaT4oYSkgcHJvZ3Jlc3NpdmVseSBwYXJzZSB0aHJvdWdoIHBpZWNlcyBvZiBhIHN0cmluZy4KICogICA8bGk+KGIpIGFsaWduIHRoZSBkZWNpbWFsIHBvaW50IGFuZCBvdGhlciBhcmVhcy4KICogPC91bD4KICogRm9yIGV4YW1wbGUsIHlvdSBjYW4gYWxpZ24gbnVtYmVycyBpbiB0d28gd2F5cy4KICogPFA+CiAqIElmIHlvdSBhcmUgdXNpbmcgYSBtb25vc3BhY2VkIGZvbnQgd2l0aCBzcGFjaW5nIGZvciBhbGlnbm1lbnQsIHlvdQogKiBjYW4gcGFzcyB0aGUgRmllbGRQb3NpdGlvbiBpbiB5b3VyIGZvcm1hdCBjYWxsLCB3aXRoIGZpZWxkID0KICogSU5URUdFUl9GSUVMRC4gT24gb3V0cHV0LCBnZXRFbmRJbmRleCB3aWxsIGJlIHNldCB0byB0aGUgb2Zmc2V0CiAqIGJldHdlZW4gdGhlIGxhc3QgY2hhcmFjdGVyIG9mIHRoZSBpbnRlZ2VyIGFuZCB0aGUgZGVjaW1hbC4gQWRkCiAqIChkZXNpcmVkU3BhY2VDb3VudCAtIGdldEVuZEluZGV4KSBzcGFjZXMgYXQgdGhlIGZyb250IG9mIHRoZQogKiBzdHJpbmcuCiAqIDxQPgogKiBJZiB5b3UgYXJlIHVzaW5nIHByb3BvcnRpb25hbCBmb250cywgaW5zdGVhZCBvZiBwYWRkaW5nIHdpdGgKICogc3BhY2VzLCBtZWFzdXJlIHRoZSB3aWR0aCBvZiB0aGUgc3RyaW5nIGluIHBpeGVscyBmcm9tIHRoZSBzdGFydCB0bwogKiBnZXRFbmRJbmRleC4gIFRoZW4gbW92ZSB0aGUgcGVuIGJ5IChkZXNpcmVkUGl4ZWxXaWR0aCAtCiAqIHdpZHRoVG9BbGlnbm1lbnRQb2ludCkgYmVmb3JlIGRyYXdpbmcgdGhlIHRleHQuICBJdCBhbHNvIHdvcmtzCiAqIHdoZXJlIHRoZXJlIGlzIG5vIGRlY2ltYWwsIGJ1dCBwb3NzaWJseSBhZGRpdGlvbmFsIGNoYXJhY3RlcnMgYXQKICogdGhlIGVuZCwgZS5nLiB3aXRoIHBhcmVudGhlc2VzIGluIG5lZ2F0aXZlIG51bWJlcnM6ICIoMTIpIiBmb3IgLTEyLgogKiBAc3RhYmxlCiAqLwpjbGFzcyBVX0kxOE5fQVBJIE51bWJlckZvcm1hdCA6IHB1YmxpYyBGb3JtYXQgewpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBBbGlnbm1lbnQgRmllbGQgY29uc3RhbnRzIHVzZWQgdG8gY29uc3RydWN0IGEgRmllbGRQb3NpdGlvbiBvYmplY3QuCiAgICAgKiBTaWduaWZpZXMgdGhhdCB0aGUgcG9zaXRpb24gb2YgdGhlIGludGVnZXIgcGFydCBvciBmcmFjdGlvbiBwYXJ0IG9mCiAgICAgKiBhIGZvcm1hdHRlZCBudW1iZXIgc2hvdWxkIGJlIHJldHVybmVkLgogICAgICoKICAgICAqIEBzZWUgRmllbGRQb3NpdGlvbgogICAgICogQHN0YWJsZQogICAgICovCiAgICBlbnVtIEVBbGlnbm1lbnRGaWVsZHMgewogICAgICAgIGtJbnRlZ2VyRmllbGQsCiAgICAgICAga0ZyYWN0aW9uRmllbGQsCgoKICAgIC8qKgogICAgICogVGhlc2UgY29uc3RhbnRzIGFyZSBwcm92aWRlZCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgb25seSwKICAgICAqIGFuZCBhcmUgZGVwcmVjYXRlZC4gIFBsZWFzZSB1c2UgdGhlIEMrKyBzdHlsZSBjb25zdGFudHMgZGVmaW5lZCBhYm92ZS4KICAgICAqIEBzdGFibGUKICAgICAqLyAgICAgICAKICAgICAgICBJTlRFR0VSX0ZJRUxEICAgICAgICA9IGtJbnRlZ2VyRmllbGQsCiAgICAgICAgRlJBQ1RJT05fRklFTEQgICAgICAgID0ga0ZyYWN0aW9uRmllbGQKICAgIH07CgogICAgdmlydHVhbCB+TnVtYmVyRm9ybWF0KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gRm9ybWF0IG9iamVjdHMgYXJlIHNlbWFudGljYWxseSBlcXVhbC4KICAgICAqIE9iamVjdHMgb2YgZGlmZmVyZW50IHN1YmNsYXNzZXMgYXJlIGNvbnNpZGVyZWQgdW5lcXVhbC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBVQm9vbCBvcGVyYXRvcj09KGNvbnN0IEZvcm1hdCYgb3RoZXIpIGNvbnN0OwoKICAgIC8qKgogICAgICogRm9ybWF0IGFuIG9iamVjdCB0byBwcm9kdWNlIGEgc3RyaW5nLiAgVGhpcyBtZXRob2QgaGFuZGxlcwogICAgICogRm9ybWF0dGFibGUgb2JqZWN0cyB3aXRoIG51bWVyaWMgdHlwZXMuIElmIHRoZSBGb3JtYXR0YWJsZQogICAgICogb2JqZWN0IHR5cGUgaXMgbm90IGEgbnVtZXJpYyB0eXBlLCB0aGVuIGl0IHJldHVybnMgYSBmYWlsaW5nCiAgICAgKiBVRXJyb3JDb2RlLgogICAgICoKICAgICAqIEBwYXJhbSBvYmogICAgICAgICAgIFRoZSBvYmplY3QgdG8gZm9ybWF0LgogICAgICogQHBhcmFtIHRvQXBwZW5kVG8gICAgV2hlcmUgdGhlIHRleHQgaXMgdG8gYmUgYXBwZW5kZWQuCiAgICAgKiBAcGFyYW0gcG9zICAgICAgICAgICBPbiBpbnB1dDogYW4gYWxpZ25tZW50IGZpZWxkLCBpZiBkZXNpcmVkLgogICAgICogICAgICAgICAgICAgICAgICAgICAgT24gb3V0cHV0OiB0aGUgb2Zmc2V0cyBvZiB0aGUgYWxpZ25tZW50IGZpZWxkLgogICAgICogQHBhcmFtIHN0YXR1cyAgICAgICAgT3V0cHV0IHBhcmFtIGZpbGxlZCB3aXRoIHN1Y2Nlc3MvZmFpbHVyZSBzdGF0dXMuCiAgICAgKiBAcmV0dXJuICAgICAgICAgICAgICBUaGUgdmFsdWUgcGFzc2VkIGluIGFzIHRvQXBwZW5kVG8gKHRoaXMgYWxsb3dzIGNoYWluaW5nLAogICAgICogICAgICAgICAgICAgICAgICAgICAgYXMgd2l0aCBVbmljb2RlU3RyaW5nOjphcHBlbmQoKSkKICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBVbmljb2RlU3RyaW5nJiBmb3JtYXQoY29uc3QgRm9ybWF0dGFibGUmIG9iaiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIHRvQXBwZW5kVG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZFBvc2l0aW9uJiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAgIC8qKgogICAgICogUGFyc2UgYSBzdHJpbmcgdG8gcHJvZHVjZSBhbiBvYmplY3QuICBUaGlzIG1ldGhvZHMgaGFuZGxlcwogICAgICogcGFyc2luZyBvZiBudW1lcmljIHN0cmluZ3MgaW50byBGb3JtYXR0YWJsZSBvYmplY3RzIHdpdGggbnVtZXJpYwogICAgICogdHlwZXMuCiAgICAgKiA8UD4KICAgICAqIEJlZm9yZSBjYWxsaW5nLCBzZXQgcGFyc2VfcG9zLmluZGV4IHRvIHRoZSBvZmZzZXQgeW91IHdhbnQgdG8KICAgICAqIHN0YXJ0IHBhcnNpbmcgYXQgaW4gdGhlIHNvdXJjZS4gQWZ0ZXIgY2FsbGluZywgcGFyc2VfcG9zLmluZGV4CiAgICAgKiBpcyB0aGUgZW5kIG9mIHRoZSB0ZXh0IHlvdSBwYXJzZWQuICBJZiBlcnJvciBvY2N1cnMsIGluZGV4IGlzCiAgICAgKiB1bmNoYW5nZWQuCiAgICAgKiA8UD4KICAgICAqIFdoZW4gcGFyc2luZywgbGVhZGluZyB3aGl0ZXNwYWNlIGlzIGRpc2NhcmRlZCAod2l0aCBzdWNjZXNzZnVsCiAgICAgKiBwYXJzZSksIHdoaWxlIHRyYWlsaW5nIHdoaXRlc3BhY2UgaXMgbGVmdCBhcyBpcy4KICAgICAqIDxQPgogICAgICogU2VlIEZvcm1hdDo6cGFyc2VPYmplY3QoKSBmb3IgbW9yZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc291cmNlICAgIFRoZSBzdHJpbmcgdG8gYmUgcGFyc2VkIGludG8gYW4gb2JqZWN0LgogICAgICogQHBhcmFtIHJlc3VsdCAgICBGb3JtYXR0YWJsZSB0byBiZSBzZXQgdG8gdGhlIHBhcnNlIHJlc3VsdC4KICAgICAqICAgICAgICAgICAgICAgICAgSWYgcGFyc2UgZmFpbHMsIHJldHVybiBjb250ZW50cyBhcmUgdW5kZWZpbmVkLgogICAgICogQHBhcmFtIHBhcnNlX3BvcyBUaGUgcG9zaXRpb24gdG8gc3RhcnQgcGFyc2luZyBhdC4gVXBvbiByZXR1cm4KICAgICAqICAgICAgICAgICAgICAgICAgdGhpcyBwYXJhbSBpcyBzZXQgdG8gdGhlIHBvc2l0aW9uIGFmdGVyIHRoZQogICAgICogICAgICAgICAgICAgICAgICBsYXN0IGNoYXJhY3RlciBzdWNjZXNzZnVsbHkgcGFyc2VkLiBJZiB0aGUKICAgICAqICAgICAgICAgICAgICAgICAgc291cmNlIGlzIG5vdCBwYXJzZWQgc3VjY2Vzc2Z1bGx5LCB0aGlzIHBhcmFtCiAgICAgKiAgICAgICAgICAgICAgICAgIHdpbGwgcmVtYWluIHVuY2hhbmdlZC4KICAgICAqIEByZXR1cm4gICAgICAgICAgQSBuZXdseSBjcmVhdGVkIEZvcm1hdHRhYmxlKiBvYmplY3QsIG9yIE5VTEwKICAgICAqICAgICAgICAgICAgICAgICAgb24gZmFpbHVyZS4gIFRoZSBjYWxsZXIgb3ducyB0aGlzIGFuZCBzaG91bGQKICAgICAqICAgICAgICAgICAgICAgICAgZGVsZXRlIGl0IHdoZW4gZG9uZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHBhcnNlT2JqZWN0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb3JtYXR0YWJsZSYgcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcnNlUG9zaXRpb24mIHBhcnNlX3BvcykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBGb3JtYXQgYSBkb3VibGUgb3IgbG9uZyBudW1iZXIuIFRoZXNlIG1ldGhvZHMgY2FsbCB0aGUgTnVtYmVyRm9ybWF0CiAgICAgKiBwdXJlIHZpcnR1YWwgZm9ybWF0KCkgbWV0aG9kcyB3aXRoIHRoZSBkZWZhdWx0IEZpZWxkUG9zaXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIG51bWJlciAgICBUaGUgdmFsdWUgdG8gYmUgZm9ybWF0dGVkLgogICAgICogQHBhcmFtIG91dHB1dCAgICBPdXRwdXQgcGFyYW0gd2l0aCB0aGUgZm9ybWF0dGVkIHN0cmluZy4KICAgICAqIEByZXR1cm4gICAgICAgICAgQSByZWZlcmVuY2UgdG8gJ291dHB1dCcgcGFyYW0uCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIFVuaWNvZGVTdHJpbmcmIGZvcm1hdCggIGRvdWJsZSBudW1iZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiBvdXRwdXQpIGNvbnN0OwoKICAgIFVuaWNvZGVTdHJpbmcmIGZvcm1hdCggIGludDMyX3QgbnVtYmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgb3V0cHV0KSBjb25zdDsKCiAgIC8qKgogICAgKiBGb3JtYXQgYSBkb3VibGUgb3IgbG9uZyBudW1iZXIuIENvbmNyZXRlIHN1YmNsYXNzZXMgbXVzdCBpbXBsZW1lbnQKICAgICogdGhlc2UgcHVyZSB2aXJ0dWFsIG1ldGhvZHMuCiAgICAqCiAgICAqIEBwYXJhbSBudW1iZXIgICAgIFRoZSB2YWx1ZSB0byBiZSBmb3JtYXR0ZWQuCiAgICAqIEBwYXJhbSB0b0FwcGVuZFRvIFRoZSBzdHJpbmcgdG8gYXBwZW5kIHRoZSBmb3JtYXR0ZWQgc3RyaW5nIHRvLgogICAgKiAgICAgICAgICAgICAgICAgICBUaGlzIGlzIGFuIG91dHB1dCBwYXJhbWV0ZXIuCiAgICAqIEBwYXJhbSBwb3MgICAgICAgIE9uIGlucHV0OiBhbiBhbGlnbm1lbnQgZmllbGQsIGlmIGRlc2lyZWQuCiAgICAqICAgICAgICAgICAgICAgICAgIE9uIG91dHB1dDogdGhlIG9mZnNldHMgb2YgdGhlIGFsaWdubWVudCBmaWVsZC4KICAgICogQHJldHVybiAgICAgICAgICAgQSByZWZlcmVuY2UgdG8gJ3RvQXBwZW5kVG8nLgogICAgICogQHN0YWJsZQogICAgKi8KICAgIHZpcnR1YWwgVW5pY29kZVN0cmluZyYgZm9ybWF0KGRvdWJsZSBudW1iZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiB0b0FwcGVuZFRvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmllbGRQb3NpdGlvbiYgcG9zKSBjb25zdCA9IDA7CiAgICB2aXJ0dWFsIFVuaWNvZGVTdHJpbmcmIGZvcm1hdChpbnQzMl90IG51bWJlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIHRvQXBwZW5kVG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGaWVsZFBvc2l0aW9uJiBwb3MpIGNvbnN0ID0gMDsKCiAgICAvKioKICAgICAqIFJlZGVjbGFyZWQgRm9ybWF0IG1ldGhvZC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgVW5pY29kZVN0cmluZyYgZm9ybWF0KGNvbnN0IEZvcm1hdHRhYmxlJiBvYmosCiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgogICAvKioKICAgICogUmV0dXJuIGEgbG9uZyBpZiBwb3NzaWJsZSAoZS5nLiB3aXRoaW4gcmFuZ2UgTE9OR19NQVgsCiAgICAqIExPTkdfTUFYXSwgYW5kIHdpdGggbm8gZGVjaW1hbHMpLCBvdGhlcndpc2UgYSBkb3VibGUuICBJZgogICAgKiBJbnRlZ2VyT25seSBpcyBzZXQsIHdpbGwgc3RvcCBhdCBhIGRlY2ltYWwgcG9pbnQgKG9yIGVxdWl2YWxlbnQ7CiAgICAqIGUuZy4gZm9yIHJhdGlvbmFsIG51bWJlcnMgIjEgMi8zIiwgd2lsbCBzdG9wIGFmdGVyIHRoZSAxKS4KICAgICogPFA+CiAgICAqIElmIG5vIG9iamVjdCBjYW4gYmUgcGFyc2VkLCBpbmRleCBpcyB1bmNoYW5nZWQsIGFuZCBOVUxMIGlzCiAgICAqIHJldHVybmVkLgogICAgKiA8UD4KICAgICogVGhpcyBpcyBhIHB1cmUgdmlydHVhbCB3aGljaCBjb25jcmV0ZSBzdWJjbGFzc2VzIG11c3QgaW1wbGVtZW50LgogICAgKgogICAgKiBAcGFyYW0gdGV4dCAgICAgICAgICAgVGhlIHRleHQgdG8gYmUgcGFyc2VkLgogICAgKiBAcGFyYW0gcmVzdWx0ICAgICAgICAgRm9ybWF0dGFibGUgdG8gYmUgc2V0IHRvIHRoZSBwYXJzZSByZXN1bHQuCiAgICAqICAgICAgICAgICAgICAgICAgICAgICBJZiBwYXJzZSBmYWlscywgcmV0dXJuIGNvbnRlbnRzIGFyZSB1bmRlZmluZWQuCiAgICAqIEBwYXJhbSBwYXJzZVBvc2l0aW9uICBUaGUgcG9zaXRpb24gdG8gc3RhcnQgcGFyc2luZyBhdCBvbiBpbnB1dC4KICAgICogICAgICAgICAgICAgICAgICAgICAgIE9uIG91dHB1dCwgbW92ZWQgdG8gYWZ0ZXIgdGhlIGxhc3Qgc3VjY2Vzc2Z1bGx5CiAgICAqICAgICAgICAgICAgICAgICAgICAgICBwYXJzZSBjaGFyYWN0ZXIuIE9uIHBhcnNlIGZhaWx1cmUsIGRvZXMgbm90IGNoYW5nZS4KICAgICogQHJldHVybiAgICAgICAgICAgICAgIEEgRm9ybWF0dGFibGUgb2JqZWN0IG9mIG51bWVyaWMgdHlwZS4gIFRoZSBjYWxsZXIKICAgICogICAgICAgICAgICAgICAgICAgICAgIG93bnMgdGhpcyBhbiBtdXN0IGRlbGV0ZSBpdC4gIE5VTEwgb24gZmFpbHVyZS4KICAgICogQHN0YWJsZQogICAgKi8KICAgIHZpcnR1YWwgdm9pZCBwYXJzZShjb25zdCBVbmljb2RlU3RyaW5nJiB0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgIEZvcm1hdHRhYmxlJiByZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgUGFyc2VQb3NpdGlvbiYgcGFyc2VQb3NpdGlvbikgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogUGFyc2UgYSBzdHJpbmcgYXMgYSBudW1lcmljIHZhbHVlLCBhbmQgcmV0dXJuIGEgRm9ybWF0dGFibGUKICAgICAqIG51bWVyaWMgb2JqZWN0LiBUaGlzIG1ldGhvZCBwYXJzZXMgaW50ZWdlcnMgb25seSBpZiBJbnRlZ2VyT25seQogICAgICogaXMgc2V0LgogICAgICoKICAgICAqIEBwYXJhbSB0ZXh0ICAgICAgICAgIFRoZSB0ZXh0IHRvIGJlIHBhcnNlZC4KICAgICAqIEBwYXJhbSByZXN1bHQgICAgICAgIEZvcm1hdHRhYmxlIHRvIGJlIHNldCB0byB0aGUgcGFyc2UgcmVzdWx0LgogICAgICogICAgICAgICAgICAgICAgICAgICAgSWYgcGFyc2UgZmFpbHMsIHJldHVybiBjb250ZW50cyBhcmUgdW5kZWZpbmVkLgogICAgICogQHBhcmFtIHN0YXR1cyAgICAgICAgU3VjY2VzcyBvciBmYWlsdXJlIG91dHB1dCBwYXJhbWV0ZXIuCiAgICAgKiBAcmV0dXJuICAgICAgICAgICAgICBBIEZvcm1hdHRhYmxlIG9iamVjdCBvZiBudW1lcmljIHR5cGUuICBUaGUgY2FsbGVyCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBvd25zIHRoaXMgYW4gbXVzdCBkZWxldGUgaXQuICBOVUxMIG9uIGZhaWx1cmUuCiAgICAgKiBAc2VlICAgICAgICAgICAgICAgICBOdW1iZXJGb3JtYXQ6OmlzUGFyc2VJbnRlZ2VyT25seQogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgcGFyc2UoIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgIEZvcm1hdHRhYmxlJiByZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGZvcm1hdCB3aWxsIHBhcnNlIG51bWJlcnMgYXMgaW50ZWdlcnMKICAgICAqIG9ubHkuICBGb3IgZXhhbXBsZSBpbiB0aGUgRW5nbGlzaCBsb2NhbGUsIHdpdGggUGFyc2VJbnRlZ2VyT25seQogICAgICogdHJ1ZSwgdGhlIHN0cmluZyAiMTIzNC4iIHdvdWxkIGJlIHBhcnNlZCBhcyB0aGUgaW50ZWdlciB2YWx1ZQogICAgICogMTIzNCBhbmQgcGFyc2luZyB3b3VsZCBzdG9wIGF0IHRoZSAiLiIgY2hhcmFjdGVyLiAgT2YgY291cnNlLAogICAgICogdGhlIGV4YWN0IGZvcm1hdCBhY2NlcHRlZCBieSB0aGUgcGFyc2Ugb3BlcmF0aW9uIGlzIGxvY2FsZQogICAgICogZGVwZW5kYW50IGFuZCBkZXRlcm1pbmVkIGJ5IHN1Yi1jbGFzc2VzIG9mIE51bWJlckZvcm1hdC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgVUJvb2wgaXNQYXJzZUludGVnZXJPbmx5KHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogU2V0cyB3aGV0aGVyIG9yIG5vdCBudW1iZXJzIHNob3VsZCBiZSBwYXJzZWQgYXMgaW50ZWdlcnMgb25seS4KICAgICAqIEBzZWUgaXNQYXJzZUludGVnZXJPbmx5CiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRQYXJzZUludGVnZXJPbmx5KFVCb29sIHZhbHVlKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgbnVtYmVyIGZvcm1hdCBmb3IgdGhlIGN1cnJlbnQgZGVmYXVsdAogICAgICogbG9jYWxlLiAgVGhlIGRlZmF1bHQgZm9ybWF0IGlzIG9uZSBvZiB0aGUgc3R5bGVzIHByb3ZpZGVkIGJ5CiAgICAgKiB0aGUgb3RoZXIgZmFjdG9yeSBtZXRob2RzOiBnZXROdW1iZXJJbnN0YW5jZSwKICAgICAqIGdldEN1cnJlbmN5SW5zdGFuY2Ugb3IgZ2V0UGVyY2VudEluc3RhbmNlLiAgRXhhY3RseSB3aGljaCBvbmUKICAgICAqIGlzIGxvY2FsZSBkZXBlbmRhbnQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyBOdW1iZXJGb3JtYXQqIGNyZWF0ZUluc3RhbmNlKFVFcnJvckNvZGUmKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGRlZmF1bHQgbnVtYmVyIGZvcm1hdCBmb3IgdGhlIHNwZWNpZmllZCBsb2NhbGUuCiAgICAgKiBUaGUgZGVmYXVsdCBmb3JtYXQgaXMgb25lIG9mIHRoZSBzdHlsZXMgcHJvdmlkZWQgYnkgdGhlIG90aGVyCiAgICAgKiBmYWN0b3J5IG1ldGhvZHM6IGdldE51bWJlckluc3RhbmNlLCBnZXRDdXJyZW5jeUluc3RhbmNlIG9yCiAgICAgKiBnZXRQZXJjZW50SW5zdGFuY2UuICBFeGFjdGx5IHdoaWNoIG9uZSBpcyBsb2NhbGUgZGVwZW5kYW50LgogICAgICogQHN0YWJsZQogICAgICovCiAgICBzdGF0aWMgTnVtYmVyRm9ybWF0KiBjcmVhdGVJbnN0YW5jZShjb25zdCBMb2NhbGUmIGluTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGN1cnJlbmN5IGZvcm1hdCBmb3IgdGhlIGN1cnJlbnQgZGVmYXVsdCBsb2NhbGUuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyBOdW1iZXJGb3JtYXQqIGNyZWF0ZUN1cnJlbmN5SW5zdGFuY2UoVUVycm9yQ29kZSYpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGN1cnJlbmN5IGZvcm1hdCBmb3IgdGhlIHNwZWNpZmllZCBsb2NhbGUuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyBOdW1iZXJGb3JtYXQqIGNyZWF0ZUN1cnJlbmN5SW5zdGFuY2UoY29uc3QgTG9jYWxlJiBpbkxvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHBlcmNlbnRhZ2UgZm9ybWF0IGZvciB0aGUgY3VycmVudCBkZWZhdWx0IGxvY2FsZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgc3RhdGljIE51bWJlckZvcm1hdCogY3JlYXRlUGVyY2VudEluc3RhbmNlKFVFcnJvckNvZGUmKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBwZXJjZW50YWdlIGZvcm1hdCBmb3IgdGhlIHNwZWNpZmllZCBsb2NhbGUuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyBOdW1iZXJGb3JtYXQqIGNyZWF0ZVBlcmNlbnRJbnN0YW5jZShjb25zdCBMb2NhbGUmIGluTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBzY2llbnRpZmljIGZvcm1hdCBmb3IgdGhlIGN1cnJlbnQgZGVmYXVsdCBsb2NhbGUuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyBOdW1iZXJGb3JtYXQqIGNyZWF0ZVNjaWVudGlmaWNJbnN0YW5jZShVRXJyb3JDb2RlJik7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc2NpZW50aWZpYyBmb3JtYXQgZm9yIHRoZSBzcGVjaWZpZWQgbG9jYWxlLgogICAgICogQHN0YWJsZQogICAgICovCiAgICBzdGF0aWMgTnVtYmVyRm9ybWF0KiBjcmVhdGVTY2llbnRpZmljSW5zdGFuY2UoY29uc3QgTG9jYWxlJiBpbkxvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYpOwoKICAgIC8qKgogICAgICogR2V0IHRoZSBzZXQgb2YgTG9jYWxlcyBmb3Igd2hpY2ggTnVtYmVyRm9ybWF0cyBhcmUgaW5zdGFsbGVkLgogICAgICogQHN0YWJsZQogICAgICovCiAgICBzdGF0aWMgY29uc3QgTG9jYWxlKiBnZXRBdmFpbGFibGVMb2NhbGVzKGludDMyX3QmIGNvdW50KTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiBncm91cGluZyBpcyB1c2VkIGluIHRoaXMgZm9ybWF0LiBGb3IgZXhhbXBsZSwKICAgICAqIGluIHRoZSBFbmdsaXNoIGxvY2FsZSwgd2l0aCBncm91cGluZyBvbiwgdGhlIG51bWJlciAxMjM0NTY3CiAgICAgKiBtaWdodCBiZSBmb3JtYXR0ZWQgYXMgIjEsMjM0LDU2NyIuIFRoZSBncm91cGluZyBzZXBhcmF0b3IgYXMKICAgICAqIHdlbGwgYXMgdGhlIHNpemUgb2YgZWFjaCBncm91cCBpcyBsb2NhbGUgZGVwZW5kYW50IGFuZCBpcwogICAgICogZGV0ZXJtaW5lZCBieSBzdWItY2xhc3NlcyBvZiBOdW1iZXJGb3JtYXQuCiAgICAgKiBAc2VlIHNldEdyb3VwaW5nVXNlZAogICAgICogQHN0YWJsZQogICAgICovCiAgICBVQm9vbCBpc0dyb3VwaW5nVXNlZCh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFNldCB3aGV0aGVyIG9yIG5vdCBncm91cGluZyB3aWxsIGJlIHVzZWQgaW4gdGhpcyBmb3JtYXQuCiAgICAgKiBAc2VlIGdldEdyb3VwaW5nVXNlZAogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0R3JvdXBpbmdVc2VkKFVCb29sIG5ld1ZhbHVlKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGRpZ2l0cyBhbGxvd2VkIGluIHRoZSBpbnRlZ2VyIHBvcnRpb24gb2YgYQogICAgICogbnVtYmVyLgogICAgICogQHNlZSBzZXRNYXhpbXVtSW50ZWdlckRpZ2l0cwogICAgICogQHN0YWJsZQogICAgICovCiAgICBpbnQzMl90IGdldE1heGltdW1JbnRlZ2VyRGlnaXRzKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgZGlnaXRzIGFsbG93ZWQgaW4gdGhlIGludGVnZXIgcG9ydGlvbiBvZiBhCiAgICAgKiBudW1iZXIuIG1heGltdW1JbnRlZ2VyRGlnaXRzIG11c3QgYmUgPj0gbWluaW11bUludGVnZXJEaWdpdHMuICBJZiB0aGUKICAgICAqIG5ldyB2YWx1ZSBmb3IgbWF4aW11bUludGVnZXJEaWdpdHMgaXMgbGVzcyB0aGFuIHRoZSBjdXJyZW50IHZhbHVlCiAgICAgKiBvZiBtaW5pbXVtSW50ZWdlckRpZ2l0cywgdGhlbiBtaW5pbXVtSW50ZWdlckRpZ2l0cyB3aWxsIGFsc28gYmUgc2V0IHRvCiAgICAgKiB0aGUgbmV3IHZhbHVlLgogICAgICoKICAgICAqIEBzZWUgZ2V0TWF4aW11bUludGVnZXJEaWdpdHMKICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHNldE1heGltdW1JbnRlZ2VyRGlnaXRzKGludDMyX3QgbmV3VmFsdWUpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbWluaW11bSBudW1iZXIgb2YgZGlnaXRzIGFsbG93ZWQgaW4gdGhlIGludGVnZXIgcG9ydGlvbiBvZiBhCiAgICAgKiBudW1iZXIuCiAgICAgKiBAc2VlIHNldE1pbmltdW1JbnRlZ2VyRGlnaXRzCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIGludDMyX3QgZ2V0TWluaW11bUludGVnZXJEaWdpdHModm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBtaW5pbXVtIG51bWJlciBvZiBkaWdpdHMgYWxsb3dlZCBpbiB0aGUgaW50ZWdlciBwb3J0aW9uIG9mIGEKICAgICAqIG51bWJlci4gbWluaW11bUludGVnZXJEaWdpdHMgbXVzdCBiZSAmbHQ7PSBtYXhpbXVtSW50ZWdlckRpZ2l0cy4gIElmIHRoZQogICAgICogbmV3IHZhbHVlIGZvciBtaW5pbXVtSW50ZWdlckRpZ2l0cyBleGNlZWRzIHRoZSBjdXJyZW50IHZhbHVlCiAgICAgKiBvZiBtYXhpbXVtSW50ZWdlckRpZ2l0cywgdGhlbiBtYXhpbXVtSW50ZWdlckRpZ2l0cyB3aWxsIGFsc28gYmUgc2V0IHRvCiAgICAgKiB0aGUgbmV3IHZhbHVlLgogICAgICogQHNlZSBnZXRNaW5pbXVtSW50ZWdlckRpZ2l0cwogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0TWluaW11bUludGVnZXJEaWdpdHMoaW50MzJfdCBuZXdWYWx1ZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG51bWJlciBvZiBkaWdpdHMgYWxsb3dlZCBpbiB0aGUgZnJhY3Rpb24gcG9ydGlvbiBvZiBhCiAgICAgKiBudW1iZXIuCiAgICAgKiBAc2VlIHNldE1heGltdW1GcmFjdGlvbkRpZ2l0cwogICAgICogQHN0YWJsZQogICAgICovCiAgICBpbnQzMl90IGdldE1heGltdW1GcmFjdGlvbkRpZ2l0cyh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGRpZ2l0cyBhbGxvd2VkIGluIHRoZSBmcmFjdGlvbiBwb3J0aW9uIG9mIGEKICAgICAqIG51bWJlci4gbWF4aW11bUZyYWN0aW9uRGlnaXRzIG11c3QgYmUgPj0gbWluaW11bUZyYWN0aW9uRGlnaXRzLiAgSWYgdGhlCiAgICAgKiBuZXcgdmFsdWUgZm9yIG1heGltdW1GcmFjdGlvbkRpZ2l0cyBpcyBsZXNzIHRoYW4gdGhlIGN1cnJlbnQgdmFsdWUKICAgICAqIG9mIG1pbmltdW1GcmFjdGlvbkRpZ2l0cywgdGhlbiBtaW5pbXVtRnJhY3Rpb25EaWdpdHMgd2lsbCBhbHNvIGJlIHNldCB0bwogICAgICogdGhlIG5ldyB2YWx1ZS4KICAgICAqIEBzZWUgZ2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoaW50MzJfdCBuZXdWYWx1ZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBtaW5pbXVtIG51bWJlciBvZiBkaWdpdHMgYWxsb3dlZCBpbiB0aGUgZnJhY3Rpb24gcG9ydGlvbiBvZiBhCiAgICAgKiBudW1iZXIuCiAgICAgKiBAc2VlIHNldE1pbmltdW1GcmFjdGlvbkRpZ2l0cwogICAgICogQHN0YWJsZQogICAgICovCiAgICBpbnQzMl90IGdldE1pbmltdW1GcmFjdGlvbkRpZ2l0cyh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIG1pbmltdW0gbnVtYmVyIG9mIGRpZ2l0cyBhbGxvd2VkIGluIHRoZSBmcmFjdGlvbiBwb3J0aW9uIG9mIGEKICAgICAqIG51bWJlci4gbWluaW11bUZyYWN0aW9uRGlnaXRzIG11c3QgYmUgJmx0Oz0gbWF4aW11bUZyYWN0aW9uRGlnaXRzLiAgIElmIHRoZQogICAgICogbmV3IHZhbHVlIGZvciBtaW5pbXVtRnJhY3Rpb25EaWdpdHMgZXhjZWVkcyB0aGUgY3VycmVudCB2YWx1ZQogICAgICogb2YgbWF4aW11bUZyYWN0aW9uRGlnaXRzLCB0aGVuIG1heGltdW1JbnRlZ2VyRGlnaXRzIHdpbGwgYWxzbyBiZSBzZXQgdG8KICAgICAqIHRoZSBuZXcgdmFsdWUKICAgICAqIEBzZWUgZ2V0TWluaW11bUZyYWN0aW9uRGlnaXRzCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMoaW50MzJfdCBuZXdWYWx1ZSk7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGNsYXNzIElEIGZvciB0aGlzIGNsYXNzLiAgVGhpcyBpcyB1c2VmdWwgb25seSBmb3IKICAgICAqIGNvbXBhcmluZyB0byBhIHJldHVybiB2YWx1ZSBmcm9tIGdldER5bmFtaWNDbGFzc0lEKCkuICBGb3IgZXhhbXBsZToKICAgICAqIDxwcmU+CiAgICAgKiAuICAgQmFzZSogcG9seW1vcnBoaWNfcG9pbnRlciA9IGNyZWF0ZVBvbHltb3JwaGljT2JqZWN0KCk7CiAgICAgKiAuICAgaWYgKHBvbHltb3JwaGljX3BvaW50ZXItPmdldER5bmFtaWNDbGFzc0lEKCkgPT0KICAgICAqIC4gICAgICAgRGVyaXZlZDo6Z2V0U3RhdGljQ2xhc3NJRCgpKSAuLi4KICAgICAqIDwvcHJlPgogICAgICogQHJldHVybiBUaGUgY2xhc3MgSUQgZm9yIGFsbCBvYmplY3RzIG9mIHRoaXMgY2xhc3MuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyBVQ2xhc3NJRCBnZXRTdGF0aWNDbGFzc0lEKHZvaWQpIHsgcmV0dXJuIChVQ2xhc3NJRCkmZmdDbGFzc0lEOyB9CgogICAgLyoqCiAgICAgKiBPdmVycmlkZSBDYWxlbmRhcgogICAgICogUmV0dXJucyBhIHVuaXF1ZSBjbGFzcyBJRCBQT0xZTU9SUEhJQ0FMTFkuICBQdXJlIHZpcnR1YWwgb3ZlcnJpZGUuCiAgICAgKiBUaGlzIG1ldGhvZCBpcyB0byBpbXBsZW1lbnQgYSBzaW1wbGUgdmVyc2lvbiBvZiBSVFRJLCBzaW5jZSBub3QgYWxsCiAgICAgKiBDKysgY29tcGlsZXJzIHN1cHBvcnQgZ2VudWluZSBSVFRJLiAgUG9seW1vcnBoaWMgb3BlcmF0b3I9PSgpIGFuZAogICAgICogY2xvbmUoKSBtZXRob2RzIGNhbGwgdGhpcyBtZXRob2QuCiAgICAgKiA8UD4KICAgICAqIEByZXR1cm4gVGhlIGNsYXNzIElEIGZvciB0aGlzIG9iamVjdC4gQWxsIG9iamVjdHMgb2YgYQogICAgICogZ2l2ZW4gY2xhc3MgaGF2ZSB0aGUgc2FtZSBjbGFzcyBJRC4gIE9iamVjdHMgb2YKICAgICAqIG90aGVyIGNsYXNzZXMgaGF2ZSBkaWZmZXJlbnQgY2xhc3MgSURzLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIFVDbGFzc0lEIGdldER5bmFtaWNDbGFzc0lEKHZvaWQpIGNvbnN0IHsgcmV0dXJuIGdldFN0YXRpY0NsYXNzSUQoKTsgfQoKcHJvdGVjdGVkOgoKICAgIC8qKgogICAgICogRGVmYXVsdCBjb25zdHJ1Y3RvciBmb3Igc3ViY2xhc3MgdXNlIG9ubHkuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIE51bWJlckZvcm1hdCgpOwoKICAgIC8qKgogICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgTnVtYmVyRm9ybWF0KGNvbnN0IE51bWJlckZvcm1hdCYpOwoKICAgIC8qKgogICAgICogQXNzaWdubWVudCBvcGVyYXRvci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgTnVtYmVyRm9ybWF0JiBvcGVyYXRvcj0oY29uc3QgTnVtYmVyRm9ybWF0Jik7Cgpwcm90ZWN0ZWQ6CiAgICBzdGF0aWMgY29uc3QgaW50MzJfdCBmZ01heEludGVnZXJEaWdpdHM7CiAgICBzdGF0aWMgY29uc3QgaW50MzJfdCBmZ01pbkludGVnZXJEaWdpdHM7Cgpwcml2YXRlOgogICAgc3RhdGljIGNoYXIgZmdDbGFzc0lEOwoKICAgIGVudW0gRVN0eWxlcyB7CiAgICAgICAga051bWJlclN0eWxlLAogICAgICAgIGtDdXJyZW5jeVN0eWxlLAogICAgICAgIGtQZXJjZW50U3R5bGUsCiAgICAgICAga1NjaWVudGlmaWNTdHlsZSwKICAgICAgICBrU3R5bGVDb3VudCAvLyBBTFdBWVMgTEFTVCBFTlVNOiBudW1iZXIgb2Ygc3R5bGVzCiAgICB9OwoKICAgIHN0YXRpYyBOdW1iZXJGb3JtYXQqIGNyZWF0ZUluc3RhbmNlKGNvbnN0IExvY2FsZSYgZGVzaXJlZExvY2FsZSwgRVN0eWxlcyBjaG9pY2UsIFVFcnJvckNvZGUmIHN1Y2Nlc3MpOwoKICAgIHN0YXRpYyBjb25zdCBpbnQzMl90ICAgICAgICAgZmdOdW1iZXJQYXR0ZXJuc0NvdW50OwogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgICAgIGZnTGFzdFJlc29ydE51bWJlclBhdHRlcm5zW107CgogICAgVUJvb2wgICAgICBmR3JvdXBpbmdVc2VkOwogICAgaW50MzJfdCAgICAgZk1heEludGVnZXJEaWdpdHM7CiAgICBpbnQzMl90ICAgICBmTWluSW50ZWdlckRpZ2l0czsKICAgIGludDMyX3QgICAgIGZNYXhGcmFjdGlvbkRpZ2l0czsKICAgIGludDMyX3QgICAgIGZNaW5GcmFjdGlvbkRpZ2l0czsKICAgIFVCb29sICAgICAgZlBhcnNlSW50ZWdlck9ubHk7Cn07CiAKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogCmlubGluZSBVQm9vbApOdW1iZXJGb3JtYXQ6OmlzUGFyc2VJbnRlZ2VyT25seSgpIGNvbnN0CnsKICAgIHJldHVybiBmUGFyc2VJbnRlZ2VyT25seTsKfQoKaW5saW5lIFVuaWNvZGVTdHJpbmcmCk51bWJlckZvcm1hdDo6Zm9ybWF0KGNvbnN0IEZvcm1hdHRhYmxlJiBvYmosCiAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIHJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdCB7CiAgICByZXR1cm4gRm9ybWF0Ojpmb3JtYXQob2JqLCByZXN1bHQsIHN0YXR1cyk7Cn0KIAojZW5kaWYgLy8gX05VTUZNVAovL2VvZgo=