LyoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgICoKICogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogJFNvdXJjZTogL3hzcmwvTnN2bi9pY3UvaWN1NGovc3JjL2NvbS9pYm0vdGV4dC9BdHRpYy9Ob3JtYWxpemVyLmphdmEsdiAkIAogKiAkRGF0ZTogMjAwMC8wOS8yMSAyMjozNzo0MSAkIAogKiAkUmV2aXNpb246IDEuMTAgJAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICovCnBhY2thZ2UgY29tLmlibS50ZXh0OwoKaW1wb3J0IGphdmEubGFuZy5DaGFyYWN0ZXI7CmltcG9ydCBqYXZhLnRleHQuQ2hhcmFjdGVySXRlcmF0b3I7CmltcG9ydCBqYXZhLnRleHQuU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3I7CmltcG9ydCBjb20uaWJtLnV0aWwuQ29tcGFjdEJ5dGVBcnJheTsKaW1wb3J0IGNvbS5pYm0udXRpbC5VdGlsaXR5OwoKLyoqCiAqIDx0dD5Ob3JtYWxpemVyPC90dD4gdHJhbnNmb3JtcyBVbmljb2RlIHRleHQgaW50byBhbiBlcXVpdmFsZW50IGNvbXBvc2VkIG9yCiAqIGRlY29tcG9zZWQgZm9ybSwgYWxsb3dpbmcgZm9yIGVhc2llciBzb3J0aW5nIGFuZCBzZWFyY2hpbmcgb2YgdGV4dC4KICogPHR0Pk5vcm1hbGl6ZXI8L3R0PiBzdXBwb3J0cyB0aGUgc3RhbmRhcmQgbm9ybWFsaXphdGlvbiBmb3JtcyBkZXNjcmliZWQgaW4KICogPGEgaHJlZj0iaHR0cDovL3d3dy51bmljb2RlLm9yZy91bmljb2RlL3JlcG9ydHMvdHIxNS8iIHRhcmdldD0idW5pY29kZSI+CiAqIFVuaWNvZGUgVGVjaG5pY2FsIFJlcG9ydCAjMTU8L2E+LgogKiA8cD4KICogQ2hhcmFjdGVycyB3aXRoIGFjY2VudHMgb3Igb3RoZXIgYWRvcm5tZW50cyBjYW4gYmUgZW5jb2RlZCBpbgogKiBzZXZlcmFsIGRpZmZlcmVudCB3YXlzIGluIFVuaWNvZGUuICBGb3IgZXhhbXBsZSwgdGFrZSB0aGUgY2hhcmFjdGVyICLCIgogKiAoQS1hY3V0ZSkuICAgSW4gVW5pY29kZSwgdGhpcyBjYW4gYmUgZW5jb2RlZCBhcyBhIHNpbmdsZSBjaGFyYWN0ZXIgKHRoZQogKiAiY29tcG9zZWQiIGZvcm0pOgogKiA8cHJlPgogKiAgICAgIDAwQzEgICAgTEFUSU4gQ0FQSVRBTCBMRVRURVIgQSBXSVRIIEFDVVRFPC9wcmU+CiAqIG9yIGFzIHR3byBzZXBhcmF0ZSBjaGFyYWN0ZXJzICh0aGUgImRlY29tcG9zZWQiIGZvcm0pOgogKiA8cHJlPgogKiAgICAgIDAwNDEgICAgTEFUSU4gQ0FQSVRBTCBMRVRURVIgQQogKiAgICAgIDAzMDEgICAgQ09NQklOSU5HIEFDVVRFIEFDQ0VOVDwvcHJlPgogKiA8cD4KICogVG8gYSB1c2VyIG9mIHlvdXIgcHJvZ3JhbSwgaG93ZXZlciwgYm90aCBvZiB0aGVzZSBzZXF1ZW5jZXMgc2hvdWxkIGJlCiAqIHRyZWF0ZWQgYXMgdGhlIHNhbWUgInVzZXItbGV2ZWwiIGNoYXJhY3RlciAiwiIuICBXaGVuIHlvdSBhcmUgc2VhcmNoaW5nIG9yCiAqIGNvbXBhcmluZyB0ZXh0LCB5b3UgbXVzdCBlbnN1cmUgdGhhdCB0aGVzZSB0d28gc2VxdWVuY2VzIGFyZSB0cmVhdGVkCiAqIGVxdWl2YWxlbnRseS4gIEluIGFkZGl0aW9uLCB5b3UgbXVzdCBoYW5kbGUgY2hhcmFjdGVycyB3aXRoIG1vcmUgdGhhbiBvbmUKICogYWNjZW50LiAgU29tZXRpbWVzIHRoZSBvcmRlciBvZiBhIGNoYXJhY3RlcidzIGNvbWJpbmluZyBhY2NlbnRzIGlzCiAqIHNpZ25pZmljYW50LCB3aGlsZSBpbiBvdGhlciBjYXNlcyBhY2NlbnQgc2VxdWVuY2VzIGluIGRpZmZlcmVudCBvcmRlcnMgYXJlCiAqIHJlYWxseSBlcXVpdmFsZW50LgogKiA8cD4KICogU2ltaWxhcmx5LCB0aGUgc3RyaW5nICJmZmkiIGNhbiBiZSBlbmNvZGVkIGFzIHRocmVlIHNlcGFyYXRlIGxldHRlcnM6CiAqIDxwcmU+CiAqICAgICAgMDA2NiAgICBMQVRJTiBTTUFMTCBMRVRURVIgRgogKiAgICAgIDAwNjYgICAgTEFUSU4gU01BTEwgTEVUVEVSIEYKICogICAgICAwMDY5ICAgIExBVElOIFNNQUxMIExFVFRFUiBJPC9wcmU+CiAqIG9yIGFzIHRoZSBzaW5nbGUgY2hhcmFjdGVyCiAqIDxwcmU+CiAqICAgICAgRkIwMyAgICBMQVRJTiBTTUFMTCBMSUdBVFVSRSBGRkk8L3ByZT4KICogPHA+CiAqIFRoZSBmZmkgbGlnYXR1cmUgaXMgbm90IGEgZGlzdGluY3Qgc2VtYW50aWMgY2hhcmFjdGVyLCBhbmQgc3RyaWN0bHkgc3BlYWtpbmcKICogaXQgc2hvdWxkbid0IGJlIGluIFVuaWNvZGUgYXQgYWxsLCBidXQgaXQgd2FzIGluY2x1ZGVkIGZvciBjb21wYXRpYmlsaXR5CiAqIHdpdGggZXhpc3RpbmcgY2hhcmFjdGVyIHNldHMgdGhhdCBhbHJlYWR5IHByb3ZpZGVkIGl0LiAgVGhlIFVuaWNvZGUgc3RhbmRhcmQKICogaWRlbnRpZmllcyBzdWNoIGNoYXJhY3RlcnMgYnkgZ2l2aW5nIHRoZW0gImNvbXBhdGliaWxpdHkiIGRlY29tcG9zaXRpb25zCiAqIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgc2VtYW50aWMgY2hhcmFjdGVycy4gIFdoZW4gc29ydGluZyBhbmQgc2VhcmNoaW5nLCB5b3UKICogd2lsbCBvZnRlbiB3YW50IHRvIHVzZSB0aGVzZSBtYXBwaW5ncy4KICogPHA+CiAqIDx0dD5Ob3JtYWxpemVyPC90dD4gaGVscHMgc29sdmUgdGhlc2UgcHJvYmxlbXMgYnkgdHJhbnNmb3JtaW5nIHRleHQgaW50byB0aGUKICogY2Fub25pY2FsIGNvbXBvc2VkIGFuZCBkZWNvbXBvc2VkIGZvcm1zIGFzIHNob3duIGluIHRoZSBmaXJzdCBleGFtcGxlIGFib3ZlLgogKiBJbiBhZGRpdGlvbiwgeW91IGNhbiBoYXZlIGl0IHBlcmZvcm0gY29tcGF0aWJpbGl0eSBkZWNvbXBvc2l0aW9ucyBzbyB0aGF0CiAqIHlvdSBjYW4gdHJlYXQgY29tcGF0aWJpbGl0eSBjaGFyYWN0ZXJzIHRoZSBzYW1lIGFzIHRoZWlyIGVxdWl2YWxlbnRzLgogKiBGaW5hbGx5LCA8dHQ+Tm9ybWFsaXplcjwvdHQ+IHJlYXJyYW5nZXMgYWNjZW50cyBpbnRvIHRoZSBwcm9wZXIgY2Fub25pY2FsCiAqIG9yZGVyLCBzbyB0aGF0IHlvdSBkbyBub3QgaGF2ZSB0byB3b3JyeSBhYm91dCBhY2NlbnQgcmVhcnJhbmdlbWVudCBvbiB5b3VyCiAqIG93bi4KICogPHA+CiAqIDx0dD5Ob3JtYWxpemVyPC90dD4gYWRkcyBvbmUgb3B0aW9uYWwgYmVoYXZpb3IsIHtAbGluayAjSUdOT1JFX0hBTkdVTH0sCiAqIHRoYXQgZGlmZmVycyBmcm9tCiAqIHRoZSBzdGFuZGFyZCBVbmljb2RlIE5vcm1hbGl6YXRpb24gRm9ybXMuICBUaGlzIG9wdGlvbiBjYW4gYmUgcGFzc2VkCiAqIHRvIHRoZSB7QGxpbmsgI05vcm1hbGl6ZXIgY29uc3RydWN0b3JzfSBhbmQgdG8gdGhlIHN0YXRpYwogKiB7QGxpbmsgI2NvbXBvc2UgY29tcG9zZX0gYW5kIHtAbGluayAjZGVjb21wb3NlIGRlY29tcG9zZX0gbWV0aG9kcy4gIFRoaXMKICogb3B0aW9uLCBhbmQgYW55IHRoYXQgYXJlIGFkZGVkIGluIHRoZSBmdXR1cmUsIHdpbGwgYmUgdHVybmVkIG9mZiBieSBkZWZhdWx0LgogKiA8cD4KICogVGhlcmUgYXJlIHRocmVlIGNvbW1vbiB1c2FnZSBtb2RlbHMgZm9yIDx0dD5Ob3JtYWxpemVyPC90dD4uICBJbiB0aGUgZmlyc3QsCiAqIHRoZSBzdGF0aWMge0BsaW5rICNub3JtYWxpemUgbm9ybWFsaXplKCl9IG1ldGhvZCBpcyB1c2VkIHRvIHByb2Nlc3MgYW4KICogZW50aXJlIGlucHV0IHN0cmluZyBhdCBvbmNlLiAgU2Vjb25kLCB5b3UgY2FuIGNyZWF0ZSBhIDx0dD5Ob3JtYWxpemVyPC90dD4KICogb2JqZWN0IGFuZCB1c2UgaXQgdG8gaXRlcmF0ZSB0aHJvdWdoIHRoZSBub3JtYWxpemVkIGZvcm0gb2YgYSBzdHJpbmcgYnkKICogY2FsbGluZyB7QGxpbmsgI2ZpcnN0fSBhbmQge0BsaW5rICNuZXh0fS4gIEZpbmFsbHksIHlvdSBjYW4gdXNlIHRoZQogKiB7QGxpbmsgI3NldEluZGV4IHNldEluZGV4KCl9IGFuZCB7QGxpbmsgI2dldEluZGV4fSBtZXRob2RzIHRvIHBlcmZvcm0KICogcmFuZG9tLWFjY2VzcyBpdGVyYXRpb24sIHdoaWNoIGlzIHZlcnkgdXNlZnVsIGZvciBzZWFyY2hpbmcuCiAqIDxwPgogKiA8Yj5Ob3RlOjwvYj4gPHR0Pk5vcm1hbGl6ZXI8L3R0PiBvYmplY3RzIGJlaGF2ZSBsaWtlIGl0ZXJhdG9ycyBhbmQgaGF2ZQogKiBtZXRob2RzIHN1Y2ggYXMgPHR0PnNldEluZGV4PC90dD4sIDx0dD5uZXh0PC90dD4sIDx0dD5wcmV2aW91czwvdHQ+LCBldGMuCiAqIFlvdSBzaG91bGQgbm90ZSB0aGF0IHdoaWxlIHRoZSA8dHQ+c2V0SW5kZXg8L3R0PiBhbmQgPHR0PmdldEluZGV4PC90dD4gcmVmZXIKICogdG8gaW5kaWNlcyBpbiB0aGUgdW5kZXJseWluZyA8ZW0+aW5wdXQ8L2VtPiB0ZXh0IGJlaW5nIHByb2Nlc3NlZCwgdGhlCiAqIDx0dD5uZXh0PC90dD4gYW5kIDx0dD5wcmV2aW91czwvdHQ+IG1ldGhvZHMgaXQgaXRlcmF0ZSB0aHJvdWdoIGNoYXJhY3RlcnMKICogaW4gdGhlIG5vcm1hbGl6ZWQgPGVtPm91dHB1dDwvZW0+LiAgVGhpcyBtZWFucyB0aGF0IHRoZXJlIGlzIG5vdAogKiBuZWNlc3NhcmlseSBhIG9uZS10by1vbmUgY29ycmVzcG9uZGVuY2UgYmV0d2VlbiBjaGFyYWN0ZXJzIHJldHVybmVkCiAqIGJ5IDx0dD5uZXh0PC90dD4gYW5kIDx0dD5wcmV2aW91czwvdHQ+IGFuZCB0aGUgaW5kaWNlcyBwYXNzZWQgdG8gYW5kCiAqIHJldHVybmVkIGZyb20gPHR0PnNldEluZGV4PC90dD4gYW5kIDx0dD5nZXRJbmRleDwvdHQ+LiAgSXQgaXMgZm9yIHRoaXMKICogcmVhc29uIHRoYXQgPHR0Pk5vcm1hbGl6ZXI8L3R0PiBkb2VzIG5vdCBpbXBsZW1lbnQgdGhlCiAqIHtAbGluayBDaGFyYWN0ZXJJdGVyYXRvcn0gaW50ZXJmYWNlLgogKiA8cD4KICogPGI+Tm90ZTo8L2I+IDx0dD5Ob3JtYWxpemVyPC90dD4gaXMgY3VycmVudGx5IGJhc2VkIG9uIHZlcnNpb24gMi4xLjgKICogb2YgdGhlIDxhIGhyZWY9Imh0dHA6Ly93d3cudW5pY29kZS5vcmciIHRhcmdldD0idW5pY29kZSI+VW5pY29kZSBTdGFuZGFyZDwvYT4uCiAqIEl0IHdpbGwgYmUgdXBkYXRlZCBhcyBsYXRlciB2ZXJzaW9ucyBvZiBVbmljb2RlIGFyZSByZWxlYXNlZC4gIElmIHlvdSBhcmUKICogdXNpbmcgdGhpcyBjbGFzcyBvbiBhIEpESyB0aGF0IHN1cHBvcnRzIGFuIGVhcmxpZXIgdmVyc2lvbiBvZiBVbmljb2RlLCBpdAogKiBpcyBwb3NzaWJsZSB0aGF0IDx0dD5Ob3JtYWxpemVyPC90dD4gbWF5IGdlbmVyYXRlIGNvbXBvc2VkIG9yIGRlZGVjb21wb3NlZAogKiBjaGFyYWN0ZXJzIGZvciB3aGljaCB5b3VyIEpESydzIHtAbGluayBqYXZhLmxhbmcuQ2hhcmFjdGVyfSBjbGFzcyBkb2VzIG5vdAogKiBoYXZlIGFueSBkYXRhLgogKiA8cD4KICogQGF1dGhvciBMYXVyYSBXZXJuZXIsIE1hcmsgRGF2aXMKICovCnB1YmxpYyBmaW5hbCBjbGFzcyBOb3JtYWxpemVyIHsKCiAgICAvKioKICAgICAqIENvbnN0YW50IGluZGljYXRpbmcgdGhhdCB0aGUgZW5kIG9mIHRoZSBpdGVyYXRpb24gaGFzIGJlZW4gcmVhY2hlZC4KICAgICAqIFRoaXMgaXMgZ3VhcmFudGVlZCB0byBoYXZlIHRoZSBzYW1lIHZhbHVlIGFzIHtAbGluayBDaGFyYWN0ZXJJdGVyYXRvciNET05FfS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjaGFyIERPTkUgPSBDaGFyYWN0ZXJJdGVyYXRvci5ET05FOwoKICAgIC8vIFRoaXMgdGVsbHMgdXMgd2hhdCB0aGUgYml0cyBpbiB0aGUgIm1vZGUiIG9iamVjdCBtZWFuLgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENPTVBBVF9CSVQgPSAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFQ09NUF9CSVQgPSAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENPTVBPU0VfQklUID0gNDsKCiAgICAvKioKICAgICAqIFRoaXMgY2xhc3MgcmVwcmVzZW50cyB0aGUgbW9kZSBvZiBhIHtAbGluayBOb3JtYWxpemVyfQogICAgICogb2JqZWN0LCA8aT5pLmUuPC9pPiB0aGUgVW5pY29kZSBOb3JtYWxpemF0aW9uIEZvcm0gb2YgdGhlCiAgICAgKiB0ZXh0IHRoYXQgdGhlIDx0dD5Ob3JtYWxpemVyPC90dD4gcHJvZHVjZXMuICA8dHQ+TW9kZTwvdHQ+IG9iamVjdHMKICAgICAqIGFyZSB1c2VkIGFzIGFyZ3VtZW50cyB0byB0aGUge0BsaW5rIE5vcm1hbGl6ZXIjTm9ybWFsaXplciBjb25zdHJ1Y3RvcnN9CiAgICAgKiBhbmQge0BsaW5rIE5vcm1hbGl6ZXIjc2V0TW9kZSBzZXRNb2RlfSBtZXRob2Qgb2YgPHR0Pk5vcm1hbGl6ZXI8L3R0Pi4KICAgICAqIDxwPgogICAgICogQ2xpZW50cyBjYW5ub3QgY3JlYXRlIDx0dD5Nb2RlPC90dD4gb2JqZWN0cyBkaXJlY3RseS4KICAgICAqIEluc3RlYWQsIHVzZSB0aGUgcHJlZGVmaW5lZCBjb25zdGFudHMge0BsaW5rIE5vcm1hbGl6ZXIjTk9fT1B9LAogICAgICoge0BsaW5rIE5vcm1hbGl6ZXIjQ09NUE9TRX0sIHtAbGluayBOb3JtYWxpemVyI0NPTVBPU0VfQ09NUEFUfSwKICAgICAqIHtAbGluayBOb3JtYWxpemVyI0RFQ09NUH0sIGFuZCB7QGxpbmsgTm9ybWFsaXplciNERUNPTVBfQ09NUEFUfS4KICAgICAqIDxwPgogICAgICogQHNlZSBOb3JtYWxpemVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTW9kZSB7CiAgICAgICAgTW9kZShpbnQgbSkgewogICAgICAgICAgICBtb2RlID0gbTsKICAgICAgICB9CiAgICAgICAgZmluYWwgYm9vbGVhbiBjb21wYXQoKSB7CiAgICAgICAgICAgIHJldHVybiAobW9kZSAmIENPTVBBVF9CSVQpICE9IDA7CiAgICAgICAgfQogICAgICAgIGZpbmFsIGJvb2xlYW4gY29tcG9zZSgpIHsKICAgICAgICAgICAgcmV0dXJuIChtb2RlICYgQ09NUE9TRV9CSVQpICE9IDA7CiAgICAgICAgfQogICAgICAgIGZpbmFsIGJvb2xlYW4gZGVjb21wKCkgewogICAgICAgICAgICByZXR1cm4gKG1vZGUgJiBERUNPTVBfQklUKSAhPSAwOwogICAgICAgIH0KICAgICAgICBmaW5hbCBpbnQgbW9kZTsKICAgIH07CgogICAgLyoqCiAgICAgKiBOdWxsIG9wZXJhdGlvbiBmb3IgdXNlIHdpdGggdGhlIHtAbGluayAjTm9ybWFsaXplciBjb25zdHJ1Y3RvcnN9CiAgICAgKiBhbmQgdGhlIHN0YXRpYyB7QGxpbmsgI25vcm1hbGl6ZSBub3JtYWxpemV9IG1ldGhvZC4gIFRoaXMgdmFsdWUgdGVsbHMKICAgICAqIHRoZSA8dHQ+Tm9ybWFsaXplcjwvdHQ+IHRvIGRvIG5vdGhpbmcgYnV0IHJldHVybiB1bnByb2Nlc3NlZCBjaGFyYWN0ZXJzCiAgICAgKiBmcm9tIHRoZSB1bmRlcmx5aW5nIFN0cmluZyBvciBDaGFyYWN0ZXJJdGVyYXRvci4gIElmIHlvdSBoYXZlIGNvZGUgd2hpY2gKICAgICAqIHJlcXVpcmVzIHJhdyB0ZXh0IGF0IHNvbWUgdGltZXMgYW5kIG5vcm1hbGl6ZWQgdGV4dCBhdCBvdGhlcnMsIHlvdSBjYW4KICAgICAqIHVzZSA8dHQ+Tk9fT1A8L3R0PiBmb3IgdGhlIGNhc2VzIHdoZXJlIHlvdSB3YW50IHJhdyB0ZXh0LCByYXRoZXIKICAgICAqIHRoYW4gaGF2aW5nIGEgc2VwYXJhdGUgY29kZSBwYXRoIHRoYXQgYnlwYXNzZXMgPHR0Pk5vcm1hbGl6ZXI8L3R0PgogICAgICogYWx0b2dldGhlci4KICAgICAqIDxwPgogICAgICogQHNlZSAjc2V0TW9kZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1vZGUgTk9fT1AgPSBuZXcgTW9kZSgwKTsKCiAgICAvKioKICAgICAqIENhbm9uaWNhbCBkZWNvbXBvc2l0aW9uIGZvbGxvd2VkIGJ5IGNhbm9uaWNhbCBjb21wb3NpdGlvbi4gIFVzZWQgd2l0aCB0aGUKICAgICAqIHtAbGluayAjTm9ybWFsaXplciBjb25zdHJ1Y3RvcnN9IGFuZCB0aGUgc3RhdGljIHtAbGluayAjbm9ybWFsaXplIG5vcm1hbGl6ZX0KICAgICAqIG1ldGhvZCB0byBkZXRlcm1pbmUgdGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQuCiAgICAgKiA8cD4KICAgICAqIElmIGFsbCBvcHRpb25hbCBmZWF0dXJlcyAoPGk+ZS5nLjwvaT4ge0BsaW5rICNJR05PUkVfSEFOR1VMfSkgYXJlIHR1cm5lZAogICAgICogb2ZmLCB0aGlzIG9wZXJhdGlvbiBwcm9kdWNlcyBvdXRwdXQgdGhhdCBpcyBpbgogICAgICogPGEgaHJlZj1odHRwOi8vd3d3LnVuaWNvZGUub3JnL3VuaWNvZGUvcmVwb3J0cy90cjE1Lz5Vbmljb2RlIENhbm9uaWNhbCBGb3JtPC9hPgogICAgICogPGI+QzwvYj4uCiAgICAgKiA8cD4KICAgICAqIEBzZWUgI3NldE1vZGUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBNb2RlIENPTVBPU0UgPSBuZXcgTW9kZShDT01QT1NFX0JJVCk7CgogICAgLyoqCiAgICAgKiBDb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpb24gZm9sbG93ZWQgYnkgY2Fub25pY2FsIGNvbXBvc2l0aW9uLgogICAgICogVXNlZCB3aXRoIHRoZSB7QGxpbmsgI05vcm1hbGl6ZXIgY29uc3RydWN0b3JzfSBhbmQgdGhlIHN0YXRpYwogICAgICoge0BsaW5rICNub3JtYWxpemUgbm9ybWFsaXplfSBtZXRob2QgdG8gZGV0ZXJtaW5lIHRoZSBvcGVyYXRpb24gdG8gYmUgcGVyZm9ybWVkLgogICAgICogPHA+CiAgICAgKiBJZiBhbGwgb3B0aW9uYWwgZmVhdHVyZXMgKDxpPmUuZy48L2k+IHtAbGluayAjSUdOT1JFX0hBTkdVTH0pIGFyZSB0dXJuZWQKICAgICAqIG9mZiwgdGhpcyBvcGVyYXRpb24gcHJvZHVjZXMgb3V0cHV0IHRoYXQgaXMgaW4KICAgICAqIDxhIGhyZWY9aHR0cDovL3d3dy51bmljb2RlLm9yZy91bmljb2RlL3JlcG9ydHMvdHIxNS8+VW5pY29kZSBDYW5vbmljYWwgRm9ybTwvYT4KICAgICAqIDxiPktDPC9iPi4KICAgICAqIDxwPgogICAgICogQHNlZSAjc2V0TW9kZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1vZGUgQ09NUE9TRV9DT01QQVQgPSBuZXcgTW9kZShDT01QT1NFX0JJVCB8IENPTVBBVF9CSVQpOwoKICAgIC8qKgogICAgICogQ2Fub25pY2FsIGRlY29tcG9zaXRpb24uICBUaGlzIHZhbHVlIGlzIHBhc3NlZCB0byB0aGUKICAgICAqIHtAbGluayAjTm9ybWFsaXplciBjb25zdHJ1Y3RvcnN9IGFuZCB0aGUgc3RhdGljIHtAbGluayAjbm9ybWFsaXplIG5vcm1hbGl6ZX0KICAgICAqIG1ldGhvZCB0byBkZXRlcm1pbmUgdGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQuCiAgICAgKiA8cD4KICAgICAqIElmIGFsbCBvcHRpb25hbCBmZWF0dXJlcyAoPGk+ZS5nLjwvaT4ge0BsaW5rICNJR05PUkVfSEFOR1VMfSkgYXJlIHR1cm5lZAogICAgICogb2ZmLCB0aGlzIG9wZXJhdGlvbiBwcm9kdWNlcyBvdXRwdXQgdGhhdCBpcyBpbgogICAgICogPGEgaHJlZj1odHRwOi8vd3d3LnVuaWNvZGUub3JnL3VuaWNvZGUvcmVwb3J0cy90cjE1Lz5Vbmljb2RlIENhbm9uaWNhbCBGb3JtPC9hPgogICAgICogPGI+RDwvYj4uCiAgICAgKiA8cD4KICAgICAqIEBzZWUgI3NldE1vZGUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBNb2RlIERFQ09NUCA9IG5ldyBNb2RlKERFQ09NUF9CSVQpOwoKICAgIC8qKgogICAgICogQ29tcGF0aWJpbGl0eSBkZWNvbXBvc2l0aW9uLiAgVGhpcyB2YWx1ZSBpcyBwYXNzZWQgdG8gdGhlCiAgICAgKiB7QGxpbmsgI05vcm1hbGl6ZXIgY29uc3RydWN0b3JzfSBhbmQgdGhlIHN0YXRpYyB7QGxpbmsgI25vcm1hbGl6ZSBub3JtYWxpemV9CiAgICAgKiBtZXRob2QgdG8gZGV0ZXJtaW5lIHRoZSBvcGVyYXRpb24gdG8gYmUgcGVyZm9ybWVkLgogICAgICogPHA+CiAgICAgKiBJZiBhbGwgb3B0aW9uYWwgZmVhdHVyZXMgKDxpPmUuZy48L2k+IHtAbGluayAjSUdOT1JFX0hBTkdVTH0pIGFyZSB0dXJuZWQKICAgICAqIG9mZiwgdGhpcyBvcGVyYXRpb24gcHJvZHVjZXMgb3V0cHV0IHRoYXQgaXMgaW4KICAgICAqIDxhIGhyZWY9aHR0cDovL3d3dy51bmljb2RlLm9yZy91bmljb2RlL3JlcG9ydHMvdHIxNS8+VW5pY29kZSBDYW5vbmljYWwgRm9ybTwvYT4KICAgICAqIDxiPktEPC9iPi4KICAgICAqIDxwPgogICAgICogQHNlZSAjc2V0TW9kZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIE1vZGUgREVDT01QX0NPTVBBVCA9IG5ldyBNb2RlKERFQ09NUF9CSVQgfCBDT01QQVRfQklUKTsKCiAgICAvKioKICAgICAqIE9wdGlvbiB0byBkaXNhYmxlIEhhbmd1bC9KYW1vIGNvbXBvc2l0aW9uIGFuZCBkZWNvbXBvc2l0aW9uLgogICAgICogVGhpcyBvcHRpb24gYXBwbGllcyB0byBLb3JlYW4gdGV4dCwKICAgICAqIHdoaWNoIGNhbiBiZSByZXByZXNlbnRlZCBlaXRoZXIgaW4gdGhlIEphbW8gYWxwaGFiZXQgb3IgaW4gSGFuZ3VsCiAgICAgKiBjaGFyYWN0ZXJzLCB3aGljaCBhcmUgcmVhbGx5IGp1c3QgdHdvIG9yIHRocmVlIEphbW8gY29tYmluZWQKICAgICAqIGludG8gb25lIHZpc3VhbCBnbHlwaC4gIFNpbmNlIEphbW8gdGFrZXMgdXAgbW9yZSBzdG9yYWdlIHNwYWNlIHRoYW4KICAgICAqIEhhbmd1bCwgYXBwbGljYXRpb25zIHRoYXQgcHJvY2VzcyBvbmx5IEhhbmd1bCB0ZXh0IG1heSB3aXNoIHRvIHR1cm4KICAgICAqIHRoaXMgb3B0aW9uIG9uIHdoZW4gZGVjb21wb3NpbmcgdGV4dC4KICAgICAqIDxwPgogICAgICogVGhlIFVuaWNvZGUgc3RhbmRhcmQgdHJlYXRlcyBIYW5ndWwgdG8gSmFtbyBjb252ZXJzaW9uIGFzIGEKICAgICAqIGNhbm9uaWNhbCBkZWNvbXBvc2l0aW9uLCBzbyB0aGlzIG9wdGlvbiBtdXN0IGJlIHR1cm5lZCA8Yj5vZmY8L2I+IGlmIHlvdQogICAgICogd2lzaCB0byB0cmFuc2Zvcm0gc3RyaW5ncyBpbnRvIG9uZSBvZiB0aGUgc3RhbmRhcmQKICAgICAqIDxhIGhyZWY9Imh0dHA6Ly93d3cudW5pY29kZS5vcmcvdW5pY29kZS9yZXBvcnRzL3RyMTUvIiB0YXJnZXQ9InVuaWNvZGUiPgogICAgICogVW5pY29kZSBOb3JtYWxpemF0aW9uIEZvcm1zPC9hPi4KICAgICAqIDxwPgogICAgICogQHNlZSAjc2V0T3B0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElHTk9SRV9IQU5HVUwgPSAweDAwMDE7CgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBDb25zdHJ1Y3RvcnMKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyA8dHQ+Tm9ybWFsaXplcjwvdHQ+IG9iamVjdCBmb3IgaXRlcmF0aW5nIG92ZXIgdGhlCiAgICAgKiBub3JtYWxpemVkIGZvcm0gb2YgYSBnaXZlbiBzdHJpbmcuCiAgICAgKiA8cD4KICAgICAqIEBwYXJhbSBzdHIgICBUaGUgc3RyaW5nIHRvIGJlIG5vcm1hbGl6ZWQuICBUaGUgbm9ybWFsaXphdGlvbgogICAgICogICAgICAgICAgICAgIHdpbGwgc3RhcnQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSBtb2RlICBUaGUgbm9ybWFsaXphdGlvbiBtb2RlLgogICAgICovCiAgICBwdWJsaWMgTm9ybWFsaXplcihTdHJpbmcgc3RyLCBNb2RlIG1vZGUpIHsKICAgICAgICB0aGlzKG5ldyBTdHJpbmdDaGFyYWN0ZXJJdGVyYXRvcihzdHIpLCBtb2RlLCAwKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgPHR0Pk5vcm1hbGl6ZXI8L3R0PiBvYmplY3QgZm9yIGl0ZXJhdGluZyBvdmVyIHRoZQogICAgICogbm9ybWFsaXplZCBmb3JtIG9mIGEgZ2l2ZW4gc3RyaW5nLgogICAgICogPHA+CiAgICAgKiBUaGUgPHR0Pm9wdGlvbnM8L3R0PiBwYXJhbWV0ZXIgc3BlY2lmaWVzIHdoaWNoIG9wdGlvbmFsCiAgICAgKiA8dHQ+Tm9ybWFsaXplcjwvdHQ+IGZlYXR1cmVzIGFyZSB0byBiZSBlbmFibGVkIGZvciB0aGlzIG9iamVjdC4KICAgICAqIDxwPgogICAgICogQHBhcmFtIHN0ciAgIFRoZSBzdHJpbmcgdG8gYmUgbm9ybWFsaXplZC4gIFRoZSBub3JtYWxpemF0aW9uCiAgICAgKiAgICAgICAgICAgICAgd2lsbCBzdGFydCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcuCiAgICAgKgogICAgICogQHBhcmFtIG1vZGUgIFRoZSBub3JtYWxpemF0aW9uIG1vZGUuCiAgICAgKgogICAgICogQHBhcmFtIG9wdCAgIEFueSBvcHRpb25hbCBmZWF0dXJlcyB0byBiZSBlbmFibGVkLgogICAgICogICAgICAgICAgICAgIEN1cnJlbnRseSB0aGUgb25seSBhdmFpbGFibGUgb3B0aW9uIGlzIHtAbGluayAjSUdOT1JFX0hBTkdVTH0uCiAgICAgKiAgICAgICAgICAgICAgSWYgeW91IHdhbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgY29ycmVzcG9uZGluZyB0byBvbmUgb2YgdGhlCiAgICAgKiAgICAgICAgICAgICAgc3RhbmRhcmQgVW5pY29kZSBOb3JtYWxpemF0aW9uIEZvcm1zLCB1c2UgMCBmb3IgdGhpcyBhcmd1bWVudC4KICAgICAqLwogICAgcHVibGljIE5vcm1hbGl6ZXIoU3RyaW5nIHN0ciwgTW9kZSBtb2RlLCBpbnQgb3B0KSB7CiAgICAgICAgdGhpcyhuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3Ioc3RyKSwgbW9kZSwgb3B0KTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgPHR0Pk5vcm1hbGl6ZXI8L3R0PiBvYmplY3QgZm9yIGl0ZXJhdGluZyBvdmVyIHRoZQogICAgICogbm9ybWFsaXplZCBmb3JtIG9mIHRoZSBnaXZlbiB0ZXh0LgogICAgICogPHA+CiAgICAgKiBAcGFyYW0gaXRlciAgVGhlIGlucHV0IHRleHQgdG8gYmUgbm9ybWFsaXplZC4gIFRoZSBub3JtYWxpemF0aW9uCiAgICAgKiAgICAgICAgICAgICAgd2lsbCBzdGFydCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcuCiAgICAgKgogICAgICogQHBhcmFtIG1vZGUgIFRoZSBub3JtYWxpemF0aW9uIG1vZGUuCiAgICAgKgogICAgICovCiAgICBwdWJsaWMgTm9ybWFsaXplcihDaGFyYWN0ZXJJdGVyYXRvciBpdGVyLCBNb2RlIG1vZGUpIHsKICAgICAgICB0aGlzKGl0ZXIsIG1vZGUsIDApOwogICAgfQoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyA8dHQ+Tm9ybWFsaXplcjwvdHQ+IG9iamVjdCBmb3IgaXRlcmF0aW5nIG92ZXIgdGhlCiAgICAgKiBub3JtYWxpemVkIGZvcm0gb2YgdGhlIGdpdmVuIHRleHQuCiAgICAgKiA8cD4KICAgICAqIEBwYXJhbSBpdGVyICBUaGUgaW5wdXQgdGV4dCB0byBiZSBub3JtYWxpemVkLiAgVGhlIG5vcm1hbGl6YXRpb24KICAgICAqICAgICAgICAgICAgICB3aWxsIHN0YXJ0IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gbW9kZSAgVGhlIG5vcm1hbGl6YXRpb24gbW9kZS4KICAgICAqCiAgICAgKiBAcGFyYW0gb3B0ICAgQW55IG9wdGlvbmFsIGZlYXR1cmVzIHRvIGJlIGVuYWJsZWQuCiAgICAgKiAgICAgICAgICAgICAgQ3VycmVudGx5IHRoZSBvbmx5IGF2YWlsYWJsZSBvcHRpb24gaXMge0BsaW5rICNJR05PUkVfSEFOR1VMfS4KICAgICAqICAgICAgICAgICAgICBJZiB5b3Ugd2FudCB0aGUgZGVmYXVsdCBiZWhhdmlvciBjb3JyZXNwb25kaW5nIHRvIG9uZSBvZiB0aGUKICAgICAqICAgICAgICAgICAgICBzdGFuZGFyZCBVbmljb2RlIE5vcm1hbGl6YXRpb24gRm9ybXMsIHVzZSAwIGZvciB0aGlzIGFyZ3VtZW50LgogICAgICovCiAgICBwdWJsaWMgTm9ybWFsaXplcihDaGFyYWN0ZXJJdGVyYXRvciBpdGVyLCBNb2RlIG1vZGUsIGludCBvcHQpIHsKICAgICAgICB0ZXh0ID0gaXRlcjsKICAgICAgICB0aGlzLm1vZGUgPSBtb2RlOwogICAgICAgIG9wdGlvbnMgPSBvcHQ7CgogICAgICAgIC8vIENvbXBhdGliaWxpdHkgZXhwbG9zaW9ucyBoYXZlIGxvd2VyIGluZGljZXM7IHNraXAgdGhlbSBpZiBuZWNlc3NhcnkKICAgICAgICBtaW5EZWNvbXAgPSBtb2RlLmNvbXBhdCgpID8gMCA6IERlY29tcERhdGEuTUFYX0NPTVBBVDsKICAgIH0KCiAgICAvKioKICAgICAqIENsb25lcyB0aGlzIDx0dD5Ob3JtYWxpemVyPC90dD4gb2JqZWN0LiAgQWxsIHByb3BlcnRpZXMgb2YgdGhpcwogICAgICogb2JqZWN0IGFyZSBkdXBsaWNhdGVkIGluIHRoZSBuZXcgb2JqZWN0LCBpbmNsdWRpbmcgdGhlIGNsb25pbmcgb2YgYW55CiAgICAgKiB7QGxpbmsgQ2hhcmFjdGVySXRlcmF0b3J9IHRoYXQgd2FzIHBhc3NlZCBpbiB0byB0aGUgY29uc3RydWN0b3IKICAgICAqIG9yIHRvIHtAbGluayAjc2V0VGV4dChDaGFyYWN0ZXJJdGVyYXRvcikgc2V0VGV4dH0uCiAgICAgKiBIb3dldmVyLCB0aGUgdGV4dCBzdG9yYWdlIHVuZGVybHlpbmcKICAgICAqIHRoZSA8dHQ+Q2hhcmFjdGVySXRlcmF0b3I8L3R0PiBpcyBub3QgZHVwbGljYXRlZCB1bmxlc3MgdGhlCiAgICAgKiBpdGVyYXRvcidzIDx0dD5jbG9uZTwvdHQ+IG1ldGhvZCBkb2VzIHNvLgogICAgICovCiAgICBwdWJsaWMgT2JqZWN0IGNsb25lKCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIE5vcm1hbGl6ZXIgY29weSA9IChOb3JtYWxpemVyKSBzdXBlci5jbG9uZSgpOwogICAgICAgICAgICBjb3B5LnRleHQgPSAoQ2hhcmFjdGVySXRlcmF0b3IpIHRleHQuY2xvbmUoKTsKICAgICAgICAgICAgcmV0dXJuIGNvcHk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChDbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGUudG9TdHJpbmcoKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gU3RhdGljIHV0aWxpdHkgbWV0aG9kcwogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBOb3JtYWxpemVzIGEgPHR0PlN0cmluZzwvdHQ+IHVzaW5nIHRoZSBnaXZlbiBub3JtYWxpemF0aW9uIG9wZXJhdGlvbi4KICAgICAqIDxwPgogICAgICogVGhlIDx0dD5vcHRpb25zPC90dD4gcGFyYW1ldGVyIHNwZWNpZmllcyB3aGljaCBvcHRpb25hbAogICAgICogPHR0Pk5vcm1hbGl6ZXI8L3R0PiBmZWF0dXJlcyBhcmUgdG8gYmUgZW5hYmxlZCBmb3IgdGhpcyBvcGVyYXRpb24uCiAgICAgKiBDdXJyZW50bHkgdGhlIG9ubHkgYXZhaWxhYmxlIG9wdGlvbiBpcyB7QGxpbmsgI0lHTk9SRV9IQU5HVUx9LgogICAgICogSWYgeW91IHdhbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgY29ycmVzcG9uZGluZyB0byBvbmUgb2YgdGhlIHN0YW5kYXJkCiAgICAgKiBVbmljb2RlIE5vcm1hbGl6YXRpb24gRm9ybXMsIHVzZSAwIGZvciB0aGlzIGFyZ3VtZW50LgogICAgICogPHA+CiAgICAgKiBAcGFyYW0gc3RyICAgICAgIHRoZSBpbnB1dCBzdHJpbmcgdG8gYmUgbm9ybWFsaXplZC4KICAgICAqCiAgICAgKiBAcGFyYW0gYU1vZGUgICAgIHRoZSBub3JtYWxpemF0aW9uIG1vZGUKICAgICAqCiAgICAgKiBAcGFyYW0gb3B0aW9ucyAgIHRoZSBvcHRpb25hbCBmZWF0dXJlcyB0byBiZSBlbmFibGVkLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBub3JtYWxpemUoU3RyaW5nIHN0ciwgTW9kZSBtb2RlLCBpbnQgb3B0aW9ucykgewogICAgICAgIGlmIChtb2RlLmNvbXBvc2UoKSkgewogICAgICAgICAgICAvLyBjb21wb3NlKCkgaGFuZGxlcyBkZWNvbXBvc2l0aW9uIGFuZCByZW9yZGVyaW5nOwogICAgICAgICAgICAvLyBkb24ndCBjYWxsIGRlY29tcG9zZSgpIGZpcnN0LgogICAgICAgICAgICByZXR1cm4gY29tcG9zZShzdHIsIG1vZGUuY29tcGF0KCksIG9wdGlvbnMpOwogICAgICAgIH0KICAgICAgICBpZiAobW9kZS5kZWNvbXAoKSkgewogICAgICAgICAgICByZXR1cm4gZGVjb21wb3NlKHN0ciwgbW9kZS5jb21wYXQoKSwgb3B0aW9ucyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHI7CiAgICB9CgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBDb21wb3NlIG1ldGhvZHMKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgICogQ29tcG9zZSBhIDx0dD5TdHJpbmc8L3R0Pi4KICAgICAqIDxwPgogICAgICogVGhlIDx0dD5vcHRpb25zPC90dD4gcGFyYW1ldGVyIHNwZWNpZmllcyB3aGljaCBvcHRpb25hbAogICAgICogPHR0Pk5vcm1hbGl6ZXI8L3R0PiBmZWF0dXJlcyBhcmUgdG8gYmUgZW5hYmxlZCBmb3IgdGhpcyBvcGVyYXRpb24uCiAgICAgKiBDdXJyZW50bHkgdGhlIG9ubHkgYXZhaWxhYmxlIG9wdGlvbiBpcyB7QGxpbmsgI0lHTk9SRV9IQU5HVUx9LgogICAgICogSWYgeW91IHdhbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3IgY29ycmVzcG9uZGluZwogICAgICogdG8gVW5pY29kZSBOb3JtYWxpemF0aW9uIEZvcm0gPGI+QzwvYj4gb3IgPGI+S0M8L2I+LAogICAgICogdXNlIDAgZm9yIHRoaXMgYXJndW1lbnQuCiAgICAgKiA8cD4KICAgICAqIEBwYXJhbSBzb3VyY2UgICAgdGhlIHN0cmluZyB0byBiZSBjb21wb3NlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gY29tcGF0ICAgIFBlcmZvcm0gY29tcGF0aWJpbGl0eSBkZWNvbXBvc2l0aW9uIGJlZm9yZSBjb21wb3NpdGlvbi4KICAgICAqICAgICAgICAgICAgICAgICAgSWYgdGhpcyBhcmd1bWVudCBpcyA8dHQ+ZmFsc2U8L3R0Piwgb25seSBjYW5vbmljYWwKICAgICAqICAgICAgICAgICAgICAgICAgZGVjb21wb3NpdGlvbiB3aWxsIGJlIHBlcmZvcm1lZC4KICAgICAqCiAgICAgKiBAcGFyYW0gb3B0aW9ucyAgIHRoZSBvcHRpb25hbCBmZWF0dXJlcyB0byBiZSBlbmFibGVkLgogICAgICoKICAgICAqIEByZXR1cm4gICAgICAgICAgdGhlIGNvbXBvc2VkIHN0cmluZy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgY29tcG9zZShTdHJpbmcgc291cmNlLCBib29sZWFuIGNvbXBhdCwgaW50IG9wdGlvbnMpCiAgICB7CiAgICAgICAgU3RyaW5nQnVmZmVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKICAgICAgICBTdHJpbmdCdWZmZXIgZXhwbG9kZUJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCiAgICAgICAgaW50ICAgICBleHBsb2RlUG9zID0gRU1QVFk7ICAgICAgICAgLy8gUG9zaXRpb24gaW4gaW5wdXQgYnVmZmVyCiAgICAgICAgaW50ICAgICBiYXNlUG9zID0gMDsgICAgICAgICAgICAgICAgLy8gUG9zaXRpb24gb2YgbGFzdCBiYXNlIGluIG91dHB1dCBzdHJpbmcKICAgICAgICBpbnQgICAgIGJhc2VJbmRleCA9IDA7ICAgICAgICAgICAgICAvLyBJbmRleCBvZiBsYXN0IGJhc2UgaW4gImFjdGlvbnMiIGFycmF5CiAgICAgICAgaW50ICAgICBjbGFzc2VzU2VlbkwgPSAwOyAgICAgICAgICAgLy8gQ29tYmluaW5nIGNsYXNzZXMgc2VlbiBzaW5jZSBsYXN0IGJhc2UKICAgICAgICBpbnQgICAgIGNsYXNzZXNTZWVuSCA9IDA7ICAgICAgICAgICAvLyAgNjQtYml0IG1hc2sKICAgICAgICBpbnQgICAgIGFjdGlvbjsKCiAgICAgICAgLy8gQ29tcGF0aWJpbGl0eSBleHBsb3Npb25zIGhhdmUgbG93ZXIgaW5kaWNlczsgc2tpcCB0aGVtIGlmIG5lY2Vzc2FyeQogICAgICAgIGludCBtaW5FeHBsb2RlID0gY29tcGF0ID8gMCA6IENvbXBvc2VEYXRhLk1BWF9DT01QQVQ7CiAgICAgICAgaW50IG1pbkRlY29tcCAgPSBjb21wYXQgPyAwIDogRGVjb21wRGF0YS5NQVhfQ09NUEFUOwoKICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigibWluRXhwbG9kZSA9ICIgKyBtaW5FeHBsb2RlKTsKCiAgICAgICAgaW50IGkgPSAwOwogICAgICAgIHdoaWxlIChpIDwgc291cmNlLmxlbmd0aCgpIHx8IGV4cGxvZGVQb3MgIT0gRU1QVFkpIHsKICAgICAgICAgICAgLy8gR2V0IHRoZSBuZXh0IGNoYXIgZnJvbSBlaXRoZXIgdGhlIGJ1ZmZlciBvciB0aGUgc291cmNlCiAgICAgICAgICAgIGNoYXIgY2g7CiAgICAgICAgICAgIGlmIChleHBsb2RlUG9zID09IEVNUFRZKSB7CiAgICAgICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQXQoaSsrKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNoID0gZXhwbG9kZUJ1Zi5jaGFyQXQoZXhwbG9kZVBvcysrKTsKICAgICAgICAgICAgICAgIGlmIChleHBsb2RlUG9zID49IGV4cGxvZGVCdWYubGVuZ3RoKCkpIHsKICAgICAgICAgICAgICAgICAgICBleHBsb2RlUG9zID0gRU1QVFk7CiAgICAgICAgICAgICAgICAgICAgZXhwbG9kZUJ1Zi5zZXRMZW5ndGgoMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEdldCB0aGUgYmFzaWMgaW5mbyBmb3IgdGhlIGNoYXJhY3RlcgogICAgICAgICAgICBpbnQgY2hhckluZm8gPSBjb21wb3NlTG9va3VwKGNoKTsKICAgICAgICAgICAgaW50IHR5cGUgPSBjaGFySW5mbyAmIENvbXBvc2VEYXRhLlRZUEVfTUFTSzsKICAgICAgICAgICAgaW50IGluZGV4ID0gY2hhckluZm8gPj4+IENvbXBvc2VEYXRhLklOREVYX1NISUZUOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIkdvdCBjaGFyICIgKyBVdGlsaXR5LmhleChjaCkgKyAiLCB0eXBlPSIgKyB0eXBlICsgIiwgaW5kZXg9IiArIGluZGV4KTsKCiAgICAgICAgICAgIC8vIEV4YW1wbGVzIG9mIE5PTl9DT01QT1NJTkdfQ09NQklOSU5HIHdpdGggYW4gaW5kZXggPCBtaW5FeHBsb2RlOgogICAgICAgICAgICAvLyAwMEE4IDAxN0YgMDNEMiAxRkJGIDFGRkUKICAgICAgICAgICAgaWYgKHR5cGUgPT0gQ29tcG9zZURhdGEuQkFTRSB8fCAodHlwZSA9PSBDb21wb3NlRGF0YS5OT05fQ09NUE9TSU5HX0NPTUJJTklORyAmJiBpbmRleCA8IG1pbkV4cGxvZGUpKSB7CiAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiTmV3IGJhc2UgIiArIFV0aWxpdHkuaGV4KGNoKSArICIsIHR5cGU9IiArIHR5cGUgKyAiLCBpbmRleD0iICsgaW5kZXgpOwogICAgICAgICAgICAgICAgY2xhc3Nlc1NlZW5MID0gY2xhc3Nlc1NlZW5IID0gMDsKICAgICAgICAgICAgICAgIGJhc2VJbmRleCA9IGluZGV4OwogICAgICAgICAgICAgICAgYmFzZVBvcyA9IHJlc3VsdC5sZW5ndGgoKTsKICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoY2gpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gQ29tcG9zZURhdGEuQ09NQklOSU5HKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBhc3NlcnQoaW5kZXggPiAwKTsKICAgICAgICAgICAgICAgIGludCBjY2xhc3MgPSBDb21wb3NlRGF0YS50eXBlQml0W2luZGV4XTsKICAgICAgICAgICAgICAgIC8vIHR5cGVCaXQgaXMgYSBiaXQgdmFsdWUgZnJvbSAwLi42MywgaW5kaWNhdGluZyB0aGUgY2xhc3MuCiAgICAgICAgICAgICAgICAvLyBXZSB1c2UgYSBiaXQgbWFzayBvZiAyIDMyLWJpdCBpbnRzLgogICAgICAgICAgICAgICAgYm9vbGVhbiBzZWVuID0gMCAhPSAoKGNjbGFzcyA8IDMyKSA/CiAgICAgICAgICAgICAgICAgICAgKGNsYXNzZXNTZWVuTCAmICgxIDw8IGNjbGFzcykpIDoKICAgICAgICAgICAgICAgICAgICAoY2xhc3Nlc1NlZW5IICYgKDEgPDwgKGNjbGFzcyAmIDMxKSkpKTsKCiAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiQ2xhc3Mgb2YgIiArIFV0aWxpdHkuaGV4KGNoKSArICIgPSAiICsgY2NsYXNzICsKICAgICAgICAgICAgICAgICAgICAiIHNlZW46IiArIHNlZW4gKwogICAgICAgICAgICAgICAgICAgICIgYmFzZUluZGV4OiIgKyBiYXNlSW5kZXggKwogICAgICAgICAgICAgICAgICAgICIgYWN0aW9uOiIgKyBjb21wb3NlQWN0aW9uKGJhc2VJbmRleCwgaW5kZXgpKTsKCiAgICAgICAgICAgICAgICAvLyBXZSBjYW4gb25seSBjb21iaW5lIGEgY2hhcmFjdGVyIHdpdGggdGhlIGJhc2UgaWYgd2UgaGF2ZW4ndAogICAgICAgICAgICAgICAgLy8gYWxyZWFkeSBzZWVuIGEgY29tYmluaW5nIGNoYXJhY3RlciB3aXRoIHRoZSBzYW1lIGNhbm9uaWNhbCBjbGFzcy4KICAgICAgICAgICAgICAgIC8vIFdlIG9ubHkgY29tYmluZSBjaGFyYWN0ZXJzIHdpdGggYW4gaW5kZXggZnJvbQogICAgICAgICAgICAgICAgLy8gMS4uQ09NQklOSU5HX0NPVU5ULTEuICBJbmRpY2VzID49IENPTUJJTklOR19DT1VOVCBhcmUKICAgICAgICAgICAgICAgIC8vIGFsc28gY29tYmluaW5nIGNoYXJhY3RlcnMsIGJ1dCB3ZSBrbm93IHRoYXQgdGhleSBkb24ndAogICAgICAgICAgICAgICAgLy8gY29tcG9zZSB3aXRoIGFueXRoaW5nLgogICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgQ29tcG9zZURhdGEuQ09NQklOSU5HX0NPVU5UICYmICFzZWVuCiAgICAgICAgICAgICAgICAgICAgJiYgKGFjdGlvbiA9IGNvbXBvc2VBY3Rpb24oYmFzZUluZGV4LCBpbmRleCkpID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYWN0aW9uID4gQ29tcG9zZURhdGEuTUFYX0NPTVBPU0VEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBhaXJ3aXNlIGV4cGxvc2lvbi4gIEFjdGlvbnMgYWJvdmUgdGhpcyB2YWx1ZSBhcmUgcmVhbGx5CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluZGljZXMgaW50byBhbiBhcnJheSB0aGF0IGluIHR1cm4gY29udGFpbnMgaW5kaWNlcwogICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnRvIHRoZSBleHBsb2Rpbmcgc3RyaW5nIHRhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IFdoYXQgaWYgdGhlcmUgYXJlIHVucHJvY2Vzc2VkIGNoYXJzIGluIHRoZSBleHBsb2RlIGJ1ZmZlcj8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIlBhaXJ3aXNlIGV4cGxvZGluZyIpOwogICAgICAgICAgICAgICAgICAgICAgICBjaGFyIG5ld0Jhc2UgPSBwYWlyRXhwbG9kZShleHBsb2RlQnVmLCBhY3Rpb24pOwogICAgICAgICAgICAgICAgICAgICAgICBleHBsb2RlUG9zID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnNldENoYXJBdChiYXNlUG9zLCBuZXdCYXNlKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VJbmRleCA9IGNvbXBvc2VMb29rdXAobmV3QmFzZSkgPj4+IENvbXBvc2VEYXRhLklOREVYX1NISUZUOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiTmV3IGJhc2UgIiArIFV0aWxpdHkuaGV4KG5ld0Jhc2UpKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3JtYWwgcGFpcndpc2UgY29tYmluYXRpb24uICBSZXBsYWNlIHRoZSBiYXNlIGNoYXIKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIlBhaXJ3aXNlIGNvbWJpbmluZyIpOwogICAgICAgICAgICAgICAgICAgICAgICBjaGFyIG5ld0Jhc2UgPSAoY2hhcikgYWN0aW9uOwogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuc2V0Q2hhckF0KGJhc2VQb3MsIG5ld0Jhc2UpOwoKICAgICAgICAgICAgICAgICAgICAgICAgYmFzZUluZGV4ID0gY29tcG9zZUxvb2t1cChuZXdCYXNlKSA+Pj4gQ29tcG9zZURhdGEuSU5ERVhfU0hJRlQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJOZXcgYmFzZSAiICsgVXRpbGl0eS5oZXgobmV3QmFzZSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIC8vIFNpbmNlIHRoZXJlIGFyZSBVbmljb2RlIGNoYXJhY3RlcnMgdGhhdCBjYW5ub3QgYmUgY29tYmluZWQgaW4gYXJiaXRyYXJ5CiAgICAgICAgICAgICAgICAgICAgLy8gb3JkZXIsIHdlIGhhdmUgdG8gcmUtcHJvY2VzcyBhbnkgY29tYmluaW5nIG1hcmtzIHRoYXQgZ28gd2l0aCB0aGlzCiAgICAgICAgICAgICAgICAgICAgLy8gYmFzZSBjaGFyYWN0ZXIuICBUaGVyZSBhcmUgb25seSBmb3VyIGNoYXJhY3RlcnMgaW4gVW5pY29kZSB0aGF0IGhhdmUKICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHByb2JsZW0uICBJZiB0aGV5IGFyZSBmaXhlZCBpbiBVbmljb2RlIDMuMCwgdGhpcyBjb2RlIGNhbiBnbyBhd2F5LgogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgaW50IGxlbiA9IHJlc3VsdC5sZW5ndGgoKTsKICAgICAgICAgICAgICAgICAgICBpZiAobGVuIC0gYmFzZVBvcyA+IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IGJhc2VQb3MrMTsgaiA8IGxlbjsgaisrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBsb2RlQnVmLmFwcGVuZChyZXN1bHQuY2hhckF0KGopKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuc2V0TGVuZ3RoKGJhc2VQb3MrMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzZXNTZWVuTCA9IGNsYXNzZXNTZWVuSCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleHBsb2RlUG9zID09IEVNUFRZKSBleHBsb2RlUG9zID0gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIE5vIGNvbWJpbmF0aW9uIHdpdGggdGhpcyBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiTm8gYWN0aW9uIik7CiAgICAgICAgICAgICAgICAgICAgYnViYmxlQXBwZW5kKHJlc3VsdCwgY2gsIGNjbGFzcyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNjbGFzcyA8IDMyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzZXNTZWVuTCB8PSAxIDw8IGNjbGFzczsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjbGFzc2VzU2VlbkggfD0gMSA8PCAoY2NsYXNzICYgMzEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChpbmRleCA+IG1pbkV4cGxvZGUpIHsKICAgICAgICAgICAgICAgIC8vIFNpbmdsZSBleHBsb2RpbmcgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICBleHBsb2RlKGV4cGxvZGVCdWYsIGluZGV4KTsKICAgICAgICAgICAgICAgIGV4cGxvZGVQb3MgPSAwOwogICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImV4cGxvc2lvbjogIiArIFV0aWxpdHkuaGV4KGNoKSArICIgLS0+ICIgKyBVdGlsaXR5LmhleChleHBsb2RlQnVmKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBDb21wb3NlRGF0YS5IQU5HVUwgJiYgbWluRXhwbG9kZSA9PSAwKSB7CiAgICAgICAgICAgICAgICAvLyBJZiB3ZSdyZSBpbiBjb21wYXRpYmlsaXR5IG1vZGUgd2UgbmVlZCB0byBkZWNvbXBvc2UgSGFuZ3VsIHRvIEphbW8sCiAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIHNvbWUgb2YgdGhlIEphbW8gbWlnaHQgaGF2ZSBjb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpb25zLgogICAgICAgICAgICAgICAgaGFuZ3VsVG9KYW1vKGNoLCBleHBsb2RlQnVmLCBtaW5EZWNvbXApOwogICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImRlY29tcG9zZWQgaGFuZ3VsICIgKyBVdGlsaXR5LmhleChjaCkgKyAiIHRvIGphbW8gIiArIFV0aWxpdHkuaGV4KGV4cGxvZGVCdWYpKTsKICAgICAgICAgICAgICAgIGV4cGxvZGVQb3MgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gQ29tcG9zZURhdGEuSU5JVElBTF9KQU1PKSB7CiAgICAgICAgICAgICAgICBjbGFzc2VzU2VlbkwgPSBjbGFzc2VzU2VlbkggPSAwOwogICAgICAgICAgICAgICAgYmFzZUluZGV4ID0gQ29tcG9zZURhdGEuSU5JVElBTF9KQU1PX0lOREVYOwogICAgICAgICAgICAgICAgYmFzZVBvcyA9IHJlc3VsdC5sZW5ndGgoKTsKICAgICAgICAgICAgICAgIHJlc3VsdC5hcHBlbmQoY2gpOwogICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdvdCBpbml0aWFsIGphbW8gIiArIFV0aWxpdHkuaGV4KGNoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBDb21wb3NlRGF0YS5NRURJQUxfSkFNTyAmJiBjbGFzc2VzU2VlbkwgPT0gMCAmJiBjbGFzc2VzU2VlbkggPT0gMAogICAgICAgICAgICAgICAgICAgICAgICAmJiBiYXNlSW5kZXggPT0gQ29tcG9zZURhdGEuSU5JVElBTF9KQU1PX0lOREVYKSB7CiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGFzdCBjaGFyYWN0ZXIgd2FzIGFuIGluaXRpYWwgamFtbywgd2UgY2FuIGNvbWJpbmUgaXQgd2l0aCB0aGlzCiAgICAgICAgICAgICAgICAvLyBvbmUgdG8gY3JlYXRlIGEgSGFuZ3VsIGNoYXJhY3Rlci4KICAgICAgICAgICAgICAgIGludCBsID0gcmVzdWx0LmNoYXJBdChiYXNlUG9zKSAtIEpBTU9fTEJBU0U7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGNoIC0gSkFNT19WQkFTRTsKICAgICAgICAgICAgICAgIGNoYXIgbmV3Q2ggPSAoY2hhcikoSEFOR1VMX0JBU0UgKyAobCpKQU1PX1ZDT1VOVCArIHYpICogSkFNT19UQ09VTlQpOwogICAgICAgICAgICAgICAgcmVzdWx0LnNldENoYXJBdChiYXNlUG9zLCBuZXdDaCk7CgogICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdvdCBtZWRpYWwgamFtbyAiICsgVXRpbGl0eS5oZXgoY2gpICsgIiwgcmVwbGFjaW5nIHdpdGggSGFuZ3VsICIgKyBVdGlsaXR5LmhleChuZXdDaCkpOwoKICAgICAgICAgICAgICAgIGJhc2VJbmRleCA9IENvbXBvc2VEYXRhLk1FRElBTF9KQU1PX0lOREVYOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gQ29tcG9zZURhdGEuRklOQUxfSkFNTyAmJiBjbGFzc2VzU2VlbkwgPT0gMCAmJiBjbGFzc2VzU2VlbkggPT0gMAogICAgICAgICAgICAgICAgICAgICAgICAmJiBiYXNlSW5kZXggPT0gQ29tcG9zZURhdGEuTUVESUFMX0pBTU9fSU5ERVgpIHsKICAgICAgICAgICAgICAgIC8vIElmIHRoZSBsYXN0IGNoYXJhY3RlciB3YXMgYSBtZWRpYWwgamFtbyB0aGF0IHdlIHR1cm5lZCBpbnRvIEhhbmd1bCwKICAgICAgICAgICAgICAgIC8vIHdlIGNhbiBhZGQgdGhpcyBjaGFyYWN0ZXIgdG9vLgogICAgICAgICAgICAgICAgY2hhciBuZXdDaCA9IChjaGFyKShyZXN1bHQuY2hhckF0KGJhc2VQb3MpICsgKGNoIC0gSkFNT19UQkFTRSkpOwogICAgICAgICAgICAgICAgcmVzdWx0LnNldENoYXJBdChiYXNlUG9zLCBuZXdDaCk7CgogICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImdvdCBmaW5hbCBqYW1vICIgKyBVdGlsaXR5LmhleChjaCkgKyAiLCByZXBsYWNpbmcgd2l0aCBIYW5ndWwgIiArIFV0aWxpdHkuaGV4KG5ld0NoKSk7CgogICAgICAgICAgICAgICAgYmFzZUluZGV4ID0gMDsKICAgICAgICAgICAgICAgIGJhc2VQb3MgPSAtMTsKICAgICAgICAgICAgICAgIGNsYXNzZXNTZWVuTCA9IGNsYXNzZXNTZWVuSCA9IDA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiTm8gYmFzZSBhcyBvZiAiICsgVXRpbGl0eS5oZXgoY2gpKTsKICAgICAgICAgICAgICAgIGJhc2VJbmRleCA9IDA7CiAgICAgICAgICAgICAgICBiYXNlUG9zID0gLTE7CiAgICAgICAgICAgICAgICBjbGFzc2VzU2VlbkwgPSBjbGFzc2VzU2VlbkggPSAwOwogICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChjaCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwogICAgfQoKICAgIC8qKgogICAgICogQ29tcG9zZSBzdGFydGluZyB3aXRoIGN1cnJlbnQgaW5wdXQgY2hhcmFjdGVyIGFuZCBjb250aW51aW5nCiAgICAgKiB1bnRpbCBqdXN0IGJlZm9yZSB0aGUgbmV4dCBiYXNlIGNoYXIuCiAgICAgKiA8cD4KICAgICAqIDxiPklucHV0PC9iPjoKICAgICAqIDx1bD4KICAgICAqICA8bGk+dW5kZXJseWluZyBjaGFyIGl0ZXIgcG9pbnRzIHRvIGZpcnN0IGNoYXJhY3RlciB0byBjb21wb3NlCiAgICAgKiA8L3VsPgogICAgICogPHA+CiAgICAgKiA8Yj5PdXRwdXQ6PC9iPgogICAgICogPHVsPgogICAgICogIDxsaT5yZXR1cm5zIGZpcnN0IGNoYXIgb2YgY29tcG9zaXRpb24gb3IgRE9ORSBpZiBhdCBlbmQKICAgICAqICA8bGk+VW5kZXJseWluZyBjaGFyIGl0ZXIgaXMgcG9pbnRpbmcgYXQgbmV4dCBiYXNlIGNoYXIgb3IgcGFzdCBlbmQKICAgICAqIDwvdWw+CiAgICAgKi8KICAgIHByaXZhdGUgY2hhciBuZXh0Q29tcG9zZSgpCiAgICB7CiAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLSB0b3Agb2YgbmV4dENvbXBvc2UoKSAtLS0tLS0tLS0tLS0tLS0iKTsKCiAgICAgICAgaW50ICAgICBleHBsb2RlUG9zID0gRU1QVFk7ICAgICAgICAgLy8gUG9zaXRpb24gaW4gaW5wdXQgYnVmZmVyCiAgICAgICAgaW50ICAgICBiYXNlUG9zID0gMDsgICAgICAgICAgICAgICAgLy8gUG9zaXRpb24gb2YgbGFzdCBiYXNlIGluIG91dHB1dCBzdHJpbmcKICAgICAgICBpbnQgICAgIGJhc2VJbmRleCA9IDA7ICAgICAgICAgICAgICAvLyBJbmRleCBvZiBsYXN0IGJhc2UgaW4gImFjdGlvbnMiIGFycmF5CiAgICAgICAgaW50ICAgICBjbGFzc2VzU2VlbkwgPSAwOyAgICAgICAgICAgLy8gQ29tYmluaW5nIGNsYXNzZXMgc2VlbiBzaW5jZSBsYXN0IGJhc2UKICAgICAgICBpbnQgICAgIGNsYXNzZXNTZWVuSCA9IDA7ICAgICAgICAgICAvLyAgNjQtYml0IG1hc2sKICAgICAgICBpbnQgICAgIGFjdGlvbjsKICAgICAgICBjaGFyICAgIGxhc3RCYXNlID0gMDsKICAgICAgICBib29sZWFuIGNoRnJvbVRleHQgPSB0cnVlOwoKICAgICAgICAvLyBDb21wYXRpYmlsaXR5IGV4cGxvc2lvbnMgaGF2ZSBsb3dlciBpbmRpY2VzOyBza2lwIHRoZW0gaWYgbmVjZXNzYXJ5CiAgICAgICAgaW50IG1pbkV4cGxvZGUgPSBtb2RlLmNvbXBhdCgpID8gMCA6IENvbXBvc2VEYXRhLk1BWF9DT01QQVQ7CiAgICAgICAgaW50IG1pbkRlY29tcCAgPSBtb2RlLmNvbXBhdCgpID8gMCA6IERlY29tcERhdGEuTUFYX0NPTVBBVDsKCiAgICAgICAgaW5pdEJ1ZmZlcigpOwogICAgICAgIGlmIChleHBsb2RlQnVmID09IG51bGwpIHsKICAgICAgICAgICAgZXhwbG9kZUJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBleHBsb2RlQnVmLnNldExlbmd0aCgwKTsKICAgICAgICB9CgogICAgICAgIGNoYXIgY2ggPSBjdXJGb3J3YXJkKCk7CgogICAgICAgIHdoaWxlIChjaCAhPSBET05FKSB7CiAgICAgICAgICAgIC8vIEdldCB0aGUgYmFzaWMgaW5mbyBmb3IgdGhlIGNoYXJhY3RlcgogICAgICAgICAgICBpbnQgY2hhckluZm8gPSBjb21wb3NlTG9va3VwKGNoKTsKICAgICAgICAgICAgaW50IHR5cGUgPSBjaGFySW5mbyAmIENvbXBvc2VEYXRhLlRZUEVfTUFTSzsKICAgICAgICAgICAgaW50IGluZGV4ID0gY2hhckluZm8gPj4+IENvbXBvc2VEYXRhLklOREVYX1NISUZUOwoKICAgICAgICAgICAgaWYgKHR5cGUgPT0gQ29tcG9zZURhdGEuQkFTRSB8fCAodHlwZSA9PSBDb21wb3NlRGF0YS5OT05fQ09NUE9TSU5HX0NPTUJJTklORyAmJiBpbmRleCA8IG1pbkV4cGxvZGUpKSB7CiAgICAgICAgICAgICAgICBpZiAoYnVmZmVyLmxlbmd0aCgpID4gMCAmJiBjaEZyb21UZXh0ICYmIGV4cGxvZGVQb3MgPT0gRU1QVFkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHdlIGhpdCBhIGJhc2UgY2hhciBpbiB0aGUgc291cmNlIHRleHQsIHdlIGNhbiByZXR1cm4gdGhlIHRleHQKICAgICAgICAgICAgICAgICAgICAvLyB0aGF0J3MgYmVlbiBjb21wb3NlZCBzbyBmYXIuICBXZSdsbCByZS1wcm9jZXNzIHRoaXMgY2hhciBuZXh0IHRpbWUgdGhyb3VnaC4KICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigicmV0dXJuaW5nIGVhcmx5IGJlY2F1c2Ugd2UgaGl0IGEgbmV3IGJhc2UiKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNsYXNzZXNTZWVuTCA9IGNsYXNzZXNTZWVuSCA9IDA7CiAgICAgICAgICAgICAgICBiYXNlSW5kZXggPSBpbmRleDsKICAgICAgICAgICAgICAgIGJhc2VQb3MgPSBidWZmZXIubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGNoKTsKICAgICAgICAgICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJnb3QgQkFTRSBjaGFyICIgKyBVdGlsaXR5LmhleChjaCkgKyAiLCB0eXBlPSIgKyB0eXBlICsgIiwgaW5kZXg9IiArIGluZGV4KTsKICAgICAgICAgICAgICAgIGxhc3RCYXNlID0gY2g7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBDb21wb3NlRGF0YS5DT01CSU5JTkcpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGFzc2VydChpbmRleCA+IDApOwogICAgICAgICAgICAgICAgaW50IGNjbGFzcyA9IENvbXBvc2VEYXRhLnR5cGVCaXRbaW5kZXhdOwogICAgICAgICAgICAgICAgYm9vbGVhbiBzZWVuID0gMCAhPSAoKGNjbGFzcyA8IDMyKSA/CiAgICAgICAgICAgICAgICAgICAgKGNsYXNzZXNTZWVuTCAmICgxIDw8IGNjbGFzcykpIDoKICAgICAgICAgICAgICAgICAgICAoY2xhc3Nlc1NlZW5IICYgKDEgPDwgKGNjbGFzcyAmIDMxKSkpKTsKCiAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ290IENPTUJJTklORyBjaGFyICIgKyBVdGlsaXR5LmhleChjaCkgKyAiLCB0eXBlPSIgKyB0eXBlICsgIiwgaW5kZXg9IiArIGluZGV4CiAgICAgICAgICAgICAgICAgICAgICAgICsgIiwgY2xhc3M9IiArIGNjbGFzcyk7CgogICAgICAgICAgICAgICAgLy8gV2UgY2FuIG9ubHkgY29tYmluZSBhIGNoYXJhY3RlciB3aXRoIHRoZSBiYXNlIGlmIHdlIGhhdmVuJ3QKICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgc2VlbiBhIGNvbWJpbmluZyBjaGFyYWN0ZXIgd2l0aCB0aGUgc2FtZSBjYW5vbmljYWwgY2xhc3MuCiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPCBDb21wb3NlRGF0YS5DT01CSU5JTkdfQ09VTlQgJiYgIXNlZW4KICAgICAgICAgICAgICAgICAgICAmJiAoYWN0aW9uID0gY29tcG9zZUFjdGlvbihiYXNlSW5kZXgsIGluZGV4KSkgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gPiBDb21wb3NlRGF0YS5NQVhfQ09NUE9TRUQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFpcndpc2UgZXhwbG9zaW9uLiAgQWN0aW9ucyBhYm92ZSB0aGlzIHZhbHVlIGFyZSByZWFsbHkKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5kaWNlcyBpbnRvIGFuIGFycmF5IHRoYXQgaW4gdHVybiBjb250YWlucyBpbmRpY2VzCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGludG8gdGhlIGV4cGxvZGluZyBzdHJpbmcgdGFibGUKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogV2hhdCBpZiB0aGVyZSBhcmUgdW5wcm9jZXNzZWQgY2hhcnMgaW4gdGhlIGV4cGxvZGUgYnVmZmVyPwogICAgICAgICAgICAgICAgICAgICAgICBjaGFyIG5ld0Jhc2UgPSBwYWlyRXhwbG9kZShleHBsb2RlQnVmLCBhY3Rpb24pOwogICAgICAgICAgICAgICAgICAgICAgICBleHBsb2RlUG9zID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLnNldENoYXJBdChiYXNlUG9zLCBuZXdCYXNlKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VJbmRleCA9IGNvbXBvc2VMb29rdXAobmV3QmFzZSkgPj4+IENvbXBvc2VEYXRhLklOREVYX1NISUZUOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIlBhaXJ3aXNlIGV4cGxvc2lvbjogIiArIFV0aWxpdHkuaGV4KGxhc3RCYXNlKSArICIsIiArIFV0aWxpdHkuaGV4KGNoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIC0tPiAiICsgVXRpbGl0eS5oZXgobmV3QmFzZSkgKyAiLCIgKyBVdGlsaXR5LmhleChleHBsb2RlQnVmKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RCYXNlID0gbmV3QmFzZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3JtYWwgcGFpcndpc2UgY29tYmluYXRpb24uICBSZXBsYWNlIHRoZSBiYXNlIGNoYXIKICAgICAgICAgICAgICAgICAgICAgICAgY2hhciBuZXdCYXNlID0gKGNoYXIpIGFjdGlvbjsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLnNldENoYXJBdChiYXNlUG9zLCBuZXdCYXNlKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VJbmRleCA9IGNvbXBvc2VMb29rdXAobmV3QmFzZSkgPj4+IENvbXBvc2VEYXRhLklOREVYX1NISUZUOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIlBhaXJ3aXNlIGNvbWJpbmF0aW9uOiAiICsgVXRpbGl0eS5oZXgobGFzdEJhc2UpICsgIiwiICsgVXRpbGl0eS5oZXgoY2gpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgLS0+ICIgKyBVdGlsaXR5LmhleChuZXdCYXNlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RCYXNlID0gbmV3QmFzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBTaW5jZSB0aGVyZSBhcmUgVW5pY29kZSBjaGFyYWN0ZXJzIHRoYXQgY2Fubm90IGJlIGNvbWJpbmVkIGluIGFyYml0cmFyeQogICAgICAgICAgICAgICAgICAgIC8vIG9yZGVyLCB3ZSBoYXZlIHRvIHJlLXByb2Nlc3MgYW55IGNvbWJpbmluZyBtYXJrcyB0aGF0IGdvIHdpdGggdGhpcwogICAgICAgICAgICAgICAgICAgIC8vIGJhc2UgY2hhcmFjdGVyLiAgVGhlcmUgYXJlIG9ubHkgZm91ciBjaGFyYWN0ZXJzIGluIFVuaWNvZGUgdGhhdCBoYXZlCiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBwcm9ibGVtLiAgSWYgdGhleSBhcmUgZml4ZWQgaW4gVW5pY29kZSAzLjAsIHRoaXMgY29kZSBjYW4gZ28gYXdheS4KICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIGludCBsZW4gPSBidWZmZXIubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxlbiAtIGJhc2VQb3MgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJSZXByb2Nlc3NpbmcgY29tYmluaW5nIG1hcmtzIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBiYXNlUG9zKzE7IGogPCBsZW47IGorKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwbG9kZUJ1Zi5hcHBlbmQoYnVmZmVyLmNoYXJBdChqKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLnNldExlbmd0aChiYXNlUG9zKzEpOwogICAgICAgICAgICAgICAgICAgICAgICBjbGFzc2VzU2VlbkwgPSBjbGFzc2VzU2VlbkggPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXhwbG9kZVBvcyA9PSBFTVBUWSkgZXhwbG9kZVBvcyA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiY2hhciBkb2Vzbid0IGNvbWJpbmUiKTsKICAgICAgICAgICAgICAgICAgICAvLyBObyBjb21iaW5hdGlvbiB3aXRoIHRoaXMgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICAgICAgYnViYmxlQXBwZW5kKGJ1ZmZlciwgY2gsIGNjbGFzcyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNjbGFzcyA8IDMyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzZXNTZWVuTCB8PSAxIDw8IGNjbGFzczsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjbGFzc2VzU2VlbkggfD0gMSA8PCAoY2NsYXNzICYgMzEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChpbmRleCA+IG1pbkV4cGxvZGUpIHsKICAgICAgICAgICAgICAgIC8vIFNpbmdsZSBleHBsb2RpbmcgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICBleHBsb2RlKGV4cGxvZGVCdWYsIGluZGV4KTsKICAgICAgICAgICAgICAgIGV4cGxvZGVQb3MgPSAwOwogICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImV4cGxvc2lvbjogIiArIFV0aWxpdHkuaGV4KGNoKSArICIgLS0+ICIgKyBVdGlsaXR5LmhleChleHBsb2RlQnVmKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBDb21wb3NlRGF0YS5IQU5HVUwgJiYgbWluRXhwbG9kZSA9PSAwKSB7CiAgICAgICAgICAgICAgICAvLyBJZiB3ZSdyZSBpbiBjb21wYXRpYmlsaXR5IG1vZGUgd2UgbmVlZCB0byBkZWNvbXBvc2UgSGFuZ3VsIHRvIEphbW8sCiAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIHNvbWUgb2YgdGhlIEphbW8gbWlnaHQgaGF2ZSBjb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpb25zLgogICAgICAgICAgICAgICAgaGFuZ3VsVG9KYW1vKGNoLCBleHBsb2RlQnVmLCBtaW5EZWNvbXApOwogICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImRlY29tcG9zZWQgaGFuZ3VsICIgKyBVdGlsaXR5LmhleChjaCkgKyAiIHRvIGphbW8gIiArIFV0aWxpdHkuaGV4KGV4cGxvZGVCdWYpKTsKICAgICAgICAgICAgICAgIGV4cGxvZGVQb3MgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gQ29tcG9zZURhdGEuSU5JVElBTF9KQU1PKSB7CiAgICAgICAgICAgICAgICBpZiAoYnVmZmVyLmxlbmd0aCgpID4gMCAmJiBjaEZyb21UZXh0ICYmIGV4cGxvZGVQb3MgPT0gRU1QVFkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHdlIGhpdCBhIGJhc2UgY2hhciBpbiB0aGUgc291cmNlIHRleHQsIHdlIGNhbiByZXR1cm4gdGhlIHRleHQKICAgICAgICAgICAgICAgICAgICAvLyB0aGF0J3MgYmVlbiBjb21wb3NlZCBzbyBmYXIuICBXZSdsbCByZS1wcm9jZXNzIHRoaXMgY2hhciBuZXh0IHRpbWUgdGhyb3VnaC4KICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigicmV0dXJuaW5nIGVhcmx5IGJlY2F1c2Ugd2UgaGl0IGEgbmV3IGJhc2UiKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNsYXNzZXNTZWVuTCA9IGNsYXNzZXNTZWVuSCA9IDA7CiAgICAgICAgICAgICAgICBiYXNlSW5kZXggPSBDb21wb3NlRGF0YS5JTklUSUFMX0pBTU9fSU5ERVg7CiAgICAgICAgICAgICAgICBiYXNlUG9zID0gYnVmZmVyLmxlbmd0aCgpOwogICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChjaCk7CiAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ290IGluaXRpYWwgamFtbyAiICsgVXRpbGl0eS5oZXgoY2gpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IENvbXBvc2VEYXRhLk1FRElBTF9KQU1PICYmIGNsYXNzZXNTZWVuTCA9PSAwICYmIGNsYXNzZXNTZWVuSCA9PSAwCiAgICAgICAgICAgICAgICAgICAgICAgICYmIGJhc2VJbmRleCA9PSBDb21wb3NlRGF0YS5JTklUSUFMX0pBTU9fSU5ERVgpIHsKICAgICAgICAgICAgICAgIC8vIElmIHRoZSBsYXN0IGNoYXJhY3RlciB3YXMgYW4gaW5pdGlhbCBqYW1vLCB3ZSBjYW4gY29tYmluZSBpdCB3aXRoIHRoaXMKICAgICAgICAgICAgICAgIC8vIG9uZSB0byBjcmVhdGUgYSBIYW5ndWwgY2hhcmFjdGVyLgogICAgICAgICAgICAgICAgaW50IGwgPSBidWZmZXIuY2hhckF0KGJhc2VQb3MpIC0gSkFNT19MQkFTRTsKICAgICAgICAgICAgICAgIGludCB2ID0gY2ggLSBKQU1PX1ZCQVNFOwogICAgICAgICAgICAgICAgY2hhciBuZXdDaCA9IChjaGFyKShIQU5HVUxfQkFTRSArIChsKkpBTU9fVkNPVU5UICsgdikgKiBKQU1PX1RDT1VOVCk7CiAgICAgICAgICAgICAgICBidWZmZXIuc2V0Q2hhckF0KGJhc2VQb3MsIG5ld0NoKTsKCiAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ290IG1lZGlhbCBqYW1vICIgKyBVdGlsaXR5LmhleChjaCkgKyAiLCByZXBsYWNpbmcgd2l0aCBIYW5ndWwgIiArIFV0aWxpdHkuaGV4KG5ld0NoKSk7CgogICAgICAgICAgICAgICAgYmFzZUluZGV4ID0gQ29tcG9zZURhdGEuTUVESUFMX0pBTU9fSU5ERVg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBDb21wb3NlRGF0YS5GSU5BTF9KQU1PICYmIGNsYXNzZXNTZWVuTCA9PSAwICYmIGNsYXNzZXNTZWVuSCA9PSAwCiAgICAgICAgICAgICAgICAgICAgICAgICYmIGJhc2VJbmRleCA9PSBDb21wb3NlRGF0YS5NRURJQUxfSkFNT19JTkRFWCkgewogICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxhc3QgY2hhcmFjdGVyIHdhcyBhIG1lZGlhbCBqYW1vIHRoYXQgd2UgdHVybmVkIGludG8gSGFuZ3VsLAogICAgICAgICAgICAgICAgLy8gd2UgY2FuIGFkZCB0aGlzIGNoYXJhY3RlciB0b28uCiAgICAgICAgICAgICAgICBjaGFyIG5ld0NoID0gKGNoYXIpKGJ1ZmZlci5jaGFyQXQoYmFzZVBvcykgKyAoY2ggLSBKQU1PX1RCQVNFKSk7CiAgICAgICAgICAgICAgICBidWZmZXIuc2V0Q2hhckF0KGJhc2VQb3MsIG5ld0NoKTsKCiAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZ290IGZpbmFsIGphbW8gIiArIFV0aWxpdHkuaGV4KGNoKSArICIsIHJlcGxhY2luZyB3aXRoIEhhbmd1bCAiICsgVXRpbGl0eS5oZXgobmV3Q2gpKTsKCiAgICAgICAgICAgICAgICBiYXNlSW5kZXggPSAwOwogICAgICAgICAgICAgICAgYmFzZVBvcyA9IC0xOwogICAgICAgICAgICAgICAgY2xhc3Nlc1NlZW5MID0gY2xhc3Nlc1NlZW5IID0gMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFRPRE86IGRlYWwgd2l0aCBKQU1PIGNoYXJhY3RlciB0eXBlcwogICAgICAgICAgICAgICAgYmFzZUluZGV4ID0gMDsKICAgICAgICAgICAgICAgIGJhc2VQb3MgPSAtMTsKICAgICAgICAgICAgICAgIGNsYXNzZXNTZWVuTCA9IGNsYXNzZXNTZWVuSCA9IDA7CiAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGNoKTsKICAgICAgICAgICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJVTktOT1dOIGNoYXIgIiArIFV0aWxpdHkuaGV4KGNoKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChleHBsb2RlUG9zID09IEVNUFRZKSB7CiAgICAgICAgICAgICAgICBjaCA9IHRleHQubmV4dCgpOwogICAgICAgICAgICAgICAgY2hGcm9tVGV4dCA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjaCA9IGV4cGxvZGVCdWYuY2hhckF0KGV4cGxvZGVQb3MrKyk7CiAgICAgICAgICAgICAgICBpZiAoZXhwbG9kZVBvcyA+PSBleHBsb2RlQnVmLmxlbmd0aCgpKSB7CiAgICAgICAgICAgICAgICAgICAgZXhwbG9kZVBvcyA9IEVNUFRZOwogICAgICAgICAgICAgICAgICAgIGV4cGxvZGVCdWYuc2V0TGVuZ3RoKDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2hGcm9tVGV4dCA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChidWZmZXIubGVuZ3RoKCkgPiAwKSB7CiAgICAgICAgICAgIGJ1ZmZlckxpbWl0ID0gYnVmZmVyLmxlbmd0aCgpIC0gMTsKICAgICAgICAgICAgY2ggPSBidWZmZXIuY2hhckF0KDApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNoID0gRE9ORTsKICAgICAgICAgICAgYnVmZmVyTGltaXQgPSAwOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY2g7CiAgICB9CgogICAgLyoqCiAgICAgKiBDb21wb3NlIHN0YXJ0aW5nIHdpdGggdGhlIGlucHV0IGNoYXIganVzdCBiZWZvcmUgdGhlIGN1cnJlbnQgcG9zaXRpb24KICAgICAqIGFuZCBjb250aW51aW5nIGJhY2t3YXJkIHVudGlsIChhbmQgaW5jbHVkaW5nKSB0aGUgcHJldmlvdXMgYmFzZSBjaGFyLgogICAgICogPHA+CiAgICAgKiA8Yj5JbnB1dDwvYj46CiAgICAgKiA8dWw+CiAgICAgKiAgPGxpPnVuZGVybHlpbmcgY2hhciBpdGVyIHBvaW50cyBqdXN0IGFmdGVyIGxhc3QgY2hhciB0byBkZWNvbXBvc2UKICAgICAqIDwvdWw+CiAgICAgKiA8cD4KICAgICAqIDxiPk91dHB1dDo8L2I+CiAgICAgKiA8dWw+CiAgICAgKiAgPGxpPnJldHVybnMgbGFzdCBjaGFyIG9mIHJlc3VsdGluZyBkZWNvbXBvc2l0aW9uIHNlcXVlbmNlCiAgICAgKiAgPGxpPnVuZGVybHlpbmcgaXRlciBwb2ludHMgdG8gbG93ZXN0LWluZGV4IGNoYXIgd2UgZGVjb21wb3NlZCwgaS5lLiB0aGUgYmFzZSBjaGFyCiAgICAgKiA8L3VsPgogICAgICovCiAgICBwcml2YXRlIGNoYXIgcHJldkNvbXBvc2UoKSB7CiAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLSB0b3Agb2YgcHJldkNvbXBvc2UoKSAtLS0tLS0tLS0tLS0tLS0iKTsKCiAgICAgICAgLy8gQ29tcGF0aWJpbGl0eSBleHBsb3Npb25zIGhhdmUgbG93ZXIgaW5kaWNlczsgc2tpcCB0aGVtIGlmIG5lY2Vzc2FyeQogICAgICAgIGludCBtaW5FeHBsb2RlID0gbW9kZS5jb21wYXQoKSA/IDAgOiBDb21wb3NlRGF0YS5NQVhfQ09NUEFUOwoKICAgICAgICBpbml0QnVmZmVyKCk7CgogICAgICAgIC8vIFNsdXJwIHVwIGNoYXJhY3RlcnMgdW50aWwgd2UgaGl0IGEgYmFzZSBjaGFyIG9yIGFuIGluaXRpYWwgSmFtbwogICAgICAgIGNoYXIgY2g7CiAgICAgICAgd2hpbGUgKChjaCA9IGN1ckJhY2t3YXJkKCkpICE9IERPTkUpIHsKICAgICAgICAgICAgYnVmZmVyLmluc2VydCgwLCBjaCk7CgogICAgICAgICAgICAvLyBHZXQgdGhlIGJhc2ljIGluZm8gZm9yIHRoZSBjaGFyYWN0ZXIKICAgICAgICAgICAgaW50IGNoYXJJbmZvID0gY29tcG9zZUxvb2t1cChjaCk7CiAgICAgICAgICAgIGludCB0eXBlID0gY2hhckluZm8gJiBDb21wb3NlRGF0YS5UWVBFX01BU0s7CiAgICAgICAgICAgIGludCBpbmRleCA9IGNoYXJJbmZvID4+PiBDb21wb3NlRGF0YS5JTkRFWF9TSElGVDsKCiAgICAgICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJwcmV2Q29tcG9zZSBnb3QgY2hhciAiICsgVXRpbGl0eS5oZXgoY2gpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiwgdHlwZT0iICsgdHlwZSArICIsIGluZGV4PSIgKyBpbmRleCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIsIG1pbkV4cGxvZGU9IiArIG1pbkV4cGxvZGUpOwoKICAgICAgICAgICAgaWYgKHR5cGUgPT0gQ29tcG9zZURhdGEuQkFTRQogICAgICAgICAgICAgICAgfHwgKHR5cGUgPT0gQ29tcG9zZURhdGEuTk9OX0NPTVBPU0lOR19DT01CSU5JTkcgJiYgaW5kZXggPCBtaW5FeHBsb2RlKQogICAgICAgICAgICAgICAgfHwgdHlwZSA9PSBDb21wb3NlRGF0YS5IQU5HVUwKICAgICAgICAgICAgICAgIHx8IHR5cGUgPT0gQ29tcG9zZURhdGEuSU5JVElBTF9KQU1PKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBJZiB0aGVyZSdzIG1vcmUgdGhhbiBvbmUgY2hhcmFjdGVyIGluIHRoZSBidWZmZXIsIGNvbXBvc2UgaXQgYWxsIGF0IG9uY2UuLi4uCiAgICAgICAgaWYgKGJ1ZmZlci5sZW5ndGgoKSA+IDApIHsKICAgICAgICAgICAgLy8gVE9ETzogVGhlIHBlcmZvcm1hbmNlIG9mIHRoaXMgaXMgYXdmdWw7IGFkZCBhIHdheSB0byBjb21wb3NlCiAgICAgICAgICAgIC8vIGEgU3RyaW5nQnVmZmVyIGluIHBsYWNlLgogICAgICAgICAgICBTdHJpbmcgY29tcG9zZWQgPSBjb21wb3NlKGJ1ZmZlci50b1N0cmluZygpLCBtb2RlLmNvbXBhdCgpLCBvcHRpb25zKTsKICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oInByZXZDb21wb3NlIGNhbGxlZCBjb21wb3NlKCIgKyBVdGlsaXR5LmhleChidWZmZXIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiktPiIgKyBVdGlsaXR5LmhleChjb21wb3NlZCkpOyAgICAgICAgICAgIAogICAgICAgICAgICBidWZmZXIuc2V0TGVuZ3RoKDApOwogICAgICAgICAgICBidWZmZXIuYXBwZW5kKGNvbXBvc2VkKTsKCiAgICAgICAgICAgIGlmIChidWZmZXIubGVuZ3RoKCkgPiAxKSB7CiAgICAgICAgICAgICAgICBidWZmZXJMaW1pdCA9IGJ1ZmZlclBvcyA9IGJ1ZmZlci5sZW5ndGgoKSAtIDE7CiAgICAgICAgICAgICAgICBjaCA9IGJ1ZmZlci5jaGFyQXQoYnVmZmVyUG9zKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNoID0gYnVmZmVyLmNoYXJBdCgwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgY2ggPSBET05FOwogICAgICAgIH0KCiAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oInByZXZDb21wb3NlIHJldHVybmluZyAiICsgVXRpbGl0eS5oZXgoY2gpKTsKICAgICAgICByZXR1cm4gY2g7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBidWJibGVBcHBlbmQoU3RyaW5nQnVmZmVyIHRhcmdldCwgY2hhciBjaCwgaW50IGNjbGFzcykgewogICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIgYnViYmxlQXBwZW5kKCIgKyBVdGlsaXR5LmhleCh0YXJnZXQpICsgIiwgIiArIFV0aWxpdHkuaGV4KGNoKSArICIsICIgKyBjY2xhc3MgKyAiKSIgKTsKICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiICBnZXRDb21wb3NlQ2xhc3MoIiArIFV0aWxpdHkuaGV4KGNoKSArICIpPSIgKyBnZXRDb21wb3NlQ2xhc3MoY2gpKTsKICAgICAgICBpbnQgaTsKICAgICAgICBmb3IgKGkgPSB0YXJnZXQubGVuZ3RoKCkgLSAxOyBpID4gMDsgLS1pKSB7CiAgICAgICAgICAgIGludCBpQ2xhc3MgPSBnZXRDb21wb3NlQ2xhc3ModGFyZ2V0LmNoYXJBdChpKSk7CiAgICAgICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIgYnViYmxlQXBwZW5kOiB0YXJnZXRbIiArIGkgKyAiXT0iICsgVXRpbGl0eS5oZXgodGFyZ2V0LmNoYXJBdChpKSkgKyAiIGlzIGNsYXNzICIgKyBpQ2xhc3MpOwoKICAgICAgICAgICAgaWYgKGlDbGFzcyA9PSAxIHx8IGlDbGFzcyA8PSBjY2xhc3MpIHsgICAgICAvLyAxIG1lYW5zIGNvbWJpbmluZyBjbGFzcyAwCiAgICAgICAgICAgICAgICAvLyBXZSd2ZSBoaXQgc29tZXRoaW5nIHdlIGNhbid0IGJ1YmJsZSB0aGlzIGNoYXJhY3RlciBwYXN0LCBzbyBpbnNlcnQgaGVyZQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gV2UgbmVlZCB0byBpbnNlcnQganVzdCBhZnRlciBjaGFyYWN0ZXIgImkiCiAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIiBidWJibGVBcHBlbmQgaW5zZXJ0aW5nIGF0IGluZGV4ICIgKyAoaSsxKSk7CiAgICAgICAgdGFyZ2V0Lmluc2VydChpKzEsIGNoKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBpbnQgZ2V0Q29tcG9zZUNsYXNzKGNoYXIgY2gpIHsKICAgICAgICBpbnQgY2NsYXNzID0gMDsKICAgICAgICBpbnQgY2hhckluZm8gPSBjb21wb3NlTG9va3VwKGNoKTsKICAgICAgICBpbnQgdHlwZSA9IGNoYXJJbmZvICYgQ29tcG9zZURhdGEuVFlQRV9NQVNLOwogICAgICAgIGlmICh0eXBlID09IENvbXBvc2VEYXRhLkNPTUJJTklORykgewogICAgICAgICAgICBjY2xhc3MgPSBDb21wb3NlRGF0YS50eXBlQml0W2NoYXJJbmZvID4+PiBDb21wb3NlRGF0YS5JTkRFWF9TSElGVF07CiAgICAgICAgfQogICAgICAgIHJldHVybiBjY2xhc3M7CiAgICB9CgogICAgc3RhdGljIGZpbmFsIGludCBjb21wb3NlTG9va3VwKGNoYXIgY2gpIHsKICAgICAgICByZXR1cm4gQ29tcG9zZURhdGEubG9va3VwLmVsZW1lbnRBdChjaCk7CiAgICB9CgogICAgc3RhdGljIGZpbmFsIGludCBjb21wb3NlQWN0aW9uKGludCBiYXNlSW5kZXgsIGludCBjb21JbmRleCkgewogICAgICAgIHJldHVybiBDb21wb3NlRGF0YS5hY3Rpb25zLmVsZW1lbnRBdCgoY2hhcikoYmFzZUluZGV4CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBDb21wb3NlRGF0YS5NQVhfQkFTRVMqY29tSW5kZXgpKTsKICAgIH0KCiAgICBzdGF0aWMgZmluYWwgdm9pZCBleHBsb2RlKFN0cmluZ0J1ZmZlciB0YXJnZXQsIGludCBpbmRleCkgewogICAgICAgIGNoYXIgY2g7CiAgICAgICAgd2hpbGUgKChjaCA9IENvbXBvc2VEYXRhLnJlcGxhY2UuY2hhckF0KGluZGV4KyspKSAhPSAwKQogICAgICAgICAgICB0YXJnZXQuYXBwZW5kKGNoKTsKICAgIH0KCiAgICBzdGF0aWMgZmluYWwgY2hhciBwYWlyRXhwbG9kZShTdHJpbmdCdWZmZXIgdGFyZ2V0LCBpbnQgYWN0aW9uKSB7CiAgICAgICAgaW50IGluZGV4ID0gQ29tcG9zZURhdGEuYWN0aW9uSW5kZXhbYWN0aW9uIC0gQ29tcG9zZURhdGEuTUFYX0NPTVBPU0VEXTsKICAgICAgICBleHBsb2RlKHRhcmdldCwgaW5kZXggKyAxKTsKICAgICAgICByZXR1cm4gQ29tcG9zZURhdGEucmVwbGFjZS5jaGFyQXQoaW5kZXgpOyAgIC8vIE5ldyBiYXNlIGNoYXIKICAgIH0KCgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBEZWNvbXBvc2UgbWV0aG9kcwogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBTdGF0aWMgbWV0aG9kIHRvIGRlY29tcG9zZSBhIDx0dD5TdHJpbmc8L3R0Pi4KICAgICAqIDxwPgogICAgICogVGhlIDx0dD5vcHRpb25zPC90dD4gcGFyYW1ldGVyIHNwZWNpZmllcyB3aGljaCBvcHRpb25hbAogICAgICogPHR0Pk5vcm1hbGl6ZXI8L3R0PiBmZWF0dXJlcyBhcmUgdG8gYmUgZW5hYmxlZCBmb3IgdGhpcyBvcGVyYXRpb24uCiAgICAgKiBDdXJyZW50bHkgdGhlIG9ubHkgYXZhaWxhYmxlIG9wdGlvbiBpcyB7QGxpbmsgI0lHTk9SRV9IQU5HVUx9LgogICAgICogVGhlIGRlc2lyZWQgb3B0aW9ucyBzaG91bGQgYmUgT1InZWQgdG9nZXRoZXIgdG8gZGV0ZXJtaW5lIHRoZSB2YWx1ZQogICAgICogb2YgdGhpcyBhcmd1bWVudC4gIElmIHlvdSB3YW50IHRoZSBkZWZhdWx0IGJlaGF2aW9yIGNvcnJlc3BvbmRpbmcKICAgICAqIHRvIFVuaWNvZGUgTm9ybWFsaXphdGlvbiBGb3JtIDxiPkQ8L2I+IG9yIDxiPktEPC9iPiwKICAgICAqIHVzZSAwIGZvciB0aGlzIGFyZ3VtZW50LgogICAgICogPHA+CiAgICAgKiBAcGFyYW0gc3RyICAgdGhlIHN0cmluZyB0byBiZSBkZWNvbXBvc2VkLgogICAgICoKICAgICAqIEBwYXJhbSBjb21wYXQgICAgUGVyZm9ybSBjb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpb24uCiAgICAgKiAgICAgICAgICAgICAgICAgIElmIHRoaXMgYXJndW1lbnQgaXMgPHR0PmZhbHNlPC90dD4sIG9ubHkgY2Fub25pY2FsCiAgICAgKiAgICAgICAgICAgICAgICAgIGRlY29tcG9zaXRpb24gd2lsbCBiZSBwZXJmb3JtZWQuCiAgICAgKgogICAgICoKICAgICAqIEByZXR1cm4gICAgICB0aGUgZGVjb21wb3NlZCBzdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGRlY29tcG9zZShTdHJpbmcgc291cmNlLCBib29sZWFuIGNvbXBhdCwgaW50IG9wdGlvbnMpCiAgICB7CiAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLSB0b3Agb2YgZGVjb21wb3NlKCkgLS0tLS0tLS0tLS0tLS0tIik7CgogICAgICAgIGJvb2xlYW4gaGFuZ3VsID0gKG9wdGlvbnMgJiBJR05PUkVfSEFOR1VMKSA9PSAwOwogICAgICAgIGludCBtaW5EZWNvbXAgPSBjb21wYXQgPyAwIDogRGVjb21wRGF0YS5NQVhfQ09NUEFUOwogCiAgICAgICAgU3RyaW5nQnVmZmVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbnVsbDsKCiAgICAgICAgaW50IGkgPSAwLCBidWZQdHIgPSAtMTsKCiAgICAgICAgd2hpbGUgKGkgPCBzb3VyY2UubGVuZ3RoKCkgfHwgYnVmUHRyID49IDApCiAgICAgICAgewogICAgICAgICAgICBjaGFyIGNoOwoKICAgICAgICAgICAgaWYgKGJ1ZlB0ciA+PSAwKSB7CiAgICAgICAgICAgICAgICBjaCA9IGJ1ZmZlci5jaGFyQXQoYnVmUHRyKyspOwogICAgICAgICAgICAgICAgaWYgKGJ1ZlB0ciA9PSBidWZmZXIubGVuZ3RoKCkpIHsKICAgICAgICAgICAgICAgICAgICBidWZQdHIgPSAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNoID0gc291cmNlLmNoYXJBdChpKyspOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpbnQgb2Zmc2V0ID0gRGVjb21wRGF0YS5vZmZzZXRzLmVsZW1lbnRBdChjaCk7CiAgICAgICAgICAgIGludCBpbmRleCA9IG9mZnNldCAmIERlY29tcERhdGEuREVDT01QX01BU0s7CgogICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiZGVjb21wb3NlIGdvdCAiICsgVXRpbGl0eS5oZXgoY2gpKTsKCiAgICAgICAgICAgIGlmIChpbmRleCA+IG1pbkRlY29tcCkgewogICAgICAgICAgICAgICAgaWYgKChvZmZzZXQgJiBEZWNvbXBEYXRhLkRFQ09NUF9SRUNVUlNFKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIiAiICsgVXRpbGl0eS5oZXgoY2gpICsgIiBoYXMgUkVDVVJTSVZFIGRlY29tcG9zaXRpb24sIGluZGV4PSIgKyBpbmRleCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1ZmZlciA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIuc2V0TGVuZ3RoKDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBkb0FwcGVuZChEZWNvbXBEYXRhLmNvbnRlbnRzLCBpbmRleCwgYnVmZmVyKTsKICAgICAgICAgICAgICAgICAgICBidWZQdHIgPSAwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiICIgKyBVdGlsaXR5LmhleChjaCkgKyAiIGhhcyBkZWNvbXBvc2l0aW9uLCBpbmRleD0iICsgaW5kZXgpOwogICAgICAgICAgICAgICAgICAgIGRvQXBwZW5kKERlY29tcERhdGEuY29udGVudHMsIGluZGV4LCByZXN1bHQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKGNoID49IEhBTkdVTF9CQVNFICYmIGNoIDwgSEFOR1VMX0xJTUlUICYmIGhhbmd1bCkgewogICAgICAgICAgICAgICAgaGFuZ3VsVG9KYW1vKGNoLCByZXN1bHQsIG1pbkRlY29tcCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXN1bHQuYXBwZW5kKGNoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmaXhDYW5vbmljYWwocmVzdWx0KTsKICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBEZWNvbXBvc2Ugc3RhcnRpbmcgd2l0aCBjdXJyZW50IGlucHV0IGNoYXJhY3RlciBhbmQgY29udGludWluZwogICAgICogdW50aWwganVzdCBiZWZvcmUgdGhlIG5leHQgYmFzZSBjaGFyLgogICAgICogPHA+CiAgICAgKiA8Yj5JbnB1dDwvYj46CiAgICAgKiA8dWw+CiAgICAgKiAgPGxpPnVuZGVybHlpbmcgY2hhciBpdGVyIHBvaW50cyB0byBmaXJzdCBjaGFyYWN0ZXIgdG8gZGVjb21wb3NlCiAgICAgKiA8L3VsPgogICAgICogPHA+CiAgICAgKiA8Yj5PdXRwdXQ6PC9iPgogICAgICogPHVsPgogICAgICogIDxsaT5yZXR1cm5zIGZpcnN0IGNoYXIgb2YgZGVjb21wb3NpdGlvbiBvciBET05FIGlmIGF0IGVuZAogICAgICogIDxsaT5VbmRlcmx5aW5nIGNoYXIgaXRlciBpcyBwb2ludGluZyBhdCBuZXh0IGJhc2UgY2hhciBvciBwYXN0IGVuZAogICAgICogPC91bD4KICAgICAqLwogICAgcHJpdmF0ZSBjaGFyIG5leHREZWNvbXAoKQogICAgewogICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0gdG9wIG9mIG5leHREZWNvbXAoKSAtLS0tLS0tLS0tLS0tLS0iKTsKCiAgICAgICAgYm9vbGVhbiBoYW5ndWwgPSAob3B0aW9ucyAmIElHTk9SRV9IQU5HVUwpID09IDA7CiAgICAgICAgY2hhciBjaCA9IGN1ckZvcndhcmQoKTsKCiAgICAgICAgaW50IG9mZnNldCA9IERlY29tcERhdGEub2Zmc2V0cy5lbGVtZW50QXQoY2gpOwogICAgICAgIGludCBpbmRleCA9IG9mZnNldCAmIERlY29tcERhdGEuREVDT01QX01BU0s7CgogICAgICAgIGlmIChpbmRleCA+IG1pbkRlY29tcCB8fCBEZWNvbXBEYXRhLmNhbm9uQ2xhc3MuZWxlbWVudEF0KGNoKSAhPSBEZWNvbXBEYXRhLkJBU0UpCiAgICAgICAgewogICAgICAgICAgICBpbml0QnVmZmVyKCk7CgogICAgICAgICAgICBpZiAoaW5kZXggPiBtaW5EZWNvbXApIHsKICAgICAgICAgICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIgIiArIFV0aWxpdHkuaGV4KGNoKSArICIgaGFzIGRlY29tcG9zaXRpb24sIGluZGV4PSIgKyBpbmRleCk7CiAgICAgICAgICAgICAgICBkb0FwcGVuZChEZWNvbXBEYXRhLmNvbnRlbnRzLCBpbmRleCwgYnVmZmVyKTsKCiAgICAgICAgICAgICAgICBpZiAoKG9mZnNldCAmIERlY29tcERhdGEuREVDT01QX1JFQ1VSU0UpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAvLyBOZWVkIHRvIGRlY29tcG9zZSB0aGUgb3V0cHV0IG9mIHRoaXMgZGVjb21wb3NpdGlvbiByZWN1cnNpdmVseS4KICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ1ZmZlci5sZW5ndGgoKTsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gYnVmZmVyLmNoYXJBdChpKTsKICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBEZWNvbXBEYXRhLm9mZnNldHMuZWxlbWVudEF0KGNoKSAmIERlY29tcERhdGEuREVDT01QX01BU0s7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiBtaW5EZWNvbXApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgKz0gZG9SZXBsYWNlKERlY29tcERhdGEuY29udGVudHMsIGluZGV4LCBidWZmZXIsIGkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYnVmZmVyLmFwcGVuZChjaCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYm9vbGVhbiBuZWVkVG9SZW9yZGVyID0gZmFsc2U7CgogICAgICAgICAgICAvLyBBbnkgb3RoZXIgY29tYmluaW5nIGNoYWN0ZXJzIHRoYXQgaW1tZWRpYXRlbHkgZm9sbG93IHRoZSBkZWNvbXBvc2VkCiAgICAgICAgICAgIC8vIGNoYXJhY3RlciBtdXN0IGJlIGluY2x1ZGVkIGluIHRoZSBidWZmZXIgdG9vLCBiZWNhdXNlIHRoZXkncmUKICAgICAgICAgICAgLy8gY29uY2VwdHVhbGx5IHBhcnQgb2YgdGhlIHNhbWUgbG9naWNhbCBjaGFyYWN0ZXIuCiAgICAgICAgICAgIHdoaWxlICgoY2ggPSB0ZXh0Lm5leHQoKSkgIT0gRE9ORQogICAgICAgICAgICAgICAgJiYgRGVjb21wRGF0YS5jYW5vbkNsYXNzLmVsZW1lbnRBdChjaCkgIT0gRGVjb21wRGF0YS5CQVNFKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuZWVkVG9SZW9yZGVyID0gdHJ1ZTsKICAgICAgICAgICAgICAgIC8vIERlY29tcG9zZSBhbnkgb2YgdGhlc2UgY2hhcmFjdGVycyB0aGF0IG5lZWQgaXQgLSBMaXUKICAgICAgICAgICAgICAgIGluZGV4ID0gRGVjb21wRGF0YS5vZmZzZXRzLmVsZW1lbnRBdChjaCkgJiBEZWNvbXBEYXRhLkRFQ09NUF9NQVNLOwogICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gbWluRGVjb21wKSB7CiAgICAgICAgICAgICAgICAgICAgZG9BcHBlbmQoRGVjb21wRGF0YS5jb250ZW50cywgaW5kZXgsIGJ1ZmZlcik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoY2gpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoYnVmZmVyLmxlbmd0aCgpID4gMSAmJiBuZWVkVG9SZW9yZGVyKSB7CiAgICAgICAgICAgICAgICAvLyBJZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGNvbWJpbmluZyBjaGFyYWN0ZXIgaW4gdGhlIGJ1ZmZlciwKICAgICAgICAgICAgICAgIC8vIHB1dCB0aGVtIGludG8gdGhlIGNhbm9uaWNhbCBvcmRlci4KICAgICAgICAgICAgICAgIC8vIEJ1dCB3ZSBkb24ndCBuZWVkIHRvIHNvcnQgaWYgb25seSBjaGFyYWN0ZXJzIGFyZSB0aGUgb25lcyB0aGF0CiAgICAgICAgICAgICAgICAvLyByZXN1bHRlZCBmcm9tIGRlY29tb3NpbmcgdGhlIGJhc2UgY2hhcmFjdGVyLgogICAgICAgICAgICAgICAgZml4Q2Fub25pY2FsKGJ1ZmZlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnVmZmVyTGltaXQgPSBidWZmZXIubGVuZ3RoKCkgLSAxOwogICAgICAgICAgICBjaCA9IGJ1ZmZlci5jaGFyQXQoMCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gSnVzdCB1c2UgdGhpcyBjaGFyYWN0ZXIsIGJ1dCBmaXJzdCBhZHZhbmNlIHRvIHRoZSBuZXh0IG9uZQogICAgICAgICAgICB0ZXh0Lm5leHQoKTsKCiAgICAgICAgICAgIC8vIERvIEhhbmd1bCAtPiBKYW1vIGRlY29tcG9zaXRpb24gaWYgbmVjZXNzYXJ5CiAgICAgICAgICAgIGlmIChoYW5ndWwgJiYgY2ggPj0gSEFOR1VMX0JBU0UgJiYgY2ggPCBIQU5HVUxfTElNSVQpIHsKICAgICAgICAgICAgICAgIGluaXRCdWZmZXIoKTsKICAgICAgICAgICAgICAgIGhhbmd1bFRvSmFtbyhjaCwgYnVmZmVyLCBtaW5EZWNvbXApOwogICAgICAgICAgICAgICAgYnVmZmVyTGltaXQgPSBidWZmZXIubGVuZ3RoKCkgLSAxOwogICAgICAgICAgICAgICAgY2ggPSBidWZmZXIuY2hhckF0KDApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIgbmV4dERlY29tcCByZXR1cm5pbmcgIiArIFV0aWxpdHkuaGV4KGNoKSArICIsIHRleHQgaW5kZXg9IiArIHRleHQuZ2V0SW5kZXgoKSk7CiAgICAgICAgcmV0dXJuIGNoOwogICAgfQoKICAgIC8qKgogICAgICogRGVjb21wb3NlIHN0YXJ0aW5nIHdpdGggdGhlIGlucHV0IGNoYXIganVzdCBiZWZvcmUgdGhlIGN1cnJlbnQgcG9zaXRpb24KICAgICAqIGFuZCBjb250aW51aW5nIGJhY2t3YXJkIHVudGlsIChhbmQgaW5jbHVkaW5nKSB0aGUgcHJldmlvdXMgYmFzZSBjaGFyLgogICAgICogPHA+CiAgICAgKiA8Yj5JbnB1dDwvYj46CiAgICAgKiA8dWw+CiAgICAgKiAgPGxpPnVuZGVybHlpbmcgY2hhciBpdGVyIHBvaW50cyBqdXN0IGFmdGVyIGxhc3QgY2hhciB0byBkZWNvbXBvc2UKICAgICAqIDwvdWw+CiAgICAgKiA8cD4KICAgICAqIDxiPk91dHB1dDo8L2I+CiAgICAgKiA8dWw+CiAgICAgKiAgPGxpPnJldHVybnMgbGFzdCBjaGFyIG9mIHJlc3VsdGluZyBkZWNvbXBvc2l0aW9uIHNlcXVlbmNlCiAgICAgKiAgPGxpPnVuZGVybHlpbmcgaXRlciBwb2ludHMgdG8gbG93ZXN0LWluZGV4IGNoYXIgd2UgZGVjb21wb3NlZCwgaS5lLiB0aGUgYmFzZSBjaGFyCiAgICAgKiA8L3VsPgogICAgICovCiAgICBwcml2YXRlIGNoYXIgcHJldkRlY29tcCgpIHsKICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tIHRvcCBvZiBwcmV2RGVjb21wKCkgLS0tLS0tLS0tLS0tLS0tIik7CgogICAgICAgIGJvb2xlYW4gaGFuZ3VsID0gKG9wdGlvbnMgJiBJR05PUkVfSEFOR1VMKSA9PSAwOwoKICAgICAgICBjaGFyIGNoID0gY3VyQmFja3dhcmQoKTsKCiAgICAgICAgaW50IG9mZnNldCA9IERlY29tcERhdGEub2Zmc2V0cy5lbGVtZW50QXQoY2gpOwogICAgICAgIGludCBpbmRleCA9IG9mZnNldCAmIERlY29tcERhdGEuREVDT01QX01BU0s7CgogICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJwcmV2RGVjb21wIGdvdCBpbnB1dCBjaGFyICIgKyBVdGlsaXR5LmhleChjaCkpOwoKICAgICAgICBpZiAoaW5kZXggPiBtaW5EZWNvbXAgfHwgRGVjb21wRGF0YS5jYW5vbkNsYXNzLmVsZW1lbnRBdChjaCkgIT0gRGVjb21wRGF0YS5CQVNFKQogICAgICAgIHsKICAgICAgICAgICAgaW5pdEJ1ZmZlcigpOwoKICAgICAgICAgICAgLy8gVGhpcyBtZXRob2QgcmV3cml0dGVuIHRvIHBhc3MgY29uZm9ybWFuY2UgdGVzdHMuIC0gTGl1CiAgICAgICAgICAgIC8vIENvbGxlY3QgYWxsIGNoYXJhY3RlcnMgdXAgdG8gdGhlIHByZXZpb3VzIGJhc2UgY2hhcgogICAgICAgICAgICB3aGlsZSAoY2ggIT0gRE9ORSkgewogICAgICAgICAgICAgICAgYnVmZmVyLmluc2VydCgwLCBjaCk7CiAgICAgICAgICAgICAgICBpZiAoRGVjb21wRGF0YS5jYW5vbkNsYXNzLmVsZW1lbnRBdChjaCkgPT0gRGVjb21wRGF0YS5CQVNFKSBicmVhazsKICAgICAgICAgICAgICAgIGNoID0gdGV4dC5wcmV2aW91cygpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigicHJldkRlY29tcCBidWZmZXI6ICIgKyBVdGlsaXR5LmhleChidWZmZXIpKTsKCiAgICAgICAgICAgIC8vIERlY29tcG9zZSB0aGUgYnVmZmVyCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYnVmZmVyLmxlbmd0aCgpOyBpKyspIHsKICAgICAgICAgICAgICAgIGNoID0gYnVmZmVyLmNoYXJBdChpKTsKICAgICAgICAgICAgICAgIG9mZnNldCA9IERlY29tcERhdGEub2Zmc2V0cy5lbGVtZW50QXQoY2gpOwogICAgICAgICAgICAgICAgaW5kZXggPSBvZmZzZXQgJiBEZWNvbXBEYXRhLkRFQ09NUF9NQVNLOyAgICAgICAgICAgICAgICAKCiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiBtaW5EZWNvbXApIHsKICAgICAgICAgICAgICAgICAgICBpbnQgaiA9IGRvUmVwbGFjZShEZWNvbXBEYXRhLmNvbnRlbnRzLCBpbmRleCwgYnVmZmVyLCBpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoKG9mZnNldCAmIERlY29tcERhdGEuREVDT01QX1JFQ1VSU0UpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byBkZWNvbXBvc2UgdGhpcyByZWN1cnNpdmVseQogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGo7ICsraSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2ggPSBidWZmZXIuY2hhckF0KGkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBEZWNvbXBEYXRhLm9mZnNldHMuZWxlbWVudEF0KGNoKSAmIERlY29tcERhdGEuREVDT01QX01BU0s7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiBtaW5EZWNvbXApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICs9IGRvUmVwbGFjZShEZWNvbXBEYXRhLmNvbnRlbnRzLCBpbmRleCwgYnVmZmVyLCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpID0gajsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oInByZXZEZWNvbXAgYnVmZmVyIGFmdGVyIGRlY29tcDogIiArIFV0aWxpdHkuaGV4KGJ1ZmZlcikpOwoKICAgICAgICAgICAgaWYgKGJ1ZmZlci5sZW5ndGgoKSA+IDEpIHsKICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgY29tYmluaW5nIGNoYXJhY3RlciBpbiB0aGUgYnVmZmVyLAogICAgICAgICAgICAgICAgLy8gcHV0IHRoZW0gaW50byB0aGUgY2Fub25pY2FsIG9yZGVyLgogICAgICAgICAgICAgICAgZml4Q2Fub25pY2FsKGJ1ZmZlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnVmZmVyTGltaXQgPSBidWZmZXJQb3MgPSBidWZmZXIubGVuZ3RoKCkgLSAxOwogICAgICAgICAgICBjaCA9IGJ1ZmZlci5jaGFyQXQoYnVmZmVyUG9zKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoaGFuZ3VsICYmIGNoID49IEhBTkdVTF9CQVNFICYmIGNoIDwgSEFOR1VMX0xJTUlUKSB7CiAgICAgICAgICAgIGluaXRCdWZmZXIoKTsKICAgICAgICAgICAgaGFuZ3VsVG9KYW1vKGNoLCBidWZmZXIsIG1pbkRlY29tcCk7CiAgICAgICAgICAgIGJ1ZmZlckxpbWl0ID0gYnVmZmVyUG9zID0gYnVmZmVyLmxlbmd0aCgpIC0gMTsKICAgICAgICAgICAgY2ggPSBidWZmZXIuY2hhckF0KGJ1ZmZlclBvcyk7CiAgICAgICAgfQogICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIgcHJldkRlY29tcCByZXR1cm5pbmcgJyIgKyBjaCArICInICIgKyBVdGlsaXR5LmhleChjaCkgKyAiLCB0ZXh0IGluZGV4PSIgKyB0ZXh0LmdldEluZGV4KCkpOwogICAgICAgIHJldHVybiBjaDsKICAgIH0KCiAgICBzdGF0aWMgZmluYWwgaW50IGdldENsYXNzKGNoYXIgY2gpIHsKICAgICAgICBpbnQgdmFsdWUgPSBEZWNvbXBEYXRhLmNhbm9uQ2xhc3MuZWxlbWVudEF0KGNoKTsKICAgICAgICByZXR1cm4gKHZhbHVlID49IDApID8gdmFsdWUgOiB2YWx1ZSArIDI1NjsKICAgIH0KCgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBDaGFyYWN0ZXJJdGVyYXRvciBvdmVycmlkZXMKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBjdXJyZW50IGNoYXJhY3RlciBpbiB0aGUgbm9ybWFsaXplZCB0ZXh0LgogICAgICovCiAgICBwdWJsaWMgY2hhciBjdXJyZW50KCkgewogICAgICAgIGlmIChjdXJyZW50Q2hhciA9PSBET05FKSB7CiAgICAgICAgICAgIGlmIChtb2RlLmNvbXBvc2UoKSkgewogICAgICAgICAgICAgICAgY3VycmVudENoYXIgPSBuZXh0Q29tcG9zZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKG1vZGUuZGVjb21wKCkpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gbmV4dERlY29tcCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgY3VycmVudENoYXIgPSB0ZXh0LmN1cnJlbnQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gY3VycmVudENoYXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgbm9ybWFsaXplZCB0ZXh0LiAgVGhpcyByZXNldHMKICAgICAqIHRoZSA8dHQ+Tm9ybWFsaXplcidzPC90dD4gcG9zaXRpb24gdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgdGV4dC4KICAgICAqLwogICAgcHVibGljIGNoYXIgZmlyc3QoKSB7CiAgICAgICAgcmV0dXJuIHNldEluZGV4KHRleHQuZ2V0QmVnaW5JbmRleCgpKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgbGFzdCBjaGFyYWN0ZXIgaW4gdGhlIG5vcm1hbGl6ZWQgdGV4dC4gIFRoaXMgcmVzZXRzCiAgICAgKiB0aGUgPHR0Pk5vcm1hbGl6ZXInczwvdHQ+IHBvc2l0aW9uIHRvIGJlIGp1c3QgYmVmb3JlIHRoZQogICAgICogdGhlIGlucHV0IHRleHQgY29ycmVzcG9uZGluZyB0byB0aGF0IG5vcm1hbGl6ZWQgY2hhcmFjdGVyLgogICAgICovCiAgICBwdWJsaWMgY2hhciBsYXN0KCkgewogICAgICAgIHRleHQuc2V0SW5kZXgodGV4dC5nZXRFbmRJbmRleCgpIC0gMSk7ICAvLyBTZXR0aW5nIHRvIGdldEVuZEluZGV4KCkgZmFpbHMgaW4gMS4xCiAgICAgICAgYXRFbmQgPSB0cnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzbyB3b3JrIGFyb3VuZCB0aGUgYnVnCgogICAgICAgIGN1cnJlbnRDaGFyID0gRE9ORTsgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgY3VycmVudCBjaGFyIGhhc24ndCBiZWVuIHByb2Nlc3NlZAogICAgICAgIGNsZWFyQnVmZmVyKCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgYnVmZmVyIGlzIGVtcHR5IHRvbwogICAgICAgIHJldHVybiBwcmV2aW91cygpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBuZXh0IGNoYXJhY3RlciBpbiB0aGUgbm9ybWFsaXplZCB0ZXh0IGFuZCBhZHZhbmNlCiAgICAgKiB0aGUgaXRlcmF0aW9uIHBvc2l0aW9uIGJ5IG9uZS4gIElmIHRoZSBlbmQKICAgICAqIG9mIHRoZSB0ZXh0IGhhcyBhbHJlYWR5IGJlZW4gcmVhY2hlZCwge0BsaW5rICNET05FfSBpcyByZXR1cm5lZC4KICAgICAqLwogICAgcHVibGljIGNoYXIgbmV4dCgpIHsKICAgICAgICBpZiAoYnVmZmVyUG9zIDwgYnVmZmVyTGltaXQpIHsKICAgICAgICAgICAgLy8gVGhlcmUgYXJlIG91dHB1dCBjaGFyYWN0ZXJzIGxlZnQgaW4gdGhlIGJ1ZmZlcgogICAgICAgICAgICBjdXJyZW50Q2hhciA9IGJ1ZmZlci5jaGFyQXQoKytidWZmZXJQb3MpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgYnVmZmVyTGltaXQgPSBidWZmZXJQb3MgPSAwOyAgICAvLyBCdWZmZXIgaXMgbm93IG91dCBvZiBkYXRlCiAgICAgICAgICAgIGlmIChtb2RlLmNvbXBvc2UoKSkgewogICAgICAgICAgICAgICAgY3VycmVudENoYXIgPSBuZXh0Q29tcG9zZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKG1vZGUuZGVjb21wKCkpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gbmV4dERlY29tcCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgY3VycmVudENoYXIgPSB0ZXh0Lm5leHQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gY3VycmVudENoYXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIHByZXZpb3VzIGNoYXJhY3RlciBpbiB0aGUgbm9ybWFsaXplZCB0ZXh0IGFuZCBkZWNyZW1lbnQKICAgICAqIHRoZSBpdGVyYXRpb24gcG9zaXRpb24gYnkgb25lLiAgSWYgdGhlIGJlZ2lubmluZwogICAgICogb2YgdGhlIHRleHQgaGFzIGFscmVhZHkgYmVlbiByZWFjaGVkLCB7QGxpbmsgI0RPTkV9IGlzIHJldHVybmVkLgogICAgICovCiAgICBwdWJsaWMgY2hhciBwcmV2aW91cygpIHsKICAgICAgICBpZiAoYnVmZmVyUG9zID4gMCkgewogICAgICAgICAgICAvLyBUaGVyZSBhcmUgb3V0cHV0IGNoYXJhY3RlcnMgbGVmdCBpbiB0aGUgYnVmZmVyCiAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gYnVmZmVyLmNoYXJBdCgtLWJ1ZmZlclBvcyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBidWZmZXJMaW1pdCA9IGJ1ZmZlclBvcyA9IDA7ICAgIC8vIEJ1ZmZlciBpcyBub3cgb3V0IG9mIGRhdGUKICAgICAgICAgICAgaWYgKG1vZGUuY29tcG9zZSgpKSB7CiAgICAgICAgICAgICAgICBjdXJyZW50Q2hhciA9IHByZXZDb21wb3NlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAobW9kZS5kZWNvbXAoKSkgewogICAgICAgICAgICAgICAgY3VycmVudENoYXIgPSBwcmV2RGVjb21wKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjdXJyZW50Q2hhciA9IHRleHQucHJldmlvdXMoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gY3VycmVudENoYXI7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGl0ZXJhdGlvbiBwb3NpdGlvbiBpbiB0aGUgaW5wdXQgdGV4dCB0aGF0IGlzIGJlaW5nIG5vcm1hbGl6ZWQKICAgICAqIGFuZCByZXR1cm4gdGhlIGZpcnN0IG5vcm1hbGl6ZWQgY2hhcmFjdGVyIGF0IHRoYXQgcG9zaXRpb24uCiAgICAgKiA8cD4KICAgICAqIEBwYXJhbSBpbmRleCB0aGUgZGVzaXJlZCBpbmRleCBpbiB0aGUgaW5wdXQgdGV4dC4KICAgICAqCiAgICAgKiBAcmV0dXJuICAgICAgdGhlIGZpcnN0IG5vcm1hbGl6ZWQgY2hhcmFjdGVyIHRoYXQgaXMgdGhlIHJlc3VsdCBvZiBpdGVyYXRpbmcKICAgICAqICAgICAgICAgICAgICBmb3J3YXJkIHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqCiAgICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gaW5kZXggaXMgbGVzcyB0aGFuCiAgICAgKiAgICAgICAgICB7QGxpbmsgI2dldEJlZ2luSW5kZXh9IG9yIGdyZWF0ZXIgdGhhbiB7QGxpbmsgI2dldEVuZEluZGV4fS4KICAgICAqLwogICAgcHVibGljIGNoYXIgc2V0SW5kZXgoaW50IGluZGV4KSB7CiAgICAgICAgdGV4dC5zZXRJbmRleChpbmRleCk7ICAgLy8gQ2hlY2tzIHJhbmdlCiAgICAgICAgY3VycmVudENoYXIgPSBET05FOyAgICAgLy8gVGhlIGN1cnJlbnQgY2hhciBoYXNuJ3QgYmVlbiBwcm9jZXNzZWQKICAgICAgICBjbGVhckJ1ZmZlcigpOyAgICAgICAgICAvLyBUaGUgYnVmZmVyIGlzIGVtcHR5IHRvbwoKICAgICAgICByZXR1cm4gY3VycmVudCgpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0cmlldmUgdGhlIGN1cnJlbnQgaXRlcmF0aW9uIHBvc2l0aW9uIGluIHRoZSBpbnB1dCB0ZXh0IHRoYXQgaXMKICAgICAqIGJlaW5nIG5vcm1hbGl6ZWQuICBUaGlzIG1ldGhvZCBpcyB1c2VmdWwgaW4gYXBwbGljYXRpb25zIHN1Y2ggYXMKICAgICAqIHNlYXJjaGluZywgd2hlcmUgeW91IG5lZWQgdG8gYmUgYWJsZSB0byBkZXRlcm1pbmUgdGhlIHBvc2l0aW9uIGluCiAgICAgKiB0aGUgaW5wdXQgdGV4dCB0aGF0IGNvcnJlc3BvbmRzIHRvIGEgZ2l2ZW4gbm9ybWFsaXplZCBvdXRwdXQgY2hhcmFjdGVyLgogICAgICovCiAgICBwdWJsaWMgZmluYWwgaW50IGdldEluZGV4KCkgewogICAgICAgIHJldHVybiB0ZXh0LmdldEluZGV4KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZSB0aGUgaW5kZXggb2YgdGhlIHN0YXJ0IG9mIHRoZSBpbnB1dCB0ZXh0LiAgVGhpcyBpcyB0aGUgYmVnaW4gaW5kZXgKICAgICAqIG9mIHRoZSA8dHQ+Q2hhcmFjdGVySXRlcmF0b3I8L3R0PiBvciB0aGUgc3RhcnQgKGkuZS4gMCkgb2YgdGhlIDx0dD5TdHJpbmc8L3R0PgogICAgICogb3ZlciB3aGljaCB0aGlzIDx0dD5Ob3JtYWxpemVyPC90dD4gaXMgaXRlcmF0aW5nCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0QmVnaW5JbmRleCgpIHsKICAgICAgICByZXR1cm4gdGV4dC5nZXRCZWdpbkluZGV4KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXRyaWV2ZSB0aGUgaW5kZXggb2YgdGhlIGVuZCBvZiB0aGUgaW5wdXQgdGV4dC4gIFRoaXMgaXMgdGhlIGVuZCBpbmRleAogICAgICogb2YgdGhlIDx0dD5DaGFyYWN0ZXJJdGVyYXRvcjwvdHQ+IG9yIHRoZSBsZW5ndGggb2YgdGhlIDx0dD5TdHJpbmc8L3R0PgogICAgICogb3ZlciB3aGljaCB0aGlzIDx0dD5Ob3JtYWxpemVyPC90dD4gaXMgaXRlcmF0aW5nCiAgICAgKi8KICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0RW5kSW5kZXgoKSB7CiAgICAgICAgcmV0dXJuIHRleHQuZ2V0RW5kSW5kZXgoKTsKICAgIH0KCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByb3BlcnR5IGFjY2VzcyBtZXRob2RzCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIFNldCB0aGUgbm9ybWFsaXphdGlvbiBtb2RlIGZvciB0aGlzIG9iamVjdC4KICAgICAqIDxwPgogICAgICogPGI+Tm90ZTo8L2I+SWYgdGhlIG5vcm1hbGl6YXRpb24gbW9kZSBpcyBjaGFuZ2VkIHdoaWxlIGl0ZXJhdGluZwogICAgICogb3ZlciBhIHN0cmluZywgY2FsbHMgdG8ge0BsaW5rICNuZXh0fSBhbmQge0BsaW5rICNwcmV2aW91c30gbWF5CiAgICAgKiByZXR1cm4gcHJldmlvdXNseSBidWZmZXJzIGNoYXJhY3RlcnMgaW4gdGhlIG9sZCBub3JtYWxpemF0aW9uIG1vZGUKICAgICAqIHVudGlsIHRoZSBpdGVyYXRpb24gaXMgYWJsZSB0byByZS1zeW5jIGF0IHRoZSBuZXh0IGJhc2UgY2hhcmFjdGVyLgogICAgICogSXQgaXMgc2FmZXN0IHRvIGNhbGwge0BsaW5rICNzZXRUZXh0IHNldFRleHQoKX0sIHtAbGluayAjZmlyc3R9LAogICAgICoge0BsaW5rICNsYXN0fSwgZXRjLiBhZnRlciBjYWxsaW5nIDx0dD5zZXRNb2RlPC90dD4uCiAgICAgKiA8cD4KICAgICAqIEBwYXJhbSBuZXdNb2RlIHRoZSBuZXcgbW9kZSBmb3IgdGhpcyA8dHQ+Tm9ybWFsaXplcjwvdHQ+LgogICAgICogVGhlIHN1cHBvcnRlZCBtb2RlcyBhcmU6CiAgICAgKiA8dWw+CiAgICAgKiAgPGxpPntAbGluayAjQ09NUE9TRX0gICAgICAgIC0gVW5pY29kZSBjYW5vbmljYWwgZGVjb21wb3NpdGlpb24KICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbGxvd2VkIGJ5IGNhbm9uaWNhbCBjb21wb3NpdGlvbi4KICAgICAqICA8bGk+e0BsaW5rICNDT01QT1NFX0NPTVBBVH0gLSBVbmljb2RlIGNvbXBhdGliaWxpdHkgZGVjb21wb3NpdGlpb24KICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvbGx3ZWQgYnkgY2Fub25pY2FsIGNvbXBvc2l0aW9uLgogICAgICogIDxsaT57QGxpbmsgI0RFQ09NUH0gICAgICAgICAtIFVuaWNvZGUgY2Fub25pY2FsIGRlY29tcG9zaXRpb24KICAgICAqICA8bGk+e0BsaW5rICNERUNPTVBfQ09NUEFUfSAgLSBVbmljb2RlIGNvbXBhdGliaWxpdHkgZGVjb21wb3NpdGlvbi4KICAgICAqICA8bGk+e0BsaW5rICNOT19PUH0gICAgICAgICAgLSBEbyBub3RoaW5nIGJ1dCByZXR1cm4gY2hhcmFjdGVycwogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSB0aGUgdW5kZXJseWluZyBpbnB1dCB0ZXh0LgogICAgICogPC91bD4KICAgICAqCiAgICAgKiBAc2VlICNnZXRNb2RlCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldE1vZGUoTW9kZSBuZXdNb2RlKSB7CiAgICAgICAgbW9kZSA9IG5ld01vZGU7CiAgICAgICAgbWluRGVjb21wID0gbW9kZS5jb21wYXQoKSA/IDAgOiBEZWNvbXBEYXRhLk1BWF9DT01QQVQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGJhc2ljIG9wZXJhdGlvbiBwZXJmb3JtZWQgYnkgdGhpcyA8dHQ+Tm9ybWFsaXplcjwvdHQ+CiAgICAgKgogICAgICogQHNlZSAjc2V0TW9kZQogICAgICovCiAgICBwdWJsaWMgTW9kZSBnZXRNb2RlKCkgewogICAgICAgIHJldHVybiBtb2RlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IG9wdGlvbnMgdGhhdCBhZmZlY3QgdGhpcyA8dHQ+Tm9ybWFsaXplcjwvdHQ+J3Mgb3BlcmF0aW9uLgogICAgICogT3B0aW9ucyBkbyBub3QgY2hhbmdlIHRoZSBiYXNpYyBjb21wb3NpdGlvbiBvciBkZWNvbXBvc2l0aW9uIG9wZXJhdGlvbgogICAgICogdGhhdCBpcyBiZWluZyBwZXJmb3JtZWQgLCBidXQgdGhleSBjb250cm9sIHdoZXRoZXIKICAgICAqIGNlcnRhaW4gb3B0aW9uYWwgcG9ydGlvbnMgb2YgdGhlIG9wZXJhdGlvbiBhcmUgZG9uZS4KICAgICAqIEN1cnJlbnRseSB0aGUgb25seSBhdmFpbGFibGUgb3B0aW9uIGlzOgogICAgICogPHA+CiAgICAgKiA8dWw+CiAgICAgKiAgIDxsaT57QGxpbmsgI0lHTk9SRV9IQU5HVUx9IC0gRG8gbm90IGRlY29tcG9zZSBIYW5ndWwgc3lsbGFibGVzIGludG8gdGhlIEphbW8gYWxwaGFiZXQKICAgICAqICAgICAgICAgIGFuZCB2aWNlLXZlcnNhLiAgVGhpcyBvcHRpb24gaXMgb2ZmIGJ5IGRlZmF1bHQgKDxpPmkuZS48L2k+IEhhbmd1bCBwcm9jZXNzaW5nCiAgICAgKiAgICAgICAgICBpcyBlbmFibGVkKSBzaW5jZSB0aGUgVW5pY29kZSBzdGFuZGFyZCBzcGVjaWZpZXMgdGhhdCBIYW5ndWwgdG8gSmFtbwogICAgICogICAgICAgICAgaXMgYSBjYW5vbmljYWwgZGVjb21wb3NpdGlvbi4gIEZvciBhbnkgb2YgdGhlIHN0YW5kYXJkIFVuaWNvZGUgTm9ybWFsaXphdGlvbgogICAgICogICAgICAgICAgRm9ybXMsIHlvdSBzaG91bGQgbGVhdmUgdGhpcyBvcHRpb24gb2ZmLgogICAgICogPC91bD4KICAgICAqIDxwPgogICAgICogQHBhcmFtICAgb3B0aW9uICB0aGUgb3B0aW9uIHdob3NlIHZhbHVlIGlzIHRvIGJlIHNldC4KICAgICAqIEBwYXJhbSAgIHZhbHVlICAgdGhlIG5ldyBzZXR0aW5nIGZvciB0aGUgb3B0aW9uLiAgVXNlIDx0dD50cnVlPC90dD4gdG8KICAgICAqICAgICAgICAgICAgICAgICAgdHVybiB0aGUgb3B0aW9uIG9uIGFuZCA8dHQ+ZmFsc2U8L3R0PiB0byB0dXJuIGl0IG9mZi4KICAgICAqCiAgICAgKiBAc2VlICNnZXRPcHRpb24KICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0T3B0aW9uKGludCBvcHRpb24sIGJvb2xlYW4gdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uICE9IElHTk9SRV9IQU5HVUwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSWxsZWdhbCBvcHRpb24iKTsKICAgICAgICB9CiAgICAgICAgaWYgKHZhbHVlKSB7CiAgICAgICAgICAgIG9wdGlvbnMgfD0gb3B0aW9uOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbnMgJj0gKH5vcHRpb24pOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIERldGVybWluZSB3aGV0aGVyIGFuIG9wdGlvbiBpcyB0dXJuZWQgb24gb3Igb2ZmLgogICAgICogPHA+CiAgICAgKiBAc2VlICNzZXRPcHRpb24KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0T3B0aW9uKGludCBvcHRpb24pIHsKICAgICAgICByZXR1cm4gKG9wdGlvbnMgJiBvcHRpb24pICE9IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGlucHV0IHRleHQgb3ZlciB3aGljaCB0aGlzIDx0dD5Ob3JtYWxpemVyPC90dD4gd2lsbCBpdGVyYXRlLgogICAgICogVGhlIGl0ZXJhdGlvbiBwb3NpdGlvbiB3aWxsIGJlIHJlc2V0IHRvIHRoZSBiZWdpbm5pbmcuCiAgICAgKiA8cD4KICAgICAqIEBwYXJhbSBuZXdUZXh0ICAgVGhlIG5ldyBzdHJpbmcgdG8gYmUgbm9ybWFsaXplZC4KICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0VGV4dChTdHJpbmcgbmV3VGV4dCkgewogICAgICAgIHRleHQgPSBuZXcgU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3IobmV3VGV4dCk7CiAgICAgICAgcmVzZXQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUgaW5wdXQgdGV4dCBvdmVyIHdoaWNoIHRoaXMgPHR0Pk5vcm1hbGl6ZXI8L3R0PiB3aWxsIGl0ZXJhdGUuCiAgICAgKiBUaGUgaXRlcmF0aW9uIHBvc2l0aW9uIHdpbGwgYmUgcmVzZXQgdG8gdGhlIGJlZ2lubmluZy4KICAgICAqIDxwPgogICAgICogQHBhcmFtIG5ld1RleHQgICBUaGUgbmV3IHRleHQgdG8gYmUgbm9ybWFsaXplZC4KICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0VGV4dChDaGFyYWN0ZXJJdGVyYXRvciBuZXdUZXh0KSB7CiAgICAgICAgdGV4dCA9IG5ld1RleHQ7CiAgICAgICAgcmVzZXQoKTsKICAgIH0KCgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcml2YXRlIHV0aWxpdHkgbWV0aG9kcwogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgcHJpdmF0ZSBmaW5hbCBjaGFyIGN1ckZvcndhcmQoKSB7CiAgICAgICAgY2hhciBjaCA9IHRleHQuY3VycmVudCgpOwogICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIgY3VyRm9yd2FyZCByZXR1cm5pbmcgIiArIFV0aWxpdHkuaGV4KGNoKSArICIsIHRleHQgaW5kZXg9IiArIHRleHQuZ2V0SW5kZXgoKSk7CiAgICAgICAgcmV0dXJuIGNoOwogICAgfQoKICAgIHByaXZhdGUgZmluYWwgY2hhciBjdXJCYWNrd2FyZCgpIHsKICAgICAgICBjaGFyIGNoID0gYXRFbmQgPyB0ZXh0LmN1cnJlbnQoKSA6IHRleHQucHJldmlvdXMoKTsKICAgICAgICBhdEVuZCA9IGZhbHNlOwogICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIgY3VyQmFja3dhcmQgcmV0dXJuaW5nICIgKyBVdGlsaXR5LmhleChjaCkgKyAiLCB0ZXh0IGluZGV4PSIgKyB0ZXh0LmdldEluZGV4KCkpOwogICAgICAgIHJldHVybiBjaDsKICAgIH0KCiAgICBzdGF0aWMgZmluYWwgaW50IGRvQXBwZW5kKFN0cmluZyBzb3VyY2UsIGludCBvZmZzZXQsIFN0cmluZ0J1ZmZlciBkZXN0KSB7CiAgICAgICAgaW50IGluZGV4ID0gb2Zmc2V0ID4+PiBTVFJfSU5ERVhfU0hJRlQ7CiAgICAgICAgaW50IGxlbmd0aCA9IG9mZnNldCAmIFNUUl9MRU5HVEhfTUFTSzsKCiAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIGNoYXIgY2g7CiAgICAgICAgICAgIHdoaWxlICgoY2ggPSBEZWNvbXBEYXRhLmNvbnRlbnRzLmNoYXJBdChpbmRleCsrKSkgIT0gMHgwMDAwKSB7CiAgICAgICAgICAgICAgICBkZXN0LmFwcGVuZChjaCk7CiAgICAgICAgICAgICAgICBsZW5ndGgrKzsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIGRlc3QuYXBwZW5kKERlY29tcERhdGEuY29udGVudHMuY2hhckF0KGluZGV4KyspKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbGVuZ3RoOwogICAgfQoKCiAgICBzdGF0aWMgZmluYWwgaW50IGRvSW5zZXJ0KFN0cmluZyBzb3VyY2UsIGludCBvZmZzZXQsIFN0cmluZ0J1ZmZlciBkZXN0LCBpbnQgcG9zKQogICAgewogICAgICAgIGludCBpbmRleCA9IG9mZnNldCA+Pj4gU1RSX0lOREVYX1NISUZUOwogICAgICAgIGludCBsZW5ndGggPSBvZmZzZXQgJiBTVFJfTEVOR1RIX01BU0s7CgogICAgICAgIGlmIChsZW5ndGggPT0gMCkgewogICAgICAgICAgICBjaGFyIGNoOwogICAgICAgICAgICB3aGlsZSAoKGNoID0gRGVjb21wRGF0YS5jb250ZW50cy5jaGFyQXQoaW5kZXgrKykpICE9IDB4MDAwMCkgewogICAgICAgICAgICAgICAgZGVzdC5pbnNlcnQocG9zKyssIGNoKTsKICAgICAgICAgICAgICAgIGxlbmd0aCsrOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgZGVzdC5pbnNlcnQocG9zKyssIERlY29tcERhdGEuY29udGVudHMuY2hhckF0KGluZGV4KyspKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbGVuZ3RoOwogICAgfQoKICAgIHN0YXRpYyBmaW5hbCBpbnQgZG9SZXBsYWNlKFN0cmluZyBzb3VyY2UsIGludCBvZmZzZXQsIFN0cmluZ0J1ZmZlciBkZXN0LCBpbnQgcG9zKQogICAgewogICAgICAgIGludCBpbmRleCA9IG9mZnNldCA+Pj4gU1RSX0lOREVYX1NISUZUOwogICAgICAgIGludCBsZW5ndGggPSBvZmZzZXQgJiBTVFJfTEVOR1RIX01BU0s7CgogICAgICAgIGRlc3Quc2V0Q2hhckF0KHBvcysrLCBEZWNvbXBEYXRhLmNvbnRlbnRzLmNoYXJBdChpbmRleCsrKSk7CiAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIGNoYXIgY2g7CiAgICAgICAgICAgIHdoaWxlICgoY2ggPSBEZWNvbXBEYXRhLmNvbnRlbnRzLmNoYXJBdChpbmRleCsrKSkgIT0gMHgwMDAwKSB7CiAgICAgICAgICAgICAgICBkZXN0Lmluc2VydChwb3MrKywgY2gpOwogICAgICAgICAgICAgICAgbGVuZ3RoKys7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBkZXN0Lmluc2VydChwb3MrKywgRGVjb21wRGF0YS5jb250ZW50cy5jaGFyQXQoaW5kZXgrKykpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBsZW5ndGg7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIHJlc2V0KCkgewogICAgICAgIHRleHQuc2V0SW5kZXgodGV4dC5nZXRCZWdpbkluZGV4KCkpOwogICAgICAgIGF0RW5kID0gZmFsc2U7CiAgICAgICAgYnVmZmVyUG9zID0gMDsKICAgICAgICBidWZmZXJMaW1pdCA9IDA7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCB2b2lkIGluaXRCdWZmZXIoKSB7CiAgICAgICAgaWYgKGJ1ZmZlciA9PSBudWxsKSB7CiAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoMTApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRMZW5ndGgoMCk7CiAgICAgICAgfQogICAgICAgIGNsZWFyQnVmZmVyKCk7CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCB2b2lkIGNsZWFyQnVmZmVyKCkgewogICAgICAgIGJ1ZmZlckxpbWl0ID0gYnVmZmVyUG9zID0gMDsKICAgIH0KCgogICAgLyoqCiAgICAgKiBGaXhlcyB0aGUgc29ydGluZyBzZXF1ZW5jZSBvZiBub24tc3BhY2luZyBjaGFyYWN0ZXJzIGFjY29yZGluZyB0bwogICAgICogdGhlaXIgY29tYmluaW5nIGNsYXNzLiAgVGhlIGFsZ29yaXRobSBpcyBsaXN0ZWQgb24gcC4zLTExIGluIHRoZQogICAgICogVW5pY29kZSBTdGFuZGFyZCAyLjAuICBUaGUgdGFibGUgb2YgY29tYmluaW5nIGNsYXNzZXMgaXMgb24gcC40LTIKICAgICAqIGluIHRoZSBVbmljb2RlIFN0YW5kYXJkIDIuMC4KICAgICAqIEBwYXJhbSByZXN1bHQgdGhlIHN0cmluZyB0byBmaXguCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIHZvaWQgZml4Q2Fub25pY2FsKFN0cmluZ0J1ZmZlciByZXN1bHQpIHsKICAgICAgICBpbnQgaSA9IHJlc3VsdC5sZW5ndGgoKSAtIDE7CiAgICAgICAgaW50IGN1cnJlbnRUeXBlID0gZ2V0Q2xhc3MocmVzdWx0LmNoYXJBdChpKSk7CiAgICAgICAgaW50IGxhc3RUeXBlOwoKICAgICAgICBmb3IgKC0taTsgaSA+PSAwOyAtLWkpIHsKICAgICAgICAgICAgbGFzdFR5cGUgPSBjdXJyZW50VHlwZTsKICAgICAgICAgICAgY3VycmVudFR5cGUgPSBnZXRDbGFzcyhyZXN1bHQuY2hhckF0KGkpKTsKCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIGEgc3dhcCBpcyBwcmVzdW1lZCB0byBiZSByYXJlIChhbmQgYSBkb3VibGUtc3dhcCB2ZXJ5IHJhcmUpLAogICAgICAgICAgICAvLyBzbyBkb24ndCB3b3JyeSBhYm91dCBlZmZpY2llbmN5IGhlcmUuCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIGlmIChjdXJyZW50VHlwZSA+IGxhc3RUeXBlICYmIGxhc3RUeXBlICE9IERlY29tcERhdGEuQkFTRSkgewogICAgICAgICAgICAgICAgLy8gc3dhcCBjaGFyYWN0ZXJzCiAgICAgICAgICAgICAgICBjaGFyIHRlbXAgPSByZXN1bHQuY2hhckF0KGkpOwogICAgICAgICAgICAgICAgcmVzdWx0LnNldENoYXJBdChpLCByZXN1bHQuY2hhckF0KGkrMSkpOwogICAgICAgICAgICAgICAgcmVzdWx0LnNldENoYXJBdChpKzEsIHRlbXApOwogICAgICAgICAgICAgICAgLy8gaWYgbm90IGF0IGVuZCwgYmFja3VwIChvbmUgZnVydGhlciwgdG8gY29tcGVuc2F0ZSBmb3IgZm9yLWxvb3ApCiAgICAgICAgICAgICAgICBpZiAoaSA8IHJlc3VsdC5sZW5ndGgoKSAtIDIpIHsKICAgICAgICAgICAgICAgICAgICBpICs9IDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyByZXNldCB0eXBlLCBzaW5jZSB3ZSBzd2FwcGVkLgogICAgICAgICAgICAgICAgY3VycmVudFR5cGUgPSBnZXRDbGFzcyhyZXN1bHQuY2hhckF0KGkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIEhhbmd1bCAvIEphbW8gY29udmVyc2lvbiB1dGlsaXRpZXMgZm9yIGludGVybmFsIHVzZQogICAgLy8gU2VlIHNlY3Rpb24gMy4xMCBvZiBUaGUgVW5pY29kZSBTdGFuZGFyZCwgdiAyLjAuCiAgICAvLwoKICAgIC8vIFBhY2thZ2UtYWNjZXNzaWJsZSBmb3IgdXNlIGJ5IENvbXBvc2VkQ2hhckl0ZXIKICAgIHN0YXRpYyBmaW5hbCBjaGFyIEhBTkdVTF9CQVNFICAgPSAweGFjMDA7CiAgICBzdGF0aWMgZmluYWwgY2hhciBIQU5HVUxfTElNSVQgID0gMHhkN2E0OwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgSkFNT19MQkFTRSAgICA9IDB4MTEwMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgSkFNT19WQkFTRSAgICA9IDB4MTE2MTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgSkFNT19UQkFTRSAgICA9IDB4MTFhNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCAgSkFNT19MQ09VTlQgICA9IDE5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50ICBKQU1PX1ZDT1VOVCAgID0gMjE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgIEpBTU9fVENPVU5UICAgPSAyODsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCAgSkFNT19OQ09VTlQgICA9IEpBTU9fVkNPVU5UICogSkFNT19UQ09VTlQ7CgogICAgLyoqCiAgICAgKiBDb252ZXJ0IGEgc2luZ2xlIEhhbmd1bCBzeWxsYWJsZSBpbnRvIG9uZSBvciBtb3JlIEphbW8gY2hhcmFjdGVycy4KICAgICAqCiAgICAgKiBAcGFyYW0gY29uam9pbiBJZiB0cnVlLCBkZWNvbXBvc2UgSmFtbyBpbnRvIGNvbmpvaW5pbmcgSmFtby4KICAgICAqLwogICAgc3RhdGljIGludCBoYW5ndWxUb0phbW8oY2hhciBjaCwgU3RyaW5nQnVmZmVyIHJlc3VsdCwgaW50IGRlY29tcExpbWl0KSB7CiAgICAgICAgY2hhciBzSW5kZXggID0gKGNoYXIpKGNoIC0gSEFOR1VMX0JBU0UpOwogICAgICAgIGNoYXIgbGVhZGluZyA9IChjaGFyKShKQU1PX0xCQVNFICsgc0luZGV4IC8gSkFNT19OQ09VTlQpOwogICAgICAgIGNoYXIgdm93ZWwgICA9IChjaGFyKShKQU1PX1ZCQVNFICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNJbmRleCAlIEpBTU9fTkNPVU5UKSAvIEpBTU9fVENPVU5UKTsKICAgICAgICBjaGFyIHRyYWlsaW5nPSAoY2hhcikoSkFNT19UQkFTRSArIChzSW5kZXggJSBKQU1PX1RDT1VOVCkpOwoKICAgICAgICBpbnQgbGVuZ3RoID0gMDsKCiAgICAgICAgbGVuZ3RoICs9IGphbW9BcHBlbmQobGVhZGluZywgZGVjb21wTGltaXQsIHJlc3VsdCk7CiAgICAgICAgbGVuZ3RoICs9IGphbW9BcHBlbmQodm93ZWwsIGRlY29tcExpbWl0LCByZXN1bHQpOwogICAgICAgIGlmICh0cmFpbGluZyAhPSBKQU1PX1RCQVNFKSB7CiAgICAgICAgICAgIGxlbmd0aCArPSBqYW1vQXBwZW5kKHRyYWlsaW5nLCBkZWNvbXBMaW1pdCwgcmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxlbmd0aDsKICAgIH0KICAgIHN0YXRpYyBmaW5hbCBpbnQgamFtb0FwcGVuZChjaGFyIGNoLCBpbnQgbGltaXQsIFN0cmluZ0J1ZmZlciBkZXN0KSB7CiAgICAgICAgaW50IG9mZnNldCA9IERlY29tcERhdGEub2Zmc2V0cy5lbGVtZW50QXQoY2gpOwogICAgICAgIGlmIChvZmZzZXQgPiBsaW1pdCkgewogICAgICAgICAgICByZXR1cm4gZG9BcHBlbmQoRGVjb21wRGF0YS5jb250ZW50cywgb2Zmc2V0LCBkZXN0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBkZXN0LmFwcGVuZChjaCk7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgcHJpdmF0ZSB2b2lkIGphbW9Ub0hhbmd1bChTdHJpbmdCdWZmZXIgYnVmZmVyLCBpbnQgc3RhcnQpIHsKICAgICAgICBpbnQgb3V0ID0gMDsKICAgICAgICBpbnQgbGltaXQgPSBidWZmZXIubGVuZ3RoKCkgLSAxOwoKICAgICAgICBpbnQgaW4sIGwsIHYsIHQ7CgogICAgICAgIGZvciAoaW4gPSBzdGFydDsgaW4gPCBsaW1pdDsgaW4rKykgewogICAgICAgICAgICBjaGFyIGNoID0gYnVmZmVyLmNoYXJBdChpbik7CgogICAgICAgICAgICBpZiAoKGwgPSBjaCAtIEpBTU9fTEJBU0UpID49IDAgJiYgbCA8IEpBTU9fTENPVU5UCiAgICAgICAgICAgICAgICAgICAgJiYgKHYgPSBidWZmZXIuY2hhckF0KGluKzEpIC0gSkFNT19WQkFTRSkgPj0gMCAmJiB2IDwgSkFNT19WQ09VTlQpIHsKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAvLyBXZSd2ZSBmb3VuZCBhIHBhaXIgb2YgSmFtbyBjaGFyYWN0ZXJzIHRvIGNvbXBvc2UuCiAgICAgICAgICAgICAgICAvLyBTbmFyZiB0aGUgSmFtbyB2b3dlbCBhbmQgc2VlIGlmIHRoZXJlJ3MgYWxzbyBhIHRyYWlsaW5nIGNoYXIKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICBpbisrOyAgIC8vIFNuYXJmIHRoZSBKYW1vIHZvd2VsIHRvby4KCiAgICAgICAgICAgICAgICB0ID0gKGluIDwgbGltaXQpID8gYnVmZmVyLmNoYXJBdChpbisxKSA6IDA7CiAgICAgICAgICAgICAgICB0IC09IEpBTU9fVEJBU0U7CgogICAgICAgICAgICAgICAgaWYgKHQgPj0gMCAmJiB0IDwgSkFNT19UQ09VTlQpIHsKICAgICAgICAgICAgICAgICAgICBpbisrOyAgIC8vIFNuYXJmIHRoZSB0cmFpbGluZyBjb25zb25hbnQgdG9vCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHQgPSAwOyAgLy8gTm8gdHJhaWxpbmcgY29uc29uYW50CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBidWZmZXIuc2V0Q2hhckF0KG91dCsrLCAoY2hhcikoKGwqSkFNT19WQ09VTlQgKyB2KSAqIEpBTU9fVENPVU5UCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyB0ICsgSEFOR1VMX0JBU0UpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJ1ZmZlci5zZXRDaGFyQXQob3V0KyssIGNoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB3aGlsZSAoaW4gPCBidWZmZXIubGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmZmVyLnNldENoYXJBdChvdXQrKywgYnVmZmVyLmNoYXJBdChpbisrKSk7CiAgICAgICAgfQoKICAgICAgICBidWZmZXIuc2V0TGVuZ3RoKG91dCk7CiAgICB9CgoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSBkYXRhCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHID0gZmFsc2U7CgogICAgcHJpdmF0ZSBNb2RlICAgICAgICAgICAgICAgIG1vZGUgPSBERUNPTVA7CiAgICBwcml2YXRlIGludCAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IDA7CiAgICBwcml2YXRlIHRyYW5zaWVudCBpbnQgICAgICAgbWluRGVjb21wOwoKICAgIC8vIFRoZSBpbnB1dCB0ZXh0IGFuZCBvdXIgcG9zaXRpb24gaW4gaXQKICAgIHByaXZhdGUgQ2hhcmFjdGVySXRlcmF0b3IgICB0ZXh0OwogICAgcHJpdmF0ZSBib29sZWFuICAgICAgICAgICAgIGF0RW5kID0gZmFsc2U7CgogICAgLy8gQSBidWZmZXIgZm9yIGhvbGRpbmcgaW50ZXJtZWRpYXRlIHJlc3VsdHMKICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyICAgICAgICBidWZmZXIgPSBudWxsOwogICAgcHJpdmF0ZSBpbnQgICAgICAgICAgICAgICAgIGJ1ZmZlclBvcyA9IDA7CiAgICBwcml2YXRlIGludCAgICAgICAgICAgICAgICAgYnVmZmVyTGltaXQgPSAwOwogICAgcHJpdmF0ZSBjaGFyICAgICAgICAgICAgICAgIGN1cnJlbnRDaGFyOwoKICAgIC8vIEFub3RoZXIgYnVmZmVyIGZvciB1c2UgZHVyaW5nIGl0ZXJhdGl2ZSBjb21wb3NpdGlvbgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50ICAgIEVNUFRZID0gLTE7CiAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciAgICAgICAgZXhwbG9kZUJ1ZiA9IG51bGw7CgogICAgLy8gVGhlc2UgbXVzdCBhZ3JlZSB3aXRoIHRoZSBjb25zdGFudHMgdXNlZCBpbiBOb3JtYWxpemVyQnVpbGRlcgogICAgc3RhdGljIGZpbmFsIGludCBTVFJfSU5ERVhfU0hJRlQgPSAyOwogICAgc3RhdGljIGZpbmFsIGludCBTVFJfTEVOR1RIX01BU0sgPSAweDAwMDM7Cn07Cg==