LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgQ29weXJpZ2h0IChDKSAyMDAxIElCTSBhbmQgb3RoZXJzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqICAwMy8yMi8yMDAwICAgaGVsZW5hICAgICAgQ3JlYXRpb24uCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCiNpZm5kZWYgU1RTRUFSQ0hfSAojZGVmaW5lIFNUU0VBUkNIX0gKCiNpbmNsdWRlICJ1bmljb2RlL3RibGNvbGwuaCIKI2luY2x1ZGUgInVuaWNvZGUvY29sZWl0ci5oIgojaW5jbHVkZSAidW5pY29kZS9zZWFyY2guaCIKClVfTkFNRVNQQUNFX0JFR0lOCgovKioKICogPHR0PlN0cmluZ1NlYXJjaDwvdHQ+IGlzIGEgPHR0PlNlYXJjaEl0ZXJhdG9yPC90dD4gdGhhdCBwcm92aWRlcwogKiBsYW5ndWFnZS1zZW5zaXRpdmUgdGV4dCBzZWFyY2hpbmcgYmFzZWQgb24gdGhlIGNvbXBhcmlzb24gcnVsZXMgZGVmaW5lZAogKiBpbiBhIHtAbGluayBSdWxlQmFzZWRDb2xsYXRvcn0gb2JqZWN0LgogKiBTdHJpbmdTZWFyY2ggZW5zdXJlcyB0aGF0IGxhbmd1YWdlIGVjY2VudHJpY2l0eSBjYW4gYmUgCiAqIGhhbmRsZWQsIGUuZy4gZm9yIHRoZSBHZXJtYW4gY29sbGF0b3IsIGNoYXJhY3RlcnMg3yBhbmQgU1Mgd2lsbCBiZSBtYXRjaGVkIAogKiBpZiBjYXNlIGlzIGNob3NlbiB0byBiZSBpZ25vcmVkLiAKICogU2VlIHRoZSA8YSBocmVmPWh0dHA6Ly9vc3Muc29mdHdhcmUuaWJtLmNvbS9pY3UvZGV2ZWxvcC9jb2xsYXRpb24vSUNVX2NvbGxhdGlvbl9kZXNpZ24uaHRtPgogKiAiSUNVIENvbGxhdGlvbiBEZXNpZ24gRG9jdW1lbnQiPC9hPiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KICogPHA+IAogKiBUaGUgYWxnb3JpdGhtIGltcGxlbWVudGVkIGlzIGEgbW9kaWZpZWQgZm9ybSBvZiB0aGUgQm95ZXIgTW9vcmUncyBzZWFyY2guCiAqIEZvciBtb3JlIGluZm9ybWF0aW9uICBzZWUgCiAqIDxhIGhyZWY9aHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS9kb2NzL3BhcGVycy90ZXh0LXNlYXJjaC5odG1sPgogKiAiRWZmaWNpZW50IFRleHQgU2VhcmNoaW5nIGluIEphdmEiPC9hPiwgcHVibGlzaGVkIGluIDxpPkphdmEgUmVwb3J0PC9pPiAKICogaW4gRmVicnVhcnksIDE5OTksIGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uIG9uIHRoZSBhbGdvcml0aG0uCiAqIDxwPgogKiBUaGVyZSBhcmUgMiBtYXRjaCBvcHRpb25zIGZvciBzZWxlY3Rpb246PGJyPgogKiBMZXQgUycgYmUgdGhlIHN1Yi1zdHJpbmcgb2YgYSB0ZXh0IHN0cmluZyBTIGJldHdlZW4gdGhlIG9mZnNldHMgc3RhcnQgYW5kIAogKiBlbmQgPHN0YXJ0LCBlbmQ+LgogKiA8YnI+CiAqIEEgcGF0dGVybiBzdHJpbmcgUCBtYXRjaGVzIGEgdGV4dCBzdHJpbmcgUyBhdCB0aGUgb2Zmc2V0cyA8c3RhcnQsIGVuZD4gCiAqIGlmCiAqIDxwcmU+IAogKiBvcHRpb24gMS4gU29tZSBjYW5vbmljYWwgZXF1aXZhbGVudCBvZiBQIG1hdGNoZXMgc29tZSBjYW5vbmljYWwgZXF1aXZhbGVudCAKICogICAgICAgICAgIG9mIFMnCiAqIG9wdGlvbiAyLiBQIG1hdGNoZXMgUycgYW5kIGlmIFAgc3RhcnRzIG9yIGVuZHMgd2l0aCBhIGNvbWJpbmluZyBtYXJrLCAKICogICAgICAgICAgIHRoZXJlIGV4aXN0cyBubyBub24taWdub3JhYmxlIGNvbWJpbmluZyBtYXJrIGJlZm9yZSBvciBhZnRlciBTPyAKICogICAgICAgICAgIGluIFMgcmVzcGVjdGl2ZWx5LiAKICogPC9wcmU+CiAqIE9wdGlvbiAyLiB3aWxsIGJlIHRoZSBkZWZhdWx0twogKiA8cD4KICogVGhpcyBzZWFyY2ggaGFzIEFQSXMgc2ltaWxhciB0byB0aGF0IG9mIG90aGVyIHRleHQgaXRlcmF0aW9uIG1lY2hhbmlzbXMgCiAqIHN1Y2ggYXMgdGhlIGJyZWFrIGl0ZXJhdG9ycyBpbiA8dHQ+QnJlYWtJdGVyYXRvcjwvdHQ+LiBVc2luZyB0aGVzZSAKICogQVBJcywgaXQgaXMgZWFzeSB0byBzY2FuIHRocm91Z2ggdGV4dCBsb29raW5nIGZvciBhbGwgb2NjdXJhbmNlcyBvZiAKICogYSBnaXZlbiBwYXR0ZXJuLiBUaGlzIHNlYXJjaCBpdGVyYXRvciBhbGxvd3MgY2hhbmdpbmcgb2YgZGlyZWN0aW9uIGJ5IAogKiBjYWxsaW5nIGEgPHR0PnJlc2V0PC90dD4gZm9sbG93ZWQgYnkgYSA8dHQ+bmV4dDwvdHQ+IG9yIDx0dD5wcmV2aW91czwvdHQ+LiAKICogVGhvdWdoIGEgZGlyZWN0aW9uIGNoYW5nZSBjYW4gb2NjdXIgd2l0aG91dCBjYWxsaW5nIDx0dD5yZXNldDwvdHQ+IGZpcnN0LCAgCiAqIHRoaXMgb3BlcmF0aW9uIGNvbWVzIHdpdGggc29tZSBzcGVlZCBwZW5hbHR5LgogKiBNYXRjaCByZXN1bHRzIGluIHRoZSBmb3J3YXJkIGRpcmVjdGlvbiB3aWxsIG1hdGNoIHRoZSByZXN1bHQgbWF0Y2hlcyBpbiAKICogdGhlIGJhY2t3YXJkcyBkaXJlY3Rpb24gaW4gdGhlIHJldmVyc2Ugb3JkZXIKICogPHA+CiAqIDx0dD5TZWFyY2hJdGVyYXRvcjwvdHQ+IHByb3ZpZGVzIEFQSXMgdG8gc3BlY2lmeSB0aGUgc3RhcnRpbmcgcG9zaXRpb24gCiAqIHdpdGhpbiB0aGUgdGV4dCBzdHJpbmcgdG8gYmUgc2VhcmNoZWQsIGUuZy4gPHR0PnNldE9mZnNldDwvdHQ+LAogKiA8dHQ+cHJlY2VkaW5nPC90dD4gYW5kIDx0dD5mb2xsb3dpbmc8L3R0Pi4gU2luY2UgdGhlIAogKiBzdGFydGluZyBwb3NpdGlvbiB3aWxsIGJlIHNldCBhcyBpdCBpcyBzcGVjaWZpZWQsIHBsZWFzZSB0YWtlIG5vdGUgdGhhdCAKICogdGhlcmUgYXJlIHNvbWUgZGFuZ2VyIHBvaW50cyB3aGljaCB0aGUgc2VhcmNoIG1heSByZW5kZXIgaW5jb3JyZWN0IAogKiByZXN1bHRzOgogKiA8dWw+CiAqIDxsaT4gVGhlIG1pZHN0IG9mIGEgc3Vic3RyaW5nIHRoYXQgcmVxdWlyZXMgbm9ybWFsaXphdGlvbi4KICogPGxpPiBJZiB0aGUgZm9sbG93aW5nIG1hdGNoIGlzIHRvIGJlIGZvdW5kLCB0aGUgcG9zaXRpb24gc2hvdWxkIG5vdCBiZSB0aGUKICogICAgICBzZWNvbmQgY2hhcmFjdGVyIHdoaWNoIHJlcXVpcmVzIHRvIGJlIHN3YXBwZWQgd2l0aCB0aGUgcHJlY2VkaW5nIAogKiAgICAgIGNoYXJhY3Rlci4gVmljZSB2ZXJzYSwgaWYgdGhlIHByZWNlZGluZyBtYXRjaCBpcyB0byBiZSBmb3VuZCwgCiAqICAgICAgcG9zaXRpb24gdG8gc2VhcmNoIGZyb20gc2hvdWxkIG5vdCBiZSB0aGUgZmlyc3QgY2hhcmFjdGVyIHdoaWNoIAogKiAgICAgIHJlcXVpcmVzIHRvIGJlIHN3YXBwZWQgd2l0aCB0aGUgbmV4dCBjaGFyYWN0ZXIuIEUuZyBjZXJ0YWluIFRoYWkgYW5kCiAqICAgICAgTGFvIGNoYXJhY3RlcnMgcmVxdWlyZSBzd2FwcGluZy4KICogPGxpPiBJZiBhIGZvbGxvd2luZyBwYXR0ZXJuIG1hdGNoIGlzIHRvIGJlIGZvdW5kLCBhbnkgcG9zaXRpb24gd2l0aGluIGEgCiAqICAgICAgY29udHJhY3Rpbmcgc2VxdWVuY2UgZXhjZXB0IHRoZSBmaXJzdCB3aWxsIGZhaWwuIFZpY2UgdmVyc2EgaWYgYSAKICogICAgICBwcmVjZWRpbmcgcGF0dGVybiBtYXRjaCBpcyB0byBiZSBmb3VuZCwgYSBpbnZhbGlkIHN0YXJ0aW5nIHBvaW50IAogKiAgICAgIHdvdWxkIGJlIGFueSBjaGFyYWN0ZXIgd2l0aGluIGEgY29udHJhY3Rpbmcgc2VxdWVuY2UgZXhjZXB0IHRoZSBsYXN0LgogKiA8XHVsPgogKiA8cD4KICogQSBicmVha2l0ZXJhdG9yIGNhbiBiZSB1c2VkIGlmIG9ubHkgbWF0Y2hlcyBhdCBsb2dpY2FsIGJyZWFrcyBhcmUgZGVzaXJlZC4KICogPHA+CiAqIE9wdGlvbnMgYXJlIHByb3ZpZGVkIHRvIGhhbmRsZSBvdmVybGFwcGluZyBtYXRjaGVzLiAKICogRS5nLiBJbiBFbmdsaXNoLCBvdmVybGFwcGluZyBtYXRjaGVzIHByb2R1Y2VzIHRoZSByZXN1bHQgMCBhbmQgMiAKICogZm9yIHRoZSBwYXR0ZXJuICJhYmFiIiBpbiB0aGUgdGV4dCAiYWJhYmFiIiwgd2hlcmUgZWxzZSBtdXR1YWxseSAKICogZXhjbHVzaXZlIG1hdGNoZXMgb25seSBwcm9kdWNlIHRoZSByZXN1bHQgb2YgMC4KICogPHA+CiAqIFRob3VnaCBjb2xsYXRvciBhdHRyaWJ1dGVzIHdpbGwgYmUgdGFrZW4gaW50byBjb25zaWRlcmF0aW9uIHdoaWxlIAogKiBwZXJmb3JtaW5nIG1hdGNoZXMsIHRoZXJlIGFyZSBubyBBUElzIGhlcmUgZm9yIHNldHRpbmcgYW5kIGdldHRpbmcgdGhlIAogKiBhdHRyaWJ1dGVzLiBUaGVzZSBhdHRyaWJ1dGVzIGNhbiBiZSBzZXQgYnkgZ2V0dGluZyB0aGUgY29sbGF0b3IKICogZnJvbSA8dHQ+Z2V0Q29sbGF0b3I8L3R0PiBhbmQgdXNpbmcgdGhlIEFQSXMgaW4gPHR0PmNvbGwuaDwvdHQ+LgogKiA8cD4gCiAqIFJlc3RyaWN0aW9uOiA8YnI+CiAqIEN1cnJlbnRseSB0aGVyZSBhcmUgbm8gY29tcG9zaXRlIGNoYXJhY3RlcnMgdGhhdCBjb25zaXN0cyBvZiBhCiAqIGNoYXJhY3RlciB3aXRoIGNvbWJpbmluZyBjbGFzcyA+IDAgYmVmb3JlIGEgY2hhcmFjdGVyIHdpdGggY29tYmluaW5nIAogKiBjbGFzcyA9PSAwLiBIb3dldmVyLCBpZiBzdWNoIGEgY2hhcmFjdGVyIGV4aXN0cyBpbiB0aGUgZnV0dXJlLCAgCiAqIFN0cmluZ1NlYXJjaCBkb2VzIG5vdCBndWFyYW50ZWUgdGhlIHJlc3VsdHMgZm9yIG9wdGlvbiAxLgogKiA8cD4KICogQ29uc3VsdCB0aGUgPHR0PlNlYXJjaEl0ZXJhdG9yPC90dD4gZG9jdW1lbnRhdGlvbiBmb3IgaW5mb3JtYXRpb24gb24KICogYW5kIGV4YW1wbGVzIG9mIGhvdyB0byB1c2UgaW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgdG8gaW1wbGVtZW50IHRleHQKICogc2VhcmNoaW5nLgogKiA8cHJlPjxjb2RlPgogKiBVbmljb2RlU3RyaW5nIHRhcmdldCgiVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBmb3giKTsKICogVW5pY29kZVN0cmluZyBwYXR0ZXJuKCJmb3giKTsKICoKICogU2VhcmNoSXRlcmF0b3IgKml0ZXIgPSBuZXcgU3RyaW5nU2VhcmNoKHBhdHRlcm4sIHRhcmdldCk7CiAqCiAqIGZvciAoaW50IHBvcyA9IGl0ZXItPmZpcnN0KCk7IHBvcyAhPSBVU0VBUkNIX0RPTkU7IAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MgPSBpdGVyLT5uZXh0KCkpIHsKICogICAgIHByaW50ZigiRm91bmQgbWF0Y2ggYXQgJWQgcG9zLCBsZW5ndGggaXMgJWRcbiIsIHBvcywgCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlci5nZXRNYXRjaExlbmd0aCgpKTsKICogfQogKiA8L2NvZGU+PC9wcmU+CiAqIEBzZWUgU2VhcmNoSXRlcmF0b3IKICogQHNlZSBSdWxlQmFzZWRDb2xsYXRvcgogKi8KCmNsYXNzIFVfSTE4Tl9BUEkgU3RyaW5nU2VhcmNoIDogcHVibGljIFNlYXJjaEl0ZXJhdG9yCnsKcHVibGljOgoKICAgIC8vIHB1YmxpYyBjb25zdHJ1Y3RvcnMgYW5kIGRlc3RydWN0b3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBDcmVhdGluZyBhIDx0dD5TdHJpbmdTZWFyY2g8L3R0PiBpbnN0YW5jZSB1c2luZyB0aGUgYXJndW1lbnQgbG9jYWxlIAogICAgICogbGFuZ3VhZ2UgcnVsZSBzZXQuIEEgY29sbGF0b3Igd2lsbCBiZSBjcmVhdGVkIGluIHRoZSBwcm9jZXNzLCB3aGljaCAKICAgICAqIHdpbGwgYmUgb3duZWQgYnkgdGhpcyBpbnN0YW5jZSBhbmQgd2lsbCBiZSBkZWxldGVkIGluIGR1cmluZyAKICAgICAqIGRlc3RydWN0aW9uCiAgICAgKiBAcGFyYW0gcGF0dGVybiBUaGUgdGV4dCBmb3Igd2hpY2ggdGhpcyBvYmplY3Qgd2lsbCBzZWFyY2guCiAgICAgKiBAcGFyYW0gdGV4dCAgICBUaGUgdGV4dCBpbiB3aGljaCB0byBzZWFyY2ggZm9yIHRoZSBwYXR0ZXJuLgogICAgICogQHBhcmFtIGxvY2FsZSAgQSBsb2NhbGUgd2hpY2ggZGVmaW5lcyB0aGUgbGFuZ3VhZ2Utc2Vuc2l0aXZlIAogICAgICogICAgICAgICAgICAgICAgY29tcGFyaXNvbiBydWxlcyB1c2VkIHRvIGRldGVybWluZSB3aGV0aGVyIHRleHQgaW4gdGhlIAogICAgICogICAgICAgICAgICAgICAgcGF0dGVybiBhbmQgdGFyZ2V0IG1hdGNoZXMuIAogICAgICogQHBhcmFtIGJyZWFraXRlciBBIDx0dD5CcmVha0l0ZXJhdG9yPC90dD4gb2JqZWN0IHVzZWQgdG8gY29uc3RyYWluIAogICAgICogICAgICAgICAgICAgICAgdGhlIG1hdGNoZXMgdGhhdCBhcmUgZm91bmQuIE1hdGNoZXMgd2hvc2Ugc3RhcnQgYW5kIGVuZCAKICAgICAqICAgICAgICAgICAgICAgIGluZGljZXMgaW4gdGhlIHRhcmdldCB0ZXh0IGFyZSBub3QgYm91bmRhcmllcyBhcyAKICAgICAqICAgICAgICAgICAgICAgIGRldGVybWluZWQgYnkgdGhlIDx0dD5CcmVha0l0ZXJhdG9yPC90dD4gYXJlIAogICAgICogICAgICAgICAgICAgICAgaWdub3JlZC4gSWYgdGhpcyBiZWhhdmlvciBpcyBub3QgZGVzaXJlZCwgCiAgICAgKiAgICAgICAgICAgICAgICA8dHQ+TlVMTDwvdHQ+IGNhbiBiZSBwYXNzZWQgaW4gaW5zdGVhZC4KICAgICAqIEBwYXJhbSBzdGF0dXMgIGZvciBlcnJvcnMgaWYgYW55LiBJZiBwYXR0ZXJuIG9yIHRleHQgaXMgTlVMTCwgb3IgaWYKICAgICAqICAgICAgICAgICAgICAgZWl0aGVyIHRoZSBsZW5ndGggb2YgcGF0dGVybiBvciB0ZXh0IGlzIDAgdGhlbiBhbiAKICAgICAqICAgICAgICAgICAgICAgVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SIGlzIHJldHVybmVkLgogICAgICovCiAgICBTdHJpbmdTZWFyY2goY29uc3QgVW5pY29kZVN0cmluZyAmcGF0dGVybiwgY29uc3QgVW5pY29kZVN0cmluZyAmdGV4dCwKICAgICAgICAgICAgICAgICBjb25zdCBMb2NhbGUgICAgICAgICZsb2NhbGUsICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgIEJyZWFrSXRlcmF0b3IgKmJyZWFraXRlciwKICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICAgICZzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ3JlYXRpbmcgYSA8dHQ+U3RyaW5nU2VhcmNoPC90dD4gaW5zdGFuY2UgdXNpbmcgdGhlIGFyZ3VtZW50IGNvbGxhdG9yIAogICAgICogbGFuZ3VhZ2UgcnVsZSBzZXQuIE5vdGUsIHVzZXIgcmV0YWlucyB0aGUgb3duZXJzaGlwIG9mIHRoaXMgY29sbGF0b3IsIAogICAgICogaXQgZG9lcyBub3QgZ2V0IGRlc3Ryb3llZCBkdXJpbmcgdGhpcyBpbnN0YW5jZSdzIGRlc3RydWN0aW9uLgogICAgICogQHBhcmFtIHBhdHRlcm4gVGhlIHRleHQgZm9yIHdoaWNoIHRoaXMgb2JqZWN0IHdpbGwgc2VhcmNoLgogICAgICogQHBhcmFtIHRleHQgICAgVGhlIHRleHQgaW4gd2hpY2ggdG8gc2VhcmNoIGZvciB0aGUgcGF0dGVybi4KICAgICAqIEBwYXJhbSBjb2xsICAgIEEgPHR0PlJ1bGVCYXNlZENvbGxhdG9yPC90dD4gb2JqZWN0IHdoaWNoIGRlZmluZXMgCiAgICAgKiAgICAgICAgICAgICAgICB0aGUgbGFuZ3VhZ2Utc2Vuc2l0aXZlIGNvbXBhcmlzb24gcnVsZXMgdXNlZCB0byAKICAgICAqICAgICAgICAgICAgICAgIGRldGVybWluZSB3aGV0aGVyIHRleHQgaW4gdGhlIHBhdHRlcm4gYW5kIHRhcmdldCAKICAgICAqICAgICAgICAgICAgICAgIG1hdGNoZXMuIFVzZXIgaXMgcmVzcG9uc2libGUgZm9yIHRoZSBjbGVhcmluZyBvZiB0aGlzCiAgICAgKiAgICAgICAgICAgICAgICBvYmplY3QuCiAgICAgKiBAcGFyYW0gYnJlYWtpdGVyIEEgPHR0PkJyZWFrSXRlcmF0b3I8L3R0PiBvYmplY3QgdXNlZCB0byBjb25zdHJhaW4gCiAgICAgKiAgICAgICAgICAgICAgICB0aGUgbWF0Y2hlcyB0aGF0IGFyZSBmb3VuZC4gTWF0Y2hlcyB3aG9zZSBzdGFydCBhbmQgZW5kIAogICAgICogICAgICAgICAgICAgICAgaW5kaWNlcyBpbiB0aGUgdGFyZ2V0IHRleHQgYXJlIG5vdCBib3VuZGFyaWVzIGFzIAogICAgICogICAgICAgICAgICAgICAgZGV0ZXJtaW5lZCBieSB0aGUgPHR0PkJyZWFrSXRlcmF0b3I8L3R0PiBhcmUgCiAgICAgKiAgICAgICAgICAgICAgICBpZ25vcmVkLiBJZiB0aGlzIGJlaGF2aW9yIGlzIG5vdCBkZXNpcmVkLCAKICAgICAqICAgICAgICAgICAgICAgIDx0dD5OVUxMPC90dD4gY2FuIGJlIHBhc3NlZCBpbiBpbnN0ZWFkLgogICAgICogQHBhcmFtIHN0YXR1cyBmb3IgZXJyb3JzIGlmIGFueS4gSWYgZWl0aGVyIHRoZSBsZW5ndGggb2YgcGF0dGVybiBvciAKICAgICAqICAgICAgICAgICAgICAgdGV4dCBpcyAwIHRoZW4gYW4gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SIGlzIHJldHVybmVkLgogICAgICovCiAgICBTdHJpbmdTZWFyY2goY29uc3QgVW5pY29kZVN0cmluZyAgICAgJnBhdHRlcm4sIAogICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcgICAgICZ0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpjb2xsLCAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICBCcmVha0l0ZXJhdG9yICAgICAqYnJlYWtpdGVyLAogICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgICAgICAgICZzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ3JlYXRpbmcgYSA8dHQ+U3RyaW5nU2VhcmNoPC90dD4gaW5zdGFuY2UgdXNpbmcgdGhlIGFyZ3VtZW50IGxvY2FsZSAKICAgICAqIGxhbmd1YWdlIHJ1bGUgc2V0LiBBIGNvbGxhdG9yIHdpbGwgYmUgY3JlYXRlZCBpbiB0aGUgcHJvY2Vzcywgd2hpY2ggCiAgICAgKiB3aWxsIGJlIG93bmVkIGJ5IHRoaXMgaW5zdGFuY2UgYW5kIHdpbGwgYmUgZGVsZXRlZCBpbiBkdXJpbmcgCiAgICAgKiBkZXN0cnVjdGlvbgogICAgICogPHA+CiAgICAgKiBOb3RlOiBObyBwYXJzaW5nIG9mIHRoZSB0ZXh0IHdpdGhpbiB0aGUgPHR0PkNoYXJhY3Rlckl0ZXJhdG9yPC90dD4gCiAgICAgKiB3aWxsIGJlIGRvbmUgZHVyaW5nIHNlYXJjaGluZyBmb3IgdGhpcyB2ZXJzaW9uLiBUaGUgYmxvY2sgb2YgdGV4dCAKICAgICAqIGluIDx0dD5DaGFyYWN0ZXJJdGVyYXRvcjwvdHQ+IHdpbGwgYmUgdXNlZCBhcyBpdCBpcy4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIFRoZSB0ZXh0IGZvciB3aGljaCB0aGlzIG9iamVjdCB3aWxsIHNlYXJjaC4KICAgICAqIEBwYXJhbSB0ZXh0ICAgIFRoZSB0ZXh0IGl0ZXJhdG9yIGluIHdoaWNoIHRvIHNlYXJjaCBmb3IgdGhlIHBhdHRlcm4uCiAgICAgKiBAcGFyYW0gbG9jYWxlICBBIGxvY2FsZSB3aGljaCBkZWZpbmVzIHRoZSBsYW5ndWFnZS1zZW5zaXRpdmUgCiAgICAgKiAgICAgICAgICAgICAgICBjb21wYXJpc29uIHJ1bGVzIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGV4dCBpbiB0aGUgCiAgICAgKiAgICAgICAgICAgICAgICBwYXR0ZXJuIGFuZCB0YXJnZXQgbWF0Y2hlcy4gVXNlciBpcyByZXNwb25zaWJsZSBmb3IgCiAgICAgKiAgICAgICAgICAgICAgICB0aGUgY2xlYXJpbmcgb2YgdGhpcyBvYmplY3QuCiAgICAgKiBAcGFyYW0gYnJlYWtpdGVyIEEgPHR0PkJyZWFrSXRlcmF0b3I8L3R0PiBvYmplY3QgdXNlZCB0byBjb25zdHJhaW4gCiAgICAgKiAgICAgICAgICAgICAgICB0aGUgbWF0Y2hlcyB0aGF0IGFyZSBmb3VuZC4gTWF0Y2hlcyB3aG9zZSBzdGFydCBhbmQgZW5kIAogICAgICogICAgICAgICAgICAgICAgaW5kaWNlcyBpbiB0aGUgdGFyZ2V0IHRleHQgYXJlIG5vdCBib3VuZGFyaWVzIGFzIAogICAgICogICAgICAgICAgICAgICAgZGV0ZXJtaW5lZCBieSB0aGUgPHR0PkJyZWFrSXRlcmF0b3I8L3R0PiBhcmUgCiAgICAgKiAgICAgICAgICAgICAgICBpZ25vcmVkLiBJZiB0aGlzIGJlaGF2aW9yIGlzIG5vdCBkZXNpcmVkLCAKICAgICAqICAgICAgICAgICAgICAgIDx0dD5OVUxMPC90dD4gY2FuIGJlIHBhc3NlZCBpbiBpbnN0ZWFkLgogICAgICogQHBhcmFtIHN0YXR1cyBmb3IgZXJyb3JzIGlmIGFueS4gSWYgZWl0aGVyIHRoZSBsZW5ndGggb2YgcGF0dGVybiBvciAKICAgICAqICAgICAgICAgICAgICAgdGV4dCBpcyAwIHRoZW4gYW4gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SIGlzIHJldHVybmVkLgogICAgICovCiAgICBTdHJpbmdTZWFyY2goY29uc3QgVW5pY29kZVN0cmluZyAmcGF0dGVybiwgQ2hhcmFjdGVySXRlcmF0b3IgJnRleHQsCiAgICAgICAgICAgICAgICAgY29uc3QgTG9jYWxlICAgICAgICAmbG9jYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICBCcmVha0l0ZXJhdG9yICpicmVha2l0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAgICAmc3RhdHVzKTsKCiAgICAvKioKICAgICAqIENyZWF0aW5nIGEgPHR0PlN0cmluZ1NlYXJjaDwvdHQ+IGluc3RhbmNlIHVzaW5nIHRoZSBhcmd1bWVudCBjb2xsYXRvciAKICAgICAqIGxhbmd1YWdlIHJ1bGUgc2V0LiBOb3RlLCB1c2VyIHJldGFpbnMgdGhlIG93bmVyc2hpcCBvZiB0aGlzIGNvbGxhdG9yLCAKICAgICAqIGl0IGRvZXMgbm90IGdldCBkZXN0cm95ZWQgZHVyaW5nIHRoaXMgaW5zdGFuY2UncyBkZXN0cnVjdGlvbi4KICAgICAqIDxwPgogICAgICogTm90ZTogTm8gcGFyc2luZyBvZiB0aGUgdGV4dCB3aXRoaW4gdGhlIDx0dD5DaGFyYWN0ZXJJdGVyYXRvcjwvdHQ+IAogICAgICogd2lsbCBiZSBkb25lIGR1cmluZyBzZWFyY2hpbmcgZm9yIHRoaXMgdmVyc2lvbi4gVGhlIGJsb2NrIG9mIHRleHQgCiAgICAgKiBpbiA8dHQ+Q2hhcmFjdGVySXRlcmF0b3I8L3R0PiB3aWxsIGJlIHVzZWQgYXMgaXQgaXMuCiAgICAgKiBAcGFyYW0gcGF0dGVybiBUaGUgdGV4dCBmb3Igd2hpY2ggdGhpcyBvYmplY3Qgd2lsbCBzZWFyY2guCiAgICAgKiBAcGFyYW0gdGV4dCAgICBUaGUgdGV4dCBpbiB3aGljaCB0byBzZWFyY2ggZm9yIHRoZSBwYXR0ZXJuLgogICAgICogQHBhcmFtIGNvbGwgICAgQSA8dHQ+UnVsZUJhc2VkQ29sbGF0b3I8L3R0PiBvYmplY3Qgd2hpY2ggZGVmaW5lcyAKICAgICAqICAgICAgICAgICAgICAgIHRoZSBsYW5ndWFnZS1zZW5zaXRpdmUgY29tcGFyaXNvbiBydWxlcyB1c2VkIHRvIAogICAgICogICAgICAgICAgICAgICAgZGV0ZXJtaW5lIHdoZXRoZXIgdGV4dCBpbiB0aGUgcGF0dGVybiBhbmQgdGFyZ2V0IAogICAgICogICAgICAgICAgICAgICAgbWF0Y2hlcy4gVXNlciBpcyByZXNwb25zaWJsZSBmb3IgdGhlIGNsZWFyaW5nIG9mIHRoaXMKICAgICAqICAgICAgICAgICAgICAgIG9iamVjdC4KICAgICAqIEBwYXJhbSBicmVha2l0ZXIgQSA8dHQ+QnJlYWtJdGVyYXRvcjwvdHQ+IG9iamVjdCB1c2VkIHRvIGNvbnN0cmFpbiAKICAgICAqICAgICAgICAgICAgICAgIHRoZSBtYXRjaGVzIHRoYXQgYXJlIGZvdW5kLiBNYXRjaGVzIHdob3NlIHN0YXJ0IGFuZCBlbmQgCiAgICAgKiAgICAgICAgICAgICAgICBpbmRpY2VzIGluIHRoZSB0YXJnZXQgdGV4dCBhcmUgbm90IGJvdW5kYXJpZXMgYXMgCiAgICAgKiAgICAgICAgICAgICAgICBkZXRlcm1pbmVkIGJ5IHRoZSA8dHQ+QnJlYWtJdGVyYXRvcjwvdHQ+IGFyZSAKICAgICAqICAgICAgICAgICAgICAgIGlnbm9yZWQuIElmIHRoaXMgYmVoYXZpb3IgaXMgbm90IGRlc2lyZWQsIAogICAgICogICAgICAgICAgICAgICAgPHR0Pk5VTEw8L3R0PiBjYW4gYmUgcGFzc2VkIGluIGluc3RlYWQuCiAgICAgKiBAcGFyYW0gc3RhdHVzIGZvciBlcnJvcnMgaWYgYW55LiBJZiBlaXRoZXIgdGhlIGxlbmd0aCBvZiBwYXR0ZXJuIG9yIAogICAgICogICAgICAgICAgICAgICB0ZXh0IGlzIDAgdGhlbiBhbiBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1IgaXMgcmV0dXJuZWQuCiAgICAgKi8KICAgIFN0cmluZ1NlYXJjaChjb25zdCBVbmljb2RlU3RyaW5nICAgICAmcGF0dGVybiwgQ2hhcmFjdGVySXRlcmF0b3IgJnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKmNvbGwsIAogICAgICAgICAgICAgICAgICAgICAgIEJyZWFrSXRlcmF0b3IgICAgICpicmVha2l0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAgICAgICAgJnN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBDb3B5IGNvbnN0cnVjdG9yIHRoYXQgY3JlYXRlcyBhIFN0cmluZ1NlYXJjaCBpbnN0YW5jZSB3aXRoIHRoZSBzYW1lIAogICAgICogYmVoYXZpb3IsIGFuZCBpdGVyYXRpbmcgb3ZlciB0aGUgc2FtZSB0ZXh0LgogICAgICogQHBhcmFtIHRoYXQgU3RyaW5nU2VhcmNoIGluc3RhbmNlIHRvIGJlIGNvcGllZC4KICAgICAqLwogICAgU3RyaW5nU2VhcmNoKGNvbnN0IFN0cmluZ1NlYXJjaCAmdGhhdCk7CgogICAgLyoqCiAgICAqIERlc3RydWN0b3IuIENsZWFucyB1cCB0aGUgc2VhcmNoIGl0ZXJhdG9yIGRhdGEgc3RydWN0LgogICAgKiBJZiBhIGNvbGxhdG9yIGlzIGNyZWF0ZWQgaW4gdGhlIGNvbnN0cnVjdG9yLCBpdCB3aWxsIGJlIGRlc3Ryb3llZCBoZXJlLgogICAgKi8KICAgIHZpcnR1YWwgflN0cmluZ1NlYXJjaCh2b2lkKTsKCiAgICAvLyBvcGVyYXRvciBvdmVybG9hZGluZyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuIFNldHMgdGhpcyBpdGVyYXRvciB0byBoYXZlIHRoZSBzYW1lIGJlaGF2aW9yLAogICAgICogYW5kIGl0ZXJhdGUgb3ZlciB0aGUgc2FtZSB0ZXh0LCBhcyB0aGUgb25lIHBhc3NlZCBpbi4KICAgICAqIEBwYXJhbSB0aGF0IGluc3RhbmNlIHRvIGJlIGNvcGllZC4KICAgICAqLwogICAgU3RyaW5nU2VhcmNoICYgb3BlcmF0b3I9KGNvbnN0IFN0cmluZ1NlYXJjaCAmdGhhdCk7CgogICAgLyoqCiAgICAgKiBFcXVhbGl0eSBvcGVyYXRvci4gCiAgICAgKiBAcGFyYW0gdGhhdCBpbnN0YW5jZSB0byBiZSBjb21wYXJlZC4KICAgICAqIEByZXR1cm4gVFJVRSBpZiBib3RoIGluc3RhbmNlcyBoYXZlIHRoZSBzYW1lIGF0dHJpYnV0ZXMsIAogICAgICogICAgICAgICBicmVha2l0ZXJhdG9ycywgY29sbGF0b3JzIGFuZCBpdGVyYXRlIG92ZXIgdGhlIHNhbWUgdGV4dCAKICAgICAqICAgICAgICAgd2hpbGUgbG9va2luZyBmb3IgdGhlIHNhbWUgcGF0dGVybi4KICAgICAqLwogICAgdmlydHVhbCBVQm9vbCBvcGVyYXRvcj09KGNvbnN0IFNlYXJjaEl0ZXJhdG9yICZ0aGF0KSBjb25zdDsKCiAgICAvLyBwdWJsaWMgZ2V0IGFuZCBzZXQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBpbmRleCB0byBwb2ludCB0byB0aGUgZ2l2ZW4gcG9zaXRpb24sIGFuZCBjbGVhcnMgYW55IHN0YXRlIAogICAgICogdGhhdCdzIGFmZmVjdGVkLgogICAgICogPHA+CiAgICAgKiBUaGlzIG1ldGhvZCB0YWtlcyB0aGUgYXJndW1lbnQgaW5kZXggYW5kIHNldHMgdGhlIHBvc2l0aW9uIGluIHRoZSB0ZXh0IAogICAgICogc3RyaW5nIGFjY29yZGluZ2x5IHdpdGhvdXQgY2hlY2tpbmcgaWYgdGhlIGluZGV4IGlzIHBvaW50aW5nIHRvIGEgCiAgICAgKiB2YWxpZCBzdGFydGluZyBwb2ludCB0byBiZWdpbiBzZWFyY2hpbmcuIAogICAgICogQHBhcmFtIHBvc2l0aW9uIHdpdGhpbiB0aGUgdGV4dCB0byBiZSBzZXQKICAgICAqIEBwYXJhbSBzdGF0dXMgZm9yIGVycm9ycyBpZiBpdCBvY2N1cnMKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHNldE9mZnNldChVVGV4dE9mZnNldCBwb3NpdGlvbiwgVUVycm9yQ29kZSAmc3RhdHVzKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgY3VycmVudCBpbmRleCBpbiB0aGUgdGV4dCBiZWluZyBzZWFyY2hlZC4KICAgICAqIElmIHRoZSBpdGVyYXRpb24gaGFzIGdvbmUgcGFzdCB0aGUgZW5kIG9mIHRoZSB0ZXh0CiAgICAgKiAob3IgcGFzdCB0aGUgYmVnaW5uaW5nIGZvciBhIGJhY2t3YXJkcyBzZWFyY2gpLCB7QGxpbmsgI1VTRUFSQ0hfRE9ORX0gCiAgICAgKiBpcyByZXR1cm5lZC4KICAgICAqIEByZXR1cm4gY3VycmVudCBpbmRleCBpbiB0aGUgdGV4dCBiZWluZyBzZWFyY2hlZC4KICAgICAqLwogICAgdmlydHVhbCBVVGV4dE9mZnNldCBnZXRPZmZzZXQodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIHRhcmdldCB0ZXh0IHRvIGJlIHNlYXJjaGVkLgogICAgICogVGV4dCBpdGVyYXRpb24gd2lsbCBoZW5jZSBiZWdpbiBhdCB0aGUgc3RhcnQgb2YgdGhlIHRleHQgc3RyaW5nLiAKICAgICAqIFRoaXMgbWV0aG9kIGlzIAogICAgICogdXNlZnVsIGlmIHlvdSB3YW50IHRvIHJlLXVzZSBhbiBpdGVyYXRvciB0byBzZWFyY2ggZm9yIHRoZSBzYW1lIAogICAgICogcGF0dGVybiB3aXRoaW4gYSBkaWZmZXJlbnQgYm9keSBvZiB0ZXh0LgogICAgICogQHBhcmFtIHRleHQgdGV4dCBzdHJpbmcgdG8gYmUgc2VhcmNoZWQKICAgICAqIEBwYXJhbSBzdGF0dXMgZm9yIGVycm9ycyBpZiBhbnkuIElmIHRoZSB0ZXh0IGxlbmd0aCBpcyAwIHRoZW4gYW4gCiAgICAgKiAgICAgICAgVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SIGlzIHJldHVybmVkLgogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0VGV4dChjb25zdCBVbmljb2RlU3RyaW5nICZ0ZXh0LCBVRXJyb3JDb2RlICZzdGF0dXMpOwogICAgCiAgICAvKioKICAgICAqIFNldCB0aGUgdGFyZ2V0IHRleHQgdG8gYmUgc2VhcmNoZWQuCiAgICAgKiBUZXh0IGl0ZXJhdGlvbiB3aWxsIGhlbmNlIGJlZ2luIGF0IHRoZSBzdGFydCBvZiB0aGUgdGV4dCBzdHJpbmcuIAogICAgICogVGhpcyBtZXRob2QgaXMgCiAgICAgKiB1c2VmdWwgaWYgeW91IHdhbnQgdG8gcmUtdXNlIGFuIGl0ZXJhdG9yIHRvIHNlYXJjaCBmb3IgdGhlIHNhbWUgCiAgICAgKiBwYXR0ZXJuIHdpdGhpbiBhIGRpZmZlcmVudCBib2R5IG9mIHRleHQuCiAgICAgKiBOb3RlOiBObyBwYXJzaW5nIG9mIHRoZSB0ZXh0IHdpdGhpbiB0aGUgPHR0PkNoYXJhY3Rlckl0ZXJhdG9yPC90dD4gCiAgICAgKiB3aWxsIGJlIGRvbmUgZHVyaW5nIHNlYXJjaGluZyBmb3IgdGhpcyB2ZXJzaW9uLiBUaGUgYmxvY2sgb2YgdGV4dCAKICAgICAqIGluIDx0dD5DaGFyYWN0ZXJJdGVyYXRvcjwvdHQ+IHdpbGwgYmUgdXNlZCBhcyBpdCBpcy4KICAgICAqIEBwYXJhbSB0ZXh0IHRleHQgc3RyaW5nIHRvIGJlIHNlYXJjaGVkCiAgICAgKiBAcGFyYW0gc3RhdHVzIGZvciBlcnJvcnMgaWYgYW55LiBJZiB0aGUgdGV4dCBsZW5ndGggaXMgMCB0aGVuIGFuIAogICAgICogICAgICAgIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiBpcyByZXR1cm5lZC4KICAgICAqLwogICAgdmlydHVhbCB2b2lkIHNldFRleHQoQ2hhcmFjdGVySXRlcmF0b3IgJnRleHQsIFVFcnJvckNvZGUgJnN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBjb2xsYXRvciB1c2VkIGZvciB0aGUgbGFuZ3VhZ2UgcnVsZXMuIAogICAgICogPHA+CiAgICAgKiBEZWxldGluZyB0aGUgcmV0dXJuZWQgPHR0PlJ1bGVCYXNlZENvbGxhdG9yPC90dD4gYmVmb3JlIGNhbGxpbmcgCiAgICAgKiB0aGUgZGVzdHJ1Y3RvciB3b3VsZCBjYXVzZSB0aGUgc3RyaW5nIHNlYXJjaCB0byBmYWlsLgogICAgICogVGhlIGRlc3RydWN0b3Igd2lsbCBkZWxldGUgdGhlIGNvbGxhdG9yIGlmIHRoaXMgaW5zdGFuY2Ugb3ducyBpdAogICAgICogQHJldHVybiBjb2xsYXRvciB1c2VkIGZvciBzdHJpbmcgc2VhcmNoCiAgICAgKi8KICAgIFJ1bGVCYXNlZENvbGxhdG9yICogZ2V0Q29sbGF0b3IoKSBjb25zdDsKICAgIAogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBjb2xsYXRvciB1c2VkIGZvciB0aGUgbGFuZ3VhZ2UgcnVsZXMuIFVzZXIgcmV0YWlucyB0aGUgCiAgICAgKiBvd25lcnNoaXAgb2YgdGhpcyBjb2xsYXRvciwgdGh1cyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgZGVsZXRpb24gbGllcyAKICAgICAqIHdpdGggdGhlIHVzZXIuIFRoaXMgbWV0aG9kIGNhdXNlcyBpbnRlcm5hbCBkYXRhIHN1Y2ggYXMgQm95ZXItTW9vcmUgCiAgICAgKiBzaGlmdCB0YWJsZXMgdG8gYmUgcmVjYWxjdWxhdGVkLCBidXQgdGhlIGl0ZXJhdG9yJ3MgcG9zaXRpb24gaXMgCiAgICAgKiB1bmNoYW5nZWQuCiAgICAgKiBAcGFyYW0gY29sbCAgICBjb2xsYXRvciAKICAgICAqIEBwYXJhbSBzdGF0dXMgIGZvciBlcnJvcnMgaWYgYW55CiAgICAgKi8KICAgIHZvaWQgc2V0Q29sbGF0b3IoUnVsZUJhc2VkQ29sbGF0b3IgKmNvbGwsIFVFcnJvckNvZGUgJnN0YXR1cyk7CiAgICAKICAgIC8qKgogICAgICogU2V0cyB0aGUgcGF0dGVybiB1c2VkIGZvciBtYXRjaGluZy4KICAgICAqIEludGVybmFsIGRhdGEgbGlrZSB0aGUgQm95ZXIgTW9vcmUgdGFibGUgd2lsbCBiZSByZWNhbGN1bGF0ZWQsIGJ1dCAKICAgICAqIHRoZSBpdGVyYXRvcidzIHBvc2l0aW9uIGlzIHVuY2hhbmdlZC4KICAgICAqIEBwYXJhbSBwYXR0ZXJuIHNlYXJjaCBwYXR0ZXJuIHRvIGJlIGZvdW5kCiAgICAgKiBAcGFyYW0gc3RhdHVzIGZvciBlcnJvcnMgaWYgYW55LiBJZiB0aGUgcGF0dGVybiBsZW5ndGggaXMgMCB0aGVuIGFuIAogICAgICogICAgICAgICAgICAgICBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1IgaXMgcmV0dXJuZWQuCiAgICAgKi8KICAgIHZvaWQgc2V0UGF0dGVybihjb25zdCBVbmljb2RlU3RyaW5nICZwYXR0ZXJuLCBVRXJyb3JDb2RlICZzdGF0dXMpOwogICAgCiAgICAvKioKICAgICAqIEdldHMgdGhlIHNlYXJjaCBwYXR0ZXJuLgogICAgICogQHJldHVybiBwYXR0ZXJuIHVzZWQgZm9yIG1hdGNoaW5nCiAgICAgKi8KICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcgJiBnZXRQYXR0ZXJuKCkgY29uc3Q7CgogICAgLy8gcHVibGljIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKiAKICAgICAqIFJlc2V0IHRoZSBpdGVyYXRpb24uCiAgICAgKiBTZWFyY2ggd2lsbCBiZWdpbiBhdCB0aGUgc3RhcnQgb2YgdGhlIHRleHQgc3RyaW5nIGlmIGEgZm9yd2FyZCAKICAgICAqIGl0ZXJhdGlvbiBpcyBpbml0aWF0ZWQgYmVmb3JlIGEgYmFja3dhcmRzIGl0ZXJhdGlvbi4gT3RoZXJ3aXNlIGlmIAogICAgICogYSBiYWNrd2FyZHMgaXRlcmF0aW9uIGlzIGluaXRpYXRlZCBiZWZvcmUgYSBmb3J3YXJkcyBpdGVyYXRpb24sIHRoZSAKICAgICAqIHNlYXJjaCB3aWxsIGJlZ2luIGF0IHRoZSBlbmQgb2YgdGhlIHRleHQgc3RyaW5nLgogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgcmVzZXQoKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBjb3B5IG9mIFN0cmluZ1NlYXJjaCB3aXRoIHRoZSBzYW1lIGJlaGF2aW9yLCBhbmQgCiAgICAgKiBpdGVyYXRpbmcgb3ZlciB0aGUgc2FtZSB0ZXh0LCBhcyB0aGlzIG9uZS4gTm90ZSB0aGF0IGFsbCBkYXRhIHdpbGwgYmUKICAgICAqIHJlcGxpY2F0ZWQsIGV4Y2VwdCBmb3IgdGhlIHVzZXItc3BlY2lmaWVkIGNvbGxhdG9yIGFuZCB0aGUKICAgICAqIGJyZWFraXRlcmF0b3IuCiAgICAgKiBAcmV0dXJuIGNsb25lZCBvYmplY3QKICAgICAqLwogICAgdmlydHVhbCBTZWFyY2hJdGVyYXRvciAqIHNhZmVDbG9uZSh2b2lkKSBjb25zdDsKICAgIApwcm90ZWN0ZWQ6CgogICAgLy8gcHJvdGVjdGVkIG1ldGhvZCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBTZWFyY2ggZm9yd2FyZCBmb3IgbWF0Y2hpbmcgdGV4dCwgc3RhcnRpbmcgYXQgYSBnaXZlbiBsb2NhdGlvbi4KICAgICAqIENsaWVudHMgc2hvdWxkIG5vdCBjYWxsIHRoaXMgbWV0aG9kIGRpcmVjdGx5OyBpbnN0ZWFkIHRoZXkgc2hvdWxkIAogICAgICogY2FsbCB7QGxpbmsgU2VhcmNoSXRlcmF0b3IjbmV4dH0uCiAgICAgKiA8cD4KICAgICAqIElmIGEgbWF0Y2ggaXMgZm91bmQsIHRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBtYXRjaAogICAgICogc3RhcnRzIGFuZCBjYWxscyB7QGxpbmsgU2VhcmNoSXRlcmF0b3Ijc2V0TWF0Y2hMZW5ndGh9IHdpdGggdGhlIG51bWJlciAKICAgICAqIG9mIGNoYXJhY3RlcnMgaW4gdGhlIHRhcmdldCB0ZXh0IHRoYXQgbWFrZSB1cCB0aGUgbWF0Y2guIElmIG5vIG1hdGNoIAogICAgICogaXMgZm91bmQsIHRoZSBtZXRob2QgcmV0dXJucyA8dHQ+VVNFQVJDSF9ET05FPC90dD4uCiAgICAgKiA8cD4KICAgICAqIFRoZSA8dHQ+U3RyaW5nU2VhcmNoPC90dD4gaXMgYWRqdXN0ZWQgc28gdGhhdCBpdHMgY3VycmVudCBpbmRleCAKICAgICAqIChhcyByZXR1cm5lZCBieSB7QGxpbmsgI2dldE9mZnNldH0pIGlzIHRoZSBtYXRjaCBwb3NpdGlvbiBpZiBvbmUgd2FzIAogICAgICogZm91bmQuCiAgICAgKiBJZiBhIG1hdGNoIGlzIG5vdCBmb3VuZCwgPHR0PlVTRUFSQ0hfRE9ORTwvdHQ+IHdpbGwgYmUgcmV0dXJuZWQgYW5kCiAgICAgKiB0aGUgPHR0PlN0cmluZ1NlYXJjaDwvdHQ+IHdpbGwgYmUgYWRqdXN0ZWQgdG8gdGhlIGluZGV4IFVTRUFSQ0hfRE9ORS4KICAgICAqIEBwYXJhbSBwb3NpdGlvbiBUaGUgaW5kZXggaW4gdGhlIHRhcmdldCB0ZXh0IGF0IHdoaWNoIHRoZSBzZWFyY2ggCiAgICAgKiAgICAgICAgICAgICAgICAgc3RhcnRzCiAgICAgKiBAcGFyYW0gc3RhdHVzIGZvciBlcnJvcnMgaWYgYW55IG9jY3VycwogICAgICogQHJldHVybiBUaGUgaW5kZXggYXQgd2hpY2ggdGhlIG1hdGNoZWQgdGV4dCBpbiB0aGUgdGFyZ2V0IHN0YXJ0cywgb3IgCiAgICAgKiAgICAgICAgIFVTRUFSQ0hfRE9ORSBpZiBubyBtYXRjaCB3YXMgZm91bmQuCiAgICAgKi8KICAgIHZpcnR1YWwgVVRleHRPZmZzZXQgaGFuZGxlTmV4dChVVGV4dE9mZnNldCBwb3NpdGlvbiwgVUVycm9yQ29kZSAmc3RhdHVzKTsKCiAgICAvKioKICAgICAqIFNlYXJjaCBiYWNrd2FyZCBmb3IgbWF0Y2hpbmcgdGV4dCwgc3RhcnRpbmcgYXQgYSBnaXZlbiBsb2NhdGlvbi4KICAgICAqIENsaWVudHMgc2hvdWxkIG5vdCBjYWxsIHRoaXMgbWV0aG9kIGRpcmVjdGx5OyBpbnN0ZWFkIHRoZXkgc2hvdWxkIGNhbGwKICAgICAqIDx0dD5TZWFyY2hJdGVyYXRvci5wcmV2aW91cygpPC90dD4sIHdoaWNoIHRoaXMgbWV0aG9kIG92ZXJyaWRlcy4KICAgICAqIDxwPgogICAgICogSWYgYSBtYXRjaCBpcyBmb3VuZCwgdGhpcyBtZXRob2QgcmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIG1hdGNoCiAgICAgKiBzdGFydHMgYW5kIGNhbGxzIHtAbGluayBTZWFyY2hJdGVyYXRvciNzZXRNYXRjaExlbmd0aH0gd2l0aCB0aGUgbnVtYmVyIAogICAgICogb2YgY2hhcmFjdGVycyBpbiB0aGUgdGFyZ2V0IHRleHQgdGhhdCBtYWtlIHVwIHRoZSBtYXRjaC4gSWYgbm8gbWF0Y2ggCiAgICAgKiBpcyBmb3VuZCwgdGhlIG1ldGhvZCByZXR1cm5zIDx0dD5VU0VBUkNIX0RPTkU8L3R0Pi4KICAgICAqIDxwPgogICAgICogVGhlIDx0dD5TdHJpbmdTZWFyY2g8L3R0PiBpcyBhZGp1c3RlZCBzbyB0aGF0IGl0cyBjdXJyZW50IGluZGV4IAogICAgICogKGFzIHJldHVybmVkIGJ5IHtAbGluayAjZ2V0T2Zmc2V0fSkgaXMgdGhlIG1hdGNoIHBvc2l0aW9uIGlmIG9uZSB3YXMgCiAgICAgKiBmb3VuZC4KICAgICAqIElmIGEgbWF0Y2ggaXMgbm90IGZvdW5kLCA8dHQ+VVNFQVJDSF9ET05FPC90dD4gd2lsbCBiZSByZXR1cm5lZCBhbmQKICAgICAqIHRoZSA8dHQ+U3RyaW5nU2VhcmNoPC90dD4gd2lsbCBiZSBhZGp1c3RlZCB0byB0aGUgaW5kZXggVVNFQVJDSF9ET05FLgogICAgICogQHBhcmFtIHBvc2l0aW9uIFRoZSBpbmRleCBpbiB0aGUgdGFyZ2V0IHRleHQgYXQgd2hpY2ggdGhlIHNlYXJjaCAKICAgICAqICAgICAgICAgICAgICAgICBzdGFydHMuCiAgICAgKiBAcGFyYW0gc3RhdHVzIGZvciBlcnJvcnMgaWYgYW55IG9jY3VycwogICAgICogQHJldHVybiBUaGUgaW5kZXggYXQgd2hpY2ggdGhlIG1hdGNoZWQgdGV4dCBpbiB0aGUgdGFyZ2V0IHN0YXJ0cywgb3IgCiAgICAgKiAgICAgICAgIFVTRUFSQ0hfRE9ORSBpZiBubyBtYXRjaCB3YXMgZm91bmQuCiAgICAgKi8KICAgIHZpcnR1YWwgVVRleHRPZmZzZXQgaGFuZGxlUHJldihVVGV4dE9mZnNldCBwb3NpdGlvbiwgVUVycm9yQ29kZSAmc3RhdHVzKTsKICAgIApwcml2YXRlIDoKCiAgICAvLyBwcml2YXRlIGRhdGEgbWVtYmVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAqIFJ1bGVCYXNlZENvbGxhdG9yLCBjb250YWlucyBleGFjdGx5IHRoZSBzYW1lIFVDb2xsYXRvciAqIGluIG1fc3Ryc3JjaF8KICAgICovCiAgICBSdWxlQmFzZWRDb2xsYXRvciAgbV9jb2xsYXRvcl87CiAgICAvKioKICAgICogUGF0dGVybiB0ZXh0CiAgICAqLwogICAgVW5pY29kZVN0cmluZyAgICAgIG1fcGF0dGVybl87CiAgICAvKioKICAgICogQ29ycmVzcG9uZGluZyBjb2xsYXRpb24gcnVsZXMKICAgICovCiAgICBVbmljb2RlU3RyaW5nICAgICAgbV9jb2xsYXRpb25fcnVsZXNfOwogICAgLyoqCiAgICAqIFN0cmluZyBzZWFyY2ggc3RydWN0IGRhdGEKICAgICovCiAgICBVU3RyaW5nU2VhcmNoICAgICAqbV9zdHJzcmNoXzsKfTsKClVfTkFNRVNQQUNFX0VORAoKI2VuZGlmCgo=