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+IGNhbiBiZSBwYXNzZWQgaW4gaW5zdGVhZC4KICAgICAqIEBwYXJhbSBzdGF0dXMgZm9yIGVycm9ycyBpZiBhbnkuIElmIGVpdGhlciB0aGUgbGVuZ3RoIG9mIHBhdHRlcm4gb3IgCiAgICAgKiAgICAgICAgICAgICAgIHRleHQgaXMgMCB0aGVuIGFuIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiBpcyByZXR1cm5lZC4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBTdHJpbmdTZWFyY2goY29uc3QgVW5pY29kZVN0cmluZyAgICAgJnBhdHRlcm4sIENoYXJhY3Rlckl0ZXJhdG9yICZ0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpjb2xsLCAKICAgICAgICAgICAgICAgICAgICAgICBCcmVha0l0ZXJhdG9yICAgICAqYnJlYWtpdGVyLAogICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgICAgICAgICZzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29weSBjb25zdHJ1Y3RvciB0aGF0IGNyZWF0ZXMgYSBTdHJpbmdTZWFyY2ggaW5zdGFuY2Ugd2l0aCB0aGUgc2FtZSAKICAgICAqIGJlaGF2aW9yLCBhbmQgaXRlcmF0aW5nIG92ZXIgdGhlIHNhbWUgdGV4dC4KICAgICAqIEBwYXJhbSB0aGF0IFN0cmluZ1NlYXJjaCBpbnN0YW5jZSB0byBiZSBjb3BpZWQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgU3RyaW5nU2VhcmNoKGNvbnN0IFN0cmluZ1NlYXJjaCAmdGhhdCk7CgogICAgLyoqCiAgICAqIERlc3RydWN0b3IuIENsZWFucyB1cCB0aGUgc2VhcmNoIGl0ZXJhdG9yIGRhdGEgc3RydWN0LgogICAgKiBJZiBhIGNvbGxhdG9yIGlzIGNyZWF0ZWQgaW4gdGhlIGNvbnN0cnVjdG9yLCBpdCB3aWxsIGJlIGRlc3Ryb3llZCBoZXJlLgogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICB2aXJ0dWFsIH5TdHJpbmdTZWFyY2godm9pZCk7CgogICAgLyoqCiAgICAgKiBDbG9uZSB0aGlzIG9iamVjdC4KICAgICAqIENsb25lcyBjYW4gYmUgdXNlZCBjb25jdXJyZW50bHkgaW4gbXVsdGlwbGUgdGhyZWFkcy4KICAgICAqIElmIGFuIGVycm9yIG9jY3VycywgdGhlbiBOVUxMIGlzIHJldHVybmVkLgogICAgICogVGhlIGNhbGxlciBtdXN0IGRlbGV0ZSB0aGUgY2xvbmUuCiAgICAgKgogICAgICogQHJldHVybiBhIGNsb25lIG9mIHRoaXMgb2JqZWN0CiAgICAgKgogICAgICogQHNlZSBnZXREeW5hbWljQ2xhc3NJRAogICAgICogQGRyYWZ0IElDVSAyLjgKICAgICAqLwogICAgU3RyaW5nU2VhcmNoICpjbG9uZSgpIGNvbnN0OwoKICAgIC8vIG9wZXJhdG9yIG92ZXJsb2FkaW5nIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgICogQXNzaWdubWVudCBvcGVyYXRvci4gU2V0cyB0aGlzIGl0ZXJhdG9yIHRvIGhhdmUgdGhlIHNhbWUgYmVoYXZpb3IsCiAgICAgKiBhbmQgaXRlcmF0ZSBvdmVyIHRoZSBzYW1lIHRleHQsIGFzIHRoZSBvbmUgcGFzc2VkIGluLgogICAgICogQHBhcmFtIHRoYXQgaW5zdGFuY2UgdG8gYmUgY29waWVkLgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIFN0cmluZ1NlYXJjaCAmIG9wZXJhdG9yPShjb25zdCBTdHJpbmdTZWFyY2ggJnRoYXQpOwoKICAgIC8qKgogICAgICogRXF1YWxpdHkgb3BlcmF0b3IuIAogICAgICogQHBhcmFtIHRoYXQgaW5zdGFuY2UgdG8gYmUgY29tcGFyZWQuCiAgICAgKiBAcmV0dXJuIFRSVUUgaWYgYm90aCBpbnN0YW5jZXMgaGF2ZSB0aGUgc2FtZSBhdHRyaWJ1dGVzLCAKICAgICAqICAgICAgICAgYnJlYWtpdGVyYXRvcnMsIGNvbGxhdG9ycyBhbmQgaXRlcmF0ZSBvdmVyIHRoZSBzYW1lIHRleHQgCiAgICAgKiAgICAgICAgIHdoaWxlIGxvb2tpbmcgZm9yIHRoZSBzYW1lIHBhdHRlcm4uCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCBVQm9vbCBvcGVyYXRvcj09KGNvbnN0IFNlYXJjaEl0ZXJhdG9yICZ0aGF0KSBjb25zdDsKCiAgICAvLyBwdWJsaWMgZ2V0IGFuZCBzZXQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBpbmRleCB0byBwb2ludCB0byB0aGUgZ2l2ZW4gcG9zaXRpb24sIGFuZCBjbGVhcnMgYW55IHN0YXRlIAogICAgICogdGhhdCdzIGFmZmVjdGVkLgogICAgICogPHA+CiAgICAgKiBUaGlzIG1ldGhvZCB0YWtlcyB0aGUgYXJndW1lbnQgaW5kZXggYW5kIHNldHMgdGhlIHBvc2l0aW9uIGluIHRoZSB0ZXh0IAogICAgICogc3RyaW5nIGFjY29yZGluZ2x5IHdpdGhvdXQgY2hlY2tpbmcgaWYgdGhlIGluZGV4IGlzIHBvaW50aW5nIHRvIGEgCiAgICAgKiB2YWxpZCBzdGFydGluZyBwb2ludCB0byBiZWdpbiBzZWFyY2hpbmcuIAogICAgICogQHBhcmFtIHBvc2l0aW9uIHdpdGhpbiB0aGUgdGV4dCB0byBiZSBzZXQuIElmIHBvc2l0aW9uIGlzIGxlc3MKICAgICAqICAgICAgICAgIHRoYW4gb3IgZ3JlYXRlciB0aGFuIHRoZSB0ZXh0IHJhbmdlIGZvciBzZWFyY2hpbmcsIAogICAgICogICAgICAgICAgYW4gVV9JTkRFWF9PVVRPRkJPVU5EU19FUlJPUiB3aWxsIGJlIHJldHVybmVkCiAgICAgKiBAcGFyYW0gc3RhdHVzIGZvciBlcnJvcnMgaWYgaXQgb2NjdXJzCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHNldE9mZnNldChpbnQzMl90IHBvc2l0aW9uLCBVRXJyb3JDb2RlICZzdGF0dXMpOwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGluZGV4IGluIHRoZSB0ZXh0IGJlaW5nIHNlYXJjaGVkLgogICAgICogSWYgdGhlIGl0ZXJhdGlvbiBoYXMgZ29uZSBwYXN0IHRoZSBlbmQgb2YgdGhlIHRleHQKICAgICAqIChvciBwYXN0IHRoZSBiZWdpbm5pbmcgZm9yIGEgYmFja3dhcmRzIHNlYXJjaCksIFVTRUFSQ0hfRE9ORQogICAgICogaXMgcmV0dXJuZWQuCiAgICAgKiBAcmV0dXJuIGN1cnJlbnQgaW5kZXggaW4gdGhlIHRleHQgYmVpbmcgc2VhcmNoZWQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGdldE9mZnNldCh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFNldCB0aGUgdGFyZ2V0IHRleHQgdG8gYmUgc2VhcmNoZWQuCiAgICAgKiBUZXh0IGl0ZXJhdGlvbiB3aWxsIGhlbmNlIGJlZ2luIGF0IHRoZSBzdGFydCBvZiB0aGUgdGV4dCBzdHJpbmcuIAogICAgICogVGhpcyBtZXRob2QgaXMgCiAgICAgKiB1c2VmdWwgaWYgeW91IHdhbnQgdG8gcmUtdXNlIGFuIGl0ZXJhdG9yIHRvIHNlYXJjaCBmb3IgdGhlIHNhbWUgCiAgICAgKiBwYXR0ZXJuIHdpdGhpbiBhIGRpZmZlcmVudCBib2R5IG9mIHRleHQuCiAgICAgKiBAcGFyYW0gdGV4dCB0ZXh0IHN0cmluZyB0byBiZSBzZWFyY2hlZAogICAgICogQHBhcmFtIHN0YXR1cyBmb3IgZXJyb3JzIGlmIGFueS4gSWYgdGhlIHRleHQgbGVuZ3RoIGlzIDAgdGhlbiBhbiAKICAgICAqICAgICAgICBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1IgaXMgcmV0dXJuZWQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHNldFRleHQoY29uc3QgVW5pY29kZVN0cmluZyAmdGV4dCwgVUVycm9yQ29kZSAmc3RhdHVzKTsKICAgIAogICAgLyoqCiAgICAgKiBTZXQgdGhlIHRhcmdldCB0ZXh0IHRvIGJlIHNlYXJjaGVkLgogICAgICogVGV4dCBpdGVyYXRpb24gd2lsbCBoZW5jZSBiZWdpbiBhdCB0aGUgc3RhcnQgb2YgdGhlIHRleHQgc3RyaW5nLiAKICAgICAqIFRoaXMgbWV0aG9kIGlzIAogICAgICogdXNlZnVsIGlmIHlvdSB3YW50IHRvIHJlLXVzZSBhbiBpdGVyYXRvciB0byBzZWFyY2ggZm9yIHRoZSBzYW1lIAogICAgICogcGF0dGVybiB3aXRoaW4gYSBkaWZmZXJlbnQgYm9keSBvZiB0ZXh0LgogICAgICogTm90ZTogTm8gcGFyc2luZyBvZiB0aGUgdGV4dCB3aXRoaW4gdGhlIDx0dD5DaGFyYWN0ZXJJdGVyYXRvcjwvdHQ+IAogICAgICogd2lsbCBiZSBkb25lIGR1cmluZyBzZWFyY2hpbmcgZm9yIHRoaXMgdmVyc2lvbi4gVGhlIGJsb2NrIG9mIHRleHQgCiAgICAgKiBpbiA8dHQ+Q2hhcmFjdGVySXRlcmF0b3I8L3R0PiB3aWxsIGJlIHVzZWQgYXMgaXQgaXMuCiAgICAgKiBAcGFyYW0gdGV4dCB0ZXh0IHN0cmluZyB0byBiZSBzZWFyY2hlZAogICAgICogQHBhcmFtIHN0YXR1cyBmb3IgZXJyb3JzIGlmIGFueS4gSWYgdGhlIHRleHQgbGVuZ3RoIGlzIDAgdGhlbiBhbiAKICAgICAqICAgICAgICBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1IgaXMgcmV0dXJuZWQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHNldFRleHQoQ2hhcmFjdGVySXRlcmF0b3IgJnRleHQsIFVFcnJvckNvZGUgJnN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjb2xsYXRvciB1c2VkIGZvciB0aGUgbGFuZ3VhZ2UgcnVsZXMuCiAgICAgKiA8cD4KICAgICAqIENhbGxlciBtYXkgbW9kaWZ5IGJ1dCA8Yj5tdXN0IG5vdDwvYj4gZGVsZXRlIHRoZSA8dHQ+UnVsZUJhc2VkQ29sbGF0b3I8L3R0PiEKICAgICAqIE1vZGlmaWNhdGlvbnMgdG8gdGhpcyBjb2xsYXRvciB3aWxsIGFmZmVjdCB0aGUgb3JpZ2luYWwgY29sbGF0b3IgcGFzc2VkIGluIHRvIAogICAgICogdGhlIDx0dD5TdHJpbmdTZWFyY2g+L3R0PiBjb25zdHJ1Y3RvciBvciB0byBzZXRDb2xsYXRvciwgaWYgYW55LgogICAgICogQHJldHVybiBjb2xsYXRvciB1c2VkIGZvciBzdHJpbmcgc2VhcmNoCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgUnVsZUJhc2VkQ29sbGF0b3IgKiBnZXRDb2xsYXRvcigpIGNvbnN0OwogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIGNvbGxhdG9yIHVzZWQgZm9yIHRoZSBsYW5ndWFnZSBydWxlcy4gVXNlciByZXRhaW5zIHRoZSAKICAgICAqIG93bmVyc2hpcCBvZiB0aGlzIGNvbGxhdG9yLCB0aHVzIHRoZSByZXNwb25zaWJpbGl0eSBvZiBkZWxldGlvbiBsaWVzIAogICAgICogd2l0aCB0aGUgdXNlci4gVGhpcyBtZXRob2QgY2F1c2VzIGludGVybmFsIGRhdGEgc3VjaCBhcyBCb3llci1Nb29yZSAKICAgICAqIHNoaWZ0IHRhYmxlcyB0byBiZSByZWNhbGN1bGF0ZWQsIGJ1dCB0aGUgaXRlcmF0b3IncyBwb3NpdGlvbiBpcyAKICAgICAqIHVuY2hhbmdlZC4KICAgICAqIEBwYXJhbSBjb2xsICAgIGNvbGxhdG9yIAogICAgICogQHBhcmFtIHN0YXR1cyAgZm9yIGVycm9ycyBpZiBhbnkKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2b2lkIHNldENvbGxhdG9yKFJ1bGVCYXNlZENvbGxhdG9yICpjb2xsLCBVRXJyb3JDb2RlICZzdGF0dXMpOwogICAgCiAgICAvKioKICAgICAqIFNldHMgdGhlIHBhdHRlcm4gdXNlZCBmb3IgbWF0Y2hpbmcuCiAgICAgKiBJbnRlcm5hbCBkYXRhIGxpa2UgdGhlIEJveWVyIE1vb3JlIHRhYmxlIHdpbGwgYmUgcmVjYWxjdWxhdGVkLCBidXQgCiAgICAgKiB0aGUgaXRlcmF0b3IncyBwb3NpdGlvbiBpcyB1bmNoYW5nZWQuCiAgICAgKiBAcGFyYW0gcGF0dGVybiBzZWFyY2ggcGF0dGVybiB0byBiZSBmb3VuZAogICAgICogQHBhcmFtIHN0YXR1cyBmb3IgZXJyb3JzIGlmIGFueS4gSWYgdGhlIHBhdHRlcm4gbGVuZ3RoIGlzIDAgdGhlbiBhbiAKICAgICAqICAgICAgICAgICAgICAgVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SIGlzIHJldHVybmVkLgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZvaWQgc2V0UGF0dGVybihjb25zdCBVbmljb2RlU3RyaW5nICZwYXR0ZXJuLCBVRXJyb3JDb2RlICZzdGF0dXMpOwogICAgCiAgICAvKioKICAgICAqIEdldHMgdGhlIHNlYXJjaCBwYXR0ZXJuLgogICAgICogQHJldHVybiBwYXR0ZXJuIHVzZWQgZm9yIG1hdGNoaW5nCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgY29uc3QgVW5pY29kZVN0cmluZyAmIGdldFBhdHRlcm4oKSBjb25zdDsKCiAgICAvLyBwdWJsaWMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqIAogICAgICogUmVzZXQgdGhlIGl0ZXJhdGlvbi4KICAgICAqIFNlYXJjaCB3aWxsIGJlZ2luIGF0IHRoZSBzdGFydCBvZiB0aGUgdGV4dCBzdHJpbmcgaWYgYSBmb3J3YXJkIAogICAgICogaXRlcmF0aW9uIGlzIGluaXRpYXRlZCBiZWZvcmUgYSBiYWNrd2FyZHMgaXRlcmF0aW9uLiBPdGhlcndpc2UgaWYgCiAgICAgKiBhIGJhY2t3YXJkcyBpdGVyYXRpb24gaXMgaW5pdGlhdGVkIGJlZm9yZSBhIGZvcndhcmRzIGl0ZXJhdGlvbiwgdGhlIAogICAgICogc2VhcmNoIHdpbGwgYmVnaW4gYXQgdGhlIGVuZCBvZiB0aGUgdGV4dCBzdHJpbmcuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHJlc2V0KCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgY29weSBvZiBTdHJpbmdTZWFyY2ggd2l0aCB0aGUgc2FtZSBiZWhhdmlvciwgYW5kIAogICAgICogaXRlcmF0aW5nIG92ZXIgdGhlIHNhbWUgdGV4dCwgYXMgdGhpcyBvbmUuIE5vdGUgdGhhdCBhbGwgZGF0YSB3aWxsIGJlCiAgICAgKiByZXBsaWNhdGVkLCBleGNlcHQgZm9yIHRoZSB1c2VyLXNwZWNpZmllZCBjb2xsYXRvciBhbmQgdGhlCiAgICAgKiBicmVha2l0ZXJhdG9yLgogICAgICogQHJldHVybiBjbG9uZWQgb2JqZWN0CiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCBTZWFyY2hJdGVyYXRvciAqIHNhZmVDbG9uZSh2b2lkKSBjb25zdDsKICAgIAogICAgLyoqCiAgICAgKiBJQ1UgInBvb3IgbWFuJ3MgUlRUSSIsIHJldHVybnMgYSBVQ2xhc3NJRCBmb3IgdGhlIGFjdHVhbCBjbGFzcy4KICAgICAqCiAgICAgKiBAc3RhYmxlIElDVSAyLjIKICAgICAqLwogICAgdmlydHVhbCBVQ2xhc3NJRCBnZXREeW5hbWljQ2xhc3NJRCgpIGNvbnN0OwoKICAgIC8qKgogICAgICogSUNVICJwb29yIG1hbidzIFJUVEkiLCByZXR1cm5zIGEgVUNsYXNzSUQgZm9yIHRoaXMgY2xhc3MuCiAgICAgKgogICAgICogQHN0YWJsZSBJQ1UgMi4yCiAgICAgKi8KICAgIHN0YXRpYyBVQ2xhc3NJRCBnZXRTdGF0aWNDbGFzc0lEKCk7Cgpwcm90ZWN0ZWQ6CgogICAgLy8gcHJvdGVjdGVkIG1ldGhvZCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBTZWFyY2ggZm9yd2FyZCBmb3IgbWF0Y2hpbmcgdGV4dCwgc3RhcnRpbmcgYXQgYSBnaXZlbiBsb2NhdGlvbi4KICAgICAqIENsaWVudHMgc2hvdWxkIG5vdCBjYWxsIHRoaXMgbWV0aG9kIGRpcmVjdGx5OyBpbnN0ZWFkIHRoZXkgc2hvdWxkIAogICAgICogY2FsbCB7QGxpbmsgU2VhcmNoSXRlcmF0b3IjbmV4dH0uCiAgICAgKiA8cD4KICAgICAqIElmIGEgbWF0Y2ggaXMgZm91bmQsIHRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBtYXRjaAogICAgICogc3RhcnRzIGFuZCBjYWxscyB7QGxpbmsgU2VhcmNoSXRlcmF0b3Ijc2V0TWF0Y2hMZW5ndGh9IHdpdGggdGhlIG51bWJlciAKICAgICAqIG9mIGNoYXJhY3RlcnMgaW4gdGhlIHRhcmdldCB0ZXh0IHRoYXQgbWFrZSB1cCB0aGUgbWF0Y2guIElmIG5vIG1hdGNoIAogICAgICogaXMgZm91bmQsIHRoZSBtZXRob2QgcmV0dXJucyA8dHQ+VVNFQVJDSF9ET05FPC90dD4uCiAgICAgKiA8cD4KICAgICAqIFRoZSA8dHQ+U3RyaW5nU2VhcmNoPC90dD4gaXMgYWRqdXN0ZWQgc28gdGhhdCBpdHMgY3VycmVudCBpbmRleCAKICAgICAqIChhcyByZXR1cm5lZCBieSB7QGxpbmsgI2dldE9mZnNldCgpfSkgaXMgdGhlIG1hdGNoIHBvc2l0aW9uIGlmIG9uZSB3YXMgCiAgICAgKiBmb3VuZC4KICAgICAqIElmIGEgbWF0Y2ggaXMgbm90IGZvdW5kLCA8dHQ+VVNFQVJDSF9ET05FPC90dD4gd2lsbCBiZSByZXR1cm5lZCBhbmQKICAgICAqIHRoZSA8dHQ+U3RyaW5nU2VhcmNoPC90dD4gd2lsbCBiZSBhZGp1c3RlZCB0byB0aGUgaW5kZXggVVNFQVJDSF9ET05FLgogICAgICogQHBhcmFtIHBvc2l0aW9uIFRoZSBpbmRleCBpbiB0aGUgdGFyZ2V0IHRleHQgYXQgd2hpY2ggdGhlIHNlYXJjaCAKICAgICAqICAgICAgICAgICAgICAgICBzdGFydHMKICAgICAqIEBwYXJhbSBzdGF0dXMgZm9yIGVycm9ycyBpZiBhbnkgb2NjdXJzCiAgICAgKiBAcmV0dXJuIFRoZSBpbmRleCBhdCB3aGljaCB0aGUgbWF0Y2hlZCB0ZXh0IGluIHRoZSB0YXJnZXQgc3RhcnRzLCBvciAKICAgICAqICAgICAgICAgVVNFQVJDSF9ET05FIGlmIG5vIG1hdGNoIHdhcyBmb3VuZC4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgaGFuZGxlTmV4dChpbnQzMl90IHBvc2l0aW9uLCBVRXJyb3JDb2RlICZzdGF0dXMpOwoKICAgIC8qKgogICAgICogU2VhcmNoIGJhY2t3YXJkIGZvciBtYXRjaGluZyB0ZXh0LCBzdGFydGluZyBhdCBhIGdpdmVuIGxvY2F0aW9uLgogICAgICogQ2xpZW50cyBzaG91bGQgbm90IGNhbGwgdGhpcyBtZXRob2QgZGlyZWN0bHk7IGluc3RlYWQgdGhleSBzaG91bGQgY2FsbAogICAgICogPHR0PlNlYXJjaEl0ZXJhdG9yLnByZXZpb3VzKCk8L3R0Piwgd2hpY2ggdGhpcyBtZXRob2Qgb3ZlcnJpZGVzLgogICAgICogPHA+CiAgICAgKiBJZiBhIG1hdGNoIGlzIGZvdW5kLCB0aGlzIG1ldGhvZCByZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgbWF0Y2gKICAgICAqIHN0YXJ0cyBhbmQgY2FsbHMge0BsaW5rIFNlYXJjaEl0ZXJhdG9yI3NldE1hdGNoTGVuZ3RofSB3aXRoIHRoZSBudW1iZXIgCiAgICAgKiBvZiBjaGFyYWN0ZXJzIGluIHRoZSB0YXJnZXQgdGV4dCB0aGF0IG1ha2UgdXAgdGhlIG1hdGNoLiBJZiBubyBtYXRjaCAKICAgICAqIGlzIGZvdW5kLCB0aGUgbWV0aG9kIHJldHVybnMgPHR0PlVTRUFSQ0hfRE9ORTwvdHQ+LgogICAgICogPHA+CiAgICAgKiBUaGUgPHR0PlN0cmluZ1NlYXJjaDwvdHQ+IGlzIGFkanVzdGVkIHNvIHRoYXQgaXRzIGN1cnJlbnQgaW5kZXggCiAgICAgKiAoYXMgcmV0dXJuZWQgYnkge0BsaW5rICNnZXRPZmZzZXQoKX0pIGlzIHRoZSBtYXRjaCBwb3NpdGlvbiBpZiBvbmUgd2FzIAogICAgICogZm91bmQuCiAgICAgKiBJZiBhIG1hdGNoIGlzIG5vdCBmb3VuZCwgPHR0PlVTRUFSQ0hfRE9ORTwvdHQ+IHdpbGwgYmUgcmV0dXJuZWQgYW5kCiAgICAgKiB0aGUgPHR0PlN0cmluZ1NlYXJjaDwvdHQ+IHdpbGwgYmUgYWRqdXN0ZWQgdG8gdGhlIGluZGV4IFVTRUFSQ0hfRE9ORS4KICAgICAqIEBwYXJhbSBwb3NpdGlvbiBUaGUgaW5kZXggaW4gdGhlIHRhcmdldCB0ZXh0IGF0IHdoaWNoIHRoZSBzZWFyY2ggCiAgICAgKiAgICAgICAgICAgICAgICAgc3RhcnRzLgogICAgICogQHBhcmFtIHN0YXR1cyBmb3IgZXJyb3JzIGlmIGFueSBvY2N1cnMKICAgICAqIEByZXR1cm4gVGhlIGluZGV4IGF0IHdoaWNoIHRoZSBtYXRjaGVkIHRleHQgaW4gdGhlIHRhcmdldCBzdGFydHMsIG9yIAogICAgICogICAgICAgICBVU0VBUkNIX0RPTkUgaWYgbm8gbWF0Y2ggd2FzIGZvdW5kLgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBoYW5kbGVQcmV2KGludDMyX3QgcG9zaXRpb24sIFVFcnJvckNvZGUgJnN0YXR1cyk7CiAgICAKcHJpdmF0ZSA6CiAgICBTdHJpbmdTZWFyY2goKTsgLy8gZGVmYXVsdCBjb25zdHJ1Y3RvciBub3QgaW1wbGVtZW50ZWQKCiAgICAvLyBwcml2YXRlIGRhdGEgbWVtYmVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAqIFJ1bGVCYXNlZENvbGxhdG9yLCBjb250YWlucyBleGFjdGx5IHRoZSBzYW1lIFVDb2xsYXRvciAqIGluIG1fc3Ryc3JjaF8KICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAqLwogICAgUnVsZUJhc2VkQ29sbGF0b3IgIG1fY29sbGF0b3JfOwogICAgLyoqCiAgICAqIFBhdHRlcm4gdGV4dAogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBVbmljb2RlU3RyaW5nICAgICAgbV9wYXR0ZXJuXzsKICAgIC8qKgogICAgKiBDb3JyZXNwb25kaW5nIGNvbGxhdGlvbiBydWxlcwogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBVbmljb2RlU3RyaW5nICAgICAgbV9jb2xsYXRpb25fcnVsZXNfOwogICAgLyoqCiAgICAqIFN0cmluZyBzZWFyY2ggc3RydWN0IGRhdGEKICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAqLwogICAgVVN0cmluZ1NlYXJjaCAgICAgKm1fc3Ryc3JjaF87Cgp9OwoKVV9OQU1FU1BBQ0VfRU5ECgojZW5kaWYgLyogI2lmICFVQ09ORklHX05PX0NPTExBVElPTiAqLwoKI2VuZGlmCgo=