LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDExLzE3Lzk5ICAgIGFsaXUgICAgICAgIENyZWF0aW9uLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCiNpZm5kZWYgUkJUX1JVTEVfSAojZGVmaW5lIFJCVF9SVUxFX0gKCiNpbmNsdWRlICJ1bmljb2RlL3VuaXN0ci5oIgoKY2xhc3MgUmVwbGFjZWFibGU7CmNsYXNzIFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhOwpjbGFzcyBVbmljb2RlRmlsdGVyOwoKLyoqCiAqIEEgdHJhbnNsaXRlcmF0aW9uIHJ1bGUgdXNlZCBieQogKiA8Y29kZT5SdWxlQmFzZWRUcmFuc2xpdGVyYXRvcjwvY29kZT4uCiAqIDxjb2RlPlRyYW5zbGl0ZXJhdGlvblJ1bGU8L2NvZGU+IGlzIGFuIGltbXV0YWJsZSBvYmplY3QuCiAqCiAqIDxwPkEgcnVsZSBjb25zaXN0cyBvZiBhbiBpbnB1dCBwYXR0ZXJuIGFuZCBhbiBvdXRwdXQgc3RyaW5nLiAgV2hlbgogKiB0aGUgaW5wdXQgcGF0dGVybiBpcyBtYXRjaGVkLCB0aGUgb3V0cHV0IHN0cmluZyBpcyBlbWl0dGVkLiAgVGhlCiAqIGlucHV0IHBhdHRlcm4gY29uc2lzdHMgb2YgemVybyBvciBtb3JlIGNoYXJhY3RlcnMgd2hpY2ggYXJlIG1hdGNoZWQKICogZXhhY3RseSAodGhlIGtleSkgYW5kIG9wdGlvbmFsIGNvbnRleHQuICBDb250ZXh0IG11c3QgbWF0Y2ggaWYgaXQKICogaXMgc3BlY2lmaWVkLiAgQ29udGV4dCBtYXkgYmUgc3BlY2lmaWVkIGJlZm9yZSB0aGUga2V5LCBhZnRlciB0aGUKICoga2V5LCBvciBib3RoLiAgVGhlIGtleSwgcHJlY2VkaW5nIGNvbnRleHQsIGFuZCBmb2xsb3dpbmcgY29udGV4dAogKiBtYXkgY29udGFpbiB2YXJpYWJsZXMuICBWYXJpYWJsZXMgcmVwcmVzZW50IGEgc2V0IG9mIFVuaWNvZGUKICogY2hhcmFjdGVycywgc3VjaCBhcyB0aGUgbGV0dGVycyA8aT5hPC9pPiB0aHJvdWdoIDxpPno8L2k+LgogKiBWYXJpYWJsZXMgYXJlIGRldGVjdGVkIGJ5IGxvb2tpbmcgdXAgZWFjaCBjaGFyYWN0ZXIgaW4gYSBzdXBwbGllZAogKiB2YXJpYWJsZSBsaXN0IHRvIHNlZSBpZiBpdCBoYXMgYmVlbiBzbyBkZWZpbmVkLiAKICoKICogQGF1dGhvciBBbGFuIExpdQogKi8KY2xhc3MgVHJhbnNsaXRlcmF0aW9uUnVsZSB7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBDb25zdGFudHMgcmV0dXJuZWQgYnkgPGNvZGU+Z2V0TWF0Y2hEZWdyZWUoKTwvY29kZT4gaW5kaWNhdGluZwogICAgICogdGhlIGRlZ3JlZSBvZiBtYXRjaCBiZXR3ZWVuIHRoZSB0ZXh0IGFuZCB0aGlzIHJ1bGUuCiAgICAgKiBAc2VlICNnZXRNYXRjaERlZ3JlZQogICAgICovCiAgICBlbnVtIHsKICAgICAgICAvKioKICAgICAgICAgKiBDb25zdGFudCByZXR1cm5lZCBieSA8Y29kZT5nZXRNYXRjaERlZ3JlZSgpPC9jb2RlPgogICAgICAgICAqIGluZGljYXRpbmcgYSBtaXNtYXRjaCBiZXR3ZWVuIHRoZSB0ZXh0IGFuZCB0aGlzIHJ1bGUuICBPbmUKICAgICAgICAgKiBvciBtb3JlIGNoYXJhY3RlcnMgb2YgdGhlIGNvbnRleHQgb3Iga2V5IGRvIG5vdCBtYXRjaCB0aGUKICAgICAgICAgKiB0ZXh0LgogICAgICAgICAqLwogICAgICAgIE1JU01BVENILAoKICAgICAgICAvKioKICAgICAgICAgKiBDb25zdGFudCByZXR1cm5lZCBieSA8Y29kZT5nZXRNYXRjaERlZ3JlZSgpPC9jb2RlPgogICAgICAgICAqIGluZGljYXRpbmcgYSBwYXJ0aWFsIG1hdGNoIGJldHdlZW4gdGhlIHRleHQgYW5kIHRoaXMgcnVsZS4KICAgICAgICAgKiBBbGwgY2hhcmFjdGVycyBvZiB0aGUgdGV4dCBtYXRjaCB0aGUgY29ycmVzcG9uZGluZyBjb250ZXh0CiAgICAgICAgICogb3Iga2V5LCBidXQgbW9yZSBjaGFyYWN0ZXJzIGFyZSByZXF1aXJlZCBmb3IgYSBjb21wbGV0ZQogICAgICAgICAqIG1hdGNoLiAgVGhlcmUgYXJlIHNvbWUga2V5IG9yIGNvbnRleHQgY2hhcmFjdGVycyBhdCB0aGUgZW5kCiAgICAgICAgICogb2YgdGhlIHBhdHRlcm4gdGhhdCByZW1haW4gdW5tYXRjaGVkIGJlY2F1c2UgdGhlIHRleHQgaXNuJ3QKICAgICAgICAgKiBsb25nIGVub3VnaC4KICAgICAgICAgKi8KICAgICAgICBQQVJUSUFMX01BVENILAogICAgICAgIAogICAgICAgIC8qKgogICAgICAgICAqIENvbnN0YW50IHJldHVybmVkIGJ5IDxjb2RlPmdldE1hdGNoRGVncmVlKCk8L2NvZGU+CiAgICAgICAgICogaW5kaWNhdGluZyBhIGNvbXBsZXRlIG1hdGNoIGJldHdlZW4gdGhlIHRleHQgYW5kIHRoaXMgcnVsZS4KICAgICAgICAgKiBUaGUgdGV4dCBtYXRjaGVzIGFsbCBjb250ZXh0IGFuZCBrZXkgY2hhcmFjdGVycy4KICAgICAgICAgKi8KICAgICAgICBGVUxMX01BVENICiAgICB9OwoKcHJpdmF0ZToKCiAgICAvKioKICAgICAqIFRoZSBzdHJpbmcgdGhhdCBtdXN0IGJlIG1hdGNoZWQsIGNvbnNpc3Rpbmcgb2YgdGhlIGFudGVDb250ZXh0LCBrZXksCiAgICAgKiBhbmQgcG9zdENvbnRleHQsIGNvbmNhdGVuYXRlZCB0b2dldGhlciwgaW4gdGhhdCBvcmRlci4gIFNvbWUgY29tcG9uZW50cwogICAgICogbWF5IGJlIGVtcHR5ICh6ZXJvIGxlbmd0aCkuCiAgICAgKiBAc2VlIGFudGVDb250ZXh0TGVuZ3RoCiAgICAgKiBAc2VlIGtleUxlbmd0aAogICAgICovCiAgICBVbmljb2RlU3RyaW5nIHBhdHRlcm47CgogICAgLyoqCiAgICAgKiBUaGUgc3RyaW5nIHRoYXQgaXMgZW1pdHRlZCBpZiB0aGUga2V5LCBhbnRlQ29udGV4dCwgYW5kIHBvc3RDb250ZXh0CiAgICAgKiBhcmUgbWF0Y2hlZC4KICAgICAqLwogICAgVW5pY29kZVN0cmluZyBvdXRwdXQ7CgogICAgLyoqCiAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgdGhhdCBtdXN0IG1hdGNoIGJlZm9yZSB0aGUga2V5LiAgSWYKICAgICAqIHplcm8sIHRoZW4gdGhlcmUgaXMgbm8gbWF0Y2hpbmcgcmVxdWlyZW1lbnQgYmVmb3JlIHRoZSBrZXkuCiAgICAgKiBTdWJzdHJpbmcgWzAsYW50ZUNvbnRleHRMZW5ndGgpIG9mIHBhdHRlcm4gaXMgdGhlIGFudGVDb250ZXh0LgogICAgICovCiAgICBpbnQzMl90IGFudGVDb250ZXh0TGVuZ3RoOwoKICAgIC8qKgogICAgICogVGhlIGxlbmd0aCBvZiB0aGUga2V5LiAgU3Vic3RyaW5nIFthbnRlQ29udGV4dExlbmd0aCwKICAgICAqIGFudGVDb250ZXh0TGVuZ3RoICsga2V5TGVuZ3RoKSBpcyB0aGUga2V5LgoKICAgICAqLwogICAgaW50MzJfdCBrZXlMZW5ndGg7CgogICAgLyoqCiAgICAgKiBUaGUgcG9zaXRpb24gb2YgdGhlIGN1cnNvciBhZnRlciBlbWl0dGluZyB0aGUgb3V0cHV0IHN0cmluZywgZnJvbSAwIHRvCiAgICAgKiBvdXRwdXQubGVuZ3RoKCkuICBGb3IgbW9zdCBydWxlcyB3aXRoIG5vIHNwZWNpYWwgY3Vyc29yIHNwZWNpZmljYXRpb24sCiAgICAgKiB0aGUgY3Vyc29yUG9zIGlzIG91dHB1dC5sZW5ndGgoKS4KICAgICAqLwogICAgaW50MzJfdCBjdXJzb3JQb3M7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3QgYSBuZXcgcnVsZSB3aXRoIHRoZSBnaXZlbiBpbnB1dCwgb3V0cHV0IHRleHQsIGFuZCBvdGhlcgogICAgICogYXR0cmlidXRlcy4gIEEgY3Vyc29yIHBvc2l0aW9uIG1heSBiZSBzcGVjaWZpZWQgZm9yIHRoZSBvdXRwdXQgdGV4dC4KICAgICAqIEBwYXJhbSBpbnB1dCBpbnB1dCBzdHJpbmcsIGluY2x1ZGluZyBrZXkgYW5kIG9wdGlvbmFsIGFudGUgYW5kCiAgICAgKiBwb3N0IGNvbnRleHQKICAgICAqIEBwYXJhbSBhbnRlQ29udGV4dFBvcyBvZmZzZXQgaW50byBpbnB1dCB0byBlbmQgb2YgYW50ZSBjb250ZXh0LCBvciAtMSBpZgogICAgICogbm9uZS4gIE11c3QgYmUgPD0gaW5wdXQubGVuZ3RoKCkgaWYgbm90IC0xLgogICAgICogQHBhcmFtIHBvc3RDb250ZXh0UG9zIG9mZnNldCBpbnRvIGlucHV0IHRvIHN0YXJ0IG9mIHBvc3QgY29udGV4dCwgb3IgLTEKICAgICAqIGlmIG5vbmUuICBNdXN0IGJlIDw9IGlucHV0Lmxlbmd0aCgpIGlmIG5vdCAtMSwgYW5kIG11c3QgYmUgPj0KICAgICAqIGFudGVDb250ZXh0UG9zLgogICAgICogQHBhcmFtIG91dHB1dCBvdXRwdXQgc3RyaW5nCiAgICAgKiBAcGFyYW0gY3Vyc29yUG9zIG9mZnNldCBpbnRvIG91dHB1dCBhdCB3aGljaCBjdXJzb3IgaXMgbG9jYXRlZCwgb3IgLTEgaWYKICAgICAqIG5vbmUuICBJZiBsZXNzIHRoYW4gemVybywgdGhlbiB0aGUgY3Vyc29yIGlzIHBsYWNlZCBhZnRlciB0aGUKICAgICAqIDxjb2RlPm91dHB1dDwvY29kZT47IHRoYXQgaXMsIC0xIGlzIGVxdWl2YWxlbnQgdG8KICAgICAqIDxjb2RlPm91dHB1dC5sZW5ndGgoKTwvY29kZT4uICBJZiBncmVhdGVyIHRoYW4KICAgICAqIDxjb2RlPm91dHB1dC5sZW5ndGgoKTwvY29kZT4gdGhlbiBhbiBleGNlcHRpb24gaXMgdGhyb3duLgogICAgICovCiAgICBUcmFuc2xpdGVyYXRpb25SdWxlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIGlucHV0LAogICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGFudGVDb250ZXh0UG9zLCBpbnQzMl90IHBvc3RDb250ZXh0UG9zLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgY3Vyc29yUG9zLAogICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogRGVzdHJ1Y3Rvci4KICAgICAqLwogICAgdmlydHVhbCB+VHJhbnNsaXRlcmF0aW9uUnVsZSgpOwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGtleS4gIEVxdWl2YWxlbnQgdG8gPGNvZGU+Z2V0S2V5KCkubGVuZ3RoKCk8L2NvZGU+LgogICAgICogQHJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBtYXRjaCBrZXkuCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBnZXRLZXlMZW5ndGgodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIG91dHB1dCBzdHJpbmcuCiAgICAgKiBAcmV0dXJuIHRoZSBvdXRwdXQgc3RyaW5nLgogICAgICovCiAgICB2aXJ0dWFsIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGdldE91dHB1dCh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgcG9zaXRpb24gb2YgdGhlIGN1cnNvciB3aXRoaW4gdGhlIG91dHB1dCBzdHJpbmcuCiAgICAgKiBAcmV0dXJuIGEgdmFsdWUgZnJvbSAwIHRvIDxjb2RlPmdldE91dHB1dCgpLmxlbmd0aCgpPC9jb2RlPiwgaW5jbHVzaXZlLgogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0Q3Vyc29yUG9zKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBwcmVjZWRpbmcgY29udGV4dCBsZW5ndGguICBUaGlzIG1ldGhvZCBpcyBuZWVkZWQgdG8KICAgICAqIHN1cHBvcnQgdGhlIDxjb2RlPlRyYW5zbGl0ZXJhdG9yPC9jb2RlPiBtZXRob2QKICAgICAqIDxjb2RlPmdldE1heGltdW1Db250ZXh0TGVuZ3RoKCk8L2NvZGU+LgogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0QW50ZUNvbnRleHRMZW5ndGgodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBJbnRlcm5hbCBtZXRob2QuICBSZXR1cm5zIDgtYml0IGluZGV4IHZhbHVlIGZvciB0aGlzIHJ1bGUuCiAgICAgKiBUaGlzIGlzIHRoZSBsb3cgYnl0ZSBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBrZXksCiAgICAgKiB1bmxlc3MgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUga2V5IGlzIGEgc2V0LiAgSWYgaXQncyBhCiAgICAgKiBzZXQsIG9yIG90aGVyd2lzZSBjYW4gbWF0Y2ggbXVsdGlwbGUga2V5cywgdGhlIGluZGV4IHZhbHVlIGlzIC0xLgogICAgICovCiAgICBpbnQxNl90IGdldEluZGV4VmFsdWUoY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEpOwoKICAgIC8qKgogICAgICogSW50ZXJuYWwgbWV0aG9kLiAgUmV0dXJucyB0cnVlIGlmIHRoaXMgcnVsZSBtYXRjaGVzIHRoZSBnaXZlbgogICAgICogaW5kZXggdmFsdWUuICBUaGUgaW5kZXggdmFsdWUgaXMgYW4gOC1iaXQgaW50ZWdlciwgMC4uMjU1LAogICAgICogcmVwcmVzZW50aW5nIHRoZSBsb3cgYnl0ZSBvZiB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBrZXkuCiAgICAgKiBJdCBtYXRjaGVzIHRoaXMgcnVsZSBpZiBpdCBtYXRjaGVzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlCiAgICAgKiBrZXksIG9yIGlmIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgdGhlIGtleSBpcyBhIHNldCwgYW5kIHRoZSBzZXQKICAgICAqIGNvbnRhaW5zIGFueSBjaGFyYWN0ZXIgd2l0aCBhIGxvdyBieXRlIGVxdWFsIHRvIHRoZSBpbmRleAogICAgICogdmFsdWUuICBJZiB0aGUgcnVsZSBjb250YWlucyBvbmx5IGFudGUgY29udGV4dCwgYXMgaW4gZm9vKT5iYXIsCiAgICAgKiB0aGVuIGl0IHdpbGwgbWF0Y2ggYW55IGtleS4KICAgICAqLwogICAgYm9vbF90IG1hdGNoZXNJbmRleFZhbHVlKHVpbnQ4X3QgdiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSYgZGF0YSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGlzIHJ1bGUgbWFza3MgYW5vdGhlciBydWxlLiAgSWYgcjEgbWFza3MgcjIgdGhlbgogICAgICogcjEgbWF0Y2hlcyBhbnkgaW5wdXQgc3RyaW5nIHRoYXQgcjIgbWF0Y2hlcy4gIElmIHIxIG1hc2tzIHIyIGFuZCByMiBtYXNrcwogICAgICogcjEgdGhlbiByMSA9PSByMi4gIEV4YW1wbGVzOiAiYT54IiBtYXNrcyAiYWI+eSIuICAiYT54IiBtYXNrcyAiYVtiXT55Ii4KICAgICAqICJbY11hPngiIG1hc2tzICJbZGNdYT55Ii4KICAgICAqLwogICAgdmlydHVhbCBib29sX3QgbWFza3MoY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZSYgcjIpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgdGhpcyBydWxlIG1hdGNoZXMgdGhlIGdpdmVuIHRleHQuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdGV4dCwgYm90aCB0cmFuc2xhdGVkIGFuZCB1bnRyYW5zbGF0ZWQKICAgICAqIEBwYXJhbSBzdGFydCB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmU7IDxjb2RlPjAgPD0gc3RhcnQKICAgICAqIDw9IGxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBsaW1pdCB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmU7IDxjb2RlPnN0YXJ0IDw9IGxpbWl0CiAgICAgKiA8PSB0ZXh0Lmxlbmd0aCgpPC9jb2RlPi4KICAgICAqIEBwYXJhbSBjdXJzb3IgcG9zaXRpb24gYXQgd2hpY2ggdG8gdHJhbnNsYXRlIG5leHQsIHJlcHJlc2VudGluZyBvZmZzZXQKICAgICAqIGludG8gdGV4dC4gIFRoaXMgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDxjb2RlPnN0YXJ0PC9jb2RlPiBhbmQKICAgICAqIDxjb2RlPmxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBmaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmlzSW4oKTwvdHQ+IHJldHVybnMgPHR0PmZhbHNlPC90dD4gd2lsbCBub3QgYmUKICAgICAqIGFsdGVyZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIElmIDx0dD5maWx0ZXI8L3R0PiBpcwogICAgICogPHR0Pm51bGw8L3R0PiB0aGVuIG5vIGZpbHRlcmluZyBpcyBhcHBsaWVkLgogICAgICovCiAgICB2aXJ0dWFsIGJvb2xfdCBtYXRjaGVzKGNvbnN0IFJlcGxhY2VhYmxlJiB0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHN0YXJ0LCBpbnQzMl90IGxpbWl0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGN1cnNvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVGaWx0ZXIqIGZpbHRlcikgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGRlZ3JlZSBvZiBtYXRjaCBiZXR3ZWVuIHRoaXMgcnVsZSBhbmQgdGhlIGdpdmVuIHRleHQuICBUaGUKICAgICAqIGRlZ3JlZSBvZiBtYXRjaCBtYXkgYmUgbWlzbWF0Y2gsIGEgcGFydGlhbCBtYXRjaCwgb3IgYSBmdWxsIG1hdGNoLiAgQQogICAgICogbWlzbWF0Y2ggbWVhbnMgYXQgbGVhc3Qgb25lIGNoYXJhY3RlciBvZiB0aGUgdGV4dCBkb2VzIG5vdCBtYXRjaCB0aGUKICAgICAqIGNvbnRleHQgb3Iga2V5LiAgQSBwYXJ0aWFsIG1hdGNoIG1lYW5zIHNvbWUgY29udGV4dCBhbmQga2V5IGNoYXJhY3RlcnMKICAgICAqIG1hdGNoLCBidXQgdGhlIHRleHQgaXMgbm90IGxvbmcgZW5vdWdoIHRvIG1hdGNoIGFsbCBvZiB0aGVtLiAgQSBmdWxsCiAgICAgKiBtYXRjaCBtZWFucyBhbGwgY29udGV4dCBhbmQga2V5IGNoYXJhY3RlcnMgbWF0Y2guCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdGV4dCwgYm90aCB0cmFuc2xhdGVkIGFuZCB1bnRyYW5zbGF0ZWQKICAgICAqIEBwYXJhbSBzdGFydCB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmU7IDxjb2RlPjAgPD0gc3RhcnQKICAgICAqIDw9IGxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBsaW1pdCB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmU7IDxjb2RlPnN0YXJ0IDw9IGxpbWl0CiAgICAgKiA8PSB0ZXh0Lmxlbmd0aCgpPC9jb2RlPi4KICAgICAqIEBwYXJhbSBjdXJzb3IgcG9zaXRpb24gYXQgd2hpY2ggdG8gdHJhbnNsYXRlIG5leHQsIHJlcHJlc2VudGluZyBvZmZzZXQKICAgICAqIGludG8gdGV4dC4gIFRoaXMgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDxjb2RlPnN0YXJ0PC9jb2RlPiBhbmQKICAgICAqIDxjb2RlPmxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBmaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmlzSW4oKTwvdHQ+IHJldHVybnMgPHR0PmZhbHNlPC90dD4gd2lsbCBub3QgYmUKICAgICAqIGFsdGVyZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIElmIDx0dD5maWx0ZXI8L3R0PiBpcwogICAgICogPHR0Pm51bGw8L3R0PiB0aGVuIG5vIGZpbHRlcmluZyBpcyBhcHBsaWVkLgogICAgICogQHJldHVybiBvbmUgb2YgPGNvZGU+TUlTTUFUQ0g8L2NvZGU+LCA8Y29kZT5QQVJUSUFMX01BVENIPC9jb2RlPiwgb3IKICAgICAqIDxjb2RlPkZVTExfTUFUQ0g8L2NvZGU+LgogICAgICogQHNlZSAjTUlTTUFUQ0gKICAgICAqIEBzZWUgI1BBUlRJQUxfTUFUQ0gKICAgICAqIEBzZWUgI0ZVTExfTUFUQ0gKICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGdldE1hdGNoRGVncmVlKGNvbnN0IFJlcGxhY2VhYmxlJiB0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc3RhcnQsIGludDMyX3QgbGltaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBjdXJzb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZUZpbHRlciogZmlsdGVyKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgb2YgdGhlIHRleHQgdGhhdCBtYXRjaCB0aGlzIHJ1bGUuICBJZgogICAgICogdGhlcmUgaXMgYSBtaXNtYXRjaCwgcmV0dXJuIC0xLiAgSWYgdGhlIHRleHQgaXMgbm90IGxvbmcgZW5vdWdoIHRvIG1hdGNoCiAgICAgKiBhbnkgY2hhcmFjdGVycywgcmV0dXJuIDAuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdGV4dCwgYm90aCB0cmFuc2xhdGVkIGFuZCB1bnRyYW5zbGF0ZWQKICAgICAqIEBwYXJhbSBzdGFydCB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmU7IDxjb2RlPjAgPD0gc3RhcnQKICAgICAqIDw9IGxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBsaW1pdCB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmU7IDxjb2RlPnN0YXJ0IDw9IGxpbWl0CiAgICAgKiA8PSB0ZXh0Lmxlbmd0aCgpPC9jb2RlPi4KICAgICAqIEBwYXJhbSBjdXJzb3IgcG9zaXRpb24gYXQgd2hpY2ggdG8gdHJhbnNsYXRlIG5leHQsIHJlcHJlc2VudGluZyBvZmZzZXQKICAgICAqIGludG8gdGV4dC4gIFRoaXMgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDxjb2RlPnN0YXJ0PC9jb2RlPiBhbmQKICAgICAqIDxjb2RlPmxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSB0ZW1wbCB0aGUgdGV4dCB0byBtYXRjaCBhZ2FpbnN0LiAgQWxsIGNoYXJhY3RlcnMgbXVzdCBtYXRjaC4KICAgICAqIEBwYXJhbSBkYXRhIGEgZGljdGlvbmFyeSBvZiB2YXJpYWJsZXMgbWFwcGluZyA8Y29kZT5DaGFyYWN0ZXI8L2NvZGU+CiAgICAgKiB0byA8Y29kZT5Vbmljb2RlU2V0PC9jb2RlPgogICAgICogQHBhcmFtIGZpbHRlciB0aGUgZmlsdGVyLiAgQW55IGNoYXJhY3RlciBmb3Igd2hpY2gKICAgICAqIDx0dD5maWx0ZXIuaXNJbigpPC90dD4gcmV0dXJucyA8dHQ+ZmFsc2U8L3R0PiB3aWxsIG5vdCBiZQogICAgICogYWx0ZXJlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLiAgSWYgPHR0PmZpbHRlcjwvdHQ+IGlzCiAgICAgKiA8dHQ+bnVsbDwvdHQ+IHRoZW4gbm8gZmlsdGVyaW5nIGlzIGFwcGxpZWQuCiAgICAgKiBAcmV0dXJuIC0xIGlmIHRoZXJlIGlzIGEgbWlzbWF0Y2gsIDAgaWYgdGhlIHRleHQgaXMgbm90IGxvbmcgZW5vdWdoIHRvCiAgICAgKiBtYXRjaCBhbnkgY2hhcmFjdGVycywgb3RoZXJ3aXNlIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBvZiB0ZXh0IHRoYXQKICAgICAqIG1hdGNoIHRoaXMgcnVsZS4KICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGdldFJlZ2lvbk1hdGNoTGVuZ3RoKGNvbnN0IFJlcGxhY2VhYmxlJiB0ZXh0LCBpbnQzMl90IHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGltaXQsIGludDMyX3QgY3Vyc29yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRlbXBsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhJiBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVGaWx0ZXIqIGZpbHRlcikgY29uc3Q7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIGtleSBtYXRjaGVzIHRoZSBnaXZlbiB0ZXh0LiAgVGhpcyBtZXRob2QKICAgICAqIGFjY291bnRzIGZvciB0aGUgZmFjdCB0aGF0IHRoZSBrZXkgY2hhcmFjdGVyIG1heSByZXByZXNlbnQgYSBjaGFyYWN0ZXIKICAgICAqIHNldC4gIE5vdGUgdGhhdCB0aGUga2V5IGFuZCB0ZXh0IGNoYXJhY3RlcnMgbWF5IG5vdCBiZSBpbnRlcmNoYW5nZWQKICAgICAqIHdpdGhvdXQgYWx0ZXJpbmcgdGhlIHJlc3VsdHMuCiAgICAgKiBAcGFyYW0ga2V5Q2hhciBhIGNoYXJhY3RlciBpbiB0aGUgbWF0Y2gga2V5CiAgICAgKiBAcGFyYW0gdGV4dENoYXIgYSBjaGFyYWN0ZXIgaW4gdGhlIHRleHQgYmVpbmcgdHJhbnNsaXRlcmF0ZWQKICAgICAqIEBwYXJhbSBkYXRhIGEgZGljdGlvbmFyeSBvZiB2YXJpYWJsZXMgbWFwcGluZyA8Y29kZT5DaGFyYWN0ZXI8L2NvZGU+CiAgICAgKiB0byA8Y29kZT5Vbmljb2RlU2V0PC9jb2RlPgogICAgICogQHBhcmFtIGZpbHRlciB0aGUgZmlsdGVyLiAgQW55IGNoYXJhY3RlciBmb3Igd2hpY2gKICAgICAqIDx0dD5maWx0ZXIuaXNJbigpPC90dD4gcmV0dXJucyA8dHQ+ZmFsc2U8L3R0PiB3aWxsIG5vdCBiZQogICAgICogYWx0ZXJlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLiAgSWYgPHR0PmZpbHRlcjwvdHQ+IGlzCiAgICAgKiA8dHQ+bnVsbDwvdHQ+IHRoZW4gbm8gZmlsdGVyaW5nIGlzIGFwcGxpZWQuCiAgICAgKi8KICAgIHZpcnR1YWwgYm9vbF90IGNoYXJNYXRjaGVzKFVDaGFyIGtleUNoYXIsIFVDaGFyIHRleHRDaGFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEmIGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlRmlsdGVyKiBmaWx0ZXIpIGNvbnN0Owp9OwoKI2VuZGlmCg==