LyoKKiBDb3B5cmlnaHQgqSB7MTk5Ny0xOTk5fSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqCiogRmlsZSBUSU1FWk9ORS5ICioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDA0LzIxLzk3ICAgIGFsaXUgICAgICAgIE92ZXJoYXVsZWQgaGVhZGVyLgoqICAgMDcvMDkvOTcgICAgaGVsZW5hICAgICAgQ2hhbmdlZCBjcmVhdGVJbnN0YW5jZSB0byBjcmVhdGVEZWZhdWx0LgoqICAgMDgvMDYvOTcgICAgYWxpdSAgICAgICAgUmVtb3ZlZCBkZXBlbmRlbmN5IG9uIGludGVybmFsIGhlYWRlciBmb3IgSGFzaHRhYmxlLgoqICAgIDA4LzEwLzk4ICAgIHN0ZXBoZW4gICAgICAgIENoYW5nZWQgZ2V0RGlzcGxheU5hbWUoKSBBUEkgY29udmVudGlvbnMgdG8gbWF0Y2gKKiAgICAwOC8xOS85OCAgICBzdGVwaGVuICAgICAgICBDaGFuZ2VkIGNyZWF0ZVRpbWVab25lKCkgdG8gbmV2ZXIgcmV0dXJuIDAKKiAgICAwOS8wMi85OCAgICBzdGVwaGVuICAgICAgICBTeW5jIHRvIEpESyAxLjIgOC8zMQoqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIEFkZGVkIGdldE9mZnNldCguLi4gbW9udGhsZW4gLi4uKQoqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIEFkZGVkIGhhc1NhbWVSdWxlcygpCiogICAgMDkvMTUvOTggICAgc3RlcGhlbiAgICAgICAgQWRkZWQgZ2V0U3RhdGljQ2xhc3NJRAoqICAxMi8wMy85OSAgICAgYWxpdSAgICAgICAgTW92ZWQgZGF0YSBvdXQgb2Ygc3RhdGljIHRhYmxlIGludG8gaWN1ZGF0YS5kbGwuCiogICAgICAgICAgICAgICAgICAgICAgICAgICBIYXNodGFibGUgcmVwbGFjZWQgYnkgbmV3IHN0YXRpYyBkYXRhIHN0cnVjdHVyZXMuCiogIDEyLzE0Lzk5ICAgICBhbGl1ICAgICAgICBNYWRlIEdNVCBwdWJsaWMuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCgojaWZuZGVmIFRJTUVaT05FX0gKI2RlZmluZSBUSU1FWk9ORV9ICgoKI2luY2x1ZGUgInVuaWNvZGUvdW5pc3RyLmgiCiNpbmNsdWRlICJ1bmljb2RlL2xvY2lkLmgiCgojaW5jbHVkZSAidW5pY29kZS91ZGF0YS5oIgoKY2xhc3MgU2ltcGxlVGltZVpvbmU7CnN0cnVjdCBUWkhlYWRlcjsKc3RydWN0IE9mZnNldEluZGV4OwogIAovKioKICogPGNvZGU+VGltZVpvbmU8L2NvZGU+IHJlcHJlc2VudHMgYSB0aW1lIHpvbmUgb2Zmc2V0LCBhbmQgYWxzbyBmaWd1cmVzIG91dCBkYXlsaWdodAogKiBzYXZpbmdzLgogKgogKiA8cD4KICogVHlwaWNhbGx5LCB5b3UgZ2V0IGEgPGNvZGU+VGltZVpvbmU8L2NvZGU+IHVzaW5nIDxjb2RlPmNyZWF0ZURlZmF1bHQ8L2NvZGU+CiAqIHdoaWNoIGNyZWF0ZXMgYSA8Y29kZT5UaW1lWm9uZTwvY29kZT4gYmFzZWQgb24gdGhlIHRpbWUgem9uZSB3aGVyZSB0aGUgcHJvZ3JhbQogKiBpcyBydW5uaW5nLiBGb3IgZXhhbXBsZSwgZm9yIGEgcHJvZ3JhbSBydW5uaW5nIGluIEphcGFuLCA8Y29kZT5jcmVhdGVEZWZhdWx0PC9jb2RlPgogKiBjcmVhdGVzIGEgPGNvZGU+VGltZVpvbmU8L2NvZGU+IG9iamVjdCBiYXNlZCBvbiBKYXBhbmVzZSBTdGFuZGFyZCBUaW1lLgogKgogKiA8cD4KICogWW91IGNhbiBhbHNvIGdldCBhIDxjb2RlPlRpbWVab25lPC9jb2RlPiB1c2luZyA8Y29kZT5jcmVhdGVUaW1lWm9uZTwvY29kZT4gYWxvbmcKICogd2l0aCBhIHRpbWUgem9uZSBJRC4gRm9yIGluc3RhbmNlLCB0aGUgdGltZSB6b25lIElEIGZvciB0aGUgUGFjaWZpYwogKiBTdGFuZGFyZCBUaW1lIHpvbmUgaXMgIlBTVCIuIFNvLCB5b3UgY2FuIGdldCBhIFBTVCA8Y29kZT5UaW1lWm9uZTwvY29kZT4gb2JqZWN0CiAqIHdpdGg6CiAqIDxibG9ja3F1b3RlPgogKiA8cHJlPgogKiBUaW1lWm9uZSAqdHogPSBUaW1lWm9uZTo6Y3JlYXRlVGltZVpvbmUoIlBTVCIpOwogKiA8L3ByZT4KICogPC9ibG9ja3F1b3RlPgogKiBZb3UgY2FuIHVzZSA8Y29kZT5nZXRBdmFpbGFibGVJRHM8L2NvZGU+IG1ldGhvZCB0byBpdGVyYXRlIHRocm91Z2gKICogYWxsIHRoZSBzdXBwb3J0ZWQgdGltZSB6b25lIElEcy4gWW91IGNhbiB0aGVuIGNob29zZSBhCiAqIHN1cHBvcnRlZCBJRCB0byBnZXQgYSA8Y29kZT5UaW1lWm9uZTwvY29kZT4uCiAqIElmIHRoZSB0aW1lIHpvbmUgeW91IHdhbnQgaXMgbm90IHJlcHJlc2VudGVkIGJ5IG9uZSBvZiB0aGUKICogc3VwcG9ydGVkIElEcywgdGhlbiB5b3UgY2FuIGNyZWF0ZSBhIGN1c3RvbSB0aW1lIHpvbmUgSUQgd2l0aAogKiB0aGUgZm9sbG93aW5nIHN5bnRheDoKICoKICogPGJsb2NrcXVvdGU+CiAqIDxwcmU+CiAqIEdNVFsrfC1daGhbWzpdbW1dCiAqIDwvcHJlPgogKiA8L2Jsb2NrcXVvdGU+CiAqCiAqIEZvciBleGFtcGxlLCB5b3UgbWlnaHQgc3BlY2lmeSBHTVQrMTQ6MDAgYXMgYSBjdXN0b20KICogdGltZSB6b25lIElELiAgVGhlIDxjb2RlPlRpbWVab25lPC9jb2RlPiB0aGF0IGlzIHJldHVybmVkCiAqIHdoZW4geW91IHNwZWNpZnkgYSBjdXN0b20gdGltZSB6b25lIElEIGRvZXMgbm90IGluY2x1ZGUKICogZGF5bGlnaHQgc2F2aW5ncyB0aW1lLgogKgoKICAKICogVGltZVpvbmUgaXMgYW4gYWJzdHJhY3QgY2xhc3MgcmVwcmVzZW50aW5nIGEgdGltZSB6b25lLiAgQSBUaW1lWm9uZSBpcyBuZWVkZWQgZm9yCiAqIENhbGVuZGFyIHRvIHByb2R1Y2UgbG9jYWwgdGltZSBmb3IgYSBwYXJ0aWN1bGFyIHRpbWUgem9uZS4gIEEgVGltZVpvbmUgY29tcHJpc2VzCiAqIHRocmVlIGJhc2ljIHBpZWNlcyBvZiBpbmZvcm1hdGlvbjo8dWw+CiAqICAgIDxsaT5BIHRpbWUgem9uZSBvZmZzZXQ7IHRoYXQsIGlzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGFkZCBvciBzdWJ0cmFjdAogKiAgICAgIGZyb20gYSB0aW1lIGV4cHJlc3NlZCBpbiB0ZXJtcyBvZiBHTVQgdG8gY29udmVydCBpdCB0byB0aGUgc2FtZSB0aW1lIGluIHRoYXQKICogICAgICB0aW1lIHpvbmUgKHdpdGhvdXQgdGFraW5nIGRheWxpZ2h0IHNhdmluZ3MgdGltZSBpbnRvIGFjY291bnQpLgogKiAgICA8bGk+TG9naWMgbmVjZXNzYXJ5IHRvIHRha2UgZGF5bGlnaHQgc2F2aW5ncyB0aW1lIGludG8gYWNjb3VudCBpZiBkYXlsaWdodCBzYXZpbmdzCiAqICAgICAgdGltZSBpcyBvYnNlcnZlZCBpbiB0aGF0IHRpbWUgem9uZSAoZS5nLiwgdGhlIGRheXMgYW5kIGhvdXJzIG9uIHdoaWNoIGRheWxpZ2h0CiAqICAgICAgc2F2aW5ncyB0aW1lIGJlZ2lucyBhbmQgZW5kcykuCiAqICAgIDxsaT5BbiBJRC4gIFRoaXMgaXMgYSB0ZXh0IHN0cmluZyB0aGF0IHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhlIHRpbWUgem9uZS48L3VsPgogKgogKiAoT25seSB0aGUgSUQgaXMgYWN0dWFsbHkgaW1wbGVtZW50ZWQgaW4gVGltZVpvbmU7IHN1YmNsYXNzZXMgb2YgVGltZVpvbmUgbWF5IGhhbmRsZQogKiBkYXlsaWdodCBzYXZpbmdzIHRpbWUgYW5kIEdNVCBvZmZzZXQgaW4gZGlmZmVyZW50IHdheXMuICBDdXJyZW50bHkgd2Ugb25seSBoYXZlIG9uZQogKiBUaW1lWm9uZSBzdWJjbGFzczogU2ltcGxlVGltZVpvbmUuKQogKiA8UD4KICogVGhlIFRpbWVab25lIGNsYXNzIGNvbnRhaW5zIGEgc3RhdGljIGxpc3QgY29udGFpbmluZyBhIFRpbWVab25lIG9iamVjdCBmb3IgZXZlcnkKICogY29tYmluYXRpb24gb2YgR01UIG9mZnNldCBhbmQgZGF5bGlnaHQtc2F2aW5ncyB0aW1lIHJ1bGVzIGN1cnJlbnRseSBpbiB1c2UgaW4gdGhlCiAqIHdvcmxkLCBlYWNoIHdpdGggYSB1bmlxdWUgSUQuICBFYWNoIElEIGNvbnNpc3RzIG9mIGEgcmVnaW9uICh1c3VhbGx5IGEgY29udGluZW50IG9yCiAqIG9jZWFuKSBhbmQgYSBjaXR5IGluIHRoYXQgcmVnaW9uLCBzZXBhcmF0ZWQgYnkgYSBzbGFzaCwgKGZvciBleGFtcGxlLCBQYWNpZmljCiAqIFN0YW5kYXJkIFRpbWUgaXMgIkFtZXJpY2EvTG9zX0FuZ2VsZXMuIikgIEJlY2F1c2Ugb2xkZXIgdmVyc2lvbnMgb2YgdGhpcyBjbGFzcyB1c2VkCiAqIHRocmVlLSBvciBmb3VyLWxldHRlciBhYmJyZXZpYXRpb25zIGluc3RlYWQsIHRoZXJlIGlzIGFsc28gYSB0YWJsZSB0aGF0IG1hcHMgdGhlIG9sZGVyCiAqIGFiYnJldmlhdGlvbnMgdG8gdGhlIG5ld2VyIG9uZXMgKGZvciBleGFtcGxlLCAiUFNUIiBtYXBzIHRvICJBbWVyaWNhL0xvc0FuZ2VsZXMiKS4KICogQW55d2hlcmUgdGhlIEFQSSByZXF1aXJlcyBhbiBJRCwgeW91IGNhbiB1c2UgZWl0aGVyIGZvcm0uCiAqIDxQPgogKiBUbyBjcmVhdGUgYSBuZXcgVGltZVpvbmUsIHlvdSBjYWxsIHRoZSBmYWN0b3J5IGZ1bmN0aW9uIFRpbWVab25lOjpjcmVhdGVUaW1lWm9uZSgpCiAqIGFuZCBwYXNzIGl0IGEgdGltZSB6b25lIElELiAgWW91IGNhbiB1c2UgdGhlIGNyZWF0ZUF2YWlsYWJsZUlEcygpIGZ1bmN0aW9uIHRvCiAqIG9idGFpbiBhIGxpc3Qgb2YgYWxsIHRoZSB0aW1lIHpvbmUgSURzIHJlY29nbml6ZWQgYnkgY3JlYXRlVGltZVpvbmUoKS4KICogPFA+CiAqIFlvdSBjYW4gYWxzbyB1c2UgVGltZVpvbmU6OmNyZWF0ZURlZmF1bHQoKSB0byBjcmVhdGUgYSBUaW1lWm9uZS4gIFRoaXMgZnVuY3Rpb24gdXNlcwogKiBwbGF0Zm9ybS1zcGVjaWZpYyBBUElzIHRvIHByb2R1Y2UgYSBUaW1lWm9uZSBmb3IgdGhlIHRpbWUgem9uZSBjb3JyZXNwb25kaW5nIHRvIAogKiB0aGUgY2xpZW50J3MgY29tcHV0ZXIncyBwaHlzaWNhbCBsb2NhdGlvbi4gIEZvciBleGFtcGxlLCBpZiB5b3UncmUgaW4gSmFwYW4gKGFzc3VtaW5nCiAqIHlvdXIgbWFjaGluZSBpcyBzZXQgdXAgY29ycmVjdGx5KSwgVGltZVpvbmU6OmNyZWF0ZURlZmF1bHQoKSB3aWxsIHJldHVybiBhIFRpbWVab25lCiAqIGZvciBKYXBhbmVzZSBTdGFuZGFyZCBUaW1lICgiQXNpYS9Ub2t5byIpLgogKi8KY2xhc3MgVV9JMThOX0FQSSBUaW1lWm9uZSB7CnB1YmxpYzoKICAgIC8qKgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIH5UaW1lWm9uZSgpOwoKICAgIC8qKgogICAgICogVGhlIEdNVCB6b25lIGhhcyBhIHJhdyBvZmZzZXQgb2YgemVybyBhbmQgZG9lcyBub3QgdXNlIGRheWxpZ2h0CiAgICAgKiBzYXZpbmdzIHRpbWUuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBUaW1lWm9uZSogR01UOwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIDxjb2RlPlRpbWVab25lPC9jb2RlPiBmb3IgdGhlIGdpdmVuIElELgogICAgICogQHBhcmFtIElEIHRoZSBJRCBmb3IgYSA8Y29kZT5UaW1lWm9uZTwvY29kZT4sIGVpdGhlciBhbiBhYmJyZXZpYXRpb24gc3VjaCBhcwogICAgICogIlBTVCIsIGEgZnVsbCBuYW1lIHN1Y2ggYXMgIkFtZXJpY2EvTG9zX0FuZ2VsZXMiLCBvciBhIGN1c3RvbSBJRAogICAgICogc3VjaCBhcyAiR01ULTg6MDAiLgogICAgICogQHJldHVybiB0aGUgc3BlY2lmaWVkIDxjb2RlPlRpbWVab25lPC9jb2RlPiwgb3IgdGhlIEdNVCB6b25lIGlmIHRoZSBnaXZlbiBJRAogICAgICogY2Fubm90IGJlIHVuZGVyc3Rvb2QuICBSZXR1cm4gcmVzdWx0IGd1YXJhbnRlZWQgdG8gYmUgbm9uLW51bGwuICBJZiB5b3UKICAgICAqIHJlcXVpcmUgdGhhdCB0aGUgc3BlY2lmaWMgem9uZSBhc2tlZCBmb3IgYmUgcmV0dXJuZWQsIGNoZWNrIHRoZSBJRCBvZiB0aGUKICAgICAqIHJldHVybiByZXN1bHQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyBUaW1lWm9uZSogY3JlYXRlVGltZVpvbmUoY29uc3QgVW5pY29kZVN0cmluZyYgSUQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGxpc3Qgb2YgdGltZSB6b25lIElEcywgb25lIGZvciBlYWNoIHRpbWUgem9uZSB3aXRoIGEgZ2l2ZW4gR01UIG9mZnNldC4KICAgICAqIFRoZSByZXR1cm4gdmFsdWUgaXMgYSBsaXN0IGJlY2F1c2UgdGhlcmUgbWF5IGJlIHNldmVyYWwgdGltZXMgem9uZXMgd2l0aCB0aGUgc2FtZQogICAgICogR01UIG9mZnNldCB0aGF0IGRpZmZlciBpbiB0aGUgd2F5IHRoZXkgaGFuZGxlIGRheWxpZ2h0IHNhdmluZ3MgdGltZS4gIEZvciBleGFtcGxlLAogICAgICogdGhlIHN0YXRlIG9mIEFyaXpvbmEgZG9lc24ndCBvYnNlcnZlIERheWxpZ2h0IFNhdmluZ3MgdGltZS4gIFNvIGlmIHlvdSBhc2sgZm9yCiAgICAgKiB0aGUgdGltZSB6b25lIElEcyBjb3JyZXNwb25kaW5nIHRvIEdNVC03OjAwLCB5b3UnbGwgZ2V0IGJhY2sgdHdvIHRpbWUgem9uZSBJRHM6CiAgICAgKiAiQW1lcmljYS9EZW52ZXIsIiB3aGljaCBjb3JyZXNwb25kcyB0byBNb3VudGFpbiBTdGFuZGFyZCBUaW1lIGluIHRoZSB3aW50ZXIgYW5kCiAgICAgKiBNb3VudGFpbiBEYXlsaWdodCBUaW1lIGluIHRoZSBzdW1tZXIsIGFuZCAiQW1lcmljYS9QaG9lbml4Iiwgd2hpY2ggY29ycmVzcG9uZHMgdG8KICAgICAqIE1vdW50YWluIFN0YW5kYXJkIFRpbWUgeWVhci1yb3VuZCwgZXZlbiBpbiB0aGUgc3VtbWVyLgogICAgICogPFA+CiAgICAgKiBUaGUgY2FsbGVyIG93bnMgdGhlIGxpc3QgdGhhdCBpcyByZXR1cm5lZCwgYnV0IGRvZXMgbm90IG93biB0aGUgc3RyaW5ncyBjb250YWluZWQKICAgICAqIGluIHRoYXQgbGlzdC4gIERlbGV0ZSB0aGUgYXJyYXksIGJ1dCBET04nVCBkZWxldGUgdGhlIGVsZW1lbnRzIGluIHRoZSBhcnJheS4KICAgICAqCiAgICAgKiBAcGFyYW0gcmF3T2Zmc2V0ICBBbiBvZmZzZXQgZnJvbSBHTVQgaW4gbWlsbGlzZWNvbmRzLgogICAgICogQHBhcmFtIG51bUlEcyAgICAgUmVjZWl2ZXMgdGhlIG51bWJlciBvZiBpdGVtcyBpbiB0aGUgYXJyYXkgdGhhdCBpcyByZXR1cm5lZC4KICAgICAqIEByZXR1cm4gICAgICAgICAgIEFuIGFycmF5IG9mIFVuaWNvZGVTdHJpbmcgcG9pbnRlcnMsIHdoZXJlIGVhY2ggVW5pY29kZVN0cmluZyBpcwogICAgICogICAgICAgICAgICAgICAgICAgYSB0aW1lIHpvbmUgSUQgZm9yIGEgdGltZSB6b25lIHdpdGggdGhlIGdpdmVuIEdNVCBvZmZzZXQuICBJZgogICAgICogICAgICAgICAgICAgICAgICAgdGhlcmUgaXMgbm8gdGltZXpvbmUgdGhhdCBtYXRjaGVzIHRoZSBHTVQgb2Zmc2V0CiAgICAgKiAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQsIE5VTEwgaXMgcmV0dXJuZWQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBVbmljb2RlU3RyaW5nKiogY29uc3QgY3JlYXRlQXZhaWxhYmxlSURzKGludDMyX3QgcmF3T2Zmc2V0LCBpbnQzMl90JiBudW1JRHMpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGxpc3Qgb2YgYWxsIHRpbWUgem9uZSBJRHMgc3VwcG9ydGVkIGJ5IHRoZSBUaW1lWm9uZSBjbGFzcyAoaS5lLiwgYWxsCiAgICAgKiBJRHMgdGhhdCBpdCdzIGxlZ2FsIHRvIHBhc3MgdG8gY3JlYXRlVGltZVpvbmUoKSkuICBUaGUgY2FsbGVyIG93bnMgdGhlIGxpc3QgdGhhdAogICAgICogaXMgcmV0dXJuZWQsIGJ1dCBkb2VzIG5vdCBvd24gdGhlIHN0cmluZ3MgY29udGFpbmVkIGluIHRoYXQgbGlzdC4gIERlbGV0ZSB0aGUgYXJyYXksCiAgICAgKiBidXQgRE9OJ1QgZGVsZXRlIHRoZSBlbGVtZW50cyBpbiB0aGUgYXJyYXkuCiAgICAgKgogICAgICogQHBhcmFtIG51bUlEcyAgUmVjZWl2ZXMgdGhlIG51bWJlciBvZiB6b25lIElEcyByZXR1cm5lZC4KICAgICAqIEByZXR1cm4gICAgICAgIEFuIGFycmF5IG9mIFVuaWNvZGVTdHJpbmcgcG9pbnRlcnMsIHdoZXJlIGVhY2ggaXMgYSB0aW1lIHpvbmUgSUQKICAgICAqICAgICAgICAgICAgICAgIHN1cHBvcnRlZCBieSB0aGUgVGltZVpvbmUgY2xhc3MuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBVbmljb2RlU3RyaW5nKiogY29uc3QgY3JlYXRlQXZhaWxhYmxlSURzKGludDMyX3QmIG51bUlEcyk7CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3IGNvcHkgb2YgdGhlIGRlZmF1bHQgVGltZVpvbmUgZm9yIHRoaXMgaG9zdC4gVW5sZXNzIHRoZSBkZWZhdWx0IHRpbWUKICAgICAqIHpvbmUgaGFzIGFscmVhZHkgYmVlbiBzZXQgdXNpbmcgYWRvcHREZWZhdWx0KCkgb3Igc2V0RGVmYXVsdCgpLCB0aGUgZGVmYXVsdCBpcwogICAgICogZGV0ZXJtaW5lZCBieSBxdWVyeWluZyB0aGUgc3lzdGVtIHVzaW5nIG1ldGhvZHMgaW4gVFBsYXRmb3JtVXRpbGl0aWVzLiBJZiB0aGUKICAgICAqIHN5c3RlbSByb3V0aW5lcyBmYWlsLCBvciBpZiB0aGV5IHNwZWNpZnkgYSBUaW1lWm9uZSBvciBUaW1lWm9uZSBvZmZzZXQgd2hpY2ggaXMgbm90CiAgICAgKiByZWNvZ25pemVkLCB0aGUgVGltZVpvbmUgaW5kaWNhdGVkIGJ5IHRoZSBJRCBrTGFzdFJlc29ydElEIGlzIGluc3RhbnRpYXRlZAogICAgICogYW5kIG1hZGUgdGhlIGRlZmF1bHQuCiAgICAgKgogICAgICogQHJldHVybiAgIEEgZGVmYXVsdCBUaW1lWm9uZS4gQ2xpZW50cyBhcmUgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIHRoZSB0aW1lIHpvbmUKICAgICAqICAgICAgICAgICBvYmplY3QgcmV0dXJuZWQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyBUaW1lWm9uZSogY3JlYXRlRGVmYXVsdCh2b2lkKTsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIGRlZmF1bHQgdGltZSB6b25lIChpLmUuLCB3aGF0J3MgcmV0dXJuZWQgYnkgZ2V0RGVmYXVsdCgpKSB0byBiZSB0aGUKICAgICAqIHNwZWNpZmllZCB0aW1lIHpvbmUuICBJZiBOVUxMIGlzIHNwZWNpZmllZCBmb3IgdGhlIHRpbWUgem9uZSwgdGhlIGRlZmF1bHQgdGltZQogICAgICogem9uZSBpcyBzZXQgdG8gdGhlIGRlZmF1bHQgaG9zdCB0aW1lIHpvbmUuICBUaGlzIGNhbGwgYWRvcHRzIHRoZSBUaW1lWm9uZSBvYmplY3QKICAgICAqIHBhc3NlZCBpbjsgdGhlIGNsZW50IGlzIG5vIGxvbmdlciByZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgaXQuCiAgICAgKgogICAgICogQHBhcmFtIHpvbmUgIEEgcG9pbnRlciB0byB0aGUgbmV3IFRpbWVab25lIG9iamVjdCB0byB1c2UgYXMgdGhlIGRlZmF1bHQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyB2b2lkIGFkb3B0RGVmYXVsdChUaW1lWm9uZSogem9uZSk7CgogICAgLyoqCiAgICAgKiBTYW1lIGFzIGFkb3B0RGVmYXVsdCgpLCBleGNlcHQgdGhhdCB0aGUgVGltZVpvbmUgb2JqZWN0IHBhc3NlZCBpbiBpcyBOT1QgYWRvcHRlZDsKICAgICAqIHRoZSBjYWxsZXIgcmVtYWlucyByZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgaXQuCiAgICAgKgogICAgICogQHBhcmFtIHpvbmUgIFRoZSBnaXZlbiB0aW1lem9uZS4KICAgICAqIEBzeXN0ZW0KICAgICAqLwogICAgc3RhdGljIHZvaWQgc2V0RGVmYXVsdChjb25zdCBUaW1lWm9uZSYgem9uZSk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHR3byBUaW1lWm9uZXMgYXJlIGVxdWFsLiAgKFRoZSBUaW1lWm9uZSB2ZXJzaW9uIG9ubHkgY29tcGFyZXMKICAgICAqIElEcywgYnV0IHN1YmNsYXNzZXMgYXJlIGV4cGVjdGVkIHRvIGFsc28gY29tcGFyZSB0aGUgZmllbGRzIHRoZXkgYWRkLikKICAgICAqCiAgICAgKiBAcGFyYW0gdGhhdCAgVGhlIFRpbWVab25lIG9iamVjdCB0byBiZSBjb21wYXJlZCB3aXRoLgogICAgICogQHJldHVybiAgICAgIFRydWUgaWYgdGhlIGdpdmVuIFRpbWVab25lIGlzIGVxdWFsIHRvIHRoaXMgVGltZVpvbmU7IGZhbHNlCiAgICAgKiAgICAgICAgICAgICAgb3RoZXJ3aXNlLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIFVCb29sIG9wZXJhdG9yPT0oY29uc3QgVGltZVpvbmUmIHRoYXQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSB0d28gVGltZVpvbmVzIGFyZSBOT1QgZXF1YWw7IHRoYXQgaXMsIGlmIG9wZXJhdG9yPT0oKSByZXR1cm5zCiAgICAgKiBmYWxzZS4KICAgICAqCiAgICAgKiBAcGFyYW0gdGhhdCAgVGhlIFRpbWVab25lIG9iamVjdCB0byBiZSBjb21wYXJlZCB3aXRoLgogICAgICogQHJldHVybiAgICAgIFRydWUgaWYgdGhlIGdpdmVuIFRpbWVab25lIGlzIG5vdCBlcXVhbCB0byB0aGlzIFRpbWVab25lOyBmYWxzZQogICAgICogICAgICAgICAgICAgIG90aGVyd2lzZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgVUJvb2wgb3BlcmF0b3IhPShjb25zdCBUaW1lWm9uZSYgdGhhdCkgY29uc3Qge3JldHVybiAhb3BlcmF0b3I9PSh0aGF0KTt9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBUaW1lWm9uZSdzIGFkanVzdGVkIEdNVCBvZmZzZXQgKGkuZS4sIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGFkZAogICAgICogdG8gR01UIHRvIGdldCBsb2NhbCB0aW1lIGluIHRoaXMgdGltZSB6b25lLCB0YWtpbmcgZGF5bGlnaHQgc2F2aW5ncyB0aW1lIGludG8KICAgICAqIGFjY291bnQpIGFzIG9mIGEgcGFydGljdWxhciByZWZlcmVuY2UgZGF0ZS4gIFRoZSByZWZlcmVuY2UgZGF0ZSBpcyB1c2VkIHRvIGRldGVybWluZQogICAgICogd2hldGhlciBkYXlsaWdodCBzYXZpbmdzIHRpbWUgaXMgaW4gZWZmZWN0IGFuZCBuZWVkcyB0byBiZSBmaWd1cmVkIGludG8gdGhlIG9mZnNldAogICAgICogdGhhdCBpcyByZXR1cm5lZCAoaW4gb3RoZXIgd29yZHMsIHdoYXQgaXMgdGhlIGFkanVzdGVkIEdNVCBvZmZzZXQgaW4gdGhpcyB0aW1lIHpvbmUKICAgICAqIGF0IHRoaXMgcGFydGljdWxhciBkYXRlIGFuZCB0aW1lPykuICBGb3IgdGhlIHRpbWUgem9uZXMgcHJvZHVjZWQgYnkgY3JlYXRlVGltZVpvbmUoKSwKICAgICAqIHRoZSByZWZlcmVuY2UgZGF0YSBpcyBzcGVjaWZpZWQgYWNjb3JkaW5nIHRvIHRoZSBHcmVnb3JpYW4gY2FsZW5kYXIsIGFuZCB0aGUgZGF0ZQogICAgICogYW5kIHRpbWUgZmllbGRzIGFyZSBpbiBHTVQsIE5PVCBsb2NhbCB0aW1lLgogICAgICoKICAgICAqIEBwYXJhbSBlcmEgICAgICAgIFRoZSByZWZlcmVuY2UgZGF0ZSdzIGVyYQogICAgICogQHBhcmFtIHllYXIgICAgICAgVGhlIHJlZmVyZW5jZSBkYXRlJ3MgeWVhcgogICAgICogQHBhcmFtIG1vbnRoICAgICAgVGhlIHJlZmVyZW5jZSBkYXRlJ3MgbW9udGggKDAtYmFzZWQ7IDAgaXMgSmFudWFyeSkKICAgICAqIEBwYXJhbSBkYXkgICAgICAgIFRoZSByZWZlcmVuY2UgZGF0ZSdzIGRheS1pbi1tb250aCAoMS1iYXNlZCkKICAgICAqIEBwYXJhbSBkYXlPZldlZWsgIFRoZSByZWZlcmVuY2UgZGF0ZSdzIGRheS1vZi13ZWVrICgxLWJhc2VkOyAxIGlzIFN1bmRheSkKICAgICAqIEBwYXJhbSBtaWxsaXMgICAgIFRoZSByZWZlcmVuY2UgZGF0ZSdzIG1pbGxpc2Vjb25kcyBpbiBkYXksIFVUVCAoTk9UIGxvY2FsIHRpbWUpLgogICAgICogQHJldHVybiAgICAgICAgICAgVGhlIG9mZnNldCBpbiBtaWxsaXNlY29uZHMgdG8gYWRkIHRvIEdNVCB0byBnZXQgbG9jYWwgdGltZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGdldE9mZnNldCh1aW50OF90IGVyYSwgaW50MzJfdCB5ZWFyLCBpbnQzMl90IG1vbnRoLCBpbnQzMl90IGRheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCBkYXlPZldlZWssIGludDMyX3QgbWlsbGlzLCBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0ID0gMDsKICAgIC8qKgogICAgICogQGRlcHJlY2F0ZWQgCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBnZXRPZmZzZXQodWludDhfdCBlcmEsIGludDMyX3QgeWVhciwgaW50MzJfdCBtb250aCwgaW50MzJfdCBkYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgZGF5T2ZXZWVrLCBpbnQzMl90IG1pbGxpcykgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgdGltZSB6b25lIG9mZnNldCwgZm9yIGN1cnJlbnQgZGF0ZSwgbW9kaWZpZWQgaW4gY2FzZSBvZgogICAgICogZGF5bGlnaHQgc2F2aW5ncy4gVGhpcyBpcyB0aGUgb2Zmc2V0IHRvIGFkZCAqdG8qIFVUQyB0byBnZXQgbG9jYWwgdGltZS4KICAgICAqIEBwYXJhbSBlcmEgdGhlIGVyYSBvZiB0aGUgZ2l2ZW4gZGF0ZS4KICAgICAqIEBwYXJhbSB5ZWFyIHRoZSB5ZWFyIGluIHRoZSBnaXZlbiBkYXRlLgogICAgICogQHBhcmFtIG1vbnRoIHRoZSBtb250aCBpbiB0aGUgZ2l2ZW4gZGF0ZS4KICAgICAqIE1vbnRoIGlzIDAtYmFzZWQuIGUuZy4sIDAgZm9yIEphbnVhcnkuCiAgICAgKiBAcGFyYW0gZGF5IHRoZSBkYXktaW4tbW9udGggb2YgdGhlIGdpdmVuIGRhdGUuCiAgICAgKiBAcGFyYW0gZGF5T2ZXZWVrIHRoZSBkYXktb2Ytd2VlayBvZiB0aGUgZ2l2ZW4gZGF0ZS4KICAgICAqIEBwYXJhbSBtaWxsaXNlY29uZHMgdGhlIG1pbGxpcyBpbiBkYXkgaW4gPGVtPnN0YW5kYXJkPC9lbT4gbG9jYWwgdGltZS4KICAgICAqIEBwYXJhbSBtb250aExlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBnaXZlbiBtb250aCBpbiBkYXlzLgogICAgICogQHJldHVybiB0aGUgb2Zmc2V0IHRvIGFkZCAqdG8qIEdNVCB0byBnZXQgbG9jYWwgdGltZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGdldE9mZnNldCh1aW50OF90IGVyYSwgaW50MzJfdCB5ZWFyLCBpbnQzMl90IG1vbnRoLCBpbnQzMl90IGRheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCBkYXlPZldlZWssIGludDMyX3QgbWlsbGlzZWNvbmRzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBtb250aExlbmd0aCwgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdCA9IDA7CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBUaW1lWm9uZSdzIHJhdyBHTVQgb2Zmc2V0IChpLmUuLCB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBhZGQKICAgICAqIHRvIEdNVCB0byBnZXQgbG9jYWwgdGltZSwgYmVmb3JlIHRha2luZyBkYXlsaWdodCBzYXZpbmdzIHRpbWUgaW50byBhY2NvdW50KS4KICAgICAqCiAgICAgKiBAcGFyYW0gb2Zmc2V0TWlsbGlzICBUaGUgbmV3IHJhdyBHTVQgb2Zmc2V0IGZvciB0aGlzIHRpbWUgem9uZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHNldFJhd09mZnNldChpbnQzMl90IG9mZnNldE1pbGxpcykgPSAwOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgVGltZVpvbmUncyByYXcgR01UIG9mZnNldCAoaS5lLiwgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gYWRkCiAgICAgKiB0byBHTVQgdG8gZ2V0IGxvY2FsIHRpbWUsIGJlZm9yZSB0YWtpbmcgZGF5bGlnaHQgc2F2aW5ncyB0aW1lIGludG8gYWNjb3VudCkuCiAgICAgKgogICAgICogQHJldHVybiAgIFRoZSBUaW1lWm9uZSdzIHJhdyBHTVQgb2Zmc2V0LgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0UmF3T2Zmc2V0KHZvaWQpIGNvbnN0ID0gMDsKCiAgICAvKioKICAgICAqIEZpbGxzIGluICJJRCIgd2l0aCB0aGUgVGltZVpvbmUncyBJRC4KICAgICAqCiAgICAgKiBAcGFyYW0gSUQgIFJlY2VpdmVzIHRoaXMgVGltZVpvbmUncyBJRC4KICAgICAqIEByZXR1cm4gICAgIklEIgogICAgICogQHN0YWJsZQogICAgICovCiAgICBVbmljb2RlU3RyaW5nJiBnZXRJRChVbmljb2RlU3RyaW5nJiBJRCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBUaW1lWm9uZSdzIElEIHRvIHRoZSBzcGVjaWZpZWQgdmFsdWUuICBUaGlzIGRvZXNuJ3QgYWZmZWN0IGFueSBvdGhlcgogICAgICogZmllbGRzIChmb3IgZXhhbXBsZSwgaWYgeW91IHNheTwKICAgICAqIGJsb2NrcXVvdGU+PHByZT4KICAgICAqIC4gICAgIFRpbWVab25lKiBmb28gPSBUaW1lWm9uZTo6Y3JlYXRlVGltZVpvbmUoIkFtZXJpY2EvTmV3X1lvcmsiKTsKICAgICAqIC4gICAgIGZvby5zZXRJRCgiQW1lcmljYS9Mb3NfQW5nZWxlcyIpOwogICAgICogPC9wcmU+PC9ibG9ja3F1b3RlPgogICAgICogdGhlIHRpbWUgem9uZSdzIEdNVCBvZmZzZXQgYW5kIGRheWxpZ2h0LXNhdmluZ3MgcnVsZXMgZG9uJ3QgY2hhbmdlIHRvIHRob3NlIGZvcgogICAgICogTG9zIEFuZ2VsZXMuICBUaGV5J3JlIHN0aWxsIHRob3NlIGZvciBOZXcgWW9yay4gIE9ubHkgdGhlIElEIGhhcyBjaGFuZ2VkLikKICAgICAqCiAgICAgKiBAcGFyYW0gSUQgIFRoZSBuZXcgdGltZXpvbmUgSUQuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZvaWQgc2V0SUQoY29uc3QgVW5pY29kZVN0cmluZyYgSUQpOwoKICAgIC8qKgogICAgICogRW51bSBmb3IgdXNlIHdpdGggZ2V0RGlzcGxheU5hbWUKICAgICAqLwoKICAgIGVudW0gRURpc3BsYXlUeXBlIHsgCiAgICAgICAgU0hPUlQgPSAxLAogICAgICAgIExPTkcgCiAgICB9OwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIG5hbWUgb2YgdGhpcyB0aW1lIHpvbmUgc3VpdGFibGUgZm9yIHByZXNlbnRhdGlvbiB0byB0aGUgdXNlcgogICAgICogaW4gdGhlIGRlZmF1bHQgbG9jYWxlLgogICAgICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgbG9uZyBuYW1lLCBub3QgaW5jbHVkaW5nIGRheWxpZ2h0IHNhdmluZ3MuCiAgICAgKiBJZiB0aGUgZGlzcGxheSBuYW1lIGlzIG5vdCBhdmFpbGFibGUgZm9yIHRoZSBsb2NhbGUsCiAgICAgKiB0aGVuIHRoaXMgbWV0aG9kIHJldHVybnMgYSBzdHJpbmcgaW4gdGhlIGZvcm1hdAogICAgICogPGNvZGU+R01UWystXWhoOm1tPC9jb2RlPi4KICAgICAqIEByZXR1cm4gdGhlIGh1bWFuLXJlYWRhYmxlIG5hbWUgb2YgdGhpcyB0aW1lIHpvbmUgaW4gdGhlIGRlZmF1bHQgbG9jYWxlLgogICAgICogQHN0YWJsZQogICAgICovCiAgICBVbmljb2RlU3RyaW5nJiBnZXREaXNwbGF5TmFtZShVbmljb2RlU3RyaW5nJiByZXN1bHQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIG5hbWUgb2YgdGhpcyB0aW1lIHpvbmUgc3VpdGFibGUgZm9yIHByZXNlbnRhdGlvbiB0byB0aGUgdXNlcgogICAgICogaW4gdGhlIHNwZWNpZmllZCBsb2NhbGUuCiAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBsb25nIG5hbWUsIG5vdCBpbmNsdWRpbmcgZGF5bGlnaHQgc2F2aW5ncy4KICAgICAqIElmIHRoZSBkaXNwbGF5IG5hbWUgaXMgbm90IGF2YWlsYWJsZSBmb3IgdGhlIGxvY2FsZSwKICAgICAqIHRoZW4gdGhpcyBtZXRob2QgcmV0dXJucyBhIHN0cmluZyBpbiB0aGUgZm9ybWF0CiAgICAgKiA8Y29kZT5HTVRbKy1daGg6bW08L2NvZGU+LgogICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIGluIHdoaWNoIHRvIHN1cHBseSB0aGUgZGlzcGxheSBuYW1lLgogICAgICogQHJldHVybiB0aGUgaHVtYW4tcmVhZGFibGUgbmFtZSBvZiB0aGlzIHRpbWUgem9uZSBpbiB0aGUgZ2l2ZW4gbG9jYWxlCiAgICAgKiBvciBpbiB0aGUgZGVmYXVsdCBsb2NhbGUgaWYgdGhlIGdpdmVuIGxvY2FsZSBpcyBub3QgcmVjb2duaXplZC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgVW5pY29kZVN0cmluZyYgZ2V0RGlzcGxheU5hbWUoY29uc3QgTG9jYWxlJiBsb2NhbGUsIFVuaWNvZGVTdHJpbmcmIHJlc3VsdCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbmFtZSBvZiB0aGlzIHRpbWUgem9uZSBzdWl0YWJsZSBmb3IgcHJlc2VudGF0aW9uIHRvIHRoZSB1c2VyCiAgICAgKiBpbiB0aGUgZGVmYXVsdCBsb2NhbGUuCiAgICAgKiBJZiB0aGUgZGlzcGxheSBuYW1lIGlzIG5vdCBhdmFpbGFibGUgZm9yIHRoZSBsb2NhbGUsCiAgICAgKiB0aGVuIHRoaXMgbWV0aG9kIHJldHVybnMgYSBzdHJpbmcgaW4gdGhlIGZvcm1hdAogICAgICogPGNvZGU+R01UWystXWhoOm1tPC9jb2RlPi4KICAgICAqIEBwYXJhbSBkYXlsaWdodCBpZiB0cnVlLCByZXR1cm4gdGhlIGRheWxpZ2h0IHNhdmluZ3MgbmFtZS4KICAgICAqIEBwYXJhbSBzdHlsZSBlaXRoZXIgPGNvZGU+TE9ORzwvY29kZT4gb3IgPGNvZGU+U0hPUlQ8L2NvZGU+CiAgICAgKiBAcmV0dXJuIHRoZSBodW1hbi1yZWFkYWJsZSBuYW1lIG9mIHRoaXMgdGltZSB6b25lIGluIHRoZSBkZWZhdWx0IGxvY2FsZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgVW5pY29kZVN0cmluZyYgZ2V0RGlzcGxheU5hbWUoVUJvb2wgZGF5bGlnaHQsIEVEaXNwbGF5VHlwZSBzdHlsZSwgVW5pY29kZVN0cmluZyYgcmVzdWx0KSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBuYW1lIG9mIHRoaXMgdGltZSB6b25lIHN1aXRhYmxlIGZvciBwcmVzZW50YXRpb24gdG8gdGhlIHVzZXIKICAgICAqIGluIHRoZSBzcGVjaWZpZWQgbG9jYWxlLgogICAgICogSWYgdGhlIGRpc3BsYXkgbmFtZSBpcyBub3QgYXZhaWxhYmxlIGZvciB0aGUgbG9jYWxlLAogICAgICogdGhlbiB0aGlzIG1ldGhvZCByZXR1cm5zIGEgc3RyaW5nIGluIHRoZSBmb3JtYXQKICAgICAqIDxjb2RlPkdNVFsrLV1oaDptbTwvY29kZT4uCiAgICAgKiBAcGFyYW0gZGF5bGlnaHQgaWYgdHJ1ZSwgcmV0dXJuIHRoZSBkYXlsaWdodCBzYXZpbmdzIG5hbWUuCiAgICAgKiBAcGFyYW0gc3R5bGUgZWl0aGVyIDxjb2RlPkxPTkc8L2NvZGU+IG9yIDxjb2RlPlNIT1JUPC9jb2RlPgogICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIGluIHdoaWNoIHRvIHN1cHBseSB0aGUgZGlzcGxheSBuYW1lLgogICAgICogQHJldHVybiB0aGUgaHVtYW4tcmVhZGFibGUgbmFtZSBvZiB0aGlzIHRpbWUgem9uZSBpbiB0aGUgZ2l2ZW4gbG9jYWxlCiAgICAgKiBvciBpbiB0aGUgZGVmYXVsdCBsb2NhbGUgaWYgdGhlIGdpdmVuIGxvY2FsZSBpcyBub3QgcmVjb2duaXplZC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgVW5pY29kZVN0cmluZyYgZ2V0RGlzcGxheU5hbWUoVUJvb2wgZGF5bGlnaHQsIEVEaXNwbGF5VHlwZSBzdHlsZSwgY29uc3QgTG9jYWxlJiBsb2NhbGUsIFVuaWNvZGVTdHJpbmcmIHJlc3VsdCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBRdWVyaWVzIGlmIHRoaXMgdGltZSB6b25lIHVzZXMgZGF5bGlnaHQgc2F2aW5ncyB0aW1lLgogICAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgdGltZSB6b25lIHVzZXMgZGF5bGlnaHQgc2F2aW5ncyB0aW1lLAogICAgICogZmFsc2UsIG90aGVyd2lzZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgdmlydHVhbCBVQm9vbCB1c2VEYXlsaWdodFRpbWUodm9pZCkgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogUXVlcmllcyBpZiB0aGUgZ2l2ZW4gZGF0ZSBpcyBpbiBkYXlsaWdodCBzYXZpbmdzIHRpbWUgaW4KICAgICAqIHRoaXMgdGltZSB6b25lLgogICAgICogQHBhcmFtIGRhdGUgdGhlIGdpdmVuIFVEYXRlLgogICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBnaXZlbiBkYXRlIGlzIGluIGRheWxpZ2h0IHNhdmluZ3MgdGltZSwKICAgICAqIGZhbHNlLCBvdGhlcndpc2UuCiAgICAgKiBAZGVwcmVjYXRlZAogICAgICovCiAgICB2aXJ0dWFsIFVCb29sIGluRGF5bGlnaHRUaW1lKFVEYXRlIGRhdGUsIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgem9uZSBoYXMgdGhlIHNhbWUgcnVsZSBhbmQgb2Zmc2V0IGFzIGFub3RoZXIgem9uZS4KICAgICAqIFRoYXQgaXMsIGlmIHRoaXMgem9uZSBkaWZmZXJzIG9ubHkgaW4gSUQsIGlmIGF0IGFsbC4KICAgICAqIEBwYXJhbSBvdGhlciB0aGUgPGNvZGU+VGltZVpvbmU8L2NvZGU+IG9iamVjdCB0byBiZSBjb21wYXJlZCB3aXRoCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIHpvbmUgaXMgdGhlIHNhbWUgYXMgdGhpcyBvbmUsCiAgICAgKiB3aXRoIHRoZSBwb3NzaWJsZSBleGNlcHRpb24gb2YgdGhlIElECiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgVUJvb2wgaGFzU2FtZVJ1bGVzKGNvbnN0IFRpbWVab25lJiBvdGhlcikgY29uc3Q7CgogICAgLyoqCiAgICAgKiBDbG9uZXMgVGltZVpvbmUgb2JqZWN0cyBwb2x5bW9ycGhpY2FsbHkuIENsaWVudHMgYXJlIHJlc3BvbnNpYmxlIGZvciBkZWxldGluZwogICAgICogdGhlIFRpbWVab25lIG9iamVjdCBjbG9uZWQuCiAgICAgKgogICAgICogQHJldHVybiAgIEEgbmV3IGNvcHkgb2YgdGhpcyBUaW1lWm9uZSBvYmplY3QuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgVGltZVpvbmUqIGNsb25lKHZvaWQpIGNvbnN0ID0gMDsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgY2xhc3MgSUQgZm9yIHRoaXMgY2xhc3MuICBUaGlzIGlzIHVzZWZ1bCBvbmx5IGZvcgogICAgICogY29tcGFyaW5nIHRvIGEgcmV0dXJuIHZhbHVlIGZyb20gZ2V0RHluYW1pY0NsYXNzSUQoKS4gIEZvciBleGFtcGxlOgogICAgICogPHByZT4KICAgICAqIC4gICBCYXNlKiBwb2x5bW9ycGhpY19wb2ludGVyID0gY3JlYXRlUG9seW1vcnBoaWNPYmplY3QoKTsKICAgICAqIC4gICBpZiAocG9seW1vcnBoaWNfcG9pbnRlci0+Z2V0RHluYW1pY0NsYXNzSUQoKSA9PQogICAgICogLiAgICAgICBEZXJpdmVkOjpnZXRTdGF0aWNDbGFzc0lEKCkpIC4uLgogICAgICogPC9wcmU+CiAgICAgKiBAcmV0dXJuIFRoZSBjbGFzcyBJRCBmb3IgYWxsIG9iamVjdHMgb2YgdGhpcyBjbGFzcy4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgc3RhdGljIFVDbGFzc0lEIGdldFN0YXRpY0NsYXNzSUQodm9pZCkgeyByZXR1cm4gKFVDbGFzc0lEKSZmZ0NsYXNzSUQ7IH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSB1bmlxdWUgY2xhc3MgSUQgUE9MWU1PUlBISUNBTExZLiBQdXJlIHZpcnR1YWwgbWV0aG9kLiBUaGlzIG1ldGhvZCBpcyB0bwogICAgICogaW1wbGVtZW50IGEgc2ltcGxlIHZlcnNpb24gb2YgUlRUSSwgc2luY2Ugbm90IGFsbCBDKysgY29tcGlsZXJzIHN1cHBvcnQgZ2VudWluZQogICAgICogUlRUSS4gUG9seW1vcnBoaWMgb3BlcmF0b3I9PSgpIGFuZCBjbG9uZSgpIG1ldGhvZHMgY2FsbCB0aGlzIG1ldGhvZC4KICAgICAqIDxQPgogICAgICogQ29uY3JldGUgc3ViY2xhc3NlcyBvZiBUaW1lWm9uZSBtdXN0IGltcGxlbWVudCBnZXREeW5hbWljQ2xhc3NJRCgpIGFuZCBhbHNvIGEKICAgICAqIHN0YXRpYyBtZXRob2QgYW5kIGRhdGEgbWVtYmVyOgogICAgICogPHByZT4KICAgICAqIC4gICAgIHN0YXRpYyBVQ2xhc3NJRCBnZXRTdGF0aWNDbGFzc0lEKCkgeyByZXR1cm4gKFVDbGFzc0lEKSZmZ0NsYXNzSUQ7IH0KICAgICAqIC4gICAgIHN0YXRpYyBjaGFyIGZnQ2xhc3NJRDsKICAgICAqIDwvcHJlPgogICAgICogQHJldHVybiAgIFRoZSBjbGFzcyBJRCBmb3IgdGhpcyBvYmplY3QuIEFsbCBvYmplY3RzIG9mIGEgZ2l2ZW4gY2xhc3MgaGF2ZSB0aGUKICAgICAqICAgICAgICAgICBzYW1lIGNsYXNzIElELiBPYmplY3RzIG9mIG90aGVyIGNsYXNzZXMgaGF2ZSBkaWZmZXJlbnQgY2xhc3MgSURzLgogICAgICogQHN0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIFVDbGFzc0lEIGdldER5bmFtaWNDbGFzc0lEKHZvaWQpIGNvbnN0ID0gMDsKCnByb3RlY3RlZDoKCiAgICAvKioKICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IuICBJRCBpcyBpbml0aWFsaXplZCB0byB0aGUgZW1wdHkgc3RyaW5nLgogICAgICogQHN0YWJsZQogICAgICovCiAgICBUaW1lWm9uZSgpOwoKICAgIC8qKgogICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgVGltZVpvbmUoY29uc3QgVGltZVpvbmUmIHNvdXJjZSk7CgogICAgLyoqCiAgICAgKiBEZWZhdWx0IGFzc2lnbm1lbnQgb3BlcmF0b3IuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIFRpbWVab25lJiBvcGVyYXRvcj0oY29uc3QgVGltZVpvbmUmIHJpZ2h0KTsKCnByaXZhdGU6CiAgICBzdGF0aWMgY2hhciBmZ0NsYXNzSUQ7CgogICAgc3RhdGljIFRpbWVab25lKiAgICAgICAgY3JlYXRlQ3VzdG9tVGltZVpvbmUoY29uc3QgVW5pY29kZVN0cmluZyYpOyAvLyBDcmVhdGVzIGEgdGltZSB6b25lIGJhc2VkIG9uIHRoZSBzdHJpbmcuCgogICAgc3RhdGljIFRpbWVab25lKiAgICAgICAgZmdEZWZhdWx0Wm9uZTsgLy8gZGVmYXVsdCB0aW1lIHpvbmUgKGxhenkgZXZhbHVhdGVkKQoKICAgIHN0YXRpYyBjb25zdCBVbmljb2RlU3RyaW5nICAgICAgR01UX0lEOwogICAgc3RhdGljIGNvbnN0IGludDMyX3QgICAgICAgICAgICBHTVRfSURfTEVOR1RIOwogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgICAgICBDVVNUT01fSUQ7CgogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgLy8gUG9pbnRlcnMgaW50byBtZW1vcnktbWFwcGVkIGljdWRhdGEuICBXcml0aW5nIHRvIHRoaXMgbWVtb3J5CiAgICAvLyB3aWxsIHNlZ2ZhdWx0ISAgU2VlIHR6ZGF0LmggZm9yIG1vcmUgZGV0YWlscy4KICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCiAgICAvKioKICAgICAqIERBVEEgaXMgdGhlIHN0YXJ0IG9mIHRoZSBtZW1vcnktbWFwcGVkIHpvbmUgZGF0YSwgYW5kCiAgICAgKiBzcGVjaWZpY2FsbHkgcG9pbnRzIHRvIHRoZSBoZWFkZXIgb2JqZWN0IGxvY2F0ZWQgdGhlcmUuCiAgICAgKiBNYXkgYmUgemVybyBpZiBsb2FkaW5nIGZhaWxlZCBmb3Igc29tZSByZWFzb24uCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBUWkhlYWRlciAqICAgIERBVEE7CgogICAgLyoqCiAgICAgKiBJTkRFWF9CWV9JRCBpcyBhbiBpbmRleCB0YWJsZSBpbiBsZXhpY29ncmFwaGljIG9yZGVyIG9mIElELgogICAgICogRWFjaCBlbnRyeSBpcyBhbiBvZmZzZXQgZnJvbSBEQVRBIHRvIHRoZSB6b25lIG9iamVjdCwgd2hpY2gKICAgICAqIHdpbGwgZWl0aGVyIGJlIGEgU3RhbmRhcmRab25lIG9yIGEgRFNUWm9uZSBvYmplY3QuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCB1aW50MzJfdCogICAgIElOREVYX0JZX0lEOwoKICAgIC8qKgogICAgICogSU5ERVhfQllfT0ZGU0VUIGlzIGFuIE9mZnNldEluZGV4IHRhYmxlLiAgVGhpcyB0YWJsZSBjYW4gb25seQogICAgICogYmUgd2Fsa2VkIHRocm91Z2ggc2VxdWVudGlhbGx5IGJlY2F1c2UgdGhlIGVudHJpZXMgYXJlIG9mCiAgICAgKiB2YXJpYWJsZSBzaXplLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgT2Zmc2V0SW5kZXgqICBJTkRFWF9CWV9PRkZTRVQ7CgogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgLy8gT3RoZXIgc3lzdGVtIHpvbmUgZGF0YSBzdHJ1Y3R1cmVzCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAvKioKICAgICAqIFpPTkVfSURTIGlzIGFuIGFycmF5IG9mIGFsbCB0aGUgc3lzdGVtIHpvbmUgSUQgc3RyaW5ncywgaW4KICAgICAqIGxleGljb2dyYXBoaWMgb3JkZXIuICBUaGUgY3JlYXRlQXZhaWxhYmxlSURzKCkgbWV0aG9kcyByZXR1cm4KICAgICAqIGFycmF5cyBvZiBwb2ludGVycyBpbnRvIHRoaXMgYXJyYXkuCiAgICAgKi8KICAgIHN0YXRpYyBVbmljb2RlU3RyaW5nKiAgICAgIFpPTkVfSURTOwoKICAgIC8qKgogICAgICogSWYgREFUQV9MT0FERUQgaXMgdHJ1ZSwgdGhlbiBhbiBhdHRlbXB0IGhhcyBhbHJlYWR5IGJlZW4gbWFkZQogICAgICogdG8gbG9hZCB0aGUgc3lzdGVtIHpvbmUgZGF0YSwgYW5kIGZ1cnRoZXIgYXR0ZW1wdHMgd2lsbCBub3QgYmUKICAgICAqIG1hZGUuICBJZiBEQVRBX0xPQURFRCBpcyB0cnVlLCBEQVRBIGl0c2VsZiB3aWxsIGJlIHplcm8gaWYKICAgICAqIGxvYWRpbmcgZmFpbGVkLCBvciBub24temVybyBpZiBpdCBzdWNjZWVkZWQuCiAgICAgKi8KICAgIHN0YXRpYyBVQm9vbCAgICAgICAgICAgICAgREFUQV9MT0FERUQ7CgogICAgLyoqCiAgICAgKiBUaGUgbXV0ZXggb2JqZWN0IHVzZWQgdG8gY29udHJvbCB3cml0ZSBhY2Nlc3MgdG8gREFUQSwKICAgICAqIElOREVYX0JZX0lELCBJTkRFWF9CWV9PRkZTRVQsIGFuZCBaT05FX0lEUy4gIEFsc28gdXNlZCB0bwogICAgICogY29udHJvbCByZWFkL3dyaXRlIGFjY2VzcyB0byBmZ0RlZmF1bHRab25lLgogICAgICovCiAgICBzdGF0aWMgVU1UWCAgICAgICAgICAgICAgICBMT0NLOyAgICAKCiAgICAvKioKICAgICAqIFJlc3BvbnNpYmxlIGZvciBzZXR0aW5nIHVwIGZnRGVmYXVsdFpvbmUuICBVc2VzIHJvdXRpbmVzIGluIFRQbGF0Zm9ybVV0aWxpdGllcwogICAgICogKGkuZS4sIHBsYXRmb3JtLXNwZWNpZmljIGNhbGxzKSB0byBnZXQgdGhlIGN1cnJlbnQgc3lzdGVtIHRpbWUgem9uZS4gIEZhaWxpbmcKICAgICAqIHRoYXQsIHVzZXMgdGhlIHBsYXRmb3JtLXNwZWNpZmljIGRlZmF1bHQgdGltZSB6b25lLiAgRmFpbGluZyB0aGF0LCB1c2VzIEdNVC4KICAgICAqLwogICAgc3RhdGljIHZvaWQgICAgICAgICAgICAgaW5pdERlZmF1bHQodm9pZCk7CgogICAgLy8gU2VlIHNvdXJjZSBmaWxlIGZvciBkb2N1bWVudGF0aW9uCiAgICBzdGF0aWMgdm9pZCAgIGxvYWRab25lRGF0YSh2b2lkKTsKCiAgICAvLyBTZWUgc291cmNlIGZpbGUgZm9yIGRvY3VtZW50YXRpb24KICAgIHN0YXRpYyBVQm9vbCBVX0NBTExDT05WIGlzRGF0YUFjY2VwdGFibGUodm9pZCAqY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0eXBlLCBjb25zdCBjaGFyICpuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVEYXRhSW5mbyAqcEluZm8pOwoKICAgIC8vIFNlZSBzb3VyY2UgZmlsZSBmb3IgZG9jdW1lbnRhdGlvbgogICAgc3RhdGljIFRpbWVab25lKiBjcmVhdGVTeXN0ZW1UaW1lWm9uZShjb25zdCBVbmljb2RlU3RyaW5nJiBuYW1lKTsKCiAgICBVbmljb2RlU3RyaW5nICAgICAgICAgICBmSUQ7ICAgIC8vIHRoaXMgdGltZSB6b25lJ3MgSUQKfTsKCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgppbmxpbmUgVW5pY29kZVN0cmluZyYKVGltZVpvbmU6OmdldElEKFVuaWNvZGVTdHJpbmcmIElEKSBjb25zdAp7CiAgICBJRCA9IGZJRDsKICAgIHJldHVybiBJRDsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW5saW5lIHZvaWQKVGltZVpvbmU6OnNldElEKGNvbnN0IFVuaWNvZGVTdHJpbmcmIElEKQp7CiAgICBmSUQgPSBJRDsKfQoKI2VuZGlmIC8vX1RJTUVaT05FCi8vZW9mCg==