LyoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kICAgICoKICogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogJFNvdXJjZTogL3hzcmwvTnN2bi9pY3UvaWN1NGovc3JjL2NvbS9pYm0vdGV4dC9BdHRpYy9Ob3JtYWxpemVyLmphdmEsdiAkIAogKiAkRGF0ZTogMjAwMS8wNC8wMiAxOToyMToyMSAkIAogKiAkUmV2aXNpb246IDEuMTEgJAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICovCnBhY2thZ2UgY29tLmlibS50ZXh0OwoKaW1wb3J0IGphdmEubGFuZy5DaGFyYWN0ZXI7CmltcG9ydCBqYXZhLnRleHQuQ2hhcmFjdGVySXRlcmF0b3I7CmltcG9ydCBqYXZhLnRleHQuU3RyaW5nQ2hhcmFjdGVySXRlcmF0b3I7CmltcG9ydCBjb20uaWJtLnV0aWwuQ29tcGFjdEJ5dGVBcnJheTsKaW1wb3J0IGNvbS5pYm0udXRpbC5VdGlsaXR5OwoKLyoqCiAqIDx0dD5Ob3JtYWxpemVyPC90dD4gdHJhbnNmb3JtcyBVbmljb2RlIHRleHQgaW50byBhbiBlcXVpdmFsZW50IGNvbXBvc2VkIG9yCiAqIGRlY29tcG9zZWQgZm9ybSwgYWxsb3dpbmcgZm9yIGVhc2llciBzb3J0aW5nIGFuZCBzZWFyY2hpbmcgb2YgdGV4dC4KICogPHR0Pk5vcm1hbGl6ZXI8L3R0PiBzdXBwb3J0cyB0aGUgc3RhbmRhcmQgbm9ybWFsaXphdGlvbiBmb3JtcyBkZXNjcmliZWQgaW4KICogPGEgaHJlZj0iaHR0cDovL3d3dy51bmljb2RlLm9yZy91bmljb2RlL3JlcG9ydHMvdHIxNS8iIHRhcmdldD0idW5pY29kZSI+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+IDApIHsKICAgICAgICAgICAgLy8gVE9ETzogVGhlIHBlcmZvcm1hbmNlIG9mIHRoaXMgaXMgYXdmdWw7IGFkZCBhIHdheSB0byBjb21wb3NlCiAgICAgICAgICAgIC8vIGEgU3RyaW5nQnVmZmVyIGluIHBsYWNlLgogICAgICAgICAgICBTdHJpbmcgY29tcG9zZWQgPSBjb21wb3NlKGJ1ZmZlci50b1N0cmluZygpLCBtb2RlLmNvbXBhdCgpLCBvcHRpb25zKTsKICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oInByZXZDb21wb3NlIGNhbGxlZCBjb21wb3NlKCIgKyBVdGlsaXR5LmhleChidWZmZXIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiktPiIgKyBVdGlsaXR5LmhleChjb21wb3NlZCkpOyAgICAgICAgICAgIAogICAgICAgICAgICBidWZmZXIuc2V0TGVuZ3RoKDApOwogICAgICAgICAgICBidWZmZXIuYXBwZW5kKGNvbXBvc2VkKTsKCiAgICAgICAgICAgIGlmIChidWZmZXIubGVuZ3RoKCkgPiAxKSB7CiAgICAgICAgICAgICAgICBidWZmZXJMaW1pdCA9IGJ1ZmZlclBvcyA9IGJ1ZmZlci5sZW5ndGgoKSAtIDE7CiAgICAgICAgICAgICAgICBjaCA9IGJ1ZmZlci5jaGFyQXQoYnVmZmVyUG9zKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNoID0gYnVmZmVyLmNoYXJBdCgwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgY2ggPSBET05FOwogICAgICAgIH0KCiAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oInByZXZDb21wb3NlIHJldHVybmluZyAiICsgVXRpbGl0eS5oZXgoY2gpKTsKICAgICAgICByZXR1cm4gY2g7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBidWJibGVBcHBlbmQoU3RyaW5nQnVmZmVyIHRhcmdldCwgY2hhciBjaCwgaW50IGNjbGFzcykgewogICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIgYnViYmxlQXBwZW5kKCIgKyBVdGlsaXR5LmhleCh0YXJnZXQpICsgIiwgIiArIFV0aWxpdHkuaGV4KGNoKSArICIsICIgKyBjY2xhc3MgKyAiKSIgKTsKICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiICBnZXRDb21wb3NlQ2xhc3MoIiArIFV0aWxpdHkuaGV4KGNoKSArICIpPSIgKyBnZXRDb21wb3NlQ2xhc3MoY2gpKTsKICAgICAgICBpbnQgaTsKICAgICAgICBmb3IgKGkgPSB0YXJnZXQubGVuZ3RoKCkgLSAxOyBpID49IDA7IC0taSkgewogICAgICAgICAgICBpbnQgaUNsYXNzID0gZ2V0Q29tcG9zZUNsYXNzKHRhcmdldC5jaGFyQXQoaSkpOwogICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiIGJ1YmJsZUFwcGVuZDogdGFyZ2V0WyIgKyBpICsgIl09IiArIFV0aWxpdHkuaGV4KHRhcmdldC5jaGFyQXQoaSkpICsgIiBpcyBjbGFzcyAiICsgaUNsYXNzKTsKCiAgICAgICAgICAgIGlmIChpQ2xhc3MgPT0gMSB8fCBpQ2xhc3MgPD0gY2NsYXNzKSB7ICAgICAgLy8gMSBtZWFucyBjb21iaW5pbmcgY2xhc3MgMAogICAgICAgICAgICAgICAgLy8gV2UndmUgaGl0IHNvbWV0aGluZyB3ZSBjYW4ndCBidWJibGUgdGhpcyBjaGFyYWN0ZXIgcGFzdCwgc28gaW5zZXJ0IGhlcmUKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIFdlIG5lZWQgdG8gaW5zZXJ0IGp1c3QgYWZ0ZXIgY2hhcmFjdGVyICJpIgogICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIgYnViYmxlQXBwZW5kIGluc2VydGluZyBhdCBpbmRleCAiICsgKGkrMSkpOwogICAgICAgIHRhcmdldC5pbnNlcnQoaSsxLCBjaCk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgaW50IGdldENvbXBvc2VDbGFzcyhjaGFyIGNoKSB7CiAgICAgICAgaW50IGNjbGFzcyA9IDA7CiAgICAgICAgaW50IGNoYXJJbmZvID0gY29tcG9zZUxvb2t1cChjaCk7CiAgICAgICAgaW50IHR5cGUgPSBjaGFySW5mbyAmIENvbXBvc2VEYXRhLlRZUEVfTUFTSzsKICAgICAgICBpZiAodHlwZSA9PSBDb21wb3NlRGF0YS5DT01CSU5JTkcpIHsKICAgICAgICAgICAgY2NsYXNzID0gQ29tcG9zZURhdGEudHlwZUJpdFtjaGFySW5mbyA+Pj4gQ29tcG9zZURhdGEuSU5ERVhfU0hJRlRdOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY2NsYXNzOwogICAgfQoKICAgIHN0YXRpYyBmaW5hbCBpbnQgY29tcG9zZUxvb2t1cChjaGFyIGNoKSB7CiAgICAgICAgcmV0dXJuIENvbXBvc2VEYXRhLmxvb2t1cC5lbGVtZW50QXQoY2gpOwogICAgfQoKICAgIHN0YXRpYyBmaW5hbCBpbnQgY29tcG9zZUFjdGlvbihpbnQgYmFzZUluZGV4LCBpbnQgY29tSW5kZXgpIHsKICAgICAgICByZXR1cm4gQ29tcG9zZURhdGEuYWN0aW9ucy5lbGVtZW50QXQoKGNoYXIpKGJhc2VJbmRleAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgQ29tcG9zZURhdGEuTUFYX0JBU0VTKmNvbUluZGV4KSk7CiAgICB9CgogICAgc3RhdGljIGZpbmFsIHZvaWQgZXhwbG9kZShTdHJpbmdCdWZmZXIgdGFyZ2V0LCBpbnQgaW5kZXgpIHsKICAgICAgICBjaGFyIGNoOwogICAgICAgIHdoaWxlICgoY2ggPSBDb21wb3NlRGF0YS5yZXBsYWNlLmNoYXJBdChpbmRleCsrKSkgIT0gMCkKICAgICAgICAgICAgdGFyZ2V0LmFwcGVuZChjaCk7CiAgICB9CgogICAgc3RhdGljIGZpbmFsIGNoYXIgcGFpckV4cGxvZGUoU3RyaW5nQnVmZmVyIHRhcmdldCwgaW50IGFjdGlvbikgewogICAgICAgIGludCBpbmRleCA9IENvbXBvc2VEYXRhLmFjdGlvbkluZGV4W2FjdGlvbiAtIENvbXBvc2VEYXRhLk1BWF9DT01QT1NFRF07CiAgICAgICAgZXhwbG9kZSh0YXJnZXQsIGluZGV4ICsgMSk7CiAgICAgICAgcmV0dXJuIENvbXBvc2VEYXRhLnJlcGxhY2UuY2hhckF0KGluZGV4KTsgICAvLyBOZXcgYmFzZSBjaGFyCiAgICB9CgoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gRGVjb21wb3NlIG1ldGhvZHMKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgICogU3RhdGljIG1ldGhvZCB0byBkZWNvbXBvc2UgYSA8dHQ+U3RyaW5nPC90dD4uCiAgICAgKiA8cD4KICAgICAqIFRoZSA8dHQ+b3B0aW9uczwvdHQ+IHBhcmFtZXRlciBzcGVjaWZpZXMgd2hpY2ggb3B0aW9uYWwKICAgICAqIDx0dD5Ob3JtYWxpemVyPC90dD4gZmVhdHVyZXMgYXJlIHRvIGJlIGVuYWJsZWQgZm9yIHRoaXMgb3BlcmF0aW9uLgogICAgICogQ3VycmVudGx5IHRoZSBvbmx5IGF2YWlsYWJsZSBvcHRpb24gaXMge0BsaW5rICNJR05PUkVfSEFOR1VMfS4KICAgICAqIFRoZSBkZXNpcmVkIG9wdGlvbnMgc2hvdWxkIGJlIE9SJ2VkIHRvZ2V0aGVyIHRvIGRldGVybWluZSB0aGUgdmFsdWUKICAgICAqIG9mIHRoaXMgYXJndW1lbnQuICBJZiB5b3Ugd2FudCB0aGUgZGVmYXVsdCBiZWhhdmlvciBjb3JyZXNwb25kaW5nCiAgICAgKiB0byBVbmljb2RlIE5vcm1hbGl6YXRpb24gRm9ybSA8Yj5EPC9iPiBvciA8Yj5LRDwvYj4sCiAgICAgKiB1c2UgMCBmb3IgdGhpcyBhcmd1bWVudC4KICAgICAqIDxwPgogICAgICogQHBhcmFtIHN0ciAgIHRoZSBzdHJpbmcgdG8gYmUgZGVjb21wb3NlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gY29tcGF0ICAgIFBlcmZvcm0gY29tcGF0aWJpbGl0eSBkZWNvbXBvc2l0aW9uLgogICAgICogICAgICAgICAgICAgICAgICBJZiB0aGlzIGFyZ3VtZW50IGlzIDx0dD5mYWxzZTwvdHQ+LCBvbmx5IGNhbm9uaWNhbAogICAgICogICAgICAgICAgICAgICAgICBkZWNvbXBvc2l0aW9uIHdpbGwgYmUgcGVyZm9ybWVkLgogICAgICoKICAgICAqCiAgICAgKiBAcmV0dXJuICAgICAgdGhlIGRlY29tcG9zZWQgc3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBkZWNvbXBvc2UoU3RyaW5nIHNvdXJjZSwgYm9vbGVhbiBjb21wYXQsIGludCBvcHRpb25zKQogICAgewogICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCItLS0tLS0tLS0tLS0tLS0gdG9wIG9mIGRlY29tcG9zZSgpIC0tLS0tLS0tLS0tLS0tLSIpOwoKICAgICAgICBib29sZWFuIGhhbmd1bCA9IChvcHRpb25zICYgSUdOT1JFX0hBTkdVTCkgPT0gMDsKICAgICAgICBpbnQgbWluRGVjb21wID0gY29tcGF0ID8gMCA6IERlY29tcERhdGEuTUFYX0NPTVBBVDsKIAogICAgICAgIFN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CiAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG51bGw7CgogICAgICAgIGludCBpID0gMCwgYnVmUHRyID0gLTE7CgogICAgICAgIHdoaWxlIChpIDwgc291cmNlLmxlbmd0aCgpIHx8IGJ1ZlB0ciA+PSAwKQogICAgICAgIHsKICAgICAgICAgICAgY2hhciBjaDsKCiAgICAgICAgICAgIGlmIChidWZQdHIgPj0gMCkgewogICAgICAgICAgICAgICAgY2ggPSBidWZmZXIuY2hhckF0KGJ1ZlB0cisrKTsKICAgICAgICAgICAgICAgIGlmIChidWZQdHIgPT0gYnVmZmVyLmxlbmd0aCgpKSB7CiAgICAgICAgICAgICAgICAgICAgYnVmUHRyID0gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQXQoaSsrKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaW50IG9mZnNldCA9IERlY29tcERhdGEub2Zmc2V0cy5lbGVtZW50QXQoY2gpOwogICAgICAgICAgICBpbnQgaW5kZXggPSBvZmZzZXQgJiBEZWNvbXBEYXRhLkRFQ09NUF9NQVNLOwoKICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImRlY29tcG9zZSBnb3QgIiArIFV0aWxpdHkuaGV4KGNoKSk7CgogICAgICAgICAgICBpZiAoaW5kZXggPiBtaW5EZWNvbXApIHsKICAgICAgICAgICAgICAgIGlmICgob2Zmc2V0ICYgRGVjb21wRGF0YS5ERUNPTVBfUkVDVVJTRSkgIT0gMCkgewogICAgICAgICAgICAgICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCIgIiArIFV0aWxpdHkuaGV4KGNoKSArICIgaGFzIFJFQ1VSU0lWRSBkZWNvbXBvc2l0aW9uLCBpbmRleD0iICsgaW5kZXgpOwogICAgICAgICAgICAgICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLnNldExlbmd0aCgwKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZG9BcHBlbmQoRGVjb21wRGF0YS5jb250ZW50cywgaW5kZXgsIGJ1ZmZlcik7CiAgICAgICAgICAgICAgICAgICAgYnVmUHRyID0gMDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIiAiICsgVXRpbGl0eS5oZXgoY2gpICsgIiBoYXMgZGVjb21wb3NpdGlvbiwgaW5kZXg9IiArIGluZGV4KTsKICAgICAgICAgICAgICAgICAgICBkb0FwcGVuZChEZWNvbXBEYXRhLmNvbnRlbnRzLCBpbmRleCwgcmVzdWx0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChjaCA+PSBIQU5HVUxfQkFTRSAmJiBjaCA8IEhBTkdVTF9MSU1JVCAmJiBoYW5ndWwpIHsKICAgICAgICAgICAgICAgIGhhbmd1bFRvSmFtbyhjaCwgcmVzdWx0LCBtaW5EZWNvbXApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChjaCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZml4Q2Fub25pY2FsKHJlc3VsdCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdC50b1N0cmluZygpOwogICAgfQoKICAgIC8qKgogICAgICogRGVjb21wb3NlIHN0YXJ0aW5nIHdpdGggY3VycmVudCBpbnB1dCBjaGFyYWN0ZXIgYW5kIGNvbnRpbnVpbmcKICAgICAqIHVudGlsIGp1c3QgYmVmb3JlIHRoZSBuZXh0IGJhc2UgY2hhci4KICAgICAqIDxwPgogICAgICogPGI+SW5wdXQ8L2I+OgogICAgICogPHVsPgogICAgICogIDxsaT51bmRlcmx5aW5nIGNoYXIgaXRlciBwb2ludHMgdG8gZmlyc3QgY2hhcmFjdGVyIHRvIGRlY29tcG9zZQogICAgICogPC91bD4KICAgICAqIDxwPgogICAgICogPGI+T3V0cHV0OjwvYj4KICAgICAqIDx1bD4KICAgICAqICA8bGk+cmV0dXJucyBmaXJzdCBjaGFyIG9mIGRlY29tcG9zaXRpb24gb3IgRE9ORSBpZiBhdCBlbmQKICAgICAqICA8bGk+VW5kZXJseWluZyBjaGFyIGl0ZXIgaXMgcG9pbnRpbmcgYXQgbmV4dCBiYXNlIGNoYXIgb3IgcGFzdCBlbmQKICAgICAqIDwvdWw+CiAgICAgKi8KICAgIHByaXZhdGUgY2hhciBuZXh0RGVjb21wKCkKICAgIHsKICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiLS0tLS0tLS0tLS0tLS0tIHRvcCBvZiBuZXh0RGVjb21wKCkgLS0tLS0tLS0tLS0tLS0tIik7CgogICAgICAgIGJvb2xlYW4gaGFuZ3VsID0gKG9wdGlvbnMgJiBJR05PUkVfSEFOR1VMKSA9PSAwOwogICAgICAgIGNoYXIgY2ggPSBjdXJGb3J3YXJkKCk7CgogICAgICAgIGludCBvZmZzZXQgPSBEZWNvbXBEYXRhLm9mZnNldHMuZWxlbWVudEF0KGNoKTsKICAgICAgICBpbnQgaW5kZXggPSBvZmZzZXQgJiBEZWNvbXBEYXRhLkRFQ09NUF9NQVNLOwoKICAgICAgICBpZiAoaW5kZXggPiBtaW5EZWNvbXAgfHwgRGVjb21wRGF0YS5jYW5vbkNsYXNzLmVsZW1lbnRBdChjaCkgIT0gRGVjb21wRGF0YS5CQVNFKQogICAgICAgIHsKICAgICAgICAgICAgaW5pdEJ1ZmZlcigpOwoKICAgICAgICAgICAgaWYgKGluZGV4ID4gbWluRGVjb21wKSB7CiAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiICIgKyBVdGlsaXR5LmhleChjaCkgKyAiIGhhcyBkZWNvbXBvc2l0aW9uLCBpbmRleD0iICsgaW5kZXgpOwogICAgICAgICAgICAgICAgZG9BcHBlbmQoRGVjb21wRGF0YS5jb250ZW50cywgaW5kZXgsIGJ1ZmZlcik7CgogICAgICAgICAgICAgICAgaWYgKChvZmZzZXQgJiBEZWNvbXBEYXRhLkRFQ09NUF9SRUNVUlNFKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gTmVlZCB0byBkZWNvbXBvc2UgdGhlIG91dHB1dCBvZiB0aGlzIGRlY29tcG9zaXRpb24gcmVjdXJzaXZlbHkuCiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBidWZmZXIubGVuZ3RoKCk7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICBjaCA9IGJ1ZmZlci5jaGFyQXQoaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gRGVjb21wRGF0YS5vZmZzZXRzLmVsZW1lbnRBdChjaCkgJiBEZWNvbXBEYXRhLkRFQ09NUF9NQVNLOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gbWluRGVjb21wKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICs9IGRvUmVwbGFjZShEZWNvbXBEYXRhLmNvbnRlbnRzLCBpbmRleCwgYnVmZmVyLCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoY2gpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJvb2xlYW4gbmVlZFRvUmVvcmRlciA9IGZhbHNlOwoKICAgICAgICAgICAgLy8gQW55IG90aGVyIGNvbWJpbmluZyBjaGFjdGVycyB0aGF0IGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgZGVjb21wb3NlZAogICAgICAgICAgICAvLyBjaGFyYWN0ZXIgbXVzdCBiZSBpbmNsdWRlZCBpbiB0aGUgYnVmZmVyIHRvbywgYmVjYXVzZSB0aGV5J3JlCiAgICAgICAgICAgIC8vIGNvbmNlcHR1YWxseSBwYXJ0IG9mIHRoZSBzYW1lIGxvZ2ljYWwgY2hhcmFjdGVyLgogICAgICAgICAgICB3aGlsZSAoKGNoID0gdGV4dC5uZXh0KCkpICE9IERPTkUKICAgICAgICAgICAgICAgICYmIERlY29tcERhdGEuY2Fub25DbGFzcy5lbGVtZW50QXQoY2gpICE9IERlY29tcERhdGEuQkFTRSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbmVlZFRvUmVvcmRlciA9IHRydWU7CiAgICAgICAgICAgICAgICAvLyBEZWNvbXBvc2UgYW55IG9mIHRoZXNlIGNoYXJhY3RlcnMgdGhhdCBuZWVkIGl0IC0gTGl1CiAgICAgICAgICAgICAgICBpbmRleCA9IERlY29tcERhdGEub2Zmc2V0cy5lbGVtZW50QXQoY2gpICYgRGVjb21wRGF0YS5ERUNPTVBfTUFTSzsKICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IG1pbkRlY29tcCkgewogICAgICAgICAgICAgICAgICAgIGRvQXBwZW5kKERlY29tcERhdGEuY29udGVudHMsIGluZGV4LCBidWZmZXIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGNoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGJ1ZmZlci5sZW5ndGgoKSA+IDEgJiYgbmVlZFRvUmVvcmRlcikgewogICAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbW9yZSB0aGFuIG9uZSBjb21iaW5pbmcgY2hhcmFjdGVyIGluIHRoZSBidWZmZXIsCiAgICAgICAgICAgICAgICAvLyBwdXQgdGhlbSBpbnRvIHRoZSBjYW5vbmljYWwgb3JkZXIuCiAgICAgICAgICAgICAgICAvLyBCdXQgd2UgZG9uJ3QgbmVlZCB0byBzb3J0IGlmIG9ubHkgY2hhcmFjdGVycyBhcmUgdGhlIG9uZXMgdGhhdAogICAgICAgICAgICAgICAgLy8gcmVzdWx0ZWQgZnJvbSBkZWNvbW9zaW5nIHRoZSBiYXNlIGNoYXJhY3Rlci4KICAgICAgICAgICAgICAgIGZpeENhbm9uaWNhbChidWZmZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJ1ZmZlckxpbWl0ID0gYnVmZmVyLmxlbmd0aCgpIC0gMTsKICAgICAgICAgICAgY2ggPSBidWZmZXIuY2hhckF0KDApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIEp1c3QgdXNlIHRoaXMgY2hhcmFjdGVyLCBidXQgZmlyc3QgYWR2YW5jZSB0byB0aGUgbmV4dCBvbmUKICAgICAgICAgICAgdGV4dC5uZXh0KCk7CgogICAgICAgICAgICAvLyBEbyBIYW5ndWwgLT4gSmFtbyBkZWNvbXBvc2l0aW9uIGlmIG5lY2Vzc2FyeQogICAgICAgICAgICBpZiAoaGFuZ3VsICYmIGNoID49IEhBTkdVTF9CQVNFICYmIGNoIDwgSEFOR1VMX0xJTUlUKSB7CiAgICAgICAgICAgICAgICBpbml0QnVmZmVyKCk7CiAgICAgICAgICAgICAgICBoYW5ndWxUb0phbW8oY2gsIGJ1ZmZlciwgbWluRGVjb21wKTsKICAgICAgICAgICAgICAgIGJ1ZmZlckxpbWl0ID0gYnVmZmVyLmxlbmd0aCgpIC0gMTsKICAgICAgICAgICAgICAgIGNoID0gYnVmZmVyLmNoYXJBdCgwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiIG5leHREZWNvbXAgcmV0dXJuaW5nICIgKyBVdGlsaXR5LmhleChjaCkgKyAiLCB0ZXh0IGluZGV4PSIgKyB0ZXh0LmdldEluZGV4KCkpOwogICAgICAgIHJldHVybiBjaDsKICAgIH0KCiAgICAvKioKICAgICAqIERlY29tcG9zZSBzdGFydGluZyB3aXRoIHRoZSBpbnB1dCBjaGFyIGp1c3QgYmVmb3JlIHRoZSBjdXJyZW50IHBvc2l0aW9uCiAgICAgKiBhbmQgY29udGludWluZyBiYWNrd2FyZCB1bnRpbCAoYW5kIGluY2x1ZGluZykgdGhlIHByZXZpb3VzIGJhc2UgY2hhci4KICAgICAqIDxwPgogICAgICogPGI+SW5wdXQ8L2I+OgogICAgICogPHVsPgogICAgICogIDxsaT51bmRlcmx5aW5nIGNoYXIgaXRlciBwb2ludHMganVzdCBhZnRlciBsYXN0IGNoYXIgdG8gZGVjb21wb3NlCiAgICAgKiA8L3VsPgogICAgICogPHA+CiAgICAgKiA8Yj5PdXRwdXQ6PC9iPgogICAgICogPHVsPgogICAgICogIDxsaT5yZXR1cm5zIGxhc3QgY2hhciBvZiByZXN1bHRpbmcgZGVjb21wb3NpdGlvbiBzZXF1ZW5jZQogICAgICogIDxsaT51bmRlcmx5aW5nIGl0ZXIgcG9pbnRzIHRvIGxvd2VzdC1pbmRleCBjaGFyIHdlIGRlY29tcG9zZWQsIGkuZS4gdGhlIGJhc2UgY2hhcgogICAgICogPC91bD4KICAgICAqLwogICAgcHJpdmF0ZSBjaGFyIHByZXZEZWNvbXAoKSB7CiAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oIi0tLS0tLS0tLS0tLS0tLSB0b3Agb2YgcHJldkRlY29tcCgpIC0tLS0tLS0tLS0tLS0tLSIpOwoKICAgICAgICBib29sZWFuIGhhbmd1bCA9IChvcHRpb25zICYgSUdOT1JFX0hBTkdVTCkgPT0gMDsKCiAgICAgICAgY2hhciBjaCA9IGN1ckJhY2t3YXJkKCk7CgogICAgICAgIGludCBvZmZzZXQgPSBEZWNvbXBEYXRhLm9mZnNldHMuZWxlbWVudEF0KGNoKTsKICAgICAgICBpbnQgaW5kZXggPSBvZmZzZXQgJiBEZWNvbXBEYXRhLkRFQ09NUF9NQVNLOwoKICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigicHJldkRlY29tcCBnb3QgaW5wdXQgY2hhciAiICsgVXRpbGl0eS5oZXgoY2gpKTsKCiAgICAgICAgaWYgKGluZGV4ID4gbWluRGVjb21wIHx8IERlY29tcERhdGEuY2Fub25DbGFzcy5lbGVtZW50QXQoY2gpICE9IERlY29tcERhdGEuQkFTRSkKICAgICAgICB7CiAgICAgICAgICAgIGluaXRCdWZmZXIoKTsKCiAgICAgICAgICAgIC8vIFRoaXMgbWV0aG9kIHJld3JpdHRlbiB0byBwYXNzIGNvbmZvcm1hbmNlIHRlc3RzLiAtIExpdQogICAgICAgICAgICAvLyBDb2xsZWN0IGFsbCBjaGFyYWN0ZXJzIHVwIHRvIHRoZSBwcmV2aW91cyBiYXNlIGNoYXIKICAgICAgICAgICAgd2hpbGUgKGNoICE9IERPTkUpIHsKICAgICAgICAgICAgICAgIGJ1ZmZlci5pbnNlcnQoMCwgY2gpOwogICAgICAgICAgICAgICAgaWYgKERlY29tcERhdGEuY2Fub25DbGFzcy5lbGVtZW50QXQoY2gpID09IERlY29tcERhdGEuQkFTRSkgYnJlYWs7CiAgICAgICAgICAgICAgICBjaCA9IHRleHQucHJldmlvdXMoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oInByZXZEZWNvbXAgYnVmZmVyOiAiICsgVXRpbGl0eS5oZXgoYnVmZmVyKSk7CgogICAgICAgICAgICAvLyBEZWNvbXBvc2UgdGhlIGJ1ZmZlcgogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ1ZmZlci5sZW5ndGgoKTsgaSsrKSB7CiAgICAgICAgICAgICAgICBjaCA9IGJ1ZmZlci5jaGFyQXQoaSk7CiAgICAgICAgICAgICAgICBvZmZzZXQgPSBEZWNvbXBEYXRhLm9mZnNldHMuZWxlbWVudEF0KGNoKTsKICAgICAgICAgICAgICAgIGluZGV4ID0gb2Zmc2V0ICYgRGVjb21wRGF0YS5ERUNPTVBfTUFTSzsgICAgICAgICAgICAgICAgCgogICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gbWluRGVjb21wKSB7CiAgICAgICAgICAgICAgICAgICAgaW50IGogPSBkb1JlcGxhY2UoRGVjb21wRGF0YS5jb250ZW50cywgaW5kZXgsIGJ1ZmZlciwgaSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKChvZmZzZXQgJiBEZWNvbXBEYXRhLkRFQ09NUF9SRUNVUlNFKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5lZWQgdG8gZGVjb21wb3NlIHRoaXMgcmVjdXJzaXZlbHkKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBqOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gYnVmZmVyLmNoYXJBdChpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gRGVjb21wRGF0YS5vZmZzZXRzLmVsZW1lbnRBdChjaCkgJiBEZWNvbXBEYXRhLkRFQ09NUF9NQVNLOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gbWluRGVjb21wKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSArPSBkb1JlcGxhY2UoRGVjb21wRGF0YS5jb250ZW50cywgaW5kZXgsIGJ1ZmZlciwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaSA9IGo7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJwcmV2RGVjb21wIGJ1ZmZlciBhZnRlciBkZWNvbXA6ICIgKyBVdGlsaXR5LmhleChidWZmZXIpKTsKCiAgICAgICAgICAgIGlmIChidWZmZXIubGVuZ3RoKCkgPiAxKSB7CiAgICAgICAgICAgICAgICAvLyBJZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGNvbWJpbmluZyBjaGFyYWN0ZXIgaW4gdGhlIGJ1ZmZlciwKICAgICAgICAgICAgICAgIC8vIHB1dCB0aGVtIGludG8gdGhlIGNhbm9uaWNhbCBvcmRlci4KICAgICAgICAgICAgICAgIGZpeENhbm9uaWNhbChidWZmZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJ1ZmZlckxpbWl0ID0gYnVmZmVyUG9zID0gYnVmZmVyLmxlbmd0aCgpIC0gMTsKICAgICAgICAgICAgY2ggPSBidWZmZXIuY2hhckF0KGJ1ZmZlclBvcyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGhhbmd1bCAmJiBjaCA+PSBIQU5HVUxfQkFTRSAmJiBjaCA8IEhBTkdVTF9MSU1JVCkgewogICAgICAgICAgICBpbml0QnVmZmVyKCk7CiAgICAgICAgICAgIGhhbmd1bFRvSmFtbyhjaCwgYnVmZmVyLCBtaW5EZWNvbXApOwogICAgICAgICAgICBidWZmZXJMaW1pdCA9IGJ1ZmZlclBvcyA9IGJ1ZmZlci5sZW5ndGgoKSAtIDE7CiAgICAgICAgICAgIGNoID0gYnVmZmVyLmNoYXJBdChidWZmZXJQb3MpOwogICAgICAgIH0KICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiIHByZXZEZWNvbXAgcmV0dXJuaW5nICciICsgY2ggKyAiJyAiICsgVXRpbGl0eS5oZXgoY2gpICsgIiwgdGV4dCBpbmRleD0iICsgdGV4dC5nZXRJbmRleCgpKTsKICAgICAgICByZXR1cm4gY2g7CiAgICB9CgogICAgc3RhdGljIGZpbmFsIGludCBnZXRDbGFzcyhjaGFyIGNoKSB7CiAgICAgICAgaW50IHZhbHVlID0gRGVjb21wRGF0YS5jYW5vbkNsYXNzLmVsZW1lbnRBdChjaCk7CiAgICAgICAgcmV0dXJuICh2YWx1ZSA+PSAwKSA/IHZhbHVlIDogdmFsdWUgKyAyNTY7CiAgICB9CgoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gQ2hhcmFjdGVySXRlcmF0b3Igb3ZlcnJpZGVzCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgY3VycmVudCBjaGFyYWN0ZXIgaW4gdGhlIG5vcm1hbGl6ZWQgdGV4dC4KICAgICAqLwogICAgcHVibGljIGNoYXIgY3VycmVudCgpIHsKICAgICAgICBpZiAoY3VycmVudENoYXIgPT0gRE9ORSkgewogICAgICAgICAgICBpZiAobW9kZS5jb21wb3NlKCkpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gbmV4dENvbXBvc2UoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChtb2RlLmRlY29tcCgpKSB7CiAgICAgICAgICAgICAgICBjdXJyZW50Q2hhciA9IG5leHREZWNvbXAoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gdGV4dC5jdXJyZW50KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGN1cnJlbnRDaGFyOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIG5vcm1hbGl6ZWQgdGV4dC4gIFRoaXMgcmVzZXRzCiAgICAgKiB0aGUgPHR0Pk5vcm1hbGl6ZXInczwvdHQ+IHBvc2l0aW9uIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRleHQuCiAgICAgKi8KICAgIHB1YmxpYyBjaGFyIGZpcnN0KCkgewogICAgICAgIHJldHVybiBzZXRJbmRleCh0ZXh0LmdldEJlZ2luSW5kZXgoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBub3JtYWxpemVkIHRleHQuICBUaGlzIHJlc2V0cwogICAgICogdGhlIDx0dD5Ob3JtYWxpemVyJ3M8L3R0PiBwb3NpdGlvbiB0byBiZSBqdXN0IGJlZm9yZSB0aGUKICAgICAqIHRoZSBpbnB1dCB0ZXh0IGNvcnJlc3BvbmRpbmcgdG8gdGhhdCBub3JtYWxpemVkIGNoYXJhY3Rlci4KICAgICAqLwogICAgcHVibGljIGNoYXIgbGFzdCgpIHsKICAgICAgICB0ZXh0LnNldEluZGV4KHRleHQuZ2V0RW5kSW5kZXgoKSAtIDEpOyAgLy8gU2V0dGluZyB0byBnZXRFbmRJbmRleCgpIGZhaWxzIGluIDEuMQogICAgICAgIGF0RW5kID0gdHJ1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc28gd29yayBhcm91bmQgdGhlIGJ1ZwoKICAgICAgICBjdXJyZW50Q2hhciA9IERPTkU7ICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGN1cnJlbnQgY2hhciBoYXNuJ3QgYmVlbiBwcm9jZXNzZWQKICAgICAgICBjbGVhckJ1ZmZlcigpOyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGJ1ZmZlciBpcyBlbXB0eSB0b28KICAgICAgICByZXR1cm4gcHJldmlvdXMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgbmV4dCBjaGFyYWN0ZXIgaW4gdGhlIG5vcm1hbGl6ZWQgdGV4dCBhbmQgYWR2YW5jZQogICAgICogdGhlIGl0ZXJhdGlvbiBwb3NpdGlvbiBieSBvbmUuICBJZiB0aGUgZW5kCiAgICAgKiBvZiB0aGUgdGV4dCBoYXMgYWxyZWFkeSBiZWVuIHJlYWNoZWQsIHtAbGluayAjRE9ORX0gaXMgcmV0dXJuZWQuCiAgICAgKi8KICAgIHB1YmxpYyBjaGFyIG5leHQoKSB7CiAgICAgICAgaWYgKGJ1ZmZlclBvcyA8IGJ1ZmZlckxpbWl0KSB7CiAgICAgICAgICAgIC8vIFRoZXJlIGFyZSBvdXRwdXQgY2hhcmFjdGVycyBsZWZ0IGluIHRoZSBidWZmZXIKICAgICAgICAgICAgY3VycmVudENoYXIgPSBidWZmZXIuY2hhckF0KCsrYnVmZmVyUG9zKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGJ1ZmZlckxpbWl0ID0gYnVmZmVyUG9zID0gMDsgICAgLy8gQnVmZmVyIGlzIG5vdyBvdXQgb2YgZGF0ZQogICAgICAgICAgICBpZiAobW9kZS5jb21wb3NlKCkpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gbmV4dENvbXBvc2UoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChtb2RlLmRlY29tcCgpKSB7CiAgICAgICAgICAgICAgICBjdXJyZW50Q2hhciA9IG5leHREZWNvbXAoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gdGV4dC5uZXh0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGN1cnJlbnRDaGFyOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBwcmV2aW91cyBjaGFyYWN0ZXIgaW4gdGhlIG5vcm1hbGl6ZWQgdGV4dCBhbmQgZGVjcmVtZW50CiAgICAgKiB0aGUgaXRlcmF0aW9uIHBvc2l0aW9uIGJ5IG9uZS4gIElmIHRoZSBiZWdpbm5pbmcKICAgICAqIG9mIHRoZSB0ZXh0IGhhcyBhbHJlYWR5IGJlZW4gcmVhY2hlZCwge0BsaW5rICNET05FfSBpcyByZXR1cm5lZC4KICAgICAqLwogICAgcHVibGljIGNoYXIgcHJldmlvdXMoKSB7CiAgICAgICAgaWYgKGJ1ZmZlclBvcyA+IDApIHsKICAgICAgICAgICAgLy8gVGhlcmUgYXJlIG91dHB1dCBjaGFyYWN0ZXJzIGxlZnQgaW4gdGhlIGJ1ZmZlcgogICAgICAgICAgICBjdXJyZW50Q2hhciA9IGJ1ZmZlci5jaGFyQXQoLS1idWZmZXJQb3MpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgYnVmZmVyTGltaXQgPSBidWZmZXJQb3MgPSAwOyAgICAvLyBCdWZmZXIgaXMgbm93IG91dCBvZiBkYXRlCiAgICAgICAgICAgIGlmIChtb2RlLmNvbXBvc2UoKSkgewogICAgICAgICAgICAgICAgY3VycmVudENoYXIgPSBwcmV2Q29tcG9zZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKG1vZGUuZGVjb21wKCkpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gcHJldkRlY29tcCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgY3VycmVudENoYXIgPSB0ZXh0LnByZXZpb3VzKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGN1cnJlbnRDaGFyOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBpdGVyYXRpb24gcG9zaXRpb24gaW4gdGhlIGlucHV0IHRleHQgdGhhdCBpcyBiZWluZyBub3JtYWxpemVkCiAgICAgKiBhbmQgcmV0dXJuIHRoZSBmaXJzdCBub3JtYWxpemVkIGNoYXJhY3RlciBhdCB0aGF0IHBvc2l0aW9uLgogICAgICogPHA+CiAgICAgKiBAcGFyYW0gaW5kZXggdGhlIGRlc2lyZWQgaW5kZXggaW4gdGhlIGlucHV0IHRleHQuCiAgICAgKgogICAgICogQHJldHVybiAgICAgIHRoZSBmaXJzdCBub3JtYWxpemVkIGNoYXJhY3RlciB0aGF0IGlzIHRoZSByZXN1bHQgb2YgaXRlcmF0aW5nCiAgICAgKiAgICAgICAgICAgICAgZm9yd2FyZCBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKgogICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGdpdmVuIGluZGV4IGlzIGxlc3MgdGhhbgogICAgICogICAgICAgICAge0BsaW5rICNnZXRCZWdpbkluZGV4fSBvciBncmVhdGVyIHRoYW4ge0BsaW5rICNnZXRFbmRJbmRleH0uCiAgICAgKi8KICAgIHB1YmxpYyBjaGFyIHNldEluZGV4KGludCBpbmRleCkgewogICAgICAgIHRleHQuc2V0SW5kZXgoaW5kZXgpOyAgIC8vIENoZWNrcyByYW5nZQogICAgICAgIGN1cnJlbnRDaGFyID0gRE9ORTsgICAgIC8vIFRoZSBjdXJyZW50IGNoYXIgaGFzbid0IGJlZW4gcHJvY2Vzc2VkCiAgICAgICAgY2xlYXJCdWZmZXIoKTsgICAgICAgICAgLy8gVGhlIGJ1ZmZlciBpcyBlbXB0eSB0b28KCiAgICAgICAgcmV0dXJuIGN1cnJlbnQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHJpZXZlIHRoZSBjdXJyZW50IGl0ZXJhdGlvbiBwb3NpdGlvbiBpbiB0aGUgaW5wdXQgdGV4dCB0aGF0IGlzCiAgICAgKiBiZWluZyBub3JtYWxpemVkLiAgVGhpcyBtZXRob2QgaXMgdXNlZnVsIGluIGFwcGxpY2F0aW9ucyBzdWNoIGFzCiAgICAgKiBzZWFyY2hpbmcsIHdoZXJlIHlvdSBuZWVkIHRvIGJlIGFibGUgdG8gZGV0ZXJtaW5lIHRoZSBwb3NpdGlvbiBpbgogICAgICogdGhlIGlucHV0IHRleHQgdGhhdCBjb3JyZXNwb25kcyB0byBhIGdpdmVuIG5vcm1hbGl6ZWQgb3V0cHV0IGNoYXJhY3Rlci4KICAgICAqLwogICAgcHVibGljIGZpbmFsIGludCBnZXRJbmRleCgpIHsKICAgICAgICByZXR1cm4gdGV4dC5nZXRJbmRleCgpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0cmlldmUgdGhlIGluZGV4IG9mIHRoZSBzdGFydCBvZiB0aGUgaW5wdXQgdGV4dC4gIFRoaXMgaXMgdGhlIGJlZ2luIGluZGV4CiAgICAgKiBvZiB0aGUgPHR0PkNoYXJhY3Rlckl0ZXJhdG9yPC90dD4gb3IgdGhlIHN0YXJ0IChpLmUuIDApIG9mIHRoZSA8dHQ+U3RyaW5nPC90dD4KICAgICAqIG92ZXIgd2hpY2ggdGhpcyA8dHQ+Tm9ybWFsaXplcjwvdHQ+IGlzIGl0ZXJhdGluZwogICAgICovCiAgICBwdWJsaWMgZmluYWwgaW50IGdldEJlZ2luSW5kZXgoKSB7CiAgICAgICAgcmV0dXJuIHRleHQuZ2V0QmVnaW5JbmRleCgpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0cmlldmUgdGhlIGluZGV4IG9mIHRoZSBlbmQgb2YgdGhlIGlucHV0IHRleHQuICBUaGlzIGlzIHRoZSBlbmQgaW5kZXgKICAgICAqIG9mIHRoZSA8dHQ+Q2hhcmFjdGVySXRlcmF0b3I8L3R0PiBvciB0aGUgbGVuZ3RoIG9mIHRoZSA8dHQ+U3RyaW5nPC90dD4KICAgICAqIG92ZXIgd2hpY2ggdGhpcyA8dHQ+Tm9ybWFsaXplcjwvdHQ+IGlzIGl0ZXJhdGluZwogICAgICovCiAgICBwdWJsaWMgZmluYWwgaW50IGdldEVuZEluZGV4KCkgewogICAgICAgIHJldHVybiB0ZXh0LmdldEVuZEluZGV4KCk7CiAgICB9CgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBQcm9wZXJ0eSBhY2Nlc3MgbWV0aG9kcwogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBTZXQgdGhlIG5vcm1hbGl6YXRpb24gbW9kZSBmb3IgdGhpcyBvYmplY3QuCiAgICAgKiA8cD4KICAgICAqIDxiPk5vdGU6PC9iPklmIHRoZSBub3JtYWxpemF0aW9uIG1vZGUgaXMgY2hhbmdlZCB3aGlsZSBpdGVyYXRpbmcKICAgICAqIG92ZXIgYSBzdHJpbmcsIGNhbGxzIHRvIHtAbGluayAjbmV4dH0gYW5kIHtAbGluayAjcHJldmlvdXN9IG1heQogICAgICogcmV0dXJuIHByZXZpb3VzbHkgYnVmZmVycyBjaGFyYWN0ZXJzIGluIHRoZSBvbGQgbm9ybWFsaXphdGlvbiBtb2RlCiAgICAgKiB1bnRpbCB0aGUgaXRlcmF0aW9uIGlzIGFibGUgdG8gcmUtc3luYyBhdCB0aGUgbmV4dCBiYXNlIGNoYXJhY3Rlci4KICAgICAqIEl0IGlzIHNhZmVzdCB0byBjYWxsIHtAbGluayAjc2V0VGV4dCBzZXRUZXh0KCl9LCB7QGxpbmsgI2ZpcnN0fSwKICAgICAqIHtAbGluayAjbGFzdH0sIGV0Yy4gYWZ0ZXIgY2FsbGluZyA8dHQ+c2V0TW9kZTwvdHQ+LgogICAgICogPHA+CiAgICAgKiBAcGFyYW0gbmV3TW9kZSB0aGUgbmV3IG1vZGUgZm9yIHRoaXMgPHR0Pk5vcm1hbGl6ZXI8L3R0Pi4KICAgICAqIFRoZSBzdXBwb3J0ZWQgbW9kZXMgYXJlOgogICAgICogPHVsPgogICAgICogIDxsaT57QGxpbmsgI0NPTVBPU0V9ICAgICAgICAtIFVuaWNvZGUgY2Fub25pY2FsIGRlY29tcG9zaXRpaW9uCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb2xsb3dlZCBieSBjYW5vbmljYWwgY29tcG9zaXRpb24uCiAgICAgKiAgPGxpPntAbGluayAjQ09NUE9TRV9DT01QQVR9IC0gVW5pY29kZSBjb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpaW9uCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb2xsd2VkIGJ5IGNhbm9uaWNhbCBjb21wb3NpdGlvbi4KICAgICAqICA8bGk+e0BsaW5rICNERUNPTVB9ICAgICAgICAgLSBVbmljb2RlIGNhbm9uaWNhbCBkZWNvbXBvc2l0aW9uCiAgICAgKiAgPGxpPntAbGluayAjREVDT01QX0NPTVBBVH0gIC0gVW5pY29kZSBjb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpb24uCiAgICAgKiAgPGxpPntAbGluayAjTk9fT1B9ICAgICAgICAgIC0gRG8gbm90aGluZyBidXQgcmV0dXJuIGNoYXJhY3RlcnMKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gdGhlIHVuZGVybHlpbmcgaW5wdXQgdGV4dC4KICAgICAqIDwvdWw+CiAgICAgKgogICAgICogQHNlZSAjZ2V0TW9kZQogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRNb2RlKE1vZGUgbmV3TW9kZSkgewogICAgICAgIG1vZGUgPSBuZXdNb2RlOwogICAgICAgIG1pbkRlY29tcCA9IG1vZGUuY29tcGF0KCkgPyAwIDogRGVjb21wRGF0YS5NQVhfQ09NUEFUOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBiYXNpYyBvcGVyYXRpb24gcGVyZm9ybWVkIGJ5IHRoaXMgPHR0Pk5vcm1hbGl6ZXI8L3R0PgogICAgICoKICAgICAqIEBzZWUgI3NldE1vZGUKICAgICAqLwogICAgcHVibGljIE1vZGUgZ2V0TW9kZSgpIHsKICAgICAgICByZXR1cm4gbW9kZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCBvcHRpb25zIHRoYXQgYWZmZWN0IHRoaXMgPHR0Pk5vcm1hbGl6ZXI8L3R0PidzIG9wZXJhdGlvbi4KICAgICAqIE9wdGlvbnMgZG8gbm90IGNoYW5nZSB0aGUgYmFzaWMgY29tcG9zaXRpb24gb3IgZGVjb21wb3NpdGlvbiBvcGVyYXRpb24KICAgICAqIHRoYXQgaXMgYmVpbmcgcGVyZm9ybWVkICwgYnV0IHRoZXkgY29udHJvbCB3aGV0aGVyCiAgICAgKiBjZXJ0YWluIG9wdGlvbmFsIHBvcnRpb25zIG9mIHRoZSBvcGVyYXRpb24gYXJlIGRvbmUuCiAgICAgKiBDdXJyZW50bHkgdGhlIG9ubHkgYXZhaWxhYmxlIG9wdGlvbiBpczoKICAgICAqIDxwPgogICAgICogPHVsPgogICAgICogICA8bGk+e0BsaW5rICNJR05PUkVfSEFOR1VMfSAtIERvIG5vdCBkZWNvbXBvc2UgSGFuZ3VsIHN5bGxhYmxlcyBpbnRvIHRoZSBKYW1vIGFscGhhYmV0CiAgICAgKiAgICAgICAgICBhbmQgdmljZS12ZXJzYS4gIFRoaXMgb3B0aW9uIGlzIG9mZiBieSBkZWZhdWx0ICg8aT5pLmUuPC9pPiBIYW5ndWwgcHJvY2Vzc2luZwogICAgICogICAgICAgICAgaXMgZW5hYmxlZCkgc2luY2UgdGhlIFVuaWNvZGUgc3RhbmRhcmQgc3BlY2lmaWVzIHRoYXQgSGFuZ3VsIHRvIEphbW8KICAgICAqICAgICAgICAgIGlzIGEgY2Fub25pY2FsIGRlY29tcG9zaXRpb24uICBGb3IgYW55IG9mIHRoZSBzdGFuZGFyZCBVbmljb2RlIE5vcm1hbGl6YXRpb24KICAgICAqICAgICAgICAgIEZvcm1zLCB5b3Ugc2hvdWxkIGxlYXZlIHRoaXMgb3B0aW9uIG9mZi4KICAgICAqIDwvdWw+CiAgICAgKiA8cD4KICAgICAqIEBwYXJhbSAgIG9wdGlvbiAgdGhlIG9wdGlvbiB3aG9zZSB2YWx1ZSBpcyB0byBiZSBzZXQuCiAgICAgKiBAcGFyYW0gICB2YWx1ZSAgIHRoZSBuZXcgc2V0dGluZyBmb3IgdGhlIG9wdGlvbi4gIFVzZSA8dHQ+dHJ1ZTwvdHQ+IHRvCiAgICAgKiAgICAgICAgICAgICAgICAgIHR1cm4gdGhlIG9wdGlvbiBvbiBhbmQgPHR0PmZhbHNlPC90dD4gdG8gdHVybiBpdCBvZmYuCiAgICAgKgogICAgICogQHNlZSAjZ2V0T3B0aW9uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldE9wdGlvbihpbnQgb3B0aW9uLCBib29sZWFuIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbiAhPSBJR05PUkVfSEFOR1VMKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklsbGVnYWwgb3B0aW9uIik7CiAgICAgICAgfQogICAgICAgIGlmICh2YWx1ZSkgewogICAgICAgICAgICBvcHRpb25zIHw9IG9wdGlvbjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25zICY9ICh+b3B0aW9uKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmUgd2hldGhlciBhbiBvcHRpb24gaXMgdHVybmVkIG9uIG9yIG9mZi4KICAgICAqIDxwPgogICAgICogQHNlZSAjc2V0T3B0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldE9wdGlvbihpbnQgb3B0aW9uKSB7CiAgICAgICAgcmV0dXJuIChvcHRpb25zICYgb3B0aW9uKSAhPSAwOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSBpbnB1dCB0ZXh0IG92ZXIgd2hpY2ggdGhpcyA8dHQ+Tm9ybWFsaXplcjwvdHQ+IHdpbGwgaXRlcmF0ZS4KICAgICAqIFRoZSBpdGVyYXRpb24gcG9zaXRpb24gd2lsbCBiZSByZXNldCB0byB0aGUgYmVnaW5uaW5nLgogICAgICogPHA+CiAgICAgKiBAcGFyYW0gbmV3VGV4dCAgIFRoZSBuZXcgc3RyaW5nIHRvIGJlIG5vcm1hbGl6ZWQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldFRleHQoU3RyaW5nIG5ld1RleHQpIHsKICAgICAgICB0ZXh0ID0gbmV3IFN0cmluZ0NoYXJhY3Rlckl0ZXJhdG9yKG5ld1RleHQpOwogICAgICAgIHJlc2V0KCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXQgdGhlIGlucHV0IHRleHQgb3ZlciB3aGljaCB0aGlzIDx0dD5Ob3JtYWxpemVyPC90dD4gd2lsbCBpdGVyYXRlLgogICAgICogVGhlIGl0ZXJhdGlvbiBwb3NpdGlvbiB3aWxsIGJlIHJlc2V0IHRvIHRoZSBiZWdpbm5pbmcuCiAgICAgKiA8cD4KICAgICAqIEBwYXJhbSBuZXdUZXh0ICAgVGhlIG5ldyB0ZXh0IHRvIGJlIG5vcm1hbGl6ZWQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldFRleHQoQ2hhcmFjdGVySXRlcmF0b3IgbmV3VGV4dCkgewogICAgICAgIHRleHQgPSBuZXdUZXh0OwogICAgICAgIHJlc2V0KCk7CiAgICB9CgoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUHJpdmF0ZSB1dGlsaXR5IG1ldGhvZHMKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIHByaXZhdGUgZmluYWwgY2hhciBjdXJGb3J3YXJkKCkgewogICAgICAgIGNoYXIgY2ggPSB0ZXh0LmN1cnJlbnQoKTsKICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiIGN1ckZvcndhcmQgcmV0dXJuaW5nICIgKyBVdGlsaXR5LmhleChjaCkgKyAiLCB0ZXh0IGluZGV4PSIgKyB0ZXh0LmdldEluZGV4KCkpOwogICAgICAgIHJldHVybiBjaDsKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGNoYXIgY3VyQmFja3dhcmQoKSB7CiAgICAgICAgY2hhciBjaCA9IGF0RW5kID8gdGV4dC5jdXJyZW50KCkgOiB0ZXh0LnByZXZpb3VzKCk7CiAgICAgICAgYXRFbmQgPSBmYWxzZTsKICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigiIGN1ckJhY2t3YXJkIHJldHVybmluZyAiICsgVXRpbGl0eS5oZXgoY2gpICsgIiwgdGV4dCBpbmRleD0iICsgdGV4dC5nZXRJbmRleCgpKTsKICAgICAgICByZXR1cm4gY2g7CiAgICB9CgogICAgc3RhdGljIGZpbmFsIGludCBkb0FwcGVuZChTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0LCBTdHJpbmdCdWZmZXIgZGVzdCkgewogICAgICAgIGludCBpbmRleCA9IG9mZnNldCA+Pj4gU1RSX0lOREVYX1NISUZUOwogICAgICAgIGludCBsZW5ndGggPSBvZmZzZXQgJiBTVFJfTEVOR1RIX01BU0s7CgogICAgICAgIGlmIChsZW5ndGggPT0gMCkgewogICAgICAgICAgICBjaGFyIGNoOwogICAgICAgICAgICB3aGlsZSAoKGNoID0gRGVjb21wRGF0YS5jb250ZW50cy5jaGFyQXQoaW5kZXgrKykpICE9IDB4MDAwMCkgewogICAgICAgICAgICAgICAgZGVzdC5hcHBlbmQoY2gpOwogICAgICAgICAgICAgICAgbGVuZ3RoKys7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBkZXN0LmFwcGVuZChEZWNvbXBEYXRhLmNvbnRlbnRzLmNoYXJBdChpbmRleCsrKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxlbmd0aDsKICAgIH0KCgogICAgc3RhdGljIGZpbmFsIGludCBkb0luc2VydChTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0LCBTdHJpbmdCdWZmZXIgZGVzdCwgaW50IHBvcykKICAgIHsKICAgICAgICBpbnQgaW5kZXggPSBvZmZzZXQgPj4+IFNUUl9JTkRFWF9TSElGVDsKICAgICAgICBpbnQgbGVuZ3RoID0gb2Zmc2V0ICYgU1RSX0xFTkdUSF9NQVNLOwoKICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKICAgICAgICAgICAgY2hhciBjaDsKICAgICAgICAgICAgd2hpbGUgKChjaCA9IERlY29tcERhdGEuY29udGVudHMuY2hhckF0KGluZGV4KyspKSAhPSAweDAwMDApIHsKICAgICAgICAgICAgICAgIGRlc3QuaW5zZXJ0KHBvcysrLCBjaCk7CiAgICAgICAgICAgICAgICBsZW5ndGgrKzsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIGRlc3QuaW5zZXJ0KHBvcysrLCBEZWNvbXBEYXRhLmNvbnRlbnRzLmNoYXJBdChpbmRleCsrKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxlbmd0aDsKICAgIH0KCiAgICBzdGF0aWMgZmluYWwgaW50IGRvUmVwbGFjZShTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0LCBTdHJpbmdCdWZmZXIgZGVzdCwgaW50IHBvcykKICAgIHsKICAgICAgICBpbnQgaW5kZXggPSBvZmZzZXQgPj4+IFNUUl9JTkRFWF9TSElGVDsKICAgICAgICBpbnQgbGVuZ3RoID0gb2Zmc2V0ICYgU1RSX0xFTkdUSF9NQVNLOwoKICAgICAgICBkZXN0LnNldENoYXJBdChwb3MrKywgRGVjb21wRGF0YS5jb250ZW50cy5jaGFyQXQoaW5kZXgrKykpOwogICAgICAgIGlmIChsZW5ndGggPT0gMCkgewogICAgICAgICAgICBjaGFyIGNoOwogICAgICAgICAgICB3aGlsZSAoKGNoID0gRGVjb21wRGF0YS5jb250ZW50cy5jaGFyQXQoaW5kZXgrKykpICE9IDB4MDAwMCkgewogICAgICAgICAgICAgICAgZGVzdC5pbnNlcnQocG9zKyssIGNoKTsKICAgICAgICAgICAgICAgIGxlbmd0aCsrOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBsZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgZGVzdC5pbnNlcnQocG9zKyssIERlY29tcERhdGEuY29udGVudHMuY2hhckF0KGluZGV4KyspKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbGVuZ3RoOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCByZXNldCgpIHsKICAgICAgICB0ZXh0LnNldEluZGV4KHRleHQuZ2V0QmVnaW5JbmRleCgpKTsKICAgICAgICBhdEVuZCA9IGZhbHNlOwogICAgICAgIGJ1ZmZlclBvcyA9IDA7CiAgICAgICAgYnVmZmVyTGltaXQgPSAwOwogICAgfQoKICAgIHByaXZhdGUgZmluYWwgdm9pZCBpbml0QnVmZmVyKCkgewogICAgICAgIGlmIChidWZmZXIgPT0gbnVsbCkgewogICAgICAgICAgICBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKDEwKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBidWZmZXIuc2V0TGVuZ3RoKDApOwogICAgICAgIH0KICAgICAgICBjbGVhckJ1ZmZlcigpOwogICAgfQoKICAgIHByaXZhdGUgZmluYWwgdm9pZCBjbGVhckJ1ZmZlcigpIHsKICAgICAgICBidWZmZXJMaW1pdCA9IGJ1ZmZlclBvcyA9IDA7CiAgICB9CgoKICAgIC8qKgogICAgICogRml4ZXMgdGhlIHNvcnRpbmcgc2VxdWVuY2Ugb2Ygbm9uLXNwYWNpbmcgY2hhcmFjdGVycyBhY2NvcmRpbmcgdG8KICAgICAqIHRoZWlyIGNvbWJpbmluZyBjbGFzcy4gIFRoZSBhbGdvcml0aG0gaXMgbGlzdGVkIG9uIHAuMy0xMSBpbiB0aGUKICAgICAqIFVuaWNvZGUgU3RhbmRhcmQgMi4wLiAgVGhlIHRhYmxlIG9mIGNvbWJpbmluZyBjbGFzc2VzIGlzIG9uIHAuNC0yCiAgICAgKiBpbiB0aGUgVW5pY29kZSBTdGFuZGFyZCAyLjAuCiAgICAgKiBAcGFyYW0gcmVzdWx0IHRoZSBzdHJpbmcgdG8gZml4LgogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyB2b2lkIGZpeENhbm9uaWNhbChTdHJpbmdCdWZmZXIgcmVzdWx0KSB7CiAgICAgICAgaW50IGkgPSByZXN1bHQubGVuZ3RoKCkgLSAxOwogICAgICAgIGludCBjdXJyZW50VHlwZSA9IGdldENsYXNzKHJlc3VsdC5jaGFyQXQoaSkpOwogICAgICAgIGludCBsYXN0VHlwZTsKCiAgICAgICAgZm9yICgtLWk7IGkgPj0gMDsgLS1pKSB7CiAgICAgICAgICAgIGxhc3RUeXBlID0gY3VycmVudFR5cGU7CiAgICAgICAgICAgIGN1cnJlbnRUeXBlID0gZ2V0Q2xhc3MocmVzdWx0LmNoYXJBdChpKSk7CgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBhIHN3YXAgaXMgcHJlc3VtZWQgdG8gYmUgcmFyZSAoYW5kIGEgZG91YmxlLXN3YXAgdmVyeSByYXJlKSwKICAgICAgICAgICAgLy8gc28gZG9uJ3Qgd29ycnkgYWJvdXQgZWZmaWNpZW5jeSBoZXJlLgogICAgICAgICAgICAvLwogICAgICAgICAgICBpZiAoY3VycmVudFR5cGUgPiBsYXN0VHlwZSAmJiBsYXN0VHlwZSAhPSBEZWNvbXBEYXRhLkJBU0UpIHsKICAgICAgICAgICAgICAgIC8vIHN3YXAgY2hhcmFjdGVycwogICAgICAgICAgICAgICAgY2hhciB0ZW1wID0gcmVzdWx0LmNoYXJBdChpKTsKICAgICAgICAgICAgICAgIHJlc3VsdC5zZXRDaGFyQXQoaSwgcmVzdWx0LmNoYXJBdChpKzEpKTsKICAgICAgICAgICAgICAgIHJlc3VsdC5zZXRDaGFyQXQoaSsxLCB0ZW1wKTsKICAgICAgICAgICAgICAgIC8vIGlmIG5vdCBhdCBlbmQsIGJhY2t1cCAob25lIGZ1cnRoZXIsIHRvIGNvbXBlbnNhdGUgZm9yIGZvci1sb29wKQogICAgICAgICAgICAgICAgaWYgKGkgPCByZXN1bHQubGVuZ3RoKCkgLSAyKSB7CiAgICAgICAgICAgICAgICAgICAgaSArPSAyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gcmVzZXQgdHlwZSwgc2luY2Ugd2Ugc3dhcHBlZC4KICAgICAgICAgICAgICAgIGN1cnJlbnRUeXBlID0gZ2V0Q2xhc3MocmVzdWx0LmNoYXJBdChpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBIYW5ndWwgLyBKYW1vIGNvbnZlcnNpb24gdXRpbGl0aWVzIGZvciBpbnRlcm5hbCB1c2UKICAgIC8vIFNlZSBzZWN0aW9uIDMuMTAgb2YgVGhlIFVuaWNvZGUgU3RhbmRhcmQsIHYgMi4wLgogICAgLy8KCiAgICAvLyBQYWNrYWdlLWFjY2Vzc2libGUgZm9yIHVzZSBieSBDb21wb3NlZENoYXJJdGVyCiAgICBzdGF0aWMgZmluYWwgY2hhciBIQU5HVUxfQkFTRSAgID0gMHhhYzAwOwogICAgc3RhdGljIGZpbmFsIGNoYXIgSEFOR1VMX0xJTUlUICA9IDB4ZDdhNDsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIEpBTU9fTEJBU0UgICAgPSAweDExMDA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIEpBTU9fVkJBU0UgICAgPSAweDExNjE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIEpBTU9fVEJBU0UgICAgPSAweDExYTc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgIEpBTU9fTENPVU5UICAgPSAxOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCAgSkFNT19WQ09VTlQgICA9IDIxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50ICBKQU1PX1RDT1VOVCAgID0gMjg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgIEpBTU9fTkNPVU5UICAgPSBKQU1PX1ZDT1VOVCAqIEpBTU9fVENPVU5UOwoKICAgIC8qKgogICAgICogQ29udmVydCBhIHNpbmdsZSBIYW5ndWwgc3lsbGFibGUgaW50byBvbmUgb3IgbW9yZSBKYW1vIGNoYXJhY3RlcnMuCiAgICAgKgogICAgICogQHBhcmFtIGNvbmpvaW4gSWYgdHJ1ZSwgZGVjb21wb3NlIEphbW8gaW50byBjb25qb2luaW5nIEphbW8uCiAgICAgKi8KICAgIHN0YXRpYyBpbnQgaGFuZ3VsVG9KYW1vKGNoYXIgY2gsIFN0cmluZ0J1ZmZlciByZXN1bHQsIGludCBkZWNvbXBMaW1pdCkgewogICAgICAgIGNoYXIgc0luZGV4ICA9IChjaGFyKShjaCAtIEhBTkdVTF9CQVNFKTsKICAgICAgICBjaGFyIGxlYWRpbmcgPSAoY2hhcikoSkFNT19MQkFTRSArIHNJbmRleCAvIEpBTU9fTkNPVU5UKTsKICAgICAgICBjaGFyIHZvd2VsICAgPSAoY2hhcikoSkFNT19WQkFTRSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzSW5kZXggJSBKQU1PX05DT1VOVCkgLyBKQU1PX1RDT1VOVCk7CiAgICAgICAgY2hhciB0cmFpbGluZz0gKGNoYXIpKEpBTU9fVEJBU0UgKyAoc0luZGV4ICUgSkFNT19UQ09VTlQpKTsKCiAgICAgICAgaW50IGxlbmd0aCA9IDA7CgogICAgICAgIGxlbmd0aCArPSBqYW1vQXBwZW5kKGxlYWRpbmcsIGRlY29tcExpbWl0LCByZXN1bHQpOwogICAgICAgIGxlbmd0aCArPSBqYW1vQXBwZW5kKHZvd2VsLCBkZWNvbXBMaW1pdCwgcmVzdWx0KTsKICAgICAgICBpZiAodHJhaWxpbmcgIT0gSkFNT19UQkFTRSkgewogICAgICAgICAgICBsZW5ndGggKz0gamFtb0FwcGVuZCh0cmFpbGluZywgZGVjb21wTGltaXQsIHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBsZW5ndGg7CiAgICB9CiAgICBzdGF0aWMgZmluYWwgaW50IGphbW9BcHBlbmQoY2hhciBjaCwgaW50IGxpbWl0LCBTdHJpbmdCdWZmZXIgZGVzdCkgewogICAgICAgIGludCBvZmZzZXQgPSBEZWNvbXBEYXRhLm9mZnNldHMuZWxlbWVudEF0KGNoKTsKICAgICAgICBpZiAob2Zmc2V0ID4gbGltaXQpIHsKICAgICAgICAgICAgcmV0dXJuIGRvQXBwZW5kKERlY29tcERhdGEuY29udGVudHMsIG9mZnNldCwgZGVzdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZGVzdC5hcHBlbmQoY2gpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIHByaXZhdGUgdm9pZCBqYW1vVG9IYW5ndWwoU3RyaW5nQnVmZmVyIGJ1ZmZlciwgaW50IHN0YXJ0KSB7CiAgICAgICAgaW50IG91dCA9IDA7CiAgICAgICAgaW50IGxpbWl0ID0gYnVmZmVyLmxlbmd0aCgpIC0gMTsKCiAgICAgICAgaW50IGluLCBsLCB2LCB0OwoKICAgICAgICBmb3IgKGluID0gc3RhcnQ7IGluIDwgbGltaXQ7IGluKyspIHsKICAgICAgICAgICAgY2hhciBjaCA9IGJ1ZmZlci5jaGFyQXQoaW4pOwoKICAgICAgICAgICAgaWYgKChsID0gY2ggLSBKQU1PX0xCQVNFKSA+PSAwICYmIGwgPCBKQU1PX0xDT1VOVAogICAgICAgICAgICAgICAgICAgICYmICh2ID0gYnVmZmVyLmNoYXJBdChpbisxKSAtIEpBTU9fVkJBU0UpID49IDAgJiYgdiA8IEpBTU9fVkNPVU5UKSB7CiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgLy8gV2UndmUgZm91bmQgYSBwYWlyIG9mIEphbW8gY2hhcmFjdGVycyB0byBjb21wb3NlLgogICAgICAgICAgICAgICAgLy8gU25hcmYgdGhlIEphbW8gdm93ZWwgYW5kIHNlZSBpZiB0aGVyZSdzIGFsc28gYSB0cmFpbGluZyBjaGFyCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgaW4rKzsgICAvLyBTbmFyZiB0aGUgSmFtbyB2b3dlbCB0b28uCgogICAgICAgICAgICAgICAgdCA9IChpbiA8IGxpbWl0KSA/IGJ1ZmZlci5jaGFyQXQoaW4rMSkgOiAwOwogICAgICAgICAgICAgICAgdCAtPSBKQU1PX1RCQVNFOwoKICAgICAgICAgICAgICAgIGlmICh0ID49IDAgJiYgdCA8IEpBTU9fVENPVU5UKSB7CiAgICAgICAgICAgICAgICAgICAgaW4rKzsgICAvLyBTbmFyZiB0aGUgdHJhaWxpbmcgY29uc29uYW50IHRvbwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0ID0gMDsgIC8vIE5vIHRyYWlsaW5nIGNvbnNvbmFudAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnVmZmVyLnNldENoYXJBdChvdXQrKywgKGNoYXIpKChsKkpBTU9fVkNPVU5UICsgdikgKiBKQU1PX1RDT1VOVAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgdCArIEhBTkdVTF9CQVNFKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBidWZmZXIuc2V0Q2hhckF0KG91dCsrLCBjaCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgd2hpbGUgKGluIDwgYnVmZmVyLmxlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRDaGFyQXQob3V0KyssIGJ1ZmZlci5jaGFyQXQoaW4rKykpOwogICAgICAgIH0KCiAgICAgICAgYnVmZmVyLnNldExlbmd0aChvdXQpOwogICAgfQoKCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFByaXZhdGUgZGF0YQogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBERUJVRyA9IGZhbHNlOwoKICAgIHByaXZhdGUgTW9kZSAgICAgICAgICAgICAgICBtb2RlID0gREVDT01QOwogICAgcHJpdmF0ZSBpbnQgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSAwOwogICAgcHJpdmF0ZSB0cmFuc2llbnQgaW50ICAgICAgIG1pbkRlY29tcDsKCiAgICAvLyBUaGUgaW5wdXQgdGV4dCBhbmQgb3VyIHBvc2l0aW9uIGluIGl0CiAgICBwcml2YXRlIENoYXJhY3Rlckl0ZXJhdG9yICAgdGV4dDsKICAgIHByaXZhdGUgYm9vbGVhbiAgICAgICAgICAgICBhdEVuZCA9IGZhbHNlOwoKICAgIC8vIEEgYnVmZmVyIGZvciBob2xkaW5nIGludGVybWVkaWF0ZSByZXN1bHRzCiAgICBwcml2YXRlIFN0cmluZ0J1ZmZlciAgICAgICAgYnVmZmVyID0gbnVsbDsKICAgIHByaXZhdGUgaW50ICAgICAgICAgICAgICAgICBidWZmZXJQb3MgPSAwOwogICAgcHJpdmF0ZSBpbnQgICAgICAgICAgICAgICAgIGJ1ZmZlckxpbWl0ID0gMDsKICAgIHByaXZhdGUgY2hhciAgICAgICAgICAgICAgICBjdXJyZW50Q2hhcjsKCiAgICAvLyBBbm90aGVyIGJ1ZmZlciBmb3IgdXNlIGR1cmluZyBpdGVyYXRpdmUgY29tcG9zaXRpb24KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCAgICBFTVBUWSA9IC0xOwogICAgcHJpdmF0ZSBTdHJpbmdCdWZmZXIgICAgICAgIGV4cGxvZGVCdWYgPSBudWxsOwoKICAgIC8vIFRoZXNlIG11c3QgYWdyZWUgd2l0aCB0aGUgY29uc3RhbnRzIHVzZWQgaW4gTm9ybWFsaXplckJ1aWxkZXIKICAgIHN0YXRpYyBmaW5hbCBpbnQgU1RSX0lOREVYX1NISUZUID0gMjsKICAgIHN0YXRpYyBmaW5hbCBpbnQgU1RSX0xFTkdUSF9NQVNLID0gMHgwMDAzOwp9Owo=