LyoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENPUFlSSUdIVDogCiAqIENvcHlyaWdodCAoYykgMTk5Ni0yMDAxLCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZAogKiBvdGhlcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKi8KCi8qCiogTW9kaWZpY2F0aW9uIGhpc3RvcnkKKiAKKiBEYXRlICAgICAgTmFtZSAgICAgIERlc2NyaXB0aW9uCiogMDIvMDIvMDEgIHN5bndlZSAgICBBZGRlZCBjb252ZXJ0ZXJzIGZyb20gRU1vZGUgdG8gVU5vcm1hbGl6YXRpb25Nb2RlLCAKKiAgICAgICAgICAgICAgICAgICAgIGdldFVOb3JtYWxpemF0aW9uTW9kZSBhbmQgZ2V0Tm9ybWFsaXplckVNb2RlLAoqICAgICAgICAgICAgICAgICAgICAgdXNlZnVsIGluIHRiY29sbCBhbmQgdW5vcm0uCiogICAgICAgICAgICAgICAgICAgICBBZGRlZCBxdWlja2NoZWNrIG1ldGhvZCBhbmQgaW5jb3Jwb3JhdGVkIGl0IGludG8gCiogICAgICAgICAgICAgICAgICAgICBub3JtYWxpemUoKQoqICAgICAgICAgICAgICAgICAgICAgUmVtb3ZlZCBoYXJkIGNvZGVkIG9uIEVNb2RlIHRvIFVOb3JtYWxpemF0aW9uTW9kZSAKKiAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnNpb24KKi8KCiNpZm5kZWYgTk9STUxaUl9ICiNkZWZpbmUgTk9STUxaUl9ICgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW5pc3RyLmgiCiNpbmNsdWRlICJ1bmljb2RlL2NoYXJpdGVyLmgiCiNpbmNsdWRlICJ1bmljb2RlL3Vub3JtLmgiCgovKiBmb3J3YXJkIGRlY2xhcmF0aW9uICovCmNsYXNzIENvbXBvc2VkQ2hhckl0ZXI7CgovKioKICogPHR0Pk5vcm1hbGl6ZXI8L3R0PiB0cmFuc2Zvcm1zIFVuaWNvZGUgdGV4dCBpbnRvIGFuIGVxdWl2YWxlbnQgY29tcG9zZWQgb3IKICogZGVjb21wb3NlZCBmb3JtLCBhbGxvd2luZyBmb3IgZWFzaWVyIHNvcnRpbmcgYW5kIHNlYXJjaGluZyBvZiB0ZXh0LgogKiA8dHQ+Tm9ybWFsaXplcjwvdHQ+IHN1cHBvcnRzIHRoZSBzdGFuZGFyZCBub3JtYWxpemF0aW9uIGZvcm1zIGRlc2NyaWJlZCBpbgogKiA8YSBocmVmPSJodHRwOi8vd3d3LnVuaWNvZGUub3JnL3VuaWNvZGUvcmVwb3J0cy90cjE1LyIgdGFyZ2V0PSJ1bmljb2RlIj4KICogVW5pY29kZSBUZWNobmljYWwgUmVwb3J0ICMxNTwvYT4uCiAqIDxwPgogKiBDaGFyYWN0ZXJzIHdpdGggYWNjZW50cyBvciBvdGhlciBhZG9ybm1lbnRzIGNhbiBiZSBlbmNvZGVkIGluCiAqIHNldmVyYWwgZGlmZmVyZW50IHdheXMgaW4gVW5pY29kZS4gIEZvciBleGFtcGxlLCB0YWtlIHRoZSBjaGFyYWN0ZXIgIsEiCiAqIChBLWFjdXRlKS4gICBJbiBVbmljb2RlLCB0aGlzIGNhbiBiZSBlbmNvZGVkIGFzIGEgc2luZ2xlIGNoYXJhY3RlciAodGhlCiAqICJjb21wb3NlZCIgZm9ybSk6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgMDBDMSAgICBMQVRJTiBDQVBJVEFMIExFVFRFUiBBIFdJVEggQUNVVEU8L3ByZT4KICogXGVuZGNvZGUKICogb3IgYXMgdHdvIHNlcGFyYXRlIGNoYXJhY3RlcnMgKHRoZSAiZGVjb21wb3NlZCIgZm9ybSk6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgMDA0MSAgICBMQVRJTiBDQVBJVEFMIExFVFRFUiBBCiAqICAgICAgMDMwMSAgICBDT01CSU5JTkcgQUNVVEUgQUNDRU5UPC9wcmU+CiAqIFxlbmRjb2RlCiAqIDxwPgogKiBUbyBhIHVzZXIgb2YgeW91ciBwcm9ncmFtLCBob3dldmVyLCBib3RoIG9mIHRoZXNlIHNlcXVlbmNlcyBzaG91bGQgYmUKICogdHJlYXRlZCBhcyB0aGUgc2FtZSAidXNlci1sZXZlbCIgY2hhcmFjdGVyICLBIi4gIFdoZW4geW91IGFyZSBzZWFyY2hpbmcgb3IKICogY29tcGFyaW5nIHRleHQsIHlvdSBtdXN0IGVuc3VyZSB0aGF0IHRoZXNlIHR3byBzZXF1ZW5jZXMgYXJlIHRyZWF0ZWQgCiAqIGVxdWl2YWxlbnRseS4gIEluIGFkZGl0aW9uLCB5b3UgbXVzdCBoYW5kbGUgY2hhcmFjdGVycyB3aXRoIG1vcmUgdGhhbiBvbmUKICogYWNjZW50LiAgU29tZXRpbWVzIHRoZSBvcmRlciBvZiBhIGNoYXJhY3RlcidzIGNvbWJpbmluZyBhY2NlbnRzIGlzCiAqIHNpZ25pZmljYW50LCB3aGlsZSBpbiBvdGhlciBjYXNlcyBhY2NlbnQgc2VxdWVuY2VzIGluIGRpZmZlcmVudCBvcmRlcnMgYXJlCiAqIHJlYWxseSBlcXVpdmFsZW50LgogKiA8cD4KICogU2ltaWxhcmx5LCB0aGUgc3RyaW5nICJmZmkiIGNhbiBiZSBlbmNvZGVkIGFzIHRocmVlIHNlcGFyYXRlIGxldHRlcnM6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgMDA2NiAgICBMQVRJTiBTTUFMTCBMRVRURVIgRgogKiAgICAgIDAwNjYgICAgTEFUSU4gU01BTEwgTEVUVEVSIEYKICogICAgICAwMDY5ICAgIExBVElOIFNNQUxMIExFVFRFUiBJPC9wcmU+CiAqIFxlbmRjb2RlCiAqIG9yIGFzIHRoZSBzaW5nbGUgY2hhcmFjdGVyCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgRkIwMyAgICBMQVRJTiBTTUFMTCBMSUdBVFVSRSBGRkk8L3ByZT4KICogXGVuZGNvZGUKICogPHA+CiAqIFRoZSBmZmkgbGlnYXR1cmUgaXMgbm90IGEgZGlzdGluY3Qgc2VtYW50aWMgY2hhcmFjdGVyLCBhbmQgc3RyaWN0bHkgc3BlYWtpbmcKICogaXQgc2hvdWxkbid0IGJlIGluIFVuaWNvZGUgYXQgYWxsLCBidXQgaXQgd2FzIGluY2x1ZGVkIGZvciBjb21wYXRpYmlsaXR5CiAqIHdpdGggZXhpc3RpbmcgY2hhcmFjdGVyIHNldHMgdGhhdCBhbHJlYWR5IHByb3ZpZGVkIGl0LiAgVGhlIFVuaWNvZGUgc3RhbmRhcmQKICogaWRlbnRpZmllcyBzdWNoIGNoYXJhY3RlcnMgYnkgZ2l2aW5nIHRoZW0gImNvbXBhdGliaWxpdHkiIGRlY29tcG9zaXRpb25zCiAqIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgc2VtYW50aWMgY2hhcmFjdGVycy4gIFdoZW4gc29ydGluZyBhbmQgc2VhcmNoaW5nLCB5b3UKICogd2lsbCBvZnRlbiB3YW50IHRvIHVzZSB0aGVzZSBtYXBwaW5ncy4KICogPHA+CiAqIDx0dD5Ob3JtYWxpemVyPC90dD4gaGVscHMgc29sdmUgdGhlc2UgcHJvYmxlbXMgYnkgdHJhbnNmb3JtaW5nIHRleHQgaW50byB0aGUKICogY2Fub25pY2FsIGNvbXBvc2VkIGFuZCBkZWNvbXBvc2VkIGZvcm1zIGFzIHNob3duIGluIHRoZSBmaXJzdCBleGFtcGxlIGFib3ZlLiAgCiAqIEluIGFkZGl0aW9uLCB5b3UgY2FuIGhhdmUgaXQgcGVyZm9ybSBjb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpb25zIHNvIHRoYXQgCiAqIHlvdSBjYW4gdHJlYXQgY29tcGF0aWJpbGl0eSBjaGFyYWN0ZXJzIHRoZSBzYW1lIGFzIHRoZWlyIGVxdWl2YWxlbnRzLgogKiBGaW5hbGx5LCA8dHQ+Tm9ybWFsaXplcjwvdHQ+IHJlYXJyYW5nZXMgYWNjZW50cyBpbnRvIHRoZSBwcm9wZXIgY2Fub25pY2FsCiAqIG9yZGVyLCBzbyB0aGF0IHlvdSBkbyBub3QgaGF2ZSB0byB3b3JyeSBhYm91dCBhY2NlbnQgcmVhcnJhbmdlbWVudCBvbiB5b3VyCiAqIG93bi4KICogPHA+CiAqIDx0dD5Ob3JtYWxpemVyPC90dD4gYWRkcyBvbmUgb3B0aW9uYWwgYmVoYXZpb3IsIHtAbGluayAjSUdOT1JFX0hBTkdVTH0sCiAqIHRoYXQgZGlmZmVycyBmcm9tCiAqIHRoZSBzdGFuZGFyZCBVbmljb2RlIE5vcm1hbGl6YXRpb24gRm9ybXMuICBUaGlzIG9wdGlvbiBjYW4gYmUgcGFzc2VkCiAqIHRvIHRoZSB7QGxpbmsgI05vcm1hbGl6ZXIgY29uc3RydWN0b3JzfSBhbmQgdG8gdGhlIHN0YXRpYwogKiB7QGxpbmsgI2NvbXBvc2UgY29tcG9zZX0gYW5kIHtAbGluayAjZGVjb21wb3NlIGRlY29tcG9zZX0gbWV0aG9kcy4gIFRoaXMKICogb3B0aW9uLCBhbmQgYW55IHRoYXQgYXJlIGFkZGVkIGluIHRoZSBmdXR1cmUsIHdpbGwgYmUgdHVybmVkIG9mZiBieSBkZWZhdWx0LgogKiA8cD4KICogVGhlcmUgYXJlIHRocmVlIGNvbW1vbiB1c2FnZSBtb2RlbHMgZm9yIDx0dD5Ob3JtYWxpemVyPC90dD4uICBJbiB0aGUgZmlyc3QsCiAqIHRoZSBzdGF0aWMge0BsaW5rICNub3JtYWxpemUgbm9ybWFsaXplKCl9IG1ldGhvZCBpcyB1c2VkIHRvIHByb2Nlc3MgYW4KICogZW50aXJlIGlucHV0IHN0cmluZyBhdCBvbmNlLiAgU2Vjb25kLCB5b3UgY2FuIGNyZWF0ZSBhIDx0dD5Ob3JtYWxpemVyPC90dD4KICogb2JqZWN0IGFuZCB1c2UgaXQgdG8gaXRlcmF0ZSB0aHJvdWdoIHRoZSBub3JtYWxpemVkIGZvcm0gb2YgYSBzdHJpbmcgYnkKICogY2FsbGluZyB7QGxpbmsgI2ZpcnN0fSBhbmQge0BsaW5rICNuZXh0fS4gIEZpbmFsbHksIHlvdSBjYW4gdXNlIHRoZQogKiB7QGxpbmsgI3NldEluZGV4IHNldEluZGV4KCl9IGFuZCB7QGxpbmsgI2dldEluZGV4fSBtZXRob2RzIHRvIHBlcmZvcm0KICogcmFuZG9tLWFjY2VzcyBpdGVyYXRpb24sIHdoaWNoIGlzIHZlcnkgdXNlZnVsIGZvciBzZWFyY2hpbmcuCiAqIDxwPgogKiA8Yj5Ob3RlOjwvYj4gPHR0Pk5vcm1hbGl6ZXI8L3R0PiBvYmplY3RzIGJlaGF2ZSBsaWtlIGl0ZXJhdG9ycyBhbmQgaGF2ZQogKiBtZXRob2RzIHN1Y2ggYXMgPHR0PnNldEluZGV4PC90dD4sIDx0dD5uZXh0PC90dD4sIDx0dD5wcmV2aW91czwvdHQ+LCBldGMuCiAqIFlvdSBzaG91bGQgbm90ZSB0aGF0IHdoaWxlIHRoZSA8dHQ+c2V0SW5kZXg8L3R0PiBhbmQgPHR0PmdldEluZGV4PC90dD4gcmVmZXIKICogdG8gaW5kaWNlcyBpbiB0aGUgdW5kZXJseWluZyA8ZW0+aW5wdXQ8L2VtPiB0ZXh0IGJlaW5nIHByb2Nlc3NlZCwgdGhlCiAqIDx0dD5uZXh0PC90dD4gYW5kIDx0dD5wcmV2aW91czwvdHQ+IG1ldGhvZHMgaXQgaXRlcmF0ZSB0aHJvdWdoIGNoYXJhY3RlcnMKICogaW4gdGhlIG5vcm1hbGl6ZWQgPGVtPm91dHB1dDwvZW0+LiAgVGhpcyBtZWFucyB0aGF0IHRoZXJlIGlzIG5vdAogKiBuZWNlc3NhcmlseSBhIG9uZS10by1vbmUgY29ycmVzcG9uZGVuY2UgYmV0d2VlbiBjaGFyYWN0ZXJzIHJldHVybmVkCiAqIGJ5IDx0dD5uZXh0PC90dD4gYW5kIDx0dD5wcmV2aW91czwvdHQ+IGFuZCB0aGUgaW5kaWNlcyBwYXNzZWQgdG8gYW5kCiAqIHJldHVybmVkIGZyb20gPHR0PnNldEluZGV4PC90dD4gYW5kIDx0dD5nZXRJbmRleDwvdHQ+LiAgSXQgaXMgZm9yIHRoaXMKICogcmVhc29uIHRoYXQgPHR0Pk5vcm1hbGl6ZXI8L3R0PiBkb2VzIG5vdCBpbXBsZW1lbnQgdGhlCiAqIHtAbGluayBDaGFyYWN0ZXJJdGVyYXRvcn0gaW50ZXJmYWNlLgogKiA8cD4KICogPGI+Tm90ZTo8L2I+IDx0dD5Ob3JtYWxpemVyPC90dD4gaXMgY3VycmVudGx5IGJhc2VkIG9uIHZlcnNpb24gMi4xLjgKICogb2YgdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudW5pY29kZS5vcmciIHRhcmdldD0idW5pY29kZSI+VW5pY29kZSBTdGFuZGFyZDwvYT4uCiAqIEl0IHdpbGwgYmUgdXBkYXRlZCBhcyBsYXRlciB2ZXJzaW9ucyBvZiBVbmljb2RlIGFyZSByZWxlYXNlZC4gIElmIHlvdSBhcmUKICogdXNpbmcgdGhpcyBjbGFzcyBvbiBhIEpESyB0aGF0IHN1cHBvcnRzIGFuIGVhcmxpZXIgdmVyc2lvbiBvZiBVbmljb2RlLCBpdAogKiBpcyBwb3NzaWJsZSB0aGF0IDx0dD5Ob3JtYWxpemVyPC90dD4gbWF5IGdlbmVyYXRlIGNvbXBvc2VkIG9yIGRlZGVjb21wb3NlZAogKiBjaGFyYWN0ZXJzIGZvciB3aGljaCB5b3VyIEpESydzIHtAbGluayBqYXZhLmxhbmcuQ2hhcmFjdGVyfSBjbGFzcyBkb2VzIG5vdAogKiBoYXZlIGFueSBkYXRhLgogKiA8cD4KICogQGF1dGhvciBMYXVyYSBXZXJuZXIsIE1hcmsgRGF2aXMKICovCmNsYXNzIFVfQ09NTU9OX0FQSSBOb3JtYWxpemVyCnsKCiBwdWJsaWM6CiAgLy8gVGhpcyB0ZWxscyB1cyB3aGF0IHRoZSBiaXRzIGluIHRoZSAibW9kZSIgbWVhbi4KICBlbnVtIHsKICAgIENPTVBBVF9CSVQgICAgICAgICA9IDEsCiAgICBERUNPTVBfQklUICAgICAgICAgPSAyLAogICAgQ09NUE9TRV9CSVQgICAgID0gNAogIH07CgoKCiAgLyoqIElmIERPTkUgaXMgcmV0dXJuZWQsIHRoZW4gdGhlcmUgYXJlIG5vIG1vcmUgbm9ybWFsaXphdGlvbiByZXN1bHRzIGF2YWlsYWJsZS4gKi8KICBlbnVtIHsKICAgICAgRE9ORT0weGZmZmYKICB9OwoKICAvKiogVGhlIG1vZGUgb2YgYSBOb3JtYWxpemVyIG9iamVjdCAqLwogIGVudW0gRU1vZGUgewoKICAgIC8qKgogICAgICogTnVsbCBvcGVyYXRpb24gZm9yIHVzZSB3aXRoIHRoZSB7QGxpbmsgI05vcm1hbGl6ZXIgY29uc3RydWN0b3JzfQogICAgICogYW5kIHRoZSBzdGF0aWMge0BsaW5rICNub3JtYWxpemUgbm9ybWFsaXplfSBtZXRob2QuICBUaGlzIHZhbHVlIHRlbGxzCiAgICAgKiB0aGUgPHR0Pk5vcm1hbGl6ZXI8L3R0PiB0byBkbyBub3RoaW5nIGJ1dCByZXR1cm4gdW5wcm9jZXNzZWQgY2hhcmFjdGVycwogICAgICogZnJvbSB0aGUgdW5kZXJseWluZyBTdHJpbmcgb3IgQ2hhcmFjdGVySXRlcmF0b3IuICBJZiB5b3UgaGF2ZSBjb2RlIHdoaWNoCiAgICAgKiByZXF1aXJlcyByYXcgdGV4dCBhdCBzb21lIHRpbWVzIGFuZCBub3JtYWxpemVkIHRleHQgYXQgb3RoZXJzLCB5b3UgY2FuCiAgICAgKiB1c2UgPHR0Pk5PX09QPC90dD4gZm9yIHRoZSBjYXNlcyB3aGVyZSB5b3Ugd2FudCByYXcgdGV4dCwgcmF0aGVyCiAgICAgKiB0aGFuIGhhdmluZyBhIHNlcGFyYXRlIGNvZGUgcGF0aCB0aGF0IGJ5cGFzc2VzIDx0dD5Ob3JtYWxpemVyPC90dD4KICAgICAqIGFsdG9nZXRoZXIuCiAgICAgKiA8cD4KICAgICAqIEBzZWUgI3NldE1vZGUKICAgICAqLwogICAgTk9fT1AgICAgICAgICA9IDAsCiAgICAKICAgIC8qKgogICAgICogQ2Fub25pY2FsIGRlY29tcG9zaXRpb24gZm9sbG93ZWQgYnkgY2Fub25pY2FsIGNvbXBvc2l0aW9uLiAgVXNlZCB3aXRoIAogICAgICogdGhlIHtAbGluayAjTm9ybWFsaXplciBjb25zdHJ1Y3RvcnN9IGFuZCB0aGUgc3RhdGljIAogICAgICoge0BsaW5rICNub3JtYWxpemUgbm9ybWFsaXplfQogICAgICogbWV0aG9kIHRvIGRldGVybWluZSB0aGUgb3BlcmF0aW9uIHRvIGJlIHBlcmZvcm1lZC4KICAgICAqIDxwPgogICAgICogSWYgYWxsIG9wdGlvbmFsIGZlYXR1cmVzICg8aT5lLmcuPC9pPiB7QGxpbmsgI0lHTk9SRV9IQU5HVUx9KSBhcmUgdHVybmVkCiAgICAgKiBvZmYsIHRoaXMgb3BlcmF0aW9uIHByb2R1Y2VzIG91dHB1dCB0aGF0IGlzIGluCiAgICAgKiA8YSBocmVmPWh0dHA6Ly93d3cudW5pY29kZS5vcmcvdW5pY29kZS9yZXBvcnRzL3RyMTUvPlVuaWNvZGUgQ2Fub25pY2FsCiAgICAgKiBGb3JtPC9hPgogICAgICogPGI+QzwvYj4uCiAgICAgKiA8cD4KICAgICAqIEBzZWUgI3NldE1vZGUKICAgICAqLwogICAgQ09NUE9TRSAgICAgICAgID0gQ09NUE9TRV9CSVQsCgogICAgLyoqCiAgICAgKiBDb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpb24gZm9sbG93ZWQgYnkgY2Fub25pY2FsIGNvbXBvc2l0aW9uLgogICAgICogVXNlZCB3aXRoIHRoZSB7QGxpbmsgI05vcm1hbGl6ZXIgY29uc3RydWN0b3JzfSBhbmQgdGhlIHN0YXRpYwogICAgICoge0BsaW5rICNub3JtYWxpemUgbm9ybWFsaXplfSBtZXRob2QgdG8gZGV0ZXJtaW5lIHRoZSBvcGVyYXRpb24gdG8gYmUKICAgICAqIHBlcmZvcm1lZC4KICAgICAqIDxwPgogICAgICogSWYgYWxsIG9wdGlvbmFsIGZlYXR1cmVzICg8aT5lLmcuPC9pPiB7QGxpbmsgI0lHTk9SRV9IQU5HVUx9KSBhcmUgdHVybmVkCiAgICAgKiBvZmYsIHRoaXMgb3BlcmF0aW9uIHByb2R1Y2VzIG91dHB1dCB0aGF0IGlzIGluCiAgICAgKiA8YSBocmVmPWh0dHA6Ly93d3cudW5pY29kZS5vcmcvdW5pY29kZS9yZXBvcnRzL3RyMTUvPlVuaWNvZGUgQ2Fub25pY2FsCiAgICAgKiBGb3JtPC9hPgogICAgICogPGI+S0M8L2I+LgogICAgICogPHA+CiAgICAgKiBAc2VlICNzZXRNb2RlCiAgICAgKi8KICAgIENPTVBPU0VfQ09NUEFUICAgICA9IENPTVBPU0VfQklUIHwgQ09NUEFUX0JJVCwKCiAgICAvKioKICAgICAqIENhbm9uaWNhbCBkZWNvbXBvc2l0aW9uLiAgVGhpcyB2YWx1ZSBpcyBwYXNzZWQgdG8gdGhlCiAgICAgKiB7QGxpbmsgI05vcm1hbGl6ZXIgY29uc3RydWN0b3JzfSBhbmQgdGhlIHN0YXRpYyAKICAgICAqIHtAbGluayAjbm9ybWFsaXplIG5vcm1hbGl6ZX0KICAgICAqIG1ldGhvZCB0byBkZXRlcm1pbmUgdGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQuCiAgICAgKiA8cD4KICAgICAqIElmIGFsbCBvcHRpb25hbCBmZWF0dXJlcyAoPGk+ZS5nLjwvaT4ge0BsaW5rICNJR05PUkVfSEFOR1VMfSkgYXJlIHR1cm5lZAogICAgICogb2ZmLCB0aGlzIG9wZXJhdGlvbiBwcm9kdWNlcyBvdXRwdXQgdGhhdCBpcyBpbgogICAgICogPGEgaHJlZj1odHRwOi8vd3d3LnVuaWNvZGUub3JnL3VuaWNvZGUvcmVwb3J0cy90cjE1Lz5Vbmljb2RlIENhbm9uaWNhbCAKICAgICAqIEZvcm08L2E+CiAgICAgKiA8Yj5EPC9iPi4KICAgICAqIDxwPgogICAgICogQHNlZSAjc2V0TW9kZQogICAgICovCiAgICBERUNPTVAgICAgICAgICA9IERFQ09NUF9CSVQsCgogICAgLyoqCiAgICAgKiBDb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpb24uICBUaGlzIHZhbHVlIGlzIHBhc3NlZCB0byB0aGUKICAgICAqIHtAbGluayAjTm9ybWFsaXplciBjb25zdHJ1Y3RvcnN9IGFuZCB0aGUgc3RhdGljIAogICAgICoge0BsaW5rICNub3JtYWxpemUgbm9ybWFsaXplfQogICAgICogbWV0aG9kIHRvIGRldGVybWluZSB0aGUgb3BlcmF0aW9uIHRvIGJlIHBlcmZvcm1lZC4KICAgICAqIDxwPgogICAgICogSWYgYWxsIG9wdGlvbmFsIGZlYXR1cmVzICg8aT5lLmcuPC9pPiB7QGxpbmsgI0lHTk9SRV9IQU5HVUx9KSBhcmUgdHVybmVkCiAgICAgKiBvZmYsIHRoaXMgb3BlcmF0aW9uIHByb2R1Y2VzIG91dHB1dCB0aGF0IGlzIGluCiAgICAgKiA8YSBocmVmPWh0dHA6Ly93d3cudW5pY29kZS5vcmcvdW5pY29kZS9yZXBvcnRzL3RyMTUvPlVuaWNvZGUgQ2Fub25pY2FsIAogICAgICogRm9ybTwvYT4KICAgICAqIDxiPktEPC9iPi4KICAgICAqIDxwPgogICAgICogQHNlZSAjc2V0TW9kZQogICAgICovCiAgICBERUNPTVBfQ09NUEFUICAgICA9IERFQ09NUF9CSVQgfCBDT01QQVRfQklUCiAgfTsKCiAgLyoqIFRoZSBvcHRpb25zIGZvciBhIE5vcm1hbGl6ZXIgb2JqZWN0ICovCiAgZW51bSB7CgogICAgLyoqCiAgICAgKiBPcHRpb24gdG8gZGlzYWJsZSBIYW5ndWwvSmFtbyBjb21wb3NpdGlvbiBhbmQgZGVjb21wb3NpdGlvbi4KICAgICAqIFRoaXMgb3B0aW9uIGFwcGxpZXMgdG8gS29yZWFuIHRleHQsIAogICAgICogd2hpY2ggY2FuIGJlIHJlcHJlc2VudGVkIGVpdGhlciBpbiB0aGUgSmFtbyBhbHBoYWJldCBvciBpbiBIYW5ndWwKICAgICAqIGNoYXJhY3RlcnMsIHdoaWNoIGFyZSByZWFsbHkganVzdCB0d28gb3IgdGhyZWUgSmFtbyBjb21iaW5lZAogICAgICogaW50byBvbmUgdmlzdWFsIGdseXBoLiAgU2luY2UgSmFtbyB0YWtlcyB1cCBtb3JlIHN0b3JhZ2Ugc3BhY2UgdGhhbgogICAgICogSGFuZ3VsLCBhcHBsaWNhdGlvbnMgdGhhdCBwcm9jZXNzIG9ubHkgSGFuZ3VsIHRleHQgbWF5IHdpc2ggdG8gdHVybgogICAgICogdGhpcyBvcHRpb24gb24gd2hlbiBkZWNvbXBvc2luZyB0ZXh0LgogICAgICogPHA+CiAgICAgKiBUaGUgVW5pY29kZSBzdGFuZGFyZCB0cmVhdGVzIEhhbmd1bCB0byBKYW1vIGNvbnZlcnNpb24gYXMgYSAKICAgICAqIGNhbm9uaWNhbCBkZWNvbXBvc2l0aW9uLCBzbyB0aGlzIG9wdGlvbiBtdXN0IGJlIHR1cm5lZCA8Yj5vZmY8L2I+IGlmIHlvdQogICAgICogd2lzaCB0byB0cmFuc2Zvcm0gc3RyaW5ncyBpbnRvIG9uZSBvZiB0aGUgc3RhbmRhcmQKICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudW5pY29kZS5vcmcvdW5pY29kZS9yZXBvcnRzL3RyMTUvIiB0YXJnZXQ9InVuaWNvZGUiPgogICAgICogVW5pY29kZSBOb3JtYWxpemF0aW9uIEZvcm1zPC9hPi4KICAgICAqIDxwPgogICAgICogQHNlZSAjc2V0T3B0aW9uCiAgICAgKi8KICAgIElHTk9SRV9IQU5HVUwgICAgID0gMHgwMDEKICB9OwoKICAvLyBDb25zdHJ1Y3RvcnMKCiAgLyoqCiAgICogQ3JlYXRlcyBhIG5ldyA8dHQ+Tm9ybWFsaXplcjwvdHQ+IG9iamVjdCBmb3IgaXRlcmF0aW5nIG92ZXIgdGhlCiAgICogbm9ybWFsaXplZCBmb3JtIG9mIGEgZ2l2ZW4gc3RyaW5nLgogICAqIDxwPgogICAqIEBwYXJhbSBzdHIgICBUaGUgc3RyaW5nIHRvIGJlIG5vcm1hbGl6ZWQuICBUaGUgbm9ybWFsaXphdGlvbgogICAqICAgICAgICAgICAgICB3aWxsIHN0YXJ0IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZy4KICAgKgogICAqIEBwYXJhbSBtb2RlICBUaGUgbm9ybWFsaXphdGlvbiBtb2RlLgogICAqIEBzdGFibGUKICAgKi8KICBOb3JtYWxpemVyKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHN0ciwgCiAgICAgICAgIEVNb2RlIG1vZGUpOwogICAgCiAgLyoqCiAgICogQ3JlYXRlcyBhIG5ldyA8dHQ+Tm9ybWFsaXplcjwvdHQ+IG9iamVjdCBmb3IgaXRlcmF0aW5nIG92ZXIgdGhlCiAgICogbm9ybWFsaXplZCBmb3JtIG9mIGEgZ2l2ZW4gc3RyaW5nLgogICAqIDxwPgogICAqIFRoZSA8dHQ+b3B0aW9uczwvdHQ+IHBhcmFtZXRlciBzcGVjaWZpZXMgd2hpY2ggb3B0aW9uYWwKICAgKiA8dHQ+Tm9ybWFsaXplcjwvdHQ+IGZlYXR1cmVzIGFyZSB0byBiZSBlbmFibGVkIGZvciB0aGlzIG9iamVjdC4KICAgKiA8cD4KICAgKiBAcGFyYW0gc3RyICAgVGhlIHN0cmluZyB0byBiZSBub3JtYWxpemVkLiAgVGhlIG5vcm1hbGl6YXRpb24KICAgKiAgICAgICAgICAgICAgd2lsbCBzdGFydCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcuCiAgICoKICAgKiBAcGFyYW0gbW9kZSAgVGhlIG5vcm1hbGl6YXRpb24gbW9kZS4KICAgKgogICAqIEBwYXJhbSBvcHQgICBBbnkgb3B0aW9uYWwgZmVhdHVyZXMgdG8gYmUgZW5hYmxlZC4KICAgKiAgICAgICAgICAgICAgQ3VycmVudGx5IHRoZSBvbmx5IGF2YWlsYWJsZSBvcHRpb24gaXMge0BsaW5rICNJR05PUkVfSEFOR1VMfQogICAqICAgICAgICAgICAgICBJZiB5b3Ugd2FudCB0aGUgZGVmYXVsdCBiZWhhdmlvciBjb3JyZXNwb25kaW5nIHRvIG9uZSBvZiB0aGUKICAgKiAgICAgICAgICAgICAgc3RhbmRhcmQgVW5pY29kZSBOb3JtYWxpemF0aW9uIEZvcm1zLCB1c2UgMCBmb3IgdGhpcyBhcmd1bWVudAogICAqIEBzdGFibGUKICAgKi8KICBOb3JtYWxpemVyKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHN0ciwgCiAgICAgICAgIEVNb2RlIG1vZGUsIAogICAgICAgICBpbnQzMl90IG9wdCk7CgogIC8qKgogICAqIENyZWF0ZXMgYSBuZXcgPHR0Pk5vcm1hbGl6ZXI8L3R0PiBvYmplY3QgZm9yIGl0ZXJhdGluZyBvdmVyIHRoZQogICAqIG5vcm1hbGl6ZWQgZm9ybSBvZiBhIGdpdmVuIFVDaGFyIHN0cmluZy4KICAgKiA8cD4KICAgKiBAcGFyYW0gc3RyICAgVGhlIHN0cmluZyB0byBiZSBub3JtYWxpemVkLiAgVGhlIG5vcm1hbGl6YXRpb24KICAgKiAgICAgICAgICAgICAgd2lsbCBzdGFydCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcuCiAgICoKICAgKiBAcGFyYW0gbGVuZ3RoIExlbmdodCBvZiB0aGUgc3RyaW5nCiAgICogQHBhcmFtIG1vZGUgIFRoZSBub3JtYWxpemF0aW9uIG1vZGUuCiAgICogQHN0YWJsZQogICAqCiAgICovCiAgTm9ybWFsaXplcihjb25zdCBVQ2hhciogc3RyLAogICAgICAgICBpbnQzMl90IGxlbmd0aCwKICAgICAgICAgRU1vZGUgbW9kZSk7CgogIC8qKgogICAqIENyZWF0ZXMgYSBuZXcgPHR0Pk5vcm1hbGl6ZXI8L3R0PiBvYmplY3QgZm9yIGl0ZXJhdGluZyBvdmVyIHRoZQogICAqIG5vcm1hbGl6ZWQgZm9ybSBvZiBhIGdpdmVuIFVDaGFyIHN0cmluZy4KICAgKiA8cD4KICAgKiBAcGFyYW0gc3RyICAgVGhlIHN0cmluZyB0byBiZSBub3JtYWxpemVkLiAgVGhlIG5vcm1hbGl6YXRpb24KICAgKiAgICAgICAgICAgICAgd2lsbCBzdGFydCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcuCiAgICoKICAgKiBAcGFyYW0gbGVuZ3RoIExlbmdodCBvZiB0aGUgc3RyaW5nCiAgICogQHBhcmFtIG1vZGUgIFRoZSBub3JtYWxpemF0aW9uIG1vZGUuCiAgICogQHBhcmFtIG9wdCAgIEFueSBvcHRpb25hbCBmZWF0dXJlcyB0byBiZSBlbmFibGVkLgogICAqICAgICAgICAgICAgICBDdXJyZW50bHkgdGhlIG9ubHkgYXZhaWxhYmxlIG9wdGlvbiBpcyB7QGxpbmsgI0lHTk9SRV9IQU5HVUx9CiAgICogICAgICAgICAgICAgIElmIHlvdSB3YW50IHRoZSBkZWZhdWx0IGJlaGF2aW9yIGNvcnJlc3BvbmRpbmcgdG8gb25lIG9mIHRoZQogICAqICAgICAgICAgICAgICBzdGFuZGFyZCBVbmljb2RlIE5vcm1hbGl6YXRpb24gRm9ybXMsIHVzZSAwIGZvciB0aGlzIGFyZ3VtZW50CiAgICogQHVuaW1wbGVtZW50ZWQgCiAgICoKICAgKi8KICBOb3JtYWxpemVyKGNvbnN0IFVDaGFyKiBzdHIsCiAgICAgICAgIGludDMyX3QgbGVuZ3RoLAogICAgICAgICBFTW9kZSBtb2RlLAogICAgICAgICBpbnQzMl90IG9wdGlvbik7CgogIC8qKgogICAqIENyZWF0ZXMgYSBuZXcgPHR0Pk5vcm1hbGl6ZXI8L3R0PiBvYmplY3QgZm9yIGl0ZXJhdGluZyBvdmVyIHRoZQogICAqIG5vcm1hbGl6ZWQgZm9ybSBvZiB0aGUgZ2l2ZW4gdGV4dC4KICAgKiA8cD4KICAgKiBAcGFyYW0gaXRlciAgVGhlIGlucHV0IHRleHQgdG8gYmUgbm9ybWFsaXplZC4gIFRoZSBub3JtYWxpemF0aW9uCiAgICogICAgICAgICAgICAgIHdpbGwgc3RhcnQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nLgogICAqCiAgICogQHBhcmFtIG1vZGUgIFRoZSBub3JtYWxpemF0aW9uIG1vZGUuCiAgICogQHN0YWJsZQogICAqCiAgICovCiAgTm9ybWFsaXplcihjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgaXRlciwgCiAgICAgICAgIEVNb2RlIG1vZGUpOwoKICAvKioKICAgKiBDcmVhdGVzIGEgbmV3IDx0dD5Ob3JtYWxpemVyPC90dD4gb2JqZWN0IGZvciBpdGVyYXRpbmcgb3ZlciB0aGUKICAgKiBub3JtYWxpemVkIGZvcm0gb2YgdGhlIGdpdmVuIHRleHQuCiAgICogPHA+CiAgICogQHBhcmFtIGl0ZXIgIFRoZSBpbnB1dCB0ZXh0IHRvIGJlIG5vcm1hbGl6ZWQuICBUaGUgbm9ybWFsaXphdGlvbgogICAqICAgICAgICAgICAgICB3aWxsIHN0YXJ0IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZy4KICAgKgogICAqIEBwYXJhbSBtb2RlICBUaGUgbm9ybWFsaXphdGlvbiBtb2RlLgogICAqCiAgICogQHBhcmFtIG9wdCAgIEFueSBvcHRpb25hbCBmZWF0dXJlcyB0byBiZSBlbmFibGVkLgogICAqICAgICAgICAgICAgICBDdXJyZW50bHkgdGhlIG9ubHkgYXZhaWxhYmxlIG9wdGlvbiBpcyB7QGxpbmsgI0lHTk9SRV9IQU5HVUx9CiAgICogICAgICAgICAgICAgIElmIHlvdSB3YW50IHRoZSBkZWZhdWx0IGJlaGF2aW9yIGNvcnJlc3BvbmRpbmcgdG8gb25lIG9mIHRoZQogICAqICAgICAgICAgICAgICBzdGFuZGFyZCBVbmljb2RlIE5vcm1hbGl6YXRpb24gRm9ybXMsIHVzZSAwIGZvciB0aGlzIGFyZ3VtZW50CiAgICogQHN0YWJsZQogICAqLwogIE5vcm1hbGl6ZXIoY29uc3QgQ2hhcmFjdGVySXRlcmF0b3ImIGl0ZXIsIAogICAgICAgICBFTW9kZSBtb2RlLCAKICAgICAgICAgaW50MzJfdCBvcHQpOwoKICAvKioKICAgKiBDb3B5IGNvbnN0cnVjdG9yLgogICAqIEBzdGFibGUKICAgKi8KICBOb3JtYWxpemVyKGNvbnN0IE5vcm1hbGl6ZXImIGNvcHkpOwoKICAvKioKICAgKiBEZXN0cnVjdG9yCiAgICogQHN0YWJsZQogICAqLwogIH5Ob3JtYWxpemVyKCk7CgoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBTdGF0aWMgdXRpbGl0eSBtZXRob2RzCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIE5vcm1hbGl6ZXMgYSA8dHQ+U3RyaW5nPC90dD4gdXNpbmcgdGhlIGdpdmVuIG5vcm1hbGl6YXRpb24gb3BlcmF0aW9uLgogICAqIDxwPgogICAqIFRoZSA8dHQ+b3B0aW9uczwvdHQ+IHBhcmFtZXRlciBzcGVjaWZpZXMgd2hpY2ggb3B0aW9uYWwKICAgKiA8dHQ+Tm9ybWFsaXplcjwvdHQ+IGZlYXR1cmVzIGFyZSB0byBiZSBlbmFibGVkIGZvciB0aGlzIG9wZXJhdGlvbi4KICAgKiBDdXJyZW50bHkgdGhlIG9ubHkgYXZhaWxhYmxlIG9wdGlvbiBpcyB7QGxpbmsgI0lHTk9SRV9IQU5HVUx9LgogICAqIElmIHlvdSB3YW50IHRoZSBkZWZhdWx0IGJlaGF2aW9yIGNvcnJlc3BvbmRpbmcgdG8gb25lIG9mIHRoZSBzdGFuZGFyZAogICAqIFVuaWNvZGUgTm9ybWFsaXphdGlvbiBGb3JtcywgdXNlIDAgZm9yIHRoaXMgYXJndW1lbnQuCiAgICogPHA+CiAgICogQHBhcmFtIHNvdXJjZSAgICB0aGUgaW5wdXQgc3RyaW5nIHRvIGJlIG5vcm1hbGl6ZWQuCiAgICoKICAgKiBAcGFyYW0gYU1vZGUgICAgIHRoZSBub3JtYWxpemF0aW9uIG1vZGUKICAgKgogICAqIEBwYXJhbSBvcHRpb25zICAgdGhlIG9wdGlvbmFsIGZlYXR1cmVzIHRvIGJlIGVuYWJsZWQuCiAgICoKICAgKiBAcGFyYW0gcmVzdWx0ICAgIFRoZSBub3JtYWxpemVkIHN0cmluZyAob24gb3V0cHV0KS4KICAgKgogICAqIEBwYXJhbSBzdGF0dXMgICAgVGhlIGVycm9yIGNvZGUuCiAgICogQHN0YWJsZQogICAqLwogIHN0YXRpYyB2b2lkIG5vcm1hbGl6ZShjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsIAogICAgICAgICAgICBFTW9kZSBtb2RlLCAKICAgICAgICAgICAgaW50MzJfdCBvcHRpb25zLAogICAgICAgICAgICBVbmljb2RlU3RyaW5nJiByZXN1bHQsIAogICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpOwoKICAvKioKICAgKiBDb21wb3NlIGEgPHR0PlN0cmluZzwvdHQ+LgogICAqIDxwPgogICAqIFRoZSA8dHQ+b3B0aW9uczwvdHQ+IHBhcmFtZXRlciBzcGVjaWZpZXMgd2hpY2ggb3B0aW9uYWwKICAgKiA8dHQ+Tm9ybWFsaXplcjwvdHQ+IGZlYXR1cmVzIGFyZSB0byBiZSBlbmFibGVkIGZvciB0aGlzIG9wZXJhdGlvbi4KICAgKiBDdXJyZW50bHkgdGhlIG9ubHkgYXZhaWxhYmxlIG9wdGlvbiBpcyB7QGxpbmsgI0lHTk9SRV9IQU5HVUx9LgogICAqIElmIHlvdSB3YW50IHRoZSBkZWZhdWx0IGJlaGF2aW9yIGNvcnJlc3BvbmRpbmcKICAgKiB0byBVbmljb2RlIE5vcm1hbGl6YXRpb24gRm9ybSA8Yj5DPC9iPiBvciA8Yj5LQzwvYj4sCiAgICogdXNlIDAgZm9yIHRoaXMgYXJndW1lbnQuCiAgICogPHA+CiAgICogQHBhcmFtIHNvdXJjZSAgICB0aGUgc3RyaW5nIHRvIGJlIGNvbXBvc2VkLgogICAqCiAgICogQHBhcmFtIGNvbXBhdCAgICBQZXJmb3JtIGNvbXBhdGliaWxpdHkgZGVjb21wb3NpdGlvbiBiZWZvcmUgY29tcG9zaXRpb24uCiAgICogICAgICAgICAgICAgICAgICBJZiB0aGlzIGFyZ3VtZW50IGlzIDx0dD5mYWxzZTwvdHQ+LCBvbmx5IGNhbm9uaWNhbAogICAqICAgICAgICAgICAgICAgICAgZGVjb21wb3NpdGlvbiB3aWxsIGJlIHBlcmZvcm1lZC4KICAgKgogICAqIEBwYXJhbSBvcHRpb25zICAgdGhlIG9wdGlvbmFsIGZlYXR1cmVzIHRvIGJlIGVuYWJsZWQuCiAgICoKICAgKiBAcGFyYW0gcmVzdWx0ICAgIFRoZSBjb21wb3NlZCBzdHJpbmcgKG9uIG91dHB1dCkuCiAgICoKICAgKiBAcGFyYW0gc3RhdHVzICAgIFRoZSBlcnJvciBjb2RlLgogICAqIEBzdGFibGUKICAgKi8KICBzdGF0aWMgdm9pZCBjb21wb3NlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwgCiAgICAgICAgICAgICAgVUJvb2wgY29tcGF0LAogICAgICAgICAgICAgIGludDMyX3Qgb3B0aW9ucywKICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiByZXN1bHQsIAogICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cyk7CgogIC8qKgogICAqIFN0YXRpYyBtZXRob2QgdG8gZGVjb21wb3NlIGEgPHR0PlN0cmluZzwvdHQ+LgogICAqIDxwPgogICAqIFRoZSA8dHQ+b3B0aW9uczwvdHQ+IHBhcmFtZXRlciBzcGVjaWZpZXMgd2hpY2ggb3B0aW9uYWwKICAgKiA8dHQ+Tm9ybWFsaXplcjwvdHQ+IGZlYXR1cmVzIGFyZSB0byBiZSBlbmFibGVkIGZvciB0aGlzIG9wZXJhdGlvbi4KICAgKiBDdXJyZW50bHkgdGhlIG9ubHkgYXZhaWxhYmxlIG9wdGlvbiBpcyB7QGxpbmsgI0lHTk9SRV9IQU5HVUx9LgogICAqIFRoZSBkZXNpcmVkIG9wdGlvbnMgc2hvdWxkIGJlIE9SJ2VkIHRvZ2V0aGVyIHRvIGRldGVybWluZSB0aGUgdmFsdWUKICAgKiBvZiB0aGlzIGFyZ3VtZW50LiAgSWYgeW91IHdhbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgY29ycmVzcG9uZGluZwogICAqIHRvIFVuaWNvZGUgTm9ybWFsaXphdGlvbiBGb3JtIDxiPkQ8L2I+IG9yIDxiPktEPC9iPiwKICAgKiB1c2UgMCBmb3IgdGhpcyBhcmd1bWVudC4KICAgKiA8cD4KICAgKiBAcGFyYW0gc3RyICAgdGhlIHN0cmluZyB0byBiZSBkZWNvbXBvc2VkLgogICAqCiAgICogQHBhcmFtIGNvbXBhdCAgICBQZXJmb3JtIGNvbXBhdGliaWxpdHkgZGVjb21wb3NpdGlvbi4KICAgKiAgICAgICAgICAgICAgICAgIElmIHRoaXMgYXJndW1lbnQgaXMgPHR0PmZhbHNlPC90dD4sIG9ubHkgY2Fub25pY2FsCiAgICogICAgICAgICAgICAgICAgICBkZWNvbXBvc2l0aW9uIHdpbGwgYmUgcGVyZm9ybWVkLgogICAqCiAgICogQHBhcmFtIG9wdGlvbnMgICB0aGUgb3B0aW9uYWwgZmVhdHVyZXMgdG8gYmUgZW5hYmxlZC4KICAgKgogICAqIEBwYXJhbSByZXN1bHQgICAgVGhlIGNvbXBvc2VkIHN0cmluZyAob24gb3V0cHV0KS4KICAgKgogICAqIEBwYXJhbSBzdGF0dXMgICAgVGhlIGVycm9yIGNvZGUuCiAgICoKICAgKiBAcmV0dXJuICAgICAgdGhlIGRlY29tcG9zZWQgc3RyaW5nLgogICAqIEBzdGFibGUKICAgKi8KICBzdGF0aWMgdm9pZCBkZWNvbXBvc2UoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCAKICAgICAgICAgICAgVUJvb2wgY29tcGF0LAogICAgICAgICAgICBpbnQzMl90IG9wdGlvbnMsCiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIHJlc3VsdCwgCiAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cyk7CgogIC8qKgogICogQ29udmVydHMgQydzIE5vcm1hbGl6ZXI6OkVNb2RlIHRvIFVOb3JtYWxpemF0aW9uTW9kZQogICogQHBhcmFtIG1vZGUgbWVtYmVyIG9mIHRoZSBlbnVtIE5vcm1hbGl6ZXI6OkVNb2RlCiAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGVzIHN0YXR1cwogICogQHJldHVybiBVTm9ybWFsaXphdGlvbk1vZGUgZXF1aXZhbGVudCBvZiBOb3JtYWxpemVyOjpFTW9kZQogICovCiAgaW5saW5lIHN0YXRpYyBVTm9ybWFsaXphdGlvbk1vZGUgZ2V0VU5vcm1hbGl6YXRpb25Nb2RlKEVNb2RlIG1vZGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICogQ29udmVydHMgQysrJ3MgVU5vcm1hbGl6YXRpb25Nb2RlIHRvIE5vcm1hbGl6ZXI6OkVNb2RlCiAgKiBAcGFyYW0gbW9kZSBtZW1iZXIgb2YgdGhlIGVudW0gVU5vcm1hbGl6YXRpb25Nb2RlCiAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGVzIHN0YXR1cwogICogQHJldHVybiBOb3JtYWxpemVyOjpFTW9kZSBlcXVpdmFsZW50IG9mIFVOb3JtYWxpemF0aW9uTW9kZQogICovCiAgaW5saW5lIHN0YXRpYyBFTW9kZSBnZXROb3JtYWxpemVyRU1vZGUoVU5vcm1hbGl6YXRpb25Nb2RlIG1vZGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICogUGVyZm9ybWluZyBxdWljayBjaGVjayBvbiBhIHN0cmluZywgdG8gcXVpY2tseSBkZXRlcm1pbmUgaWYgdGhlIHN0cmluZyBpcyAKICAqIGluIGEgcGFydGljdWxhciBub3JtYWxpemF0aW9uIGZvcm1hdC4KICAqIFRocmVlIHR5cGVzIG9mIHJlc3VsdCBjYW4gYmUgcmV0dXJuZWQgVU5PUk1fWUVTLCBVTk9STV9OTyBvcgogICogVU5PUk1fTUFZQkUuIFJlc3VsdCBVTk9STV9ZRVMgaW5kaWNhdGVzIHRoYXQgdGhlIGFyZ3VtZW50CiAgKiBzdHJpbmcgaXMgaW4gdGhlIGRlc2lyZWQgbm9ybWFsaXplZCBmb3JtYXQsIFVOT1JNX05PIGRldGVybWluZXMgdGhhdAogICogYXJndW1lbnQgc3RyaW5nIGlzIG5vdCBpbiB0aGUgZGVzaXJlZCBub3JtYWxpemVkIGZvcm1hdC4gQSAKICAqIFVOT1JNX01BWUJFIHJlc3VsdCBpbmRpY2F0ZXMgdGhhdCBhIG1vcmUgdGhvcm91Z2ggY2hlY2sgaXMgcmVxdWlyZWQsIAogICogdGhlIHVzZXIgbWF5IGhhdmUgdG8gcHV0IHRoZSBzdHJpbmcgaW4gaXRzIG5vcm1hbGl6ZWQgZm9ybSBhbmQgY29tcGFyZSB0aGUgCiAgKiByZXN1bHRzLgogICogQHBhcmFtIHNvdXJjZSAgICAgICBzdHJpbmcgZm9yIGRldGVybWluaW5nIGlmIGl0IGlzIGluIGEgbm9ybWFsaXplZCBmb3JtYXQKICAqIEBwYXJhbiBtb2RlICAgICAgICAgbm9ybWFsaXphdGlvbiBmb3JtYXQKICAqIEBwYXJhbSBzdGF0dXMgQSBwb2ludGVyIHRvIGFuIFVFcnJvckNvZGUgdG8gcmVjZWl2ZSBhbnkgZXJyb3JzCiAgKiBAcmV0dXJuIFVOT1JNX1lFUywgVU5PUk1fTk8gb3IgVU5PUk1fTUFZQkUKICAqLwogIHN0YXRpYyBVTm9ybWFsaXphdGlvbkNoZWNrUmVzdWx0CiAgcXVpY2tDaGVjayhjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICBFTW9kZSAgICAgICAgICAgICAgICBtb2RlLCAKICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgICAgIHN0YXR1cyk7CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIENoYXJhY3Rlckl0ZXJhdG9yIG92ZXJyaWRlcwogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIAogIC8qKgogICAqIFJldHVybiB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaW4gdGhlIG5vcm1hbGl6ZWQgdGV4dC4KICAgKiBAZHJhZnQKICAgKi8KICBVQ2hhcjMyICAgICAgICAgICAgICBjdXJyZW50KHZvaWQpIGNvbnN0OwoKICAvKioKICAgKiBSZXR1cm4gdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgbm9ybWFsaXplZCB0ZXh0LiAgVGhpcyByZXNldHMKICAgKiB0aGUgPHR0Pk5vcm1hbGl6ZXInczwvdHQ+IHBvc2l0aW9uIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRleHQuCiAgICogQGRyYWZ0CiAgICovCiAgVUNoYXIzMiAgICAgICAgICAgICAgZmlyc3Qodm9pZCk7CgogIC8qKgogICAqIFJldHVybiB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIG5vcm1hbGl6ZWQgdGV4dC4gIFRoaXMgcmVzZXRzCiAgICogdGhlIDx0dD5Ob3JtYWxpemVyJ3M8L3R0PiBwb3NpdGlvbiB0byBiZSBqdXN0IGJlZm9yZSB0aGUKICAgKiB0aGUgaW5wdXQgdGV4dCBjb3JyZXNwb25kaW5nIHRvIHRoYXQgbm9ybWFsaXplZCBjaGFyYWN0ZXIuCiAgICogQGRyYWZ0CiAgICovCiAgVUNoYXIzMiAgICAgICAgICAgICAgbGFzdCh2b2lkKTsKCiAgLyoqCiAgICogUmV0dXJuIHRoZSBuZXh0IGNoYXJhY3RlciBpbiB0aGUgbm9ybWFsaXplZCB0ZXh0IGFuZCBhZHZhbmNlCiAgICogdGhlIGl0ZXJhdGlvbiBwb3NpdGlvbiBieSBvbmUuICBJZiB0aGUgZW5kCiAgICogb2YgdGhlIHRleHQgaGFzIGFscmVhZHkgYmVlbiByZWFjaGVkLCB7QGxpbmsgI0RPTkV9IGlzIHJldHVybmVkLgogICAqIEBkcmFmdAogICAqLwogIFVDaGFyMzIgICAgICAgICAgICAgIG5leHQodm9pZCk7CgogIC8qKgogICAqIFJldHVybiB0aGUgcHJldmlvdXMgY2hhcmFjdGVyIGluIHRoZSBub3JtYWxpemVkIHRleHQgYW5kIGRlY3JlbWVudAogICAqIHRoZSBpdGVyYXRpb24gcG9zaXRpb24gYnkgb25lLiAgSWYgdGhlIGJlZ2lubmluZwogICAqIG9mIHRoZSB0ZXh0IGhhcyBhbHJlYWR5IGJlZW4gcmVhY2hlZCwge0BsaW5rICNET05FfSBpcyByZXR1cm5lZC4KICAgKiBAZHJhZnQKICAgKi8KICBVQ2hhcjMyICAgICAgICAgICAgICBwcmV2aW91cyh2b2lkKTsKCiAgLyoqCiAgICogU2V0IHRoZSBpdGVyYXRpb24gcG9zaXRpb24gaW4gdGhlIGlucHV0IHRleHQgdGhhdCBpcyBiZWluZyBub3JtYWxpemVkCiAgICogYW5kIHJldHVybiB0aGUgZmlyc3Qgbm9ybWFsaXplZCBjaGFyYWN0ZXIgYXQgdGhhdCBwb3NpdGlvbi4KICAgKiA8cD4KICAgKiA8Yj5Ob3RlOjwvYj4gVGhpcyBtZXRob2Qgc2V0cyB0aGUgcG9zaXRpb24gaW4gdGhlIDxlbT5pbnB1dDwvZW0+IHRleHQsCiAgICogd2hpbGUge0BsaW5rICNuZXh0fSBhbmQge0BsaW5rICNwcmV2aW91c30gaXRlcmF0ZSB0aHJvdWdoIGNoYXJhY3RlcnMKICAgKiBpbiB0aGUgbm9ybWFsaXplZCA8ZW0+b3V0cHV0PC9lbT4uICBUaGlzIG1lYW5zIHRoYXQgdGhlcmUgaXMgbm90CiAgICogbmVjZXNzYXJpbHkgYSBvbmUtdG8tb25lIGNvcnJlc3BvbmRlbmNlIGJldHdlZW4gY2hhcmFjdGVycyByZXR1cm5lZAogICAqIGJ5IDx0dD5uZXh0PC90dD4gYW5kIDx0dD5wcmV2aW91czwvdHQ+IGFuZCB0aGUgaW5kaWNlcyBwYXNzZWQgdG8gYW5kCiAgICogcmV0dXJuZWQgZnJvbSA8dHQ+c2V0SW5kZXg8L3R0PiBhbmQge0BsaW5rICNnZXRJbmRleH0uCiAgICogPHA+CiAgICogQHBhcmFtIGluZGV4IHRoZSBkZXNpcmVkIGluZGV4IGluIHRoZSBpbnB1dCB0ZXh0LgogICAqCiAgICogQHJldHVybiAgICAgIHRoZSBmaXJzdCBub3JtYWxpemVkIGNoYXJhY3RlciB0aGF0IGlzIHRoZSByZXN1bHQgb2YgaXRlcmF0aW5nCiAgICogICAgICAgICAgICAgIGZvcndhcmQgc3RhcnRpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAqIEBkcmFmdAogICAqLwogIFVDaGFyMzIgICAgICAgICAgICAgIHNldEluZGV4KFVUZXh0T2Zmc2V0IGluZGV4KTsKCiAgLyoqCiAgICogUmVzZXQgdGhlIGl0ZXJhdG9yIHNvIHRoYXQgaXQgaXMgaW4gdGhlIHNhbWUgc3RhdGUgdGhhdCBpdCB3YXMganVzdCBhZnRlcgogICAqIGl0IHdhcyBjb25zdHJ1Y3RlZC4gIEEgc3Vic2VxdWVudCBjYWxsIHRvIDx0dD5uZXh0PC90dD4gd2lsbCByZXR1cm4gdGhlIGZpcnN0CiAgICogY2hhcmFjdGVyIGluIHRoZSBub3JtYWxpemVkIHRleHQuICBJbiBjb250cmFzdCwgY2FsbGluZyA8dHQ+c2V0SW5kZXgoMCk8L3R0PiBmb2xsb3dlZAogICAqIGJ5IDx0dD5uZXh0PC90dD4gd2lsbCByZXR1cm4gdGhlIDxlbT5zZWNvbmQ8L2VtPiBjaGFyYWN0ZXIgaW4gdGhlIG5vcm1hbGl6ZWQgdGV4dCwKICAgKiBiZWNhdXNlIDx0dD5zZXRJbmRleDwvdHQ+IGl0c2VsZiByZXR1cm5zIHRoZSBmaXJzdCBjaGFyYWN0ZXIKICAgKiBAc3RhYmxlCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICByZXNldCh2b2lkKTsKCiAgLyoqCiAgICogUmV0cmlldmUgdGhlIGN1cnJlbnQgaXRlcmF0aW9uIHBvc2l0aW9uIGluIHRoZSBpbnB1dCB0ZXh0IHRoYXQgaXMKICAgKiBiZWluZyBub3JtYWxpemVkLiAgVGhpcyBtZXRob2QgaXMgdXNlZnVsIGluIGFwcGxpY2F0aW9ucyBzdWNoIGFzCiAgICogc2VhcmNoaW5nLCB3aGVyZSB5b3UgbmVlZCB0byBiZSBhYmxlIHRvIGRldGVybWluZSB0aGUgcG9zaXRpb24gaW4KICAgKiB0aGUgaW5wdXQgdGV4dCB0aGF0IGNvcnJlc3BvbmRzIHRvIGEgZ2l2ZW4gbm9ybWFsaXplZCBvdXRwdXQgY2hhcmFjdGVyLgogICAqIDxwPgogICAqIDxiPk5vdGU6PC9iPiBUaGlzIG1ldGhvZCBzZXRzIHRoZSBwb3NpdGlvbiBpbiB0aGUgPGVtPmlucHV0PC9lbT4sIHdoaWxlCiAgICoge0BsaW5rICNuZXh0fSBhbmQge0BsaW5rICNwcmV2aW91c30gaXRlcmF0ZSB0aHJvdWdoIGNoYXJhY3RlcnMgaW4gdGhlCiAgICogPGVtPm91dHB1dDwvZW0+LiAgVGhpcyBtZWFucyB0aGF0IHRoZXJlIGlzIG5vdCBuZWNlc3NhcmlseSBhIG9uZS10by1vbmUKICAgKiBjb3JyZXNwb25kZW5jZSBiZXR3ZWVuIGNoYXJhY3RlcnMgcmV0dXJuZWQgYnkgPHR0Pm5leHQ8L3R0PiBhbmQKICAgKiA8dHQ+cHJldmlvdXM8L3R0PiBhbmQgdGhlIGluZGljZXMgcGFzc2VkIHRvIGFuZCByZXR1cm5lZCBmcm9tCiAgICogPHR0PnNldEluZGV4PC90dD4gYW5kIHtAbGluayAjZ2V0SW5kZXh9LgogICAqIEBzdGFibGUKICAgKi8KICBVVGV4dE9mZnNldCAgICAgICAgICAgIGdldEluZGV4KHZvaWQpIGNvbnN0OwoKICAvKioKICAgKiBSZXRyaWV2ZSB0aGUgaW5kZXggb2YgdGhlIHN0YXJ0IG9mIHRoZSBpbnB1dCB0ZXh0LiAgVGhpcyBpcyB0aGUgYmVnaW4gaW5kZXgKICAgKiBvZiB0aGUgPHR0PkNoYXJhY3Rlckl0ZXJhdG9yPC90dD4gb3IgdGhlIHN0YXJ0IChpLmUuIDApIG9mIHRoZSA8dHQ+U3RyaW5nPC90dD4KICAgKiBvdmVyIHdoaWNoIHRoaXMgPHR0Pk5vcm1hbGl6ZXI8L3R0PiBpcyBpdGVyYXRpbmcKICAgKiBAc3RhYmxlCiAgICovCiAgVVRleHRPZmZzZXQgICAgICAgICAgICBzdGFydEluZGV4KHZvaWQpIGNvbnN0OwoKICAvKioKICAgKiBSZXRyaWV2ZSB0aGUgaW5kZXggb2YgdGhlIGVuZCBvZiB0aGUgaW5wdXQgdGV4dC4gIFRoaXMgaXMgdGhlIGVuZCBpbmRleAogICAqIG9mIHRoZSA8dHQ+Q2hhcmFjdGVySXRlcmF0b3I8L3R0PiBvciB0aGUgbGVuZ3RoIG9mIHRoZSA8dHQ+U3RyaW5nPC90dD4KICAgKiBvdmVyIHdoaWNoIHRoaXMgPHR0Pk5vcm1hbGl6ZXI8L3R0PiBpcyBpdGVyYXRpbmcKICAgKiBAc3RhYmxlCiAgICovCiAgVVRleHRPZmZzZXQgICAgICAgICAgICBlbmRJbmRleCh2b2lkKSBjb25zdDsKCgogIC8qKgogICAqIFJldHVybnMgdHJ1ZSB3aGVuIGJvdGggaXRlcmF0b3JzIHJlZmVyIHRvIHRoZSBzYW1lIGNoYXJhY3RlciBpbiB0aGUgc2FtZQogICAqIGNoYXJhY3Rlci1zdG9yYWdlIG9iamVjdC4KICAgKiBAc3RhYmxlCiAgICovCiAgLy8gIHZpcnR1YWwgVUJvb2wgICAgb3BlcmF0b3I9PShjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgdGhhdCkgY29uc3Q7CiAgVUJvb2wgICAgICAgIG9wZXJhdG9yPT0oY29uc3QgTm9ybWFsaXplciYgdGhhdCkgY29uc3Q7CiAgaW5saW5lIFVCb29sICAgICAgICBvcGVyYXRvciE9KGNvbnN0IE5vcm1hbGl6ZXImIHRoYXQpIGNvbnN0OwoKICAvKioKICAgKiBSZXR1cm5zIGEgcG9pbnRlciB0byBhIG5ldyBOb3JtYWxpemVyIHRoYXQgaXMgYSBjbG9uZSBvZiB0aGlzIG9uZS4KICAgKiBUaGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBkZWxldGluZyB0aGUgbmV3IGNsb25lLgogICAqIEBzdGFibGUKICAgKi8KICBOb3JtYWxpemVyKiAgICAgICAgY2xvbmUodm9pZCkgY29uc3Q7CgogIC8qKgogICAqIEdlbmVyYXRlcyBhIGhhc2ggY29kZSBmb3IgdGhpcyBpdGVyYXRvci4KICAgKiBAc3RhYmxlCiAgICovCiAgaW50MzJfdCAgICAgICAgICAgICAgICBoYXNoQ29kZSh2b2lkKSBjb25zdDsKCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gUHJvcGVydHkgYWNjZXNzIG1ldGhvZHMKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogU2V0IHRoZSBub3JtYWxpemF0aW9uIG1vZGUgZm9yIHRoaXMgb2JqZWN0LgogICAqIDxwPgogICAqIDxiPk5vdGU6PC9iPklmIHRoZSBub3JtYWxpemF0aW9uIG1vZGUgaXMgY2hhbmdlZCB3aGlsZSBpdGVyYXRpbmcKICAgKiBvdmVyIGEgc3RyaW5nLCBjYWxscyB0byB7QGxpbmsgI25leHR9IGFuZCB7QGxpbmsgI3ByZXZpb3VzfSBtYXkKICAgKiByZXR1cm4gcHJldmlvdXNseSBidWZmZXJzIGNoYXJhY3RlcnMgaW4gdGhlIG9sZCBub3JtYWxpemF0aW9uIG1vZGUKICAgKiB1bnRpbCB0aGUgaXRlcmF0aW9uIGlzIGFibGUgdG8gcmUtc3luYyBhdCB0aGUgbmV4dCBiYXNlIGNoYXJhY3Rlci4KICAgKiBJdCBpcyBzYWZlc3QgdG8gY2FsbCB7QGxpbmsgI3NldFRleHQgc2V0VGV4dCgpfSwge0BsaW5rICNmaXJzdH0sCiAgICoge0BsaW5rICNsYXN0fSwgZXRjLiBhZnRlciBjYWxsaW5nIDx0dD5zZXRNb2RlPC90dD4uCiAgICogPHA+CiAgICogQHBhcmFtIG5ld01vZGUgdGhlIG5ldyBtb2RlIGZvciB0aGlzIDx0dD5Ob3JtYWxpemVyPC90dD4uCiAgICogVGhlIHN1cHBvcnRlZCBtb2RlcyBhcmU6CiAgICogPHVsPgogICAqICA8bGk+e0BsaW5rICNDT01QT1NFfSAgICAgICAgLSBVbmljb2RlIGNhbm9uaWNhbCBkZWNvbXBvc2l0aWlvbgogICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbGxvd2VkIGJ5IGNhbm9uaWNhbCBjb21wb3NpdGlvbi4KICAgKiAgPGxpPntAbGluayAjQ09NUE9TRV9DT01QQVR9IC0gVW5pY29kZSBjb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpaW9uCiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9sbHdlZCBieSBjYW5vbmljYWwgY29tcG9zaXRpb24uCiAgICogIDxsaT57QGxpbmsgI0RFQ09NUH0gICAgICAgICAtIFVuaWNvZGUgY2Fub25pY2FsIGRlY29tcG9zaXRpb24KICAgKiAgPGxpPntAbGluayAjREVDT01QX0NPTVBBVH0gIC0gVW5pY29kZSBjb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpb24uCiAgICogIDxsaT57QGxpbmsgI05PX09QfSAgICAgICAgICAtIERvIG5vdGhpbmcgYnV0IHJldHVybiBjaGFyYWN0ZXJzCiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSB0aGUgdW5kZXJseWluZyBpbnB1dCB0ZXh0LgogICAqIDwvdWw+CiAgICoKICAgKiBAc2VlICNnZXRNb2RlCiAgICogQHN0YWJsZQogICAqLwogIHZvaWQgc2V0TW9kZShFTW9kZSBuZXdNb2RlKTsKCiAgLyoqCiAgICogUmV0dXJuIHRoZSBiYXNpYyBvcGVyYXRpb24gcGVyZm9ybWVkIGJ5IHRoaXMgPHR0Pk5vcm1hbGl6ZXI8L3R0PgogICAqCiAgICogQHNlZSAjc2V0TW9kZQogICAqIEBzdGFibGUKICAgKi8KICBFTW9kZSBnZXRNb2RlKHZvaWQpIGNvbnN0OwoKICAvKioKICAgKiBTZXQgb3B0aW9ucyB0aGF0IGFmZmVjdCB0aGlzIDx0dD5Ob3JtYWxpemVyPC90dD4ncyBvcGVyYXRpb24uCiAgICogT3B0aW9ucyBkbyBub3QgY2hhbmdlIHRoZSBiYXNpYyBjb21wb3NpdGlvbiBvciBkZWNvbXBvc2l0aW9uIG9wZXJhdGlvbgogICAqIHRoYXQgaXMgYmVpbmcgcGVyZm9ybWVkICwgYnV0IHRoZXkgY29udHJvbCB3aGV0aGVyCiAgICogY2VydGFpbiBvcHRpb25hbCBwb3J0aW9ucyBvZiB0aGUgb3BlcmF0aW9uIGFyZSBkb25lLgogICAqIEN1cnJlbnRseSB0aGUgb25seSBhdmFpbGFibGUgb3B0aW9uIGlzOgogICAqIDxwPgogICAqIDx1bD4KICAgKiAgIDxsaT57QGxpbmsgI0lHTk9SRV9IQU5HVUx9IC0gRG8gbm90IGRlY29tcG9zZSBIYW5ndWwgc3lsbGFibGVzIGludG8gdGhlCiAgICogICAgICAgSmFtbyBhbHBoYWJldCBhbmQgdmljZS12ZXJzYS4gIFRoaXMgb3B0aW9uIGlzIG9mZiBieSBkZWZhdWx0IAogICAqICAgICAgICg8aT5pLmUuPC9pPiBIYW5ndWwgcHJvY2Vzc2luZyBpcyBlbmFibGVkKSBzaW5jZSB0aGUgVW5pY29kZSAKICAgKiAgICAgICBzdGFuZGFyZCBzcGVjaWZpZXMgdGhhdCBIYW5ndWwgdG8gSmFtbyBpcyBhIGNhbm9uaWNhbCBkZWNvbXBvc2l0aW9uLgogICAqICAgICAgIEZvciBhbnkgb2YgdGhlIHN0YW5kYXJkIFVuaWNvZGUgTm9ybWFsaXphdGlvbgogICAqICAgICAgIEZvcm1zLCB5b3Ugc2hvdWxkIGxlYXZlIHRoaXMgb3B0aW9uIG9mZi4KICAgKiA8L3VsPgogICAqIDxwPgogICAqIEBwYXJhbSAgIG9wdGlvbiAgdGhlIG9wdGlvbiB3aG9zZSB2YWx1ZSBpcyB0byBiZSBzZXQuCiAgICogQHBhcmFtICAgdmFsdWUgICB0aGUgbmV3IHNldHRpbmcgZm9yIHRoZSBvcHRpb24uICBVc2UgPHR0PnRydWU8L3R0PiB0bwogICAqICAgICAgICAgICAgICAgICAgdHVybiB0aGUgb3B0aW9uIG9uIGFuZCA8dHQ+ZmFsc2U8L3R0PiB0byB0dXJuIGl0IG9mZi4KICAgKgogICAqIEBzZWUgI2dldE9wdGlvbgogICAqIEBzdGFibGUKICAgKi8KICB2b2lkIHNldE9wdGlvbihpbnQzMl90IG9wdGlvbiwgCiAgICAgICAgIFVCb29sIHZhbHVlKTsKCiAgLyoqCiAgICogRGV0ZXJtaW5lIHdoZXRoZXIgYW4gb3B0aW9uIGlzIHR1cm5lZCBvbiBvciBvZmYuCiAgICogPHA+CiAgICogQHNlZSAjc2V0T3B0aW9uCiAgICogQHN0YWJsZQogICAqLwogIFVCb29sIGdldE9wdGlvbihpbnQzMl90IG9wdGlvbikgY29uc3Q7CgogIC8qKgogICAqIFNldCB0aGUgaW5wdXQgdGV4dCBvdmVyIHdoaWNoIHRoaXMgPHR0Pk5vcm1hbGl6ZXI8L3R0PiB3aWxsIGl0ZXJhdGUuCiAgICogVGhlIGl0ZXJhdGlvbiBwb3NpdGlvbiBpcyBzZXQgdG8gdGhlIGJlZ2lubmluZy4KICAgKiBAc3RhYmxlCiAgICovCiAgdm9pZCBzZXRUZXh0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIG5ld1RleHQsIAogICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cyk7CgogIC8qKgogICAqIFNldCB0aGUgaW5wdXQgdGV4dCBvdmVyIHdoaWNoIHRoaXMgPHR0Pk5vcm1hbGl6ZXI8L3R0PiB3aWxsIGl0ZXJhdGUuCiAgICogVGhlIGl0ZXJhdGlvbiBwb3NpdGlvbiBpcyBzZXQgdG8gdGhlIGJlZ2lubmluZy4KICAgKiBAc3RhYmxlCiAgICovCiAgdm9pZCBzZXRUZXh0KGNvbnN0IENoYXJhY3Rlckl0ZXJhdG9yJiBuZXdUZXh0LCAKICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpOwoKICAvKioKICAgKiBTZXQgdGhlIGlucHV0IHRleHQgb3ZlciB3aGljaCB0aGlzIDx0dD5Ob3JtYWxpemVyPC90dD4gd2lsbCBpdGVyYXRlLgogICAqIFRoZSBpdGVyYXRpb24gcG9zaXRpb24gaXMgc2V0IHRvIHRoZSBiZWdpbm5pbmcuCiAgICogQHN0YWJsZQogICAqLwogIHZvaWQgc2V0VGV4dChjb25zdCBVQ2hhciogbmV3VGV4dCwKICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxlbmd0aCwKICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKTsKICAvKioKICAgKiBDb3BpZXMgdGhlIHRleHQgdW5kZXIgaXRlcmF0aW9uIGludG8gdGhlIFVuaWNvZGVTdHJpbmcgcmVmZXJyZWQgdG8gYnkgCiAgICogInJlc3VsdCIuCiAgICogQHBhcmFtIHJlc3VsdCBSZWNlaXZlcyBhIGNvcHkgb2YgdGhlIHRleHQgdW5kZXIgaXRlcmF0aW9uLgogICAqIEBkcmFmdCBzaG91bGQgYWxzbyByZXR1cm4gdGhlIHJlc3VsdCBVbmljb2RlU3RyaW5nICYKICAgKi8KICB2b2lkICAgICAgICAgICAgZ2V0VGV4dChVbmljb2RlU3RyaW5nJiAgcmVzdWx0KTsKCiAgLyoqCiAgICogUmV0dXJucyB0aGUgdGV4dCB1bmRlciBpdGVyYXRpb24gaW50byB0aGUgVUNoYXIqIGJ1ZmZlciBwb2ludGVyLgogICAqIEBwYXJhbSByZXN1bHQgUmVjZWl2ZXMgYSBjb3B5IG9mIHRoZSB0ZXh0IHVuZGVyIGl0ZXJhdGlvbi4KICAgKiBAdW5pbXBsZW1lbnRlZAogICAqLwogIGNvbnN0IFVDaGFyKiAgICAgZ2V0VGV4dChpbnQzMl90JiAgY291bnQpOwoKcHJpdmF0ZToKICAvLyBQcml2YXRlIHV0aWxpdHkgbWV0aG9kcyBmb3IgaXRlcmF0aW9uCiAgLy8gRm9yIGRvY3VtZW50YXRpb24sIHNlZSB0aGUgc291cmNlIGNvZGUKICBVQ2hhciBuZXh0Q29tcG9zZSh2b2lkKTsKICBVQ2hhciBwcmV2Q29tcG9zZSh2b2lkKTsKICBVQ2hhciBuZXh0RGVjb21wKHZvaWQpOwogIFVDaGFyIHByZXZEZWNvbXAodm9pZCk7CgogIFVDaGFyIGN1ckZvcndhcmQodm9pZCk7CiAgVUNoYXIgY3VyQmFja3dhcmQodm9pZCk7CgogIHZvaWQgICAgaW5pdChDaGFyYWN0ZXJJdGVyYXRvciogaXRlciwgCiAgICAgICAgIEVNb2RlIG1vZGUsIAogICAgICAgICBpbnQzMl90IG9wdGlvbik7CiAgdm9pZCAgICBpbml0QnVmZmVyKHZvaWQpOwogIHZvaWQgICAgY2xlYXJCdWZmZXIodm9pZCk7CgogIC8vIFV0aWxpdGllcyB1c2VkIGJ5IENvbXBvc2UKICBzdGF0aWMgdm9pZCAgICAgICAgYnViYmxlQXBwZW5kKFVuaWNvZGVTdHJpbmcmIHRhcmdldCwgCiAgICAgICAgICAgICAgICAgICAgIFVDaGFyIGNoLCAKICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgY2NsYXNzKTsKICBzdGF0aWMgdWludDMyX3QgICAgIGdldENvbXBvc2VDbGFzcyhVQ2hhciBjaCk7CiAgc3RhdGljIHVpbnQxNl90ICAgIGNvbXBvc2VMb29rdXAoVUNoYXIgY2gpOwogIHN0YXRpYyB1aW50MTZfdCAgICBjb21wb3NlQWN0aW9uKHVpbnQxNl90IGJhc2VJbmRleCwgCiAgICAgICAgICAgICAgICAgICAgICB1aW50MTZfdCBjb21JbmRleCk7CiAgc3RhdGljIHZvaWQgICAgICAgIGV4cGxvZGUoVW5pY29kZVN0cmluZyYgdGFyZ2V0LCAKICAgICAgICAgICAgICAgIHVpbnQxNl90IGluZGV4KTsKICBzdGF0aWMgVUNoYXIgICAgcGFpckV4cGxvZGUoVW5pY29kZVN0cmluZyYgdGFyZ2V0LCAKICAgICAgICAgICAgICAgICAgICB1aW50MTZfdCBhY3Rpb24pOwoKICAvLyBVdGlsaXRpZXMgdXNlZCBieSBEZWNvbXBvc2UKICBzdGF0aWMgdm9pZCAgICAgICAgZml4Q2Fub25pY2FsKFVuaWNvZGVTdHJpbmcmIHJlc3VsdCk7ICAgIC8vIFJlb3JkZXJzIGNvbWJpbmluZyBtYXJrcwogIHN0YXRpYyB1aW50OF90ICAgIGdldENsYXNzKFVDaGFyIGNoKTsgICAgICAgICAgICAgICAgICAgIC8vIEdldHMgY2hhcidzIGNvbWJpbmluZyBjbGFzcwoKICAvLyBPdGhlciBzdGF0aWMgdXRpbGl0eSBtZXRob2RzCiAgc3RhdGljIHZvaWQgZG9BcHBlbmQoY29uc3QgVUNoYXIgc291cmNlW10sIAogICAgICAgICAgICAgICB1aW50MTZfdCBvZmZzZXQsIAogICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiBkZXN0KTsKICBzdGF0aWMgdm9pZCBkb0luc2VydChjb25zdCBVQ2hhciBzb3VyY2VbXSwgCiAgICAgICAgICAgICAgIHVpbnQxNl90IG9mZnNldCwgCiAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIGRlc3QsIAogICAgICAgICAgICAgICBVVGV4dE9mZnNldCBwb3MpOwogIHN0YXRpYyB1aW50MTZfdCBkb1JlcGxhY2UoY29uc3QgVUNoYXIgc291cmNlW10sIAogICAgICAgICAgICAgICB1aW50MTZfdCBvZmZzZXQsIAogICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiBkZXN0LCAKICAgICAgICAgICAgICAgVVRleHRPZmZzZXQgcG9zKTsKCiAgc3RhdGljIHZvaWQgaGFuZ3VsVG9KYW1vKFVDaGFyIGNoLCAKICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgcmVzdWx0LCAKICAgICAgICAgICAgICAgdWludDE2X3QgZGVjb21wTGltaXQpOwogIHN0YXRpYyB2b2lkIGphbW9BcHBlbmQoVUNoYXIgY2gsIAogICAgICAgICAgICAgdWludDE2X3QgZGVjb21wTGltaXQsIAogICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgZGVzdCk7CiAgc3RhdGljIHZvaWQgamFtb1RvSGFuZ3VsKFVuaWNvZGVTdHJpbmcmIGJ1ZmZlciwgCiAgICAgICAgICAgICAgIFVUZXh0T2Zmc2V0IHN0YXJ0KTsKCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gUHJpdmF0ZSBkYXRhCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIEVNb2RlICAgICAgICAgZk1vZGU7CiAgaW50MzJfdCAgICAgICBmT3B0aW9uczsKICBpbnQxNl90ICAgIG1pbkRlY29tcDsKCiAgLy8gVGhlIGlucHV0IHRleHQgYW5kIG91ciBwb3NpdGlvbiBpbiBpdAogIENoYXJhY3Rlckl0ZXJhdG9yKiAgdGV4dDsKCiAgLy8gQSBidWZmZXIgZm9yIGhvbGRpbmcgaW50ZXJtZWRpYXRlIHJlc3VsdHMKICBVbmljb2RlU3RyaW5nICAgICAgIGJ1ZmZlcjsKICBVVGV4dE9mZnNldCAgICAgICAgICBidWZmZXJQb3M7CiAgVVRleHRPZmZzZXQgICAgICAgICAgYnVmZmVyTGltaXQ7CiAgVUNoYXIgICAgICAgICAgICAgY3VycmVudENoYXI7CgogIC8vIEFub3RoZXIgYnVmZmVyIGZvciB1c2UgZHVyaW5nIGl0ZXJhdGl2ZSBjb21wb3NpdGlvbgogIFVuaWNvZGVTdHJpbmcgICAgICAgZXhwbG9kZUJ1ZjsKCiAgZW51bSB7CiAgICBFTVBUWSA9IC0xLAogICAgU1RSX0lOREVYX1NISUZUID0gMiwgLy9NdXN0IGFncmVlIHdpdGggdGhlIGNvbnN0YW50cyB1c2VkIGluIE5vcm1hbGl6ZXJCdWlsZGVyCiAgICBTVFJfTEVOR1RIX01BU0sgPSAweDAwMDMKICB9OwoKICBlbnVtIHsKICAgIEhBTkdVTF9CQVNFID0gMHhhYzAwLAogICAgSEFOR1VMX0xJTUlUID0gMHhkN2E0LAogICAgSkFNT19MQkFTRSA9IDB4MTEwMCwKICAgIEpBTU9fVkJBU0UgPSAweDExNjEsCiAgICBKQU1PX1RCQVNFID0gMHgxMWE3LAogICAgSkFNT19MQ09VTlQgPSAxOSwKICAgIEpBTU9fVkNPVU5UID0gMjEsCiAgICBKQU1PX1RDT1VOVCA9IDI4LAogICAgSkFNT19OQ09VTlQgPSBKQU1PX1ZDT1VOVCAqIEpBTU9fVENPVU5UCiAgfTsKCiAgZnJpZW5kIGNsYXNzIENvbXBvc2VkQ2hhckl0ZXI7Cn07CgppbmxpbmUgVUJvb2wKTm9ybWFsaXplcjo6b3BlcmF0b3IhPSAoY29uc3QgTm9ybWFsaXplciYgb3RoZXIpIGNvbnN0CnsgcmV0dXJuICEgb3BlcmF0b3I9PShvdGhlcik7IH0KCmlubGluZSBVTm9ybWFsaXphdGlvbk1vZGUgTm9ybWFsaXplcjo6Z2V0VU5vcm1hbGl6YXRpb25Nb2RlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlICBtb2RlLCBVRXJyb3JDb2RlICZzdGF0dXMpCnsKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpCiAgeyAKICAgIHN3aXRjaCAobW9kZSkKICAgIHsKICAgIGNhc2UgTm9ybWFsaXplcjo6Tk9fT1AgOiAKICAgICAgcmV0dXJuIFVOT1JNX05PTkU7CiAgICBjYXNlIE5vcm1hbGl6ZXI6OkNPTVBPU0UgOgogICAgICByZXR1cm4gVU5PUk1fTkZDOwogICAgY2FzZSBOb3JtYWxpemVyOjpDT01QT1NFX0NPTVBBVCA6CiAgICAgIHJldHVybiBVTk9STV9ORktDOwogICAgY2FzZSBOb3JtYWxpemVyOjpERUNPTVAgOgogICAgICByZXR1cm4gVU5PUk1fTkZEOwogICAgY2FzZSBOb3JtYWxpemVyOjpERUNPTVBfQ09NUEFUIDoKICAgICAgcmV0dXJuIFVOT1JNX05GS0Q7CiAgICBkZWZhdWx0IDogCiAgICAgIHN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsgCiAgICB9CiAgfQogIHJldHVybiBVTk9STV9ERUZBVUxUOwp9CgppbmxpbmUgTm9ybWFsaXplcjo6RU1vZGUgTm9ybWFsaXplcjo6Z2V0Tm9ybWFsaXplckVNb2RlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVU5vcm1hbGl6YXRpb25Nb2RlIG1vZGUsIFVFcnJvckNvZGUgJnN0YXR1cykKewogIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkKICB7CiAgICBzd2l0Y2ggKG1vZGUpCiAgICB7CiAgICBjYXNlIFVOT1JNX05PTkUgOgogICAgICByZXR1cm4gTm9ybWFsaXplcjo6Tk9fT1A7CiAgICBjYXNlIFVOT1JNX05GRCA6CiAgICAgIHJldHVybiBOb3JtYWxpemVyOjpERUNPTVA7CiAgICBjYXNlIFVOT1JNX05GS0QgOgogICAgICByZXR1cm4gTm9ybWFsaXplcjo6REVDT01QX0NPTVBBVDsKICAgIGNhc2UgVU5PUk1fTkZDIDoKICAgICAgcmV0dXJuIE5vcm1hbGl6ZXI6OkNPTVBPU0U7CiAgICBjYXNlIFVOT1JNX05GS0MgOgogICAgICByZXR1cm4gTm9ybWFsaXplcjo6Q09NUE9TRV9DT01QQVQ7CiAgICBkZWZhdWx0IDogCiAgICAgIHN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsgCiAgICB9CiAgfQogIHJldHVybiBOb3JtYWxpemVyOjpERUNPTVBfQ09NUEFUOwp9CgojZW5kaWYgLy8gX05PUk1MWlIK