LyoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwMiwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAgKgoqIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKgoqICRTb3VyY2U6IC94c3JsL05zdm4vaWN1L2ljdTRqL3NyYy9jb20vaWJtL2ljdS90ZXh0L1VURjE2LmphdmEsdiAkIAoqICREYXRlOiAyMDAyLzEyLzExIDAyOjA5OjA1ICQgCiogJFJldmlzaW9uOiAxLjI4ICQKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCgpwYWNrYWdlIGNvbS5pYm0uaWN1LnRleHQ7CgppbXBvcnQgY29tLmlibS5pY3UuaW1wbC5VQ2hhcmFjdGVyUHJvcGVydHk7CmltcG9ydCBjb20uaWJtLmljdS5pbXBsLk5vcm1hbGl6ZXJJbXBsOwovKioKICogPHA+U3RhbmRhbG9uZSB1dGlsaXR5IGNsYXNzIHByb3ZpZGluZyBVVEYxNiBjaGFyYWN0ZXIgY29udmVyc2lvbnMgYW5kIAogKiBpbmRleGluZyBjb252ZXJzaW9ucy48L3A+CiAqIDxwPkNvZGUgdGhhdCB1c2VzIHN0cmluZ3MgYWxvbmUgcmFyZWx5IG5lZWQgbW9kaWZpY2F0aW9uLiAKICogQnkgZGVzaWduLCBVVEYtMTYgZG9lcyBub3QgYWxsb3cgb3ZlcmxhcCwgc28gc2VhcmNoaW5nIGZvciBzdHJpbmdzIGlzIGEgc2FmZSAKICogb3BlcmF0aW9uLiBTaW1pbGFybHksIGNvbmNhdGVuYXRpb24gaXMgYWx3YXlzIHNhZmUuIFN1YnN0cmluZ2luZyBpcyBzYWZlIGlmIAogKiB0aGUgc3RhcnQgYW5kIGVuZCBhcmUgYm90aCBvbiBVVEYtMzIgYm91bmRhcmllcy4gSW4gbm9ybWFsIGNvZGUsIHRoZSB2YWx1ZXMgCiAqIGZvciBzdGFydCBhbmQgZW5kIGFyZSBvbiB0aG9zZSBib3VuZGFyaWVzLCBzaW5jZSB0aGV5IGFyb3NlIGZyb20gb3BlcmF0aW9ucyAKICogbGlrZSBzZWFyY2hpbmcuIElmIG5vdCwgdGhlIG5lYXJlc3QgVVRGLTMyIGJvdW5kYXJpZXMgY2FuIGJlIGRldGVybWluZWQgCiAqIHVzaW5nIDxjb2RlPmJvdW5kcygpPC9jb2RlPi48L3A+CiAqIDxzdHJvbmc+RXhhbXBsZXM6PC9zdHJvbmc+CiAqIDxwPlRoZSBmb2xsb3dpbmcgZXhhbXBsZXMgaWxsdXN0cmF0ZSB1c2Ugb2Ygc29tZSBvZiB0aGVzZSBtZXRob2RzLiAKICogPHByZT4KICogLy8gaXRlcmF0aW9uIGZvcndhcmRzOiBPcmlnaW5hbAogKiBmb3IgKGludCBpID0gMDsgaSAmbHQ7IHMubGVuZ3RoKCk7ICsraSkgewogKqCgoGNoYXIgY2ggPSBzLmNoYXJBdChpKTsKICqgoKBkb1NvbWV0aGluZ1dpdGgoY2gpOwogKiB9CiAqCiAqIC8vIGl0ZXJhdGlvbiBmb3J3YXJkczogQ2hhbmdlcyBmb3IgVVRGLTMyCiAqIGludCBjaDsKICogZm9yIChpbnQgaSA9IDA7IGkgJmx0OyBzLmxlbmd0aCgpOyBpKz1VVEYxNi5nZXRDaGFyQ291bnQoY2gpKSB7CiAqoKCgY2ggPSBVVEYxNi5jaGFyQXQocyxpKTsKICqgoKBkb1NvbWV0aGluZ1dpdGgoY2gpOwogKiB9CiAqCiAqIC8vIGl0ZXJhdGlvbiBiYWNrd2FyZHM6IE9yaWdpbmFsCiAqIGZvciAoaW50IGkgPSBzLmxlbmd0aCgpIC0xOyBpID49IDA7IC0taSkgewogKqCgoGNoYXIgY2ggPSBzLmNoYXJBdChpKTsKICogoKCgZG9Tb21ldGhpbmdXaXRoKGNoKTsKICogfQogKiAgCiAqIC8vIGl0ZXJhdGlvbiBiYWNrd2FyZHM6IENoYW5nZXMgZm9yIFVURi0zMgogKiBpbnQgY2g7CiAqIGZvciAoaW50IGkgPSBzLmxlbmd0aCgpIC0xOyBpID4gMDsgaS09VVRGMTYuZ2V0Q2hhckNvdW50KGNoKSkgewogKqCgoGNoID0gVVRGMTYuY2hhckF0KHMsaSk7CiAqoKCgZG9Tb21ldGhpbmdXaXRoKGNoKTsKICogfQogKiA8L3ByZT4KICogPHN0cm9uZz5Ob3Rlczo8L3N0cm9uZz4KICogPHVsPgogKiAgIDxsaT4KICogICA8c3Ryb25nPk5hbWluZzo8L3N0cm9uZz4gRm9yIGNsYXJpdHksIEhpZ2ggYW5kIExvdyBzdXJyb2dhdGVzIGFyZSBjYWxsZWQgCiAqICAgPGNvZGU+TGVhZDwvY29kZT4gYW5kIDxjb2RlPlRyYWlsPC9jb2RlPiBpbiB0aGUgQVBJLCB3aGljaCBnaXZlcyBhIGJldHRlciAKICogICBzZW5zZSBvZiB0aGVpciBvcmRlcmluZyBpbiBhIHN0cmluZy4gPGNvZGU+b2Zmc2V0MTY8L2NvZGU+IGFuZCAKICogICA8Y29kZT5vZmZzZXQzMjwvY29kZT4gYXJlIHVzZWQgdG8gZGlzdGluZ3Vpc2ggb2Zmc2V0cyB0byBVVEYtMTYgCiAqICAgYm91bmRhcmllcyB2cyBvZmZzZXRzIHRvIFVURi0zMiBib3VuZGFyaWVzLiA8Y29kZT5pbnQgY2hhcjMyPC9jb2RlPiBpcyAKICogICB1c2VkIHRvIGNvbnRhaW4gVVRGLTMyIGNoYXJhY3RlcnMsIGFzIG9wcG9zZWQgdG8gPGNvZGU+Y2hhcjE2PC9jb2RlPiwgCiAqICAgd2hpY2ggaXMgYSBVVEYtMTYgY29kZSB1bml0LgogKiAgIDwvbGk+CiAqICAgPGxpPgogKiAgIDxzdHJvbmc+Um91bmR0cmlwcGluZyBPZmZzZXRzOjwvc3Ryb25nPiBZb3UgY2FuIGFsd2F5cyByb3VuZHRyaXAgZnJvbSBhIAogKiAgIFVURi0zMiBvZmZzZXQgdG8gYSBVVEYtMTYgb2Zmc2V0IGFuZCBiYWNrLiBCZWNhdXNlIG9mIHRoZSBkaWZmZXJlbmNlIGluIAogKiAgIHN0cnVjdHVyZSwgeW91IGNhbiByb3VuZHRyaXAgZnJvbSBhIFVURi0xNiBvZmZzZXQgdG8gYSBVVEYtMzIgb2Zmc2V0IGFuZCAKICogICBiYWNrIGlmIGFuZCBvbmx5IGlmIDxjb2RlPmJvdW5kcyhzdHJpbmcsIG9mZnNldDE2KSAhPSBUUkFJTDwvY29kZT4uCiAqICAgPC9saT4KICogICA8bGk+CiAqICAgIDxzdHJvbmc+RXhjZXB0aW9uczo8L3N0cm9uZz4gVGhlIGVycm9yIGNoZWNraW5nIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIAogKiAgIGlmIGluZGljZXMgYXJlIG91dCBvZiBib3VuZHMuIE90aGVyIHRoYW4gdGhhbiB0aGF0LCBhbGwgbWV0aG9kcyB3aWxsIAogKiAgIGJlaGF2ZSByZWFzb25hYmx5LCBldmVuIGlmIHVubWF0Y2hlZCBzdXJyb2dhdGVzIG9yIG91dC1vZi1ib3VuZHMgVVRGLTMyIAogKiAgIHZhbHVlcyBhcmUgcHJlc2VudC4gPGNvZGU+VUNoYXJhY3Rlci5pc0xlZ2FsKCk8L2NvZGU+IGNhbiBiZSB1c2VkIHRvIGNoZWNrIAogKiAgIGZvciB2YWxpZGl0eSBpZiBkZXNpcmVkLgogKiAgIDwvbGk+CiAqICAgPGxpPgogKiAgIDxzdHJvbmc+VW5tYXRjaGVkIFN1cnJvZ2F0ZXM6PC9zdHJvbmc+IElmIHRoZSBzdHJpbmcgY29udGFpbnMgdW5tYXRjaGVkIAogKiAgIHN1cnJvZ2F0ZXMsIHRoZW4gdGhlc2UgYXJlIGNvdW50ZWQgYXMgb25lIFVURi0zMiB2YWx1ZS4gVGhpcyBtYXRjaGVzIAogKiAgIHRoZWlyIGl0ZXJhdGlvbiBiZWhhdmlvciwgd2hpY2ggaXMgdml0YWwuIEl0IGFsc28gbWF0Y2hlcyBjb21tb24gZGlzcGxheSAKICogICBwcmFjdGljZSBhcyBtaXNzaW5nIGdseXBocyAoc2VlIHRoZSBVbmljb2RlIFN0YW5kYXJkIFNlY3Rpb24gNS40LCA1LjUpLgogKiAgIDwvbGk+CiAqICAgPGxpPgogKiAgICAgPHN0cm9uZz5PcHRpbWl6YXRpb246PC9zdHJvbmc+IFRoZSBtZXRob2QgaW1wbGVtZW50YXRpb25zIG1heSBuZWVkIAogKiAgICAgb3B0aW1pemF0aW9uIGlmIHRoZSBjb21waWxlciBkb2Vzbid0IGZvbGQgc3RhdGljIGZpbmFsIG1ldGhvZHMuIFNpbmNlIAogKiAgICAgc3Vycm9nYXRlIHBhaXJzIHdpbGwgZm9ybSBhbiBleGNlZWRpbmcgc21hbGwgcGVyY2VudGFnZSBvZiBhbGwgdGhlIHRleHQgCiAqICAgICBpbiB0aGUgd29ybGQsIHRoZSBzaW5nbGV0b24gY2FzZSBzaG91bGQgYWx3YXlzIGJlIG9wdGltaXplZCBmb3IuCiAqICAgPC9saT4KICogPC91bD4KICogQGF1dGhvciBNYXJrIERhdmlzLCB3aXRoIGhlbHAgZnJvbSBNYXJrdXMgU2NoZXJlcgogKiBAc3RhYmxlIElDVSAyLjEKICovCgpwdWJsaWMgZmluYWwgY2xhc3MgVVRGMTYKewogICAgLy8gcHVibGljIHZhcmlhYmxlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgCiAgICAvKioKICAgICAqIFZhbHVlIHJldHVybmVkIGluIDxjb2RlPjxhIGhyZWY9IiNib3VuZHMoamF2YS5sYW5nLlN0cmluZywgaW50KSI+CiAgICAgKiBib3VuZHMoKTwvYT48L2NvZGU+LgogICAgICogVGhlc2UgdmFsdWVzIGFyZSBjaG9zZW4gc3BlY2lmaWNhbGx5IHNvIHRoYXQgaXQgYWN0dWFsbHkgcmVwcmVzZW50cyAgCiAgICAgKiB0aGUgcG9zaXRpb24gb2YgdGhlIGNoYXJhY3RlciAKICAgICAqIFtvZmZzZXQxNiAtICh2YWx1ZSA+PiAyKSwgb2Zmc2V0MTYgKyAodmFsdWUgJiAzKV0KICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSU5HTEVfQ0hBUl9CT1VOREFSWSA9IDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTEVBRF9TVVJST0dBVEVfQk9VTkRBUlkgPSAyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWSA9IDU7CiAgICAvKiogCiAgICAgKiBUaGUgbG93ZXN0IFVuaWNvZGUgY29kZSBwb2ludCB2YWx1ZS4KICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT0RFUE9JTlRfTUlOX1ZBTFVFID0gMDsKICAgIC8qKgogICAgICogVGhlIGhpZ2hlc3QgVW5pY29kZSBjb2RlIHBvaW50IHZhbHVlIChzY2FsYXIgdmFsdWUpIGFjY29yZGluZyB0byB0aGUgCiAgICAgKiBVbmljb2RlIFN0YW5kYXJkLgogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPREVQT0lOVF9NQVhfVkFMVUUgPSAweDEwZmZmZjsgCiAgICAvKioKICAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIGZvciBTdXBwbGVtZW50YXJ5IGNvZGUgcG9pbnRzCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUgID0gMHgxMDAwMDsgIAogICAgLyoqCiAgICAgKiBMZWFkIHN1cnJvZ2F0ZSBtaW5pbXVtIHZhbHVlCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFID0gMHhEODAwOwoJLyoqCiAgICAgKiBUcmFpbCBzdXJyb2dhdGUgbWluaW11bSB2YWx1ZQogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRSQUlMX1NVUlJPR0FURV9NSU5fVkFMVUUgPSAweERDMDA7IAogICAgLyoqCiAgICAgKiBMZWFkIHN1cnJvZ2F0ZSBtYXhpbXVtIHZhbHVlCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEVBRF9TVVJST0dBVEVfTUFYX1ZBTFVFID0gMHhEQkZGOwoJLyoqCiAgICAgKiBUcmFpbCBzdXJyb2dhdGUgbWF4aW11bSB2YWx1ZQogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUUgPSAweERGRkY7CiAgICAvKioKICAgICAqIFN1cnJvZ2F0ZSBtaW5pbXVtIHZhbHVlCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VSUk9HQVRFX01JTl9WQUxVRSA9IExFQURfU1VSUk9HQVRFX01JTl9WQUxVRTsKICAgIC8qKgogICAgICogTWF4aW11bSBzdXJyb2dhdGUgdmFsdWUKICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVVJST0dBVEVfTUFYX1ZBTFVFID0gVFJBSUxfU1VSUk9HQVRFX01BWF9WQUxVRTsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgLy8gY29uc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvLy9DTE9WRVI6T0ZGCiAgICAvKioKICAgICAqIFByZXZlbnQgaW5zdGFuY2UgZnJvbSBiZWluZyBjcmVhdGVkLgogICAgICovCiAgICBwcml2YXRlIFVURjE2KCkgCiAgICB7CiAgICB9CiAgICAvLy9DTE9WRVI6T04KICAgIC8vIHB1YmxpYyBtZXRob2QgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgIAogICAgLyoqCiAgICAgKiBFeHRyYWN0IGEgc2luZ2xlIFVURi0zMiB2YWx1ZSBmcm9tIGEgc3RyaW5nLgogICAgICogVXNlZCB3aGVuIGl0ZXJhdGluZyBmb3J3YXJkcyBvciBiYWNrd2FyZHMgKHdpdGggCiAgICAgKiA8Y29kZT5VVEYxNi5nZXRDaGFyQ291bnQoKTwvY29kZT4sIGFzIHdlbGwgYXMgcmFuZG9tIGFjY2Vzcy4gSWYgYSAKICAgICAqIHZhbGlkaXR5IGNoZWNrIGlzIHJlcXVpcmVkLCB1c2UgCiAgICAgKiA8Y29kZT48YSBocmVmPSIuLi9VQ2hhcmFjdGVyLmh0bWwjaXNMZWdhbChjaGFyKSI+CiAgICAgKiBVQ2hhcmFjdGVyLmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIHRoZSByZXR1cm4gdmFsdWUuCiAgICAgKiBJZiB0aGUgY2hhciByZXRyaWV2ZWQgaXMgcGFydCBvZiBhIHN1cnJvZ2F0ZSBwYWlyLCBpdHMgc3VwcGxlbWVudGFyeSAKICAgICAqIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkLiBJZiBhIGNvbXBsZXRlIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIGlzIAogICAgICogbm90IGZvdW5kIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkCiAgICAgKiBAcGFyYW0gc291cmNlIGFycmF5IG9mIFVURi0xNiBjaGFycwogICAgICogQHBhcmFtIG9mZnNldDE2IFVURi0xNiBvZmZzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBjaGFyYWN0ZXIuCiAgICAgKiBAcmV0dXJuIFVURi0zMiB2YWx1ZSBmb3IgdGhlIFVURi0zMiB2YWx1ZSB0aGF0IGNvbnRhaW5zIHRoZSBjaGFyIGF0IAogICAgICogICAgICAgICBvZmZzZXQxNi4gVGhlIGJvdW5kYXJpZXMgb2YgdGhhdCBjb2RlcG9pbnQgYXJlIHRoZSBzYW1lIGFzIGluIAogICAgICogICAgICAgICA8Y29kZT5ib3VuZHMzMigpPC9jb2RlPi4gCiAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gdGhyb3duIGlmIG9mZnNldDE2IGlzIG91dCBvZiAKICAgICAqICAgICAgICAgICAgYm91bmRzLgogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNoYXJBdChTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0MTYpIAogICAgeyAgICAgICAgICAgICAKICAgICAgICBpZiAob2Zmc2V0MTYgPCAwIHx8IG9mZnNldDE2ID49IHNvdXJjZS5sZW5ndGgoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQxNik7CiAgICAgICAgfQogICAgICAgICAgCiAgICAgICAgY2hhciBzaW5nbGUgPSBzb3VyY2UuY2hhckF0KG9mZnNldDE2KTsKICAgICAgICBpZiAoc2luZ2xlIDwgTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFIHx8IAogICAgICAgICAgICBzaW5nbGUgPiBUUkFJTF9TVVJST0dBVEVfTUFYX1ZBTFVFKSB7CiAgICAgICAgICAgIHJldHVybiBzaW5nbGU7CiAgICAgICAgfQoKICAgICAgICAvLyBDb252ZXJ0IHRoZSBVVEYtMTYgc3Vycm9nYXRlIHBhaXIgaWYgbmVjZXNzYXJ5LgogICAgICAgIC8vIEZvciBzaW1wbGljaXR5IGluIHVzYWdlLCBhbmQgYmVjYXVzZSB0aGUgZnJlcXVlbmN5IG9mIHBhaXJzIGlzIAogICAgICAgIC8vIGxvdywgbG9vayBib3RoIGRpcmVjdGlvbnMuCiAgICAgICAgICAgICAgICAKCSAgICBpZiAoc2luZ2xlIDw9IExFQURfU1VSUk9HQVRFX01BWF9WQUxVRSkgewoJICAgICAgICArKyBvZmZzZXQxNjsKCSAgICAgICAgaWYgKHNvdXJjZS5sZW5ndGgoKSAhPSBvZmZzZXQxNikgewogICAgCSAgICAgICAgY2hhciB0cmFpbCA9IHNvdXJjZS5jaGFyQXQob2Zmc2V0MTYpOwoJICAgICAgICAgICAgaWYgKHRyYWlsID49IFRSQUlMX1NVUlJPR0FURV9NSU5fVkFMVUUgJiYKCSAgICAgICAgICAgICAgICB0cmFpbCA8PSBUUkFJTF9TVVJST0dBVEVfTUFYX1ZBTFVFKSB7CgkgICAgICAgICAgICAgICAgcmV0dXJuIFVDaGFyYWN0ZXJQcm9wZXJ0eS5nZXRSYXdTdXBwbGVtZW50YXJ5KHNpbmdsZSwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWlsKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgIH0gCgkgICAgZWxzZSAKCSAgICB7IAoJICAgICAgICAtLSBvZmZzZXQxNjsKCSAgICAgICAgaWYgKG9mZnNldDE2ID49IDApIHsKCSAgICAgICAgCS8vIHNpbmdsZSBpcyBhIHRyYWlsIHN1cnJvZ2F0ZSBzbwoJICAgICAgICAJY2hhciBsZWFkID0gc291cmNlLmNoYXJBdChvZmZzZXQxNik7CgkgICAgICAgIAlpZiAobGVhZCA+PSBMRUFEX1NVUlJPR0FURV9NSU5fVkFMVUUgJiYKCSAgICAgICAgCSAgICBsZWFkIDw9IExFQURfU1VSUk9HQVRFX01BWF9WQUxVRSkgewoJICAgICAgICAgCSAgIHJldHVybiBVQ2hhcmFjdGVyUHJvcGVydHkuZ2V0UmF3U3VwcGxlbWVudGFyeShsZWFkLCAKCSAgICAgICAgIAkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlKTsKCSAgICAgICAgCX0KCSAgICAgICAgfQoJICAgIH0gCgkgICAgcmV0dXJuIHNpbmdsZTsgLy8gcmV0dXJuIHVubWF0Y2hlZCBzdXJyb2dhdGUKICAgIH0KICAgICAgCiAgICAvKioKICAgICAqIEV4dHJhY3QgYSBzaW5nbGUgVVRGLTMyIHZhbHVlIGZyb20gYSBzdHJpbmcuCiAgICAgKiBVc2VkIHdoZW4gaXRlcmF0aW5nIGZvcndhcmRzIG9yIGJhY2t3YXJkcyAod2l0aAogICAgICogPGNvZGU+VVRGMTYuZ2V0Q2hhckNvdW50KCk8L2NvZGU+LCBhcyB3ZWxsIGFzIHJhbmRvbSBhY2Nlc3MuIElmIGEgCiAgICAgKiB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgICogPGNvZGU+PGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPlVDaGFyYWN0ZXIuaXNMZWdhbCgpCiAgICAgKiA8L2E+PC9jb2RlPiBvbiB0aGUgcmV0dXJuIHZhbHVlLgogICAgICogSWYgdGhlIGNoYXIgcmV0cmlldmVkIGlzIHBhcnQgb2YgYSBzdXJyb2dhdGUgcGFpciwgaXRzIHN1cHBsZW1lbnRhcnkKICAgICAqIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkLiBJZiBhIGNvbXBsZXRlIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIGlzIAogICAgICogbm90IGZvdW5kIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkCiAgICAgKiBAcGFyYW0gc291cmNlIFVURi0xNiBjaGFycyBzdHJpbmcgYnVmZmVyCiAgICAgKiBAcGFyYW0gb2Zmc2V0MTYgVVRGLTE2IG9mZnNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGNoYXJhY3Rlci4KICAgICAqIEByZXR1cm4gVVRGLTMyIHZhbHVlIGZvciB0aGUgVVRGLTMyIHZhbHVlIHRoYXQgY29udGFpbnMgdGhlIGNoYXIgYXQKICAgICAqICAgICAgICAgb2Zmc2V0MTYuIFRoZSBib3VuZGFyaWVzIG9mIHRoYXQgY29kZXBvaW50IGFyZSB0aGUgc2FtZSBhcyBpbgogICAgICogICAgICAgICA8Y29kZT5ib3VuZHMzMigpPC9jb2RlPi4KICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB0aHJvd24gaWYgb2Zmc2V0MTYgaXMgb3V0IG9mIAogICAgICogICAgICAgICAgICBib3VuZHMuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgY2hhckF0KFN0cmluZ0J1ZmZlciBzb3VyY2UsIGludCBvZmZzZXQxNikKICAgIHsKICAgICAgICBpZiAob2Zmc2V0MTYgPCAwIHx8IG9mZnNldDE2ID49IHNvdXJjZS5sZW5ndGgoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQxNik7CiAgICAgICAgfQogICAgICAgICAgCiAgICAgICAgY2hhciBzaW5nbGUgPSBzb3VyY2UuY2hhckF0KG9mZnNldDE2KTsKICAgICAgICBpZiAoIWlzU3Vycm9nYXRlKHNpbmdsZSkpIHsKICAgICAgICAgICAgcmV0dXJuIHNpbmdsZTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnZlcnQgdGhlIFVURi0xNiBzdXJyb2dhdGUgcGFpciBpZiBuZWNlc3NhcnkuCiAgICAgICAgLy8gRm9yIHNpbXBsaWNpdHkgaW4gdXNhZ2UsIGFuZCBiZWNhdXNlIHRoZSBmcmVxdWVuY3kgb2YgcGFpcnMgaXMgCiAgICAgICAgLy8gbG93LCBsb29rIGJvdGggZGlyZWN0aW9ucy4KICAgICAgICAgICAgICAgIAoJICAgIGlmIChzaW5nbGUgPD0gTEVBRF9TVVJST0dBVEVfTUFYX1ZBTFVFKSAKCSAgICB7CgkgICAgICAgICsrIG9mZnNldDE2OwoJICAgICAgICBpZiAoc291cmNlLmxlbmd0aCgpICE9IG9mZnNldDE2KQoJICAgICAgICB7CgkgICAgICAgIGNoYXIgdHJhaWwgPSBzb3VyY2UuY2hhckF0KG9mZnNldDE2KTsKCSAgICAgICAgaWYgKGlzVHJhaWxTdXJyb2dhdGUodHJhaWwpKQoJICAgICAgICAgICAgcmV0dXJuIFVDaGFyYWN0ZXJQcm9wZXJ0eS5nZXRSYXdTdXBwbGVtZW50YXJ5KHNpbmdsZSwgdHJhaWwpOwoJICAgICAgICB9CgkgICAgfSAKCSAgICBlbHNlIAoJICAgIHsgCgkgICAgICAgIC0tIG9mZnNldDE2OwoJICAgICAgICBpZiAob2Zmc2V0MTYgPj0gMCkKCSAgICAgICAgewoJICAgICAgICAvLyBzaW5nbGUgaXMgYSB0cmFpbCBzdXJyb2dhdGUgc28KCSAgICAgICAgY2hhciBsZWFkID0gc291cmNlLmNoYXJBdChvZmZzZXQxNik7CgkgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUobGVhZCkpIHsKCSAgICAgICAgICAgIHJldHVybiBVQ2hhcmFjdGVyUHJvcGVydHkuZ2V0UmF3U3VwcGxlbWVudGFyeShsZWFkLCBzaW5nbGUpOwoJICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9IAoJICAgIHJldHVybiBzaW5nbGU7IC8vIHJldHVybiB1bm1hdGNoZWQgc3Vycm9nYXRlCiAgICB9CiAgICAgIAogICAgLyoqCiAgICAgKiBFeHRyYWN0IGEgc2luZ2xlIFVURi0zMiB2YWx1ZSBmcm9tIGEgc3Vic3RyaW5nLgogICAgICogVXNlZCB3aGVuIGl0ZXJhdGluZyBmb3J3YXJkcyBvciBiYWNrd2FyZHMgKHdpdGgKICAgICAqIDxjb2RlPlVURjE2LmdldENoYXJDb3VudCgpPC9jb2RlPiwgYXMgd2VsbCBhcyByYW5kb20gYWNjZXNzLiBJZiBhCiAgICAgKiB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgICogPGNvZGU+PGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPlVDaGFyYWN0ZXIuaXNMZWdhbCgpCiAgICAgKiA8L2E+PC9jb2RlPiBvbiB0aGUgcmV0dXJuIHZhbHVlLgogICAgICogSWYgdGhlIGNoYXIgcmV0cmlldmVkIGlzIHBhcnQgb2YgYSBzdXJyb2dhdGUgcGFpciwgaXRzIHN1cHBsZW1lbnRhcnkKICAgICAqIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkLiBJZiBhIGNvbXBsZXRlIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIGlzIAogICAgICogbm90IGZvdW5kIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkCiAgICAgKiBAcGFyYW0gc291cmNlIGFycmF5IG9mIFVURi0xNiBjaGFycwogICAgICogQHBhcmFtIHN0YXJ0IG9mZnNldCB0byBzdWJzdHJpbmcgaW4gdGhlIHNvdXJjZSBhcnJheSBmb3IgYW5hbHl6aW5nCiAgICAgKiBAcGFyYW0gbGltaXQgb2Zmc2V0IHRvIHN1YnN0cmluZyBpbiB0aGUgc291cmNlIGFycmF5IGZvciBhbmFseXppbmcKICAgICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYtMTYgb2Zmc2V0IHJlbGF0aXZlIHRvIHN0YXJ0CiAgICAgKiBAcmV0dXJuIFVURi0zMiB2YWx1ZSBmb3IgdGhlIFVURi0zMiB2YWx1ZSB0aGF0IGNvbnRhaW5zIHRoZSBjaGFyIGF0CiAgICAgKiAgICAgICAgIG9mZnNldDE2LiBUaGUgYm91bmRhcmllcyBvZiB0aGF0IGNvZGVwb2ludCBhcmUgdGhlIHNhbWUgYXMgaW4KICAgICAqICAgICAgICAgPGNvZGU+Ym91bmRzMzIoKTwvY29kZT4uCiAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gdGhyb3duIGlmIG9mZnNldDE2IGlzIG5vdCB3aXRoaW4gCiAgICAgKiAgICAgICAgICAgIHRoZSByYW5nZSBvZiBzdGFydCBhbmQgbGltaXQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgY2hhckF0KGNoYXIgc291cmNlW10sIGludCBzdGFydCwgaW50IGxpbWl0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0MTYpCiAgICB7CiAgICAgICAgb2Zmc2V0MTYgKz0gc3RhcnQ7CiAgICAgICAgaWYgKG9mZnNldDE2IDwgc3RhcnQgfHwgb2Zmc2V0MTYgPj0gbGltaXQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQxNik7CiAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICBjaGFyIHNpbmdsZSA9IHNvdXJjZVtvZmZzZXQxNl07CiAgICAgICAgaWYgKCFpc1N1cnJvZ2F0ZShzaW5nbGUpKSB7CiAgICAgICAgICAgIHJldHVybiBzaW5nbGU7CiAgICAgICAgfQoKICAgICAgICAvLyBDb252ZXJ0IHRoZSBVVEYtMTYgc3Vycm9nYXRlIHBhaXIgaWYgbmVjZXNzYXJ5LgogICAgICAgIC8vIEZvciBzaW1wbGljaXR5IGluIHVzYWdlLCBhbmQgYmVjYXVzZSB0aGUgZnJlcXVlbmN5IG9mIHBhaXJzIGlzIAogICAgICAgIC8vIGxvdywgbG9vayBib3RoIGRpcmVjdGlvbnMuICAgICAgCgkgICAgaWYgKHNpbmdsZSA8PSBMRUFEX1NVUlJPR0FURV9NQVhfVkFMVUUpIHsKCSAgICAgICAgb2Zmc2V0MTYgKys7CgkgICAgICAgIGlmIChvZmZzZXQxNiA+PSBsaW1pdCkgewoJICAgICAgICAgICAgcmV0dXJuIHNpbmdsZTsKCSAgICAgICAgfQoJICAgICAgICBjaGFyIHRyYWlsID0gc291cmNlW29mZnNldDE2XTsKCSAgICAgICAgaWYgKGlzVHJhaWxTdXJyb2dhdGUodHJhaWwpKSB7CgkgICAgICAgICAgICByZXR1cm4gVUNoYXJhY3RlclByb3BlcnR5LmdldFJhd1N1cHBsZW1lbnRhcnkoc2luZ2xlLCB0cmFpbCk7CgkgICAgICAgIH0KICAgICAgICB9IAogICAgICAgIGVsc2UgeyAvLyBpc1RyYWlsU3Vycm9nYXRlKHNpbmdsZSksIHNvCiAgICAgICAgICAgIGlmIChvZmZzZXQxNiA9PSBzdGFydCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHNpbmdsZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvZmZzZXQxNiAtLTsKCSAgICAgICAgY2hhciBsZWFkID0gc291cmNlW29mZnNldDE2XTsKCSAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShsZWFkKSkKCSAgICAgICAgICAgIHJldHVybiBVQ2hhcmFjdGVyUHJvcGVydHkuZ2V0UmF3U3VwcGxlbWVudGFyeShsZWFkLCBzaW5nbGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2luZ2xlOyAvLyByZXR1cm4gdW5tYXRjaGVkIHN1cnJvZ2F0ZQogICAgfQogICAgICAKICAgIC8qKgogICAgICogRXh0cmFjdCBhIHNpbmdsZSBVVEYtMzIgdmFsdWUgZnJvbSBhIHN0cmluZy4KICAgICAqIFVzZWQgd2hlbiBpdGVyYXRpbmcgZm9yd2FyZHMgb3IgYmFja3dhcmRzICh3aXRoCiAgICAgKiA8Y29kZT5VVEYxNi5nZXRDaGFyQ291bnQoKTwvY29kZT4sIGFzIHdlbGwgYXMgcmFuZG9tIGFjY2Vzcy4gSWYgYSAKICAgICAqIHZhbGlkaXR5IGNoZWNrIGlzIHJlcXVpcmVkLCB1c2UgCiAgICAgKiA8Y29kZT48YSBocmVmPSIuLi9VQ2hhcmFjdGVyLmh0bWwjaXNMZWdhbChjaGFyKSI+VUNoYXJhY3Rlci5pc0xlZ2FsKCkKICAgICAqIDwvYT48L2NvZGU+IG9uIHRoZSByZXR1cm4gdmFsdWUuCiAgICAgKiBJZiB0aGUgY2hhciByZXRyaWV2ZWQgaXMgcGFydCBvZiBhIHN1cnJvZ2F0ZSBwYWlyLCBpdHMgc3VwcGxlbWVudGFyeQogICAgICogY2hhcmFjdGVyIHdpbGwgYmUgcmV0dXJuZWQuIElmIGEgY29tcGxldGUgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgaXMgCiAgICAgKiBub3QgZm91bmQgdGhlIGluY29tcGxldGUgY2hhcmFjdGVyIHdpbGwgYmUgcmV0dXJuZWQKICAgICAqIEBwYXJhbSBzb3VyY2UgVVRGLTE2IGNoYXJzIHN0cmluZyBidWZmZXIKICAgICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYtMTYgb2Zmc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgY2hhcmFjdGVyLgogICAgICogQHJldHVybiBVVEYtMzIgdmFsdWUgZm9yIHRoZSBVVEYtMzIgdmFsdWUgdGhhdCBjb250YWlucyB0aGUgY2hhciBhdAogICAgICogICAgICAgICBvZmZzZXQxNi4gVGhlIGJvdW5kYXJpZXMgb2YgdGhhdCBjb2RlcG9pbnQgYXJlIHRoZSBzYW1lIGFzIGluCiAgICAgKiAgICAgICAgIDxjb2RlPmJvdW5kczMyKCk8L2NvZGU+LgogICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHRocm93biBpZiBvZmZzZXQxNiBpcyBvdXQgb2YgCiAgICAgKiAgICAgICAgICAgIGJvdW5kcy4KICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBjaGFyQXQoUmVwbGFjZWFibGUgc291cmNlLCBpbnQgb2Zmc2V0MTYpCiAgICB7CiAgICAgICAgaWYgKG9mZnNldDE2IDwgMCB8fCBvZmZzZXQxNiA+PSBzb3VyY2UubGVuZ3RoKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24ob2Zmc2V0MTYpOwogICAgICAgIH0KICAgICAgICAgIAogICAgICAgIGNoYXIgc2luZ2xlID0gc291cmNlLmNoYXJBdChvZmZzZXQxNik7CiAgICAgICAgaWYgKCFpc1N1cnJvZ2F0ZShzaW5nbGUpKSB7CiAgICAgICAgICAgIHJldHVybiBzaW5nbGU7CiAgICAgICAgfQoKICAgICAgICAvLyBDb252ZXJ0IHRoZSBVVEYtMTYgc3Vycm9nYXRlIHBhaXIgaWYgbmVjZXNzYXJ5LgogICAgICAgIC8vIEZvciBzaW1wbGljaXR5IGluIHVzYWdlLCBhbmQgYmVjYXVzZSB0aGUgZnJlcXVlbmN5IG9mIHBhaXJzIGlzIAogICAgICAgIC8vIGxvdywgbG9vayBib3RoIGRpcmVjdGlvbnMuCiAgICAgICAgICAgICAgICAKCSAgICBpZiAoc2luZ2xlIDw9IExFQURfU1VSUk9HQVRFX01BWF9WQUxVRSkgCgkgICAgewoJICAgICAgICArKyBvZmZzZXQxNjsKCSAgICAgICAgaWYgKHNvdXJjZS5sZW5ndGgoKSAhPSBvZmZzZXQxNikKCSAgICAgICAgewoJICAgICAgICBjaGFyIHRyYWlsID0gc291cmNlLmNoYXJBdChvZmZzZXQxNik7CgkgICAgICAgIGlmIChpc1RyYWlsU3Vycm9nYXRlKHRyYWlsKSkKCSAgICAgICAgICAgIHJldHVybiBVQ2hhcmFjdGVyUHJvcGVydHkuZ2V0UmF3U3VwcGxlbWVudGFyeShzaW5nbGUsIHRyYWlsKTsKCSAgICAgICAgfQoJICAgIH0gCgkgICAgZWxzZSAKCSAgICB7IAoJICAgICAgICAtLSBvZmZzZXQxNjsKCSAgICAgICAgaWYgKG9mZnNldDE2ID49IDApCgkgICAgICAgIHsKCSAgICAgICAgLy8gc2luZ2xlIGlzIGEgdHJhaWwgc3Vycm9nYXRlIHNvCgkgICAgICAgIGNoYXIgbGVhZCA9IHNvdXJjZS5jaGFyQXQob2Zmc2V0MTYpOwoJICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKGxlYWQpKSB7CgkgICAgICAgICAgICByZXR1cm4gVUNoYXJhY3RlclByb3BlcnR5LmdldFJhd1N1cHBsZW1lbnRhcnkobGVhZCwgc2luZ2xlKTsKCSAgICAgICAgfQoJICAgICAgICB9CgkgICAgfSAKCSAgICByZXR1cm4gc2luZ2xlOyAvLyByZXR1cm4gdW5tYXRjaGVkIHN1cnJvZ2F0ZQogICAgfQogICAgICAKICAgIC8qKgogICAgICogRGV0ZXJtaW5lcyBob3cgbWFueSBjaGFycyB0aGlzIGNoYXIzMiByZXF1aXJlcy4KICAgICAqIElmIGEgdmFsaWRpdHkgY2hlY2sgaXMgcmVxdWlyZWQsIHVzZSA8Y29kZT4KICAgICAqIDxhIGhyZWY9Ii4uL1VDaGFyYWN0ZXIuaHRtbCNpc0xlZ2FsKGNoYXIpIj5pc0xlZ2FsKCk8L2E+PC9jb2RlPiBvbiAKICAgICAqIGNoYXIzMiBiZWZvcmUgY2FsbGluZy4KICAgICAqIEBwYXJhbSBjaCB0aGUgaW5wdXQgY29kZXBvaW50LgogICAgICogQHJldHVybiAyIGlmIGlzIGluIHN1cHBsZW1lbnRhcnkgc3BhY2UsIG90aGVyd2lzZSAxLiAKICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBnZXRDaGFyQ291bnQoaW50IGNoYXIzMikgCiAgICB7CiAgICAgICAgaWYgKGNoYXIzMiA8IFNVUFBMRU1FTlRBUllfTUlOX1ZBTFVFKSB7CiAgICAgICAgCXJldHVybiAxOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMjsKICAgIH0KICAgICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhlIGJvdW5kYXJpZXMgYXJvdW5kIHRoZSBjaGFyIGF0IG9mZnNldDE2LgogICAgICogVXNlZCBmb3IgcmFuZG9tIGFjY2Vzcy4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGV4dCB0byBhbmFseXNlCiAgICAgKiBAcGFyYW0gb2Zmc2V0MTYgVVRGLTE2IG9mZnNldAogICAgICogQHJldHVybiA8dWw+CiAgICAgKiAgICAgICAgICAgPGxpPiBTSU5HTEVfQ0hBUl9CT1VOREFSWSA6IGEgc2luZ2xlIGNoYXI7IHRoZSBib3VuZHMgYXJlIAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb2Zmc2V0MTYsIG9mZnNldDE2KzFdCiAgICAgKiAgICAgICAgICAgPGxpPiBMRUFEX1NVUlJPR0FURV9CT1VOREFSWSA6IGEgc3Vycm9nYXRlIHBhaXIgc3RhcnRpbmcgYXQgCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDE2OyAKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGJvdW5kcyBhcmUgCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvZmZzZXQxNiwgb2Zmc2V0MTYgKyAyXQogICAgICogICAgICAgICAgIDxsaT4gVFJBSUxfU1VSUk9HQVRFX0JPVU5EQVJZIDogYSBzdXJyb2dhdGUgcGFpciBzdGFydGluZyBhdCAKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDE2IC0gMTsgdGhlIGJvdW5kcyBhcmUgCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb2Zmc2V0MTYgLSAxLCBvZmZzZXQxNiArIDFdCiAgICAgKiAgICAgICAgIDwvdWw+CiAgICAgKiAgICAgICAgIEZvciBiaXQtdHdpZGRsZXJzLCB0aGUgcmV0dXJuIHZhbHVlcyBmb3IgdGhlc2UgYXJlIGNob3NlbiBzbyAKICAgICAqICAgICAgICAgdGhhdCB0aGUgYm91bmRhcmllcyBjYW4gYmUgZ290dGVuIGJ5OgogICAgICogICAgICAgICBbb2Zmc2V0MTYgLSAodmFsdWUgPj4gMiksIG9mZnNldDE2ICsgKHZhbHVlICYgMyldLgogICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIG9mZnNldDE2IGlzIG91dCBvZiBib3VuZHMuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgYm91bmRzKFN0cmluZyBzb3VyY2UsIGludCBvZmZzZXQxNikgCiAgICB7CiAgICAgICAgY2hhciBjaCA9IHNvdXJjZS5jaGFyQXQob2Zmc2V0MTYpOwogICAgICAgIGlmIChpc1N1cnJvZ2F0ZShjaCkpIHsKICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkpIAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoKysgb2Zmc2V0MTYgPCBzb3VyY2UubGVuZ3RoKCkgJiYgCiAgICAgICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KG9mZnNldDE2KSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTEVBRF9TVVJST0dBVEVfQk9VTkRBUlk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gCiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLy8gaXNUcmFpbFN1cnJvZ2F0ZShjaCksIHNvCiAgICAgICAgICAgICAgICAtLSBvZmZzZXQxNjsKICAgICAgICAgICAgICAgIGlmIChvZmZzZXQxNiA+PSAwICYmIGlzTGVhZFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KG9mZnNldDE2KSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVFJBSUxfU1VSUk9HQVRFX0JPVU5EQVJZOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBTSU5HTEVfQ0hBUl9CT1VOREFSWTsKICAgIH0KICAgICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhlIGJvdW5kYXJpZXMgYXJvdW5kIHRoZSBjaGFyIGF0IG9mZnNldDE2LiBVc2VkIAogICAgICogZm9yIHJhbmRvbSBhY2Nlc3MuCiAgICAgKiBAcGFyYW0gc291cmNlIHN0cmluZyBidWZmZXIgdG8gYW5hbHlzZQogICAgICogQHBhcmFtIG9mZnNldDE2IFVURjE2IG9mZnNldAogICAgICogQHJldHVybgogICAgICogICAgIDx1bD4KICAgICAqICAgICA8bGk+IFNJTkdMRV9DSEFSX0JPVU5EQVJZIDogYSBzaW5nbGUgY2hhcjsgdGhlIGJvdW5kcyBhcmUKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb2Zmc2V0MTYsIG9mZnNldDE2ICsgMV0KICAgICAqICAgICA8bGk+IExFQURfU1VSUk9HQVRFX0JPVU5EQVJZIDogYSBzdXJyb2dhdGUgcGFpciBzdGFydGluZyBhdCAKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0MTY7IHRoZSBib3VuZHMgYXJlIAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb2Zmc2V0MTYsIG9mZnNldDE2ICsgMl0KICAgICAqICAgICA8bGk+IFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWSA6IGEgc3Vycm9nYXRlIHBhaXIgc3RhcnRpbmcgYXQgCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQxNiAtIDE7IHRoZSBib3VuZHMgYXJlIAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29mZnNldDE2IC0gMSwgb2Zmc2V0MTYgKyAxXQogICAgICogICAgIDwvdWw+CiAgICAgKiBGb3IgYml0LXR3aWRkbGVycywgdGhlIHJldHVybiB2YWx1ZXMgZm9yIHRoZXNlIGFyZSBjaG9zZW4gc28gdGhhdCB0aGUgCiAgICAgKiBib3VuZGFyaWVzIGNhbiBiZSBnb3R0ZW4gYnk6IAogICAgICogICAgICAgICAgICAgICAgICAgIFtvZmZzZXQxNiAtICh2YWx1ZSA+PiAyKSwgb2Zmc2V0MTYgKyAodmFsdWUgJiAzKV0uCiAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgb2Zmc2V0MTYgaXMgb3V0IG9mIGJvdW5kcy4KICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBib3VuZHMoU3RyaW5nQnVmZmVyIHNvdXJjZSwgaW50IG9mZnNldDE2KQogICAgewogICAgICAgIGNoYXIgY2ggPSBzb3VyY2UuY2hhckF0KG9mZnNldDE2KTsKICAgICAgICBpZiAoaXNTdXJyb2dhdGUoY2gpKSB7CiAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoY2gpKSAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCsrIG9mZnNldDE2IDwgc291cmNlLmxlbmd0aCgpICYmIAogICAgICAgICAgICAgICAgICAgIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlLmNoYXJBdChvZmZzZXQxNikpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIExFQURfU1VSUk9HQVRFX0JPVU5EQVJZOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IAogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGlzVHJhaWxTdXJyb2dhdGUoY2gpLCBzbwogICAgICAgICAgICAgICAgLS0gb2Zmc2V0MTY7CiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0MTYgPj0gMCAmJiAKICAgICAgICAgICAgICAgICAgICBpc0xlYWRTdXJyb2dhdGUoc291cmNlLmNoYXJBdChvZmZzZXQxNikpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gU0lOR0xFX0NIQVJfQk9VTkRBUlk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIHRoZSBib3VuZGFyaWVzIGFyb3VuZCB0aGUgY2hhciBhdCBvZmZzZXQxNi4gVXNlZCAKICAgICAqIGZvciByYW5kb20gYWNjZXNzLiBOb3RlIHRoYXQgdGhlIGJvdW5kYXJpZXMgYXJlIGRldGVybWluZWQgd2l0aCByZXNwZWN0IAogICAgICogdG8gdGhlIHN1YmFycmF5LCBoZW5jZSB0aGUgY2hhciBhcnJheSB7MHhEODAwLCAweERDMDB9IGhhcyB0aGUgcmVzdWx0IAogICAgICogU0lOR0xFX0NIQVJfQk9VTkRBUlkgZm9yIHN0YXJ0ID0gb2Zmc2V0MTYgPSAwIGFuZCBsaW1pdCA9IDEuCiAgICAgKiBAcGFyYW0gc291cmNlIGNoYXIgYXJyYXkgdG8gYW5hbHlzZQogICAgICogQHBhcmFtIHN0YXJ0IG9mZnNldCB0byBzdWJzdHJpbmcgaW4gdGhlIHNvdXJjZSBhcnJheSBmb3IgYW5hbHl6aW5nCiAgICAgKiBAcGFyYW0gbGltaXQgb2Zmc2V0IHRvIHN1YnN0cmluZyBpbiB0aGUgc291cmNlIGFycmF5IGZvciBhbmFseXppbmcKICAgICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYxNiBvZmZzZXQgcmVsYXRpdmUgdG8gc3RhcnQKICAgICAqIEByZXR1cm4KICAgICAqICAgICA8dWw+CiAgICAgKiAgICAgICAgIDxsaT4gU0lOR0xFX0NIQVJfQk9VTkRBUlkgOiBhIHNpbmdsZSBjaGFyOyB0aGUgYm91bmRzIGFyZQogICAgICogICAgICAgICA8bGk+IExFQURfU1VSUk9HQVRFX0JPVU5EQVJZIDogYSBzdXJyb2dhdGUgcGFpciBzdGFydGluZyBhdAogICAgICogICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDE2OyB0aGUgYm91bmRzIGFyZSBbb2Zmc2V0MTYsIG9mZnNldDE2ICsgMl0KICAgICAqICAgICAgICAgPGxpPiBUUkFJTF9TVVJST0dBVEVfQk9VTkRBUlkgOiBhIHN1cnJvZ2F0ZSBwYWlyIHN0YXJ0aW5nIGF0CiAgICAgKiAgICAgICAgICAgICAgIG9mZnNldDE2IC0gMTsgdGhlIGJvdW5kcyBhcmUgW29mZnNldDE2IC0gMSwgb2Zmc2V0MTYgKyAxXQogICAgICogICAgIDwvdWw+CiAgICAgKiBGb3IgYml0LXR3aWRkbGVycywgdGhlIGJvdW5kYXJ5IHZhbHVlcyBmb3IgdGhlc2UgYXJlIGNob3NlbiBzbyB0aGF0IHRoZSAKICAgICAqIGJvdW5kYXJpZXMgY2FuIGJlIGdvdHRlbiBieTogW29mZnNldDE2IC0gKGJvdW5kdmFsdWUgPj4gMiksIG9mZnNldDE2IAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoYm91bmR2YWx1ZSAmIDMpXS4KICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBvZmZzZXQxNiBpcyBub3Qgd2l0aGluIHRoZSAKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZSBvZiBzdGFydCBhbmQgbGltaXQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgYm91bmRzKGNoYXIgc291cmNlW10sIGludCBzdGFydCwgaW50IGxpbWl0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0MTYpCiAgICB7CiAgICAgICAgb2Zmc2V0MTYgKz0gc3RhcnQ7CiAgICAgICAgaWYgKG9mZnNldDE2IDwgc3RhcnQgfHwgb2Zmc2V0MTYgPj0gbGltaXQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQxNik7CiAgICAgICAgfQogICAgICAgIGNoYXIgY2ggPSBzb3VyY2Vbb2Zmc2V0MTZdOwogICAgICAgIGlmIChpc1N1cnJvZ2F0ZShjaCkpIHsKICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkpIHsKICAgICAgICAgICAgICAgICsrIG9mZnNldDE2OwogICAgICAgICAgICAgICAgaWYgKG9mZnNldDE2IDwgbGltaXQgJiYgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2Vbb2Zmc2V0MTZdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBMRUFEX1NVUlJPR0FURV9CT1VOREFSWTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSAKICAgICAgICAgICAgZWxzZSB7IC8vIGlzVHJhaWxTdXJyb2dhdGUoY2gpLCBzbwogICAgICAgICAgICAgICAgLS0gb2Zmc2V0MTY7CiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0MTYgPj0gc3RhcnQgJiYgaXNMZWFkU3Vycm9nYXRlKHNvdXJjZVtvZmZzZXQxNl0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gU0lOR0xFX0NIQVJfQk9VTkRBUlk7ICAgIAogICAgfQoKICAgIC8qKgogICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBjb2RlIHZhbHVlIGlzIGEgc3Vycm9nYXRlLgogICAgICogQHBhcmFtIGNoIHRoZSBpbnB1dCBjaGFyYWN0ZXIuCiAgICAgKiBAcmV0dXJuIHRydWUgaWZmIHRoZSBpbnB1dCBjaGFyYWN0ZXIgaXMgYSBzdXJyb2dhdGUuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3Vycm9nYXRlKGNoYXIgY2hhcjE2KSAKICAgIHsKICAgICAgICByZXR1cm4gTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFIDw9IGNoYXIxNiAmJiAKICAgICAgICAgICAgY2hhcjE2IDw9IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUU7CiAgICB9CiAgICAgICAgCiAgICAvKioKICAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgY2hhcmFjdGVyIGlzIGEgdHJhaWwgc3Vycm9nYXRlLgogICAgICogQHBhcmFtIGNoYXIxNiB0aGUgaW5wdXQgY2hhcmFjdGVyLgogICAgICogQHJldHVybiB0cnVlIGlmZiB0aGUgaW5wdXQgY2hhcmFjdGVyIGlzIGEgdHJhaWwgc3Vycm9nYXRlLgogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1RyYWlsU3Vycm9nYXRlKGNoYXIgY2hhcjE2KSAKICAgIHsKICAgICAgICByZXR1cm4gKFRSQUlMX1NVUlJPR0FURV9NSU5fVkFMVUUgPD0gY2hhcjE2ICYmIAogICAgICAgICAgICAgICAgY2hhcjE2IDw9IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUUpOwogICAgfQogICAgICAgIAogICAgLyoqCiAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGNoYXJhY3RlciBpcyBhIGxlYWQgc3Vycm9nYXRlLgogICAgICogQHBhcmFtIGNoYXIxNiB0aGUgaW5wdXQgY2hhcmFjdGVyLgogICAgICogQHJldHVybiB0cnVlIGlmZiB0aGUgaW5wdXQgY2hhcmFjdGVyIGlzIGEgbGVhZCBzdXJyb2dhdGUKICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNMZWFkU3Vycm9nYXRlKGNoYXIgY2hhcjE2KSAKICAgIHsKICAgICAgICByZXR1cm4gTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFIDw9IGNoYXIxNiAmJiAKICAgICAgICAgICAgY2hhcjE2IDw9IExFQURfU1VSUk9HQVRFX01BWF9WQUxVRTsKICAgIH0KICAgICAgICAgICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxlYWQgc3Vycm9nYXRlLgogICAgICogSWYgYSB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgICogPGNvZGU+PGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IAogICAgICogb24gY2hhcjMyIGJlZm9yZSBjYWxsaW5nLgogICAgICogQHBhcmFtIGNoYXIzMiB0aGUgaW5wdXQgY2hhcmFjdGVyLgogICAgICogQHJldHVybiBsZWFkIHN1cnJvZ2F0ZSBpZiB0aGUgZ2V0Q2hhckNvdW50KGNoKSBpcyAyOyA8YnI+CiAgICAgKiAgICAgICAgIGFuZCAwIG90aGVyd2lzZSAobm90ZTogMCBpcyBub3QgYSB2YWxpZCBsZWFkIHN1cnJvZ2F0ZSkuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjaGFyIGdldExlYWRTdXJyb2dhdGUoaW50IGNoYXIzMikgCiAgICB7CiAgICAgICAgaWYgKGNoYXIzMiA+PSBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkgewogICAgICAgIAlyZXR1cm4gKGNoYXIpKExFQURfU1VSUk9HQVRFX09GRlNFVF8gKyAKICAgICAgICAgICAgICAgICAgICAgIChjaGFyMzIgPj4gTEVBRF9TVVJST0dBVEVfU0hJRlRfKSk7CiAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgICAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgdHJhaWwgc3Vycm9nYXRlLgogICAgICogSWYgYSB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgICogPGNvZGU+PGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IAogICAgICogb24gY2hhcjMyIGJlZm9yZSBjYWxsaW5nLgogICAgICogQHBhcmFtIGNoYXIzMiB0aGUgaW5wdXQgY2hhcmFjdGVyLgogICAgICogQHJldHVybiB0aGUgdHJhaWwgc3Vycm9nYXRlIGlmIHRoZSBnZXRDaGFyQ291bnQoY2gpIGlzIDI7IDxicj5vdGhlcndpc2UgCiAgICAgKiAgICAgICAgIHRoZSBjaGFyYWN0ZXIgaXRzZWxmCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBjaGFyIGdldFRyYWlsU3Vycm9nYXRlKGludCBjaGFyMzIpIAogICAgewogICAgICAgIGlmIChjaGFyMzIgPj0gU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUpIHsKICAgICAgICAJcmV0dXJuIChjaGFyKShUUkFJTF9TVVJST0dBVEVfTUlOX1ZBTFVFICsgCiAgICAgICAgICAgICAgICAgICAgICAoY2hhcjMyICYgVFJBSUxfU1VSUk9HQVRFX01BU0tfKSk7ICAgICAgIAogICAgICAgIH0KICAgICAgICAgIAogICAgICAgIHJldHVybiAoY2hhciljaGFyMzI7CiAgICB9CiAgICAgICAgCiAgICAvKioKICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIFN0cmluZy52YWx1ZU9mKGNoYXIpLiBSZXR1cm5zIGEgb25lIAogICAgICogb3IgdHdvIGNoYXIgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIFVURi0zMiB2YWx1ZSBpbiBVVEYxNiBmb3JtYXQuIElmIGEgCiAgICAgKiB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgICogPGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIAogICAgICogY2hhcjMyIGJlZm9yZSBjYWxsaW5nLgogICAgICogQHBhcmFtIGNoYXIzMiB0aGUgaW5wdXQgY2hhcmFjdGVyLgogICAgICogQHJldHVybiBzdHJpbmcgdmFsdWUgb2YgY2hhcjMyIGluIFVURjE2IGZvcm1hdAogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdGhyb3duIGlmIGNoYXIzMiBpcyBhIGludmFsaWQgCiAgICAgKiAgICAgICAgICAgIGNvZGVwb2ludC4KICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB2YWx1ZU9mKGludCBjaGFyMzIpCiAgICB7CiAgICAgICAgaWYgKGNoYXIzMiA8IENPREVQT0lOVF9NSU5fVkFMVUUgfHwgY2hhcjMyID4gQ09ERVBPSU5UX01BWF9WQUxVRSkgewogICAgICAgIAl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbGxlZ2FsIGNvZGVwb2ludCIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdG9TdHJpbmcoY2hhcjMyKTsKICAgIH0KICAgICAgCiAgICAvKioKICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIFN0cmluZy52YWx1ZU9mKGNvZGVwb2ludCBhdCAKICAgICAqIG9mZnNldDE2KS4gCiAgICAgKiBSZXR1cm5zIGEgb25lIG9yIHR3byBjaGFyIHN0cmluZyBjb250YWluaW5nIHRoZSBVVEYtMzIgdmFsdWUgaW4gVVRGMTYgCiAgICAgKiBmb3JtYXQuIElmIG9mZnNldDE2IGluZGV4ZXMgYSBzdXJyb2dhdGUgY2hhcmFjdGVyLCB0aGUgd2hvbGUgCiAgICAgKiBzdXBwbGVtZW50YXJ5IGNvZGVwb2ludCB3aWxsIGJlIHJldHVybmVkLgogICAgICogSWYgYSB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgICogPGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIHRoZSAKICAgICAqIGNvZGVwb2ludCBhdCBvZmZzZXQxNiBiZWZvcmUgY2FsbGluZy4KICAgICAqIFRoZSByZXN1bHQgcmV0dXJuZWQgd2lsbCBiZSBhIG5ld2x5IGNyZWF0ZWQgU3RyaW5nIG9idGFpbmVkIGJ5IGNhbGxpbmcgCiAgICAgKiBzb3VyY2Uuc3Vic3RyaW5nKC4uKSB3aXRoIHRoZSBhcHByb3ByaWF0ZSBpbmRleGVzLgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgaW5wdXQgc3RyaW5nLgogICAgICogQHBhcmFtIG9mZnNldDE2IHRoZSBVVEYxNiBpbmRleCB0byB0aGUgY29kZXBvaW50IGluIHNvdXJjZQogICAgICogQHJldHVybiBzdHJpbmcgdmFsdWUgb2YgY2hhcjMyIGluIFVURjE2IGZvcm1hdAogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHZhbHVlT2YoU3RyaW5nIHNvdXJjZSwgaW50IG9mZnNldDE2KQogICAgewogICAgICAgIHN3aXRjaCAoYm91bmRzKHNvdXJjZSwgb2Zmc2V0MTYpKSB7CiAgICAgICAgICAgIGNhc2UgTEVBRF9TVVJST0dBVEVfQk9VTkRBUlk6IAogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnN0cmluZyhvZmZzZXQxNiwgb2Zmc2V0MTYgKyAyKTsKICAgICAgICAgICAgY2FzZSBUUkFJTF9TVVJST0dBVEVfQk9VTkRBUlk6IAogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnN0cmluZyhvZmZzZXQxNiAtIDEsIG9mZnNldDE2ICsgMSk7CiAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBzb3VyY2Uuc3Vic3RyaW5nKG9mZnNldDE2LCBvZmZzZXQxNiArIDEpOwogICAgICAgIH0KICAgIH0KICAgICAgCiAgICAvKioKICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIAogICAgICogU3RyaW5nQnVmZmVyLnZhbHVlT2YoY29kZXBvaW50IGF0IG9mZnNldDE2KS4gCiAgICAgKiBSZXR1cm5zIGEgb25lIG9yIHR3byBjaGFyIHN0cmluZyBjb250YWluaW5nIHRoZSBVVEYtMzIgdmFsdWUgaW4gVVRGMTYgCiAgICAgKiBmb3JtYXQuIElmIG9mZnNldDE2IGluZGV4ZXMgYSBzdXJyb2dhdGUgY2hhcmFjdGVyLCB0aGUgd2hvbGUgCiAgICAgKiBzdXBwbGVtZW50YXJ5IGNvZGVwb2ludCB3aWxsIGJlIHJldHVybmVkLgogICAgICogSWYgYSB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgICogPGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIHRoZSAKICAgICAqIGNvZGVwb2ludCBhdCBvZmZzZXQxNiBiZWZvcmUgY2FsbGluZy4KICAgICAqIFRoZSByZXN1bHQgcmV0dXJuZWQgd2lsbCBiZSBhIG5ld2x5IGNyZWF0ZWQgU3RyaW5nIG9idGFpbmVkIGJ5IGNhbGxpbmcgCiAgICAgKiBzb3VyY2Uuc3Vic3RyaW5nKC4uKSB3aXRoIHRoZSBhcHByb3ByaWF0ZSBpbmRleGVzLgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgaW5wdXQgc3RyaW5nIGJ1ZmZlci4KICAgICAqIEBwYXJhbSBvZmZzZXQxNiB0aGUgVVRGMTYgaW5kZXggdG8gdGhlIGNvZGVwb2ludCBpbiBzb3VyY2UKICAgICAqIEByZXR1cm4gc3RyaW5nIHZhbHVlIG9mIGNoYXIzMiBpbiBVVEYxNiBmb3JtYXQKICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB2YWx1ZU9mKFN0cmluZ0J1ZmZlciBzb3VyY2UsIGludCBvZmZzZXQxNikKICAgIHsKICAgICAgICBzd2l0Y2ggKGJvdW5kcyhzb3VyY2UsIG9mZnNldDE2KSkgewogICAgICAgICAgICBjYXNlIExFQURfU1VSUk9HQVRFX0JPVU5EQVJZOiAKICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzb3VyY2Uuc3Vic3RyaW5nKG9mZnNldDE2LCBvZmZzZXQxNiArIDIpOwogICAgICAgICAgICBjYXNlIFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWTogCiAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnN0cmluZyhvZmZzZXQxNiAtIDEsIG9mZnNldDE2ICsgMSk7CiAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBzb3VyY2Uuc3Vic3RyaW5nKG9mZnNldDE2LCBvZmZzZXQxNiArIDEpOwogICAgICAgIH0KICAgIH0KICAgICAgCiAgICAvKioKICAgICAqIENvbnZlbmllbmNlIG1ldGhvZC4gCiAgICAgKiBSZXR1cm5zIGEgb25lIG9yIHR3byBjaGFyIHN0cmluZyBjb250YWluaW5nIHRoZSBVVEYtMzIgdmFsdWUgaW4gVVRGMTYgCiAgICAgKiBmb3JtYXQuIElmIG9mZnNldDE2IGluZGV4ZXMgYSBzdXJyb2dhdGUgY2hhcmFjdGVyLCB0aGUgd2hvbGUgCiAgICAgKiBzdXBwbGVtZW50YXJ5IGNvZGVwb2ludCB3aWxsIGJlIHJldHVybmVkLCBleGNlcHQgd2hlbiBlaXRoZXIgdGhlIAogICAgICogbGVhZGluZyBvciB0cmFpbGluZyBzdXJyb2dhdGUgY2hhcmFjdGVyIGxpZXMgb3V0IG9mIHRoZSBzcGVjaWZpZWQgCiAgICAgKiBzdWJhcnJheS4gSW4gdGhlIGxhdHRlciBjYXNlLCBvbmx5IHRoZSBzdXJyb2dhdGUgY2hhcmFjdGVyIHdpdGhpbiAKICAgICAqIGJvdW5kcyB3aWxsIGJlIHJldHVybmVkLgogICAgICogSWYgYSB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgICogPGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIHRoZSAKICAgICAqIGNvZGVwb2ludCBhdCBvZmZzZXQxNiBiZWZvcmUgY2FsbGluZy4KICAgICAqIFRoZSByZXN1bHQgcmV0dXJuZWQgd2lsbCBiZSBhIG5ld2x5IGNyZWF0ZWQgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIAogICAgICogcmVsZXZhbnQgY2hhcmFjdGVycy4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIGlucHV0IGNoYXIgYXJyYXkuCiAgICAgKiBAcGFyYW0gc3RhcnQgc3RhcnQgaW5kZXggb2YgdGhlIHN1YmFycmF5CiAgICAgKiBAcGFyYW0gbGltaXQgZW5kIGluZGV4IG9mIHRoZSBzdWJhcnJheQogICAgICogQHBhcmFtIG9mZnNldDE2IHRoZSBVVEYxNiBpbmRleCB0byB0aGUgY29kZXBvaW50IGluIHNvdXJjZSByZWxhdGl2ZSB0byAKICAgICAqICAgICAgICBzdGFydAogICAgICogQHJldHVybiBzdHJpbmcgdmFsdWUgb2YgY2hhcjMyIGluIFVURjE2IGZvcm1hdAogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHZhbHVlT2YoY2hhciBzb3VyY2VbXSwgaW50IHN0YXJ0LCBpbnQgbGltaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvZmZzZXQxNikKICAgIHsKICAgICAgICBzd2l0Y2ggKGJvdW5kcyhzb3VyY2UsIHN0YXJ0LCBsaW1pdCwgb2Zmc2V0MTYpKSB7CiAgICAgICAgICAgIGNhc2UgTEVBRF9TVVJST0dBVEVfQk9VTkRBUlk6IAogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoc291cmNlLCBzdGFydCArIG9mZnNldDE2LCAyKTsKICAgICAgICAgICAgY2FzZSBUUkFJTF9TVVJST0dBVEVfQk9VTkRBUlk6IAogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoc291cmNlLCBzdGFydCArIG9mZnNldDE2IC0gMSwgMik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXcgU3RyaW5nKHNvdXJjZSwgc3RhcnQgKyBvZmZzZXQxNiwgMSk7CiAgICB9CiAgICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBVVEYtMTYgb2Zmc2V0IHRoYXQgY29ycmVzcG9uZHMgdG8gYSBVVEYtMzIgb2Zmc2V0LiAKICAgICAqIFVzZWQgZm9yIHJhbmRvbSBhY2Nlc3MuIFNlZSB0aGUgPGEgbmFtZT0iX3RvcF8iPmNsYXNzIGRlc2NyaXB0aW9uPC9hPiAKICAgICAqIGZvciBub3RlcyBvbiByb3VuZHRyaXBwaW5nLgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgVVRGLTE2IHN0cmluZwogICAgICogQHBhcmFtIG9mZnNldDMyIFVURi0zMiBvZmZzZXQKICAgICAqIEByZXR1cm4gVVRGLTE2IG9mZnNldCAKICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBvZmZzZXQzMiBpcyBvdXQgb2YgYm91bmRzLgogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGZpbmRPZmZzZXRGcm9tQ29kZVBvaW50KFN0cmluZyBzb3VyY2UsIGludCBvZmZzZXQzMikgCiAgICB7CiAgICAgICAgY2hhciBjaDsKICAgICAgICBpbnQgc2l6ZSA9IHNvdXJjZS5sZW5ndGgoKSwKICAgICAgICAgICAgcmVzdWx0ID0gMCwKICAgICAgICAgICAgY291bnQgPSBvZmZzZXQzMjsKICAgICAgICBpZiAob2Zmc2V0MzIgPCAwIHx8IG9mZnNldDMyID4gc2l6ZSkgewogICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDMyKTsKICAgICAgICB9CiAgICAgICAgd2hpbGUgKHJlc3VsdCA8IHNpemUgJiYgY291bnQgPiAwKQogICAgICAgIHsKICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQXQocmVzdWx0KTsKICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKGNoKSAmJiAoKHJlc3VsdCArIDEpIDwgc2l6ZSkgJiYgCiAgICAgICAgICAgIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlLmNoYXJBdChyZXN1bHQgKyAxKSkpIHsKICAgICAgICAgICAgcmVzdWx0ICsrOwogICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgY291bnQgLS07CiAgICAgICAgcmVzdWx0ICsrOwogICAgICAgIH0KICAgICAgICBpZiAoY291bnQgIT0gMCkgewogICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDMyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIFVURi0xNiBvZmZzZXQgdGhhdCBjb3JyZXNwb25kcyB0byBhIFVURi0zMiBvZmZzZXQuCiAgICAgKiBVc2VkIGZvciByYW5kb20gYWNjZXNzLiBTZWUgdGhlIDxhIG5hbWU9Il90b3BfIj5jbGFzcyBkZXNjcmlwdGlvbjwvYT4KICAgICAqIGZvciBub3RlcyBvbiByb3VuZHRyaXBwaW5nLgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgVVRGLTE2IHN0cmluZyBidWZmZXIKICAgICAqIEBwYXJhbSBvZmZzZXQzMiBVVEYtMzIgb2Zmc2V0CiAgICAgKiBAcmV0dXJuIFVURi0xNiBvZmZzZXQKICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBvZmZzZXQzMiBpcyBvdXQgb2YgYm91bmRzLgogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGZpbmRPZmZzZXRGcm9tQ29kZVBvaW50KFN0cmluZ0J1ZmZlciBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldDMyKQogICAgewogICAgICAgIGNoYXIgY2g7CiAgICAgICAgaW50IHNpemUgPSBzb3VyY2UubGVuZ3RoKCksCiAgICAgICAgICAgIHJlc3VsdCA9IDAsCiAgICAgICAgICAgIGNvdW50ID0gb2Zmc2V0MzI7CiAgICAgICAgaWYgKG9mZnNldDMyIDwgMCB8fCBvZmZzZXQzMiA+IHNpemUpIHsKICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQzMik7CiAgICAgICAgfQogICAgICAgIHdoaWxlIChyZXN1bHQgPCBzaXplICYmIGNvdW50ID4gMCkKICAgICAgICB7CiAgICAgICAgY2ggPSBzb3VyY2UuY2hhckF0KHJlc3VsdCk7CiAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgKChyZXN1bHQgKyAxKSA8IHNpemUpICYmIAogICAgICAgICAgICBpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0ICsgMSkpKSB7CiAgICAgICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIGNvdW50IC0tOwogICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50ICE9IDApIHsKICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQzMik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBVVEYtMTYgb2Zmc2V0IHRoYXQgY29ycmVzcG9uZHMgdG8gYSBVVEYtMzIgb2Zmc2V0LgogICAgICogVXNlZCBmb3IgcmFuZG9tIGFjY2Vzcy4gU2VlIHRoZSA8YSBuYW1lPSJfdG9wXyI+Y2xhc3MgZGVzY3JpcHRpb248L2E+CiAgICAgKiBmb3Igbm90ZXMgb24gcm91bmR0cmlwcGluZy4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIFVURi0xNiBjaGFyIGFycmF5IHdob3NlIHN1YnN0cmluZyBpcyB0byBiZSBhbmFseXNlZAogICAgICogQHBhcmFtIHN0YXJ0IG9mZnNldCBvZiB0aGUgc3Vic3RyaW5nIHRvIGJlIGFuYWx5c2VkCiAgICAgKiBAcGFyYW0gbGltaXQgb2Zmc2V0IG9mIHRoZSBzdWJzdHJpbmcgdG8gYmUgYW5hbHlzZWQKICAgICAqIEBwYXJhbSBvZmZzZXQzMiBVVEYtMzIgb2Zmc2V0IHJlbGF0aXZlIHRvIHN0YXJ0CiAgICAgKiBAcmV0dXJuIFVURi0xNiBvZmZzZXQgcmVsYXRpdmUgdG8gc3RhcnQKICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBvZmZzZXQzMiBpcyBvdXQgb2YgYm91bmRzLgogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGZpbmRPZmZzZXRGcm9tQ29kZVBvaW50KGNoYXIgc291cmNlW10sIGludCBzdGFydCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGltaXQsIGludCBvZmZzZXQzMikKICAgIHsKICAgICAgICBjaGFyIGNoOwogICAgICAgIGludCByZXN1bHQgPSBzdGFydCwKICAgICAgICAgICAgY291bnQgPSBvZmZzZXQzMjsKICAgICAgICBpZiAob2Zmc2V0MzIgPiBsaW1pdCAtIHN0YXJ0KSB7CiAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQzMik7CiAgICAgICAgfQogICAgICAgIHdoaWxlIChyZXN1bHQgPCBsaW1pdCAmJiBjb3VudCA+IDApCiAgICAgICAgewogICAgICAgIGNoID0gc291cmNlW3Jlc3VsdF07CiAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgKChyZXN1bHQgKyAxKSA8IGxpbWl0KSAmJiAKICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2VbcmVzdWx0ICsgMV0pKSB7CiAgICAgICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIGNvdW50IC0tOwogICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50ICE9IDApIHsKICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDMyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdCAtIHN0YXJ0OwogICAgfQogICAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgVVRGLTMyIG9mZnNldCBjb3JyZXNwb25kaW5nIHRvIHRoZSBmaXJzdCBVVEYtMzIgYm91bmRhcnkgYXQgCiAgICAgKiBvciBhZnRlciB0aGUgZ2l2ZW4gVVRGLTE2IG9mZnNldC4gVXNlZCBmb3IgcmFuZG9tIGFjY2Vzcy4gU2VlIHRoZSAKICAgICAqIDxhIG5hbWU9Il90b3BfIj5jbGFzcyBkZXNjcmlwdGlvbjwvYT4gZm9yIG5vdGVzIG9uIHJvdW5kdHJpcHBpbmcuPGJyPgogICAgICogPGk+Tm90ZTogSWYgdGhlIFVURi0xNiBvZmZzZXQgaXMgaW50byB0aGUgbWlkZGxlIG9mIGEgc3Vycm9nYXRlIHBhaXIsIAogICAgICogdGhlbiB0aGUgVVRGLTMyIG9mZnNldCBvZiB0aGUgPHN0cm9uZz5sZWFkPC9zdHJvbmc+IG9mIHRoZSBwYWlyIGlzIAogICAgICogcmV0dXJuZWQuCiAgICAgKiA8L2k+CiAgICAgKiA8cD4KICAgICAqIFRvIGZpbmQgdGhlIFVURi0zMiBsZW5ndGggb2YgYSBzdHJpbmcsIHVzZToKICAgICAqICAgPHByZT4KICAgICAqICAgICBsZW4zMiA9IGNvdW50Q29kZVBvaW50KHNvdXJjZSwgc291cmNlLmxlbmd0aCgpKTsKICAgICAqICAgPC9wcmU+CiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGV4dCB0byBhbmFseXNlCiAgICAgKiBAcGFyYW0gb2Zmc2V0MTYgVVRGLTE2IG9mZnNldCA8IHNvdXJjZSB0ZXh0IGxlbmd0aC4KICAgICAqIEByZXR1cm4gVVRGLTMyIG9mZnNldAogICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIG9mZnNldDE2IGlzIG91dCBvZiBib3VuZHMuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgZmluZENvZGVQb2ludE9mZnNldChTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0MTYpIAogICAgewogICAgICAgIGlmIChvZmZzZXQxNiA8IDAgfHwgb2Zmc2V0MTYgPiBzb3VyY2UubGVuZ3RoKCkpIHsKICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQxNik7CiAgICAgICAgfQogICAgICAgICAKICAgICAgICBpbnQgcmVzdWx0ID0gMDsKICAgICAgICBjaGFyIGNoOwogICAgICAgIGJvb2xlYW4gaGFkTGVhZFN1cnJvZ2F0ZSA9IGZhbHNlOwogICAgICAgIAogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2Zmc2V0MTY7ICsrIGkpIAogICAgICAgIHsKICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQXQoaSk7CiAgICAgICAgaWYgKGhhZExlYWRTdXJyb2dhdGUgJiYgaXNUcmFpbFN1cnJvZ2F0ZShjaCkpIHsKICAgICAgICAgICAgaGFkTGVhZFN1cnJvZ2F0ZSA9IGZhbHNlOyAgICAgICAgICAgLy8gY291bnQgdmFsaWQgdHJhaWwgYXMgemVybwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBoYWRMZWFkU3Vycm9nYXRlID0gaXNMZWFkU3Vycm9nYXRlKGNoKTsKICAgICAgICAgICAgKysgcmVzdWx0OyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY291bnQgb3RoZXJzIGFzIDEKICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmIChvZmZzZXQxNiA9PSBzb3VyY2UubGVuZ3RoKCkpIHsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gZW5kIG9mIHNvdXJjZSBiZWluZyB0aGUgbGVzcyBzaWduaWZpY2FudCBzdXJyb2dhdGUgY2hhcmFjdGVyCiAgICAgICAgLy8gc2hpZnQgcmVzdWx0IGJhY2sgdG8gdGhlIHN0YXJ0IG9mIHRoZSBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcgogICAgICAgIGlmIChoYWRMZWFkU3Vycm9nYXRlICYmIChpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQob2Zmc2V0MTYpKSkpIHsKICAgICAgICByZXN1bHQgLS07CiAgICAgICAgfQogICAgICAgICAgCiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgICAgCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIFVURi0zMiBvZmZzZXQgY29ycmVzcG9uZGluZyB0byB0aGUgZmlyc3QgVVRGLTMyIGJvdW5kYXJ5IGF0CiAgICAgKiB0aGUgZ2l2ZW4gVVRGLTE2IG9mZnNldC4gVXNlZCBmb3IgcmFuZG9tIGFjY2Vzcy4gU2VlIHRoZQogICAgICogPGEgbmFtZT0iX3RvcF8iPmNsYXNzIGRlc2NyaXB0aW9uPC9hPiBmb3Igbm90ZXMgb24gcm91bmR0cmlwcGluZy48YnI+CiAgICAgKiA8aT5Ob3RlOiBJZiB0aGUgVVRGLTE2IG9mZnNldCBpcyBpbnRvIHRoZSBtaWRkbGUgb2YgYSBzdXJyb2dhdGUgcGFpciwgCiAgICAgKiB0aGVuIHRoZSBVVEYtMzIgb2Zmc2V0IG9mIHRoZSA8c3Ryb25nPmxlYWQ8L3N0cm9uZz4gb2YgdGhlIHBhaXIgaXMgCiAgICAgKiByZXR1cm5lZC4KICAgICAqIDwvaT4KICAgICAqIDxwPgogICAgICogVG8gZmluZCB0aGUgVVRGLTMyIGxlbmd0aCBvZiBhIHN0cmluZywgdXNlOgogICAgICogICA8cHJlPgogICAgICogICAgIGxlbjMyID0gY291bnRDb2RlUG9pbnQoc291cmNlKTsKICAgICAqICAgPC9wcmU+CiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGV4dCB0byBhbmFseXNlCiAgICAgKiBAcGFyYW0gb2Zmc2V0MTYgVVRGLTE2IG9mZnNldCA8IHNvdXJjZSB0ZXh0IGxlbmd0aC4KICAgICAqIEByZXR1cm4gVVRGLTMyIG9mZnNldAogICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIG9mZnNldDE2IGlzIG91dCBvZiBib3VuZHMuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgZmluZENvZGVQb2ludE9mZnNldChTdHJpbmdCdWZmZXIgc291cmNlLCBpbnQgb2Zmc2V0MTYpCiAgICB7CiAgICAgICAgaWYgKG9mZnNldDE2IDwgMCB8fCBvZmZzZXQxNiA+IHNvdXJjZS5sZW5ndGgoKSkgewogICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDE2KTsKICAgICAgICB9CiAgICAgICAgIAogICAgICAgIGludCByZXN1bHQgPSAwOwogICAgICAgIGNoYXIgY2g7CiAgICAgICAgYm9vbGVhbiBoYWRMZWFkU3Vycm9nYXRlID0gZmFsc2U7CiAgICAgICAgCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvZmZzZXQxNjsgKysgaSkgCiAgICAgICAgewogICAgICAgIGNoID0gc291cmNlLmNoYXJBdChpKTsKICAgICAgICBpZiAoaGFkTGVhZFN1cnJvZ2F0ZSAmJiBpc1RyYWlsU3Vycm9nYXRlKGNoKSkgewogICAgICAgICAgICBoYWRMZWFkU3Vycm9nYXRlID0gZmFsc2U7ICAgICAgICAgICAvLyBjb3VudCB2YWxpZCB0cmFpbCBhcyB6ZXJvCiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGhhZExlYWRTdXJyb2dhdGUgPSBpc0xlYWRTdXJyb2dhdGUoY2gpOwogICAgICAgICAgICArKyByZXN1bHQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb3VudCBvdGhlcnMgYXMgMQogICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKG9mZnNldDE2ID09IHNvdXJjZS5sZW5ndGgoKSkgewogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBlbmQgb2Ygc291cmNlIGJlaW5nIHRoZSBsZXNzIHNpZ25pZmljYW50IHN1cnJvZ2F0ZSBjaGFyYWN0ZXIKICAgICAgICAvLyBzaGlmdCByZXN1bHQgYmFjayB0byB0aGUgc3RhcnQgb2YgdGhlIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyCiAgICAgICAgaWYgKGhhZExlYWRTdXJyb2dhdGUgJiYgKGlzVHJhaWxTdXJyb2dhdGUoc291cmNlLmNoYXJBdChvZmZzZXQxNikpKSkgCiAgICAgICAgewogICAgICAgICAgICByZXN1bHQgLS07CiAgICAgICAgfQogICAgICAgICAgCiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIFVURi0zMiBvZmZzZXQgY29ycmVzcG9uZGluZyB0byB0aGUgZmlyc3QgVVRGLTMyIGJvdW5kYXJ5IGF0CiAgICAgKiB0aGUgZ2l2ZW4gVVRGLTE2IG9mZnNldC4gVXNlZCBmb3IgcmFuZG9tIGFjY2Vzcy4gU2VlIHRoZQogICAgICogPGEgbmFtZT0iX3RvcF8iPmNsYXNzIGRlc2NyaXB0aW9uPC9hPiBmb3Igbm90ZXMgb24gcm91bmR0cmlwcGluZy48YnI+CiAgICAgKiA8aT5Ob3RlOiBJZiB0aGUgVVRGLTE2IG9mZnNldCBpcyBpbnRvIHRoZSBtaWRkbGUgb2YgYSBzdXJyb2dhdGUgcGFpciwgCiAgICAgKiB0aGVuIHRoZSBVVEYtMzIgb2Zmc2V0IG9mIHRoZSA8c3Ryb25nPmxlYWQ8L3N0cm9uZz4gb2YgdGhlIHBhaXIgaXMgCiAgICAgKiByZXR1cm5lZC4KICAgICAqIDwvaT4KICAgICAqIDxwPgogICAgICogVG8gZmluZCB0aGUgVVRGLTMyIGxlbmd0aCBvZiBhIHN1YnN0cmluZywgdXNlOgogICAgICogICA8cHJlPgogICAgICogICAgIGxlbjMyID0gY291bnRDb2RlUG9pbnQoc291cmNlLCBzdGFydCwgbGltaXQpOwogICAgICogICA8L3ByZT4KICAgICAqIDwvcD4KICAgICAqIDxwPgogICAgICogQHBhcmFtIHNvdXJjZSB0ZXh0IHRvIGFuYWx5c2UKICAgICAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgdGhlIHN1YnN0cmluZwogICAgICogQHBhcmFtIGxpbWl0IG9mZnNldCBvZiB0aGUgc3Vic3RyaW5nCiAgICAgICogQHBhcmFtIG9mZnNldDE2IFVURi0xNiByZWxhdGl2ZSB0byBzdGFydAogICAgICogQHJldHVybiBVVEYtMzIgb2Zmc2V0IHJlbGF0aXZlIHRvIHN0YXJ0CiAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgb2Zmc2V0MTYgaXMgbm90IHdpdGhpbiB0aGUgCiAgICAgKiAgICAgICAgICAgIHJhbmdlIG9mIHN0YXJ0IGFuZCBsaW1pdC4KICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBmaW5kQ29kZVBvaW50T2Zmc2V0KGNoYXIgc291cmNlW10sIGludCBzdGFydCwgaW50IGxpbWl0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0MTYpCiAgICB7CiAgICAgICAgb2Zmc2V0MTYgKz0gc3RhcnQ7CiAgICAgICAgaWYgKG9mZnNldDE2ID4gbGltaXQpIHsKICAgICAgICAJdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24ob2Zmc2V0MTYpOwogICAgICAgIH0KICAgICAgICAgCiAgICAgICAgaW50IHJlc3VsdCA9IDA7CiAgICAgICAgY2hhciBjaDsKICAgICAgICBib29sZWFuIGhhZExlYWRTdXJyb2dhdGUgPSBmYWxzZTsKICAgICAgICAKICAgICAgICBmb3IgKGludCBpID0gc3RhcnQ7IGkgPCBvZmZzZXQxNjsgKysgaSkgCiAgICAgICAgewogICAgICAgIAljaCA9IHNvdXJjZVtpXTsKICAgICAgICAJaWYgKGhhZExlYWRTdXJyb2dhdGUgJiYgaXNUcmFpbFN1cnJvZ2F0ZShjaCkpIHsKICAgICAgICAgICAgCWhhZExlYWRTdXJyb2dhdGUgPSBmYWxzZTsgLy8gY291bnQgdmFsaWQgdHJhaWwgYXMgemVybwogICAgICAgIAl9CiAgICAgICAgCWVsc2UKICAgICAgICAJewogICAgICAgICAgICAJaGFkTGVhZFN1cnJvZ2F0ZSA9IGlzTGVhZFN1cnJvZ2F0ZShjaCk7CiAgICAgICAgICAgIAkrKyByZXN1bHQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb3VudCBvdGhlcnMgYXMgMQogICAgICAgIAl9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmIChvZmZzZXQxNiA9PSBsaW1pdCkgewogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBlbmQgb2Ygc291cmNlIGJlaW5nIHRoZSBsZXNzIHNpZ25pZmljYW50IHN1cnJvZ2F0ZSBjaGFyYWN0ZXIKICAgICAgICAvLyBzaGlmdCByZXN1bHQgYmFjayB0byB0aGUgc3RhcnQgb2YgdGhlIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyCiAgICAgICAgaWYgKGhhZExlYWRTdXJyb2dhdGUgJiYgKGlzVHJhaWxTdXJyb2dhdGUoc291cmNlW29mZnNldDE2XSkpKSB7CiAgICAgICAgCXJlc3VsdCAtLTsKICAgICAgICB9CiAgICAgICAgICAKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogQXBwZW5kIGEgc2luZ2xlIFVURi0zMiB2YWx1ZSB0byB0aGUgZW5kIG9mIGEgU3RyaW5nQnVmZmVyLgogICAgICogSWYgYSB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgICogPGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIAogICAgICogY2hhcjMyIGJlZm9yZSBjYWxsaW5nLgogICAgICogQHBhcmFtIGNoYXIzMiB2YWx1ZSB0byBhcHBlbmQuCiAgICAgKiBAcmV0dXJuIHRoZSB1cGRhdGVkIFN0cmluZ0J1ZmZlcgogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdGhyb3duIHdoZW4gY2hhcjMyIGRvZXMgbm90IGxpZSAKICAgICAqICAgICAgICAgICAgd2l0aGluIHRoZSByYW5nZSBvZiB0aGUgVW5pY29kZSBjb2RlcG9pbnRzCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmdCdWZmZXIgYXBwZW5kKFN0cmluZ0J1ZmZlciB0YXJnZXQsIGludCBjaGFyMzIpCiAgICB7CiAgICAgICAgLy8gQ2hlY2sgZm9yIGlycmVndWxhciB2YWx1ZXMKICAgICAgICBpZiAoY2hhcjMyIDwgQ09ERVBPSU5UX01JTl9WQUxVRSB8fCBjaGFyMzIgPiBDT0RFUE9JTlRfTUFYX1ZBTFVFKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklsbGVnYWwgY29kZXBvaW50Iik7CiAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAvLyBXcml0ZSB0aGUgVVRGLTE2IHZhbHVlcwogICAgICAgIGlmIChjaGFyMzIgPj0gU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUpIAogICAgICAgIHsKICAgICAgICAgICAgdGFyZ2V0LmFwcGVuZChnZXRMZWFkU3Vycm9nYXRlKGNoYXIzMikpOwoJICAgICAgICB0YXJnZXQuYXBwZW5kKGdldFRyYWlsU3Vycm9nYXRlKGNoYXIzMikpOwogICAgICAgIH0gCgkgICAgZWxzZSB7CgkgICAgICAgIHRhcmdldC5hcHBlbmQoKGNoYXIpY2hhcjMyKTsKCSAgICB9CgkgICAgcmV0dXJuIHRhcmdldDsKICAgIH0KICAgICAgCiAgICAvKioKICAgICAqIEFkZHMgYSBjb2RlcG9pbnQgdG8gb2Zmc2V0MTYgcG9zaXRpb24gb2YgdGhlIGFyZ3VtZW50IGNoYXIgYXJyYXkuCiAgICAgKiBAcGFyYW0gdGFyZ2V0IGNoYXIgYXJyYXkgdG8gYmUgYXBwZW5kIHdpdGggdGhlIG5ldyBjb2RlIHBvaW50CiAgICAgKiBAcGFyYW0gbGltaXQgVVRGMTYgb2Zmc2V0IHdoaWNoIHRoZSBjb2RlcG9pbnQgd2lsbCBiZSBhcHBlbmRlZC4KICAgICAqIEBwYXJhbSBjaGFyMzIgY29kZSBwb2ludCB0byBiZSBhcHBlbmRlZAogICAgICogQHJldHVybiBvZmZzZXQgYWZ0ZXIgY2hhcjMyIGluIHRoZSBhcnJheS4KICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHRocm93biBpZiB0aGVyZSBpcyBub3QgZW5vdWdoIAogICAgICogICAgICAgICAgICBzcGFjZSBmb3IgdGhlIGFwcGVuZCwgb3Igd2hlbiBjaGFyMzIgZG9lcyBub3QgbGllIHdpdGhpbgogICAgICogICAgICAgICAgICB0aGUgcmFuZ2Ugb2YgdGhlIFVuaWNvZGUgY29kZXBvaW50cy4KICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBhcHBlbmQoY2hhcltdIHRhcmdldCwgaW50IGxpbWl0LCBpbnQgY2hhcjMyKQogICAgewogICAgICAgIC8vIENoZWNrIGZvciBpcnJlZ3VsYXIgdmFsdWVzCiAgICAgICAgaWYgKGNoYXIzMiA8IENPREVQT0lOVF9NSU5fVkFMVUUgfHwgY2hhcjMyID4gQ09ERVBPSU5UX01BWF9WQUxVRSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbGxlZ2FsIGNvZGVwb2ludCIpOwogICAgICAgIH0KICAgICAgICAvLyBXcml0ZSB0aGUgVVRGLTE2IHZhbHVlcwogICAgICAgIGlmIChjaGFyMzIgPj0gU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUpIAogICAgICAgIHsKICAgICAgICAgICAgdGFyZ2V0W2xpbWl0ICsrXSA9IGdldExlYWRTdXJyb2dhdGUoY2hhcjMyKTsKICAgICAgICAgICAgdGFyZ2V0W2xpbWl0ICsrXSA9IGdldFRyYWlsU3Vycm9nYXRlKGNoYXIzMik7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICB0YXJnZXRbbGltaXQgKytdID0gKGNoYXIpY2hhcjMyOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbGltaXQ7CiAgICB9CiAgICAgICAgCiAgICAvKioKICAgICAqIE51bWJlciBvZiBjb2RlcG9pbnRzIGluIGEgVVRGMTYgU3RyaW5nCiAgICAgKiBAcGFyYW0gc291cmNlIFVURjE2IHN0cmluZwogICAgICogQHJldHVybiBudW1iZXIgb2YgY29kZXBvaW50IGluIHN0cmluZwogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvdW50Q29kZVBvaW50KFN0cmluZyBzb3VyY2UpCiAgICB7CiAgICAgICAgaWYgKHNvdXJjZSA9PSBudWxsIHx8IHNvdXJjZS5sZW5ndGgoKSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmluZENvZGVQb2ludE9mZnNldChzb3VyY2UsIHNvdXJjZS5sZW5ndGgoKSk7CiAgICB9CiAgICAgIAogICAgLyoqCiAgICAgKiBOdW1iZXIgb2YgY29kZXBvaW50cyBpbiBhIFVURjE2IFN0cmluZyBidWZmZXIKICAgICAqIEBwYXJhbSBzb3VyY2UgVVRGMTYgc3RyaW5nIGJ1ZmZlcgogICAgICogQHJldHVybiBudW1iZXIgb2YgY29kZXBvaW50IGluIHN0cmluZwogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvdW50Q29kZVBvaW50KFN0cmluZ0J1ZmZlciBzb3VyY2UpCiAgICB7CiAgICAgICAgaWYgKHNvdXJjZSA9PSBudWxsIHx8IHNvdXJjZS5sZW5ndGgoKSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmluZENvZGVQb2ludE9mZnNldChzb3VyY2UsIHNvdXJjZS5sZW5ndGgoKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBOdW1iZXIgb2YgY29kZXBvaW50cyBpbiBhIFVURjE2IGNoYXIgYXJyYXkgc3Vic3RyaW5nCiAgICAgKiBAcGFyYW0gc291cmNlIFVURjE2IGNoYXIgYXJyYXkKICAgICAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgdGhlIHN1YnN0cmluZwogICAgICogQHBhcmFtIGxpbWl0IG9mZnNldCBvZiB0aGUgc3Vic3RyaW5nCiAgICAgKiBAcmV0dXJuIG51bWJlciBvZiBjb2RlcG9pbnQgaW4gdGhlIHN1YnN0cmluZwogICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHN0YXJ0IGFuZCBsaW1pdCBhcmUgbm90IHZhbGlkLgogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvdW50Q29kZVBvaW50KGNoYXIgc291cmNlW10sIGludCBzdGFydCwgaW50IGxpbWl0KQogICAgewogICAgICAgIGlmIChzb3VyY2UgPT0gbnVsbCB8fCBzb3VyY2UubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaW5kQ29kZVBvaW50T2Zmc2V0KHNvdXJjZSwgc3RhcnQsIGxpbWl0LCBsaW1pdCAtIHN0YXJ0KTsKICAgIH0KICAgICAgCiAgICAvKioKICAgICAqIFNldCBhIGNvZGUgcG9pbnQgaW50byBhIFVURjE2IHBvc2l0aW9uLiAKICAgICAqIEFkanVzdHMgdGFyZ2V0IGFjY29yZGluZyBpZiB3ZSBhcmUgcmVwbGFjaW5nIGEgbm9uLXN1cHBsZW1lbnRhcnkgCiAgICAgKiBjb2RlcG9pbnQgd2l0aCBhIHN1cHBsZW1lbnRhcnkgYW5kIHZpY2UgdmVyc2EuCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHN0cmluZ2J1ZmZlcgogICAgICogQHBhcmFtIG9mZnNldDE2IFVURjE2IHBvc2l0aW9uIHRvIGluc2VydCBpbnRvCiAgICAgKiBAcGFyYW0gY2hhcjMyIGNvZGUgcG9pbnQKICAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0Q2hhckF0KFN0cmluZ0J1ZmZlciB0YXJnZXQsIGludCBvZmZzZXQxNiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjaGFyMzIpCiAgICB7CiAgICAgICAgaW50IGNvdW50ID0gMTsKICAgICAgICBjaGFyIHNpbmdsZSA9IHRhcmdldC5jaGFyQXQob2Zmc2V0MTYpOwogICAgICAgIAogICAgICAgIGlmIChpc1N1cnJvZ2F0ZShzaW5nbGUpKSAKICAgICAgICB7CiAgICAgICAgICAgIC8vIHBhaXJzIG9mIHRoZSBzdXJyb2dhdGUgd2l0aCBvZmZzZXQxNiBhdCB0aGUgbGVhZCBjaGFyIGZvdW5kCiAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoc2luZ2xlKSAmJiAodGFyZ2V0Lmxlbmd0aCgpID4gb2Zmc2V0MTYgKyAxKSAKICAgICAgICAgICAgICAgICYmIGlzVHJhaWxTdXJyb2dhdGUodGFyZ2V0LmNoYXJBdChvZmZzZXQxNiArIDEpKSkgewoJICAgICAgICAgICAgY291bnQgKys7CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICAvLyBwYWlycyBvZiB0aGUgc3Vycm9nYXRlIHdpdGggb2Zmc2V0MTYgYXQgdGhlIHRyYWlsIGNoYXIgCgkgICAgICAgICAgICAvLyBmb3VuZAoJICAgICAgICAgICAgaWYgKGlzVHJhaWxTdXJyb2dhdGUoc2luZ2xlKSAmJiAob2Zmc2V0MTYgPiAwKSAmJgoJICAgICAgICAgICAgICAgIGlzTGVhZFN1cnJvZ2F0ZSh0YXJnZXQuY2hhckF0KG9mZnNldDE2IC0xKSkpCgkgICAgICAgICAgICB7CgkgICAgICAgICAgICAgICAgb2Zmc2V0MTYgLS07CgkgICAgICAgICAgICAgICAgY291bnQgKys7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgdGFyZ2V0LnJlcGxhY2Uob2Zmc2V0MTYsIG9mZnNldDE2ICsgY291bnQsIHZhbHVlT2YoY2hhcjMyKSk7CiAgICB9CiAgICAJCiAgICAvKioKICAgICAqIFNldCBhIGNvZGUgcG9pbnQgaW50byBhIFVURjE2IHBvc2l0aW9uIGluIGEgY2hhciBhcnJheS4KICAgICAqIEFkanVzdHMgdGFyZ2V0IGFjY29yZGluZyBpZiB3ZSBhcmUgcmVwbGFjaW5nIGEgbm9uLXN1cHBsZW1lbnRhcnkgCiAgICAgKiBjb2RlcG9pbnQgd2l0aCBhIHN1cHBsZW1lbnRhcnkgYW5kIHZpY2UgdmVyc2EuCiAgICAgKiBAcGFyYW0gdGFyZ2V0IGNoYXIgYXJyYXkKICAgICAqIEBwYXJhbSBsaW1pdCBudW1iZXJzIG9mIHZhbGlkIGNoYXJzIGluIHRhcmdldCwgZGlmZmVyZW50IGZyb20gCiAgICAgKiAgICAgICAgdGFyZ2V0Lmxlbmd0aC4gbGltaXQgY291bnRzIHRoZSBudW1iZXIgb2YgY2hhcnMgaW4gdGFyZ2V0IAogICAgICogICAgICAgIHRoYXQgcmVwcmVzZW50cyBhIHN0cmluZywgbm90IHRoZSBzaXplIG9mIGFycmF5IHRhcmdldC4KICAgICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYxNiBwb3NpdGlvbiB0byBpbnNlcnQgaW50bwogICAgICogQHBhcmFtIGNoYXIzMiBjb2RlIHBvaW50CiAgICAgKiBAcmV0dXJuIG5ldyBudW1iZXIgb2YgY2hhcnMgaW4gdGFyZ2V0IHRoYXQgcmVwcmVzZW50cyBhIHN0cmluZwogICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIG9mZnNldDE2IGlzIG91dCBvZiByYW5nZQogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IHNldENoYXJBdChjaGFyIHRhcmdldFtdLCBpbnQgbGltaXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvZmZzZXQxNiwgaW50IGNoYXIzMikKICAgIHsKICAgICAgICBpZiAob2Zmc2V0MTYgPj0gbGltaXQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQxNik7CiAgICAgICAgfQogICAgICAgIGludCBjb3VudCA9IDE7CiAgICAgICAgY2hhciBzaW5nbGUgPSB0YXJnZXRbb2Zmc2V0MTZdOwogICAgICAgIAogICAgICAgIGlmIChpc1N1cnJvZ2F0ZShzaW5nbGUpKSAKICAgICAgICB7CiAgICAgICAgICAgIC8vIHBhaXJzIG9mIHRoZSBzdXJyb2dhdGUgd2l0aCBvZmZzZXQxNiBhdCB0aGUgbGVhZCBjaGFyIGZvdW5kCiAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoc2luZ2xlKSAmJiAodGFyZ2V0Lmxlbmd0aCA+IG9mZnNldDE2ICsgMSkgJiYKICAgICAgICAgICAgICAgIGlzVHJhaWxTdXJyb2dhdGUodGFyZ2V0W29mZnNldDE2ICsgMV0pKSB7CgkgICAgICAgICAgICBjb3VudCArKzsKCSAgICAgICAgfQoJICAgICAgICBlbHNlIHsKCSAgICAgICAgICAgIC8vIHBhaXJzIG9mIHRoZSBzdXJyb2dhdGUgd2l0aCBvZmZzZXQxNiBhdCB0aGUgdHJhaWwgY2hhciAKCSAgICAgICAgICAgIC8vIGZvdW5kCgkgICAgICAgICAgICBpZiAoaXNUcmFpbFN1cnJvZ2F0ZShzaW5nbGUpICYmIChvZmZzZXQxNiA+IDApICYmCgkgICAgICAgICAgICAgICAgaXNMZWFkU3Vycm9nYXRlKHRhcmdldFtvZmZzZXQxNiAtMV0pKQoJICAgICAgICAgICAgewoJICAgICAgICAgICAgICAgIG9mZnNldDE2IC0tOwoJICAgICAgICAgICAgICAgIGNvdW50ICsrOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQogICAgCSAgCgkgICAgU3RyaW5nIHN0ciA9IHZhbHVlT2YoY2hhcjMyKTsKCSAgICBpbnQgcmVzdWx0ID0gbGltaXQ7CgkgICAgaW50IHN0cmxlbmd0aCA9IHN0ci5sZW5ndGgoKTsKCSAgICB0YXJnZXRbb2Zmc2V0MTZdID0gc3RyLmNoYXJBdCgwKTsKCSAgICBpZiAoY291bnQgPT0gc3RybGVuZ3RoKSB7CgkgICAgICAgIGlmIChjb3VudCA9PSAyKSB7CgkgICAgICAgICAgICB0YXJnZXRbb2Zmc2V0MTYgKyAxXSA9IHN0ci5jaGFyQXQoMSk7CgkgICAgICAgIH0KCSAgICB9CgkgICAgZWxzZSB7CgkgICAgICAgIC8vIHRoaXMgaXMgbm90IGV4YWN0IG1hdGNoIGluIHNwYWNlLCB3ZSdsbCBoYXZlIHRvIGRvIHNvbWUgCgkgICAgICAgIC8vIHNoaWZ0aW5nCgkgICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGFyZ2V0LCBvZmZzZXQxNiArIGNvdW50LCB0YXJnZXQsIAoJICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQxNiArIHN0cmxlbmd0aCwgbGltaXQgLSAob2Zmc2V0MTYgKyBjb3VudCkpOwoJICAgICAgICBpZiAoY291bnQgPCBzdHJsZW5ndGgpIHsKCSAgICAgICAgICAgIC8vIGNoYXIzMiBpcyBhIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIHRyeWluZyB0byBzcXVlZXplIGludG8KCSAgICAgICAgICAgIC8vIGEgbm9uLXN1cHBsZW1lbnRhcnkgc3BhY2UKCSAgICAgICAgICAgIHRhcmdldFtvZmZzZXQxNiArIDFdID0gc3RyLmNoYXJBdCgxKTsKCSAgICAgICAgICAgIHJlc3VsdCArKzsKCSAgICAgICAgICAgIGlmIChyZXN1bHQgPCB0YXJnZXQubGVuZ3RoKSB7CgkgICAgICAgICAgICAgICAgdGFyZ2V0W3Jlc3VsdF0gPSAwOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgLy8gY2hhcjMyIGlzIGEgbm9uLXN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIHRyeWluZyB0byBmaWxsIAoJICAgICAgICAgICAgLy8gaW50byBhIHN1cHBsZW1lbnRhcnkgc3BhY2UKCSAgICAgICAgICAgIHJlc3VsdCAtLTsKCSAgICAgICAgICAgIHRhcmdldFtyZXN1bHRdID0gMDsKCSAgICAgICAgfQoJICAgIH0KCSAgICByZXR1cm4gcmVzdWx0OwogICAgfQogICAgICAKICAgIC8qKgogICAgICogU2hpZnRzIG9mZnNldDE2IGJ5IHRoZSBhcmd1bWVudCBudW1iZXIgb2YgY29kZXBvaW50cwogICAgICogQHBhcmFtIHNvdXJjZSBzdHJpbmcKICAgICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYxNiBwb3NpdGlvbiB0byBzaGlmdAogICAgICogQHBhcmFtIHNoaWZ0MzIgbnVtYmVyIG9mIGNvZGVwb2ludHMgdG8gc2hpZnQKICAgICAqIEByZXR1cm4gbmV3IHNoaWZ0ZWQgb2Zmc2V0MTYgCiAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIG5ldyBvZmZzZXQxNiBpcyBvdXQgb2YgCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm91bmRzLgogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IG1vdmVDb2RlUG9pbnRPZmZzZXQoU3RyaW5nIHNvdXJjZSwgaW50IG9mZnNldDE2LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2hpZnQzMikKICAgIHsKICAgICAgICBpbnQgc2l6ZSA9IHNvdXJjZS5sZW5ndGgoKTsKICAgICAgICBpZiAob2Zmc2V0MTYgPCAwIHx8IHNoaWZ0MzIgKyBvZmZzZXQxNiA+IHNpemUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24ob2Zmc2V0MTYpOwogICAgICAgIH0KICAgICAgICBjaGFyIGNoOwogICAgICAgIGludCByZXN1bHQgPSBvZmZzZXQxNjsKICAgICAgICBpbnQgY291bnQgPSBzaGlmdDMyOwogICAgICAgIHdoaWxlIChyZXN1bHQgPCBzaXplICYmIGNvdW50ID4gMCkKICAgICAgICB7CiAgICAgICAgICAgIGNoID0gc291cmNlLmNoYXJBdChyZXN1bHQpOwogICAgICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKGNoKSAmJiAoKHJlc3VsdCArIDEpIDwgc2l6ZSkgJiYgCiAgICAgICAgICAgICAgICBpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0ICsgMSkpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICBjb3VudCAtLTsKICAgICAgICAgICAgcmVzdWx0ICsrOwogICAgICAgIH0KICAgICAgICBpZiAoY291bnQgIT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihzaGlmdDMyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICAqIFNoaWZ0cyBvZmZzZXQxNiBieSB0aGUgYXJndW1lbnQgbnVtYmVyIG9mIGNvZGVwb2ludHMKICAgICAqIEBwYXJhbSB0YXJnZXQgc3RyaW5nIGJ1ZmZlcgogICAgICogQHBhcmFtIG9mZnNldDE2IFVURjE2IHBvc2l0aW9uIHRvIHNoaWZ0CiAgICAgKiBAcGFyYW0gc2hpZnQzMiBudW1iZXIgb2YgY29kZXBvaW50cyB0byBzaGlmdAogICAgICogQHJldHVybiBuZXcgc2hpZnRlZCBvZmZzZXQxNiAKICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgbmV3IG9mZnNldDE2IGlzIG91dCBvZiAKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3VuZHMuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgbW92ZUNvZGVQb2ludE9mZnNldChTdHJpbmdCdWZmZXIgc291cmNlLCBpbnQgb2Zmc2V0MTYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNoaWZ0MzIpCiAgICB7CiAgICAgICAgaW50IHNpemUgPSBzb3VyY2UubGVuZ3RoKCk7CiAgICAgICAgaWYgKG9mZnNldDE2IDwgMCB8fCBzaGlmdDMyICsgb2Zmc2V0MTYgPiBzaXplKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDE2KTsKICAgICAgICB9CiAgICAgICAgY2hhciBjaDsKICAgICAgICBpbnQgcmVzdWx0ID0gb2Zmc2V0MTY7CiAgICAgICAgaW50IGNvdW50ID0gc2hpZnQzMjsKICAgICAgICB3aGlsZSAocmVzdWx0IDwgc2l6ZSAmJiBjb3VudCA+IDApCiAgICAgICAgewogICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQXQocmVzdWx0KTsKICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgKChyZXN1bHQgKyAxKSA8IHNpemUpICYmIAogICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCArIDEpKSkgewogICAgICAgICAgICAgICAgcmVzdWx0ICsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgY291bnQgLS07CiAgICAgICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50ICE9IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oc2hpZnQzMik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBTaGlmdHMgb2Zmc2V0MTYgYnkgdGhlIGFyZ3VtZW50IG51bWJlciBvZiBjb2RlcG9pbnRzIHdpdGhpbiBhIHN1YmFycmF5LgogICAgICogQHBhcmFtIHRhcmdldCBjaGFyIGFycmF5CiAgICAgKiBAcGFyYW0gc3RhcnQgcG9zaXRpb24gb2YgdGhlIHN1YmFycmF5IHRvIGJlIHBlcmZvcm1lZCBvbgogICAgICogQHBhcmFtIGxpbWl0IHBvc2l0aW9uIG9mIHRoZSBzdWJhcnJheSB0byBiZSBwZXJmb3JtZWQgb24KICAgICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYxNiBwb3NpdGlvbiB0byBzaGlmdCByZWxhdGl2ZSB0byBzdGFydAogICAgICogQHBhcmFtIHNoaWZ0MzIgbnVtYmVyIG9mIGNvZGVwb2ludHMgdG8gc2hpZnQKICAgICAqIEByZXR1cm4gbmV3IHNoaWZ0ZWQgb2Zmc2V0MTYgcmVsYXRpdmUgdG8gc3RhcnQKICAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgbmV3IG9mZnNldDE2IGlzIG91dCBvZiAKICAgICAqICAgICAgICAgICAgYm91bmRzIHdpdGggcmVzcGVjdCB0byB0aGUgc3ViYXJyYXkuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgbW92ZUNvZGVQb2ludE9mZnNldChjaGFyIHNvdXJjZVtdLCBpbnQgc3RhcnQsIGludCBsaW1pdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvZmZzZXQxNiwgaW50IHNoaWZ0MzIpCiAgICB7CiAgICAgICAgb2Zmc2V0MTYgKz0gc3RhcnQ7CiAgICAgICAgaWYgKHNoaWZ0MzIgKyBvZmZzZXQxNiA+IGxpbWl0KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDE2KTsKICAgICAgICB9CiAgICAgICAgY2hhciBjaDsKICAgICAgICBpbnQgcmVzdWx0ID0gb2Zmc2V0MTY7CiAgICAgICAgaW50IGNvdW50ID0gc2hpZnQzMjsKICAgICAgICB3aGlsZSAocmVzdWx0IDwgbGltaXQgJiYgY291bnQgPiAwKQogICAgICAgIHsKICAgICAgICAgICAgY2ggPSBzb3VyY2VbcmVzdWx0XTsKICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgKChyZXN1bHQgKyAxKSA8IGxpbWl0KSAmJiAKICAgICAgICAgICAgICAgIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlW3Jlc3VsdCArIDFdKSkgewogICAgICAgICAgICAgICAgcmVzdWx0ICsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgY291bnQgLS07CiAgICAgICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50ICE9IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oc2hpZnQzMik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQgLSBzdGFydDsKICAgIH0KICAgICAgCiAgICAvKioKICAgICAqIEluc2VydHMgY2hhcjMyIGNvZGVwb2ludCBpbnRvIHRhcmdldCBhdCB0aGUgYXJndW1lbnQgb2Zmc2V0MTYuIAogICAgICogSWYgdGhlIG9mZnNldDE2IGlzIGluIHRoZSBtaWRkbGUgb2YgYSBzdXBwbGVtZW50YXJ5IGNvZGVwb2ludCwgY2hhcjMyIAogICAgICogd2lsbCBiZSBpbnNlcnRlZCBhZnRlciB0aGUgc3VwcGxlbWVudGFyeSBjb2RlcG9pbnQuCiAgICAgKiBUaGUgbGVuZ3RoIG9mIHRhcmdldCBpbmNyZWFzZXMgYnkgb25lIGlmIGNvZGVwb2ludCBpcyBub24tc3VwcGxlbWVudGFyeSwgCiAgICAgKiAyIG90aGVyd2lzZS4gCiAgICAgKiA8cD4KICAgICAqIFRoZSBvdmVyYWxsIGVmZmVjdCBpcyBleGFjdGx5IGFzIGlmIHRoZSBhcmd1bWVudCB3ZXJlIGNvbnZlcnRlZCB0byBhIAogICAgICogc3RyaW5nIGJ5IHRoZSBtZXRob2QgdmFsdWVPZihjaGFyKSBhbmQgdGhlIGNoYXJhY3RlcnMgaW4gdGhhdCBzdHJpbmcgCiAgICAgKiB3ZXJlIHRoZW4gaW5zZXJ0ZWQgaW50byB0YXJnZXQgYXQgdGhlIHBvc2l0aW9uIGluZGljYXRlZCBieSBvZmZzZXQxNi4gCiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIFRoZSBvZmZzZXQgYXJndW1lbnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMCwgYW5kIGxlc3MgdGhhbiAKICAgICAqIG9yIGVxdWFsIHRvIHRoZSBsZW5ndGggb2Ygc291cmNlLgogICAgICogQHBhcmFtIHRhcmdldCBzdHJpbmcgYnVmZmVyIHRvIGluc2VydCB0bwogICAgICogQHBhcmFtIG9mZnNldDE2IG9mZnNldCB3aGljaCBjaGFyMzIgd2lsbCBiZSBpbnNlcnRlZCBpbgogICAgICogQHBhcmFtIGNoYXIzMiBjb2RlcG9pbnQgdG8gYmUgaW5zZXJ0ZWQKICAgICAqIEByZXR1cm4gYSByZWZlcmVuY2UgdG8gdGFyZ2V0CiAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gdGhyb3duIGlmIG9mZnNldDE2IGlzIGludmFsaWQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmdCdWZmZXIgaW5zZXJ0KFN0cmluZ0J1ZmZlciB0YXJnZXQsIGludCBvZmZzZXQxNiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhcjMyKQogICAgewogICAgICAgIFN0cmluZyBzdHIgPSB2YWx1ZU9mKGNoYXIzMik7CiAgICAgICAgaWYgKG9mZnNldDE2ICE9IHRhcmdldC5sZW5ndGgoKSAmJiAKICAgICAgICAgICAgYm91bmRzKHRhcmdldCwgb2Zmc2V0MTYpID09IFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWSkgewogICAgICAgICAgICBvZmZzZXQxNiArKzsKICAgICAgICB9CiAgICAgICAgdGFyZ2V0Lmluc2VydChvZmZzZXQxNiwgc3RyKTsKICAgICAgICByZXR1cm4gdGFyZ2V0OwogICAgfQoKICAgIC8qKgogICAgICogSW5zZXJ0cyBjaGFyMzIgY29kZXBvaW50IGludG8gdGFyZ2V0IGF0IHRoZSBhcmd1bWVudCBvZmZzZXQxNi4gCiAgICAgKiBJZiB0aGUgb2Zmc2V0MTYgaXMgaW4gdGhlIG1pZGRsZSBvZiBhIHN1cHBsZW1lbnRhcnkgY29kZXBvaW50LCBjaGFyMzIgCiAgICAgKiB3aWxsIGJlIGluc2VydGVkIGFmdGVyIHRoZSBzdXBwbGVtZW50YXJ5IGNvZGVwb2ludC4KICAgICAqIExpbWl0IGluY3JlYXNlcyBieSBvbmUgaWYgY29kZXBvaW50IGlzIG5vbi1zdXBwbGVtZW50YXJ5LCAyIG90aGVyd2lzZS4gCiAgICAgKiA8cD4KICAgICAqIFRoZSBvdmVyYWxsIGVmZmVjdCBpcyBleGFjdGx5IGFzIGlmIHRoZSBhcmd1bWVudCB3ZXJlIGNvbnZlcnRlZCB0byBhIAogICAgICogc3RyaW5nIGJ5IHRoZSBtZXRob2QgdmFsdWVPZihjaGFyKSBhbmQgdGhlIGNoYXJhY3RlcnMgaW4gdGhhdCBzdHJpbmcgCiAgICAgKiB3ZXJlIHRoZW4gaW5zZXJ0ZWQgaW50byB0YXJnZXQgYXQgdGhlIHBvc2l0aW9uIGluZGljYXRlZCBieSBvZmZzZXQxNi4gCiAgICAgKiA8L3A+CiAgICAgKiA8cD4KICAgICAqIFRoZSBvZmZzZXQgYXJndW1lbnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMCwgYW5kIGxlc3MgdGhhbiAKICAgICAqIG9yIGVxdWFsIHRvIHRoZSBsaW1pdC4KICAgICAqIEBwYXJhbSB0YXJnZXQgY2hhciBhcnJheSB0byBpbnNlcnQgdG8KICAgICAqIEBwYXJhbSBsaW1pdCBlbmQgaW5kZXggb2YgdGhlIGNoYXIgYXJyYXksIGxpbWl0IDw9IHRhcmdldC5sZW5ndGgKICAgICAqIEBwYXJhbSBvZmZzZXQxNiBvZmZzZXQgd2hpY2ggY2hhcjMyIHdpbGwgYmUgaW5zZXJ0ZWQgaW4KICAgICAqIEBwYXJhbSBjaGFyMzIgY29kZXBvaW50IHRvIGJlIGluc2VydGVkCiAgICAgKiBAcmV0dXJuIG5ldyBsaW1pdCBzaXplCiAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gdGhyb3duIGlmIG9mZnNldDE2IGlzIGludmFsaWQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgaW5zZXJ0KGNoYXIgdGFyZ2V0W10sIGludCBsaW1pdCwgaW50IG9mZnNldDE2LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhcjMyKQogICAgewogICAgICAgIFN0cmluZyBzdHIgPSB2YWx1ZU9mKGNoYXIzMik7CiAgICAgICAgaWYgKG9mZnNldDE2ICE9IGxpbWl0ICYmCiAgICAgICAgICAgIGJvdW5kcyh0YXJnZXQsIDAsIGxpbWl0LCBvZmZzZXQxNikgPT0gVFJBSUxfU1VSUk9HQVRFX0JPVU5EQVJZKSB7CiAgICAgICAgICAgIG9mZnNldDE2ICsrOwogICAgICAgIH0KICAgICAgICBpbnQgc2l6ZSA9IHN0ci5sZW5ndGgoKTsKICAgICAgICBpZiAobGltaXQgKyBzaXplID4gdGFyZ2V0Lmxlbmd0aCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDE2ICsgc2l6ZSk7CiAgICAgICAgfQogICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGFyZ2V0LCBvZmZzZXQxNiwgdGFyZ2V0LCBvZmZzZXQxNiArIHNpemUsIAogICAgICAgICAgICAgICAgICAgICAgICBsaW1pdCAtIG9mZnNldDE2KTsKICAgICAgICB0YXJnZXRbb2Zmc2V0MTZdID0gc3RyLmNoYXJBdCgwKTsKICAgICAgICBpZiAoc2l6ZSA9PSAyKSB7CiAgICAgICAgICAgIHRhcmdldFtvZmZzZXQxNiArIDFdID0gc3RyLmNoYXJBdCgxKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxpbWl0ICsgc2l6ZTsKICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgdGhlIGNvZGVwb2ludCBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uIGluIHRoaXMgdGFyZ2V0IAogICAgICogKHNob3J0ZW5pbmcgdGFyZ2V0IGJ5IDEgY2hhcmFjdGVyIGlmIHRoZSBjb2RlcG9pbnQgaXMgYSAKICAgICAqIG5vbi1zdXBwbGVtZW50YXJ5LCAyIG90aGVyd2lzZSkuCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHN0cmluZyBidWZmZXIgdG8gcmVtb3ZlIGNvZGVwb2ludCBmcm9tCiAgICAgKiBAcGFyYW0gb2Zmc2V0MTYgb2Zmc2V0IHdoaWNoIHRoZSBjb2RlcG9pbnQgd2lsbCBiZSByZW1vdmVkCiAgICAgKiBAcmV0dXJuIGEgcmVmZXJlbmNlIHRvIHRhcmdldAogICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHRocm93biBpZiBvZmZzZXQxNiBpcyBpbnZhbGlkLgogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nQnVmZmVyIGRlbGV0ZShTdHJpbmdCdWZmZXIgdGFyZ2V0LCBpbnQgb2Zmc2V0MTYpCiAgICB7CiAgICAgICAgaW50IGNvdW50ID0gMTsKICAgICAgICBzd2l0Y2ggKGJvdW5kcyh0YXJnZXQsIG9mZnNldDE2KSkgewogICAgICAgICAgICBjYXNlIExFQURfU1VSUk9HQVRFX0JPVU5EQVJZOiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCArKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBUUkFJTF9TVVJST0dBVEVfQk9VTkRBUlk6IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDE2IC0tOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICB0YXJnZXQuZGVsZXRlKG9mZnNldDE2LCBvZmZzZXQxNiArIGNvdW50KTsKICAgICAgICByZXR1cm4gdGFyZ2V0OwogICAgfQoKICAgIC8qKgogICAgICogUmVtb3ZlcyB0aGUgY29kZXBvaW50IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4gdGhpcyB0YXJnZXQgCiAgICAgKiAoc2hvcnRlbmluZyB0YXJnZXQgYnkgMSBjaGFyYWN0ZXIgaWYgdGhlIGNvZGVwb2ludCBpcyBhIAogICAgICogbm9uLXN1cHBsZW1lbnRhcnksIDIgb3RoZXJ3aXNlKS4KICAgICAqIEBwYXJhbSB0YXJnZXQgc3RyaW5nIGJ1ZmZlciB0byByZW1vdmUgY29kZXBvaW50IGZyb20KICAgICAqIEBwYXJhbSBsaW1pdCBlbmQgaW5kZXggb2YgdGhlIGNoYXIgYXJyYXksIGxpbWl0IDw9IHRhcmdldC5sZW5ndGgKICAgICAqIEBwYXJhbSBvZmZzZXQxNiBvZmZzZXQgd2hpY2ggdGhlIGNvZGVwb2ludCB3aWxsIGJlIHJlbW92ZWQKICAgICAqIEByZXR1cm4gYSBuZXcgbGltaXQgc2l6ZQogICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHRocm93biBpZiBvZmZzZXQxNiBpcyBpbnZhbGlkLgogICAgICogQHN0YWJsZSBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGRlbGV0ZShjaGFyIHRhcmdldFtdLCBpbnQgbGltaXQsIGludCBvZmZzZXQxNikKICAgIHsKICAgICAgICBpbnQgY291bnQgPSAxOwogICAgICAgIHN3aXRjaCAoYm91bmRzKHRhcmdldCwgMCwgbGltaXQsIG9mZnNldDE2KSkgewogICAgICAgICAgICBjYXNlIExFQURfU1VSUk9HQVRFX0JPVU5EQVJZOiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCArKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBUUkFJTF9TVVJST0dBVEVfQk9VTkRBUlk6IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDE2IC0tOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRhcmdldCwgb2Zmc2V0MTYgKyBjb3VudCwgdGFyZ2V0LCBvZmZzZXQxNiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0IC0gKG9mZnNldDE2ICsgY291bnQpKTsKICAgICAgICB0YXJnZXRbbGltaXQgLSBjb3VudF0gPSAwOwogICAgICAgIHJldHVybiBsaW1pdCAtIGNvdW50OwogICAgfQogICAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoZSBhcmd1bWVudCBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgb2YgCiAgICAgKiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgYXJndW1lbnQgY29kZXBvaW50LiBJLmUuLCB0aGUgc21hbGxlc3QgCiAgICAgKiBpbmRleCA8Y29kZT5pPC9jb2RlPiBzdWNoIHRoYXQgPGNvZGU+VVRGMTYuY2hhckF0KHNvdXJjZSwgaSkgPT0gCiAgICAgKiBjaGFyMzI8L2NvZGU+IGlzIHRydWUuIAogICAgICogPHA+SWYgbm8gc3VjaCBjaGFyYWN0ZXIgb2NjdXJzIGluIHRoaXMgc3RyaW5nLCB0aGVuIC0xIGlzIHJldHVybmVkLjwvcD4gCiAgICAgKiA8cD4gCiAgICAgKiBFeGFtcGxlczo8YnI+CiAgICAgKiBVVEYxNi5pbmRleE9mKCJhYmMiLCAnYScpIHJldHVybnMgMDxicj4KICAgICAqIFVURjE2LmluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsIDB4MTAwMDApIHJldHVybnMgMzxicj4KICAgICAqIFVURjE2LmluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsIDB4ZDgwMCkgcmV0dXJucyAtMTxicj4KICAgICAqIDwvcD4KICAgICAqIE5vdGUgdGhpcyBtZXRob2QgaXMgcHJvdmlkZWQgYXMgc3VwcG9ydCB0byBqZGsgMS4zLCB3aGljaCBkb2VzIG5vdCAKICAgICAqIHN1cHBvcnQgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHRvIGl0cyBmdWxsZXN0LgogICAgICogQHBhcmFtIHNvdXJjZSBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgdGhhdCB3aWxsIGJlIHNlYXJjaGVkCiAgICAgKiBAcGFyYW0gY2hhcjMyIGNvZGVwb2ludCB0byBzZWFyY2ggZm9yIAogICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGNvZGVwb2ludCBpbiB0aGUgCiAgICAgKiAgICAgICAgIGFyZ3VtZW50IFVuaWNvZGUgc3RyaW5nLCBvciAtMSBpZiB0aGUgY29kZXBvaW50IGRvZXMgbm90IG9jY3VyLgogICAgICogQGRyYWZ0IElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgaW5kZXhPZihTdHJpbmcgc291cmNlLCBpbnQgY2hhcjMyKSAgCiAgICB7CiAgICAgICAgaWYgKGNoYXIzMiA8IENPREVQT0lOVF9NSU5fVkFMVUUgfHwgCiAgICAgICAgICAgIGNoYXIzMiA+IENPREVQT0lOVF9NQVhfVkFMVUUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBcmd1bWVudCBjaGFyMzIgaXMgbm90IGEgdmFsaWQgY29kZXBvaW50Iik7CiAgICAgICAgfQogICAgICAgIC8vIG5vbi1zdXJyb2dhdGUgYm1wCiAgICAgICAgaWYgKGNoYXIzMiA8IExFQURfU1VSUk9HQVRFX01JTl9WQUxVRSB8fAogICAgICAgICAgICAoY2hhcjMyID4gVFJBSUxfU1VSUk9HQVRFX01BWF9WQUxVRSAmJiAKICAgICAgICAgICAgIGNoYXIzMiA8IFNVUFBMRU1FTlRBUllfTUlOX1ZBTFVFKSkgewogICAgICAgICAgICByZXR1cm4gc291cmNlLmluZGV4T2YoKGNoYXIpY2hhcjMyKTsKICAgICAgICB9CiAgICAgICAgLy8gc3Vycm9nYXRlCiAgICAgICAgaWYgKGNoYXIzMiA8IFNVUFBMRU1FTlRBUllfTUlOX1ZBTFVFKSB7CiAgICAgICAgICAgIGludCByZXN1bHQgPSBzb3VyY2UuaW5kZXhPZigoY2hhciljaGFyMzIpOwogICAgICAgICAgICBpZiAocmVzdWx0ID49IDApIHsKICAgICAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoKGNoYXIpY2hhcjMyKSAmJiAKICAgICAgICAgICAgICAgICAgICAocmVzdWx0IDwgc291cmNlLmxlbmd0aCgpIC0gMSkgJiYgCiAgICAgICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCArIDEpKSkgeyAKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXhPZihzb3VyY2UsIGNoYXIzMiwgcmVzdWx0ICsgMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyB0cmFpbCBzdXJyb2dhdGUKICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPiAwICYmIAogICAgICAgICAgICAgICAgICAgIGlzTGVhZFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCAtIDEpKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmRleE9mKHNvdXJjZSwgY2hhcjMyLCByZXN1bHQgKyAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgLy8gc3VwcGxlbWVudGFyeQogICAgICAgIFN0cmluZyBjaGFyMzJzdHIgPSB0b1N0cmluZyhjaGFyMzIpOwogICAgICAgIHJldHVybiBzb3VyY2UuaW5kZXhPZihjaGFyMzJzdHIpOwogICAgfQogICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFyZ3VtZW50IFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyBvZiAKICAgICAqIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBzdHJpbmcgc3RyLiBUaGlzIG1ldGhvZCBpcyAKICAgICAqIGltcGxlbWVudGVkIGJhc2VkIG9uIGNvZGVwb2ludHMsIGhlbmNlIGEgImxlYWQgc3Vycm9nYXRlIGNoYXJhY3RlciArCiAgICAgKiB0cmFpbCBzdXJyb2dhdGUgY2hhcmFjdGVyIiBpcyB0cmVhdGVkIGFzIG9uZSBlbnRpdHkuZQogICAgICogSGVuY2UgaWYgdGhlIHN0ciBzdGFydHMgd2l0aCB0cmFpbCBzdXJyb2dhdGUgY2hhcmFjdGVyIGF0IGluZGV4IDAsIGEgCiAgICAgKiBzb3VyY2Ugd2l0aCBhIGxlYWRpbmcgYSBzdXJyb2dhdGUgY2hhcmFjdGVyIGJlZm9yZSBzdHIgZm91bmQgYXQgaW4gCiAgICAgKiBzb3VyY2Ugd2lsbCBub3QgaGF2ZSBhIHZhbGlkIG1hdGNoLiBWaWNlIHZlcnNhIGZvciBsZWFkIHN1cnJvZ2F0ZXMgCiAgICAgKiB0aGF0IGVuZHMgc3RyLgogICAgICogU2VlIGV4YW1wbGUgYmVsb3cuCiAgICAgKiA8cD5JZiBubyBzdWNoIHN0cmluZyBzdHIgb2NjdXJzIGluIHRoaXMgc291cmNlLCB0aGVuIC0xIGlzIHJldHVybmVkLgogICAgICogPC9wPiA8cD4KICAgICAqIEV4YW1wbGVzOjxicj4KICAgICAqIFVURjE2LmluZGV4T2YoImFiYyIsICJhYiIpIHJldHVybnMgMDxicj4KICAgICAqIFVURjE2LmluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsICJcdWQ4MDBcdWRjMDAiKSByZXR1cm5zIDM8YnI+CiAgICAgKiBVVEYxNi5pbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAiXHVkODAwIikgcmV0dXJucyAtMTxicj4KICAgICAqIDwvcD4KICAgICAqIE5vdGUgdGhpcyBtZXRob2QgaXMgcHJvdmlkZWQgYXMgc3VwcG9ydCB0byBqZGsgMS4zLCB3aGljaCBkb2VzIG5vdCAKICAgICAqIHN1cHBvcnQgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHRvIGl0cyBmdWxsZXN0LgogICAgICogQHBhcmFtIHNvdXJjZSBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgdGhhdCB3aWxsIGJlIHNlYXJjaGVkCiAgICAgKiBAcGFyYW0gc3RyIFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyB0byBzZWFyY2ggZm9yCiAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY29kZXBvaW50IGluIHRoZSAKICAgICAqICAgICAgICAgYXJndW1lbnQgVW5pY29kZSBzdHJpbmcsIG9yIC0xIGlmIHRoZSBjb2RlcG9pbnQgZG9lcyBub3Qgb2NjdXIuCiAgICAgKiBAZHJhZnQgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBpbmRleE9mKFN0cmluZyBzb3VyY2UsIFN0cmluZyBzdHIpICAKICAgIHsKICAgICAgICBpbnQgc3RyTGVuZ3RoID0gc3RyLmxlbmd0aCgpOwogICAgICAgIC8vIG5vbi1zdXJyb2dhdGUgZW5kcwogICAgICAgIGlmICghaXNUcmFpbFN1cnJvZ2F0ZShzdHIuY2hhckF0KDApKSAmJiAKICAgICAgICAgICAgIWlzTGVhZFN1cnJvZ2F0ZShzdHIuY2hhckF0KHN0ckxlbmd0aCAtIDEpKSkgewogICAgICAgICAgICByZXR1cm4gc291cmNlLmluZGV4T2Yoc3RyKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaW50IHJlc3VsdCAgICA9IHNvdXJjZS5pbmRleE9mKHN0cik7CiAgICAgICAgaW50IHJlc3VsdEVuZCA9IHJlc3VsdCArIHN0ckxlbmd0aDsKICAgICAgICBpZiAocmVzdWx0ID49IDApIHsKICAgICAgICAgICAgLy8gY2hlY2sgbGFzdCBjaGFyYWN0ZXIKICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShzdHIuY2hhckF0KHN0ckxlbmd0aCAtIDEpKSAmJiAKICAgICAgICAgICAgICAgIChyZXN1bHQgPCBzb3VyY2UubGVuZ3RoKCkgLSAxKSAmJiAKICAgICAgICAgICAgICAgIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlLmNoYXJBdChyZXN1bHRFbmQgKyAxKSkpIHsgCiAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXhPZihzb3VyY2UsIHN0ciwgcmVzdWx0RW5kICsgMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gY2hlY2sgZmlyc3QgY2hhcmFjdGVyIHdoaWNoIGlzIGEgdHJhaWwgc3Vycm9nYXRlCiAgICAgICAgICAgIGlmIChpc1RyYWlsU3Vycm9nYXRlKHN0ci5jaGFyQXQoMCkpICYmIHJlc3VsdCA+IDAgJiYgCiAgICAgICAgICAgICAgICBpc0xlYWRTdXJyb2dhdGUoc291cmNlLmNoYXJBdChyZXN1bHQgLSAxKSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpbmRleE9mKHNvdXJjZSwgc3RyLCByZXN1bHRFbmQgKyAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFyZ3VtZW50IFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyBvZiAKICAgICAqIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBjb2RlcG9pbnQuIEkuZS4sIHRoZSBzbWFsbGVzdCAKICAgICAqIGluZGV4IGkgc3VjaCB0aGF0OiA8YnI+CiAgICAgKiAoVVRGMTYuY2hhckF0KHNvdXJjZSwgaSkgPT0gY2hhcjMyICYmIGkgPj0gZnJvbUluZGV4KSBpcyB0cnVlLiAKICAgICAqIDxwPklmIG5vIHN1Y2ggY2hhcmFjdGVyIG9jY3VycyBpbiB0aGlzIHN0cmluZywgdGhlbiAtMSBpcyByZXR1cm5lZC48L3A+IAogICAgICogPHA+CiAgICAgKiBFeGFtcGxlczo8YnI+CiAgICAgKiBVVEYxNi5pbmRleE9mKCJhYmMiLCAnYScsIDEpIHJldHVybnMgLTE8YnI+CiAgICAgKiBVVEYxNi5pbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAweDEwMDAwLCAxKSByZXR1cm5zIDM8YnI+CiAgICAgKiBVVEYxNi5pbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAweGQ4MDAsIDEpIHJldHVybnMgLTE8YnI+CiAgICAgKiA8L3A+CiAgICAgKiBOb3RlIHRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGFzIHN1cHBvcnQgdG8gamRrIDEuMywgd2hpY2ggZG9lcyBub3QgCiAgICAgKiBzdXBwb3J0IHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycyB0byBpdHMgZnVsbGVzdC4KICAgICAqIEBwYXJhbSBzb3VyY2UgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIHRoYXQgd2lsbCBiZSBzZWFyY2hlZAogICAgICogQHBhcmFtIGNoYXIzMiBjb2RlcG9pbnQgdG8gc2VhcmNoIGZvciAKICAgICAqIEBwYXJhbSBmcm9tSW5kZXggdGhlIGluZGV4IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbS4gCiAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY29kZXBvaW50IGluIHRoZSAKICAgICAqICAgICAgICAgYXJndW1lbnQgVW5pY29kZSBzdHJpbmcgYXQgb3IgYWZ0ZXIgZnJvbUluZGV4LCBvciAtMSBpZiB0aGUgCiAgICAgKiAgICAgICAgIGNvZGVwb2ludCBkb2VzIG5vdCBvY2N1ci4KICAgICAqIEBkcmFmdCBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGluZGV4T2YoU3RyaW5nIHNvdXJjZSwgaW50IGNoYXIzMiwgaW50IGZyb21JbmRleCkgCiAgICB7CiAgICAgICAgaWYgKGNoYXIzMiA8IENPREVQT0lOVF9NSU5fVkFMVUUgfHwgY2hhcjMyID4gQ09ERVBPSU5UX01BWF9WQUxVRSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFyZ3VtZW50IGNoYXIzMiBpcyBub3QgYSB2YWxpZCBjb2RlcG9pbnQiKTsKICAgICAgICB9CiAgICAgICAgLy8gbm9uLXN1cnJvZ2F0ZSBibXAKICAgICAgICBpZiAoY2hhcjMyIDwgTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFIHx8CiAgICAgICAgICAgIChjaGFyMzIgPiBUUkFJTF9TVVJST0dBVEVfTUFYX1ZBTFVFICYmIAogICAgICAgICAgICAgY2hhcjMyIDwgU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUpKSB7CiAgICAgICAgICAgIHJldHVybiBzb3VyY2UuaW5kZXhPZigoY2hhciljaGFyMzIsIGZyb21JbmRleCk7CiAgICAgICAgfQogICAgICAgIC8vIHN1cnJvZ2F0ZQogICAgICAgIGlmIChjaGFyMzIgPCBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkgewogICAgICAgICAgICBpbnQgcmVzdWx0ID0gc291cmNlLmluZGV4T2YoKGNoYXIpY2hhcjMyLCBmcm9tSW5kZXgpOwogICAgICAgICAgICBpZiAocmVzdWx0ID49IDApIHsKICAgICAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoKGNoYXIpY2hhcjMyKSAmJiAKICAgICAgICAgICAgICAgICAgICAocmVzdWx0IDwgc291cmNlLmxlbmd0aCgpIC0gMSkgJiYgCiAgICAgICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCArIDEpKSkgeyAKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXhPZihzb3VyY2UsIGNoYXIzMiwgcmVzdWx0ICsgMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyB0cmFpbCBzdXJyb2dhdGUKICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPiAwICYmIAogICAgICAgICAgICAgICAgICAgIGlzTGVhZFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCAtIDEpKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmRleE9mKHNvdXJjZSwgY2hhcjMyLCByZXN1bHQgKyAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgLy8gc3VwcGxlbWVudGFyeQogICAgICAgIFN0cmluZyBjaGFyMzJzdHIgPSB0b1N0cmluZyhjaGFyMzIpOwogICAgICAgIHJldHVybiBzb3VyY2UuaW5kZXhPZihjaGFyMzJzdHIsIGZyb21JbmRleCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFyZ3VtZW50IFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyBvZiAKICAgICAqIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBzdHJpbmcgc3RyLiBUaGlzIG1ldGhvZCBpcyAKICAgICAqIGltcGxlbWVudGVkIGJhc2VkIG9uIGNvZGVwb2ludHMsIGhlbmNlIGEgImxlYWQgc3Vycm9nYXRlIGNoYXJhY3RlciArCiAgICAgKiB0cmFpbCBzdXJyb2dhdGUgY2hhcmFjdGVyIiBpcyB0cmVhdGVkIGFzIG9uZSBlbnRpdHkuZQogICAgICogSGVuY2UgaWYgdGhlIHN0ciBzdGFydHMgd2l0aCB0cmFpbCBzdXJyb2dhdGUgY2hhcmFjdGVyIGF0IGluZGV4IDAsIGEgCiAgICAgKiBzb3VyY2Ugd2l0aCBhIGxlYWRpbmcgYSBzdXJyb2dhdGUgY2hhcmFjdGVyIGJlZm9yZSBzdHIgZm91bmQgYXQgaW4gICAKICAgICAqIHNvdXJjZSB3aWxsIG5vdCBoYXZlIGEgdmFsaWQgbWF0Y2guIFZpY2UgdmVyc2EgZm9yIGxlYWQgc3Vycm9nYXRlcyAgIAogICAgICogdGhhdCBlbmRzIHN0ci4KICAgICAqIFNlZSBleGFtcGxlIGJlbG93LgogICAgICogPHA+SWYgbm8gc3VjaCBzdHJpbmcgc3RyIG9jY3VycyBpbiB0aGlzIHNvdXJjZSwgdGhlbiAtMSBpcyByZXR1cm5lZC4KICAgICAqIDwvcD4gPHA+CiAgICAgKiBFeGFtcGxlczo8YnI+CiAgICAgKiBVVEYxNi5pbmRleE9mKCJhYmMiLCAiYWIiLCAwKSByZXR1cm5zIDA8YnI+CiAgICAgKiBVVEYxNi5pbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAiXHVkODAwXHVkYzAwIiwgMCkgcmV0dXJucyAzPGJyPgogICAgICogVVRGMTYuaW5kZXhPZigiYWJjXHVkODAwXHVkYzAwIiwgIlx1ZDgwMFx1ZGMwMCIsIDIpIHJldHVybnMgMzxicj4gCiAgICAgKiBVVEYxNi5pbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAiXHVkODAwIiwgMCkgcmV0dXJucyAtMTxicj4KICAgICAqIDwvcD4KICAgICAqIE5vdGUgdGhpcyBtZXRob2QgaXMgcHJvdmlkZWQgYXMgc3VwcG9ydCB0byBqZGsgMS4zLCB3aGljaCBkb2VzIG5vdCAKICAgICAqIHN1cHBvcnQgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHRvIGl0cyBmdWxsZXN0LgogICAgICogQHBhcmFtIHNvdXJjZSBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgdGhhdCB3aWxsIGJlIHNlYXJjaGVkCiAgICAgKiBAcGFyYW0gc3RyIFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyB0byBzZWFyY2ggZm9yCiAgICAgKiBAcGFyYW0gZnJvbUluZGV4IHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uIAogICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGNvZGVwb2ludCBpbiB0aGUgCiAgICAgKiAgICAgICAgIGFyZ3VtZW50IFVuaWNvZGUgc3RyaW5nLCBvciAtMSBpZiB0aGUgY29kZXBvaW50IGRvZXMgbm90IG9jY3VyLgogICAgICogQGRyYWZ0IElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgaW5kZXhPZihTdHJpbmcgc291cmNlLCBTdHJpbmcgc3RyLCBpbnQgZnJvbUluZGV4KSAgCiAgICB7CiAgICAgICAgaW50IHN0ckxlbmd0aCA9IHN0ci5sZW5ndGgoKTsKICAgICAgICAvLyBub24tc3Vycm9nYXRlIGVuZHMKICAgICAgICBpZiAoIWlzVHJhaWxTdXJyb2dhdGUoc3RyLmNoYXJBdCgwKSkgJiYgCiAgICAgICAgICAgICFpc0xlYWRTdXJyb2dhdGUoc3RyLmNoYXJBdChzdHJMZW5ndGggLSAxKSkpIHsKICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5pbmRleE9mKHN0ciwgZnJvbUluZGV4KTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaW50IHJlc3VsdCAgICA9IHNvdXJjZS5pbmRleE9mKHN0ciwgZnJvbUluZGV4KTsKICAgICAgICBpbnQgcmVzdWx0RW5kID0gcmVzdWx0ICsgc3RyTGVuZ3RoOwogICAgICAgIGlmIChyZXN1bHQgPj0gMCkgewogICAgICAgICAgICAvLyBjaGVjayBsYXN0IGNoYXJhY3RlcgogICAgICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKHN0ci5jaGFyQXQoc3RyTGVuZ3RoIC0gMSkpICYmIAogICAgICAgICAgICAgICAgKHJlc3VsdCA8IHNvdXJjZS5sZW5ndGgoKSAtIDEpICYmIAogICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdEVuZCkpKSB7IAogICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4T2Yoc291cmNlLCBzdHIsIHJlc3VsdEVuZCArIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGNoZWNrIGZpcnN0IGNoYXJhY3RlciB3aGljaCBpcyBhIHRyYWlsIHN1cnJvZ2F0ZQogICAgICAgICAgICBpZiAoaXNUcmFpbFN1cnJvZ2F0ZShzdHIuY2hhckF0KDApKSAmJiByZXN1bHQgPiAwICYmIAogICAgICAgICAgICAgICAgaXNMZWFkU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0IC0gMSkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXhPZihzb3VyY2UsIHN0ciwgcmVzdWx0RW5kICsgMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoZSBhcmd1bWVudCBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgb2YgCiAgICAgKiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBjb2RlcG9pbnQuIEkuZS4sIHRoZSBpbmRleCByZXR1cm5lZCAKICAgICAqIGlzIHRoZSBsYXJnZXN0IHZhbHVlIGkgc3VjaCB0aGF0OiBVVEYxNi5jaGFyQXQoc291cmNlLCBpKSA9PSBjaGFyMzIKICAgICAqIGlzIHRydWUuIAogICAgICogPHA+CiAgICAgKiBFeGFtcGxlczo8YnI+CiAgICAgKiBVVEYxNi5sYXN0SW5kZXhPZigiYWJjIiwgJ2EnKSByZXR1cm5zIDA8YnI+CiAgICAgKiBVVEYxNi5sYXN0SW5kZXhPZigiYWJjXHVkODAwXHVkYzAwIiwgMHgxMDAwMCkgcmV0dXJucyAzPGJyPgogICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsIDB4ZDgwMCkgcmV0dXJucyAtMTxicj4KICAgICAqIDwvcD4KICAgICAqIDxwPnNvdXJjZSBpcyBzZWFyY2hlZCBiYWNrd2FyZHMgc3RhcnRpbmcgYXQgdGhlIGxhc3QgY2hhcmFjdGVyLjwvcD4gCiAgICAgKiBOb3RlIHRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGFzIHN1cHBvcnQgdG8gamRrIDEuMywgd2hpY2ggZG9lcyBub3QgCiAgICAgKiBzdXBwb3J0IHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycyB0byBpdHMgZnVsbGVzdC4KICAgICAqIEBwYXJhbSBzb3VyY2UgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIHRoYXQgd2lsbCBiZSBzZWFyY2hlZAogICAgICogQHBhcmFtIGNoYXIzMiBjb2RlcG9pbnQgdG8gc2VhcmNoIGZvciAKICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlIGNvZGVwb2ludCBpbiBzb3VyY2UsIAogICAgICogICAgICAgICBvciAtMSBpZiB0aGUgY29kZXBvaW50IGRvZXMgbm90IG9jY3VyLgogICAgICogQGRyYWZ0IElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgbGFzdEluZGV4T2YoU3RyaW5nIHNvdXJjZSwgaW50IGNoYXIzMikgIAogICAgewogICAgICAgIGlmIChjaGFyMzIgPCBDT0RFUE9JTlRfTUlOX1ZBTFVFIHx8IGNoYXIzMiA+IENPREVQT0lOVF9NQVhfVkFMVUUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBcmd1bWVudCBjaGFyMzIgaXMgbm90IGEgdmFsaWQgY29kZXBvaW50Iik7CiAgICAgICAgfQogICAgICAgIC8vIG5vbi1zdXJyb2dhdGUgYm1wCiAgICAgICAgaWYgKGNoYXIzMiA8IExFQURfU1VSUk9HQVRFX01JTl9WQUxVRSB8fAogICAgICAgICAgICAoY2hhcjMyID4gVFJBSUxfU1VSUk9HQVRFX01BWF9WQUxVRSAmJiAKICAgICAgICAgICAgIGNoYXIzMiA8IFNVUFBMRU1FTlRBUllfTUlOX1ZBTFVFKSkgewogICAgICAgICAgICByZXR1cm4gc291cmNlLmxhc3RJbmRleE9mKChjaGFyKWNoYXIzMik7CiAgICAgICAgfQogICAgICAgIC8vIHN1cnJvZ2F0ZQogICAgICAgIGlmIChjaGFyMzIgPCBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkgewogICAgICAgICAgICBpbnQgcmVzdWx0ID0gc291cmNlLmxhc3RJbmRleE9mKChjaGFyKWNoYXIzMik7CiAgICAgICAgICAgIGlmIChyZXN1bHQgPj0gMCkgewogICAgICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZSgoY2hhciljaGFyMzIpICYmIAogICAgICAgICAgICAgICAgICAgIChyZXN1bHQgPCBzb3VyY2UubGVuZ3RoKCkgLSAxKSAmJiAKICAgICAgICAgICAgICAgICAgICBpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0ICsgMSkpKSB7IAogICAgICAgICAgICAgICAgICAgIHJldHVybiBsYXN0SW5kZXhPZihzb3VyY2UsIGNoYXIzMiwgcmVzdWx0IC0gMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyB0cmFpbCBzdXJyb2dhdGUKICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPiAwICYmIAogICAgICAgICAgICAgICAgICAgIGlzTGVhZFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCAtIDEpKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBsYXN0SW5kZXhPZihzb3VyY2UsIGNoYXIzMiwgcmVzdWx0IC0gMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgICAgIC8vIHN1cHBsZW1lbnRhcnkKICAgICAgICBTdHJpbmcgY2hhcjMyc3RyID0gdG9TdHJpbmcoY2hhcjMyKTsKICAgICAgICByZXR1cm4gc291cmNlLmxhc3RJbmRleE9mKGNoYXIzMnN0cik7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoZSBhcmd1bWVudCBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgb2YgCiAgICAgKiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBzdHJpbmcgc3RyLiBUaGlzIG1ldGhvZCBpcyAKICAgICAqIGltcGxlbWVudGVkIGJhc2VkIG9uIGNvZGVwb2ludHMsIGhlbmNlIGEgImxlYWQgc3Vycm9nYXRlIGNoYXJhY3RlciArCiAgICAgKiB0cmFpbCBzdXJyb2dhdGUgY2hhcmFjdGVyIiBpcyB0cmVhdGVkIGFzIG9uZSBlbnRpdHkuZQogICAgICogSGVuY2UgaWYgdGhlIHN0ciBzdGFydHMgd2l0aCB0cmFpbCBzdXJyb2dhdGUgY2hhcmFjdGVyIGF0IGluZGV4IDAsIGEgCiAgICAgKiBzb3VyY2Ugd2l0aCBhIGxlYWRpbmcgYSBzdXJyb2dhdGUgY2hhcmFjdGVyIGJlZm9yZSBzdHIgZm91bmQgYXQgaW4gCiAgICAgKiBzb3VyY2Ugd2lsbCBub3QgaGF2ZSBhIHZhbGlkIG1hdGNoLiBWaWNlIHZlcnNhIGZvciBsZWFkIHN1cnJvZ2F0ZXMgCiAgICAgKiB0aGF0IGVuZHMgc3RyLgogICAgICogU2VlIGV4YW1wbGUgYmVsb3cuCiAgICAgKiA8cD4KICAgICAqIEV4YW1wbGVzOjxicj4KICAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmMiLCAiYSIpIHJldHVybnMgMDxicj4KICAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAiXHVkODAwXHVkYzAwIikgcmV0dXJucyAzPGJyPgogICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsICJcdWQ4MDAiKSByZXR1cm5zIC0xPGJyPgogICAgICogPC9wPgogICAgICogPHA+c291cmNlIGlzIHNlYXJjaGVkIGJhY2t3YXJkcyBzdGFydGluZyBhdCB0aGUgbGFzdCBjaGFyYWN0ZXIuPC9wPiAKICAgICAqIE5vdGUgdGhpcyBtZXRob2QgaXMgcHJvdmlkZWQgYXMgc3VwcG9ydCB0byBqZGsgMS4zLCB3aGljaCBkb2VzIG5vdCAKICAgICAqIHN1cHBvcnQgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHRvIGl0cyBmdWxsZXN0LgogICAgICogQHBhcmFtIHNvdXJjZSBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgdGhhdCB3aWxsIGJlIHNlYXJjaGVkCiAgICAgKiBAcGFyYW0gc3RyIFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyB0byBzZWFyY2ggZm9yIAogICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY29kZXBvaW50IGluIHNvdXJjZSwgCiAgICAgKiAgICAgICAgIG9yIC0xIGlmIHRoZSBjb2RlcG9pbnQgZG9lcyBub3Qgb2NjdXIuCiAgICAgKiBAZHJhZnQgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBsYXN0SW5kZXhPZihTdHJpbmcgc291cmNlLCBTdHJpbmcgc3RyKSAgCiAgICB7CiAgICAgICAgaW50IHN0ckxlbmd0aCA9IHN0ci5sZW5ndGgoKTsKICAgICAgICAvLyBub24tc3Vycm9nYXRlIGVuZHMKICAgICAgICBpZiAoIWlzVHJhaWxTdXJyb2dhdGUoc3RyLmNoYXJBdCgwKSkgJiYgCiAgICAgICAgICAgICFpc0xlYWRTdXJyb2dhdGUoc3RyLmNoYXJBdChzdHJMZW5ndGggLSAxKSkpIHsKICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5sYXN0SW5kZXhPZihzdHIpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpbnQgcmVzdWx0ICAgID0gc291cmNlLmxhc3RJbmRleE9mKHN0cik7CiAgICAgICAgaWYgKHJlc3VsdCA+PSAwKSB7CiAgICAgICAgICAgIC8vIGNoZWNrIGxhc3QgY2hhcmFjdGVyCiAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoc3RyLmNoYXJBdChzdHJMZW5ndGggLSAxKSkgJiYgCiAgICAgICAgICAgICAgICAocmVzdWx0IDwgc291cmNlLmxlbmd0aCgpIC0gMSkgJiYgCiAgICAgICAgICAgICAgICBpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0ICsgc3RyTGVuZ3RoICsgMSkpKSB7IAogICAgICAgICAgICAgICAgcmV0dXJuIGxhc3RJbmRleE9mKHNvdXJjZSwgc3RyLCByZXN1bHQgLSAxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBjaGVjayBmaXJzdCBjaGFyYWN0ZXIgd2hpY2ggaXMgYSB0cmFpbCBzdXJyb2dhdGUKICAgICAgICAgICAgaWYgKGlzVHJhaWxTdXJyb2dhdGUoc3RyLmNoYXJBdCgwKSkgJiYgcmVzdWx0ID4gMCAmJiAKICAgICAgICAgICAgICAgIGlzTGVhZFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCAtIDEpKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGxhc3RJbmRleE9mKHNvdXJjZSwgc3RyLCByZXN1bHQgLSAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiA8cD5SZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFyZ3VtZW50IFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyBvZiAKICAgICAqIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlIGFyZ3VtZW50IGNvZGVwb2ludCwgd2hlcmUgdGhlIHJlc3VsdCBpcyBsZXNzCiAgICAgKiB0aGFuIG9yIGVxdWFscyB0byBmcm9tSW5kZXguPC9wPiAKICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGltcGxlbWVudGVkIGJhc2VkIG9uIGNvZGVwb2ludHMsIGhlbmNlIGEgc2luZ2xlIAogICAgICogc3Vycm9nYXRlIGNoYXJhY3RlciB3aWxsIG5vdCBtYXRjaCBhIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyLjwvcD4KICAgICAqIDxwPnNvdXJjZSBpcyBzZWFyY2hlZCBiYWNrd2FyZHMgc3RhcnRpbmcgYXQgdGhlIGxhc3QgY2hhcmFjdGVyIHN0YXJ0aW5nIAogICAgICogYXQgdGhlIHNwZWNpZmllZCBpbmRleC48L3A+CiAgICAgKiA8cD4KICAgICAqIEV4YW1wbGVzOjxicj4KICAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmMiLCAnYycsIDIpIHJldHVybnMgMjxicj4KICAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmMiLCAnYycsIDEpIHJldHVybnMgLTE8YnI+CiAgICAgKiBVVEYxNi5sYXN0SW5kZXhPZigiYWJjXHVkODAwXHVkYzAwIiwgMHgxMDAwMCwgNSkgcmV0dXJucyAzPGJyPgogICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsIDB4MTAwMDAsIDMpIHJldHVybnMgMzxicj4KICAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAweGQ4MDApIHJldHVybnMgLTE8YnI+CiAgICAgKiA8L3A+CiAgICAgKiBOb3RlIHRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGFzIHN1cHBvcnQgdG8gamRrIDEuMywgd2hpY2ggZG9lcyBub3QgCiAgICAgKiBzdXBwb3J0IHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycyB0byBpdHMgZnVsbGVzdC4KICAgICAqIEBwYXJhbSBzb3VyY2UgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIHRoYXQgd2lsbCBiZSBzZWFyY2hlZAogICAgICogQHBhcmFtIGNoYXIzMiBjb2RlcG9pbnQgdG8gc2VhcmNoIGZvciAKICAgICAqIEBwYXJhbSBmcm9tSW5kZXggdGhlIGluZGV4IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbS4gVGhlcmUgaXMgbm8gCiAgICAgKiAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiBmcm9tSW5kZXguIElmIGl0IGlzIAogICAgICogICAgICAgICAgICAgICAgICBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZywgCiAgICAgKiAgICAgICAgICAgICAgICAgIGl0IGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQgd2VyZSBlcXVhbCB0byBvbmUgCiAgICAgKiAgICAgICAgICAgICAgICAgIGxlc3MgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nOiB0aGlzIGVudGlyZSAKICAgICAqICAgICAgICAgICAgICAgICAgc3RyaW5nIG1heSBiZSBzZWFyY2hlZC4gSWYgaXQgaXMgbmVnYXRpdmUsIGl0IGhhcyAKICAgICAqICAgICAgICAgICAgICAgICAgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgLTE6IC0xIGlzIHJldHVybmVkLiAKICAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlIGNvZGVwb2ludCBpbiBzb3VyY2UsIAogICAgICogICAgICAgICBvciAtMSBpZiB0aGUgY29kZXBvaW50IGRvZXMgbm90IG9jY3VyLgogICAgICogQGRyYWZ0IElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgbGFzdEluZGV4T2YoU3RyaW5nIHNvdXJjZSwgaW50IGNoYXIzMiwgaW50IGZyb21JbmRleCkKICAgIHsKICAgICAgICBpZiAoY2hhcjMyIDwgQ09ERVBPSU5UX01JTl9WQUxVRSB8fCBjaGFyMzIgPiBDT0RFUE9JTlRfTUFYX1ZBTFVFKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXJndW1lbnQgY2hhcjMyIGlzIG5vdCBhIHZhbGlkIGNvZGVwb2ludCIpOwogICAgICAgIH0KICAgICAgICAvLyBub24tc3Vycm9nYXRlIGJtcAogICAgICAgIGlmIChjaGFyMzIgPCBMRUFEX1NVUlJPR0FURV9NSU5fVkFMVUUgfHwKICAgICAgICAgICAgKGNoYXIzMiA+IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUUgJiYgCiAgICAgICAgICAgICBjaGFyMzIgPCBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkpIHsKICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5sYXN0SW5kZXhPZigoY2hhciljaGFyMzIsIGZyb21JbmRleCk7CiAgICAgICAgfQogICAgICAgIC8vIHN1cnJvZ2F0ZQogICAgICAgIGlmIChjaGFyMzIgPCBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkgewogICAgICAgICAgICBpbnQgcmVzdWx0ID0gc291cmNlLmxhc3RJbmRleE9mKChjaGFyKWNoYXIzMiwgZnJvbUluZGV4KTsKICAgICAgICAgICAgaWYgKHJlc3VsdCA+PSAwKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKChjaGFyKWNoYXIzMikgJiYgCiAgICAgICAgICAgICAgICAgICAgKHJlc3VsdCA8IHNvdXJjZS5sZW5ndGgoKSAtIDEpICYmIAogICAgICAgICAgICAgICAgICAgIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlLmNoYXJBdChyZXN1bHQgKyAxKSkpIHsgCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxhc3RJbmRleE9mKHNvdXJjZSwgY2hhcjMyLCByZXN1bHQgLSAxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIHRyYWlsIHN1cnJvZ2F0ZQogICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA+IDAgJiYgCiAgICAgICAgICAgICAgICAgICAgaXNMZWFkU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0IC0gMSkpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxhc3RJbmRleE9mKHNvdXJjZSwgY2hhcjMyLCByZXN1bHQgLSAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgLy8gc3VwcGxlbWVudGFyeQogICAgICAgIFN0cmluZyBjaGFyMzJzdHIgPSB0b1N0cmluZyhjaGFyMzIpOwogICAgICAgIHJldHVybiBzb3VyY2UubGFzdEluZGV4T2YoY2hhcjMyc3RyLCBmcm9tSW5kZXgpOwogICAgfQogICAgCiAgICAvKioKICAgICAqIDxwPlJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGUgYXJndW1lbnQgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIG9mIAogICAgICogdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgYXJndW1lbnQgc3RyaW5nIHN0ciwgd2hlcmUgdGhlIHJlc3VsdCBpcyBsZXNzCiAgICAgKiB0aGFuIG9yIGVxdWFscyB0byBmcm9tSW5kZXguPC9wPiAKICAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGltcGxlbWVudGVkIGJhc2VkIG9uIGNvZGVwb2ludHMsIGhlbmNlIGEgCiAgICAgKiAibGVhZCBzdXJyb2dhdGUgY2hhcmFjdGVyICsgdHJhaWwgc3Vycm9nYXRlIGNoYXJhY3RlciIgaXMgdHJlYXRlZCBhcyBvbmUgCiAgICAgKiBlbnRpdHkuCiAgICAgKiBIZW5jZSBpZiB0aGUgc3RyIHN0YXJ0cyB3aXRoIHRyYWlsIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIgYXQgaW5kZXggMCwgYSAKICAgICAqIHNvdXJjZSB3aXRoIGEgbGVhZGluZyBhIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIgYmVmb3JlIHN0ciBmb3VuZCBhdCBpbiAKICAgICAqIHNvdXJjZSB3aWxsIG5vdCBoYXZlIGEgdmFsaWQgbWF0Y2guIFZpY2UgdmVyc2EgZm9yIGxlYWQgc3Vycm9nYXRlcyAKICAgICAqIHRoYXQgZW5kcyBzdHIuCiAgICAgKiA8L3A+CiAgICAgKiBTZWUgZXhhbXBsZSBiZWxvdy4KICAgICAqIDxwPgogICAgICogRXhhbXBsZXM6PGJyPgogICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiYyIsICJjIiwgMikgcmV0dXJucyAyPGJyPgogICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiYyIsICJjIiwgMSkgcmV0dXJucyAtMTxicj4KICAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAiXHVkODAwXHVkYzAwIiwgNSkgcmV0dXJucyAzPGJyPgogICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsICJcdWQ4MDBcdWRjMDAiLCAzKSByZXR1cm5zIDM8YnI+CiAgICAgKiBVVEYxNi5sYXN0SW5kZXhPZigiYWJjXHVkODAwXHVkYzAwIiwgIlx1ZDgwMCIsIDQpIHJldHVybnMgLTE8YnI+CiAgICAgKiA8L3A+CiAgICAgKiA8cD5zb3VyY2UgaXMgc2VhcmNoZWQgYmFja3dhcmRzIHN0YXJ0aW5nIGF0IHRoZSBsYXN0IGNoYXJhY3Rlci48L3A+IAogICAgICogTm90ZSB0aGlzIG1ldGhvZCBpcyBwcm92aWRlZCBhcyBzdXBwb3J0IHRvIGpkayAxLjMsIHdoaWNoIGRvZXMgbm90IAogICAgICogc3VwcG9ydCBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMgdG8gaXRzIGZ1bGxlc3QuCiAgICAgKiBAcGFyYW0gc291cmNlIFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyB0aGF0IHdpbGwgYmUgc2VhcmNoZWQKICAgICAqIEBwYXJhbSBzdHIgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIHRvIHNlYXJjaCBmb3IgCiAgICAgKiBAcGFyYW0gZnJvbUluZGV4IHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uIFRoZXJlIGlzIG5vIAogICAgICogICAgICAgICAgICAgICAgICByZXN0cmljdGlvbiBvbiB0aGUgdmFsdWUgb2YgZnJvbUluZGV4LiBJZiBpdCBpcyAKICAgICAqICAgICAgICAgICAgICAgICAgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBsZW5ndGggb2YgdGhpcyBzdHJpbmcsIAogICAgICogICAgICAgICAgICAgICAgICBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgZXF1YWwgdG8gb25lIAogICAgICogICAgICAgICAgICAgICAgICBsZXNzIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZzogdGhpcyBlbnRpcmUgCiAgICAgKiAgICAgICAgICAgICAgICAgIHN0cmluZyBtYXkgYmUgc2VhcmNoZWQuIElmIGl0IGlzIG5lZ2F0aXZlLCBpdCBoYXMgCiAgICAgKiAgICAgICAgICAgICAgICAgIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIC0xOiAtMSBpcyByZXR1cm5lZC4gCiAgICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZSBjb2RlcG9pbnQgaW4gc291cmNlLCAKICAgICAqICAgICAgICAgb3IgLTEgaWYgdGhlIGNvZGVwb2ludCBkb2VzIG5vdCBvY2N1ci4KICAgICAqIEBkcmFmdCBJQ1UgMi4xCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGxhc3RJbmRleE9mKFN0cmluZyBzb3VyY2UsIFN0cmluZyBzdHIsIGludCBmcm9tSW5kZXgpICAKICAgIHsKICAgICAgICBpbnQgc3RyTGVuZ3RoID0gc3RyLmxlbmd0aCgpOwogICAgICAgIC8vIG5vbi1zdXJyb2dhdGUgZW5kcwogICAgICAgIGlmICghaXNUcmFpbFN1cnJvZ2F0ZShzdHIuY2hhckF0KDApKSAmJiAKICAgICAgICAgICAgIWlzTGVhZFN1cnJvZ2F0ZShzdHIuY2hhckF0KHN0ckxlbmd0aCAtIDEpKSkgewogICAgICAgICAgICByZXR1cm4gc291cmNlLmxhc3RJbmRleE9mKHN0ciwgZnJvbUluZGV4KTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaW50IHJlc3VsdCAgICA9IHNvdXJjZS5sYXN0SW5kZXhPZihzdHIsIGZyb21JbmRleCk7CiAgICAgICAgaWYgKHJlc3VsdCA+PSAwKSB7CiAgICAgICAgICAgIC8vIGNoZWNrIGxhc3QgY2hhcmFjdGVyCiAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoc3RyLmNoYXJBdChzdHJMZW5ndGggLSAxKSkgJiYgCiAgICAgICAgICAgICAgICAocmVzdWx0IDwgc291cmNlLmxlbmd0aCgpIC0gMSkgJiYgCiAgICAgICAgICAgICAgICBpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0ICsgc3RyTGVuZ3RoKSkpIHsgCiAgICAgICAgICAgICAgICByZXR1cm4gbGFzdEluZGV4T2Yoc291cmNlLCBzdHIsIHJlc3VsdCAtIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGNoZWNrIGZpcnN0IGNoYXJhY3RlciB3aGljaCBpcyBhIHRyYWlsIHN1cnJvZ2F0ZQogICAgICAgICAgICBpZiAoaXNUcmFpbFN1cnJvZ2F0ZShzdHIuY2hhckF0KDApKSAmJiByZXN1bHQgPiAwICYmIAogICAgICAgICAgICAgICAgaXNMZWFkU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0IC0gMSkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbGFzdEluZGV4T2Yoc291cmNlLCBzdHIsIHJlc3VsdCAtIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBhIG5ldyBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgcmVzdWx0aW5nIGZyb20gcmVwbGFjaW5nIGFsbCAKICAgICAqIG9jY3VycmVuY2VzIG9mIG9sZENoYXIzMiBpbiBzb3VyY2Ugd2l0aCBuZXdDaGFyMzIuIAogICAgICogSWYgdGhlIGNoYXJhY3RlciBvbGRDaGFyMzIgZG9lcyBub3Qgb2NjdXIgaW4gdGhlIFVURjE2IGZvcm1hdCBVbmljb2RlCiAgICAgKiBzdHJpbmcgc291cmNlLCB0aGVuIHNvdXJjZSB3aWxsIGJlIHJldHVybmVkLiBPdGhlcndpc2UsIGEgbmV3IFN0cmluZyAKICAgICAqIG9iamVjdCBpcyBjcmVhdGVkIHRoYXQgcmVwcmVzZW50cyBhIGNvZGVwb2ludCBzZXF1ZW5jZSBpZGVudGljYWwgdG8gdGhlIAogICAgICogY29kZXBvaW50IHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHNvdXJjZSwgZXhjZXB0IHRoYXQgZXZlcnkgb2NjdXJyZW5jZSAKICAgICAqIG9mIG9sZENoYXIzMiBpcyByZXBsYWNlZCBieSBhbiBvY2N1cnJlbmNlIG9mIG5ld0NoYXIzMi4gCiAgICAgKiA8cD4KICAgICAqIEV4YW1wbGVzOiA8YnI+CiAgICAgKiBVVEYxNi5yZXBsYWNlKCJtZXNxdWl0ZSBpbiB5b3VyIGNlbGxhciIsICdlJywgJ28nKTs8YnI+CiAgICAgKiAgICAgICAgcmV0dXJucyAibW9zcXVpdG8gaW4geW91ciBjb2xsYXIiPGJyPgogICAgICogVVRGMTYucmVwbGFjZSgiSm9uTCIsICdxJywgJ3gnKTs8YnI+CiAgICAgKiAgICAgICAgcmV0dXJucyAiSm9uTCIgKG5vIGNoYW5nZSk8YnI+CiAgICAgKiBVVEYxNi5yZXBsYWNlKCJTdXBwbGVtZW50YXJ5IGNoYXJhY3RlciBcdWQ4MDBcdWRjMDAiLCAweDEwMDAwLCAnIScpOwogICAgICogPGJyPiAgIHJldHVybnMgIlN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyICEiPGJyPgogICAgICogVVRGMTYucmVwbGFjZSgiU3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgXHVkODAwXHVkYzAwIiwgMHhkODAwLCAnIScpOwogICAgICogPGJyPiAgIHJldHVybnMgIlN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIFx1ZDgwMFx1ZGMwMCI8YnI+CiAgICAgKiA8L3A+CiAgICAgKiBOb3RlIHRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGFzIHN1cHBvcnQgdG8gamRrIDEuMywgd2hpY2ggZG9lcyBub3QgCiAgICAgKiBzdXBwb3J0IHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycyB0byBpdHMgZnVsbGVzdC4KICAgICAqIEBwYXJhbSBzb3VyY2UgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIHdoaWNoIHRoZSBjb2RlcG9pbnQgCiAgICAgKiAgICAgICAgICAgICAgIHJlcGxhY2VtZW50cyB3aWxsIGJlIGJhc2VkIG9uLgogICAgICogQHBhcmFtIG9sZENoYXIzMiBub24temVybyBvbGQgY29kZXBvaW50IHRvIGJlIHJlcGxhY2VkLgogICAgICogQHBhcmFtIG5ld0NoYXIzMiB0aGUgbmV3IGNvZGVwb2ludCB0byByZXBsYWNlIG9sZENoYXIzMgogICAgICogQHJldHVybiBuZXcgU3RyaW5nIGRlcml2ZWQgZnJvbSBzb3VyY2UgYnkgcmVwbGFjaW5nIGV2ZXJ5IG9jY3VycmVuY2UgCiAgICAgKiAgICAgICAgIG9mIG9sZENoYXIzMiB3aXRoIG5ld0NoYXIzMiwgdW5sZXNzIHdoZW4gbm8gb2xkQ2hhcjMyIGlzIGZvdW5kCiAgICAgKiAgICAgICAgIGluIHNvdXJjZSB0aGVuIHNvdXJjZSB3aWxsIGJlIHJldHVybmVkLgogICAgICogQGRyYWZ0IElDVSAyLjEKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgcmVwbGFjZShTdHJpbmcgc291cmNlLCBpbnQgb2xkQ2hhcjMyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5ld0NoYXIzMikgIAogICAgewogICAgICAgIGlmIChvbGRDaGFyMzIgPD0gMCB8fCBvbGRDaGFyMzIgPiBDT0RFUE9JTlRfTUFYX1ZBTFVFKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXJndW1lbnQgb2xkQ2hhcjMyIGlzIG5vdCBhIHZhbGlkIGNvZGVwb2ludCIpOwogICAgICAgIH0KICAgICAgICBpZiAobmV3Q2hhcjMyIDw9IDAgfHwgbmV3Q2hhcjMyID4gQ09ERVBPSU5UX01BWF9WQUxVRSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFyZ3VtZW50IG5ld0NoYXIzMiBpcyBub3QgYSB2YWxpZCBjb2RlcG9pbnQiKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaW50IGluZGV4ICAgICA9IGluZGV4T2Yoc291cmNlLCBvbGRDaGFyMzIpOwogICAgICAgIGlmIChpbmRleCA9PSAtMSkgewogICAgICAgICAgICByZXR1cm4gc291cmNlOwogICAgICAgIH0KICAgICAgICBTdHJpbmcgICAgICAgbmV3Q2hhcjMyU3RyICAgID0gdG9TdHJpbmcobmV3Q2hhcjMyKTsKICAgICAgICBpbnQgICAgICAgICAgb2xkQ2hhcjMyU2l6ZSAgID0gMTsKICAgICAgICBpbnQgICAgICAgICAgbmV3Q2hhcjMyU2l6ZSAgID0gbmV3Q2hhcjMyU3RyLmxlbmd0aCgpOwogICAgICAgIFN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKHNvdXJjZSk7CiAgICAgICAgaW50ICAgICAgICAgIHJlc3VsdEluZGV4ICAgICA9IGluZGV4OwogICAgICAgIAogICAgICAgIGlmIChvbGRDaGFyMzIgPj0gU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUpIHsKICAgICAgICAgICAgb2xkQ2hhcjMyU2l6ZSA9IDI7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHdoaWxlIChpbmRleCAhPSAtMSkgewogICAgICAgICAgICBpbnQgZW5kUmVzdWx0SW5kZXggID0gcmVzdWx0SW5kZXggKyBvbGRDaGFyMzJTaXplOwogICAgICAgICAgICByZXN1bHQucmVwbGFjZShyZXN1bHRJbmRleCwgZW5kUmVzdWx0SW5kZXgsIG5ld0NoYXIzMlN0cik7CiAgICAgICAgICAgIGludCBsYXN0RW5kSW5kZXggICAgPSBpbmRleCArIG9sZENoYXIzMlNpemU7CiAgICAgICAgICAgIGluZGV4ICAgICAgID0gaW5kZXhPZihzb3VyY2UsIG9sZENoYXIzMiwgbGFzdEVuZEluZGV4KTsKICAgICAgICAgICAgcmVzdWx0SW5kZXggKz0gbmV3Q2hhcjMyU2l6ZSArIGluZGV4IC0gbGFzdEVuZEluZGV4OwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgICogUmV0dXJucyBhIG5ldyBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgcmVzdWx0aW5nIGZyb20gcmVwbGFjaW5nIGFsbCAKICAgICAqIG9jY3VycmVuY2VzIG9mIG9sZFN0ciBpbiBzb3VyY2Ugd2l0aCBuZXdTdHIuIAogICAgICogSWYgdGhlIGNoYXJhY3RlciBvbGRTdHIgZG9lcyBub3Qgb2NjdXIgaW4gdGhlIFVURjE2IGZvcm1hdCBVbmljb2RlCiAgICAgKiBzdHJpbmcgc291cmNlLCB0aGVuIHNvdXJjZSB3aWxsIGJlIHJldHVybmVkLiBPdGhlcndpc2UsIGEgbmV3IFN0cmluZyAKICAgICAqIG9iamVjdCBpcyBjcmVhdGVkIHRoYXQgcmVwcmVzZW50cyBhIGNvZGVwb2ludCBzZXF1ZW5jZSBpZGVudGljYWwgdG8gdGhlIAogICAgICogY29kZXBvaW50IHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHNvdXJjZSwgZXhjZXB0IHRoYXQgZXZlcnkgb2NjdXJyZW5jZSAKICAgICAqIG9mIG9sZFN0ciBpcyByZXBsYWNlZCBieSBhbiBvY2N1cnJlbmNlIG9mIG5ld1N0ci4gCiAgICAgKiA8cD4KICAgICAqIEV4YW1wbGVzOiA8YnI+CiAgICAgKiBVVEYxNi5yZXBsYWNlKCJtZXNxdWl0ZSBpbiB5b3VyIGNlbGxhciIsICJlIiwgIm8iKTs8YnI+CiAgICAgKiAgICAgICAgcmV0dXJucyAibW9zcXVpdG8gaW4geW91ciBjb2xsYXIiPGJyPgogICAgICogVVRGMTYucmVwbGFjZSgibWVzcXVpdGUgaW4geW91ciBjZWxsYXIiLCAibWVzcXVpdGUiLCAiY2F0Iik7PGJyPgogICAgICogICAgICAgIHJldHVybnMgImNhdCBpbiB5b3VyIGNvbGxhciI8YnI+CiAgICAgKiBVVEYxNi5yZXBsYWNlKCJKb25MIiwgInEiLCAieCIpOzxicj4KICAgICAqICAgICAgICByZXR1cm5zICJKb25MIiAobm8gY2hhbmdlKTxicj4KICAgICAqIFVURjE2LnJlcGxhY2UoIlN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIFx1ZDgwMFx1ZGMwMCIsICJcdWQ4MDBcdWRjMDAiLAogICAgICogICAgICAgICAgICAgICAnIScpOwogICAgICogPGJyPiAgIHJldHVybnMgIlN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyICEiPGJyPgogICAgICogVVRGMTYucmVwbGFjZSgiU3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgXHVkODAwXHVkYzAwIiwgIlx1ZDgwMCIsICchJyk7CiAgICAgKiA8YnI+ICAgcmV0dXJucyAiU3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgXHVkODAwXHVkYzAwIjxicj4KICAgICAqIDwvcD4KICAgICAqIE5vdGUgdGhpcyBtZXRob2QgaXMgcHJvdmlkZWQgYXMgc3VwcG9ydCB0byBqZGsgMS4zLCB3aGljaCBkb2VzIG5vdCAKICAgICAqIHN1cHBvcnQgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHRvIGl0cyBmdWxsZXN0LgogICAgICogQHBhcmFtIHNvdXJjZSBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgd2hpY2ggdGhlIGNvZGVwb2ludCAKICAgICAqICAgICAgICAgICAgICAgcmVwbGFjZW1lbnRzIHdpbGwgYmUgYmFzZWQgb24uCiAgICAgKiBAcGFyYW0gb2xkQ2hhcjMyIG5vbi16ZXJvIG9sZCBjb2RlcG9pbnQgdG8gYmUgcmVwbGFjZWQuCiAgICAgKiBAcGFyYW0gbmV3Q2hhcjMyIHRoZSBuZXcgY29kZXBvaW50IHRvIHJlcGxhY2Ugb2xkQ2hhcjMyCiAgICAgKiBAcmV0dXJuIG5ldyBTdHJpbmcgZGVyaXZlZCBmcm9tIHNvdXJjZSBieSByZXBsYWNpbmcgZXZlcnkgb2NjdXJyZW5jZSAKICAgICAqICAgICAgICAgb2Ygb2xkQ2hhcjMyIHdpdGggbmV3Q2hhcjMyLCB1bmxlc3Mgd2hlbiBubyBvbGRDaGFyMzIgaXMgZm91bmQKICAgICAqICAgICAgICAgaW4gc291cmNlIHRoZW4gc291cmNlIHdpbGwgYmUgcmV0dXJuZWQuCiAgICAgKiBAZHJhZnQgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZXBsYWNlKFN0cmluZyBzb3VyY2UsIFN0cmluZyBvbGRTdHIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmV3U3RyKSAgCiAgICB7CiAgICAgICAgaW50IGluZGV4ICAgICA9IGluZGV4T2Yoc291cmNlLCBvbGRTdHIpOwogICAgICAgIGlmIChpbmRleCA9PSAtMSkgewogICAgICAgICAgICByZXR1cm4gc291cmNlOwogICAgICAgIH0KICAgICAgICBpbnQgICAgICAgICAgb2xkU3RyU2l6ZSAgID0gb2xkU3RyLmxlbmd0aCgpOwogICAgICAgIGludCAgICAgICAgICBuZXdTdHJTaXplICAgPSBuZXdTdHIubGVuZ3RoKCk7CiAgICAgICAgU3RyaW5nQnVmZmVyIHJlc3VsdCAgICAgICA9IG5ldyBTdHJpbmdCdWZmZXIoc291cmNlKTsKICAgICAgICBpbnQgICAgICAgICAgcmVzdWx0SW5kZXggICAgID0gaW5kZXg7CiAgICAgICAgCiAgICAgICAgd2hpbGUgKGluZGV4ICE9IC0xKSB7CiAgICAgICAgICAgIGludCBlbmRSZXN1bHRJbmRleCAgPSByZXN1bHRJbmRleCArIG9sZFN0clNpemU7CiAgICAgICAgICAgIHJlc3VsdC5yZXBsYWNlKHJlc3VsdEluZGV4LCBlbmRSZXN1bHRJbmRleCwgbmV3U3RyKTsKICAgICAgICAgICAgaW50IGxhc3RFbmRJbmRleCAgICA9IGluZGV4ICsgb2xkU3RyU2l6ZTsKICAgICAgICAgICAgaW5kZXggICAgICAgPSBpbmRleE9mKHNvdXJjZSwgb2xkU3RyLCBsYXN0RW5kSW5kZXgpOwogICAgICAgICAgICByZXN1bHRJbmRleCArPSBuZXdTdHJTaXplICsgaW5kZXggLSBsYXN0RW5kSW5kZXg7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKICAgIH0KICAgIAogICAgLyoqIAogICAgICogUmV2ZXJzZXMgYSBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgYW5kIHJlcGxhY2VzIHNvdXJjZSdzIGNvbnRlbnQgCiAgICAgKiB3aXRoIGl0LgogICAgICogVGhpcyBtZXRob2Qgd2lsbCByZXZlcnNlIHN1cnJvZ2F0ZSBjaGFyYWN0ZXJzIGNvcnJlY3RseSwgaW5zdGVhZCBvZiAKICAgICAqIGJsaW5kbHkgcmV2ZXJzaW5nIGV2ZXJ5IGNoYXJhY3Rlci4KICAgICAqIDxwPgogICAgICogRXhhbXBsZXM6PGJyPgogICAgICogVVRGMTYucmV2ZXJzZShuZXcgU3RyaW5nQnVmZmVyKAogICAgICogICAgICAgICAgICAgIlN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycyBcdWQ4MDBcdWRjMDBcdWQ4MDFcdWRjMDEiKSk8YnI+CiAgICAgKiByZXR1cm5zICJcdWQ4MDFcdWRjMDFcdWQ4MDBcdWRjMDAgc3JldGNhcmFoYyB5cmF0bmVtZWxwcHVTIi4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBTdHJpbmdCdWZmZXIgdGhhdCBjb250YWlucyBVVEYxNiBmb3JtYXQgCiAgICAgKiAgICAgICAgVW5pY29kZSBzdHJpbmcgdG8gYmUgcmV2ZXJzZWQKICAgICAqIEByZXR1cm4gYSBtb2RpZmllZCBzb3VyY2Ugd2l0aCByZXZlcnNlZCBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcuCiAgICAgKiBAZHJhZnQgSUNVIDIuMQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZ0J1ZmZlciByZXZlcnNlKFN0cmluZ0J1ZmZlciBzb3VyY2UpICAgICAgCiAgICB7CiAgICAgICAgU3RyaW5nQnVmZmVyIHJlc3VsdCA9IHNvdXJjZS5yZXZlcnNlKCk7CiAgICAgICAgaW50IHJlc3VsdExlbmd0aCAgPSByZXN1bHQubGVuZ3RoKCk7CiAgICAgICAgaW50IG1heExlYWRMZW5ndGggPSByZXN1bHRMZW5ndGggLSAyOwogICAgICAgIGludCBpID0gMDsKICAgICAgICB3aGlsZSAoaSA8IHJlc3VsdExlbmd0aCkgewogICAgICAgICAgICBpZiAoaSA8PSBtYXhMZWFkTGVuZ3RoICYmIGlzVHJhaWxTdXJyb2dhdGUocmVzdWx0LmNoYXJBdChpKSkgJiYKICAgICAgICAgICAgICAgIGlzTGVhZFN1cnJvZ2F0ZShyZXN1bHQuY2hhckF0KGkgKyAxKSkpIHsKICAgICAgICAgICAgICAgIGNoYXIgdHJhaWwgPSByZXN1bHQuY2hhckF0KGkpOwogICAgICAgICAgICAgICAgcmVzdWx0LmRlbGV0ZUNoYXJBdChpKTsKICAgICAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoaSArIDEsIHRyYWlsKTsKICAgICAgICAgICAgICAgIGkgKz0gMjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGkgKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVjayBpZiB0aGUgc3RyaW5nIGNvbnRhaW5zIG1vcmUgVW5pY29kZSBjb2RlIHBvaW50cyB0aGFuIGEgY2VydGFpbiAKICAgICAqIG51bWJlci4gVGhpcyBpcyBtb3JlIGVmZmljaWVudCB0aGFuIGNvdW50aW5nIGFsbCBjb2RlIHBvaW50cyBpbiB0aGUgCiAgICAgKiBlbnRpcmUgc3RyaW5nIGFuZCBjb21wYXJpbmcgdGhhdCBudW1iZXIgd2l0aCBhIHRocmVzaG9sZC4KICAgICAqIFRoaXMgZnVuY3Rpb24gbWF5IG5vdCBuZWVkIHRvIHNjYW4gdGhlIHN0cmluZyBhdCBhbGwgaWYgdGhlIGxlbmd0aCBpcwogICAgICogd2l0aGluIGEgY2VydGFpbiByYW5nZSwgYW5kIG5ldmVyIG5lZWRzIHRvIGNvdW50IG1vcmUgdGhhbiAnbnVtYmVyICsgMScgCiAgICAgKiBjb2RlIHBvaW50cy4gTG9naWNhbGx5IGVxdWl2YWxlbnQgdG8gKGNvdW50Q29kZVBvaW50KHMpID4gbnVtYmVyKS4gQSAKICAgICAqIFVuaWNvZGUgY29kZSBwb2ludCBtYXkgb2NjdXB5IGVpdGhlciBvbmUgb3IgdHdvIGNvZGUgdW5pdHMuCiAgICAgKiBAcGFyYW0gc291cmNlIFRoZSBpbnB1dCBzdHJpbmcuCiAgICAgKiBAcGFyYW0gbnVtYmVyIFRoZSBudW1iZXIgb2YgY29kZSBwb2ludHMgaW4gdGhlIHN0cmluZyBpcyBjb21wYXJlZCAKICAgICAqICAgICAgICAgICAgICAgYWdhaW5zdCB0aGUgJ251bWJlcicgcGFyYW1ldGVyLgogICAgICogQHJldHVybiBib29sZWFuIHZhbHVlIGZvciB3aGV0aGVyIHRoZSBzdHJpbmcgY29udGFpbnMgbW9yZSBVbmljb2RlIGNvZGUgCiAgICAgKiAgICAgICAgIHBvaW50cyB0aGFuICdudW1iZXInLiAKICAgICAqIEBkcmFmdCBJQ1UgMi40CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBoYXNNb3JlQ29kZVBvaW50c1RoYW4oU3RyaW5nIHNvdXJjZSwgaW50IG51bWJlcikKICAgIHsKICAgICAgICBpZiAobnVtYmVyIDwgMCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9ICAKICAgICAgICBpZiAoc291cmNlID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpbnQgbGVuZ3RoID0gc291cmNlLmxlbmd0aCgpOwogICAgICAgIAogICAgICAgIC8vIGxlbmd0aCA+PSAwIGtub3duCiAgICAgICAgLy8gc291cmNlIGNvbnRhaW5zIGF0IGxlYXN0IChsZW5ndGggKyAxKSAvIDIgY29kZSBwb2ludHM6IDw9IDIgCiAgICAgICAgLy8gY2hhcnMgcGVyIGNwCiAgICAgICAgaWYgKCgobGVuZ3RoICsgMSkgPj4gMSkgPiBudW1iZXIpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgCiAgICAgICAgLy8gY2hlY2sgaWYgc291cmNlIGRvZXMgbm90IGV2ZW4gY29udGFpbiBlbm91Z2ggY2hhcnMKICAgICAgICBpbnQgbWF4c3VwcGxlbWVudGFyeSA9IGxlbmd0aCAtIG51bWJlcjsKICAgICAgICBpZiAobWF4c3VwcGxlbWVudGFyeSA8PSAwKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gdGhlcmUgYXJlIG1heHN1cHBsZW1lbnRhcnkgPSBsZW5ndGggLSBudW1iZXIgbW9yZSBjaGFycyB0aGFuIAogICAgICAgIC8vIGFza2VkLWZvciBjb2RlIHBvaW50cwogICAgCiAgICAgICAgLy8gY291bnQgY29kZSBwb2ludHMgdW50aWwgdGhleSBleGNlZWQgYW5kIGFsc28gY2hlY2sgdGhhdCB0aGVyZSBhcmUKICAgICAgICAvLyBubyBtb3JlIHRoYW4gbWF4c3VwcGxlbWVudGFyeSBzdXBwbGVtZW50YXJ5IGNvZGUgcG9pbnRzIChjaGFyIHBhaXJzKQogICAgICAgIGludCBzdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgaWYgKGxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG51bWJlciA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQoc3RhcnQgKyspKSAmJiBzdGFydCAhPSBsZW5ndGggCiAgICAgICAgICAgICAgICAmJiBpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQoc3RhcnQpKSkgewogICAgICAgICAgICAgICAgc3RhcnQgKys7CiAgICAgICAgICAgICAgICBpZiAoLS0gbWF4c3VwcGxlbWVudGFyeSA8PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gdG9vIG1hbnkgcGFpcnMgLSB0b28gZmV3IGNvZGUgcG9pbnRzCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC0tIG51bWJlcjsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ2hlY2sgaWYgdGhlIHN1Yi1yYW5nZSBvZiBjaGFyIGFycmF5LCBmcm9tIGFyZ3VtZW50IHN0YXJ0IHRvIGxpbWl0LAogICAgICogY29udGFpbnMgbW9yZSBVbmljb2RlIGNvZGUgcG9pbnRzIHRoYW4gYSBjZXJ0YWluIAogICAgICogbnVtYmVyLiBUaGlzIGlzIG1vcmUgZWZmaWNpZW50IHRoYW4gY291bnRpbmcgYWxsIGNvZGUgcG9pbnRzIGluIHRoZSAKICAgICAqIGVudGlyZSBjaGFyIGFycmF5IHJhbmdlIGFuZCBjb21wYXJpbmcgdGhhdCBudW1iZXIgd2l0aCBhIHRocmVzaG9sZC4KICAgICAqIFRoaXMgZnVuY3Rpb24gbWF5IG5vdCBuZWVkIHRvIHNjYW4gdGhlIGNoYXIgYXJyYXkgYXQgYWxsIGlmIHN0YXJ0IGFuZAogICAgICogbGltaXQgaXMgd2l0aGluIGEgY2VydGFpbiByYW5nZSwgYW5kIG5ldmVyIG5lZWRzIHRvIGNvdW50IG1vcmUgdGhhbiAKICAgICAqICdudW1iZXIgKyAxJyBjb2RlIHBvaW50cy4gCiAgICAgKiBMb2dpY2FsbHkgZXF1aXZhbGVudCB0byAoY291bnRDb2RlUG9pbnQoc291cmNlLCBzdGFydCwgbGltaXQpID4gbnVtYmVyKS4gCiAgICAgKiBBIFVuaWNvZGUgY29kZSBwb2ludCBtYXkgb2NjdXB5IGVpdGhlciBvbmUgb3IgdHdvIGNvZGUgdW5pdHMuCiAgICAgKiBAcGFyYW0gc291cmNlIGFycmF5IG9mIFVURi0xNiBjaGFycwogICAgICogQHBhcmFtIHN0YXJ0IG9mZnNldCB0byBzdWJzdHJpbmcgaW4gdGhlIHNvdXJjZSBhcnJheSBmb3IgYW5hbHl6aW5nCiAgICAgKiBAcGFyYW0gbGltaXQgb2Zmc2V0IHRvIHN1YnN0cmluZyBpbiB0aGUgc291cmNlIGFycmF5IGZvciBhbmFseXppbmcKICAgICAqIEBwYXJhbSBudW1iZXIgVGhlIG51bWJlciBvZiBjb2RlIHBvaW50cyBpbiB0aGUgc3RyaW5nIGlzIGNvbXBhcmVkIAogICAgICogICAgICAgICAgICAgICBhZ2FpbnN0IHRoZSAnbnVtYmVyJyBwYXJhbWV0ZXIuCiAgICAgKiBAcmV0dXJuIGJvb2xlYW4gdmFsdWUgZm9yIHdoZXRoZXIgdGhlIHN0cmluZyBjb250YWlucyBtb3JlIFVuaWNvZGUgY29kZSAKICAgICAqICAgICAgICAgcG9pbnRzIHRoYW4gJ251bWJlcicuCiAgICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gdGhyb3duIHdoZW4gbGltaXQgJmx0OyBzdGFydAogICAgICogQGRyYWZ0IElDVSAyLjQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGhhc01vcmVDb2RlUG9pbnRzVGhhbihjaGFyIHNvdXJjZVtdLCBpbnQgc3RhcnQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGltaXQsIGludCBudW1iZXIpCiAgICB7CiAgICAgICAgaW50IGxlbmd0aCA9IGxpbWl0IC0gc3RhcnQ7CiAgICAgICAgaWYgKGxlbmd0aCA8IDAgfHwgc3RhcnQgPCAwIHx8IGxpbWl0IDwgMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJTdGFydCBhbmQgbGltaXQgaW5kZXhlcyBzaG91bGQgYmUgbm9uLW5lZ2F0aXZlIGFuZCBzdGFydCA8PSBsaW1pdCIpOwogICAgICAgIH0KICAgICAgICBpZiAobnVtYmVyIDwgMCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9ICAKICAgICAgICBpZiAoc291cmNlID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIAogICAgICAgIC8vIGxlbmd0aCA+PSAwIGtub3duCiAgICAgICAgLy8gc291cmNlIGNvbnRhaW5zIGF0IGxlYXN0IChsZW5ndGggKyAxKSAvIDIgY29kZSBwb2ludHM6IDw9IDIgCiAgICAgICAgLy8gY2hhcnMgcGVyIGNwCiAgICAgICAgaWYgKCgobGVuZ3RoICsgMSkgPj4gMSkgPiBudW1iZXIpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgCiAgICAgICAgLy8gY2hlY2sgaWYgc291cmNlIGRvZXMgbm90IGV2ZW4gY29udGFpbiBlbm91Z2ggY2hhcnMKICAgICAgICBpbnQgbWF4c3VwcGxlbWVudGFyeSA9IGxlbmd0aCAtIG51bWJlcjsKICAgICAgICBpZiAobWF4c3VwcGxlbWVudGFyeSA8PSAwKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gdGhlcmUgYXJlIG1heHN1cHBsZW1lbnRhcnkgPSBsZW5ndGggLSBudW1iZXIgbW9yZSBjaGFycyB0aGFuIAogICAgICAgIC8vIGFza2VkLWZvciBjb2RlIHBvaW50cwogICAgCiAgICAgICAgLy8gY291bnQgY29kZSBwb2ludHMgdW50aWwgdGhleSBleGNlZWQgYW5kIGFsc28gY2hlY2sgdGhhdCB0aGVyZSBhcmUKICAgICAgICAvLyBubyBtb3JlIHRoYW4gbWF4c3VwcGxlbWVudGFyeSBzdXBwbGVtZW50YXJ5IGNvZGUgcG9pbnRzIChjaGFyIHBhaXJzKQogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIGlmIChsZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChudW1iZXIgPT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShzb3VyY2Vbc3RhcnQgKytdKSAmJiBzdGFydCAhPSBsaW1pdCAKICAgICAgICAgICAgICAgICYmIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlW3N0YXJ0XSkpIHsKICAgICAgICAgICAgICAgIHN0YXJ0ICsrOwogICAgICAgICAgICAgICAgaWYgKC0tIG1heHN1cHBsZW1lbnRhcnkgPD0gMCkgewogICAgICAgICAgICAgICAgICAgIC8vIHRvbyBtYW55IHBhaXJzIC0gdG9vIGZldyBjb2RlIHBvaW50cwogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAtLSBudW1iZXI7CiAgICAgICAgfQogICAgfQogICAgIAogICAgLyoqCiAgICAgKiBDaGVjayBpZiB0aGUgc3RyaW5nIGJ1ZmZlciBjb250YWlucyBtb3JlIFVuaWNvZGUgY29kZSBwb2ludHMgdGhhbiBhIAogICAgICogY2VydGFpbiBudW1iZXIuIFRoaXMgaXMgbW9yZSBlZmZpY2llbnQgdGhhbiBjb3VudGluZyBhbGwgY29kZSBwb2ludHMgaW4gCiAgICAgKiB0aGUgZW50aXJlIHN0cmluZyBidWZmZXIgYW5kIGNvbXBhcmluZyB0aGF0IG51bWJlciB3aXRoIGEgdGhyZXNob2xkLgogICAgICogVGhpcyBmdW5jdGlvbiBtYXkgbm90IG5lZWQgdG8gc2NhbiB0aGUgc3RyaW5nIGJ1ZmZlciBhdCBhbGwgaWYgdGhlIAogICAgICogbGVuZ3RoIGlzIHdpdGhpbiBhIGNlcnRhaW4gcmFuZ2UsIGFuZCBuZXZlciBuZWVkcyB0byBjb3VudCBtb3JlIHRoYW4gCiAgICAgKiAnbnVtYmVyICsgMScgY29kZSBwb2ludHMuIExvZ2ljYWxseSBlcXVpdmFsZW50IHRvIAogICAgICogKGNvdW50Q29kZVBvaW50KHMpID4gbnVtYmVyKS4gQSBVbmljb2RlIGNvZGUgcG9pbnQgbWF5IG9jY3VweSBlaXRoZXIgb25lIAogICAgICogb3IgdHdvIGNvZGUgdW5pdHMuCiAgICAgKiBAcGFyYW0gc291cmNlIFRoZSBpbnB1dCBzdHJpbmcgYnVmZmVyLgogICAgICogQHBhcmFtIG51bWJlciBUaGUgbnVtYmVyIG9mIGNvZGUgcG9pbnRzIGluIHRoZSBzdHJpbmcgYnVmZmVyIGlzIGNvbXBhcmVkIAogICAgICogICAgICAgICAgICAgICBhZ2FpbnN0IHRoZSAnbnVtYmVyJyBwYXJhbWV0ZXIuCiAgICAgKiBAcmV0dXJuIGJvb2xlYW4gdmFsdWUgZm9yIHdoZXRoZXIgdGhlIHN0cmluZyBidWZmZXIgY29udGFpbnMgbW9yZSAKICAgICAqICAgICAgICAgVW5pY29kZSBjb2RlIHBvaW50cyB0aGFuICdudW1iZXInLgogICAgICogQGRyYWZ0IElDVSAyLjQKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGhhc01vcmVDb2RlUG9pbnRzVGhhbihTdHJpbmdCdWZmZXIgc291cmNlLCBpbnQgbnVtYmVyKQogICAgewogICAgICAgIGlmIChudW1iZXIgPCAwKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0gIAogICAgICAgIGlmIChzb3VyY2UgPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGludCBsZW5ndGggPSBzb3VyY2UubGVuZ3RoKCk7CiAgICAgICAgCiAgICAgICAgLy8gbGVuZ3RoID49IDAga25vd24KICAgICAgICAvLyBzb3VyY2UgY29udGFpbnMgYXQgbGVhc3QgKGxlbmd0aCArIDEpIC8gMiBjb2RlIHBvaW50czogPD0gMiAKICAgICAgICAvLyBjaGFycyBwZXIgY3AKICAgICAgICBpZiAoKChsZW5ndGggKyAxKSA+PiAxKSA+IG51bWJlcikgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAKICAgICAgICAvLyBjaGVjayBpZiBzb3VyY2UgZG9lcyBub3QgZXZlbiBjb250YWluIGVub3VnaCBjaGFycwogICAgICAgIGludCBtYXhzdXBwbGVtZW50YXJ5ID0gbGVuZ3RoIC0gbnVtYmVyOwogICAgICAgIGlmIChtYXhzdXBwbGVtZW50YXJ5IDw9IDApIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyB0aGVyZSBhcmUgbWF4c3VwcGxlbWVudGFyeSA9IGxlbmd0aCAtIG51bWJlciBtb3JlIGNoYXJzIHRoYW4gCiAgICAgICAgLy8gYXNrZWQtZm9yIGNvZGUgcG9pbnRzCiAgICAKICAgICAgICAvLyBjb3VudCBjb2RlIHBvaW50cyB1bnRpbCB0aGV5IGV4Y2VlZCBhbmQgYWxzbyBjaGVjayB0aGF0IHRoZXJlIGFyZQogICAgICAgIC8vIG5vIG1vcmUgdGhhbiBtYXhzdXBwbGVtZW50YXJ5IHN1cHBsZW1lbnRhcnkgY29kZSBwb2ludHMgKGNoYXIgcGFpcnMpCiAgICAgICAgaW50IHN0YXJ0ID0gMDsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBpZiAobGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobnVtYmVyID09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoc291cmNlLmNoYXJBdChzdGFydCArKykpICYmIHN0YXJ0ICE9IGxlbmd0aCAKICAgICAgICAgICAgICAgICYmIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlLmNoYXJBdChzdGFydCkpKSB7CiAgICAgICAgICAgICAgICBzdGFydCArKzsKICAgICAgICAgICAgICAgIGlmICgtLSBtYXhzdXBwbGVtZW50YXJ5IDw9IDApIHsKICAgICAgICAgICAgICAgICAgICAvLyB0b28gbWFueSBwYWlycyAtIHRvbyBmZXcgY29kZSBwb2ludHMKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLS0gbnVtYmVyOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAqIDxwPlVURjE2IHN0cmluZyBjb21wYXJhdG9yIGNsYXNzLgogICAgKiBBbGxvd3MgVVRGMTYgc3RyaW5nIGNvbXBhcmlzb24gdG8gYmUgZG9uZSB3aXRoIHRoZSB2YXJpb3VzIG1vZGVzPC9wPgogICAgKiA8dWw+CiAgICAqIDxsaT4gQ29kZSBwb2ludCBjb21wYXJpc29uIG9yIGNvZGUgdW5pdCBjb21wYXJpc29uCiAgICAqIDxsaT4gQ2FzZSBzZW5zaXRpdmUgY29tcGFyaXNvbiwgY2FzZSBpbnNlbnNpdGl2ZSBjb21wYXJpc29uIG9yIGNhc2UgCiAgICAqICAgICAgaW5zZW5zaXRpdmUgY29tcGFyaXNvbiB3aXRoIHNwZWNpYWwgaGFuZGxpbmcgZm9yIGNoYXJhY3RlciAnaScuCiAgICAqIDwvdWw+CiAgICAqIDxwPlRoZSBjb2RlIHVuaXQgb3IgY29kZSBwb2ludCBjb21wYXJpc29uIGRpZmZlciBvbmx5IHdoZW4gY29tcGFyaW5nIAogICAgKiBzdXBwbGVtZW50YXJ5IGNvZGUgcG9pbnRzICgmIzkyO3UxMDAwMC4uJiM5Mjt1MTBmZmZmKSB0byBCTVAgY29kZSBwb2ludHMgCiAgICAqIG5lYXIgdGhlIGVuZCBvZiB0aGUgQk1QIChpLmUuLCAmIzkyO3VlMDAwLi4mIzkyO3VmZmZmKS4gSW4gY29kZSB1bml0IAogICAgKiBjb21wYXJpc29uLCBoaWdoIEJNUCBjb2RlIHBvaW50cyBzb3J0IGFmdGVyIHN1cHBsZW1lbnRhcnkgY29kZSBwb2ludHMgCiAgICAqIGJlY2F1c2UgdGhleSBhcmUgc3RvcmVkIGFzIHBhaXJzIG9mIHN1cnJvZ2F0ZXMgd2hpY2ggYXJlIGF0IAogICAgKiAmIzkyO3VkODAwLi4mIzkyO3VkZmZmLjwvcD4KICAgICogQHNlZSAjRk9MRF9DQVNFX0RFRkFVTFQKICAgICogQHNlZSAjRk9MRF9DQVNFX0VYQ0xVREVfU1BFQ0lBTF9JCiAgICAqIEBzdGFibGUgSUNVIDIuMQogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nQ29tcGFyYXRvciBpbXBsZW1lbnRzIGphdmEudXRpbC5Db21wYXJhdG9yIAogICAgewogICAgICAgIC8vIHB1YmxpYyBjb25zdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yIHRoYXQgZG9lcyBjb2RlIHVuaXQgY29tcGFyaXNvbiBhbmQgY2FzZSAKICAgICAgICAgKiBzZW5zaXRpdmUgY29tcGFyaXNvbi4KICAgICAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgU3RyaW5nQ29tcGFyYXRvcigpCiAgICAgICAgewogICAgICAgICAgICB0aGlzKGZhbHNlLCBmYWxzZSwgRk9MRF9DQVNFX0RFRkFVTFQpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiBDb25zdHJ1Y3RvciB0aGF0IGRvZXMgY29tcGFyaXNvbiBiYXNlZCBvbiB0aGUgYXJndW1lbnQgb3B0aW9ucy4KICAgICAgICAgKiBAcGFyYW0gY29kZXBvaW50Y29tcGFyZSBmbGFnIHRvIGluZGljYXRlIHRydWUgZm9yIGNvZGUgcG9pbnQgCiAgICAgICAgICogICAgICAgIGNvbXBhcmlzb24gb3IgZmFsc2UgZm9yIGNvZGUgdW5pdCBjb21wYXJpc29uLgogICAgICAgICAqIEBwYXJhbSBpZ25vcmVjYXNlIGZhbHNlIGZvciBjYXNlIHNlbnNpdGl2ZSBjb21wYXJpc29uLCB0cnVlIGZvcgogICAgICAgICAqICAgICAgICBjYXNlLWluc2Vuc2l0aXZlIGNvbXBhcmlzb24KICAgICAgICAgKiBAcGFyYW0gZm9sZGNhc2VvcHRpb24gRk9MRF9DQVNFX0RFRkFVTFQgb3IgCiAgICAgICAgICogICAgICAgIEZPTERfQ0FTRV9FWENMVURFX1NQRUNJQUxfSS4gVGhpcyBvcHRpb24gaXMgdXNlZCBvbmx5IHdoZW4KICAgICAgICAgKiAgICAgICAgaWdub3JlY2FzZSBpcyBzZXQgdG8gdHJ1ZS4gSWYgaWdub3JlY2FzZSBpcyBmYWxzZSwgdGhpcyBvcHRpb24KICAgICAgICAgKiAgICAgICAgaXMgaWdub3JlZC4KICAgICAgICAgKiBAc2VlICNGT0xEX0NBU0VfREVGQVVMVAogICAgICAgICAqIEBzZWUgI0ZPTERfQ0FTRV9FWENMVURFX1NQRUNJQUxfSQogICAgICAgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIGZvbGRjYXNlb3B0aW9uIGlzIG91dCBvZiByYW5nZQogICAgICAgICAqIEBkcmFmdCBJQ1UgMi40CiAgICAgICAgICovCiAgICAgICAgcHVibGljIFN0cmluZ0NvbXBhcmF0b3IoYm9vbGVhbiBjb2RlcG9pbnRjb21wYXJlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGlnbm9yZWNhc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZvbGRjYXNlb3B0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgc2V0Q29kZVBvaW50Q29tcGFyZShjb2RlcG9pbnRjb21wYXJlKTsKICAgICAgICAgICAgbV9pZ25vcmVDYXNlXyA9IGlnbm9yZWNhc2U7ICAgCiAgICAgICAgICAgIGlmIChmb2xkY2FzZW9wdGlvbiA8IEZPTERfQ0FTRV9ERUZBVUxUIAogICAgICAgICAgICAgICAgfHwgZm9sZGNhc2VvcHRpb24gPiBGT0xEX0NBU0VfRVhDTFVERV9TUEVDSUFMX0kpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgZm9sZCBjYXNlIG9wdGlvbiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG1fZm9sZENhc2VfID0gZm9sZGNhc2VvcHRpb247CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIHB1YmxpYyBkYXRhIG1lbWJlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAKICAgICAgICAvKiogCiAgICAgICAgICogPHA+T3B0aW9uIHZhbHVlIGZvciBjYXNlIGZvbGRpbmcgY29tcGFyaXNvbjo8L3A+IAogICAgICAgICAqIDxwPkNvbXBhcmlzb24gaXMgY2FzZSBpbnNlbnNpdGl2ZSwgc3RyaW5ncyBhcmUgZm9sZGVkIHVzaW5nIGRlZmF1bHQgCiAgICAgICAgICogbWFwcGluZ3MgZGVmaW5lZCBpbiBVbmljb2RlIGRhdGEgZmlsZSBDYXNlRm9sZGluZy50eHQsIGJlZm9yZSAKICAgICAgICAgKiBjb21wYXJpc29uLiAKICAgICAgICAgKiA8L3A+CiAgICAgICAgICogQGRyYWZ0IElDVSAyLjQKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT0xEX0NBU0VfREVGQVVMVCA9IDA7CiAgICAgICAgLyoqCiAgICAgICAgICogPHA+T3B0aW9uIHZhbHVlIGZvciBjYXNlIGZvbGRpbmcgY29tcGFyaXNvbjo8L3A+CiAgICAgICAgICogPHA+Q29tcGFyaXNvbiBpcyBjYXNlIGluc2Vuc2l0aXZlLCBzdHJpbmdzIGFyZSBmb2xkZWQgdXNpbmcgbW9kaWZpZWQgCiAgICAgICAgICogbWFwcGluZ3MgZGVmaW5lZCBpbiBVbmljb2RlIGRhdGEgZmlsZSBDYXNlRm9sZGluZy50eHQsIGJlZm9yZSAKICAgICAgICAgKiBjb21wYXJpc29uLiAKICAgICAgICAgKiA8L3A+CiAgICAgICAgICogPHA+VGhlIG1vZGlmaWVkIHNldCBvZiBtYXBwaW5ncyBpcyBwcm92aWRlZCBpbiBhIFVuaWNvZGUgZGF0YSBmaWxlCiAgICAgICAgICogQ2FzZUZvbGRpbmcudHh0IHRvIGhhbmRsZSBkb3R0ZWQgSSBhbmQgZG90bGVzcyBpIGFwcHJvcHJpYXRlbHkgZm9yIAogICAgICAgICAqIFR1cmtpYyBsYW5ndWFnZXMgKHRyLCBheikuPC9wPgogICAgICAgICAqIDxwPkJlZm9yZSBVbmljb2RlIDMuMiwgQ2FzZUZvbGRpbmcudHh0IGNvbnRhaW5zIG1hcHBpbmdzIG1hcmtlZCB3aXRoIAogICAgICAgICAqICdJJyB0aGF0IGFyZSB0byBiZSBpbmNsdWRlZCBmb3IgZGVmYXVsdCBtYXBwaW5ncyBhbmQgZXhjbHVkZWQgZm9yIAogICAgICAgICAqIHRoZSBUdXJraWMtc3BlY2lmaWMgbWFwcGluZ3MuPC9wPgogICAgICAgICAqIDxwPlVuaWNvZGUgMy4yIENhc2VGb2xkaW5nLnR4dCBpbnN0ZWFkIGNvbnRhaW5zIG1hcHBpbmdzIG1hcmtlZCB3aXRoIAogICAgICAgICAqICdUJyB0aGF0IGFyZSB0byBiZSBleGNsdWRlZCBmb3IgZGVmYXVsdCBtYXBwaW5ncyBhbmQgaW5jbHVkZWQgZm9yIAogICAgICAgICAqIHRoZSBUdXJraWMtc3BlY2lmaWMgbWFwcGluZ3MuPC9wPgogICAgICAgICAqIEBkcmFmdCBJQ1UgMi40CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9MRF9DQVNFX0VYQ0xVREVfU1BFQ0lBTF9JID0gMTsKICAgICAgICAKICAgICAgICAvLyBwdWJsaWMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgCiAgICAgICAgLy8gcHVibGljIHNldHRlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIAogICAgICAgIC8qKgogICAgICAgICAqIFNldHMgdGhlIGNvbXBhcmlzb24gbW9kZSB0byBjb2RlIHBvaW50IGNvbXBhcmUgaWYgZmxhZyBpcyB0cnVlLgogICAgICAgICAqIE90aGVyd2lzZSBjb21wYXJpc29uIG1vZGUgaXMgc2V0IHRvIGNvZGUgdW5pdCBjb21wYXJlCiAgICAgICAgICogQHBhcmFtIGZsYWcgdHJ1ZSBmb3IgY29kZSBwb2ludCBjb21wYXJlLCBmYWxzZSBmb3IgY29kZSB1bml0IGNvbXBhcmUKICAgICAgICAgKiBAZHJhZnQgSUNVIDIuNAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIHNldENvZGVQb2ludENvbXBhcmUoYm9vbGVhbiBmbGFnKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGZsYWcpIHsKICAgICAgICAgICAgICAgIG1fY29kZVBvaW50Q29tcGFyZV8gPSBOb3JtYWxpemVyLkNPTVBBUkVfQ09ERV9QT0lOVF9PUkRFUjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIG1fY29kZVBvaW50Q29tcGFyZV8gPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8qKgogICAgICAgICAqIFNldHMgdGhlIENvbXBhcmF0b3IgdG8gY2FzZS1pbnNlbnNpdGl2ZSBjb21wYXJpc29uIG1vZGUgaWYgYXJndW1lbnQgCiAgICAgICAgICogaXMgdHJ1ZSwgb3RoZXJ3aXNlIGNhc2Ugc2Vuc2l0aXZlIGNvbXBhcmlzb24gbW9kZSBpZiBzZXQgdG8gZmFsc2UuCiAgICAgICAgICogQHBhcmFtIGlnbm9yZWNhc2UgdHJ1ZSBmb3IgY2FzZS1pbnNpdGl2ZSBjb21wYXJpc29uLCBmYWxzZSBmb3IKICAgICAgICAgKiAgICAgICAgY2FzZSBzZW5zaXRpdmUgY29tcGFyaXNvbgogICAgICAgICAqIEBwYXJhbSBmb2xkY2FzZW9wdGlvbnMgRk9MRF9DQVNFX0RFRkFVTFQgb3IgCiAgICAgICAgICogICAgICAgIEZPTERfQ0FTRV9FWENMVURFX1NQRUNJQUxfSS4gVGhpcyBvcHRpb24gaXMgdXNlZCBvbmx5IHdoZW4KICAgICAgICAgKiAgICAgICAgaWdub3JlY2FzZSBpcyBzZXQgdG8gdHJ1ZS4gSWYgaWdub3JlY2FzZSBpcyBmYWxzZSwgdGhpcyBvcHRpb24KICAgICAgICAgKiAgICAgICAgaXMgaWdub3JlZC4KICAgICAgICAgKiBAc2VlICNGT0xEX0NBU0VfREVGQVVMVAogICAgICAgICAqIEBzZWUgI0ZPTERfQ0FTRV9FWENMVURFX1NQRUNJQUxfSQogICAgICAgICAqIEBkcmFmdCBJQ1UgMi40CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHZvaWQgc2V0SWdub3JlQ2FzZShib29sZWFuIGlnbm9yZWNhc2UsIGludCBmb2xkY2FzZW9wdGlvbikgCiAgICAgICAgewogICAgICAgICAgICBtX2lnbm9yZUNhc2VfID0gaWdub3JlY2FzZTsKICAgICAgICAgICAgaWYgKGZvbGRjYXNlb3B0aW9uIDwgRk9MRF9DQVNFX0RFRkFVTFQgCiAgICAgICAgICAgICAgICB8fCBmb2xkY2FzZW9wdGlvbiA+IEZPTERfQ0FTRV9FWENMVURFX1NQRUNJQUxfSSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBmb2xkIGNhc2Ugb3B0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbV9mb2xkQ2FzZV8gPSBmb2xkY2FzZW9wdGlvbjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gcHVibGljIGdldHRlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIAogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrcyBpZiB0aGUgY29tcGFyaXNvbiBtb2RlIGlzIGNvZGUgcG9pbnQgY29tcGFyZS4KICAgICAgICAgKiBAcmV0dXJuIHRydWUgZm9yIGNvZGUgcG9pbnQgY29tcGFyZSwgZmFsc2UgZm9yIGNvZGUgdW5pdCBjb21wYXJlCiAgICAgICAgICogQGRyYWZ0IElDVSAyLjQKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBnZXRDb2RlUG9pbnRDb21wYXJlKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBtX2NvZGVQb2ludENvbXBhcmVfID09IE5vcm1hbGl6ZXIuQ09NUEFSRV9DT0RFX1BPSU5UX09SREVSOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiBDaGVja3MgaWYgQ29tcGFyYXRvciBpcyBpbiB0aGUgY2FzZSBpbnNlbnNpdGl2ZSBtb2RlLgogICAgICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBDb21wYXJhdG9yIHBlcmZvcm1zIGNhc2UgaW5zZW5zaXRpdmUgY29tcGFyaXNvbiwgCiAgICAgICAgICogICAgICAgICBmYWxzZSBvdGhlcndpc2UKICAgICAgICAgKiBAZHJhZnQgSUNVIDIuNAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBib29sZWFuIGdldElnbm9yZUNhc2UoKSAKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBtX2lnbm9yZUNhc2VfOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiBHZXRzIHRoZSBmb2xkIGNhc2Ugb3B0aW9ucyBzZXQgaW4gQ29tcGFyYXRvciB0byBiZSB1c2VkIHdpdGggY2FzZSAKICAgICAgICAgKiBpbnNlbnNpdGl2ZSBjb21wYXJpc29uLiAKICAgICAgICAgKiBAcmV0dXJuIGVpdGhlciBGT0xEX0NBU0VfREVGQVVMVCBvciBGT0xEX0NBU0VfRVhDTFVERV9TUEVDSUFMX0kKICAgICAgICAgKiBAc2VlICNGT0xEX0NBU0VfREVGQVVMVAogICAgICAgICAqIEBzZWUgI0ZPTERfQ0FTRV9FWENMVURFX1NQRUNJQUxfSQogICAgICAgICAqIEBkcmFmdCBJQ1UgMi40CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCBnZXRJZ25vcmVDYXNlT3B0aW9uKCkgCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbV9mb2xkQ2FzZV87CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIHB1YmxpYyBvdGhlciBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiBDb21wYXJlIHR3byBzdHJpbmdzIGRlcGVuZGluZyBvbiB0aGUgb3B0aW9ucyBzZWxlY3RlZCBkdXJpbmcgCiAgICAgICAgICogY29uc3RydWN0aW9uLgogICAgICAgICAqIEBwYXJhbSBhIGZpcnN0IHNvdXJjZSBzdHJpbmcuCiAgICAgICAgICogQHBhcmFtIGIgc2Vjb25kIHNvdXJjZSBzdHJpbmcuCiAgICAgICAgICogQHJldHVybiAwIHJldHVybmVkIGlmIGEgPT0gYi4gSWYgYSA8IGIsIGEgbmVnYXRpdmUgdmFsdWUgaXMgcmV0dXJuZWQuCiAgICAgICAgICogICAgICAgICBPdGhlcndpc2UgaWYgYSA+IGIsIGEgcG9zaXRpdmUgdmFsdWUgaXMgcmV0dXJuZWQuCiAgICAgICAgICogQGV4Y2VwdGlvbiBDbGFzc0Nhc3RFeGNlcHRpb24gdGhyb3duIHdoZW4gZWl0aGVyIGEgb3IgYiBpcyBub3QgYSAKICAgICAgICAgKiAgICAgICAgICAgIFN0cmluZyBvYmplY3QKICAgICAgICAgKiBAZHJhZnQgSUNVIDIuNAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZShPYmplY3QgYSwgT2JqZWN0IGIpIAogICAgICAgIHsKICAgICAgICAgICAgU3RyaW5nIHN0cjEgPSAoU3RyaW5nKWE7CiAgICAgICAgICAgIFN0cmluZyBzdHIyID0gKFN0cmluZyliOwogICAgICAgICAgICAKCSAgICAgICAgaWYgKHN0cjEgPT0gc3RyMikgewoJICAgICAgICAJcmV0dXJuIDA7CgkgICAgICAgIH0KCSAgICAgICAgaWYgKHN0cjEgPT0gbnVsbCkgewoJICAgICAgICAgICAgcmV0dXJuIC0xOwoJICAgICAgICB9CgkgICAgICAgIGlmIChzdHIyID09IG51bGwpIHsKCSAgICAgICAgICAgIHJldHVybiAxOwoJICAgICAgICB9CgkgICAgICAgIAogICAgICAgICAgICBpZiAobV9pZ25vcmVDYXNlXykgewogICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmVDYXNlSW5zZW5zaXRpdmUoc3RyMSwgc3RyMik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmVDYXNlU2Vuc2l0aXZlKHN0cjEsIHN0cjIpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBwcml2YXRlIGRhdGEgbWVtYmVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiBDb2RlIHVuaXQgY29tcGFyaXNvbiBmbGFnLiBUcnVlIGlmIGNvZGUgdW5pdCBjb21wYXJpc29uIGlzIHJlcXVpcmVkLgogICAgICAgICAqIEZhbHNlIGlmIGNvZGUgcG9pbnQgY29tcGFyaXNvbiBpcyByZXF1aXJlZC4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIGludCBtX2NvZGVQb2ludENvbXBhcmVfOwogICAgICAgIC8qKgogICAgICAgICAqIEZvbGQgY2FzZSBjb21wYXJpc29uIG9wdGlvbi4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIGludCBtX2ZvbGRDYXNlXzsKICAgICAgICAvKiogCiAgICAgICAgICogRmxhZyBpbmRpY2F0b3IgaWYgaWdub3JlIGNhc2UgaXMgdG8gYmUgdXNlZCBkdXJpbmcgY29tcGFyaXNvbgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgYm9vbGVhbiBtX2lnbm9yZUNhc2VfOwogICAgICAgIC8qKgogICAgICAgICAqIENvZGUgcG9pbnQgb3JkZXIgb2Zmc2V0IGZvciBzdXJyb2dhdGUgY2hhcmFjdGVycwogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDT0RFX1BPSU5UX0NPTVBBUkVfU1VSUk9HQVRFX09GRlNFVF8gPSAweDI4MDA7CiAgICAgICAgCiAgICAgICAgLy8gcHJpdmF0ZSBtZXRob2QgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgCiAgICAgICAgLyoqCiAgICAgICAgICogQ29tcGFyZXMgY2FzZSBpbnNlbnNpdGl2ZS4gVGhpcyBpcyBhIGRpcmVjdCBwb3J0IG9mIElDVTRDLCB0byBtYWtlCiAgICAgICAgICogbWFpbnRhaW5lbmNlIGxpZmUgZWFzaWVyLgogICAgICAgICAqIEBwYXJhbSBzMSBmaXJzdCBzdHJpbmcgdG8gY29tcGFyZQogICAgICAgICAqIEBwYXJhbSBzMiBzZWNvbmQgc3RyaW5nIHRvIGNvbXBhcmUKICAgICAgICAgKiBAcmV0dXJuIC0xIGlzIHMxICZsdDsgczIsIDAgaWYgZXF1YWxzLCAKICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIGludCBjb21wYXJlQ2FzZUluc2Vuc2l0aXZlKFN0cmluZyBzMSwgU3RyaW5nIHMyKSAgCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gTm9ybWFsaXplckltcGwuY21wRXF1aXZGb2xkKHMxLCBzMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2ZvbGRDYXNlXyB8IG1fY29kZVBvaW50Q29tcGFyZV8gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IE5vcm1hbGl6ZXIuQ09NUEFSRV9JR05PUkVfQ0FTRSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBDb21wYXJlcyBjYXNlIHNlbnNpdGl2ZS4gVGhpcyBpcyBhIGRpcmVjdCBwb3J0IG9mIElDVTRDLCB0byBtYWtlCiAgICAgICAgICogbWFpbnRhaW5lbmNlIGxpZmUgZWFzaWVyLgogICAgICAgICAqIEBwYXJhbSBzMSBmaXJzdCBzdHJpbmcgdG8gY29tcGFyZQogICAgICAgICAqIEBwYXJhbSBzMiBzZWNvbmQgc3RyaW5nIHRvIGNvbXBhcmUKICAgICAgICAgKiBAcmV0dXJuIC0xIGlzIHMxICZsdDsgczIsIDAgaWYgZXF1YWxzLCAKICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIGludCBjb21wYXJlQ2FzZVNlbnNpdGl2ZShTdHJpbmcgczEsIFN0cmluZyBzMikgCiAgICAgICAgewogICAgICAgICAgICAvLyBjb21wYXJlIGlkZW50aWNhbCBwcmVmaXhlcyAtIHRoZXkgZG8gbm90IG5lZWQgdG8gYmUgZml4ZWQgdXAKICAgICAgICAgICAgLy8gbGltaXQxID0gc3RhcnQxICsgbWluKGxlbmdodDEsIGxlbmd0aDIpCiAgICAgICAgICAgIGludCBsZW5ndGgxID0gczEubGVuZ3RoKCk7CiAgICAgICAgICAgIGludCBsZW5ndGgyID0gczIubGVuZ3RoKCk7CiAgICAgICAgICAgIGludCBtaW5sZW5ndGggPSBsZW5ndGgxOwogICAgICAgICAgICBpbnQgcmVzdWx0ID0gMDsKICAgICAgICAgICAgaWYgKGxlbmd0aDEgPCBsZW5ndGgyKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChsZW5ndGgxID4gbGVuZ3RoMikgewogICAgICAgICAgICAgICAgcmVzdWx0ID0gMTsKICAgICAgICAgICAgICAgIG1pbmxlbmd0aCA9IGxlbmd0aDI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICBjaGFyIGMxID0gMDsKICAgICAgICAgICAgY2hhciBjMiA9IDA7CiAgICAgICAgICAgIGludCBpbmRleCA9IDA7CiAgICAgICAgICAgIGZvciAoOyBpbmRleCA8IG1pbmxlbmd0aDsgaW5kZXggKyspIHsKICAgICAgICAgICAgICAgIGMxID0gczEuY2hhckF0KGluZGV4KTsKICAgICAgICAgICAgICAgIGMyID0gczIuY2hhckF0KGluZGV4KTsKICAgICAgICAgICAgICAgIC8vIGNoZWNrIHBzZXVkby1saW1pdAogICAgICAgICAgICAgICAgaWYgKGMxICE9IGMyKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICAgICAgaWYgKGluZGV4ID09IG1pbmxlbmd0aCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgYm9vbGVhbiBjb2RlcG9pbnRjb21wYXJlIAogICAgICAgICAgICAgICAgPSBtX2NvZGVQb2ludENvbXBhcmVfID09IE5vcm1hbGl6ZXIuQ09NUEFSRV9DT0RFX1BPSU5UX09SREVSOwogICAgICAgICAgICAvLyBpZiBib3RoIHZhbHVlcyBhcmUgaW4gb3IgYWJvdmUgdGhlIHN1cnJvZ2F0ZSByYW5nZSwgZml4IHRoZW0gdXAKICAgICAgICAgICAgaWYgKGMxID49IExFQURfU1VSUk9HQVRFX01JTl9WQUxVRSAKICAgICAgICAgICAgICAgICYmIGMyID49IExFQURfU1VSUk9HQVRFX01JTl9WQUxVRSAmJiBjb2RlcG9pbnRjb21wYXJlKSB7CiAgICAgICAgICAgICAgICAvLyBzdWJ0cmFjdCAweDI4MDAgZnJvbSBCTVAgY29kZSBwb2ludHMgdG8gbWFrZSB0aGVtIHNtYWxsZXIgCiAgICAgICAgICAgICAgICAvLyB0aGFuIHN1cHBsZW1lbnRhcnkgb25lcwogICAgICAgICAgICAgICAgaWYgKChjMSA8PSBMRUFEX1NVUlJPR0FURV9NQVhfVkFMVUUgJiYgKGluZGV4ICsgMSkgIT0gbGVuZ3RoMSAKICAgICAgICAgICAgICAgICAgICAmJiBpc1RyYWlsU3Vycm9nYXRlKHMxLmNoYXJBdChpbmRleCArIDEpKSkgCiAgICAgICAgICAgICAgICAgICAgfHwgKGlzVHJhaWxTdXJyb2dhdGUoYzEpICYmIGluZGV4ICE9IDAgCiAgICAgICAgICAgICAgICAgICAgICAgICYmIGlzTGVhZFN1cnJvZ2F0ZShzMS5jaGFyQXQoaW5kZXggLSAxKSkpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gcGFydCBvZiBhIHN1cnJvZ2F0ZSBwYWlyLCBsZWF2ZSA+PWQ4MDAKICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBCTVAgY29kZSBwb2ludCAtIG1heSBiZSBzdXJyb2dhdGUgY29kZSBwb2ludCAtIG1ha2UgCiAgICAgICAgICAgICAgICAgICAgLy8gPCBkODAwCiAgICAgICAgICAgICAgICAgICAgYzEgLT0gQ09ERV9QT0lOVF9DT01QQVJFX1NVUlJPR0FURV9PRkZTRVRfOwogICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgaWYgKChjMiA8PSBMRUFEX1NVUlJPR0FURV9NQVhfVkFMVUUgCiAgICAgICAgICAgICAgICAgICAgICYmIChpbmRleCArIDEpICE9IGxlbmd0aDIgCiAgICAgICAgICAgICAgICAgICAgICYmIGlzVHJhaWxTdXJyb2dhdGUoczIuY2hhckF0KGluZGV4ICsgMSkpKSB8fAogICAgICAgICAgICAgICAgICAgIChpc1RyYWlsU3Vycm9nYXRlKGMyKSAmJiBpbmRleCAhPSAwIAogICAgICAgICAgICAgICAgICAgICAmJiBpc0xlYWRTdXJyb2dhdGUoczIuY2hhckF0KGluZGV4IC0gMSkpKSkgewogICAgICAgICAgICAgICAgICAgIC8vIHBhcnQgb2YgYSBzdXJyb2dhdGUgcGFpciwgbGVhdmUgPj1kODAwCiAgICAgICAgICAgICAgICB9IAogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gQk1QIGNvZGUgcG9pbnQgLSBtYXkgYmUgc3Vycm9nYXRlIGNvZGUgcG9pbnQgLSBtYWtlIDxkODAwCiAgICAgICAgICAgICAgICAgICAgYzIgLT0gQ09ERV9QT0lOVF9DT01QQVJFX1NVUlJPR0FURV9PRkZTRVRfOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgICAgIC8vIG5vdyBjMSBhbmQgYzIgYXJlIGluIFVURi0zMi1jb21wYXRpYmxlIG9yZGVyCiAgICAgICAgICAgIHJldHVybiBjMSAtIGMyOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLy8gcHJpdmF0ZSBkYXRhIG1lbWJlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgLyoqCiAgICAqIFNoaWZ0IHZhbHVlIGZvciBsZWFkIHN1cnJvZ2F0ZSB0byBmb3JtIGEgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIuCiAgICAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExFQURfU1VSUk9HQVRFX1NISUZUXyA9IDEwOwoJLyoqCiAgICAqIE1hc2sgdG8gcmV0cmlldmUgdGhlIHNpZ25pZmljYW50IHZhbHVlIGZyb20gYSB0cmFpbCBzdXJyb2dhdGUuCiAgICAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRSQUlMX1NVUlJPR0FURV9NQVNLXyAgICAgPSAweDNGRjsgICAKICAgIC8qKgogICAgICogVmFsdWUgdGhhdCBhbGwgbGVhZCBzdXJyb2dhdGUgc3RhcnRzIHdpdGgKICAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExFQURfU1VSUk9HQVRFX09GRlNFVF8gPSAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExFQURfU1VSUk9HQVRFX01JTl9WQUxVRSAtIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PiBMRUFEX1NVUlJPR0FURV9TSElGVF8pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAvLyBwcml2YXRlIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKICAgIC8qKgogICAgKiA8cD5Db252ZXJ0cyBhcmd1bWVudCBjb2RlIHBvaW50IGFuZCByZXR1cm5zIGEgU3RyaW5nIG9iamVjdCByZXByZXNlbnRpbmcgCiAgICAqIHRoZSBjb2RlIHBvaW50J3MgdmFsdWUgaW4gVVRGMTYgZm9ybWF0LjwvcD4KICAgICogPHA+VGhpcyBtZXRob2QgZG9lcyBub3QgY2hlY2sgZm9yIHRoZSB2YWxpZGl0eSBvZiB0aGUgY29kZXBvaW50LCB0aGUKICAgICogcmVzdWx0cyBhcmUgbm90IGd1YXJhbnRlZWQgaWYgYSBpbnZhbGlkIGNvZGVwb2ludCBpcyBwYXNzZWQgYXMgCiAgICAqIGFyZ3VtZW50LjwvcD4KICAgICogPHA+VGhlIHJlc3VsdCBpcyBhIHN0cmluZyB3aG9zZSBsZW5ndGggaXMgMSBmb3Igbm9uLXN1cHBsZW1lbnRhcnkgY29kZSAKICAgICogcG9pbnRzLCAyIG90aGVyd2lzZS48L3A+CiAgICAqIEBwYXJhbSBjaCBjb2RlIHBvaW50CiAgICAqIEByZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb2RlIHBvaW50CiAgICAqIEBvYnNvbGV0ZSBJQ1UgMi40LiBVc2UgVUNoYXJhY3Rlci50b1N0cmluZyhpbnQpIGluc3RlYWQgc2luY2UgaXQgd2lsbCBiZQogICAgKiAgICAgICAgICAgcmVtb3ZlZCBpbiB0aGF0IHJlbGVhc2UuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoaW50IGNoKQogICAgeyAgIAogICAgICAgIGlmIChjaCA8IFNVUFBMRU1FTlRBUllfTUlOX1ZBTFVFKSB7CiAgICAgICAgICAgIHJldHVybiBTdHJpbmcudmFsdWVPZigoY2hhciljaCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIFN0cmluZ0J1ZmZlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CiAgICAgICAgcmVzdWx0LmFwcGVuZChnZXRMZWFkU3Vycm9nYXRlKGNoKSk7CiAgICAgICAgcmVzdWx0LmFwcGVuZChnZXRUcmFpbFN1cnJvZ2F0ZShjaCkpOwogICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKICAgIH0KfQo=