LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDMgSUJNIGFuZCBvdGhlcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAgIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogIDAzLzIyLzIwMDAgICBoZWxlbmEgICAgICBDcmVhdGlvbi4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKI2lmbmRlZiBTVFNFQVJDSF9ICiNkZWZpbmUgU1RTRUFSQ0hfSAoKI2luY2x1ZGUgInVuaWNvZGUvdXR5cGVzLmgiCgojaWYgIVVDT05GSUdfTk9fQ09MTEFUSU9OCgojaW5jbHVkZSAidW5pY29kZS90Ymxjb2xsLmgiCiNpbmNsdWRlICJ1bmljb2RlL2NvbGVpdHIuaCIKI2luY2x1ZGUgInVuaWNvZGUvc2VhcmNoLmgiCgpVX05BTUVTUEFDRV9CRUdJTgoKLyoqCiAqIDx0dD5TdHJpbmdTZWFyY2g8L3R0PiBpcyBhIDx0dD5TZWFyY2hJdGVyYXRvcjwvdHQ+IHRoYXQgcHJvdmlkZXMKICogbGFuZ3VhZ2Utc2Vuc2l0aXZlIHRleHQgc2VhcmNoaW5nIGJhc2VkIG9uIHRoZSBjb21wYXJpc29uIHJ1bGVzIGRlZmluZWQKICogaW4gYSB7QGxpbmsgUnVsZUJhc2VkQ29sbGF0b3J9IG9iamVjdC4KICogU3RyaW5nU2VhcmNoIGVuc3VyZXMgdGhhdCBsYW5ndWFnZSBlY2NlbnRyaWNpdHkgY2FuIGJlIAogKiBoYW5kbGVkLCBlLmcuIGZvciB0aGUgR2VybWFuIGNvbGxhdG9yLCBjaGFyYWN0ZXJzIN8gYW5kIFNTIHdpbGwgYmUgbWF0Y2hlZCAKICogaWYgY2FzZSBpcyBjaG9zZW4gdG8gYmUgaWdub3JlZC4KICogU2VlIHRoZSA8YSBocmVmPSJodHRwOi8vb3NzLnNvZnR3YXJlLmlibS5jb20vY3ZzL2ljdS9+Y2hlY2tvdXR+L2ljdWh0bWwvZGVzaWduL2NvbGxhdGlvbi9JQ1VfY29sbGF0aW9uX2Rlc2lnbi5odG0iPgogKiAiSUNVIENvbGxhdGlvbiBEZXNpZ24gRG9jdW1lbnQiPC9hPiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KICogPHA+IAogKiBUaGUgYWxnb3JpdGhtIGltcGxlbWVudGVkIGlzIGEgbW9kaWZpZWQgZm9ybSBvZiB0aGUgQm95ZXIgTW9vcmUncyBzZWFyY2guCiAqIEZvciBtb3JlIGluZm9ybWF0aW9uICBzZWUgCiAqIDxhIGhyZWY9aHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS9kb2NzL3BhcGVycy90ZXh0LXNlYXJjaC5odG1sPgogKiAiRWZmaWNpZW50IFRleHQgU2VhcmNoaW5nIGluIEphdmEiPC9hPiwgcHVibGlzaGVkIGluIDxpPkphdmEgUmVwb3J0PC9pPiAKICogaW4gRmVicnVhcnksIDE5OTksIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uIG9uIHRoZSBhbGdvcml0aG0uCiAqIDxwPgogKiBUaGVyZSBhcmUgMiBtYXRjaCBvcHRpb25zIGZvciBzZWxlY3Rpb246PGJyPgogKiBMZXQgUycgYmUgdGhlIHN1Yi1zdHJpbmcgb2YgYSB0ZXh0IHN0cmluZyBTIGJldHdlZW4gdGhlIG9mZnNldHMgc3RhcnQgYW5kIAogKiBlbmQgPHN0YXJ0LCBlbmQ+LgogKiA8YnI+CiAqIEEgcGF0dGVybiBzdHJpbmcgUCBtYXRjaGVzIGEgdGV4dCBzdHJpbmcgUyBhdCB0aGUgb2Zmc2V0cyA8c3RhcnQsIGVuZD4gCiAqIGlmCiAqIDxwcmU+IAogKiBvcHRpb24gMS4gU29tZSBjYW5vbmljYWwgZXF1aXZhbGVudCBvZiBQIG1hdGNoZXMgc29tZSBjYW5vbmljYWwgZXF1aXZhbGVudCAKICogICAgICAgICAgIG9mIFMnCiAqIG9wdGlvbiAyLiBQIG1hdGNoZXMgUycgYW5kIGlmIFAgc3RhcnRzIG9yIGVuZHMgd2l0aCBhIGNvbWJpbmluZyBtYXJrLCAKICogICAgICAgICAgIHRoZXJlIGV4aXN0cyBubyBub24taWdub3JhYmxlIGNvbWJpbmluZyBtYXJrIGJlZm9yZSBvciBhZnRlciBTPyAKICogICAgICAgICAgIGluIFMgcmVzcGVjdGl2ZWx5LiAKICogPC9wcmU+CiAqIE9wdGlvbiAyLiB3aWxsIGJlIHRoZSBkZWZhdWx0twogKiA8cD4KICogVGhpcyBzZWFyY2ggaGFzIEFQSXMgc2ltaWxhciB0byB0aGF0IG9mIG90aGVyIHRleHQgaXRlcmF0aW9uIG1lY2hhbmlzbXMgCiAqIHN1Y2ggYXMgdGhlIGJyZWFrIGl0ZXJhdG9ycyBpbiA8dHQ+QnJlYWtJdGVyYXRvcjwvdHQ+LiBVc2luZyB0aGVzZSAKICogQVBJcywgaXQgaXMgZWFzeSB0byBzY2FuIHRocm91Z2ggdGV4dCBsb29raW5nIGZvciBhbGwgb2NjdXJhbmNlcyBvZiAKICogYSBnaXZlbiBwYXR0ZXJuLiBUaGlzIHNlYXJjaCBpdGVyYXRvciBhbGxvd3MgY2hhbmdpbmcgb2YgZGlyZWN0aW9uIGJ5IAogKiBjYWxsaW5nIGEgPHR0PnJlc2V0PC90dD4gZm9sbG93ZWQgYnkgYSA8dHQ+bmV4dDwvdHQ+IG9yIDx0dD5wcmV2aW91czwvdHQ+LiAKICogVGhvdWdoIGEgZGlyZWN0aW9uIGNoYW5nZSBjYW4gb2NjdXIgd2l0aG91dCBjYWxsaW5nIDx0dD5yZXNldDwvdHQ+IGZpcnN0LCAgCiAqIHRoaXMgb3BlcmF0aW9uIGNvbWVzIHdpdGggc29tZSBzcGVlZCBwZW5hbHR5LgogKiBNYXRjaCByZXN1bHRzIGluIHRoZSBmb3J3YXJkIGRpcmVjdGlvbiB3aWxsIG1hdGNoIHRoZSByZXN1bHQgbWF0Y2hlcyBpbiAKICogdGhlIGJhY2t3YXJkcyBkaXJlY3Rpb24gaW4gdGhlIHJldmVyc2Ugb3JkZXIKICogPHA+CiAqIDx0dD5TZWFyY2hJdGVyYXRvcjwvdHQ+IHByb3ZpZGVzIEFQSXMgdG8gc3BlY2lmeSB0aGUgc3RhcnRpbmcgcG9zaXRpb24gCiAqIHdpdGhpbiB0aGUgdGV4dCBzdHJpbmcgdG8gYmUgc2VhcmNoZWQsIGUuZy4gPHR0PnNldE9mZnNldDwvdHQ+LAogKiA8dHQ+cHJlY2VkaW5nPC90dD4gYW5kIDx0dD5mb2xsb3dpbmc8L3R0Pi4gU2luY2UgdGhlIAogKiBzdGFydGluZyBwb3NpdGlvbiB3aWxsIGJlIHNldCBhcyBpdCBpcyBzcGVjaWZpZWQsIHBsZWFzZSB0YWtlIG5vdGUgdGhhdCAKICogdGhlcmUgYXJlIHNvbWUgZGFuZ2VyIHBvaW50cyB3aGljaCB0aGUgc2VhcmNoIG1heSByZW5kZXIgaW5jb3JyZWN0IAogKiByZXN1bHRzOgogKiA8dWw+CiAqIDxsaT4gVGhlIG1pZHN0IG9mIGEgc3Vic3RyaW5nIHRoYXQgcmVxdWlyZXMgbm9ybWFsaXphdGlvbi4KICogPGxpPiBJZiB0aGUgZm9sbG93aW5nIG1hdGNoIGlzIHRvIGJlIGZvdW5kLCB0aGUgcG9zaXRpb24gc2hvdWxkIG5vdCBiZSB0aGUKICogICAgICBzZWNvbmQgY2hhcmFjdGVyIHdoaWNoIHJlcXVpcmVzIHRvIGJlIHN3YXBwZWQgd2l0aCB0aGUgcHJlY2VkaW5nIAogKiAgICAgIGNoYXJhY3Rlci4gVmljZSB2ZXJzYSwgaWYgdGhlIHByZWNlZGluZyBtYXRjaCBpcyB0byBiZSBmb3VuZCwgCiAqICAgICAgcG9zaXRpb24gdG8gc2VhcmNoIGZyb20gc2hvdWxkIG5vdCBiZSB0aGUgZmlyc3QgY2hhcmFjdGVyIHdoaWNoIAogKiAgICAgIHJlcXVpcmVzIHRvIGJlIHN3YXBwZWQgd2l0aCB0aGUgbmV4dCBjaGFyYWN0ZXIuIEUuZyBjZXJ0YWluIFRoYWkgYW5kCiAqICAgICAgTGFvIGNoYXJhY3RlcnMgcmVxdWlyZSBzd2FwcGluZy4KICogPGxpPiBJZiBhIGZvbGxvd2luZyBwYXR0ZXJuIG1hdGNoIGlzIHRvIGJlIGZvdW5kLCBhbnkgcG9zaXRpb24gd2l0aGluIGEgCiAqICAgICAgY29udHJhY3Rpbmcgc2VxdWVuY2UgZXhjZXB0IHRoZSBmaXJzdCB3aWxsIGZhaWwuIFZpY2UgdmVyc2EgaWYgYSAKICogICAgICBwcmVjZWRpbmcgcGF0dGVybiBtYXRjaCBpcyB0byBiZSBmb3VuZCwgYSBpbnZhbGlkIHN0YXJ0aW5nIHBvaW50IAogKiAgICAgIHdvdWxkIGJlIGFueSBjaGFyYWN0ZXIgd2l0aGluIGEgY29udHJhY3Rpbmcgc2VxdWVuY2UgZXhjZXB0IHRoZSBsYXN0LgogKiA8L3VsPgogKiA8cD4KICogQSBicmVha2l0ZXJhdG9yIGNhbiBiZSB1c2VkIGlmIG9ubHkgbWF0Y2hlcyBhdCBsb2dpY2FsIGJyZWFrcyBhcmUgZGVzaXJlZC4KICogVXNpbmcgYSBicmVha2l0ZXJhdG9yIHdpbGwgb25seSBnaXZlIHlvdSByZXN1bHRzIHRoYXQgZXhhY3RseSBtYXRjaGVzIHRoZQogKiBib3VuZGFyaWVzIGdpdmVuIGJ5IHRoZSBicmVha2l0ZXJhdG9yLiBGb3IgaW5zdGFuY2UgdGhlIHBhdHRlcm4gImUiIHdpbGwKICogbm90IGJlIGZvdW5kIGluIHRoZSBzdHJpbmcgIlx1MDBlOSIgaWYgYSBjaGFyYWN0ZXIgYnJlYWsgaXRlcmF0b3IgaXMgdXNlZC4KICogPHA+CiAqIE9wdGlvbnMgYXJlIHByb3ZpZGVkIHRvIGhhbmRsZSBvdmVybGFwcGluZyBtYXRjaGVzLiAKICogRS5nLiBJbiBFbmdsaXNoLCBvdmVybGFwcGluZyBtYXRjaGVzIHByb2R1Y2VzIHRoZSByZXN1bHQgMCBhbmQgMiAKICogZm9yIHRoZSBwYXR0ZXJuICJhYmFiIiBpbiB0aGUgdGV4dCAiYWJhYmFiIiwgd2hlcmUgZWxzZSBtdXR1YWxseSAKICogZXhjbHVzaXZlIG1hdGNoZXMgb25seSBwcm9kdWNlIHRoZSByZXN1bHQgb2YgMC4KICogPHA+CiAqIFRob3VnaCBjb2xsYXRvciBhdHRyaWJ1dGVzIHdpbGwgYmUgdGFrZW4gaW50byBjb25zaWRlcmF0aW9uIHdoaWxlIAogKiBwZXJmb3JtaW5nIG1hdGNoZXMsIHRoZXJlIGFyZSBubyBBUElzIGhlcmUgZm9yIHNldHRpbmcgYW5kIGdldHRpbmcgdGhlIAogKiBhdHRyaWJ1dGVzLiBUaGVzZSBhdHRyaWJ1dGVzIGNhbiBiZSBzZXQgYnkgZ2V0dGluZyB0aGUgY29sbGF0b3IKICogZnJvbSA8dHQ+Z2V0Q29sbGF0b3I8L3R0PiBhbmQgdXNpbmcgdGhlIEFQSXMgaW4gPHR0PmNvbGwuaDwvdHQ+LgogKiBMYXN0bHkgdG8gdXBkYXRlIFN0cmluZ1NlYXJjaCB0byB0aGUgbmV3IGNvbGxhdG9yIGF0dHJpYnV0ZXMsIAogKiByZXNldCgpIGhhcyB0byBiZSBjYWxsZWQuCiAqIDxwPiAKICogUmVzdHJpY3Rpb246IDxicj4KICogQ3VycmVudGx5IHRoZXJlIGFyZSBubyBjb21wb3NpdGUgY2hhcmFjdGVycyB0aGF0IGNvbnNpc3RzIG9mIGEKICogY2hhcmFjdGVyIHdpdGggY29tYmluaW5nIGNsYXNzID4gMCBiZWZvcmUgYSBjaGFyYWN0ZXIgd2l0aCBjb21iaW5pbmcgCiAqIGNsYXNzID09IDAuIEhvd2V2ZXIsIGlmIHN1Y2ggYSBjaGFyYWN0ZXIgZXhpc3RzIGluIHRoZSBmdXR1cmUsICAKICogU3RyaW5nU2VhcmNoIGRvZXMgbm90IGd1YXJhbnRlZSB0aGUgcmVzdWx0cyBmb3Igb3B0aW9uIDEuCiAqIDxwPgogKiBDb25zdWx0IHRoZSA8dHQ+U2VhcmNoSXRlcmF0b3I8L3R0PiBkb2N1bWVudGF0aW9uIGZvciBpbmZvcm1hdGlvbiBvbgogKiBhbmQgZXhhbXBsZXMgb2YgaG93IHRvIHVzZSBpbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyB0byBpbXBsZW1lbnQgdGV4dAogKiBzZWFyY2hpbmcuCiAqIDxwcmU+PGNvZGU+CiAqIFVuaWNvZGVTdHJpbmcgdGFyZ2V0KCJUaGUgcXVpY2sgYnJvd24gZm94IGp1bXBlZCBvdmVyIHRoZSBsYXp5IGZveCIpOwogKiBVbmljb2RlU3RyaW5nIHBhdHRlcm4oImZveCIpOwogKgogKiBTZWFyY2hJdGVyYXRvciAqaXRlciAgPSBuZXcgU3RyaW5nU2VhcmNoKHBhdHRlcm4sIHRhcmdldCk7CiAqIFVFcnJvckNvZGUgICAgICBlcnJvciA9IFVfWkVST19FUlJPUjsKICogZm9yIChpbnQgcG9zID0gaXRlci0+Zmlyc3QoZXJyb3IpOyBwb3MgIT0gVVNFQVJDSF9ET05FOyAKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zID0gaXRlci0+bmV4dChlcnJvcikpIHsKICogICAgIHByaW50ZigiRm91bmQgbWF0Y2ggYXQgJWQgcG9zLCBsZW5ndGggaXMgJWRcbiIsIHBvcywgCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlci5nZXRNYXRjaExlbmd0aCgpKTsKICogfQogKiA8L2NvZGU+PC9wcmU+CiAqIDxwPgogKiBOb3RlLCBTdHJpbmdTZWFyY2ggaXMgbm90IHRvIGJlIHN1YmNsYXNzZWQuCiAqIDwvcD4KICogQHNlZSBTZWFyY2hJdGVyYXRvcgogKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yCiAqIEBzaW5jZSBJQ1UgMi4wCiAqLwoKY2xhc3MgVV9JMThOX0FQSSBTdHJpbmdTZWFyY2ggOiBwdWJsaWMgU2VhcmNoSXRlcmF0b3IKewpwdWJsaWM6CgogICAgLy8gcHVibGljIGNvbnN0cnVjdG9ycyBhbmQgZGVzdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIENyZWF0aW5nIGEgPHR0PlN0cmluZ1NlYXJjaDwvdHQ+IGluc3RhbmNlIHVzaW5nIHRoZSBhcmd1bWVudCBsb2NhbGUgCiAgICAgKiBsYW5ndWFnZSBydWxlIHNldC4gQSBjb2xsYXRvciB3aWxsIGJlIGNyZWF0ZWQgaW4gdGhlIHByb2Nlc3MsIHdoaWNoIAogICAgICogd2lsbCBiZSBvd25lZCBieSB0aGlzIGluc3RhbmNlIGFuZCB3aWxsIGJlIGRlbGV0ZWQgZHVyaW5nIAogICAgICogZGVzdHJ1Y3Rpb24KICAgICAqIEBwYXJhbSBwYXR0ZXJuIFRoZSB0ZXh0IGZvciB3aGljaCB0aGlzIG9iamVjdCB3aWxsIHNlYXJjaC4KICAgICAqIEBwYXJhbSB0ZXh0ICAgIFRoZSB0ZXh0IGluIHdoaWNoIHRvIHNlYXJjaCBmb3IgdGhlIHBhdHRlcm4uCiAgICAgKiBAcGFyYW0gbG9jYWxlICBBIGxvY2FsZSB3aGljaCBkZWZpbmVzIHRoZSBsYW5ndWFnZS1zZW5zaXRpdmUgCiAgICAgKiAgICAgICAgICAgICAgICBjb21wYXJpc29uIHJ1bGVzIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGV4dCBpbiB0aGUgCiAgICAgKiAgICAgICAgICAgICAgICBwYXR0ZXJuIGFuZCB0YXJnZXQgbWF0Y2hlcy4gCiAgICAgKiBAcGFyYW0gYnJlYWtpdGVyIEEgPHR0PkJyZWFrSXRlcmF0b3I8L3R0PiBvYmplY3QgdXNlZCB0byBjb25zdHJhaW4gCiAgICAgKiAgICAgICAgICAgICAgICB0aGUgbWF0Y2hlcyB0aGF0IGFyZSBmb3VuZC4gTWF0Y2hlcyB3aG9zZSBzdGFydCBhbmQgZW5kIAogICAgICogICAgICAgICAgICAgICAgaW5kaWNlcyBpbiB0aGUgdGFyZ2V0IHRleHQgYXJlIG5vdCBib3VuZGFyaWVzIGFzIAogICAgICogICAgICAgICAgICAgICAgZGV0ZXJtaW5lZCBieSB0aGUgPHR0PkJyZWFrSXRlcmF0b3I8L3R0PiBhcmUgCiAgICAgKiAgICAgICAgICAgICAgICBpZ25vcmVkLiBJZiB0aGlzIGJlaGF2aW9yIGlzIG5vdCBkZXNpcmVkLCAKICAgICAqICAgICAgICAgICAgICAgIDx0dD5OVUxMPC90dD4gY2FuIGJlIHBhc3NlZCBpbiBpbnN0ZWFkLgogICAgICogQHBhcmFtIHN0YXR1cyAgZm9yIGVycm9ycyBpZiBhbnkuIElmIHBhdHRlcm4gb3IgdGV4dCBpcyBOVUxMLCBvciBpZgogICAgICogICAgICAgICAgICAgICBlaXRoZXIgdGhlIGxlbmd0aCBvZiBwYXR0ZXJuIG9yIHRleHQgaXMgMCB0aGVuIGFuIAogICAgICogICAgICAgICAgICAgICBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1IgaXMgcmV0dXJuZWQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgU3RyaW5nU2VhcmNoKGNvbnN0IFVuaWNvZGVTdHJpbmcgJnBhdHRlcm4sIGNvbnN0IFVuaWNvZGVTdHJpbmcgJnRleHQsCiAgICAgICAgICAgICAgICAgY29uc3QgTG9jYWxlICAgICAgICAmbG9jYWxlLCAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICBCcmVha0l0ZXJhdG9yICpicmVha2l0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAgICAmc3RhdHVzKTsKCiAgICAvKioKICAgICAqIENyZWF0aW5nIGEgPHR0PlN0cmluZ1NlYXJjaDwvdHQ+IGluc3RhbmNlIHVzaW5nIHRoZSBhcmd1bWVudCBjb2xsYXRvciAKICAgICAqIGxhbmd1YWdlIHJ1bGUgc2V0LiBOb3RlLCB1c2VyIHJldGFpbnMgdGhlIG93bmVyc2hpcCBvZiB0aGlzIGNvbGxhdG9yLCAKICAgICAqIGl0IGRvZXMgbm90IGdldCBkZXN0cm95ZWQgZHVyaW5nIHRoaXMgaW5zdGFuY2UncyBkZXN0cnVjdGlvbi4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIFRoZSB0ZXh0IGZvciB3aGljaCB0aGlzIG9iamVjdCB3aWxsIHNlYXJjaC4KICAgICAqIEBwYXJhbSB0ZXh0ICAgIFRoZSB0ZXh0IGluIHdoaWNoIHRvIHNlYXJjaCBmb3IgdGhlIHBhdHRlcm4uCiAgICAgKiBAcGFyYW0gY29sbCAgICBBIDx0dD5SdWxlQmFzZWRDb2xsYXRvcjwvdHQ+IG9iamVjdCB3aGljaCBkZWZpbmVzIAogICAgICogICAgICAgICAgICAgICAgdGhlIGxhbmd1YWdlLXNlbnNpdGl2ZSBjb21wYXJpc29uIHJ1bGVzIHVzZWQgdG8gCiAgICAgKiAgICAgICAgICAgICAgICBkZXRlcm1pbmUgd2hldGhlciB0ZXh0IGluIHRoZSBwYXR0ZXJuIGFuZCB0YXJnZXQgCiAgICAgKiAgICAgICAgICAgICAgICBtYXRjaGVzLiBVc2VyIGlzIHJlc3BvbnNpYmxlIGZvciB0aGUgY2xlYXJpbmcgb2YgdGhpcwogICAgICogICAgICAgICAgICAgICAgb2JqZWN0LgogICAgICogQHBhcmFtIGJyZWFraXRlciBBIDx0dD5CcmVha0l0ZXJhdG9yPC90dD4gb2JqZWN0IHVzZWQgdG8gY29uc3RyYWluIAogICAgICogICAgICAgICAgICAgICAgdGhlIG1hdGNoZXMgdGhhdCBhcmUgZm91bmQuIE1hdGNoZXMgd2hvc2Ugc3RhcnQgYW5kIGVuZCAKICAgICAqICAgICAgICAgICAgICAgIGluZGljZXMgaW4gdGhlIHRhcmdldCB0ZXh0IGFyZSBub3QgYm91bmRhcmllcyBhcyAKICAgICAqICAgICAgICAgICAgICAgIGRldGVybWluZWQgYnkgdGhlIDx0dD5CcmVha0l0ZXJhdG9yPC90dD4gYXJlIAogICAgICogICAgICAgICAgICAgICAgaWdub3JlZC4gSWYgdGhpcyBiZWhhdmlvciBpcyBub3QgZGVzaXJlZCwgCiAgICAgKiAgICAgICAgICAgICAgICA8dHQ+TlVMTDwvdHQ+IGNhbiBiZSBwYXNzZWQgaW4gaW5zdGVhZC4KICAgICAqIEBwYXJhbSBzdGF0dXMgZm9yIGVycm9ycyBpZiBhbnkuIElmIGVpdGhlciB0aGUgbGVuZ3RoIG9mIHBhdHRlcm4gb3IgCiAgICAgKiAgICAgICAgICAgICAgIHRleHQgaXMgMCB0aGVuIGFuIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiBpcyByZXR1cm5lZC4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBTdHJpbmdTZWFyY2goY29uc3QgVW5pY29kZVN0cmluZyAgICAgJnBhdHRlcm4sIAogICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcgICAgICZ0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpjb2xsLCAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICBCcmVha0l0ZXJhdG9yICAgICAqYnJlYWtpdGVyLAogICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgICAgICAgICZzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ3JlYXRpbmcgYSA8dHQ+U3RyaW5nU2VhcmNoPC90dD4gaW5zdGFuY2UgdXNpbmcgdGhlIGFyZ3VtZW50IGxvY2FsZSAKICAgICAqIGxhbmd1YWdlIHJ1bGUgc2V0LiBBIGNvbGxhdG9yIHdpbGwgYmUgY3JlYXRlZCBpbiB0aGUgcHJvY2Vzcywgd2hpY2ggCiAgICAgKiB3aWxsIGJlIG93bmVkIGJ5IHRoaXMgaW5zdGFuY2UgYW5kIHdpbGwgYmUgZGVsZXRlZCBkdXJpbmcgCiAgICAgKiBkZXN0cnVjdGlvbgogICAgICogPHA+CiAgICAgKiBOb3RlOiBObyBwYXJzaW5nIG9mIHRoZSB0ZXh0IHdpdGhpbiB0aGUgPHR0PkNoYXJhY3Rlckl0ZXJhdG9yPC90dD4gCiAgICAgKiB3aWxsIGJlIGRvbmUgZHVyaW5nIHNlYXJjaGluZyBmb3IgdGhpcyB2ZXJzaW9uLiBUaGUgYmxvY2sgb2YgdGV4dCAKICAgICAqIGluIDx0dD5DaGFyYWN0ZXJJdGVyYXRvcjwvdHQ+IHdpbGwgYmUgdXNlZCBhcyBpdCBpcy4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIFRoZSB0ZXh0IGZvciB3aGljaCB0aGlzIG9iamVjdCB3aWxsIHNlYXJjaC4KICAgICAqIEBwYXJhbSB0ZXh0ICAgIFRoZSB0ZXh0IGl0ZXJhdG9yIGluIHdoaWNoIHRvIHNlYXJjaCBmb3IgdGhlIHBhdHRlcm4uCiAgICAgKiBAcGFyYW0gbG9jYWxlICBBIGxvY2FsZSB3aGljaCBkZWZpbmVzIHRoZSBsYW5ndWFnZS1zZW5zaXRpdmUgCiAgICAgKiAgICAgICAgICAgICAgICBjb21wYXJpc29uIHJ1bGVzIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGV4dCBpbiB0aGUgCiAgICAgKiAgICAgICAgICAgICAgICBwYXR0ZXJuIGFuZCB0YXJnZXQgbWF0Y2hlcy4gVXNlciBpcyByZXNwb25zaWJsZSBmb3IgCiAgICAgKiAgICAgICAgICAgICAgICB0aGUgY2xlYXJpbmcgb2YgdGhpcyBvYmplY3QuCiAgICAgKiBAcGFyYW0gYnJlYWtpdGVyIEEgPHR0PkJyZWFrSXRlcmF0b3I8L3R0PiBvYmplY3QgdXNlZCB0byBjb25zdHJhaW4gCiAgICAgKiAgICAgICAgICAgICAgICB0aGUgbWF0Y2hlcyB0aGF0IGFyZSBmb3VuZC4gTWF0Y2hlcyB3aG9zZSBzdGFydCBhbmQgZW5kIAogICAgICogICAgICAgICAgICAgICAgaW5kaWNlcyBpbiB0aGUgdGFyZ2V0IHRleHQgYXJlIG5vdCBib3VuZGFyaWVzIGFzIAogICAgICogICAgICAgICAgICAgICAgZGV0ZXJtaW5lZCBieSB0aGUgPHR0PkJyZWFrSXRlcmF0b3I8L3R0PiBhcmUgCiAgICAgKiAgICAgICAgICAgICAgICBpZ25vcmVkLiBJZiB0aGlzIGJlaGF2aW9yIGlzIG5vdCBkZXNpcmVkLCAKICAgICAqICAgICAgICAgICAgICAgIDx0dD5OVUxMPC90dD4gY2FuIGJlIHBhc3NlZCBpbiBpbnN0ZWFkLgogICAgICogQHBhcmFtIHN0YXR1cyBmb3IgZXJyb3JzIGlmIGFueS4gSWYgZWl0aGVyIHRoZSBsZW5ndGggb2YgcGF0dGVybiBvciAKICAgICAqICAgICAgICAgICAgICAgdGV4dCBpcyAwIHRoZW4gYW4gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SIGlzIHJldHVybmVkLgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIFN0cmluZ1NlYXJjaChjb25zdCBVbmljb2RlU3RyaW5nICZwYXR0ZXJuLCBDaGFyYWN0ZXJJdGVyYXRvciAmdGV4dCwKICAgICAgICAgICAgICAgICBjb25zdCBMb2NhbGUgICAgICAgICZsb2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgIEJyZWFrSXRlcmF0b3IgKmJyZWFraXRlciwKICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICAgICZzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ3JlYXRpbmcgYSA8dHQ+U3RyaW5nU2VhcmNoPC90dD4gaW5zdGFuY2UgdXNpbmcgdGhlIGFyZ3VtZW50IGNvbGxhdG9yIAogICAgICogbGFuZ3VhZ2UgcnVsZSBzZXQuIE5vdGUsIHVzZXIgcmV0YWlucyB0aGUgb3duZXJzaGlwIG9mIHRoaXMgY29sbGF0b3IsIAogICAgICogaXQgZG9lcyBub3QgZ2V0IGRlc3Ryb3llZCBkdXJpbmcgdGhpcyBpbnN0YW5jZSdzIGRlc3RydWN0aW9uLgogICAgICogPHA+CiAgICAgKiBOb3RlOiBObyBwYXJzaW5nIG9mIHRoZSB0ZXh0IHdpdGhpbiB0aGUgPHR0PkNoYXJhY3Rlckl0ZXJhdG9yPC90dD4gCiAgICAgKiB3aWxsIGJlIGRvbmUgZHVyaW5nIHNlYXJjaGluZyBmb3IgdGhpcyB2ZXJzaW9uLiBUaGUgYmxvY2sgb2YgdGV4dCAKICAgICAqIGluIDx0dD5DaGFyYWN0ZXJJdGVyYXRvcjwvdHQ+IHdpbGwgYmUgdXNlZCBhcyBpdCBpcy4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIFRoZSB0ZXh0IGZvciB3aGljaCB0aGlzIG9iamVjdCB3aWxsIHNlYXJjaC4KICAgICAqIEBwYXJhbSB0ZXh0ICAgIFRoZSB0ZXh0IGluIHdoaWNoIHRvIHNlYXJjaCBmb3IgdGhlIHBhdHRlcm4uCiAgICAgKiBAcGFyYW0gY29sbCAgICBBIDx0dD5SdWxlQmFzZWRDb2xsYXRvcjwvdHQ+IG9iamVjdCB3aGljaCBkZWZpbmVzIAogICAgICogICAgICAgICAgICAgICAgdGhlIGxhbmd1YWdlLXNlbnNpdGl2ZSBjb21wYXJpc29uIHJ1bGVzIHVzZWQgdG8gCiAgICAgKiAgICAgICAgICAgICAgICBkZXRlcm1pbmUgd2hldGhlciB0ZXh0IGluIHRoZSBwYXR0ZXJuIGFuZCB0YXJnZXQgCiAgICAgKiAgICAgICAgICAgICAgICBtYXRjaGVzLiBVc2VyIGlzIHJlc3BvbnNpYmxlIGZvciB0aGUgY2xlYXJpbmcgb2YgdGhpcwogICAgICogICAgICAgICAgICAgICAgb2JqZWN0LgogICAgICogQHBhcmFtIGJyZWFraXRlciBBIDx0dD5CcmVha0l0ZXJhdG9yPC90dD4gb2JqZWN0IHVzZWQgdG8gY29uc3RyYWluIAogICAgICogICAgICAgICAgICAgICAgdGhlIG1hdGNoZXMgdGhhdCBhcmUgZm91bmQuIE1hdGNoZXMgd2hvc2Ugc3RhcnQgYW5kIGVuZCAKICAgICAqICAgICAgICAgICAgICAgIGluZGljZXMgaW4gdGhlIHRhcmdldCB0ZXh0IGFyZSBub3QgYm91bmRhcmllcyBhcyAKICAgICAqICAgICAgICAgICAgICAgIGRldGVybWluZWQgYnkgdGhlIDx0dD5CcmVha0l0ZXJhdG9yPC90dD4gYXJlIAogICAgICogICAgICAgICAgICAgICAgaWdub3JlZC4gSWYgdGhpcyBiZWhhdmlvciBpcyBub3QgZGVzaXJlZCwgCiAgICAgKiAgICAgICAgICAgICAgICA8dHQ+TlVMTDwvdHQ+IGNhbiBiZSBwYXNzZWQgaW4gaW5zdGVhZC4KICAgICAqIEBwYXJhbSBzdGF0dXMgZm9yIGVycm9ycyBpZiBhbnkuIElmIGVpdGhlciB0aGUgbGVuZ3RoIG9mIHBhdHRlcm4gb3IgCiAgICAgKiAgICAgICAgICAgICAgIHRleHQgaXMgMCB0aGVuIGFuIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiBpcyByZXR1cm5lZC4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBTdHJpbmdTZWFyY2goY29uc3QgVW5pY29kZVN0cmluZyAgICAgJnBhdHRlcm4sIENoYXJhY3Rlckl0ZXJhdG9yICZ0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpjb2xsLCAKICAgICAgICAgICAgICAgICAgICAgICBCcmVha0l0ZXJhdG9yICAgICAqYnJlYWtpdGVyLAogICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgICAgICAgICZzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29weSBjb25zdHJ1Y3RvciB0aGF0IGNyZWF0ZXMgYSBTdHJpbmdTZWFyY2ggaW5zdGFuY2Ugd2l0aCB0aGUgc2FtZSAKICAgICAqIGJlaGF2aW9yLCBhbmQgaXRlcmF0aW5nIG92ZXIgdGhlIHNhbWUgdGV4dC4KICAgICAqIEBwYXJhbSB0aGF0IFN0cmluZ1NlYXJjaCBpbnN0YW5jZSB0byBiZSBjb3BpZWQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgU3RyaW5nU2VhcmNoKGNvbnN0IFN0cmluZ1NlYXJjaCAmdGhhdCk7CgogICAgLyoqCiAgICAqIERlc3RydWN0b3IuIENsZWFucyB1cCB0aGUgc2VhcmNoIGl0ZXJhdG9yIGRhdGEgc3RydWN0LgogICAgKiBJZiBhIGNvbGxhdG9yIGlzIGNyZWF0ZWQgaW4gdGhlIGNvbnN0cnVjdG9yLCBpdCB3aWxsIGJlIGRlc3Ryb3llZCBoZXJlLgogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICB2aXJ0dWFsIH5TdHJpbmdTZWFyY2godm9pZCk7CgogICAgLy8gb3BlcmF0b3Igb3ZlcmxvYWRpbmcgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBBc3NpZ25tZW50IG9wZXJhdG9yLiBTZXRzIHRoaXMgaXRlcmF0b3IgdG8gaGF2ZSB0aGUgc2FtZSBiZWhhdmlvciwKICAgICAqIGFuZCBpdGVyYXRlIG92ZXIgdGhlIHNhbWUgdGV4dCwgYXMgdGhlIG9uZSBwYXNzZWQgaW4uCiAgICAgKiBAcGFyYW0gdGhhdCBpbnN0YW5jZSB0byBiZSBjb3BpZWQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgU3RyaW5nU2VhcmNoICYgb3BlcmF0b3I9KGNvbnN0IFN0cmluZ1NlYXJjaCAmdGhhdCk7CgogICAgLyoqCiAgICAgKiBFcXVhbGl0eSBvcGVyYXRvci4gCiAgICAgKiBAcGFyYW0gdGhhdCBpbnN0YW5jZSB0byBiZSBjb21wYXJlZC4KICAgICAqIEByZXR1cm4gVFJVRSBpZiBib3RoIGluc3RhbmNlcyBoYXZlIHRoZSBzYW1lIGF0dHJpYnV0ZXMsIAogICAgICogICAgICAgICBicmVha2l0ZXJhdG9ycywgY29sbGF0b3JzIGFuZCBpdGVyYXRlIG92ZXIgdGhlIHNhbWUgdGV4dCAKICAgICAqICAgICAgICAgd2hpbGUgbG9va2luZyBmb3IgdGhlIHNhbWUgcGF0dGVybi4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIFVCb29sIG9wZXJhdG9yPT0oY29uc3QgU2VhcmNoSXRlcmF0b3IgJnRoYXQpIGNvbnN0OwoKICAgIC8vIHB1YmxpYyBnZXQgYW5kIHNldCBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIFNldHMgdGhlIGluZGV4IHRvIHBvaW50IHRvIHRoZSBnaXZlbiBwb3NpdGlvbiwgYW5kIGNsZWFycyBhbnkgc3RhdGUgCiAgICAgKiB0aGF0J3MgYWZmZWN0ZWQuCiAgICAgKiA8cD4KICAgICAqIFRoaXMgbWV0aG9kIHRha2VzIHRoZSBhcmd1bWVudCBpbmRleCBhbmQgc2V0cyB0aGUgcG9zaXRpb24gaW4gdGhlIHRleHQgCiAgICAgKiBzdHJpbmcgYWNjb3JkaW5nbHkgd2l0aG91dCBjaGVja2luZyBpZiB0aGUgaW5kZXggaXMgcG9pbnRpbmcgdG8gYSAKICAgICAqIHZhbGlkIHN0YXJ0aW5nIHBvaW50IHRvIGJlZ2luIHNlYXJjaGluZy4gCiAgICAgKiBAcGFyYW0gcG9zaXRpb24gd2l0aGluIHRoZSB0ZXh0IHRvIGJlIHNldC4gSWYgcG9zaXRpb24gaXMgbGVzcwogICAgICogCQkJdGhhbiBvciBncmVhdGVyIHRoYW4gdGhlIHRleHQgcmFuZ2UgZm9yIHNlYXJjaGluZywgCiAgICAgKiAgICAgICAgICBhbiBVX0lOREVYX09VVE9GQk9VTkRTX0VSUk9SIHdpbGwgYmUgcmV0dXJuZWQKICAgICAqIEBwYXJhbSBzdGF0dXMgZm9yIGVycm9ycyBpZiBpdCBvY2N1cnMKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0T2Zmc2V0KGludDMyX3QgcG9zaXRpb24sIFVFcnJvckNvZGUgJnN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgaW5kZXggaW4gdGhlIHRleHQgYmVpbmcgc2VhcmNoZWQuCiAgICAgKiBJZiB0aGUgaXRlcmF0aW9uIGhhcyBnb25lIHBhc3QgdGhlIGVuZCBvZiB0aGUgdGV4dAogICAgICogKG9yIHBhc3QgdGhlIGJlZ2lubmluZyBmb3IgYSBiYWNrd2FyZHMgc2VhcmNoKSwgVVNFQVJDSF9ET05FCiAgICAgKiBpcyByZXR1cm5lZC4KICAgICAqIEByZXR1cm4gY3VycmVudCBpbmRleCBpbiB0aGUgdGV4dCBiZWluZyBzZWFyY2hlZC4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0T2Zmc2V0KHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogU2V0IHRoZSB0YXJnZXQgdGV4dCB0byBiZSBzZWFyY2hlZC4KICAgICAqIFRleHQgaXRlcmF0aW9uIHdpbGwgaGVuY2UgYmVnaW4gYXQgdGhlIHN0YXJ0IG9mIHRoZSB0ZXh0IHN0cmluZy4gCiAgICAgKiBUaGlzIG1ldGhvZCBpcyAKICAgICAqIHVzZWZ1bCBpZiB5b3Ugd2FudCB0byByZS11c2UgYW4gaXRlcmF0b3IgdG8gc2VhcmNoIGZvciB0aGUgc2FtZSAKICAgICAqIHBhdHRlcm4gd2l0aGluIGEgZGlmZmVyZW50IGJvZHkgb2YgdGV4dC4KICAgICAqIEBwYXJhbSB0ZXh0IHRleHQgc3RyaW5nIHRvIGJlIHNlYXJjaGVkCiAgICAgKiBAcGFyYW0gc3RhdHVzIGZvciBlcnJvcnMgaWYgYW55LiBJZiB0aGUgdGV4dCBsZW5ndGggaXMgMCB0aGVuIGFuIAogICAgICogICAgICAgIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiBpcyByZXR1cm5lZC4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0VGV4dChjb25zdCBVbmljb2RlU3RyaW5nICZ0ZXh0LCBVRXJyb3JDb2RlICZzdGF0dXMpOwogICAgCiAgICAvKioKICAgICAqIFNldCB0aGUgdGFyZ2V0IHRleHQgdG8gYmUgc2VhcmNoZWQuCiAgICAgKiBUZXh0IGl0ZXJhdGlvbiB3aWxsIGhlbmNlIGJlZ2luIGF0IHRoZSBzdGFydCBvZiB0aGUgdGV4dCBzdHJpbmcuIAogICAgICogVGhpcyBtZXRob2QgaXMgCiAgICAgKiB1c2VmdWwgaWYgeW91IHdhbnQgdG8gcmUtdXNlIGFuIGl0ZXJhdG9yIHRvIHNlYXJjaCBmb3IgdGhlIHNhbWUgCiAgICAgKiBwYXR0ZXJuIHdpdGhpbiBhIGRpZmZlcmVudCBib2R5IG9mIHRleHQuCiAgICAgKiBOb3RlOiBObyBwYXJzaW5nIG9mIHRoZSB0ZXh0IHdpdGhpbiB0aGUgPHR0PkNoYXJhY3Rlckl0ZXJhdG9yPC90dD4gCiAgICAgKiB3aWxsIGJlIGRvbmUgZHVyaW5nIHNlYXJjaGluZyBmb3IgdGhpcyB2ZXJzaW9uLiBUaGUgYmxvY2sgb2YgdGV4dCAKICAgICAqIGluIDx0dD5DaGFyYWN0ZXJJdGVyYXRvcjwvdHQ+IHdpbGwgYmUgdXNlZCBhcyBpdCBpcy4KICAgICAqIEBwYXJhbSB0ZXh0IHRleHQgc3RyaW5nIHRvIGJlIHNlYXJjaGVkCiAgICAgKiBAcGFyYW0gc3RhdHVzIGZvciBlcnJvcnMgaWYgYW55LiBJZiB0aGUgdGV4dCBsZW5ndGggaXMgMCB0aGVuIGFuIAogICAgICogICAgICAgIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiBpcyByZXR1cm5lZC4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0VGV4dChDaGFyYWN0ZXJJdGVyYXRvciAmdGV4dCwgVUVycm9yQ29kZSAmc3RhdHVzKTsKCiAgICAvKioKICAgICAqIEdldHMgdGhlIGNvbGxhdG9yIHVzZWQgZm9yIHRoZSBsYW5ndWFnZSBydWxlcy4KICAgICAqIDxwPgogICAgICogQ2FsbGVyIG1heSBtb2RpZnkgYnV0IDxiPm11c3Qgbm90PC9iPiBkZWxldGUgdGhlIDx0dD5SdWxlQmFzZWRDb2xsYXRvcjwvdHQ+IQoJICogTW9kaWZpY2F0aW9ucyB0byB0aGlzIGNvbGxhdG9yIHdpbGwgYWZmZWN0IHRoZSBvcmlnaW5hbCBjb2xsYXRvciBwYXNzZWQgaW4gdG8gCgkgKiB0aGUgPHR0PlN0cmluZ1NlYXJjaD4vdHQ+IGNvbnN0cnVjdG9yIG9yIHRvIHNldENvbGxhdG9yLCBpZiBhbnkuCiAgICAgKiBAcmV0dXJuIGNvbGxhdG9yIHVzZWQgZm9yIHN0cmluZyBzZWFyY2gKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBSdWxlQmFzZWRDb2xsYXRvciAqIGdldENvbGxhdG9yKCkgY29uc3Q7CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgY29sbGF0b3IgdXNlZCBmb3IgdGhlIGxhbmd1YWdlIHJ1bGVzLiBVc2VyIHJldGFpbnMgdGhlIAogICAgICogb3duZXJzaGlwIG9mIHRoaXMgY29sbGF0b3IsIHRodXMgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIGRlbGV0aW9uIGxpZXMgCiAgICAgKiB3aXRoIHRoZSB1c2VyLiBUaGlzIG1ldGhvZCBjYXVzZXMgaW50ZXJuYWwgZGF0YSBzdWNoIGFzIEJveWVyLU1vb3JlIAogICAgICogc2hpZnQgdGFibGVzIHRvIGJlIHJlY2FsY3VsYXRlZCwgYnV0IHRoZSBpdGVyYXRvcidzIHBvc2l0aW9uIGlzIAogICAgICogdW5jaGFuZ2VkLgogICAgICogQHBhcmFtIGNvbGwgICAgY29sbGF0b3IgCiAgICAgKiBAcGFyYW0gc3RhdHVzICBmb3IgZXJyb3JzIGlmIGFueQogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZvaWQgc2V0Q29sbGF0b3IoUnVsZUJhc2VkQ29sbGF0b3IgKmNvbGwsIFVFcnJvckNvZGUgJnN0YXR1cyk7CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcGF0dGVybiB1c2VkIGZvciBtYXRjaGluZy4KICAgICAqIEludGVybmFsIGRhdGEgbGlrZSB0aGUgQm95ZXIgTW9vcmUgdGFibGUgd2lsbCBiZSByZWNhbGN1bGF0ZWQsIGJ1dCAKICAgICAqIHRoZSBpdGVyYXRvcidzIHBvc2l0aW9uIGlzIHVuY2hhbmdlZC4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIHNlYXJjaCBwYXR0ZXJuIHRvIGJlIGZvdW5kCiAgICAgKiBAcGFyYW0gc3RhdHVzIGZvciBlcnJvcnMgaWYgYW55LiBJZiB0aGUgcGF0dGVybiBsZW5ndGggaXMgMCB0aGVuIGFuIAogICAgICogICAgICAgICAgICAgICBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1IgaXMgcmV0dXJuZWQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdm9pZCBzZXRQYXR0ZXJuKGNvbnN0IFVuaWNvZGVTdHJpbmcgJnBhdHRlcm4sIFVFcnJvckNvZGUgJnN0YXR1cyk7CiAgICAKICAgIC8qKgogICAgICogR2V0cyB0aGUgc2VhcmNoIHBhdHRlcm4uCiAgICAgKiBAcmV0dXJuIHBhdHRlcm4gdXNlZCBmb3IgbWF0Y2hpbmcKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBjb25zdCBVbmljb2RlU3RyaW5nICYgZ2V0UGF0dGVybigpIGNvbnN0OwoKICAgIC8vIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKiogCiAgICAgKiBSZXNldCB0aGUgaXRlcmF0aW9uLgogICAgICogU2VhcmNoIHdpbGwgYmVnaW4gYXQgdGhlIHN0YXJ0IG9mIHRoZSB0ZXh0IHN0cmluZyBpZiBhIGZvcndhcmQgCiAgICAgKiBpdGVyYXRpb24gaXMgaW5pdGlhdGVkIGJlZm9yZSBhIGJhY2t3YXJkcyBpdGVyYXRpb24uIE90aGVyd2lzZSBpZiAKICAgICAqIGEgYmFja3dhcmRzIGl0ZXJhdGlvbiBpcyBpbml0aWF0ZWQgYmVmb3JlIGEgZm9yd2FyZHMgaXRlcmF0aW9uLCB0aGUgCiAgICAgKiBzZWFyY2ggd2lsbCBiZWdpbiBhdCB0aGUgZW5kIG9mIHRoZSB0ZXh0IHN0cmluZy4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgcmVzZXQoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBjb3B5IG9mIFN0cmluZ1NlYXJjaCB3aXRoIHRoZSBzYW1lIGJlaGF2aW9yLCBhbmQgCiAgICAgKiBpdGVyYXRpbmcgb3ZlciB0aGUgc2FtZSB0ZXh0LCBhcyB0aGlzIG9uZS4gTm90ZSB0aGF0IGFsbCBkYXRhIHdpbGwgYmUKICAgICAqIHJlcGxpY2F0ZWQsIGV4Y2VwdCBmb3IgdGhlIHVzZXItc3BlY2lmaWVkIGNvbGxhdG9yIGFuZCB0aGUKICAgICAqIGJyZWFraXRlcmF0b3IuCiAgICAgKiBAcmV0dXJuIGNsb25lZCBvYmplY3QKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIFNlYXJjaEl0ZXJhdG9yICogc2FmZUNsb25lKHZvaWQpIGNvbnN0OwogICAgCiAgICAvKioKICAgICAqIElDVSAicG9vciBtYW4ncyBSVFRJIiwgcmV0dXJucyBhIFVDbGFzc0lEIGZvciB0aGUgYWN0dWFsIGNsYXNzLgogICAgICoKICAgICAqIEBkcmFmdCBJQ1UgMi4yCiAgICAgKi8KICAgIHZpcnR1YWwgaW5saW5lIFVDbGFzc0lEIGdldER5bmFtaWNDbGFzc0lEKCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBJQ1UgInBvb3IgbWFuJ3MgUlRUSSIsIHJldHVybnMgYSBVQ2xhc3NJRCBmb3IgdGhpcyBjbGFzcy4KICAgICAqCiAgICAgKiBAZHJhZnQgSUNVIDIuMgogICAgICovCiAgICBzdGF0aWMgaW5saW5lIFVDbGFzc0lEIGdldFN0YXRpY0NsYXNzSUQoKTsKCnByb3RlY3RlZDoKCiAgICAvLyBwcm90ZWN0ZWQgbWV0aG9kIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIFNlYXJjaCBmb3J3YXJkIGZvciBtYXRjaGluZyB0ZXh0LCBzdGFydGluZyBhdCBhIGdpdmVuIGxvY2F0aW9uLgogICAgICogQ2xpZW50cyBzaG91bGQgbm90IGNhbGwgdGhpcyBtZXRob2QgZGlyZWN0bHk7IGluc3RlYWQgdGhleSBzaG91bGQgCiAgICAgKiBjYWxsIHtAbGluayBTZWFyY2hJdGVyYXRvciNuZXh0fS4KICAgICAqIDxwPgogICAgICogSWYgYSBtYXRjaCBpcyBmb3VuZCwgdGhpcyBtZXRob2QgcmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIG1hdGNoCiAgICAgKiBzdGFydHMgYW5kIGNhbGxzIHtAbGluayBTZWFyY2hJdGVyYXRvciNzZXRNYXRjaExlbmd0aH0gd2l0aCB0aGUgbnVtYmVyIAogICAgICogb2YgY2hhcmFjdGVycyBpbiB0aGUgdGFyZ2V0IHRleHQgdGhhdCBtYWtlIHVwIHRoZSBtYXRjaC4gSWYgbm8gbWF0Y2ggCiAgICAgKiBpcyBmb3VuZCwgdGhlIG1ldGhvZCByZXR1cm5zIDx0dD5VU0VBUkNIX0RPTkU8L3R0Pi4KICAgICAqIDxwPgogICAgICogVGhlIDx0dD5TdHJpbmdTZWFyY2g8L3R0PiBpcyBhZGp1c3RlZCBzbyB0aGF0IGl0cyBjdXJyZW50IGluZGV4IAogICAgICogKGFzIHJldHVybmVkIGJ5IHtAbGluayAjZ2V0T2Zmc2V0KCl9KSBpcyB0aGUgbWF0Y2ggcG9zaXRpb24gaWYgb25lIHdhcyAKICAgICAqIGZvdW5kLgogICAgICogSWYgYSBtYXRjaCBpcyBub3QgZm91bmQsIDx0dD5VU0VBUkNIX0RPTkU8L3R0PiB3aWxsIGJlIHJldHVybmVkIGFuZAogICAgICogdGhlIDx0dD5TdHJpbmdTZWFyY2g8L3R0PiB3aWxsIGJlIGFkanVzdGVkIHRvIHRoZSBpbmRleCBVU0VBUkNIX0RPTkUuCiAgICAgKiBAcGFyYW0gcG9zaXRpb24gVGhlIGluZGV4IGluIHRoZSB0YXJnZXQgdGV4dCBhdCB3aGljaCB0aGUgc2VhcmNoIAogICAgICogICAgICAgICAgICAgICAgIHN0YXJ0cwogICAgICogQHBhcmFtIHN0YXR1cyBmb3IgZXJyb3JzIGlmIGFueSBvY2N1cnMKICAgICAqIEByZXR1cm4gVGhlIGluZGV4IGF0IHdoaWNoIHRoZSBtYXRjaGVkIHRleHQgaW4gdGhlIHRhcmdldCBzdGFydHMsIG9yIAogICAgICogICAgICAgICBVU0VBUkNIX0RPTkUgaWYgbm8gbWF0Y2ggd2FzIGZvdW5kLgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBoYW5kbGVOZXh0KGludDMyX3QgcG9zaXRpb24sIFVFcnJvckNvZGUgJnN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBTZWFyY2ggYmFja3dhcmQgZm9yIG1hdGNoaW5nIHRleHQsIHN0YXJ0aW5nIGF0IGEgZ2l2ZW4gbG9jYXRpb24uCiAgICAgKiBDbGllbnRzIHNob3VsZCBub3QgY2FsbCB0aGlzIG1ldGhvZCBkaXJlY3RseTsgaW5zdGVhZCB0aGV5IHNob3VsZCBjYWxsCiAgICAgKiA8dHQ+U2VhcmNoSXRlcmF0b3IucHJldmlvdXMoKTwvdHQ+LCB3aGljaCB0aGlzIG1ldGhvZCBvdmVycmlkZXMuCiAgICAgKiA8cD4KICAgICAqIElmIGEgbWF0Y2ggaXMgZm91bmQsIHRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBtYXRjaAogICAgICogc3RhcnRzIGFuZCBjYWxscyB7QGxpbmsgU2VhcmNoSXRlcmF0b3Ijc2V0TWF0Y2hMZW5ndGh9IHdpdGggdGhlIG51bWJlciAKICAgICAqIG9mIGNoYXJhY3RlcnMgaW4gdGhlIHRhcmdldCB0ZXh0IHRoYXQgbWFrZSB1cCB0aGUgbWF0Y2guIElmIG5vIG1hdGNoIAogICAgICogaXMgZm91bmQsIHRoZSBtZXRob2QgcmV0dXJucyA8dHQ+VVNFQVJDSF9ET05FPC90dD4uCiAgICAgKiA8cD4KICAgICAqIFRoZSA8dHQ+U3RyaW5nU2VhcmNoPC90dD4gaXMgYWRqdXN0ZWQgc28gdGhhdCBpdHMgY3VycmVudCBpbmRleCAKICAgICAqIChhcyByZXR1cm5lZCBieSB7QGxpbmsgI2dldE9mZnNldCgpfSkgaXMgdGhlIG1hdGNoIHBvc2l0aW9uIGlmIG9uZSB3YXMgCiAgICAgKiBmb3VuZC4KICAgICAqIElmIGEgbWF0Y2ggaXMgbm90IGZvdW5kLCA8dHQ+VVNFQVJDSF9ET05FPC90dD4gd2lsbCBiZSByZXR1cm5lZCBhbmQKICAgICAqIHRoZSA8dHQ+U3RyaW5nU2VhcmNoPC90dD4gd2lsbCBiZSBhZGp1c3RlZCB0byB0aGUgaW5kZXggVVNFQVJDSF9ET05FLgogICAgICogQHBhcmFtIHBvc2l0aW9uIFRoZSBpbmRleCBpbiB0aGUgdGFyZ2V0IHRleHQgYXQgd2hpY2ggdGhlIHNlYXJjaCAKICAgICAqICAgICAgICAgICAgICAgICBzdGFydHMuCiAgICAgKiBAcGFyYW0gc3RhdHVzIGZvciBlcnJvcnMgaWYgYW55IG9jY3VycwogICAgICogQHJldHVybiBUaGUgaW5kZXggYXQgd2hpY2ggdGhlIG1hdGNoZWQgdGV4dCBpbiB0aGUgdGFyZ2V0IHN0YXJ0cywgb3IgCiAgICAgKiAgICAgICAgIFVTRUFSQ0hfRE9ORSBpZiBubyBtYXRjaCB3YXMgZm91bmQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGhhbmRsZVByZXYoaW50MzJfdCBwb3NpdGlvbiwgVUVycm9yQ29kZSAmc3RhdHVzKTsKICAgIApwcml2YXRlIDoKICAgIFN0cmluZ1NlYXJjaCgpOyAvLyBkZWZhdWx0IGNvbnN0cnVjdG9yIG5vdCBpbXBsZW1lbnRlZAoKICAgIC8vIHByaXZhdGUgZGF0YSBtZW1iZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICogUnVsZUJhc2VkQ29sbGF0b3IsIGNvbnRhaW5zIGV4YWN0bHkgdGhlIHNhbWUgVUNvbGxhdG9yICogaW4gbV9zdHJzcmNoXwogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBSdWxlQmFzZWRDb2xsYXRvciAgbV9jb2xsYXRvcl87CiAgICAvKioKICAgICogUGF0dGVybiB0ZXh0CiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIFVuaWNvZGVTdHJpbmcgICAgICBtX3BhdHRlcm5fOwogICAgLyoqCiAgICAqIENvcnJlc3BvbmRpbmcgY29sbGF0aW9uIHJ1bGVzCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIFVuaWNvZGVTdHJpbmcgICAgICBtX2NvbGxhdGlvbl9ydWxlc187CiAgICAvKioKICAgICogU3RyaW5nIHNlYXJjaCBzdHJ1Y3QgZGF0YQogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBVU3RyaW5nU2VhcmNoICAgICAqbV9zdHJzcmNoXzsKCiAgICAvKioKICAgICAqIFRoZSBhZGRyZXNzIG9mIHRoaXMgc3RhdGljIGNsYXNzIHZhcmlhYmxlIHNlcnZlcyBhcyB0aGlzIGNsYXNzJ3MgSUQKICAgICAqIGZvciBJQ1UgInBvb3IgbWFuJ3MgUlRUSSIuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBjaGFyIGZnQ2xhc3NJRDsKfTsKCmlubGluZSBVQ2xhc3NJRApTdHJpbmdTZWFyY2g6OmdldFN0YXRpY0NsYXNzSUQoKQp7IHJldHVybiAoVUNsYXNzSUQpJmZnQ2xhc3NJRDsgfQoKaW5saW5lIFVDbGFzc0lEClN0cmluZ1NlYXJjaDo6Z2V0RHluYW1pY0NsYXNzSUQoKSBjb25zdAp7IHJldHVybiBTdHJpbmdTZWFyY2g6OmdldFN0YXRpY0NsYXNzSUQoKTsgfQoKVV9OQU1FU1BBQ0VfRU5ECgojZW5kaWYgLyogI2lmICFVQ09ORklHX05PX0NPTExBVElPTiAqLwoKI2VuZGlmCgo=