LyoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwMSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAgKgoqIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKgoqICRTb3VyY2U6IC94c3JsL05zdm4vaWN1L2ljdTRqL3NyYy9jb20vaWJtL2ljdS90ZXh0L1VURjE2LmphdmEsdiAkIAoqICREYXRlOiAyMDAyLzA0LzAzIDIyOjQ4OjEwICQgCiogJFJldmlzaW9uOiAxLjE5ICQKKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCgpwYWNrYWdlIGNvbS5pYm0uaWN1LnRleHQ7CgppbXBvcnQgY29tLmlibS5pY3UuaW1wbC5VQ2hhcmFjdGVyUHJvcGVydHk7Ci8qKgoqIFN0YW5kYWxvbmUgdXRpbGl0eSBjbGFzcyBwcm92aWRpbmcgVVRGMTYgY2hhcmFjdGVyIGNvbnZlcnNpb25zIGFuZCBpbmRleGluZyAKKiBjb252ZXJzaW9ucy4KKiA8cD5Db2RlIHRoYXQgdXNlcyBzdHJpbmdzIGFsb25lIHJhcmVseSBuZWVkIG1vZGlmaWNhdGlvbi4gCiogQnkgZGVzaWduLCBVVEYtMTYgZG9lcyBub3QgYWxsb3cgb3ZlcmxhcCwgc28gc2VhcmNoaW5nIGZvciBzdHJpbmdzIGlzIGEgc2FmZSAKKiBvcGVyYXRpb24uIFNpbWlsYXJseSwgY29uY2F0ZW5hdGlvbiBpcyBhbHdheXMgc2FmZS4gU3Vic3RyaW5naW5nIGlzIHNhZmUgaWYgCiogdGhlIHN0YXJ0IGFuZCBlbmQgYXJlIGJvdGggb24gVVRGLTMyIGJvdW5kYXJpZXMuIEluIG5vcm1hbCBjb2RlLCB0aGUgdmFsdWVzIAoqIGZvciBzdGFydCBhbmQgZW5kIGFyZSBvbiB0aG9zZSBib3VuZGFyaWVzLCBzaW5jZSB0aGV5IGFyb3NlIGZyb20gb3BlcmF0aW9ucyAKKiBsaWtlIHNlYXJjaGluZy4gSWYgbm90LCB0aGUgbmVhcmVzdCBVVEYtMzIgYm91bmRhcmllcyBjYW4gYmUgZGV0ZXJtaW5lZCAKKiB1c2luZyA8Y29kZT5ib3VuZHMoKTwvY29kZT4uCiogPHN0cm9uZz5FeGFtcGxlczo8L3N0cm9uZz4KKiA8cD5UaGUgZm9sbG93aW5nIGV4YW1wbGVzIGlsbHVzdHJhdGUgdXNlIG9mIHNvbWUgb2YgdGhlc2UgbWV0aG9kcy4gCiogPHByZT4KKiAvLyBpdGVyYXRpb24gZm9yd2FyZHM6IE9yaWdpbmFsCiogZm9yIChpbnQgaSA9IDA7IGkgPCBzLmxlbmd0aCgpOyArK2kpIHsKKqCgoGNoYXIgY2ggPSBzLmNoYXJBdChpKTsKKqCgoGRvU29tZXRoaW5nV2l0aChjaCk7CiogfQoqCiogLy8gaXRlcmF0aW9uIGZvcndhcmRzOiBDaGFuZ2VzIGZvciBVVEYtMzIKKiBpbnQgY2g7CiogZm9yIChpbnQgaSA9IDA7IGkgPCBzLmxlbmd0aCgpOyBpKz1VVEYxNi5nZXRDaGFyQ291bnQoY2gpKSB7CiqgoKBjaCA9IFVURjE2LmNoYXJBdChzLGkpOwoqoKCgZG9Tb21ldGhpbmdXaXRoKGNoKTsKKiB9CioKKiAvLyBpdGVyYXRpb24gYmFja3dhcmRzOiBPcmlnaW5hbAoqIGZvciAoaW50IGkgPSBzLmxlbmd0aCgpIC0xOyBpID49IDA7IC0taSkgewoqoKCgY2hhciBjaCA9IHMuY2hhckF0KGkpOwoqoKCgZG9Tb21ldGhpbmdXaXRoKGNoKTsKKiB9CiogIAoqIC8vIGl0ZXJhdGlvbiBiYWNrd2FyZHM6IENoYW5nZXMgZm9yIFVURi0zMgoqIGludCBjaDsKKiBmb3IgKGludCBpID0gcy5sZW5ndGgoKSAtMTsgaSA+IDA7IGktPVVURjE2LmdldENoYXJDb3VudChjaCkpIHsKKqCgoGNoID0gVVRGMTYuY2hhckF0KHMsaSk7CiqgoKBkb1NvbWV0aGluZ1dpdGgoY2gpOwoqIH0KKiA8L3ByZT4KKiA8c3Ryb25nPk5vdGVzOjwvc3Ryb25nPgoqIDx1bD4KKiAgIDxsaT4KKiAgIDxzdHJvbmc+TmFtaW5nOjwvc3Ryb25nPiBGb3IgY2xhcml0eSwgSGlnaCBhbmQgTG93IHN1cnJvZ2F0ZXMgYXJlIGNhbGxlZCAKKiAgIDxjb2RlPkxlYWQ8L2NvZGU+IGFuZCA8Y29kZT5UcmFpbDwvY29kZT4gaW4gdGhlIEFQSSwgd2hpY2ggZ2l2ZXMgYSBiZXR0ZXIgCiogICBzZW5zZSBvZiB0aGVpciBvcmRlcmluZyBpbiBhIHN0cmluZy4gPGNvZGU+b2Zmc2V0MTY8L2NvZGU+IGFuZCAKKiAgIDxjb2RlPm9mZnNldDMyPC9jb2RlPiBhcmUgdXNlZCB0byBkaXN0aW5ndWlzaCBvZmZzZXRzIHRvIFVURi0xNiAKKiAgIGJvdW5kYXJpZXMgdnMgb2Zmc2V0cyB0byBVVEYtMzIgYm91bmRhcmllcy4gPGNvZGU+aW50IGNoYXIzMjwvY29kZT4gaXMgCiogICB1c2VkIHRvIGNvbnRhaW4gVVRGLTMyIGNoYXJhY3RlcnMsIGFzIG9wcG9zZWQgdG8gPGNvZGU+Y2hhcjE2PC9jb2RlPiwgCiogICB3aGljaCBpcyBhIFVURi0xNiBjb2RlIHVuaXQuCiogICA8L2xpPgoqICAgPGxpPgoqICAgPHN0cm9uZz5Sb3VuZHRyaXBwaW5nIE9mZnNldHM6PC9zdHJvbmc+IFlvdSBjYW4gYWx3YXlzIHJvdW5kdHJpcCBmcm9tIGEgCiogICBVVEYtMzIgb2Zmc2V0IHRvIGEgVVRGLTE2IG9mZnNldCBhbmQgYmFjay4gQmVjYXVzZSBvZiB0aGUgZGlmZmVyZW5jZSBpbiAKKiAgIHN0cnVjdHVyZSwgeW91IGNhbiByb3VuZHRyaXAgZnJvbSBhIFVURi0xNiBvZmZzZXQgdG8gYSBVVEYtMzIgb2Zmc2V0IGFuZCAKKiAgIGJhY2sgaWYgYW5kIG9ubHkgaWYgPGNvZGU+Ym91bmRzKHN0cmluZywgb2Zmc2V0MTYpICE9IFRSQUlMPC9jb2RlPi4KKiAgIDwvbGk+CiogICA8bGk+CiogICA8c3Ryb25nPkV4Y2VwdGlvbnM6PC9zdHJvbmc+IFRoZSBlcnJvciBjaGVja2luZyB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiAKKiAgIGlmIGluZGljZXMgYXJlIG91dCBvZiBib3VuZHMuIE90aGVyIHRoYW4gdGhhbiB0aGF0LCBhbGwgbWV0aG9kcyB3aWxsIAoqICAgYmVoYXZlIHJlYXNvbmFibHksIGV2ZW4gaWYgdW5tYXRjaGVkIHN1cnJvZ2F0ZXMgb3Igb3V0LW9mLWJvdW5kcyBVVEYtMzIgCiogICB2YWx1ZXMgYXJlIHByZXNlbnQuIDxjb2RlPlVDaGFyYWN0ZXIuaXNMZWdhbCgpPC9jb2RlPiBjYW4gYmUgdXNlZCB0byBjaGVjayAKKiAgIGZvciB2YWxpZGl0eSBpZiBkZXNpcmVkLgoqICAgPC9saT4KKiAgIDxsaT4KKiAgIDxzdHJvbmc+VW5tYXRjaGVkIFN1cnJvZ2F0ZXM6PC9zdHJvbmc+IElmIHRoZSBzdHJpbmcgY29udGFpbnMgdW5tYXRjaGVkIAoqICAgc3Vycm9nYXRlcywgdGhlbiB0aGVzZSBhcmUgY291bnRlZCBhcyBvbmUgVVRGLTMyIHZhbHVlLiBUaGlzIG1hdGNoZXMgCiogICB0aGVpciBpdGVyYXRpb24gYmVoYXZpb3IsIHdoaWNoIGlzIHZpdGFsLiBJdCBhbHNvIG1hdGNoZXMgY29tbW9uIGRpc3BsYXkgCiogICBwcmFjdGljZSBhcyBtaXNzaW5nIGdseXBocyAoc2VlIHRoZSBVbmljb2RlIFN0YW5kYXJkIFNlY3Rpb24gNS40LCA1LjUpLgoqICAgPC9saT4KKiAgIDxsaT4KKiAgICAgPHN0cm9uZz5PcHRpbWl6YXRpb246PC9zdHJvbmc+IFRoZSBtZXRob2QgaW1wbGVtZW50YXRpb25zIG1heSBuZWVkIAoqICAgICBvcHRpbWl6YXRpb24gaWYgdGhlIGNvbXBpbGVyIGRvZXNuJ3QgZm9sZCBzdGF0aWMgZmluYWwgbWV0aG9kcy4gU2luY2UgCiogICAgIHN1cnJvZ2F0ZSBwYWlycyB3aWxsIGZvcm0gYW4gZXhjZWVkaW5nIHNtYWxsIHBlcmNlbnRhZ2Ugb2YgYWxsIHRoZSB0ZXh0IAoqICAgICBpbiB0aGUgd29ybGQsIHRoZSBzaW5nbGV0b24gY2FzZSBzaG91bGQgYWx3YXlzIGJlIG9wdGltaXplZCBmb3IuCiogICA8L2xpPgoqIDwvdWw+CiogQGF1dGhvciBNYXJrIERhdmlzLCB3aXRoIGhlbHAgZnJvbSBNYXJrdXMgU2NoZXJlcgoqIEBzaW5jZSBOb3YyNDAwCiovCgpwdWJsaWMgZmluYWwgY2xhc3MgVVRGMTYKewogICAgLy8gcHVibGljIHZhcmlhYmxlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgCiAgICAvKioKICAgICogVmFsdWUgcmV0dXJuZWQgaW4gPGNvZGU+PGEgaHJlZj0iI2JvdW5kcyhqYXZhLmxhbmcuU3RyaW5nLCBpbnQpIj4KICAgICogYm91bmRzKCk8L2E+PC9jb2RlPi4KICAgICogVGhlc2UgdmFsdWVzIGFyZSBjaG9zZW4gc3BlY2lmaWNhbGx5IHNvIHRoYXQgaXQgYWN0dWFsbHkgcmVwcmVzZW50cyAgCiAgICAqIHRoZSBwb3NpdGlvbiBvZiB0aGUgY2hhcmFjdGVyIAogICAgKiBbb2Zmc2V0MTYgLSAodmFsdWUgPj4gMiksIG9mZnNldDE2ICsgKHZhbHVlICYgMyldCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lOR0xFX0NIQVJfQk9VTkRBUlkgPSAxLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExFQURfU1VSUk9HQVRFX0JPVU5EQVJZID0gMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFJTF9TVVJST0dBVEVfQk9VTkRBUlkgPSA1OwogICAgLyoqIAogICAgKiBUaGUgbG93ZXN0IFVuaWNvZGUgY29kZSBwb2ludCB2YWx1ZS4KICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT0RFUE9JTlRfTUlOX1ZBTFVFID0gMDsKICAgIC8qKgogICAgKiBUaGUgaGlnaGVzdCBVbmljb2RlIGNvZGUgcG9pbnQgdmFsdWUgKHNjYWxhciB2YWx1ZSkgYWNjb3JkaW5nIHRvIHRoZSAKICAgICogVW5pY29kZSBTdGFuZGFyZC4KICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT0RFUE9JTlRfTUFYX1ZBTFVFID0gMHgxMGZmZmY7IAogICAgLyoqCiAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIGZvciBTdXBwbGVtZW50YXJ5IGNvZGUgcG9pbnRzCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUgID0gMHgxMDAwMDsgIAogICAgLyoqCiAgICAgKiBMZWFkIHN1cnJvZ2F0ZSBtaW5pbXVtIHZhbHVlCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExFQURfU1VSUk9HQVRFX01JTl9WQUxVRSA9IDB4RDgwMDsKCS8qKgogICAgICogVHJhaWwgc3Vycm9nYXRlIG1pbmltdW0gdmFsdWUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFJBSUxfU1VSUk9HQVRFX01JTl9WQUxVRSA9IDB4REMwMDsgCiAgICAvKioKICAgICAqIExlYWQgc3Vycm9nYXRlIG1heGltdW0gdmFsdWUKICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEVBRF9TVVJST0dBVEVfTUFYX1ZBTFVFID0gMHhEQkZGOwoJLyoqCiAgICAgKiBUcmFpbCBzdXJyb2dhdGUgbWF4aW11bSB2YWx1ZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUUkFJTF9TVVJST0dBVEVfTUFYX1ZBTFVFID0gMHhERkZGOwogICAgLyoqCiAgICAgKiBTdXJyb2dhdGUgbWluaW11bSB2YWx1ZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVVJST0dBVEVfTUlOX1ZBTFVFID0gTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFOwogICAgLyoqCiAgICAgKiBNYXhpbXVtIHN1cnJvZ2F0ZSB2YWx1ZQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVVJST0dBVEVfTUFYX1ZBTFVFID0gVFJBSUxfU1VSUk9HQVRFX01BWF9WQUxVRTsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgLy8gY29uc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgCiAgICAvKioKICAgICogUHJldmVudCBpbnN0YW5jZSBmcm9tIGJlaW5nIGNyZWF0ZWQuCiAgICAqLwogICAgcHJpdmF0ZSBVVEYxNigpIAogICAgewogICAgfQoKICAgIC8vIHB1YmxpYyBtZXRob2QgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgIAogICAgLyoqCiAgICAqIEV4dHJhY3QgYSBzaW5nbGUgVVRGLTMyIHZhbHVlIGZyb20gYSBzdHJpbmcuCiAgICAqIFVzZWQgd2hlbiBpdGVyYXRpbmcgZm9yd2FyZHMgb3IgYmFja3dhcmRzICh3aXRoIAogICAgKiA8Y29kZT5VVEYxNi5nZXRDaGFyQ291bnQoKTwvY29kZT4sIGFzIHdlbGwgYXMgcmFuZG9tIGFjY2Vzcy4gSWYgYSAKICAgICogdmFsaWRpdHkgY2hlY2sgaXMgcmVxdWlyZWQsIHVzZSAKICAgICogPGNvZGU+PGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPgogICAgKiBVQ2hhcmFjdGVyLmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIHRoZSByZXR1cm4gdmFsdWUuCiAgICAqIElmIHRoZSBjaGFyIHJldHJpZXZlZCBpcyBwYXJ0IG9mIGEgc3Vycm9nYXRlIHBhaXIsIGl0cyBzdXBwbGVtZW50YXJ5IAogICAgKiBjaGFyYWN0ZXIgd2lsbCBiZSByZXR1cm5lZC4gSWYgYSBjb21wbGV0ZSBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlciBpcyAKICAgICogbm90IGZvdW5kIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkCiAgICAqIEBwYXJhbSBzb3VyY2UgYXJyYXkgb2YgVVRGLTE2IGNoYXJzCiAgICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYtMTYgb2Zmc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgY2hhcmFjdGVyLgogICAgKiBAcmV0dXJuIFVURi0zMiB2YWx1ZSBmb3IgdGhlIFVURi0zMiB2YWx1ZSB0aGF0IGNvbnRhaW5zIHRoZSBjaGFyIGF0IAogICAgKiAgICAgICAgIG9mZnNldDE2LiBUaGUgYm91bmRhcmllcyBvZiB0aGF0IGNvZGVwb2ludCBhcmUgdGhlIHNhbWUgYXMgaW4gCiAgICAqICAgICAgICAgPGNvZGU+Ym91bmRzMzIoKTwvY29kZT4uIAogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gdGhyb3duIGlmIG9mZnNldDE2IGlzIG91dCBvZiAKICAgICogICAgICAgICAgICBib3VuZHMuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgY2hhckF0KFN0cmluZyBzb3VyY2UsIGludCBvZmZzZXQxNikgCiAgICB7ICAgICAgICAgICAgIAogICAgICAgIGlmIChvZmZzZXQxNiA8IDAgfHwgb2Zmc2V0MTYgPj0gc291cmNlLmxlbmd0aCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDE2KTsKICAgICAgICB9CiAgICAgICAgICAKICAgICAgICBjaGFyIHNpbmdsZSA9IHNvdXJjZS5jaGFyQXQob2Zmc2V0MTYpOwogICAgICAgIGlmIChzaW5nbGUgPCBMRUFEX1NVUlJPR0FURV9NSU5fVkFMVUUgfHwgCiAgICAgICAgICAgIHNpbmdsZSA+IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUUpIHsKICAgICAgICAgICAgcmV0dXJuIHNpbmdsZTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnZlcnQgdGhlIFVURi0xNiBzdXJyb2dhdGUgcGFpciBpZiBuZWNlc3NhcnkuCiAgICAgICAgLy8gRm9yIHNpbXBsaWNpdHkgaW4gdXNhZ2UsIGFuZCBiZWNhdXNlIHRoZSBmcmVxdWVuY3kgb2YgcGFpcnMgaXMgCiAgICAgICAgLy8gbG93LCBsb29rIGJvdGggZGlyZWN0aW9ucy4KICAgICAgICAgICAgICAgIAoJICAgIGlmIChzaW5nbGUgPD0gTEVBRF9TVVJST0dBVEVfTUFYX1ZBTFVFKSB7CgkgICAgICAgICsrIG9mZnNldDE2OwoJICAgICAgICBpZiAoc291cmNlLmxlbmd0aCgpICE9IG9mZnNldDE2KSB7CiAgICAJICAgICAgICBjaGFyIHRyYWlsID0gc291cmNlLmNoYXJBdChvZmZzZXQxNik7CgkgICAgICAgICAgICBpZiAodHJhaWwgPj0gVFJBSUxfU1VSUk9HQVRFX01JTl9WQUxVRSAmJgoJICAgICAgICAgICAgICAgIHRyYWlsIDw9IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUUpIHsKCSAgICAgICAgICAgICAgICByZXR1cm4gVUNoYXJhY3RlclByb3BlcnR5LmdldFJhd1N1cHBsZW1lbnRhcnkoc2luZ2xlLCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhaWwpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfSAKCSAgICBlbHNlIAoJICAgIHsgCgkgICAgICAgIC0tIG9mZnNldDE2OwoJICAgICAgICBpZiAob2Zmc2V0MTYgPj0gMCkgewoJICAgICAgICAJLy8gc2luZ2xlIGlzIGEgdHJhaWwgc3Vycm9nYXRlIHNvCgkgICAgICAgIAljaGFyIGxlYWQgPSBzb3VyY2UuY2hhckF0KG9mZnNldDE2KTsKCSAgICAgICAgCWlmIChsZWFkID49IExFQURfU1VSUk9HQVRFX01JTl9WQUxVRSAmJgoJICAgICAgICAJICAgIGxlYWQgPD0gTEVBRF9TVVJST0dBVEVfTUFYX1ZBTFVFKSB7CgkgICAgICAgICAJICAgcmV0dXJuIFVDaGFyYWN0ZXJQcm9wZXJ0eS5nZXRSYXdTdXBwbGVtZW50YXJ5KGxlYWQsIAoJICAgICAgICAgCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUpOwoJICAgICAgICAJfQoJICAgICAgICB9CgkgICAgfSAKCSAgICByZXR1cm4gc2luZ2xlOyAvLyByZXR1cm4gdW5tYXRjaGVkIHN1cnJvZ2F0ZQogICAgfQogICAgICAKICAgIC8qKgogICAgKiBFeHRyYWN0IGEgc2luZ2xlIFVURi0zMiB2YWx1ZSBmcm9tIGEgc3RyaW5nLgogICAgKiBVc2VkIHdoZW4gaXRlcmF0aW5nIGZvcndhcmRzIG9yIGJhY2t3YXJkcyAod2l0aAogICAgKiA8Y29kZT5VVEYxNi5nZXRDaGFyQ291bnQoKTwvY29kZT4sIGFzIHdlbGwgYXMgcmFuZG9tIGFjY2Vzcy4gSWYgYSAKICAgICogdmFsaWRpdHkgY2hlY2sgaXMgcmVxdWlyZWQsIHVzZSAKICAgICogPGNvZGU+PGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPlVDaGFyYWN0ZXIuaXNMZWdhbCgpCiAgICAqIDwvYT48L2NvZGU+IG9uIHRoZSByZXR1cm4gdmFsdWUuCiAgICAqIElmIHRoZSBjaGFyIHJldHJpZXZlZCBpcyBwYXJ0IG9mIGEgc3Vycm9nYXRlIHBhaXIsIGl0cyBzdXBwbGVtZW50YXJ5CiAgICAqIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkLiBJZiBhIGNvbXBsZXRlIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIGlzIAogICAgKiBub3QgZm91bmQgdGhlIGluY29tcGxldGUgY2hhcmFjdGVyIHdpbGwgYmUgcmV0dXJuZWQKICAgICogQHBhcmFtIHNvdXJjZSBVVEYtMTYgY2hhcnMgc3RyaW5nIGJ1ZmZlcgogICAgKiBAcGFyYW0gb2Zmc2V0MTYgVVRGLTE2IG9mZnNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGNoYXJhY3Rlci4KICAgICogQHJldHVybiBVVEYtMzIgdmFsdWUgZm9yIHRoZSBVVEYtMzIgdmFsdWUgdGhhdCBjb250YWlucyB0aGUgY2hhciBhdAogICAgKiAgICAgICAgIG9mZnNldDE2LiBUaGUgYm91bmRhcmllcyBvZiB0aGF0IGNvZGVwb2ludCBhcmUgdGhlIHNhbWUgYXMgaW4KICAgICogICAgICAgICA8Y29kZT5ib3VuZHMzMigpPC9jb2RlPi4KICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHRocm93biBpZiBvZmZzZXQxNiBpcyBvdXQgb2YgCiAgICAqICAgICAgICAgICAgYm91bmRzLgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNoYXJBdChTdHJpbmdCdWZmZXIgc291cmNlLCBpbnQgb2Zmc2V0MTYpCiAgICB7CiAgICAgICAgaWYgKG9mZnNldDE2IDwgMCB8fCBvZmZzZXQxNiA+PSBzb3VyY2UubGVuZ3RoKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24ob2Zmc2V0MTYpOwogICAgICAgIH0KICAgICAgICAgIAogICAgICAgIGNoYXIgc2luZ2xlID0gc291cmNlLmNoYXJBdChvZmZzZXQxNik7CiAgICAgICAgaWYgKCFpc1N1cnJvZ2F0ZShzaW5nbGUpKSB7CiAgICAgICAgICAgIHJldHVybiBzaW5nbGU7CiAgICAgICAgfQoKICAgICAgICAvLyBDb252ZXJ0IHRoZSBVVEYtMTYgc3Vycm9nYXRlIHBhaXIgaWYgbmVjZXNzYXJ5LgogICAgICAgIC8vIEZvciBzaW1wbGljaXR5IGluIHVzYWdlLCBhbmQgYmVjYXVzZSB0aGUgZnJlcXVlbmN5IG9mIHBhaXJzIGlzIAogICAgICAgIC8vIGxvdywgbG9vayBib3RoIGRpcmVjdGlvbnMuCiAgICAgICAgICAgICAgICAKCSAgICBpZiAoc2luZ2xlIDw9IExFQURfU1VSUk9HQVRFX01BWF9WQUxVRSkgCgkgICAgewoJICAgICAgICArKyBvZmZzZXQxNjsKCSAgICAgICAgaWYgKHNvdXJjZS5sZW5ndGgoKSAhPSBvZmZzZXQxNikKCSAgICAgICAgewoJICAgICAgICBjaGFyIHRyYWlsID0gc291cmNlLmNoYXJBdChvZmZzZXQxNik7CgkgICAgICAgIGlmIChpc1RyYWlsU3Vycm9nYXRlKHRyYWlsKSkKCSAgICAgICAgICAgIHJldHVybiBVQ2hhcmFjdGVyUHJvcGVydHkuZ2V0UmF3U3VwcGxlbWVudGFyeShzaW5nbGUsIHRyYWlsKTsKCSAgICAgICAgfQoJICAgIH0gCgkgICAgZWxzZSAKCSAgICB7IAoJICAgICAgICAtLSBvZmZzZXQxNjsKCSAgICAgICAgaWYgKG9mZnNldDE2ID49IDApCgkgICAgICAgIHsKCSAgICAgICAgLy8gc2luZ2xlIGlzIGEgdHJhaWwgc3Vycm9nYXRlIHNvCgkgICAgICAgIGNoYXIgbGVhZCA9IHNvdXJjZS5jaGFyQXQob2Zmc2V0MTYpOwoJICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKGxlYWQpKSB7CgkgICAgICAgICAgICByZXR1cm4gVUNoYXJhY3RlclByb3BlcnR5LmdldFJhd1N1cHBsZW1lbnRhcnkobGVhZCwgc2luZ2xlKTsKCSAgICAgICAgfQoJICAgICAgICB9CgkgICAgfSAKCSAgICByZXR1cm4gc2luZ2xlOyAvLyByZXR1cm4gdW5tYXRjaGVkIHN1cnJvZ2F0ZQogICAgfQogICAgICAKICAgIC8qKgogICAgKiBFeHRyYWN0IGEgc2luZ2xlIFVURi0zMiB2YWx1ZSBmcm9tIGEgc3Vic3RyaW5nLgogICAgKiBVc2VkIHdoZW4gaXRlcmF0aW5nIGZvcndhcmRzIG9yIGJhY2t3YXJkcyAod2l0aAogICAgKiA8Y29kZT5VVEYxNi5nZXRDaGFyQ291bnQoKTwvY29kZT4sIGFzIHdlbGwgYXMgcmFuZG9tIGFjY2Vzcy4gSWYgYQogICAgKiB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgKiA8Y29kZT48YSBocmVmPSIuLi9VQ2hhcmFjdGVyLmh0bWwjaXNMZWdhbChjaGFyKSI+VUNoYXJhY3Rlci5pc0xlZ2FsKCkKICAgICogPC9hPjwvY29kZT4gb24gdGhlIHJldHVybiB2YWx1ZS4KICAgICogSWYgdGhlIGNoYXIgcmV0cmlldmVkIGlzIHBhcnQgb2YgYSBzdXJyb2dhdGUgcGFpciwgaXRzIHN1cHBsZW1lbnRhcnkKICAgICogY2hhcmFjdGVyIHdpbGwgYmUgcmV0dXJuZWQuIElmIGEgY29tcGxldGUgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgaXMgCiAgICAqIG5vdCBmb3VuZCB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXIgd2lsbCBiZSByZXR1cm5lZAogICAgKiBAcGFyYW0gc291cmNlIGFycmF5IG9mIFVURi0xNiBjaGFycwogICAgKiBAcGFyYW0gc3RhcnQgb2Zmc2V0IHRvIHN1YnN0cmluZyBpbiB0aGUgc291cmNlIGFycmF5IGZvciBhbmFseXppbmcKICAgICogQHBhcmFtIGxpbWl0IG9mZnNldCB0byBzdWJzdHJpbmcgaW4gdGhlIHNvdXJjZSBhcnJheSBmb3IgYW5hbHl6aW5nCiAgICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYtMTYgb2Zmc2V0IHJlbGF0aXZlIHRvIHN0YXJ0CiAgICAqIEByZXR1cm4gVVRGLTMyIHZhbHVlIGZvciB0aGUgVVRGLTMyIHZhbHVlIHRoYXQgY29udGFpbnMgdGhlIGNoYXIgYXQKICAgICogICAgICAgICBvZmZzZXQxNi4gVGhlIGJvdW5kYXJpZXMgb2YgdGhhdCBjb2RlcG9pbnQgYXJlIHRoZSBzYW1lIGFzIGluCiAgICAqICAgICAgICAgPGNvZGU+Ym91bmRzMzIoKTwvY29kZT4uCiAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB0aHJvd24gaWYgb2Zmc2V0MTYgaXMgbm90IHdpdGhpbiAKICAgICogICAgICAgICAgICB0aGUgcmFuZ2Ugb2Ygc3RhcnQgYW5kIGxpbWl0LgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNoYXJBdChjaGFyIHNvdXJjZVtdLCBpbnQgc3RhcnQsIGludCBsaW1pdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldDE2KQogICAgewogICAgICAgIG9mZnNldDE2ICs9IHN0YXJ0OwogICAgICAgIGlmIChvZmZzZXQxNiA8IHN0YXJ0IHx8IG9mZnNldDE2ID49IGxpbWl0KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBBcnJheUluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24ob2Zmc2V0MTYpOwogICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgY2hhciBzaW5nbGUgPSBzb3VyY2Vbb2Zmc2V0MTZdOwogICAgICAgIGlmICghaXNTdXJyb2dhdGUoc2luZ2xlKSkgewogICAgICAgICAgICByZXR1cm4gc2luZ2xlOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29udmVydCB0aGUgVVRGLTE2IHN1cnJvZ2F0ZSBwYWlyIGlmIG5lY2Vzc2FyeS4KICAgICAgICAvLyBGb3Igc2ltcGxpY2l0eSBpbiB1c2FnZSwgYW5kIGJlY2F1c2UgdGhlIGZyZXF1ZW5jeSBvZiBwYWlycyBpcyAKICAgICAgICAvLyBsb3csIGxvb2sgYm90aCBkaXJlY3Rpb25zLiAgICAgIAoJICAgIGlmIChzaW5nbGUgPD0gTEVBRF9TVVJST0dBVEVfTUFYX1ZBTFVFKSB7CgkgICAgICAgIG9mZnNldDE2ICsrOwoJICAgICAgICBpZiAob2Zmc2V0MTYgPj0gbGltaXQpIHsKCSAgICAgICAgICAgIHJldHVybiBzaW5nbGU7CgkgICAgICAgIH0KCSAgICAgICAgY2hhciB0cmFpbCA9IHNvdXJjZVtvZmZzZXQxNl07CgkgICAgICAgIGlmIChpc1RyYWlsU3Vycm9nYXRlKHRyYWlsKSkgewoJICAgICAgICAgICAgcmV0dXJuIFVDaGFyYWN0ZXJQcm9wZXJ0eS5nZXRSYXdTdXBwbGVtZW50YXJ5KHNpbmdsZSwgdHJhaWwpOwoJICAgICAgICB9CiAgICAgICAgfSAKICAgICAgICBlbHNlIHsgLy8gaXNUcmFpbFN1cnJvZ2F0ZShzaW5nbGUpLCBzbwogICAgICAgICAgICBpZiAob2Zmc2V0MTYgPT0gc3RhcnQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzaW5nbGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb2Zmc2V0MTYgLS07CgkgICAgICAgIGNoYXIgbGVhZCA9IHNvdXJjZVtvZmZzZXQxNl07CgkgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUobGVhZCkpCgkgICAgICAgICAgICByZXR1cm4gVUNoYXJhY3RlclByb3BlcnR5LmdldFJhd1N1cHBsZW1lbnRhcnkobGVhZCwgc2luZ2xlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNpbmdsZTsgLy8gcmV0dXJuIHVubWF0Y2hlZCBzdXJyb2dhdGUKICAgIH0KICAgICAgCiAgICAvKioKICAgICogRXh0cmFjdCBhIHNpbmdsZSBVVEYtMzIgdmFsdWUgZnJvbSBhIHN0cmluZy4KICAgICogVXNlZCB3aGVuIGl0ZXJhdGluZyBmb3J3YXJkcyBvciBiYWNrd2FyZHMgKHdpdGgKICAgICogPGNvZGU+VVRGMTYuZ2V0Q2hhckNvdW50KCk8L2NvZGU+LCBhcyB3ZWxsIGFzIHJhbmRvbSBhY2Nlc3MuIElmIGEgCiAgICAqIHZhbGlkaXR5IGNoZWNrIGlzIHJlcXVpcmVkLCB1c2UgCiAgICAqIDxjb2RlPjxhIGhyZWY9Ii4uL1VDaGFyYWN0ZXIuaHRtbCNpc0xlZ2FsKGNoYXIpIj5VQ2hhcmFjdGVyLmlzTGVnYWwoKQogICAgKiA8L2E+PC9jb2RlPiBvbiB0aGUgcmV0dXJuIHZhbHVlLgogICAgKiBJZiB0aGUgY2hhciByZXRyaWV2ZWQgaXMgcGFydCBvZiBhIHN1cnJvZ2F0ZSBwYWlyLCBpdHMgc3VwcGxlbWVudGFyeQogICAgKiBjaGFyYWN0ZXIgd2lsbCBiZSByZXR1cm5lZC4gSWYgYSBjb21wbGV0ZSBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlciBpcyAKICAgICogbm90IGZvdW5kIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkCiAgICAqIEBwYXJhbSBzb3VyY2UgVVRGLTE2IGNoYXJzIHN0cmluZyBidWZmZXIKICAgICogQHBhcmFtIG9mZnNldDE2IFVURi0xNiBvZmZzZXQgdG8gdGhlIHN0YXJ0IG9mIHRoZSBjaGFyYWN0ZXIuCiAgICAqIEByZXR1cm4gVVRGLTMyIHZhbHVlIGZvciB0aGUgVVRGLTMyIHZhbHVlIHRoYXQgY29udGFpbnMgdGhlIGNoYXIgYXQKICAgICogICAgICAgICBvZmZzZXQxNi4gVGhlIGJvdW5kYXJpZXMgb2YgdGhhdCBjb2RlcG9pbnQgYXJlIHRoZSBzYW1lIGFzIGluCiAgICAqICAgICAgICAgPGNvZGU+Ym91bmRzMzIoKTwvY29kZT4uCiAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiB0aHJvd24gaWYgb2Zmc2V0MTYgaXMgb3V0IG9mIAogICAgKiAgICAgICAgICAgIGJvdW5kcy4KICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBjaGFyQXQoUmVwbGFjZWFibGUgc291cmNlLCBpbnQgb2Zmc2V0MTYpCiAgICB7CiAgICAgICAgaWYgKG9mZnNldDE2IDwgMCB8fCBvZmZzZXQxNiA+PSBzb3VyY2UubGVuZ3RoKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24ob2Zmc2V0MTYpOwogICAgICAgIH0KICAgICAgICAgIAogICAgICAgIGNoYXIgc2luZ2xlID0gc291cmNlLmNoYXJBdChvZmZzZXQxNik7CiAgICAgICAgaWYgKCFpc1N1cnJvZ2F0ZShzaW5nbGUpKSB7CiAgICAgICAgICAgIHJldHVybiBzaW5nbGU7CiAgICAgICAgfQoKICAgICAgICAvLyBDb252ZXJ0IHRoZSBVVEYtMTYgc3Vycm9nYXRlIHBhaXIgaWYgbmVjZXNzYXJ5LgogICAgICAgIC8vIEZvciBzaW1wbGljaXR5IGluIHVzYWdlLCBhbmQgYmVjYXVzZSB0aGUgZnJlcXVlbmN5IG9mIHBhaXJzIGlzIAogICAgICAgIC8vIGxvdywgbG9vayBib3RoIGRpcmVjdGlvbnMuCiAgICAgICAgICAgICAgICAKCSAgICBpZiAoc2luZ2xlIDw9IExFQURfU1VSUk9HQVRFX01BWF9WQUxVRSkgCgkgICAgewoJICAgICAgICArKyBvZmZzZXQxNjsKCSAgICAgICAgaWYgKHNvdXJjZS5sZW5ndGgoKSAhPSBvZmZzZXQxNikKCSAgICAgICAgewoJICAgICAgICBjaGFyIHRyYWlsID0gc291cmNlLmNoYXJBdChvZmZzZXQxNik7CgkgICAgICAgIGlmIChpc1RyYWlsU3Vycm9nYXRlKHRyYWlsKSkKCSAgICAgICAgICAgIHJldHVybiBVQ2hhcmFjdGVyUHJvcGVydHkuZ2V0UmF3U3VwcGxlbWVudGFyeShzaW5nbGUsIHRyYWlsKTsKCSAgICAgICAgfQoJICAgIH0gCgkgICAgZWxzZSAKCSAgICB7IAoJICAgICAgICAtLSBvZmZzZXQxNjsKCSAgICAgICAgaWYgKG9mZnNldDE2ID49IDApCgkgICAgICAgIHsKCSAgICAgICAgLy8gc2luZ2xlIGlzIGEgdHJhaWwgc3Vycm9nYXRlIHNvCgkgICAgICAgIGNoYXIgbGVhZCA9IHNvdXJjZS5jaGFyQXQob2Zmc2V0MTYpOwoJICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKGxlYWQpKSB7CgkgICAgICAgICAgICByZXR1cm4gVUNoYXJhY3RlclByb3BlcnR5LmdldFJhd1N1cHBsZW1lbnRhcnkobGVhZCwgc2luZ2xlKTsKCSAgICAgICAgfQoJICAgICAgICB9CgkgICAgfSAKCSAgICByZXR1cm4gc2luZ2xlOyAvLyByZXR1cm4gdW5tYXRjaGVkIHN1cnJvZ2F0ZQogICAgfQogICAgICAKICAgIC8qKgogICAgKiBFeHRyYWN0IGEgc2luZ2xlIFVURi0zMiB2YWx1ZSBmcm9tIGEgc3RyaW5nLgogICAgKiBJZiBhIHZhbGlkaXR5IGNoZWNrIGlzIHJlcXVpcmVkLCB1c2UgCiAgICAqIDxjb2RlPjxhIGhyZWY9Ii4uL1VDaGFyYWN0ZXIuaHRtbCNpc0xlZ2FsKGNoYXIpIj4KICAgICogVUNoYXJhY3Rlci5pc0xlZ2FsKCk8L2E+PC9jb2RlPiBvbiB0aGUgcmV0dXJuIHZhbHVlLgogICAgKiBJZiB0YmUgY2hhciByZXRyaWV2ZWQgaXMgcGFydCBvZiBhIHN1cnJvZ2F0ZSBwYWlyLCBpdHMgc3VwcGxlbWVudGFyeSAKICAgICogY2hhcmFjdGVyIHdpbGwgYmUgcmV0dXJuZWQuIElmIGEgY29tcGxldGUgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgaXMgCiAgICAqIG5vdCBmb3VuZCB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXIgd2lsbCBiZSByZXR1cm5lZAogICAgKiBAcmV0dXJuIFVURi0zMiB2YWx1ZSBmb3IgdGhlIFVURi0zMiB2YWx1ZSB0aGF0IGNvbnRhaW5zIHRoZSBjaGFyIGF0IAogICAgKiAgICAgICAgIG9mZnNldDE2LiBUaGUgYm91bmRhcmllcyBvZiB0aGF0IGNvZGVwb2ludCBhcmUgdGhlIHNhbWUgYXMgaW4gCiAgICAqICAgICAgICAgPGNvZGU+Ym91bmRzMzIoKTwvY29kZT4uIAogICAgKiBAcGFyYW0gc291cmNlIGFycmF5IG9mIFVURi0xNiBjaGFycwogICAgKiBAcGFyYW0gb2Zmc2V0MzIgVVRGLTMyIG9mZnNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGNoYXJhY3Rlci4KICAgICogQHJldHVybiBhIHNpbmdsZSBVVEYzMiB2YWx1ZQogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgb2Zmc2V0MTYgaXMgb3V0IG9mIGJvdW5kcy4KICAgICogQGRlcHJlY2F0ZWQgdG8gYmUgcmVtb3ZlZCBhZnRlciB0aGUgeWVhciAyMDAyLCByZXBsYWNlZCBieSAKICAgICogICAgICBVVEYxNi5jaGFyQXQoc291cmNlLCBVVEYxNi5maW5kT2Zmc2V0RnJvbUNvZGVQb2ludChzb3VyY2UsIAogICAgKiAgICAgICAgICAgICAgICAgICBvZmZzZXQzMikpOwogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNoYXJBdENvZGVQb2ludE9mZnNldChTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0MzIpIAogICAgewogICAgICAgIHJldHVybiBjaGFyQXQoc291cmNlLCBmaW5kT2Zmc2V0RnJvbUNvZGVQb2ludChzb3VyY2UsIG9mZnNldDMyKSk7CiAgICB9CiAgICAgIAogICAgLyoqCiAgICAqIERldGVybWluZXMgaG93IG1hbnkgY2hhcnMgdGhpcyBjaGFyMzIgcmVxdWlyZXMuCiAgICAqIElmIGEgdmFsaWRpdHkgY2hlY2sgaXMgcmVxdWlyZWQsIHVzZSA8Y29kZT4KICAgICogPGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIAogICAgKiBjaGFyMzIgYmVmb3JlIGNhbGxpbmcuCiAgICAqIEBwYXJhbSBjaCB0aGUgaW5wdXQgY29kZXBvaW50LgogICAgKiBAcmV0dXJuIDIgaWYgaXMgaW4gc3VwcGxlbWVudGFyeSBzcGFjZSwgb3RoZXJ3aXNlIDEuIAogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGdldENoYXJDb3VudChpbnQgY2hhcjMyKSAKICAgIHsKICAgICAgICBpZiAoY2hhcjMyIDwgU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUpIHsKICAgICAgICAJcmV0dXJuIDE7CiAgICAgICAgfQogICAgICAgIHJldHVybiAyOwogICAgfQogICAgICAKICAgIC8qKgogICAgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIHRoZSBib3VuZGFyaWVzIGFyb3VuZCB0aGUgY2hhciBhdCBvZmZzZXQxNi4KICAgICogVXNlZCBmb3IgcmFuZG9tIGFjY2Vzcy4KICAgICogQHBhcmFtIHNvdXJjZSB0ZXh0IHRvIGFuYWx5c2UKICAgICogQHBhcmFtIG9mZnNldDE2IFVURi0xNiBvZmZzZXQKICAgICogQHJldHVybiA8dWw+CiAgICAqICAgICAgICAgICA8bGk+IFNJTkdMRV9DSEFSX0JPVU5EQVJZIDogYSBzaW5nbGUgY2hhcjsgdGhlIGJvdW5kcyBhcmUgCiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29mZnNldDE2LCBvZmZzZXQxNisxXQogICAgKiAgICAgICAgICAgPGxpPiBMRUFEX1NVUlJPR0FURV9CT1VOREFSWSA6IGEgc3Vycm9nYXRlIHBhaXIgc3RhcnRpbmcgYXQgCiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0MTY7IAogICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBib3VuZHMgYXJlIAogICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvZmZzZXQxNiwgb2Zmc2V0MTYgKyAyXQogICAgKiAgICAgICAgICAgPGxpPiBUUkFJTF9TVVJST0dBVEVfQk9VTkRBUlkgOiBhIHN1cnJvZ2F0ZSBwYWlyIHN0YXJ0aW5nIGF0IAogICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQxNiAtIDE7IHRoZSBib3VuZHMgYXJlIAogICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb2Zmc2V0MTYgLSAxLCBvZmZzZXQxNiArIDFdCiAgICAqICAgICAgICAgPC91bD4KICAgICogICAgICAgICBGb3IgYml0LXR3aWRkbGVycywgdGhlIHJldHVybiB2YWx1ZXMgZm9yIHRoZXNlIGFyZSBjaG9zZW4gc28gCiAgICAqICAgICAgICAgdGhhdCB0aGUgYm91bmRhcmllcyBjYW4gYmUgZ290dGVuIGJ5OgogICAgKiAgICAgICAgIFtvZmZzZXQxNiAtICh2YWx1ZSA+PiAyKSwgb2Zmc2V0MTYgKyAodmFsdWUgJiAzKV0uCiAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBvZmZzZXQxNiBpcyBvdXQgb2YgYm91bmRzLgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGJvdW5kcyhTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0MTYpIAogICAgewogICAgICAgIGNoYXIgY2ggPSBzb3VyY2UuY2hhckF0KG9mZnNldDE2KTsKICAgICAgICBpZiAoaXNTdXJyb2dhdGUoY2gpKSB7CiAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoY2gpKSAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCsrIG9mZnNldDE2IDwgc291cmNlLmxlbmd0aCgpICYmIAogICAgICAgICAgICAgICAgICAgIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlLmNoYXJBdChvZmZzZXQxNikpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIExFQURfU1VSUk9HQVRFX0JPVU5EQVJZOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IAogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGlzVHJhaWxTdXJyb2dhdGUoY2gpLCBzbwogICAgICAgICAgICAgICAgLS0gb2Zmc2V0MTY7CiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0MTYgPj0gMCAmJiBpc0xlYWRTdXJyb2dhdGUoc291cmNlLmNoYXJBdChvZmZzZXQxNikpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gU0lOR0xFX0NIQVJfQk9VTkRBUlk7CiAgICB9CiAgICAgIAogICAgLyoqCiAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhlIGJvdW5kYXJpZXMgYXJvdW5kIHRoZSBjaGFyIGF0IG9mZnNldDE2LiBVc2VkIAogICAgKiBmb3IgcmFuZG9tIGFjY2Vzcy4KICAgICogQHBhcmFtIHNvdXJjZSBzdHJpbmcgYnVmZmVyIHRvIGFuYWx5c2UKICAgICogQHBhcmFtIG9mZnNldDE2IFVURjE2IG9mZnNldAogICAgKiBAcmV0dXJuCiAgICAqICAgICA8dWw+CiAgICAqICAgICA8bGk+IFNJTkdMRV9DSEFSX0JPVU5EQVJZIDogYSBzaW5nbGUgY2hhcjsgdGhlIGJvdW5kcyBhcmUKICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvZmZzZXQxNiwgb2Zmc2V0MTYgKyAxXQogICAgKiAgICAgPGxpPiBMRUFEX1NVUlJPR0FURV9CT1VOREFSWSA6IGEgc3Vycm9nYXRlIHBhaXIgc3RhcnRpbmcgYXQgCiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0MTY7IHRoZSBib3VuZHMgYXJlIAogICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvZmZzZXQxNiwgb2Zmc2V0MTYgKyAyXQogICAgKiAgICAgPGxpPiBUUkFJTF9TVVJST0dBVEVfQk9VTkRBUlkgOiBhIHN1cnJvZ2F0ZSBwYWlyIHN0YXJ0aW5nIGF0IAogICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQxNiAtIDE7IHRoZSBib3VuZHMgYXJlIAogICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb2Zmc2V0MTYgLSAxLCBvZmZzZXQxNiArIDFdCiAgICAqICAgICA8L3VsPgogICAgKiBGb3IgYml0LXR3aWRkbGVycywgdGhlIHJldHVybiB2YWx1ZXMgZm9yIHRoZXNlIGFyZSBjaG9zZW4gc28gdGhhdCB0aGUgCiAgICAqIGJvdW5kYXJpZXMgY2FuIGJlIGdvdHRlbiBieTogCiAgICAqICAgICAgICAgICAgICAgICAgICBbb2Zmc2V0MTYgLSAodmFsdWUgPj4gMiksIG9mZnNldDE2ICsgKHZhbHVlICYgMyldLgogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgb2Zmc2V0MTYgaXMgb3V0IG9mIGJvdW5kcy4KICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBib3VuZHMoU3RyaW5nQnVmZmVyIHNvdXJjZSwgaW50IG9mZnNldDE2KQogICAgewogICAgICAgIGNoYXIgY2ggPSBzb3VyY2UuY2hhckF0KG9mZnNldDE2KTsKICAgICAgICBpZiAoaXNTdXJyb2dhdGUoY2gpKSB7CiAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoY2gpKSAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCsrIG9mZnNldDE2IDwgc291cmNlLmxlbmd0aCgpICYmIAogICAgICAgICAgICAgICAgICAgIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlLmNoYXJBdChvZmZzZXQxNikpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIExFQURfU1VSUk9HQVRFX0JPVU5EQVJZOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IAogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGlzVHJhaWxTdXJyb2dhdGUoY2gpLCBzbwogICAgICAgICAgICAgICAgLS0gb2Zmc2V0MTY7CiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0MTYgPj0gMCAmJiAKICAgICAgICAgICAgICAgICAgICBpc0xlYWRTdXJyb2dhdGUoc291cmNlLmNoYXJBdChvZmZzZXQxNikpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gU0lOR0xFX0NIQVJfQk9VTkRBUlk7CiAgICB9CgogICAgLyoqCiAgICAqIFJldHVybnMgdGhlIHR5cGUgb2YgdGhlIGJvdW5kYXJpZXMgYXJvdW5kIHRoZSBjaGFyIGF0IG9mZnNldDE2LiBVc2VkIAogICAgKiBmb3IgcmFuZG9tIGFjY2Vzcy4gTm90ZSB0aGF0IHRoZSBib3VuZGFyaWVzIGFyZSBkZXRlcm1pbmVkIHdpdGggcmVzcGVjdCAKICAgICogdG8gdGhlIHN1YmFycmF5LCBoZW5jZSB0aGUgY2hhciBhcnJheSB7MHhEODAwLCAweERDMDB9IGhhcyB0aGUgcmVzdWx0IAogICAgKiBTSU5HTEVfQ0hBUl9CT1VOREFSWSBmb3Igc3RhcnQgPSBvZmZzZXQxNiA9IDAgYW5kIGxpbWl0ID0gMS4KICAgICogQHBhcmFtIHNvdXJjZSBjaGFyIGFycmF5IHRvIGFuYWx5c2UKICAgICogQHBhcmFtIHN0YXJ0IG9mZnNldCB0byBzdWJzdHJpbmcgaW4gdGhlIHNvdXJjZSBhcnJheSBmb3IgYW5hbHl6aW5nCiAgICAqIEBwYXJhbSBsaW1pdCBvZmZzZXQgdG8gc3Vic3RyaW5nIGluIHRoZSBzb3VyY2UgYXJyYXkgZm9yIGFuYWx5emluZwogICAgKiBAcGFyYW0gb2Zmc2V0MTYgVVRGMTYgb2Zmc2V0IHJlbGF0aXZlIHRvIHN0YXJ0CiAgICAqIEByZXR1cm4KICAgICogICAgIDx1bD4KICAgICogICAgICAgICA8bGk+IFNJTkdMRV9DSEFSX0JPVU5EQVJZIDogYSBzaW5nbGUgY2hhcjsgdGhlIGJvdW5kcyBhcmUKICAgICogICAgICAgICA8bGk+IExFQURfU1VSUk9HQVRFX0JPVU5EQVJZIDogYSBzdXJyb2dhdGUgcGFpciBzdGFydGluZyBhdAogICAgKiAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0MTY7IHRoZSBib3VuZHMgYXJlIFtvZmZzZXQxNiwgb2Zmc2V0MTYgKyAyXQogICAgKiAgICAgICAgIDxsaT4gVFJBSUxfU1VSUk9HQVRFX0JPVU5EQVJZIDogYSBzdXJyb2dhdGUgcGFpciBzdGFydGluZyBhdAogICAgKiAgICAgICAgICAgICAgIG9mZnNldDE2IC0gMTsgdGhlIGJvdW5kcyBhcmUgW29mZnNldDE2IC0gMSwgb2Zmc2V0MTYgKyAxXQogICAgKiAgICAgPC91bD4KICAgICogRm9yIGJpdC10d2lkZGxlcnMsIHRoZSBib3VuZGFyeSB2YWx1ZXMgZm9yIHRoZXNlIGFyZSBjaG9zZW4gc28gdGhhdCB0aGUgCiAgICAqIGJvdW5kYXJpZXMgY2FuIGJlIGdvdHRlbiBieTogW29mZnNldDE2IC0gKGJvdW5kdmFsdWUgPj4gMiksIG9mZnNldDE2IAogICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIChib3VuZHZhbHVlICYgMyldLgogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgb2Zmc2V0MTYgaXMgbm90IHdpdGhpbiB0aGUgCiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZSBvZiBzdGFydCBhbmQgbGltaXQuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgYm91bmRzKGNoYXIgc291cmNlW10sIGludCBzdGFydCwgaW50IGxpbWl0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgb2Zmc2V0MTYpCiAgICB7CiAgICAgICAgb2Zmc2V0MTYgKz0gc3RhcnQ7CiAgICAgICAgaWYgKG9mZnNldDE2IDwgc3RhcnQgfHwgb2Zmc2V0MTYgPj0gbGltaXQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQxNik7CiAgICAgICAgfQogICAgICAgIGNoYXIgY2ggPSBzb3VyY2Vbb2Zmc2V0MTZdOwogICAgICAgIGlmIChpc1N1cnJvZ2F0ZShjaCkpIHsKICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkpIHsKICAgICAgICAgICAgICAgICsrIG9mZnNldDE2OwogICAgICAgICAgICAgICAgaWYgKG9mZnNldDE2IDwgbGltaXQgJiYgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2Vbb2Zmc2V0MTZdKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBMRUFEX1NVUlJPR0FURV9CT1VOREFSWTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSAKICAgICAgICAgICAgZWxzZSB7IC8vIGlzVHJhaWxTdXJyb2dhdGUoY2gpLCBzbwogICAgICAgICAgICAgICAgLS0gb2Zmc2V0MTY7CiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0MTYgPj0gc3RhcnQgJiYgaXNMZWFkU3Vycm9nYXRlKHNvdXJjZVtvZmZzZXQxNl0pKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gU0lOR0xFX0NIQVJfQk9VTkRBUlk7ICAgIAogICAgfQoKICAgIC8qKgogICAgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIHRoZSBib3VuZGFyaWVzIGFyb3VuZCB0aGUgY2hhciBhdCBvZmZzZXQzMi4gVXNlZCAKICAgICogZm9yIHJhbmRvbSBhY2Nlc3MuCiAgICAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nIHRvIGFuYWx5c2UKICAgICogQHBhcmFtIG9mZnNldDMyIFVURjMyIG9mZnNldAogICAgKiBAcmV0dXJuCiAgICAqICAgICA8dWw+CiAgICAqICAgICAgICAgPGxpPiBTSU5HTEVfQ0hBUl9CT1VOREFSWSA6IGEgc2luZ2xlIGNoYXIKICAgICogICAgICAgICA8bGk+IExFQURfU1VSUk9HQVRFX0JPVU5EQVJZIDogYSBzdXJyb2dhdGUgcGFpciBzdGFydGluZyBhdAogICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQzMgogICAgKiAgICAgPC91bD4KICAgICogRm9yIGJpdC10d2lkZGxlcnMsIHNlZSA8YSBocmVmPSNib3VuZHMoamF2YS5sYW5nLlN0cmluZywgaW50KT4KICAgICogYm91bmRzKGphdmEubGFuZy5TdHJpbmcsIGludCk8L2E+IGZvciBpbmZvcm1hdGlvbiBvbiB0aGUgY2hvaWNlIG9mIHRoZSAKICAgICogYm91bmRhcnkgdmFsdWVzLgogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgb2Zmc2V0MTYgaXMgb3V0IG9mIGJvdW5kcy4KICAgICogQGRlcHJlY2F0ZWQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGVuZCBvZiB5ZWFyIDIwMDIsIHJlcGxhY2VkIGJ5CiAgICAqICBVVEYxNi5ib3VuZHMoc291cmNlLCBVVEYxNi5maW5kT2Zmc2V0RnJvbUNvZGVQb2ludChzb3VyY2UsIG9mZnNldDMyKSk7CiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgYm91bmRzQXRDb2RlUG9pbnRPZmZzZXQoU3RyaW5nIHNvdXJjZSwgaW50IG9mZnNldDMyKSAKICAgIHsKICAgICAgICByZXR1cm4gYm91bmRzKHNvdXJjZSwgZmluZE9mZnNldEZyb21Db2RlUG9pbnQoc291cmNlLCBvZmZzZXQzMikpOwogICAgfQoKICAgIC8qKgogICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIDxiPmNvZGUgdmFsdWUgaXMgYSBzdXJyb2dhdGUuCiAgICAqIEBwYXJhbSBjaCB0aGUgaW5wdXQgY2hhcmFjdGVyLgogICAgKiBAcmV0dXJuIHRydWUgaWZmIHRoZSBpbnB1dCBjaGFyYWN0ZXIgaXMgYSBzdXJyb2dhdGUuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3Vycm9nYXRlKGNoYXIgY2hhcjE2KSAKICAgIHsKICAgICAgICByZXR1cm4gTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFIDw9IGNoYXIxNiAmJiAKICAgICAgICAgICAgY2hhcjE2IDw9IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUU7CiAgICB9CiAgICAgICAgCiAgICAvKioKICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBjaGFyYWN0ZXIgaXMgYSB0cmFpbCBzdXJyb2dhdGUuCiAgICAqIEBwYXJhbSBjaGFyMTYgdGhlIGlucHV0IGNoYXJhY3Rlci4KICAgICogQHJldHVybiB0cnVlIGlmZiB0aGUgaW5wdXQgY2hhcmFjdGVyIGlzIGEgdHJhaWwgc3Vycm9nYXRlLgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc1RyYWlsU3Vycm9nYXRlKGNoYXIgY2hhcjE2KSAKICAgIHsKICAgICAgICByZXR1cm4gKFRSQUlMX1NVUlJPR0FURV9NSU5fVkFMVUUgPD0gY2hhcjE2ICYmIAogICAgICAgICAgICAgICAgY2hhcjE2IDw9IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUUpOwogICAgfQogICAgICAgIAogICAgLyoqCiAgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgY2hhcmFjdGVyIGlzIGEgbGVhZCBzdXJyb2dhdGUuCiAgICAqIEBwYXJhbSBjaGFyMTYgdGhlIGlucHV0IGNoYXJhY3Rlci4KICAgICogQHJldHVybiB0cnVlIGlmZiB0aGUgaW5wdXQgY2hhcmFjdGVyIGlzIGEgbGVhZCBzdXJyb2dhdGUKICAgICovCiAgICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNMZWFkU3Vycm9nYXRlKGNoYXIgY2hhcjE2KSAKICAgIHsKICAgICAgICByZXR1cm4gTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFIDw9IGNoYXIxNiAmJiAKICAgICAgICAgICAgY2hhcjE2IDw9IExFQURfU1VSUk9HQVRFX01BWF9WQUxVRTsKICAgIH0KICAgICAgICAgICAgCiAgICAvKioKICAgICogUmV0dXJucyB0aGUgbGVhZCBzdXJyb2dhdGUuCiAgICAqIElmIGEgdmFsaWRpdHkgY2hlY2sgaXMgcmVxdWlyZWQsIHVzZSAKICAgICogPGNvZGU+PGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IAogICAgKiBvbiBjaGFyMzIgYmVmb3JlIGNhbGxpbmcuCiAgICAqIEBwYXJhbSBjaGFyMzIgdGhlIGlucHV0IGNoYXJhY3Rlci4KICAgICogQHJldHVybiBsZWFkIHN1cnJvZ2F0ZSBpZiB0aGUgZ2V0Q2hhckNvdW50KGNoKSBpcyAyOyA8YnI+CiAgICAqICAgICAgICAgYW5kIDAgb3RoZXJ3aXNlIChub3RlOiAwIGlzIG5vdCBhIHZhbGlkIGxlYWQgc3Vycm9nYXRlKS4KICAgICovCiAgICBwdWJsaWMgc3RhdGljIGNoYXIgZ2V0TGVhZFN1cnJvZ2F0ZShpbnQgY2hhcjMyKSAKICAgIHsKICAgICAgICBpZiAoY2hhcjMyID49IFNVUFBMRU1FTlRBUllfTUlOX1ZBTFVFKSB7CiAgICAgICAgCXJldHVybiAoY2hhcikoTEVBRF9TVVJST0dBVEVfT0ZGU0VUXyArIAogICAgICAgICAgICAgICAgICAgICAgKGNoYXIzMiA+PiBMRUFEX1NVUlJPR0FURV9TSElGVF8pKTsKICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIHJldHVybiAwOwogICAgfQogICAgICAgIAogICAgLyoqCiAgICAqIFJldHVybnMgdGhlIHRyYWlsIHN1cnJvZ2F0ZS4KICAgICogSWYgYSB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgKiA8Y29kZT48YSBocmVmPSIuLi9VQ2hhcmFjdGVyLmh0bWwjaXNMZWdhbChjaGFyKSI+aXNMZWdhbCgpPC9hPjwvY29kZT4gCiAgICAqIG9uIGNoYXIzMiBiZWZvcmUgY2FsbGluZy4KICAgICogQHBhcmFtIGNoYXIzMiB0aGUgaW5wdXQgY2hhcmFjdGVyLgogICAgKiBAcmV0dXJuIHRoZSB0cmFpbCBzdXJyb2dhdGUgaWYgdGhlIGdldENoYXJDb3VudChjaCkgaXMgMjsgPGJyPm90aGVyd2lzZSAKICAgICogICAgICAgICB0aGUgY2hhcmFjdGVyIGl0c2VsZgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgY2hhciBnZXRUcmFpbFN1cnJvZ2F0ZShpbnQgY2hhcjMyKSAKICAgIHsKICAgICAgICBpZiAoY2hhcjMyID49IFNVUFBMRU1FTlRBUllfTUlOX1ZBTFVFKSB7CiAgICAgICAgCXJldHVybiAoY2hhcikoVFJBSUxfU1VSUk9HQVRFX01JTl9WQUxVRSArIAogICAgICAgICAgICAgICAgICAgICAgKGNoYXIzMiAmIFRSQUlMX1NVUlJPR0FURV9NQVNLXykpOyAgICAgICAKICAgICAgICB9CiAgICAgICAgICAKICAgICAgICByZXR1cm4gKGNoYXIpY2hhcjMyOwogICAgfQogICAgICAgIAogICAgLyoqCiAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIFN0cmluZy52YWx1ZU9mKGNoYXIpLiBSZXR1cm5zIGEgb25lIAogICAgKiBvciB0d28gY2hhciBzdHJpbmcgY29udGFpbmluZyB0aGUgVVRGLTMyIHZhbHVlIGluIFVURjE2IGZvcm1hdC4gSWYgYSAKICAgICogdmFsaWRpdHkgY2hlY2sgaXMgcmVxdWlyZWQsIHVzZSAKICAgICogPGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIAogICAgKiBjaGFyMzIgYmVmb3JlIGNhbGxpbmcuCiAgICAqIEBwYXJhbSBjaGFyMzIgdGhlIGlucHV0IGNoYXJhY3Rlci4KICAgICogQHJldHVybiBzdHJpbmcgdmFsdWUgb2YgY2hhcjMyIGluIFVURjE2IGZvcm1hdAogICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB0aHJvd24gaWYgY2hhcjMyIGlzIGEgaW52YWxpZCAKICAgICogICAgICAgICAgICBjb2RlcG9pbnQuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdmFsdWVPZihpbnQgY2hhcjMyKQogICAgewogICAgICAgIGlmIChjaGFyMzIgPCBDT0RFUE9JTlRfTUlOX1ZBTFVFIHx8IGNoYXIzMiA+IENPREVQT0lOVF9NQVhfVkFMVUUpIHsKICAgICAgICAJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSWxsZWdhbCBjb2RlcG9pbnQiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRvU3RyaW5nKGNoYXIzMik7CiAgICB9CiAgICAgIAogICAgLyoqCiAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBjb3JyZXNwb25kaW5nIHRvIFN0cmluZy52YWx1ZU9mKGNvZGVwb2ludCBhdCAKICAgICogb2Zmc2V0MTYpLiAKICAgICogUmV0dXJucyBhIG9uZSBvciB0d28gY2hhciBzdHJpbmcgY29udGFpbmluZyB0aGUgVVRGLTMyIHZhbHVlIGluIFVURjE2IAogICAgKiBmb3JtYXQuIElmIG9mZnNldDE2IGluZGV4ZXMgYSBzdXJyb2dhdGUgY2hhcmFjdGVyLCB0aGUgd2hvbGUgCiAgICAqIHN1cHBsZW1lbnRhcnkgY29kZXBvaW50IHdpbGwgYmUgcmV0dXJuZWQuCiAgICAqIElmIGEgdmFsaWRpdHkgY2hlY2sgaXMgcmVxdWlyZWQsIHVzZSAKICAgICogPGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIHRoZSAKICAgICogY29kZXBvaW50IGF0IG9mZnNldDE2IGJlZm9yZSBjYWxsaW5nLgogICAgKiBUaGUgcmVzdWx0IHJldHVybmVkIHdpbGwgYmUgYSBuZXdseSBjcmVhdGVkIFN0cmluZyBvYnRhaW5lZCBieSBjYWxsaW5nIAogICAgKiBzb3VyY2Uuc3Vic3RyaW5nKC4uKSB3aXRoIHRoZSBhcHByb3ByaWF0ZSBpbmRleGVzLgogICAgKiBAcGFyYW0gc291cmNlIHRoZSBpbnB1dCBzdHJpbmcuCiAgICAqIEBwYXJhbSBvZmZzZXQxNiB0aGUgVVRGMTYgaW5kZXggdG8gdGhlIGNvZGVwb2ludCBpbiBzb3VyY2UKICAgICogQHJldHVybiBzdHJpbmcgdmFsdWUgb2YgY2hhcjMyIGluIFVURjE2IGZvcm1hdAogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHZhbHVlT2YoU3RyaW5nIHNvdXJjZSwgaW50IG9mZnNldDE2KQogICAgewogICAgICAgIHN3aXRjaCAoYm91bmRzKHNvdXJjZSwgb2Zmc2V0MTYpKSB7CiAgICAgICAgICAgIGNhc2UgTEVBRF9TVVJST0dBVEVfQk9VTkRBUlk6IAogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnN0cmluZyhvZmZzZXQxNiwgb2Zmc2V0MTYgKyAyKTsKICAgICAgICAgICAgY2FzZSBUUkFJTF9TVVJST0dBVEVfQk9VTkRBUlk6IAogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnN0cmluZyhvZmZzZXQxNiAtIDEsIG9mZnNldDE2ICsgMSk7CiAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBzb3VyY2Uuc3Vic3RyaW5nKG9mZnNldDE2LCBvZmZzZXQxNiArIDEpOwogICAgICAgIH0KICAgIH0KICAgICAgCiAgICAvKioKICAgICogQ29udmVuaWVuY2UgbWV0aG9kIGNvcnJlc3BvbmRpbmcgdG8gCiAgICAqIFN0cmluZ0J1ZmZlci52YWx1ZU9mKGNvZGVwb2ludCBhdCBvZmZzZXQxNikuIAogICAgKiBSZXR1cm5zIGEgb25lIG9yIHR3byBjaGFyIHN0cmluZyBjb250YWluaW5nIHRoZSBVVEYtMzIgdmFsdWUgaW4gVVRGMTYgCiAgICAqIGZvcm1hdC4gSWYgb2Zmc2V0MTYgaW5kZXhlcyBhIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIsIHRoZSB3aG9sZSAKICAgICogc3VwcGxlbWVudGFyeSBjb2RlcG9pbnQgd2lsbCBiZSByZXR1cm5lZC4KICAgICogSWYgYSB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgKiA8YSBocmVmPSIuLi9VQ2hhcmFjdGVyLmh0bWwjaXNMZWdhbChjaGFyKSI+aXNMZWdhbCgpPC9hPjwvY29kZT4gb24gdGhlIAogICAgKiBjb2RlcG9pbnQgYXQgb2Zmc2V0MTYgYmVmb3JlIGNhbGxpbmcuCiAgICAqIFRoZSByZXN1bHQgcmV0dXJuZWQgd2lsbCBiZSBhIG5ld2x5IGNyZWF0ZWQgU3RyaW5nIG9idGFpbmVkIGJ5IGNhbGxpbmcgCiAgICAqIHNvdXJjZS5zdWJzdHJpbmcoLi4pIHdpdGggdGhlIGFwcHJvcHJpYXRlIGluZGV4ZXMuCiAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIGlucHV0IHN0cmluZyBidWZmZXIuCiAgICAqIEBwYXJhbSBvZmZzZXQxNiB0aGUgVVRGMTYgaW5kZXggdG8gdGhlIGNvZGVwb2ludCBpbiBzb3VyY2UKICAgICogQHJldHVybiBzdHJpbmcgdmFsdWUgb2YgY2hhcjMyIGluIFVURjE2IGZvcm1hdAogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHZhbHVlT2YoU3RyaW5nQnVmZmVyIHNvdXJjZSwgaW50IG9mZnNldDE2KQogICAgewogICAgICAgIHN3aXRjaCAoYm91bmRzKHNvdXJjZSwgb2Zmc2V0MTYpKSB7CiAgICAgICAgICAgIGNhc2UgTEVBRF9TVVJST0dBVEVfQk9VTkRBUlk6IAogICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5zdWJzdHJpbmcob2Zmc2V0MTYsIG9mZnNldDE2ICsgMik7CiAgICAgICAgICAgIGNhc2UgVFJBSUxfU1VSUk9HQVRFX0JPVU5EQVJZOiAKICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzb3VyY2Uuc3Vic3RyaW5nKG9mZnNldDE2IC0gMSwgb2Zmc2V0MTYgKyAxKTsKICAgICAgICAgICAgZGVmYXVsdDogcmV0dXJuIHNvdXJjZS5zdWJzdHJpbmcob2Zmc2V0MTYsIG9mZnNldDE2ICsgMSk7CiAgICAgICAgfQogICAgfQogICAgICAKICAgIC8qKgogICAgKiBDb252ZW5pZW5jZSBtZXRob2QuIAogICAgKiBSZXR1cm5zIGEgb25lIG9yIHR3byBjaGFyIHN0cmluZyBjb250YWluaW5nIHRoZSBVVEYtMzIgdmFsdWUgaW4gVVRGMTYgCiAgICAqIGZvcm1hdC4gSWYgb2Zmc2V0MTYgaW5kZXhlcyBhIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIsIHRoZSB3aG9sZSAKICAgICogc3VwcGxlbWVudGFyeSBjb2RlcG9pbnQgd2lsbCBiZSByZXR1cm5lZCwgZXhjZXB0IHdoZW4gZWl0aGVyIHRoZSAKICAgICogbGVhZGluZyBvciB0cmFpbGluZyBzdXJyb2dhdGUgY2hhcmFjdGVyIGxpZXMgb3V0IG9mIHRoZSBzcGVjaWZpZWQgCiAgICAqIHN1YmFycmF5LiBJbiB0aGUgbGF0dGVyIGNhc2UsIG9ubHkgdGhlIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIgd2l0aGluIAogICAgKiBib3VuZHMgd2lsbCBiZSByZXR1cm5lZC4KICAgICogSWYgYSB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgKiA8YSBocmVmPSIuLi9VQ2hhcmFjdGVyLmh0bWwjaXNMZWdhbChjaGFyKSI+aXNMZWdhbCgpPC9hPjwvY29kZT4gb24gdGhlIAogICAgKiBjb2RlcG9pbnQgYXQgb2Zmc2V0MTYgYmVmb3JlIGNhbGxpbmcuCiAgICAqIFRoZSByZXN1bHQgcmV0dXJuZWQgd2lsbCBiZSBhIG5ld2x5IGNyZWF0ZWQgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIAogICAgKiByZWxldmFudCBjaGFyYWN0ZXJzLgogICAgKiBAcGFyYW0gc291cmNlIHRoZSBpbnB1dCBjaGFyIGFycmF5LgogICAgKiBAcGFyYW0gc3RhcnQgc3RhcnQgaW5kZXggb2YgdGhlIHN1YmFycmF5CiAgICAqIEBwYXJhbSBsaW1pdCBlbmQgaW5kZXggb2YgdGhlIHN1YmFycmF5CiAgICAqIEBwYXJhbSBvZmZzZXQxNiB0aGUgVVRGMTYgaW5kZXggdG8gdGhlIGNvZGVwb2ludCBpbiBzb3VyY2UgcmVsYXRpdmUgdG8gCiAgICAqICAgICAgICBzdGFydAogICAgKiBAcmV0dXJuIHN0cmluZyB2YWx1ZSBvZiBjaGFyMzIgaW4gVVRGMTYgZm9ybWF0CiAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdmFsdWVPZihjaGFyIHNvdXJjZVtdLCBpbnQgc3RhcnQsIGludCBsaW1pdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldDE2KQogICAgewogICAgICAgIHN3aXRjaCAoYm91bmRzKHNvdXJjZSwgc3RhcnQsIGxpbWl0LCBvZmZzZXQxNikpIHsKICAgICAgICAgICAgY2FzZSBMRUFEX1NVUlJPR0FURV9CT1VOREFSWTogCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhzb3VyY2UsIHN0YXJ0ICsgb2Zmc2V0MTYsIDIpOwogICAgICAgICAgICBjYXNlIFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWTogCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhzb3VyY2UsIHN0YXJ0ICsgb2Zmc2V0MTYgLSAxLCAyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoc291cmNlLCBzdGFydCArIG9mZnNldDE2LCAxKTsKICAgIH0KICAgICAgCiAgICAvKioKICAgICogUmV0dXJucyB0aGUgVVRGLTE2IG9mZnNldCB0aGF0IGNvcnJlc3BvbmRzIHRvIGEgVVRGLTMyIG9mZnNldC4gCiAgICAqIFVzZWQgZm9yIHJhbmRvbSBhY2Nlc3MuIFNlZSB0aGUgPGEgbmFtZT0iX3RvcF8iPmNsYXNzIGRlc2NyaXB0aW9uPC9hPiAKICAgICogZm9yIG5vdGVzIG9uIHJvdW5kdHJpcHBpbmcuCiAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIFVURi0xNiBzdHJpbmcKICAgICogQHBhcmFtIG9mZnNldDMyIFVURi0zMiBvZmZzZXQKICAgICogQHJldHVybiBVVEYtMTYgb2Zmc2V0IAogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgb2Zmc2V0MzIgaXMgb3V0IG9mIGJvdW5kcy4KICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBmaW5kT2Zmc2V0RnJvbUNvZGVQb2ludChTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0MzIpIAogICAgewogICAgICAgIGNoYXIgY2g7CiAgICAgICAgaW50IHNpemUgPSBzb3VyY2UubGVuZ3RoKCksCiAgICAgICAgICAgIHJlc3VsdCA9IDAsCiAgICAgICAgICAgIGNvdW50ID0gb2Zmc2V0MzI7CiAgICAgICAgaWYgKG9mZnNldDMyIDwgMCB8fCBvZmZzZXQzMiA+IHNpemUpIHsKICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQzMik7CiAgICAgICAgfQogICAgICAgIHdoaWxlIChyZXN1bHQgPCBzaXplICYmIGNvdW50ID4gMCkKICAgICAgICB7CiAgICAgICAgY2ggPSBzb3VyY2UuY2hhckF0KHJlc3VsdCk7CiAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgKChyZXN1bHQgKyAxKSA8IHNpemUpICYmIAogICAgICAgICAgICBpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0ICsgMSkpKSB7CiAgICAgICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIGNvdW50IC0tOwogICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50ICE9IDApIHsKICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQzMik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAgIAogICAgLyoqCiAgICAqIFJldHVybnMgdGhlIFVURi0xNiBvZmZzZXQgdGhhdCBjb3JyZXNwb25kcyB0byBhIFVURi0zMiBvZmZzZXQuCiAgICAqIFVzZWQgZm9yIHJhbmRvbSBhY2Nlc3MuIFNlZSB0aGUgPGEgbmFtZT0iX3RvcF8iPmNsYXNzIGRlc2NyaXB0aW9uPC9hPgogICAgKiBmb3Igbm90ZXMgb24gcm91bmR0cmlwcGluZy4KICAgICogQHBhcmFtIHNvdXJjZSB0aGUgVVRGLTE2IHN0cmluZyBidWZmZXIKICAgICogQHBhcmFtIG9mZnNldDMyIFVURi0zMiBvZmZzZXQKICAgICogQHJldHVybiBVVEYtMTYgb2Zmc2V0CiAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBvZmZzZXQzMiBpcyBvdXQgb2YgYm91bmRzLgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGZpbmRPZmZzZXRGcm9tQ29kZVBvaW50KFN0cmluZ0J1ZmZlciBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldDMyKQogICAgewogICAgICAgIGNoYXIgY2g7CiAgICAgICAgaW50IHNpemUgPSBzb3VyY2UubGVuZ3RoKCksCiAgICAgICAgICAgIHJlc3VsdCA9IDAsCiAgICAgICAgICAgIGNvdW50ID0gb2Zmc2V0MzI7CiAgICAgICAgaWYgKG9mZnNldDMyIDwgMCB8fCBvZmZzZXQzMiA+IHNpemUpIHsKICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQzMik7CiAgICAgICAgfQogICAgICAgIHdoaWxlIChyZXN1bHQgPCBzaXplICYmIGNvdW50ID4gMCkKICAgICAgICB7CiAgICAgICAgY2ggPSBzb3VyY2UuY2hhckF0KHJlc3VsdCk7CiAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgKChyZXN1bHQgKyAxKSA8IHNpemUpICYmIAogICAgICAgICAgICBpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0ICsgMSkpKSB7CiAgICAgICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIGNvdW50IC0tOwogICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50ICE9IDApIHsKICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQzMik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAqIFJldHVybnMgdGhlIFVURi0xNiBvZmZzZXQgdGhhdCBjb3JyZXNwb25kcyB0byBhIFVURi0zMiBvZmZzZXQuCiAgICAqIFVzZWQgZm9yIHJhbmRvbSBhY2Nlc3MuIFNlZSB0aGUgPGEgbmFtZT0iX3RvcF8iPmNsYXNzIGRlc2NyaXB0aW9uPC9hPgogICAgKiBmb3Igbm90ZXMgb24gcm91bmR0cmlwcGluZy4KICAgICogQHBhcmFtIHNvdXJjZSB0aGUgVVRGLTE2IGNoYXIgYXJyYXkgd2hvc2Ugc3Vic3RyaW5nIGlzIHRvIGJlIGFuYWx5c2VkCiAgICAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgdGhlIHN1YnN0cmluZyB0byBiZSBhbmFseXNlZAogICAgKiBAcGFyYW0gbGltaXQgb2Zmc2V0IG9mIHRoZSBzdWJzdHJpbmcgdG8gYmUgYW5hbHlzZWQKICAgICogQHBhcmFtIG9mZnNldDMyIFVURi0zMiBvZmZzZXQgcmVsYXRpdmUgdG8gc3RhcnQKICAgICogQHJldHVybiBVVEYtMTYgb2Zmc2V0IHJlbGF0aXZlIHRvIHN0YXJ0CiAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBvZmZzZXQzMiBpcyBvdXQgb2YgYm91bmRzLgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGZpbmRPZmZzZXRGcm9tQ29kZVBvaW50KGNoYXIgc291cmNlW10sIGludCBzdGFydCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGltaXQsIGludCBvZmZzZXQzMikKICAgIHsKICAgICAgICBjaGFyIGNoOwogICAgICAgIGludCByZXN1bHQgPSBzdGFydCwKICAgICAgICAgICAgY291bnQgPSBvZmZzZXQzMjsKICAgICAgICBpZiAob2Zmc2V0MzIgPiBsaW1pdCAtIHN0YXJ0KSB7CiAgICAgICAgdGhyb3cgbmV3IEFycmF5SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQzMik7CiAgICAgICAgfQogICAgICAgIHdoaWxlIChyZXN1bHQgPCBsaW1pdCAmJiBjb3VudCA+IDApCiAgICAgICAgewogICAgICAgIGNoID0gc291cmNlW3Jlc3VsdF07CiAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgKChyZXN1bHQgKyAxKSA8IGxpbWl0KSAmJiAKICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2VbcmVzdWx0ICsgMV0pKSB7CiAgICAgICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIGNvdW50IC0tOwogICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50ICE9IDApIHsKICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDMyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdCAtIHN0YXJ0OwogICAgfQogICAgICAKICAgIC8qKgogICAgKiBSZXR1cm5zIHRoZSBVVEYtMzIgb2Zmc2V0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGZpcnN0IFVURi0zMiBib3VuZGFyeSBhdCAKICAgICogb3IgYWZ0ZXIgdGhlIGdpdmVuIFVURi0xNiBvZmZzZXQuIFVzZWQgZm9yIHJhbmRvbSBhY2Nlc3MuIFNlZSB0aGUgCiAgICAqIDxhIG5hbWU9Il90b3BfIj5jbGFzcyBkZXNjcmlwdGlvbjwvYT4gZm9yIG5vdGVzIG9uIHJvdW5kdHJpcHBpbmcuPGJyPgogICAgKiA8aT5Ob3RlOiBJZiB0aGUgVVRGLTE2IG9mZnNldCBpcyBpbnRvIHRoZSBtaWRkbGUgb2YgYSBzdXJyb2dhdGUgcGFpciwgCiAgICAqIHRoZW4gdGhlIFVURi0zMiBvZmZzZXQgb2YgdGhlIDxzdHJvbmc+bGVhZDwvc3Ryb25nPiBvZiB0aGUgcGFpciBpcyAKICAgICogcmV0dXJuZWQuCiAgICAqIDwvaT4KICAgICogPHA+CiAgICAqIFRvIGZpbmQgdGhlIFVURi0zMiBsZW5ndGggb2YgYSBzdHJpbmcsIHVzZToKICAgICogICA8cHJlPgogICAgKiAgICAgbGVuMzIgPSBjb3VudENvZGVQb2ludChzb3VyY2UsIHNvdXJjZS5sZW5ndGgoKSk7CiAgICAqICAgPC9wcmU+CiAgICAqIDwvcD4KICAgICogPHA+CiAgICAqIEBwYXJhbSBzb3VyY2UgdGV4dCB0byBhbmFseXNlCiAgICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYtMTYgb2Zmc2V0IDwgc291cmNlIHRleHQgbGVuZ3RoLgogICAgKiBAcmV0dXJuIFVURi0zMiBvZmZzZXQKICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIG9mZnNldDE2IGlzIG91dCBvZiBib3VuZHMuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgZmluZENvZGVQb2ludE9mZnNldChTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0MTYpIAogICAgewogICAgICAgIGlmIChvZmZzZXQxNiA8IDAgfHwgb2Zmc2V0MTYgPiBzb3VyY2UubGVuZ3RoKCkpIHsKICAgICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQxNik7CiAgICAgICAgfQogICAgICAgICAKICAgICAgICBpbnQgcmVzdWx0ID0gMDsKICAgICAgICBjaGFyIGNoOwogICAgICAgIGJvb2xlYW4gaGFkTGVhZFN1cnJvZ2F0ZSA9IGZhbHNlOwogICAgICAgIAogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2Zmc2V0MTY7ICsrIGkpIAogICAgICAgIHsKICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQXQoaSk7CiAgICAgICAgaWYgKGhhZExlYWRTdXJyb2dhdGUgJiYgaXNUcmFpbFN1cnJvZ2F0ZShjaCkpIHsKICAgICAgICAgICAgaGFkTGVhZFN1cnJvZ2F0ZSA9IGZhbHNlOyAgICAgICAgICAgLy8gY291bnQgdmFsaWQgdHJhaWwgYXMgemVybwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBoYWRMZWFkU3Vycm9nYXRlID0gaXNMZWFkU3Vycm9nYXRlKGNoKTsKICAgICAgICAgICAgKysgcmVzdWx0OyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY291bnQgb3RoZXJzIGFzIDEKICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmIChvZmZzZXQxNiA9PSBzb3VyY2UubGVuZ3RoKCkpIHsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gZW5kIG9mIHNvdXJjZSBiZWluZyB0aGUgbGVzcyBzaWduaWZpY2FudCBzdXJyb2dhdGUgY2hhcmFjdGVyCiAgICAgICAgLy8gc2hpZnQgcmVzdWx0IGJhY2sgdG8gdGhlIHN0YXJ0IG9mIHRoZSBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcgogICAgICAgIGlmIChoYWRMZWFkU3Vycm9nYXRlICYmIChpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQob2Zmc2V0MTYpKSkpIHsKICAgICAgICByZXN1bHQgLS07CiAgICAgICAgfQogICAgICAgICAgCiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgICAgCiAgICAvKioKICAgICogUmV0dXJucyB0aGUgVVRGLTMyIG9mZnNldCBjb3JyZXNwb25kaW5nIHRvIHRoZSBmaXJzdCBVVEYtMzIgYm91bmRhcnkgYXQKICAgICogdGhlIGdpdmVuIFVURi0xNiBvZmZzZXQuIFVzZWQgZm9yIHJhbmRvbSBhY2Nlc3MuIFNlZSB0aGUKICAgICogPGEgbmFtZT0iX3RvcF8iPmNsYXNzIGRlc2NyaXB0aW9uPC9hPiBmb3Igbm90ZXMgb24gcm91bmR0cmlwcGluZy48YnI+CiAgICAqIDxpPk5vdGU6IElmIHRoZSBVVEYtMTYgb2Zmc2V0IGlzIGludG8gdGhlIG1pZGRsZSBvZiBhIHN1cnJvZ2F0ZSBwYWlyLCAKICAgICogdGhlbiB0aGUgVVRGLTMyIG9mZnNldCBvZiB0aGUgPHN0cm9uZz5sZWFkPC9zdHJvbmc+IG9mIHRoZSBwYWlyIGlzIAogICAgKiByZXR1cm5lZC4KICAgICogPC9pPgogICAgKiA8cD4KICAgICogVG8gZmluZCB0aGUgVVRGLTMyIGxlbmd0aCBvZiBhIHN0cmluZywgdXNlOgogICAgKiAgIDxwcmU+CiAgICAqICAgICBsZW4zMiA9IGNvdW50Q29kZVBvaW50KHNvdXJjZSk7CiAgICAqICAgPC9wcmU+CiAgICAqIDwvcD4KICAgICogPHA+CiAgICAqIEBwYXJhbSBzb3VyY2UgdGV4dCB0byBhbmFseXNlCiAgICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYtMTYgb2Zmc2V0IDwgc291cmNlIHRleHQgbGVuZ3RoLgogICAgKiBAcmV0dXJuIFVURi0zMiBvZmZzZXQKICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIG9mZnNldDE2IGlzIG91dCBvZiBib3VuZHMuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgZmluZENvZGVQb2ludE9mZnNldChTdHJpbmdCdWZmZXIgc291cmNlLCBpbnQgb2Zmc2V0MTYpCiAgICB7CiAgICAgICAgaWYgKG9mZnNldDE2IDwgMCB8fCBvZmZzZXQxNiA+IHNvdXJjZS5sZW5ndGgoKSkgewogICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDE2KTsKICAgICAgICB9CiAgICAgICAgIAogICAgICAgIGludCByZXN1bHQgPSAwOwogICAgICAgIGNoYXIgY2g7CiAgICAgICAgYm9vbGVhbiBoYWRMZWFkU3Vycm9nYXRlID0gZmFsc2U7CiAgICAgICAgCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBvZmZzZXQxNjsgKysgaSkgCiAgICAgICAgewogICAgICAgIGNoID0gc291cmNlLmNoYXJBdChpKTsKICAgICAgICBpZiAoaGFkTGVhZFN1cnJvZ2F0ZSAmJiBpc1RyYWlsU3Vycm9nYXRlKGNoKSkgewogICAgICAgICAgICBoYWRMZWFkU3Vycm9nYXRlID0gZmFsc2U7ICAgICAgICAgICAvLyBjb3VudCB2YWxpZCB0cmFpbCBhcyB6ZXJvCiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGhhZExlYWRTdXJyb2dhdGUgPSBpc0xlYWRTdXJyb2dhdGUoY2gpOwogICAgICAgICAgICArKyByZXN1bHQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb3VudCBvdGhlcnMgYXMgMQogICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKG9mZnNldDE2ID09IHNvdXJjZS5sZW5ndGgoKSkgewogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBlbmQgb2Ygc291cmNlIGJlaW5nIHRoZSBsZXNzIHNpZ25pZmljYW50IHN1cnJvZ2F0ZSBjaGFyYWN0ZXIKICAgICAgICAvLyBzaGlmdCByZXN1bHQgYmFjayB0byB0aGUgc3RhcnQgb2YgdGhlIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyCiAgICAgICAgaWYgKGhhZExlYWRTdXJyb2dhdGUgJiYgKGlzVHJhaWxTdXJyb2dhdGUoc291cmNlLmNoYXJBdChvZmZzZXQxNikpKSkgCiAgICAgICAgewogICAgICAgICAgICByZXN1bHQgLS07CiAgICAgICAgfQogICAgICAgICAgCiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICogUmV0dXJucyB0aGUgVVRGLTMyIG9mZnNldCBjb3JyZXNwb25kaW5nIHRvIHRoZSBmaXJzdCBVVEYtMzIgYm91bmRhcnkgYXQKICAgICogdGhlIGdpdmVuIFVURi0xNiBvZmZzZXQuIFVzZWQgZm9yIHJhbmRvbSBhY2Nlc3MuIFNlZSB0aGUKICAgICogPGEgbmFtZT0iX3RvcF8iPmNsYXNzIGRlc2NyaXB0aW9uPC9hPiBmb3Igbm90ZXMgb24gcm91bmR0cmlwcGluZy48YnI+CiAgICAqIDxpPk5vdGU6IElmIHRoZSBVVEYtMTYgb2Zmc2V0IGlzIGludG8gdGhlIG1pZGRsZSBvZiBhIHN1cnJvZ2F0ZSBwYWlyLCAKICAgICogdGhlbiB0aGUgVVRGLTMyIG9mZnNldCBvZiB0aGUgPHN0cm9uZz5sZWFkPC9zdHJvbmc+IG9mIHRoZSBwYWlyIGlzIAogICAgKiByZXR1cm5lZC4KICAgICogPC9pPgogICAgKiA8cD4KICAgICogVG8gZmluZCB0aGUgVVRGLTMyIGxlbmd0aCBvZiBhIHN1YnN0cmluZywgdXNlOgogICAgKiAgIDxwcmU+CiAgICAqICAgICBsZW4zMiA9IGNvdW50Q29kZVBvaW50KHNvdXJjZSwgc3RhcnQsIGxpbWl0KTsKICAgICogICA8L3ByZT4KICAgICogPC9wPgogICAgKiA8cD4KICAgICogQHBhcmFtIHNvdXJjZSB0ZXh0IHRvIGFuYWx5c2UKICAgICogQHBhcmFtIHN0YXJ0IG9mZnNldCBvZiB0aGUgc3Vic3RyaW5nCiAgICAqIEBwYXJhbSBsaW1pdCBvZmZzZXQgb2YgdGhlIHN1YnN0cmluZwogICAgKiBAcGFyYW0gb2Zmc2V0MTYgVVRGLTE2IHJlbGF0aXZlIHRvIHN0YXJ0CiAgICAqIEByZXR1cm4gVVRGLTMyIG9mZnNldCByZWxhdGl2ZSB0byBzdGFydAogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgb2Zmc2V0MTYgaXMgbm90IHdpdGhpbiB0aGUgCiAgICAqICAgICAgICAgICAgcmFuZ2Ugb2Ygc3RhcnQgYW5kIGxpbWl0LgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGZpbmRDb2RlUG9pbnRPZmZzZXQoY2hhciBzb3VyY2VbXSwgaW50IHN0YXJ0LCBpbnQgbGltaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvZmZzZXQxNikKICAgIHsKICAgICAgICBvZmZzZXQxNiArPSBzdGFydDsKICAgICAgICBpZiAob2Zmc2V0MTYgPiBsaW1pdCkgewogICAgICAgIAl0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQxNik7CiAgICAgICAgfQogICAgICAgICAKICAgICAgICBpbnQgcmVzdWx0ID0gMDsKICAgICAgICBjaGFyIGNoOwogICAgICAgIGJvb2xlYW4gaGFkTGVhZFN1cnJvZ2F0ZSA9IGZhbHNlOwogICAgICAgIAogICAgICAgIGZvciAoaW50IGkgPSBzdGFydDsgaSA8IG9mZnNldDE2OyArKyBpKSAKICAgICAgICB7CiAgICAgICAgCWNoID0gc291cmNlW2ldOwogICAgICAgIAlpZiAoaGFkTGVhZFN1cnJvZ2F0ZSAmJiBpc1RyYWlsU3Vycm9nYXRlKGNoKSkgewogICAgICAgICAgICAJaGFkTGVhZFN1cnJvZ2F0ZSA9IGZhbHNlOyAvLyBjb3VudCB2YWxpZCB0cmFpbCBhcyB6ZXJvCiAgICAgICAgCX0KICAgICAgICAJZWxzZQogICAgICAgIAl7CiAgICAgICAgICAgIAloYWRMZWFkU3Vycm9nYXRlID0gaXNMZWFkU3Vycm9nYXRlKGNoKTsKICAgICAgICAgICAgCSsrIHJlc3VsdDsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvdW50IG90aGVycyBhcyAxCiAgICAgICAgCX0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKG9mZnNldDE2ID09IGxpbWl0KSB7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIGVuZCBvZiBzb3VyY2UgYmVpbmcgdGhlIGxlc3Mgc2lnbmlmaWNhbnQgc3Vycm9nYXRlIGNoYXJhY3RlcgogICAgICAgIC8vIHNoaWZ0IHJlc3VsdCBiYWNrIHRvIHRoZSBzdGFydCBvZiB0aGUgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIKICAgICAgICBpZiAoaGFkTGVhZFN1cnJvZ2F0ZSAmJiAoaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2Vbb2Zmc2V0MTZdKSkpIHsKICAgICAgICAJcmVzdWx0IC0tOwogICAgICAgIH0KICAgICAgICAgIAogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAqIEFwcGVuZCBhIHNpbmdsZSBVVEYtMzIgdmFsdWUgdG8gdGhlIGVuZCBvZiBhIFN0cmluZ0J1ZmZlci4KICAgICogSWYgYSB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICAgKiA8YSBocmVmPSIuLi9VQ2hhcmFjdGVyLmh0bWwjaXNMZWdhbChjaGFyKSI+aXNMZWdhbCgpPC9hPjwvY29kZT4gb24gCiAgICAqIGNoYXIzMiBiZWZvcmUgY2FsbGluZy4KICAgICogQHBhcmFtIGNoYXIzMiB2YWx1ZSB0byBhcHBlbmQuCiAgICAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgU3RyaW5nQnVmZmVyCiAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIHRocm93biB3aGVuIGNoYXIzMiBkb2VzIG5vdCBsaWUgd2l0aGluCiAgICAqICAgICAgICAgICAgdGhlIHJhbmdlIG9mIHRoZSBVbmljb2RlIGNvZGVwb2ludHMKICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZ0J1ZmZlciBhcHBlbmQoU3RyaW5nQnVmZmVyIHRhcmdldCwgaW50IGNoYXIzMikKICAgIHsKICAgICAgICAvLyBDaGVjayBmb3IgaXJyZWd1bGFyIHZhbHVlcwogICAgICAgIGlmIChjaGFyMzIgPCBDT0RFUE9JTlRfTUlOX1ZBTFVFIHx8IGNoYXIzMiA+IENPREVQT0lOVF9NQVhfVkFMVUUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSWxsZWdhbCBjb2RlcG9pbnQiKTsKICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIC8vIFdyaXRlIHRoZSBVVEYtMTYgdmFsdWVzCiAgICAgICAgaWYgKGNoYXIzMiA+PSBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkgCiAgICAgICAgewogICAgICAgICAgICB0YXJnZXQuYXBwZW5kKGdldExlYWRTdXJyb2dhdGUoY2hhcjMyKSk7CgkgICAgICAgIHRhcmdldC5hcHBlbmQoZ2V0VHJhaWxTdXJyb2dhdGUoY2hhcjMyKSk7CiAgICAgICAgfSAKCSAgICBlbHNlIHsKCSAgICAgICAgdGFyZ2V0LmFwcGVuZCgoY2hhciljaGFyMzIpOwoJICAgIH0KCSAgICByZXR1cm4gdGFyZ2V0OwogICAgfQogICAgICAKICAgIC8qKgogICAgKiBBZGRzIGEgY29kZXBvaW50IHRvIG9mZnNldDE2IHBvc2l0aW9uIG9mIHRoZSBhcmd1bWVudCBjaGFyIGFycmF5LgogICAgKiBAcGFyYW0gdGFyZ2V0IGNoYXIgYXJyYXkgdG8gYmUgYXBwZW5kIHdpdGggdGhlIG5ldyBjb2RlIHBvaW50CiAgICAqIEBwYXJhbSBsaW1pdCBVVEYxNiBvZmZzZXQgd2hpY2ggdGhlIGNvZGVwb2ludCB3aWxsIGJlIGFwcGVuZGVkLgogICAgKiBAcGFyYW0gY2hhcjMyIGNvZGUgcG9pbnQgdG8gYmUgYXBwZW5kZWQKICAgICogQHJldHVybiBvZmZzZXQgYWZ0ZXIgY2hhcjMyIGluIHRoZSBhcnJheS4KICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gdGhyb3duIGlmIHRoZXJlIGlzIG5vdCBlbm91Z2ggCiAgICAqICAgICAgICAgICAgc3BhY2UgZm9yIHRoZSBhcHBlbmQsIG9yIHdoZW4gY2hhcjMyIGRvZXMgbm90IGxpZSB3aXRoaW4KICAgICogICAgICAgICAgICB0aGUgcmFuZ2Ugb2YgdGhlIFVuaWNvZGUgY29kZXBvaW50cy4KICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBhcHBlbmQoY2hhcltdIHRhcmdldCwgaW50IGxpbWl0LCBpbnQgY2hhcjMyKQogICAgewogICAgICAgIC8vIENoZWNrIGZvciBpcnJlZ3VsYXIgdmFsdWVzCiAgICAgICAgaWYgKGNoYXIzMiA8IENPREVQT0lOVF9NSU5fVkFMVUUgfHwgY2hhcjMyID4gQ09ERVBPSU5UX01BWF9WQUxVRSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbGxlZ2FsIGNvZGVwb2ludCIpOwogICAgICAgIH0KICAgICAgICAvLyBXcml0ZSB0aGUgVVRGLTE2IHZhbHVlcwogICAgICAgIGlmIChjaGFyMzIgPj0gU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUpIAogICAgICAgIHsKICAgICAgICAgICAgdGFyZ2V0W2xpbWl0ICsrXSA9IGdldExlYWRTdXJyb2dhdGUoY2hhcjMyKTsKICAgICAgICAgICAgdGFyZ2V0W2xpbWl0ICsrXSA9IGdldFRyYWlsU3Vycm9nYXRlKGNoYXIzMik7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICB0YXJnZXRbbGltaXQgKytdID0gKGNoYXIpY2hhcjMyOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbGltaXQ7CiAgICB9CiAgICAgICAgCiAgICAvKioKICAgICogTnVtYmVyIG9mIGNvZGVwb2ludHMgaW4gYSBVVEYxNiBTdHJpbmcKICAgICogQHBhcmFtIHNvdXJjZSBVVEYxNiBzdHJpbmcKICAgICogQHJldHVybiBudW1iZXIgb2YgY29kZXBvaW50IGluIHN0cmluZwogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvdW50Q29kZVBvaW50KFN0cmluZyBzb3VyY2UpCiAgICB7CiAgICAgICAgaWYgKHNvdXJjZSA9PSBudWxsIHx8IHNvdXJjZS5sZW5ndGgoKSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmluZENvZGVQb2ludE9mZnNldChzb3VyY2UsIHNvdXJjZS5sZW5ndGgoKSk7CiAgICB9CiAgICAgIAogICAgLyoqCiAgICAqIE51bWJlciBvZiBjb2RlcG9pbnRzIGluIGEgVVRGMTYgU3RyaW5nIGJ1ZmZlcgogICAgKiBAcGFyYW0gc291cmNlIFVURjE2IHN0cmluZyBidWZmZXIKICAgICogQHJldHVybiBudW1iZXIgb2YgY29kZXBvaW50IGluIHN0cmluZwogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvdW50Q29kZVBvaW50KFN0cmluZ0J1ZmZlciBzb3VyY2UpCiAgICB7CiAgICAgICAgaWYgKHNvdXJjZSA9PSBudWxsIHx8IHNvdXJjZS5sZW5ndGgoKSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmluZENvZGVQb2ludE9mZnNldChzb3VyY2UsIHNvdXJjZS5sZW5ndGgoKSk7CiAgICB9CgogICAgLyoqCiAgICAqIE51bWJlciBvZiBjb2RlcG9pbnRzIGluIGEgVVRGMTYgY2hhciBhcnJheSBzdWJzdHJpbmcKICAgICogQHBhcmFtIHNvdXJjZSBVVEYxNiBjaGFyIGFycmF5CiAgICAqIEBwYXJhbSBzdGFydCBvZmZzZXQgb2YgdGhlIHN1YnN0cmluZwogICAgKiBAcGFyYW0gbGltaXQgb2Zmc2V0IG9mIHRoZSBzdWJzdHJpbmcKICAgICogQHJldHVybiBudW1iZXIgb2YgY29kZXBvaW50IGluIHRoZSBzdWJzdHJpbmcKICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGlmIHN0YXJ0IGFuZCBsaW1pdCBhcmUgbm90IHZhbGlkLgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGNvdW50Q29kZVBvaW50KGNoYXIgc291cmNlW10sIGludCBzdGFydCwgaW50IGxpbWl0KQogICAgewogICAgICAgIGlmIChzb3VyY2UgPT0gbnVsbCB8fCBzb3VyY2UubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaW5kQ29kZVBvaW50T2Zmc2V0KHNvdXJjZSwgc3RhcnQsIGxpbWl0LCBsaW1pdCAtIHN0YXJ0KTsKICAgIH0KICAgICAgCiAgICAvKioKICAgICogU2V0cyBhIGNvZGUgcG9pbnQgaW50byBhIFVURjMyIHBvc2l0aW9uLgogICAgKiBBZGp1c3RzIHRhcmdldCBhY2NvcmRpbmcgaWYgd2UgYXJlIHJlcGxhY2luZyBhIG5vbi1zdXBwbGVtZW50YXJ5IAogICAgKiBjb2RlcG9pbnQgd2l0aCBhIHN1cHBsZW1lbnRhcnkgYW5kIHZpY2UgdmVyc2EuCiAgICAqIEBwYXJhbSB0YXJnZXQgc3RyaW5nYnVmZmVyCiAgICAqIEBwYXJhbSBvZmZzZXQzMiBVVEYzMiBwb3NpdGlvbiB0byBpbnNlcnQgaW50bwogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgb2Zmc2V0MzIgaXMgb3V0IG9mIGJvdW5kcy4KICAgICogQHBhcmFtIGNoYXIzMiBjb2RlIHBvaW50CiAgICAqIEBkZXByZWNhdGVkIHRvIGJlIHJlbW92ZWQgYWZ0ZXIgdGhlIHllYXIgMjAwMiwKICAgICogVVRGMTYuc2V0Q2hhckF0KHRhcmdldCwgCiAgICAqICAgICAgICAgICAgICAgICBmaW5kT2Zmc2V0RnJvbUNvZGVQb2ludCh0YXJnZXQudG9TdHJpbmcoKSwgb2Zmc2V0MzIpLCAKICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIzMik7CiAgICAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIHNldENoYXJBdENvZGVQb2ludE9mZnNldChTdHJpbmdCdWZmZXIgdGFyZ2V0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldDMyLCBpbnQgY2hhcjMyKQogICAgewogICAgICAgIGludCBvZmZzZXQxNiA9IGZpbmRPZmZzZXRGcm9tQ29kZVBvaW50KHRhcmdldC50b1N0cmluZygpLCBvZmZzZXQzMik7CiAgICAgICAgc2V0Q2hhckF0KHRhcmdldCwgb2Zmc2V0MTYsIGNoYXIzMik7CiAgICB9CgogICAgLyoqCiAgICAqIFNldCBhIGNvZGUgcG9pbnQgaW50byBhIFVURjE2IHBvc2l0aW9uLiAKICAgICogQWRqdXN0cyB0YXJnZXQgYWNjb3JkaW5nIGlmIHdlIGFyZSByZXBsYWNpbmcgYSBub24tc3VwcGxlbWVudGFyeSAKICAgICogY29kZXBvaW50IHdpdGggYSBzdXBwbGVtZW50YXJ5IGFuZCB2aWNlIHZlcnNhLgogICAgKiBAcGFyYW0gdGFyZ2V0IHN0cmluZ2J1ZmZlcgogICAgKiBAcGFyYW0gb2Zmc2V0MTYgVVRGMTYgcG9zaXRpb24gdG8gaW5zZXJ0IGludG8KICAgICogQHBhcmFtIGNoYXIzMiBjb2RlIHBvaW50CiAgICAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIHNldENoYXJBdChTdHJpbmdCdWZmZXIgdGFyZ2V0LCBpbnQgb2Zmc2V0MTYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhcjMyKQogICAgewogICAgICAgIGludCBjb3VudCA9IDE7CiAgICAgICAgY2hhciBzaW5nbGUgPSB0YXJnZXQuY2hhckF0KG9mZnNldDE2KTsKICAgICAgICAKICAgICAgICBpZiAoaXNTdXJyb2dhdGUoc2luZ2xlKSkgCiAgICAgICAgewogICAgICAgICAgICAvLyBwYWlycyBvZiB0aGUgc3Vycm9nYXRlIHdpdGggb2Zmc2V0MTYgYXQgdGhlIGxlYWQgY2hhciBmb3VuZAogICAgICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKHNpbmdsZSkgJiYgKHRhcmdldC5sZW5ndGgoKSA+IG9mZnNldDE2ICsgMSkgCiAgICAgICAgICAgICAgICAmJiBpc1RyYWlsU3Vycm9nYXRlKHRhcmdldC5jaGFyQXQob2Zmc2V0MTYgKyAxKSkpIHsKCSAgICAgICAgICAgIGNvdW50ICsrOwoJICAgICAgICB9CgkgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgLy8gcGFpcnMgb2YgdGhlIHN1cnJvZ2F0ZSB3aXRoIG9mZnNldDE2IGF0IHRoZSB0cmFpbCBjaGFyIAoJICAgICAgICAgICAgLy8gZm91bmQKCSAgICAgICAgICAgIGlmIChpc1RyYWlsU3Vycm9nYXRlKHNpbmdsZSkgJiYgKG9mZnNldDE2ID4gMCkgJiYKCSAgICAgICAgICAgICAgICBpc0xlYWRTdXJyb2dhdGUodGFyZ2V0LmNoYXJBdChvZmZzZXQxNiAtMSkpKQoJICAgICAgICAgICAgewoJICAgICAgICAgICAgICAgIG9mZnNldDE2IC0tOwoJICAgICAgICAgICAgICAgIGNvdW50ICsrOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAgIHRhcmdldC5yZXBsYWNlKG9mZnNldDE2LCBvZmZzZXQxNiArIGNvdW50LCB2YWx1ZU9mKGNoYXIzMikpOwogICAgfQogICAgCQogICAgLyoqCiAgICAqIFNldCBhIGNvZGUgcG9pbnQgaW50byBhIFVURjE2IHBvc2l0aW9uIGluIGEgY2hhciBhcnJheS4KICAgICogQWRqdXN0cyB0YXJnZXQgYWNjb3JkaW5nIGlmIHdlIGFyZSByZXBsYWNpbmcgYSBub24tc3VwcGxlbWVudGFyeSAKICAgICogY29kZXBvaW50IHdpdGggYSBzdXBwbGVtZW50YXJ5IGFuZCB2aWNlIHZlcnNhLgogICAgKiBAcGFyYW0gdGFyZ2V0IGNoYXIgYXJyYXkKICAgICogQHBhcmFtIGxpbWl0IG51bWJlcnMgb2YgdmFsaWQgY2hhcnMgaW4gdGFyZ2V0LCBkaWZmZXJlbnQgZnJvbSAKICAgICogICAgICAgIHRhcmdldC5sZW5ndGguIGxpbWl0IGNvdW50cyB0aGUgbnVtYmVyIG9mIGNoYXJzIGluIHRhcmdldCAKICAgICogICAgICAgIHRoYXQgcmVwcmVzZW50cyBhIHN0cmluZywgbm90IHRoZSBzaXplIG9mIGFycmF5IHRhcmdldC4KICAgICogQHBhcmFtIG9mZnNldDE2IFVURjE2IHBvc2l0aW9uIHRvIGluc2VydCBpbnRvCiAgICAqIEBwYXJhbSBjaGFyMzIgY29kZSBwb2ludAogICAgKiBAcmV0dXJuIG5ldyBudW1iZXIgb2YgY2hhcnMgaW4gdGFyZ2V0IHRoYXQgcmVwcmVzZW50cyBhIHN0cmluZwogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgb2Zmc2V0MTYgaXMgb3V0IG9mIHJhbmdlCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgc2V0Q2hhckF0KGNoYXIgdGFyZ2V0W10sIGludCBsaW1pdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldDE2LCBpbnQgY2hhcjMyKQogICAgewogICAgICAgIGlmIChvZmZzZXQxNiA+PSBsaW1pdCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDE2KTsKICAgICAgICB9CiAgICAgICAgaW50IGNvdW50ID0gMTsKICAgICAgICBjaGFyIHNpbmdsZSA9IHRhcmdldFtvZmZzZXQxNl07CiAgICAgICAgCiAgICAgICAgaWYgKGlzU3Vycm9nYXRlKHNpbmdsZSkpIAogICAgICAgIHsKICAgICAgICAgICAgLy8gcGFpcnMgb2YgdGhlIHN1cnJvZ2F0ZSB3aXRoIG9mZnNldDE2IGF0IHRoZSBsZWFkIGNoYXIgZm91bmQKICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShzaW5nbGUpICYmICh0YXJnZXQubGVuZ3RoID4gb2Zmc2V0MTYgKyAxKSAmJgogICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZSh0YXJnZXRbb2Zmc2V0MTYgKyAxXSkpIHsKCSAgICAgICAgICAgIGNvdW50ICsrOwoJICAgICAgICB9CgkgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgLy8gcGFpcnMgb2YgdGhlIHN1cnJvZ2F0ZSB3aXRoIG9mZnNldDE2IGF0IHRoZSB0cmFpbCBjaGFyIAoJICAgICAgICAgICAgLy8gZm91bmQKCSAgICAgICAgICAgIGlmIChpc1RyYWlsU3Vycm9nYXRlKHNpbmdsZSkgJiYgKG9mZnNldDE2ID4gMCkgJiYKCSAgICAgICAgICAgICAgICBpc0xlYWRTdXJyb2dhdGUodGFyZ2V0W29mZnNldDE2IC0xXSkpCgkgICAgICAgICAgICB7CgkgICAgICAgICAgICAgICAgb2Zmc2V0MTYgLS07CgkgICAgICAgICAgICAgICAgY291bnQgKys7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CiAgICAJICAKCSAgICBTdHJpbmcgc3RyID0gdmFsdWVPZihjaGFyMzIpOwoJICAgIGludCByZXN1bHQgPSBsaW1pdDsKCSAgICBpbnQgc3RybGVuZ3RoID0gc3RyLmxlbmd0aCgpOwoJICAgIHRhcmdldFtvZmZzZXQxNl0gPSBzdHIuY2hhckF0KDApOwoJICAgIGlmIChjb3VudCA9PSBzdHJsZW5ndGgpIHsKCSAgICAgICAgaWYgKGNvdW50ID09IDIpIHsKCSAgICAgICAgICAgIHRhcmdldFtvZmZzZXQxNiArIDFdID0gc3RyLmNoYXJBdCgxKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBlbHNlIHsKCSAgICAgICAgLy8gdGhpcyBpcyBub3QgZXhhY3QgbWF0Y2ggaW4gc3BhY2UsIHdlJ2xsIGhhdmUgdG8gZG8gc29tZSAKCSAgICAgICAgLy8gc2hpZnRpbmcKCSAgICAgICAgU3lzdGVtLmFycmF5Y29weSh0YXJnZXQsIG9mZnNldDE2ICsgY291bnQsIHRhcmdldCwgCgkgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDE2ICsgc3RybGVuZ3RoLCBsaW1pdCAtIChvZmZzZXQxNiArIGNvdW50KSk7CgkgICAgICAgIGlmIChjb3VudCA8IHN0cmxlbmd0aCkgewoJICAgICAgICAgICAgLy8gY2hhcjMyIGlzIGEgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgdHJ5aW5nIHRvIHNxdWVlemUgaW50bwoJICAgICAgICAgICAgLy8gYSBub24tc3VwcGxlbWVudGFyeSBzcGFjZQoJICAgICAgICAgICAgdGFyZ2V0W29mZnNldDE2ICsgMV0gPSBzdHIuY2hhckF0KDEpOwoJICAgICAgICAgICAgcmVzdWx0ICsrOwoJICAgICAgICAgICAgaWYgKHJlc3VsdCA8IHRhcmdldC5sZW5ndGgpIHsKCSAgICAgICAgICAgICAgICB0YXJnZXRbcmVzdWx0XSA9IDA7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICAvLyBjaGFyMzIgaXMgYSBub24tc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgdHJ5aW5nIHRvIGZpbGwgCgkgICAgICAgICAgICAvLyBpbnRvIGEgc3VwcGxlbWVudGFyeSBzcGFjZQoJICAgICAgICAgICAgcmVzdWx0IC0tOwoJICAgICAgICAgICAgdGFyZ2V0W3Jlc3VsdF0gPSAwOwoJICAgICAgICB9CgkgICAgfQoJICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAgIAogICAgLyoqCiAgICAqIFNoaWZ0cyBvZmZzZXQxNiBieSB0aGUgYXJndW1lbnQgbnVtYmVyIG9mIGNvZGVwb2ludHMKICAgICogQHBhcmFtIHNvdXJjZSBzdHJpbmcKICAgICogQHBhcmFtIG9mZnNldDE2IFVURjE2IHBvc2l0aW9uIHRvIHNoaWZ0CiAgICAqIEBwYXJhbSBzaGlmdDMyIG51bWJlciBvZiBjb2RlcG9pbnRzIHRvIHNoaWZ0CiAgICAqIEByZXR1cm4gbmV3IHNoaWZ0ZWQgb2Zmc2V0MTYgCiAgICAqIEBleGNlcHRpb24gSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiB0aGUgbmV3IG9mZnNldDE2IGlzIG91dCBvZiAKICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kcy4KICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBtb3ZlQ29kZVBvaW50T2Zmc2V0KFN0cmluZyBzb3VyY2UsIGludCBvZmZzZXQxNiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNoaWZ0MzIpCiAgICB7CiAgICAgICAgaW50IHNpemUgPSBzb3VyY2UubGVuZ3RoKCk7CiAgICAgICAgaWYgKG9mZnNldDE2IDwgMCB8fCBzaGlmdDMyICsgb2Zmc2V0MTYgPiBzaXplKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDE2KTsKICAgICAgICB9CiAgICAgICAgY2hhciBjaDsKICAgICAgICBpbnQgcmVzdWx0ID0gb2Zmc2V0MTY7CiAgICAgICAgaW50IGNvdW50ID0gc2hpZnQzMjsKICAgICAgICB3aGlsZSAocmVzdWx0IDwgc2l6ZSAmJiBjb3VudCA+IDApCiAgICAgICAgewogICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQXQocmVzdWx0KTsKICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgKChyZXN1bHQgKyAxKSA8IHNpemUpICYmIAogICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCArIDEpKSkgewogICAgICAgICAgICAgICAgcmVzdWx0ICsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgY291bnQgLS07CiAgICAgICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50ICE9IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oc2hpZnQzMik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAqIFNoaWZ0cyBvZmZzZXQxNiBieSB0aGUgYXJndW1lbnQgbnVtYmVyIG9mIGNvZGVwb2ludHMKICAgICogQHBhcmFtIHRhcmdldCBzdHJpbmcgYnVmZmVyCiAgICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYxNiBwb3NpdGlvbiB0byBzaGlmdAogICAgKiBAcGFyYW0gc2hpZnQzMiBudW1iZXIgb2YgY29kZXBvaW50cyB0byBzaGlmdAogICAgKiBAcmV0dXJuIG5ldyBzaGlmdGVkIG9mZnNldDE2IAogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIG5ldyBvZmZzZXQxNiBpcyBvdXQgb2YgCiAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3VuZHMuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgbW92ZUNvZGVQb2ludE9mZnNldChTdHJpbmdCdWZmZXIgc291cmNlLCBpbnQgb2Zmc2V0MTYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNoaWZ0MzIpCiAgICB7CiAgICAgICAgaW50IHNpemUgPSBzb3VyY2UubGVuZ3RoKCk7CiAgICAgICAgaWYgKG9mZnNldDE2IDwgMCB8fCBzaGlmdDMyICsgb2Zmc2V0MTYgPiBzaXplKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDE2KTsKICAgICAgICB9CiAgICAgICAgY2hhciBjaDsKICAgICAgICBpbnQgcmVzdWx0ID0gb2Zmc2V0MTY7CiAgICAgICAgaW50IGNvdW50ID0gc2hpZnQzMjsKICAgICAgICB3aGlsZSAocmVzdWx0IDwgc2l6ZSAmJiBjb3VudCA+IDApCiAgICAgICAgewogICAgICAgICAgICBjaCA9IHNvdXJjZS5jaGFyQXQocmVzdWx0KTsKICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgKChyZXN1bHQgKyAxKSA8IHNpemUpICYmIAogICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCArIDEpKSkgewogICAgICAgICAgICAgICAgcmVzdWx0ICsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgY291bnQgLS07CiAgICAgICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50ICE9IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oc2hpZnQzMik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgLyoqCiAgICAqIFNoaWZ0cyBvZmZzZXQxNiBieSB0aGUgYXJndW1lbnQgbnVtYmVyIG9mIGNvZGVwb2ludHMgd2l0aGluIGEgc3ViYXJyYXkuCiAgICAqIEBwYXJhbSB0YXJnZXQgY2hhciBhcnJheQogICAgKiBAcGFyYW0gc3RhcnQgcG9zaXRpb24gb2YgdGhlIHN1YmFycmF5IHRvIGJlIHBlcmZvcm1lZCBvbgogICAgKiBAcGFyYW0gbGltaXQgcG9zaXRpb24gb2YgdGhlIHN1YmFycmF5IHRvIGJlIHBlcmZvcm1lZCBvbgogICAgKiBAcGFyYW0gb2Zmc2V0MTYgVVRGMTYgcG9zaXRpb24gdG8gc2hpZnQgcmVsYXRpdmUgdG8gc3RhcnQKICAgICogQHBhcmFtIHNoaWZ0MzIgbnVtYmVyIG9mIGNvZGVwb2ludHMgdG8gc2hpZnQKICAgICogQHJldHVybiBuZXcgc2hpZnRlZCBvZmZzZXQxNiByZWxhdGl2ZSB0byBzdGFydAogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgdGhlIG5ldyBvZmZzZXQxNiBpcyBvdXQgb2YgCiAgICAqICAgICAgICAgICAgYm91bmRzIHdpdGggcmVzcGVjdCB0byB0aGUgc3ViYXJyYXkuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgbW92ZUNvZGVQb2ludE9mZnNldChjaGFyIHNvdXJjZVtdLCBpbnQgc3RhcnQsIGludCBsaW1pdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvZmZzZXQxNiwgaW50IHNoaWZ0MzIpCiAgICB7CiAgICAgICAgb2Zmc2V0MTYgKz0gc3RhcnQ7CiAgICAgICAgaWYgKHNoaWZ0MzIgKyBvZmZzZXQxNiA+IGxpbWl0KSB7CiAgICAgICAgICAgIHRocm93IG5ldyBTdHJpbmdJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDE2KTsKICAgICAgICB9CiAgICAgICAgY2hhciBjaDsKICAgICAgICBpbnQgcmVzdWx0ID0gb2Zmc2V0MTY7CiAgICAgICAgaW50IGNvdW50ID0gc2hpZnQzMjsKICAgICAgICB3aGlsZSAocmVzdWx0IDwgbGltaXQgJiYgY291bnQgPiAwKQogICAgICAgIHsKICAgICAgICAgICAgY2ggPSBzb3VyY2VbcmVzdWx0XTsKICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkgJiYgKChyZXN1bHQgKyAxKSA8IGxpbWl0KSAmJiAKICAgICAgICAgICAgICAgIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlW3Jlc3VsdCArIDFdKSkgewogICAgICAgICAgICAgICAgcmVzdWx0ICsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgY291bnQgLS07CiAgICAgICAgICAgIHJlc3VsdCArKzsKICAgICAgICB9CiAgICAgICAgaWYgKGNvdW50ICE9IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oc2hpZnQzMik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQgLSBzdGFydDsKICAgIH0KICAgICAgCiAgICAvKioKICAgICogSW5zZXJ0cyBjaGFyMzIgY29kZXBvaW50IGludG8gdGFyZ2V0IGF0IHRoZSBhcmd1bWVudCBvZmZzZXQxNi4gCiAgICAqIElmIHRoZSBvZmZzZXQxNiBpcyBpbiB0aGUgbWlkZGxlIG9mIGEgc3VwcGxlbWVudGFyeSBjb2RlcG9pbnQsIGNoYXIzMiAKICAgICogd2lsbCBiZSBpbnNlcnRlZCBhZnRlciB0aGUgc3VwcGxlbWVudGFyeSBjb2RlcG9pbnQuCiAgICAqIFRoZSBsZW5ndGggb2YgdGFyZ2V0IGluY3JlYXNlcyBieSBvbmUgaWYgY29kZXBvaW50IGlzIG5vbi1zdXBwbGVtZW50YXJ5LCAKICAgICogMiBvdGhlcndpc2UuIAogICAgKiA8cD4KICAgICogVGhlIG92ZXJhbGwgZWZmZWN0IGlzIGV4YWN0bHkgYXMgaWYgdGhlIGFyZ3VtZW50IHdlcmUgY29udmVydGVkIHRvIGEgCiAgICAqIHN0cmluZyBieSB0aGUgbWV0aG9kIHZhbHVlT2YoY2hhcikgYW5kIHRoZSBjaGFyYWN0ZXJzIGluIHRoYXQgc3RyaW5nIAogICAgKiB3ZXJlIHRoZW4gaW5zZXJ0ZWQgaW50byB0YXJnZXQgYXQgdGhlIHBvc2l0aW9uIGluZGljYXRlZCBieSBvZmZzZXQxNi4gCiAgICAqIDwvcD4KICAgICogPHA+CiAgICAqIFRoZSBvZmZzZXQgYXJndW1lbnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMCwgYW5kIGxlc3MgdGhhbiAKICAgICogb3IgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZiBzb3VyY2UuCiAgICAqIEBwYXJhbSB0YXJnZXQgc3RyaW5nIGJ1ZmZlciB0byBpbnNlcnQgdG8KICAgICogQHBhcmFtIG9mZnNldDE2IG9mZnNldCB3aGljaCBjaGFyMzIgd2lsbCBiZSBpbnNlcnRlZCBpbgogICAgKiBAcGFyYW0gY2hhcjMyIGNvZGVwb2ludCB0byBiZSBpbnNlcnRlZAogICAgKiBAcmV0dXJuIGEgcmVmZXJlbmNlIHRvIHRhcmdldAogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gdGhyb3duIGlmIG9mZnNldDE2IGlzIGludmFsaWQuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmdCdWZmZXIgaW5zZXJ0KFN0cmluZ0J1ZmZlciB0YXJnZXQsIGludCBvZmZzZXQxNiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhcjMyKQogICAgewogICAgICAgIFN0cmluZyBzdHIgPSB2YWx1ZU9mKGNoYXIzMik7CiAgICAgICAgaWYgKG9mZnNldDE2ICE9IHRhcmdldC5sZW5ndGgoKSAmJiAKICAgICAgICAgICAgYm91bmRzKHRhcmdldCwgb2Zmc2V0MTYpID09IFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWSkgewogICAgICAgICAgICBvZmZzZXQxNiArKzsKICAgICAgICB9CiAgICAgICAgdGFyZ2V0Lmluc2VydChvZmZzZXQxNiwgc3RyKTsKICAgICAgICByZXR1cm4gdGFyZ2V0OwogICAgfQoKICAgIC8qKgogICAgKiBJbnNlcnRzIGNoYXIzMiBjb2RlcG9pbnQgaW50byB0YXJnZXQgYXQgdGhlIGFyZ3VtZW50IG9mZnNldDE2LiAKICAgICogSWYgdGhlIG9mZnNldDE2IGlzIGluIHRoZSBtaWRkbGUgb2YgYSBzdXBwbGVtZW50YXJ5IGNvZGVwb2ludCwgY2hhcjMyIAogICAgKiB3aWxsIGJlIGluc2VydGVkIGFmdGVyIHRoZSBzdXBwbGVtZW50YXJ5IGNvZGVwb2ludC4KICAgICogTGltaXQgaW5jcmVhc2VzIGJ5IG9uZSBpZiBjb2RlcG9pbnQgaXMgbm9uLXN1cHBsZW1lbnRhcnksIDIgb3RoZXJ3aXNlLiAKICAgICogPHA+CiAgICAqIFRoZSBvdmVyYWxsIGVmZmVjdCBpcyBleGFjdGx5IGFzIGlmIHRoZSBhcmd1bWVudCB3ZXJlIGNvbnZlcnRlZCB0byBhIAogICAgKiBzdHJpbmcgYnkgdGhlIG1ldGhvZCB2YWx1ZU9mKGNoYXIpIGFuZCB0aGUgY2hhcmFjdGVycyBpbiB0aGF0IHN0cmluZyAKICAgICogd2VyZSB0aGVuIGluc2VydGVkIGludG8gdGFyZ2V0IGF0IHRoZSBwb3NpdGlvbiBpbmRpY2F0ZWQgYnkgb2Zmc2V0MTYuIAogICAgKiA8L3A+CiAgICAqIDxwPgogICAgKiBUaGUgb2Zmc2V0IGFyZ3VtZW50IG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAsIGFuZCBsZXNzIHRoYW4gCiAgICAqIG9yIGVxdWFsIHRvIHRoZSBsaW1pdC4KICAgICogQHBhcmFtIHRhcmdldCBjaGFyIGFycmF5IHRvIGluc2VydCB0bwogICAgKiBAcGFyYW0gbGltaXQgZW5kIGluZGV4IG9mIHRoZSBjaGFyIGFycmF5LCBsaW1pdCA8PSB0YXJnZXQubGVuZ3RoCiAgICAqIEBwYXJhbSBvZmZzZXQxNiBvZmZzZXQgd2hpY2ggY2hhcjMyIHdpbGwgYmUgaW5zZXJ0ZWQgaW4KICAgICogQHBhcmFtIGNoYXIzMiBjb2RlcG9pbnQgdG8gYmUgaW5zZXJ0ZWQKICAgICogQHJldHVybiBuZXcgbGltaXQgc2l6ZQogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gdGhyb3duIGlmIG9mZnNldDE2IGlzIGludmFsaWQuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgaW5zZXJ0KGNoYXIgdGFyZ2V0W10sIGludCBsaW1pdCwgaW50IG9mZnNldDE2LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY2hhcjMyKQogICAgewogICAgICAgIFN0cmluZyBzdHIgPSB2YWx1ZU9mKGNoYXIzMik7CiAgICAgICAgaWYgKG9mZnNldDE2ICE9IGxpbWl0ICYmCiAgICAgICAgICAgIGJvdW5kcyh0YXJnZXQsIDAsIGxpbWl0LCBvZmZzZXQxNikgPT0gVFJBSUxfU1VSUk9HQVRFX0JPVU5EQVJZKSB7CiAgICAgICAgICAgIG9mZnNldDE2ICsrOwogICAgICAgIH0KICAgICAgICBpbnQgc2l6ZSA9IHN0ci5sZW5ndGgoKTsKICAgICAgICBpZiAobGltaXQgKyBzaXplID4gdGFyZ2V0Lmxlbmd0aCkgewogICAgICAgICAgICB0aHJvdyBuZXcgQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKG9mZnNldDE2ICsgc2l6ZSk7CiAgICAgICAgfQogICAgICAgIFN5c3RlbS5hcnJheWNvcHkodGFyZ2V0LCBvZmZzZXQxNiwgdGFyZ2V0LCBvZmZzZXQxNiArIHNpemUsIAogICAgICAgICAgICAgICAgICAgICAgICBsaW1pdCAtIG9mZnNldDE2KTsKICAgICAgICB0YXJnZXRbb2Zmc2V0MTZdID0gc3RyLmNoYXJBdCgwKTsKICAgICAgICBpZiAoc2l6ZSA9PSAyKSB7CiAgICAgICAgICAgIHRhcmdldFtvZmZzZXQxNiArIDFdID0gc3RyLmNoYXJBdCgxKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxpbWl0ICsgc2l6ZTsKICAgIH0KCiAgICAvKioKICAgICogUmVtb3ZlcyB0aGUgY29kZXBvaW50IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4gdGhpcyB0YXJnZXQgCiAgICAqIChzaG9ydGVuaW5nIHRhcmdldCBieSAxIGNoYXJhY3RlciBpZiB0aGUgY29kZXBvaW50IGlzIGEgCiAgICAqIG5vbi1zdXBwbGVtZW50YXJ5LCAyIG90aGVyd2lzZSkuCiAgICAqIEBwYXJhbSB0YXJnZXQgc3RyaW5nIGJ1ZmZlciB0byByZW1vdmUgY29kZXBvaW50IGZyb20KICAgICogQHBhcmFtIG9mZnNldDE2IG9mZnNldCB3aGljaCB0aGUgY29kZXBvaW50IHdpbGwgYmUgcmVtb3ZlZAogICAgKiBAcmV0dXJuIGEgcmVmZXJlbmNlIHRvIHRhcmdldAogICAgKiBAZXhjZXB0aW9uIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gdGhyb3duIGlmIG9mZnNldDE2IGlzIGludmFsaWQuCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmdCdWZmZXIgZGVsZXRlKFN0cmluZ0J1ZmZlciB0YXJnZXQsIGludCBvZmZzZXQxNikKICAgIHsKICAgICAgICBpbnQgY291bnQgPSAxOwogICAgICAgIHN3aXRjaCAoYm91bmRzKHRhcmdldCwgb2Zmc2V0MTYpKSB7CiAgICAgICAgICAgIGNhc2UgTEVBRF9TVVJST0dBVEVfQk9VTkRBUlk6IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWTogCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0MTYgLS07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHRhcmdldC5kZWxldGUob2Zmc2V0MTYsIG9mZnNldDE2ICsgY291bnQpOwogICAgICAgIHJldHVybiB0YXJnZXQ7CiAgICB9CgogICAgLyoqCiAgICAqIFJlbW92ZXMgdGhlIGNvZGVwb2ludCBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uIGluIHRoaXMgdGFyZ2V0IAogICAgKiAoc2hvcnRlbmluZyB0YXJnZXQgYnkgMSBjaGFyYWN0ZXIgaWYgdGhlIGNvZGVwb2ludCBpcyBhIAogICAgKiBub24tc3VwcGxlbWVudGFyeSwgMiBvdGhlcndpc2UpLgogICAgKiBAcGFyYW0gdGFyZ2V0IHN0cmluZyBidWZmZXIgdG8gcmVtb3ZlIGNvZGVwb2ludCBmcm9tCiAgICAqIEBwYXJhbSBsaW1pdCBlbmQgaW5kZXggb2YgdGhlIGNoYXIgYXJyYXksIGxpbWl0IDw9IHRhcmdldC5sZW5ndGgKICAgICogQHBhcmFtIG9mZnNldDE2IG9mZnNldCB3aGljaCB0aGUgY29kZXBvaW50IHdpbGwgYmUgcmVtb3ZlZAogICAgKiBAcmV0dXJuIGEgbmV3IGxpbWl0IHNpemUKICAgICogQGV4Y2VwdGlvbiBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIHRocm93biBpZiBvZmZzZXQxNiBpcyBpbnZhbGlkLgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGRlbGV0ZShjaGFyIHRhcmdldFtdLCBpbnQgbGltaXQsIGludCBvZmZzZXQxNikKICAgIHsKICAgICAgICBpbnQgY291bnQgPSAxOwogICAgICAgIHN3aXRjaCAoYm91bmRzKHRhcmdldCwgMCwgbGltaXQsIG9mZnNldDE2KSkgewogICAgICAgICAgICBjYXNlIExFQURfU1VSUk9HQVRFX0JPVU5EQVJZOiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCArKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBUUkFJTF9TVVJST0dBVEVfQk9VTkRBUlk6IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDE2IC0tOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBTeXN0ZW0uYXJyYXljb3B5KHRhcmdldCwgb2Zmc2V0MTYgKyBjb3VudCwgdGFyZ2V0LCBvZmZzZXQxNiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0IC0gKG9mZnNldDE2ICsgY291bnQpKTsKICAgICAgICB0YXJnZXRbbGltaXQgLSBjb3VudF0gPSAwOwogICAgICAgIHJldHVybiBsaW1pdCAtIGNvdW50OwogICAgfQogICAgICAKICAgIC8qKgogICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFyZ3VtZW50IFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyBvZiAKICAgICogdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGFyZ3VtZW50IGNvZGVwb2ludC4gSS5lLiwgdGhlIHNtYWxsZXN0IAogICAgKiBpbmRleCA8Y29kZT5pPC9jb2RlPiBzdWNoIHRoYXQgPGNvZGU+VVRGMTYuY2hhckF0KHNvdXJjZSwgaSkgPT0gY2hhcjMyPC9jb2RlPiBpcyB0cnVlLiAKICAgICogPHA+SWYgbm8gc3VjaCBjaGFyYWN0ZXIgb2NjdXJzIGluIHRoaXMgc3RyaW5nLCB0aGVuIC0xIGlzIHJldHVybmVkLjwvcD4gCiAgICAqIDxwPgogICAgKiBFeGFtcGxlczo8YnI+CiAgICAqIFVURjE2LmluZGV4T2YoImFiYyIsICdhJykgcmV0dXJucyAwPGJyPgogICAgKiBVVEYxNi5pbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAweDEwMDAwKSByZXR1cm5zIDM8YnI+CiAgICAqIFVURjE2LmluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsIDB4ZDgwMCkgcmV0dXJucyAtMTxicj4KICAgICogPC9wPgogICAgKiBOb3RlIHRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGFzIHN1cHBvcnQgdG8gamRrIDEuMywgd2hpY2ggZG9lcyBub3QgCiAgICAqIHN1cHBvcnQgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHRvIGl0cyBmdWxsZXN0LgogICAgKiBAcGFyYW0gc291cmNlIFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyB0aGF0IHdpbGwgYmUgc2VhcmNoZWQKICAgICogQHBhcmFtIGNoYXIzMiBjb2RlcG9pbnQgdG8gc2VhcmNoIGZvciAKICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGNvZGVwb2ludCBpbiB0aGUgCiAgICAqICAgICAgICAgYXJndW1lbnQgVW5pY29kZSBzdHJpbmcsIG9yIC0xIGlmIHRoZSBjb2RlcG9pbnQgZG9lcyBub3Qgb2NjdXIuCiAgICAqIEBkcmFmdCBzaW5jZSByZWxlYXNlIDIuMQogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGluZGV4T2YoU3RyaW5nIHNvdXJjZSwgaW50IGNoYXIzMikgIAogICAgewogICAgICAgIGlmIChjaGFyMzIgPCBDT0RFUE9JTlRfTUlOX1ZBTFVFIHx8IAogICAgICAgICAgICBjaGFyMzIgPiBDT0RFUE9JTlRfTUFYX1ZBTFVFKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXJndW1lbnQgY2hhcjMyIGlzIG5vdCBhIHZhbGlkIGNvZGVwb2ludCIpOwogICAgICAgIH0KICAgICAgICAvLyBub24tc3Vycm9nYXRlIGJtcAogICAgICAgIGlmIChjaGFyMzIgPCBMRUFEX1NVUlJPR0FURV9NSU5fVkFMVUUgfHwKICAgICAgICAgICAgKGNoYXIzMiA+IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUUgJiYgCiAgICAgICAgICAgICBjaGFyMzIgPCBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkpIHsKICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5pbmRleE9mKChjaGFyKWNoYXIzMik7CiAgICAgICAgfQogICAgICAgIC8vIHN1cnJvZ2F0ZQogICAgICAgIGlmIChjaGFyMzIgPCBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkgewogICAgICAgICAgICBpbnQgcmVzdWx0ID0gc291cmNlLmluZGV4T2YoKGNoYXIpY2hhcjMyKTsKICAgICAgICAgICAgaWYgKHJlc3VsdCA+PSAwKSB7CiAgICAgICAgICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKChjaGFyKWNoYXIzMikgJiYgCiAgICAgICAgICAgICAgICAgICAgKHJlc3VsdCA8IHNvdXJjZS5sZW5ndGgoKSAtIDEpICYmIAogICAgICAgICAgICAgICAgICAgIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlLmNoYXJBdChyZXN1bHQgKyAxKSkpIHsgCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4T2Yoc291cmNlLCBjaGFyMzIsIHJlc3VsdCArIDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gdHJhaWwgc3Vycm9nYXRlCiAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID4gMCAmJiAKICAgICAgICAgICAgICAgICAgICBpc0xlYWRTdXJyb2dhdGUoc291cmNlLmNoYXJBdChyZXN1bHQgLSAxKSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXhPZihzb3VyY2UsIGNoYXIzMiwgcmVzdWx0ICsgMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgICAgIC8vIHN1cHBsZW1lbnRhcnkKICAgICAgICBTdHJpbmcgY2hhcjMyc3RyID0gdG9TdHJpbmcoY2hhcjMyKTsKICAgICAgICByZXR1cm4gc291cmNlLmluZGV4T2YoY2hhcjMyc3RyKTsKICAgIH0KICAgICAKICAgIC8qKgogICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFyZ3VtZW50IFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyBvZiAKICAgICogdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGFyZ3VtZW50IHN0cmluZyBzdHIuIFRoaXMgbWV0aG9kIGlzIAogICAgKiBpbXBsZW1lbnRlZCBiYXNlZCBvbiBjb2RlcG9pbnRzLCBoZW5jZSBhICJsZWFkIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIgKwogICAgKiB0cmFpbCBzdXJyb2dhdGUgY2hhcmFjdGVyIiBpcyB0cmVhdGVkIGFzIG9uZSBlbnRpdHkuZQogICAgKiBIZW5jZSBpZiB0aGUgc3RyIHN0YXJ0cyB3aXRoIHRyYWlsIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIgYXQgaW5kZXggMCwgYSAKICAgICogc291cmNlIHdpdGggYSBsZWFkaW5nIGEgc3Vycm9nYXRlIGNoYXJhY3RlciBiZWZvcmUgc3RyIGZvdW5kIGF0IGluIAogICAgKiBzb3VyY2Ugd2lsbCBub3QgaGF2ZSBhIHZhbGlkIG1hdGNoLiBWaWNlIHZlcnNhIGZvciBsZWFkIHN1cnJvZ2F0ZXMgCiAgICAqIHRoYXQgZW5kcyBzdHIuCiAgICAqIFNlZSBleGFtcGxlIGJlbG93LgogICAgKiA8cD5JZiBubyBzdWNoIHN0cmluZyBzdHIgb2NjdXJzIGluIHRoaXMgc291cmNlLCB0aGVuIC0xIGlzIHJldHVybmVkLgogICAgKiA8L3A+IDxwPgogICAgKiBFeGFtcGxlczo8YnI+CiAgICAqIFVURjE2LmluZGV4T2YoImFiYyIsICJhYiIpIHJldHVybnMgMDxicj4KICAgICogVVRGMTYuaW5kZXhPZigiYWJjXHVkODAwXHVkYzAwIiwgIlx1ZDgwMFx1ZGMwMCIpIHJldHVybnMgMzxicj4KICAgICogVVRGMTYuaW5kZXhPZigiYWJjXHVkODAwXHVkYzAwIiwgIlx1ZDgwMCIpIHJldHVybnMgLTE8YnI+CiAgICAqIDwvcD4KICAgICogTm90ZSB0aGlzIG1ldGhvZCBpcyBwcm92aWRlZCBhcyBzdXBwb3J0IHRvIGpkayAxLjMsIHdoaWNoIGRvZXMgbm90IAogICAgKiBzdXBwb3J0IHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVycyB0byBpdHMgZnVsbGVzdC4KICAgICogQHBhcmFtIHNvdXJjZSBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgdGhhdCB3aWxsIGJlIHNlYXJjaGVkCiAgICAqIEBwYXJhbSBzdHIgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIHRvIHNlYXJjaCBmb3IKICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgdGhlIGNvZGVwb2ludCBpbiB0aGUgCiAgICAqICAgICAgICAgYXJndW1lbnQgVW5pY29kZSBzdHJpbmcsIG9yIC0xIGlmIHRoZSBjb2RlcG9pbnQgZG9lcyBub3Qgb2NjdXIuCiAgICAqIEBkcmFmdCBzaW5jZSByZWxlYXNlIDIuMQogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGluZGV4T2YoU3RyaW5nIHNvdXJjZSwgU3RyaW5nIHN0cikgIAogICAgewogICAgICAgIGludCBzdHJMZW5ndGggPSBzdHIubGVuZ3RoKCk7CiAgICAgICAgLy8gbm9uLXN1cnJvZ2F0ZSBlbmRzCiAgICAgICAgaWYgKCFpc1RyYWlsU3Vycm9nYXRlKHN0ci5jaGFyQXQoMCkpICYmIAogICAgICAgICAgICAhaXNMZWFkU3Vycm9nYXRlKHN0ci5jaGFyQXQoc3RyTGVuZ3RoIC0gMSkpKSB7CiAgICAgICAgICAgIHJldHVybiBzb3VyY2UuaW5kZXhPZihzdHIpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpbnQgcmVzdWx0ICAgID0gc291cmNlLmluZGV4T2Yoc3RyKTsKICAgICAgICBpbnQgcmVzdWx0RW5kID0gcmVzdWx0ICsgc3RyTGVuZ3RoOwogICAgICAgIGlmIChyZXN1bHQgPj0gMCkgewogICAgICAgICAgICAvLyBjaGVjayBsYXN0IGNoYXJhY3RlcgogICAgICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKHN0ci5jaGFyQXQoc3RyTGVuZ3RoIC0gMSkpICYmIAogICAgICAgICAgICAgICAgKHJlc3VsdCA8IHNvdXJjZS5sZW5ndGgoKSAtIDEpICYmIAogICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdEVuZCArIDEpKSkgeyAKICAgICAgICAgICAgICAgIHJldHVybiBpbmRleE9mKHNvdXJjZSwgc3RyLCByZXN1bHRFbmQgKyAxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBjaGVjayBmaXJzdCBjaGFyYWN0ZXIgd2hpY2ggaXMgYSB0cmFpbCBzdXJyb2dhdGUKICAgICAgICAgICAgaWYgKGlzVHJhaWxTdXJyb2dhdGUoc3RyLmNoYXJBdCgwKSkgJiYgcmVzdWx0ID4gMCAmJiAKICAgICAgICAgICAgICAgIGlzTGVhZFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCAtIDEpKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4T2Yoc291cmNlLCBzdHIsIHJlc3VsdEVuZCArIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQogICAgCiAgICAvKioKICAgICogUmV0dXJucyB0aGUgaW5kZXggd2l0aGluIHRoZSBhcmd1bWVudCBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgb2YgCiAgICAqIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBhcmd1bWVudCBjb2RlcG9pbnQuIEkuZS4sIHRoZSBzbWFsbGVzdCAKICAgICogaW5kZXggaSBzdWNoIHRoYXQ6IDxicj4KICAgICogKFVURjE2LmNoYXJBdChzb3VyY2UsIGkpID09IGNoYXIzMiAmJiBpID49IGZyb21JbmRleCkgaXMgdHJ1ZS4gCiAgICAqIDxwPklmIG5vIHN1Y2ggY2hhcmFjdGVyIG9jY3VycyBpbiB0aGlzIHN0cmluZywgdGhlbiAtMSBpcyByZXR1cm5lZC48L3A+IAogICAgKiA8cD4KICAgICogRXhhbXBsZXM6PGJyPgogICAgKiBVVEYxNi5pbmRleE9mKCJhYmMiLCAnYScsIDEpIHJldHVybnMgLTE8YnI+CiAgICAqIFVURjE2LmluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsIDB4MTAwMDAsIDEpIHJldHVybnMgMzxicj4KICAgICogVVRGMTYuaW5kZXhPZigiYWJjXHVkODAwXHVkYzAwIiwgMHhkODAwLCAxKSByZXR1cm5zIC0xPGJyPgogICAgKiA8L3A+CiAgICAqIE5vdGUgdGhpcyBtZXRob2QgaXMgcHJvdmlkZWQgYXMgc3VwcG9ydCB0byBqZGsgMS4zLCB3aGljaCBkb2VzIG5vdCAKICAgICogc3VwcG9ydCBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMgdG8gaXRzIGZ1bGxlc3QuCiAgICAqIEBwYXJhbSBzb3VyY2UgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIHRoYXQgd2lsbCBiZSBzZWFyY2hlZAogICAgKiBAcGFyYW0gY2hhcjMyIGNvZGVwb2ludCB0byBzZWFyY2ggZm9yIAogICAgKiBAcGFyYW0gZnJvbUluZGV4IHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uIAogICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY29kZXBvaW50IGluIHRoZSAKICAgICogICAgICAgICBhcmd1bWVudCBVbmljb2RlIHN0cmluZyBhdCBvciBhZnRlciBmcm9tSW5kZXgsIG9yIC0xIGlmIHRoZSAKICAgICogICAgICAgICBjb2RlcG9pbnQgZG9lcyBub3Qgb2NjdXIuCiAgICAqIEBkcmFmdCBzaW5jZSByZWxlYXNlIDIuMQogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGluZGV4T2YoU3RyaW5nIHNvdXJjZSwgaW50IGNoYXIzMiwgaW50IGZyb21JbmRleCkgCiAgICB7CiAgICAgICAgaWYgKGNoYXIzMiA8IENPREVQT0lOVF9NSU5fVkFMVUUgfHwgY2hhcjMyID4gQ09ERVBPSU5UX01BWF9WQUxVRSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFyZ3VtZW50IGNoYXIzMiBpcyBub3QgYSB2YWxpZCBjb2RlcG9pbnQiKTsKICAgICAgICB9CiAgICAgICAgLy8gbm9uLXN1cnJvZ2F0ZSBibXAKICAgICAgICBpZiAoY2hhcjMyIDwgTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFIHx8CiAgICAgICAgICAgIChjaGFyMzIgPiBUUkFJTF9TVVJST0dBVEVfTUFYX1ZBTFVFICYmIAogICAgICAgICAgICAgY2hhcjMyIDwgU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUpKSB7CiAgICAgICAgICAgIHJldHVybiBzb3VyY2UuaW5kZXhPZigoY2hhciljaGFyMzIsIGZyb21JbmRleCk7CiAgICAgICAgfQogICAgICAgIC8vIHN1cnJvZ2F0ZQogICAgICAgIGlmIChjaGFyMzIgPCBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkgewogICAgICAgICAgICBpbnQgcmVzdWx0ID0gc291cmNlLmluZGV4T2YoKGNoYXIpY2hhcjMyLCBmcm9tSW5kZXgpOwogICAgICAgICAgICBpZiAocmVzdWx0ID49IDApIHsKICAgICAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoKGNoYXIpY2hhcjMyKSAmJiAKICAgICAgICAgICAgICAgICAgICAocmVzdWx0IDwgc291cmNlLmxlbmd0aCgpIC0gMSkgJiYgCiAgICAgICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCArIDEpKSkgeyAKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXhPZihzb3VyY2UsIGNoYXIzMiwgcmVzdWx0ICsgMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyB0cmFpbCBzdXJyb2dhdGUKICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPiAwICYmIAogICAgICAgICAgICAgICAgICAgIGlzTGVhZFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCAtIDEpKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmRleE9mKHNvdXJjZSwgY2hhcjMyLCByZXN1bHQgKyAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgLy8gc3VwcGxlbWVudGFyeQogICAgICAgIFN0cmluZyBjaGFyMzJzdHIgPSB0b1N0cmluZyhjaGFyMzIpOwogICAgICAgIHJldHVybiBzb3VyY2UuaW5kZXhPZihjaGFyMzJzdHIsIGZyb21JbmRleCk7CiAgICB9CgogICAgLyoqCiAgICAqIFJldHVybnMgdGhlIGluZGV4IHdpdGhpbiB0aGUgYXJndW1lbnQgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIG9mIAogICAgKiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgYXJndW1lbnQgc3RyaW5nIHN0ci4gVGhpcyBtZXRob2QgaXMgCiAgICAqIGltcGxlbWVudGVkIGJhc2VkIG9uIGNvZGVwb2ludHMsIGhlbmNlIGEgImxlYWQgc3Vycm9nYXRlIGNoYXJhY3RlciArCiAgICAqIHRyYWlsIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIiIGlzIHRyZWF0ZWQgYXMgb25lIGVudGl0eS5lCiAgICAqIEhlbmNlIGlmIHRoZSBzdHIgc3RhcnRzIHdpdGggdHJhaWwgc3Vycm9nYXRlIGNoYXJhY3RlciBhdCBpbmRleCAwLCBhIAogICAgKiBzb3VyY2Ugd2l0aCBhIGxlYWRpbmcgYSBzdXJyb2dhdGUgY2hhcmFjdGVyIGJlZm9yZSBzdHIgZm91bmQgYXQgaW4gCiAgICAqIHNvdXJjZSB3aWxsIG5vdCBoYXZlIGEgdmFsaWQgbWF0Y2guIFZpY2UgdmVyc2EgZm9yIGxlYWQgc3Vycm9nYXRlcyAKICAgICogdGhhdCBlbmRzIHN0ci4KICAgICogU2VlIGV4YW1wbGUgYmVsb3cuCiAgICAqIDxwPklmIG5vIHN1Y2ggc3RyaW5nIHN0ciBvY2N1cnMgaW4gdGhpcyBzb3VyY2UsIHRoZW4gLTEgaXMgcmV0dXJuZWQuCiAgICAqIDwvcD4gPHA+CiAgICAqIEV4YW1wbGVzOjxicj4KICAgICogVVRGMTYuaW5kZXhPZigiYWJjIiwgImFiIiwgMCkgcmV0dXJucyAwPGJyPgogICAgKiBVVEYxNi5pbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAiXHVkODAwXHVkYzAwIiwgMCkgcmV0dXJucyAzPGJyPgogICAgKiBVVEYxNi5pbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAiXHVkODAwXHVkYzAwIiwgMikgcmV0dXJucyAzPGJyPgogICAgKiBVVEYxNi5pbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAiXHVkODAwIiwgMCkgcmV0dXJucyAtMTxicj4KICAgICogPC9wPgogICAgKiBOb3RlIHRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGFzIHN1cHBvcnQgdG8gamRrIDEuMywgd2hpY2ggZG9lcyBub3QgCiAgICAqIHN1cHBvcnQgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHRvIGl0cyBmdWxsZXN0LgogICAgKiBAcGFyYW0gc291cmNlIFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyB0aGF0IHdpbGwgYmUgc2VhcmNoZWQKICAgICogQHBhcmFtIHN0ciBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgdG8gc2VhcmNoIGZvcgogICAgKiBAcGFyYW0gZnJvbUluZGV4IHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uIAogICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY29kZXBvaW50IGluIHRoZSAKICAgICogICAgICAgICBhcmd1bWVudCBVbmljb2RlIHN0cmluZywgb3IgLTEgaWYgdGhlIGNvZGVwb2ludCBkb2VzIG5vdCBvY2N1ci4KICAgICogQGRyYWZ0IHNpbmNlIHJlbGVhc2UgMi4xCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgaW5kZXhPZihTdHJpbmcgc291cmNlLCBTdHJpbmcgc3RyLCBpbnQgZnJvbUluZGV4KSAgCiAgICB7CiAgICAgICAgaW50IHN0ckxlbmd0aCA9IHN0ci5sZW5ndGgoKTsKICAgICAgICAvLyBub24tc3Vycm9nYXRlIGVuZHMKICAgICAgICBpZiAoIWlzVHJhaWxTdXJyb2dhdGUoc3RyLmNoYXJBdCgwKSkgJiYgCiAgICAgICAgICAgICFpc0xlYWRTdXJyb2dhdGUoc3RyLmNoYXJBdChzdHJMZW5ndGggLSAxKSkpIHsKICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5pbmRleE9mKHN0ciwgZnJvbUluZGV4KTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaW50IHJlc3VsdCAgICA9IHNvdXJjZS5pbmRleE9mKHN0ciwgZnJvbUluZGV4KTsKICAgICAgICBpbnQgcmVzdWx0RW5kID0gcmVzdWx0ICsgc3RyTGVuZ3RoOwogICAgICAgIGlmIChyZXN1bHQgPj0gMCkgewogICAgICAgICAgICAvLyBjaGVjayBsYXN0IGNoYXJhY3RlcgogICAgICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKHN0ci5jaGFyQXQoc3RyTGVuZ3RoIC0gMSkpICYmIAogICAgICAgICAgICAgICAgKHJlc3VsdCA8IHNvdXJjZS5sZW5ndGgoKSAtIDEpICYmIAogICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdEVuZCkpKSB7IAogICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4T2Yoc291cmNlLCBzdHIsIHJlc3VsdEVuZCArIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGNoZWNrIGZpcnN0IGNoYXJhY3RlciB3aGljaCBpcyBhIHRyYWlsIHN1cnJvZ2F0ZQogICAgICAgICAgICBpZiAoaXNUcmFpbFN1cnJvZ2F0ZShzdHIuY2hhckF0KDApKSAmJiByZXN1bHQgPiAwICYmIAogICAgICAgICAgICAgICAgaXNMZWFkU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0IC0gMSkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXhPZihzb3VyY2UsIHN0ciwgcmVzdWx0RW5kICsgMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFyZ3VtZW50IFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyBvZiAKICAgICogdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgYXJndW1lbnQgY29kZXBvaW50LiBJLmUuLCB0aGUgaW5kZXggcmV0dXJuZWQgCiAgICAqIGlzIHRoZSBsYXJnZXN0IHZhbHVlIGkgc3VjaCB0aGF0OiBVVEYxNi5jaGFyQXQoc291cmNlLCBpKSA9PSBjaGFyMzIKICAgICogaXMgdHJ1ZS4gCiAgICAqIDxwPgogICAgKiBFeGFtcGxlczo8YnI+CiAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmMiLCAnYScpIHJldHVybnMgMDxicj4KICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsIDB4MTAwMDApIHJldHVybnMgMzxicj4KICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsIDB4ZDgwMCkgcmV0dXJucyAtMTxicj4KICAgICogPC9wPgogICAgKiA8cD5zb3VyY2UgaXMgc2VhcmNoZWQgYmFja3dhcmRzIHN0YXJ0aW5nIGF0IHRoZSBsYXN0IGNoYXJhY3Rlci48L3A+IAogICAgKiBOb3RlIHRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGFzIHN1cHBvcnQgdG8gamRrIDEuMywgd2hpY2ggZG9lcyBub3QgCiAgICAqIHN1cHBvcnQgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHRvIGl0cyBmdWxsZXN0LgogICAgKiBAcGFyYW0gc291cmNlIFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyB0aGF0IHdpbGwgYmUgc2VhcmNoZWQKICAgICogQHBhcmFtIGNoYXIzMiBjb2RlcG9pbnQgdG8gc2VhcmNoIGZvciAKICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY29kZXBvaW50IGluIHNvdXJjZSwgCiAgICAqICAgICAgICAgb3IgLTEgaWYgdGhlIGNvZGVwb2ludCBkb2VzIG5vdCBvY2N1ci4KICAgICogQGRyYWZ0IHNpbmNlIHJlbGVhc2UgMi4xCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgbGFzdEluZGV4T2YoU3RyaW5nIHNvdXJjZSwgaW50IGNoYXIzMikgIAogICAgewogICAgICAgIGlmIChjaGFyMzIgPCBDT0RFUE9JTlRfTUlOX1ZBTFVFIHx8IGNoYXIzMiA+IENPREVQT0lOVF9NQVhfVkFMVUUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBcmd1bWVudCBjaGFyMzIgaXMgbm90IGEgdmFsaWQgY29kZXBvaW50Iik7CiAgICAgICAgfQogICAgICAgIC8vIG5vbi1zdXJyb2dhdGUgYm1wCiAgICAgICAgaWYgKGNoYXIzMiA8IExFQURfU1VSUk9HQVRFX01JTl9WQUxVRSB8fAogICAgICAgICAgICAoY2hhcjMyID4gVFJBSUxfU1VSUk9HQVRFX01BWF9WQUxVRSAmJiAKICAgICAgICAgICAgIGNoYXIzMiA8IFNVUFBMRU1FTlRBUllfTUlOX1ZBTFVFKSkgewogICAgICAgICAgICByZXR1cm4gc291cmNlLmxhc3RJbmRleE9mKChjaGFyKWNoYXIzMik7CiAgICAgICAgfQogICAgICAgIC8vIHN1cnJvZ2F0ZQogICAgICAgIGlmIChjaGFyMzIgPCBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkgewogICAgICAgICAgICBpbnQgcmVzdWx0ID0gc291cmNlLmxhc3RJbmRleE9mKChjaGFyKWNoYXIzMik7CiAgICAgICAgICAgIGlmIChyZXN1bHQgPj0gMCkgewogICAgICAgICAgICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZSgoY2hhciljaGFyMzIpICYmIAogICAgICAgICAgICAgICAgICAgIChyZXN1bHQgPCBzb3VyY2UubGVuZ3RoKCkgLSAxKSAmJiAKICAgICAgICAgICAgICAgICAgICBpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0ICsgMSkpKSB7IAogICAgICAgICAgICAgICAgICAgIHJldHVybiBsYXN0SW5kZXhPZihzb3VyY2UsIGNoYXIzMiwgcmVzdWx0IC0gMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyB0cmFpbCBzdXJyb2dhdGUKICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPiAwICYmIAogICAgICAgICAgICAgICAgICAgIGlzTGVhZFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCAtIDEpKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBsYXN0SW5kZXhPZihzb3VyY2UsIGNoYXIzMiwgcmVzdWx0IC0gMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgICAgIC8vIHN1cHBsZW1lbnRhcnkKICAgICAgICBTdHJpbmcgY2hhcjMyc3RyID0gdG9TdHJpbmcoY2hhcjMyKTsKICAgICAgICByZXR1cm4gc291cmNlLmxhc3RJbmRleE9mKGNoYXIzMnN0cik7CiAgICB9CiAgICAKICAgIC8qKgogICAgKiBSZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFyZ3VtZW50IFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyBvZiAKICAgICogdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgYXJndW1lbnQgc3RyaW5nIHN0ci4gVGhpcyBtZXRob2QgaXMgCiAgICAqIGltcGxlbWVudGVkIGJhc2VkIG9uIGNvZGVwb2ludHMsIGhlbmNlIGEgImxlYWQgc3Vycm9nYXRlIGNoYXJhY3RlciArCiAgICAqIHRyYWlsIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIiIGlzIHRyZWF0ZWQgYXMgb25lIGVudGl0eS5lCiAgICAqIEhlbmNlIGlmIHRoZSBzdHIgc3RhcnRzIHdpdGggdHJhaWwgc3Vycm9nYXRlIGNoYXJhY3RlciBhdCBpbmRleCAwLCBhIAogICAgKiBzb3VyY2Ugd2l0aCBhIGxlYWRpbmcgYSBzdXJyb2dhdGUgY2hhcmFjdGVyIGJlZm9yZSBzdHIgZm91bmQgYXQgaW4gCiAgICAqIHNvdXJjZSB3aWxsIG5vdCBoYXZlIGEgdmFsaWQgbWF0Y2guIFZpY2UgdmVyc2EgZm9yIGxlYWQgc3Vycm9nYXRlcyAKICAgICogdGhhdCBlbmRzIHN0ci4KICAgICogU2VlIGV4YW1wbGUgYmVsb3cuCiAgICAqIDxwPgogICAgKiBFeGFtcGxlczo8YnI+CiAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmMiLCAiYSIpIHJldHVybnMgMDxicj4KICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsICJcdWQ4MDBcdWRjMDAiKSByZXR1cm5zIDM8YnI+CiAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAiXHVkODAwIikgcmV0dXJucyAtMTxicj4KICAgICogPC9wPgogICAgKiA8cD5zb3VyY2UgaXMgc2VhcmNoZWQgYmFja3dhcmRzIHN0YXJ0aW5nIGF0IHRoZSBsYXN0IGNoYXJhY3Rlci48L3A+IAogICAgKiBOb3RlIHRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGFzIHN1cHBvcnQgdG8gamRrIDEuMywgd2hpY2ggZG9lcyBub3QgCiAgICAqIHN1cHBvcnQgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHRvIGl0cyBmdWxsZXN0LgogICAgKiBAcGFyYW0gc291cmNlIFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyB0aGF0IHdpbGwgYmUgc2VhcmNoZWQKICAgICogQHBhcmFtIHN0ciBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgdG8gc2VhcmNoIGZvciAKICAgICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgY29kZXBvaW50IGluIHNvdXJjZSwgCiAgICAqICAgICAgICAgb3IgLTEgaWYgdGhlIGNvZGVwb2ludCBkb2VzIG5vdCBvY2N1ci4KICAgICogQGRyYWZ0IHNpbmNlIHJlbGVhc2UgMi4xCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBpbnQgbGFzdEluZGV4T2YoU3RyaW5nIHNvdXJjZSwgU3RyaW5nIHN0cikgIAogICAgewogICAgICAgIGludCBzdHJMZW5ndGggPSBzdHIubGVuZ3RoKCk7CiAgICAgICAgLy8gbm9uLXN1cnJvZ2F0ZSBlbmRzCiAgICAgICAgaWYgKCFpc1RyYWlsU3Vycm9nYXRlKHN0ci5jaGFyQXQoMCkpICYmIAogICAgICAgICAgICAhaXNMZWFkU3Vycm9nYXRlKHN0ci5jaGFyQXQoc3RyTGVuZ3RoIC0gMSkpKSB7CiAgICAgICAgICAgIHJldHVybiBzb3VyY2UubGFzdEluZGV4T2Yoc3RyKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaW50IHJlc3VsdCAgICA9IHNvdXJjZS5sYXN0SW5kZXhPZihzdHIpOwogICAgICAgIGlmIChyZXN1bHQgPj0gMCkgewogICAgICAgICAgICAvLyBjaGVjayBsYXN0IGNoYXJhY3RlcgogICAgICAgICAgICBpZiAoaXNMZWFkU3Vycm9nYXRlKHN0ci5jaGFyQXQoc3RyTGVuZ3RoIC0gMSkpICYmIAogICAgICAgICAgICAgICAgKHJlc3VsdCA8IHNvdXJjZS5sZW5ndGgoKSAtIDEpICYmIAogICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCArIHN0ckxlbmd0aCArIDEpKSkgeyAKICAgICAgICAgICAgICAgIHJldHVybiBsYXN0SW5kZXhPZihzb3VyY2UsIHN0ciwgcmVzdWx0IC0gMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gY2hlY2sgZmlyc3QgY2hhcmFjdGVyIHdoaWNoIGlzIGEgdHJhaWwgc3Vycm9nYXRlCiAgICAgICAgICAgIGlmIChpc1RyYWlsU3Vycm9nYXRlKHN0ci5jaGFyQXQoMCkpICYmIHJlc3VsdCA+IDAgJiYgCiAgICAgICAgICAgICAgICBpc0xlYWRTdXJyb2dhdGUoc291cmNlLmNoYXJBdChyZXN1bHQgLSAxKSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBsYXN0SW5kZXhPZihzb3VyY2UsIHN0ciwgcmVzdWx0IC0gMSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAKICAgIC8qKgogICAgKiA8cD5SZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFyZ3VtZW50IFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyBvZiAKICAgICogdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgYXJndW1lbnQgY29kZXBvaW50LCB3aGVyZSB0aGUgcmVzdWx0IGlzIGxlc3MKICAgICogdGhhbiBvciBlcXVhbHMgdG8gZnJvbUluZGV4LjwvcD4gCiAgICAqIDxwPlRoaXMgbWV0aG9kIGlzIGltcGxlbWVudGVkIGJhc2VkIG9uIGNvZGVwb2ludHMsIGhlbmNlIGEgc2luZ2xlIAogICAgKiBzdXJyb2dhdGUgY2hhcmFjdGVyIHdpbGwgbm90IG1hdGNoIGEgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIuPC9wPgogICAgKiA8cD5zb3VyY2UgaXMgc2VhcmNoZWQgYmFja3dhcmRzIHN0YXJ0aW5nIGF0IHRoZSBsYXN0IGNoYXJhY3RlciBzdGFydGluZyAKICAgICogYXQgdGhlIHNwZWNpZmllZCBpbmRleC48L3A+CiAgICAqIDxwPgogICAgKiBFeGFtcGxlczo8YnI+CiAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmMiLCAnYycsIDIpIHJldHVybnMgMjxicj4KICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiYyIsICdjJywgMSkgcmV0dXJucyAtMTxicj4KICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsIDB4MTAwMDAsIDUpIHJldHVybnMgMzxicj4KICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsIDB4MTAwMDAsIDMpIHJldHVybnMgMzxicj4KICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsIDB4ZDgwMCkgcmV0dXJucyAtMTxicj4KICAgICogPC9wPgogICAgKiBOb3RlIHRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGFzIHN1cHBvcnQgdG8gamRrIDEuMywgd2hpY2ggZG9lcyBub3QgCiAgICAqIHN1cHBvcnQgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHRvIGl0cyBmdWxsZXN0LgogICAgKiBAcGFyYW0gc291cmNlIFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyB0aGF0IHdpbGwgYmUgc2VhcmNoZWQKICAgICogQHBhcmFtIGNoYXIzMiBjb2RlcG9pbnQgdG8gc2VhcmNoIGZvciAKICAgICogQHBhcmFtIGZyb21JbmRleCB0aGUgaW5kZXggdG8gc3RhcnQgdGhlIHNlYXJjaCBmcm9tLiBUaGVyZSBpcyBubyAKICAgICogICAgICAgICAgICAgICAgICByZXN0cmljdGlvbiBvbiB0aGUgdmFsdWUgb2YgZnJvbUluZGV4LiBJZiBpdCBpcyAKICAgICogICAgICAgICAgICAgICAgICBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZywgCiAgICAqICAgICAgICAgICAgICAgICAgaXQgaGFzIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIGVxdWFsIHRvIG9uZSAKICAgICogICAgICAgICAgICAgICAgICBsZXNzIHRoYW4gdGhlIGxlbmd0aCBvZiB0aGlzIHN0cmluZzogdGhpcyBlbnRpcmUgCiAgICAqICAgICAgICAgICAgICAgICAgc3RyaW5nIG1heSBiZSBzZWFyY2hlZC4gSWYgaXQgaXMgbmVnYXRpdmUsIGl0IGhhcyAKICAgICogICAgICAgICAgICAgICAgICB0aGUgc2FtZSBlZmZlY3QgYXMgaWYgaXQgd2VyZSAtMTogLTEgaXMgcmV0dXJuZWQuIAogICAgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBvY2N1cnJlbmNlIG9mIHRoZSBjb2RlcG9pbnQgaW4gc291cmNlLCAKICAgICogICAgICAgICBvciAtMSBpZiB0aGUgY29kZXBvaW50IGRvZXMgbm90IG9jY3VyLgogICAgKiBAZHJhZnQgc2luY2UgcmVsZWFzZSAyLjEKICAgICovCiAgICBwdWJsaWMgc3RhdGljIGludCBsYXN0SW5kZXhPZihTdHJpbmcgc291cmNlLCBpbnQgY2hhcjMyLCBpbnQgZnJvbUluZGV4KQogICAgewogICAgICAgIGlmIChjaGFyMzIgPCBDT0RFUE9JTlRfTUlOX1ZBTFVFIHx8IGNoYXIzMiA+IENPREVQT0lOVF9NQVhfVkFMVUUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBcmd1bWVudCBjaGFyMzIgaXMgbm90IGEgdmFsaWQgY29kZXBvaW50Iik7CiAgICAgICAgfQogICAgICAgIC8vIG5vbi1zdXJyb2dhdGUgYm1wCiAgICAgICAgaWYgKGNoYXIzMiA8IExFQURfU1VSUk9HQVRFX01JTl9WQUxVRSB8fAogICAgICAgICAgICAoY2hhcjMyID4gVFJBSUxfU1VSUk9HQVRFX01BWF9WQUxVRSAmJiAKICAgICAgICAgICAgIGNoYXIzMiA8IFNVUFBMRU1FTlRBUllfTUlOX1ZBTFVFKSkgewogICAgICAgICAgICByZXR1cm4gc291cmNlLmxhc3RJbmRleE9mKChjaGFyKWNoYXIzMiwgZnJvbUluZGV4KTsKICAgICAgICB9CiAgICAgICAgLy8gc3Vycm9nYXRlCiAgICAgICAgaWYgKGNoYXIzMiA8IFNVUFBMRU1FTlRBUllfTUlOX1ZBTFVFKSB7CiAgICAgICAgICAgIGludCByZXN1bHQgPSBzb3VyY2UubGFzdEluZGV4T2YoKGNoYXIpY2hhcjMyLCBmcm9tSW5kZXgpOwogICAgICAgICAgICBpZiAocmVzdWx0ID49IDApIHsKICAgICAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoKGNoYXIpY2hhcjMyKSAmJiAKICAgICAgICAgICAgICAgICAgICAocmVzdWx0IDwgc291cmNlLmxlbmd0aCgpIC0gMSkgJiYgCiAgICAgICAgICAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KHJlc3VsdCArIDEpKSkgeyAKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGFzdEluZGV4T2Yoc291cmNlLCBjaGFyMzIsIHJlc3VsdCAtIDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gdHJhaWwgc3Vycm9nYXRlCiAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID4gMCAmJiAKICAgICAgICAgICAgICAgICAgICBpc0xlYWRTdXJyb2dhdGUoc291cmNlLmNoYXJBdChyZXN1bHQgLSAxKSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGFzdEluZGV4T2Yoc291cmNlLCBjaGFyMzIsIHJlc3VsdCAtIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgICAgICAvLyBzdXBwbGVtZW50YXJ5CiAgICAgICAgU3RyaW5nIGNoYXIzMnN0ciA9IHRvU3RyaW5nKGNoYXIzMik7CiAgICAgICAgcmV0dXJuIHNvdXJjZS5sYXN0SW5kZXhPZihjaGFyMzJzdHIsIGZyb21JbmRleCk7CiAgICB9CiAgICAKICAgIC8qKgogICAgKiA8cD5SZXR1cm5zIHRoZSBpbmRleCB3aXRoaW4gdGhlIGFyZ3VtZW50IFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyBvZiAKICAgICogdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiB0aGUgYXJndW1lbnQgc3RyaW5nIHN0ciwgd2hlcmUgdGhlIHJlc3VsdCBpcyBsZXNzCiAgICAqIHRoYW4gb3IgZXF1YWxzIHRvIGZyb21JbmRleC48L3A+IAogICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBpbXBsZW1lbnRlZCBiYXNlZCBvbiBjb2RlcG9pbnRzLCBoZW5jZSBhIAogICAgKiAibGVhZCBzdXJyb2dhdGUgY2hhcmFjdGVyICsgdHJhaWwgc3Vycm9nYXRlIGNoYXJhY3RlciIgaXMgdHJlYXRlZCBhcyBvbmUgCiAgICAqIGVudGl0eS4KICAgICogSGVuY2UgaWYgdGhlIHN0ciBzdGFydHMgd2l0aCB0cmFpbCBzdXJyb2dhdGUgY2hhcmFjdGVyIGF0IGluZGV4IDAsIGEgCiAgICAqIHNvdXJjZSB3aXRoIGEgbGVhZGluZyBhIHN1cnJvZ2F0ZSBjaGFyYWN0ZXIgYmVmb3JlIHN0ciBmb3VuZCBhdCBpbiAKICAgICogc291cmNlIHdpbGwgbm90IGhhdmUgYSB2YWxpZCBtYXRjaC4gVmljZSB2ZXJzYSBmb3IgbGVhZCBzdXJyb2dhdGVzIAogICAgKiB0aGF0IGVuZHMgc3RyLgogICAgKiA8L3A+CiAgICAqIFNlZSBleGFtcGxlIGJlbG93LgogICAgKiA8cD4KICAgICogRXhhbXBsZXM6PGJyPgogICAgKiBVVEYxNi5sYXN0SW5kZXhPZigiYWJjIiwgImMiLCAyKSByZXR1cm5zIDI8YnI+CiAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmMiLCAiYyIsIDEpIHJldHVybnMgLTE8YnI+CiAgICAqIFVURjE2Lmxhc3RJbmRleE9mKCJhYmNcdWQ4MDBcdWRjMDAiLCAiXHVkODAwXHVkYzAwIiwgNSkgcmV0dXJucyAzPGJyPgogICAgKiBVVEYxNi5sYXN0SW5kZXhPZigiYWJjXHVkODAwXHVkYzAwIiwgIlx1ZDgwMFx1ZGMwMCIsIDMpIHJldHVybnMgMzxicj4KICAgICogVVRGMTYubGFzdEluZGV4T2YoImFiY1x1ZDgwMFx1ZGMwMCIsICJcdWQ4MDAiLCA0KSByZXR1cm5zIC0xPGJyPgogICAgKiA8L3A+CiAgICAqIDxwPnNvdXJjZSBpcyBzZWFyY2hlZCBiYWNrd2FyZHMgc3RhcnRpbmcgYXQgdGhlIGxhc3QgY2hhcmFjdGVyLjwvcD4gCiAgICAqIE5vdGUgdGhpcyBtZXRob2QgaXMgcHJvdmlkZWQgYXMgc3VwcG9ydCB0byBqZGsgMS4zLCB3aGljaCBkb2VzIG5vdCAKICAgICogc3VwcG9ydCBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMgdG8gaXRzIGZ1bGxlc3QuCiAgICAqIEBwYXJhbSBzb3VyY2UgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIHRoYXQgd2lsbCBiZSBzZWFyY2hlZAogICAgKiBAcGFyYW0gc3RyIFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyB0byBzZWFyY2ggZm9yIAogICAgKiBAcGFyYW0gZnJvbUluZGV4IHRoZSBpbmRleCB0byBzdGFydCB0aGUgc2VhcmNoIGZyb20uIFRoZXJlIGlzIG5vIAogICAgKiAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9uIG9uIHRoZSB2YWx1ZSBvZiBmcm9tSW5kZXguIElmIGl0IGlzIAogICAgKiAgICAgICAgICAgICAgICAgIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nLCAKICAgICogICAgICAgICAgICAgICAgICBpdCBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGlmIGl0IHdlcmUgZXF1YWwgdG8gb25lIAogICAgKiAgICAgICAgICAgICAgICAgIGxlc3MgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoaXMgc3RyaW5nOiB0aGlzIGVudGlyZSAKICAgICogICAgICAgICAgICAgICAgICBzdHJpbmcgbWF5IGJlIHNlYXJjaGVkLiBJZiBpdCBpcyBuZWdhdGl2ZSwgaXQgaGFzIAogICAgKiAgICAgICAgICAgICAgICAgIHRoZSBzYW1lIGVmZmVjdCBhcyBpZiBpdCB3ZXJlIC0xOiAtMSBpcyByZXR1cm5lZC4gCiAgICAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0IG9jY3VycmVuY2Ugb2YgdGhlIGNvZGVwb2ludCBpbiBzb3VyY2UsIAogICAgKiAgICAgICAgIG9yIC0xIGlmIHRoZSBjb2RlcG9pbnQgZG9lcyBub3Qgb2NjdXIuCiAgICAqIEBkcmFmdCBzaW5jZSByZWxlYXNlIDIuMQogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgaW50IGxhc3RJbmRleE9mKFN0cmluZyBzb3VyY2UsIFN0cmluZyBzdHIsIGludCBmcm9tSW5kZXgpICAKICAgIHsKICAgICAgICBpbnQgc3RyTGVuZ3RoID0gc3RyLmxlbmd0aCgpOwogICAgICAgIC8vIG5vbi1zdXJyb2dhdGUgZW5kcwogICAgICAgIGlmICghaXNUcmFpbFN1cnJvZ2F0ZShzdHIuY2hhckF0KDApKSAmJiAKICAgICAgICAgICAgIWlzTGVhZFN1cnJvZ2F0ZShzdHIuY2hhckF0KHN0ckxlbmd0aCAtIDEpKSkgewogICAgICAgICAgICByZXR1cm4gc291cmNlLmxhc3RJbmRleE9mKHN0ciwgZnJvbUluZGV4KTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaW50IHJlc3VsdCAgICA9IHNvdXJjZS5sYXN0SW5kZXhPZihzdHIsIGZyb21JbmRleCk7CiAgICAgICAgaWYgKHJlc3VsdCA+PSAwKSB7CiAgICAgICAgICAgIC8vIGNoZWNrIGxhc3QgY2hhcmFjdGVyCiAgICAgICAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoc3RyLmNoYXJBdChzdHJMZW5ndGggLSAxKSkgJiYgCiAgICAgICAgICAgICAgICAocmVzdWx0IDwgc291cmNlLmxlbmd0aCgpIC0gMSkgJiYgCiAgICAgICAgICAgICAgICBpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0ICsgc3RyTGVuZ3RoKSkpIHsgCiAgICAgICAgICAgICAgICByZXR1cm4gbGFzdEluZGV4T2Yoc291cmNlLCBzdHIsIHJlc3VsdCAtIDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGNoZWNrIGZpcnN0IGNoYXJhY3RlciB3aGljaCBpcyBhIHRyYWlsIHN1cnJvZ2F0ZQogICAgICAgICAgICBpZiAoaXNUcmFpbFN1cnJvZ2F0ZShzdHIuY2hhckF0KDApKSAmJiByZXN1bHQgPiAwICYmIAogICAgICAgICAgICAgICAgaXNMZWFkU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQocmVzdWx0IC0gMSkpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbGFzdEluZGV4T2Yoc291cmNlLCBzdHIsIHJlc3VsdCAtIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIC8qKgogICAgKiBSZXR1cm5zIGEgbmV3IFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyByZXN1bHRpbmcgZnJvbSByZXBsYWNpbmcgYWxsIAogICAgKiBvY2N1cnJlbmNlcyBvZiBvbGRDaGFyMzIgaW4gc291cmNlIHdpdGggbmV3Q2hhcjMyLiAKICAgICogSWYgdGhlIGNoYXJhY3RlciBvbGRDaGFyMzIgZG9lcyBub3Qgb2NjdXIgaW4gdGhlIFVURjE2IGZvcm1hdCBVbmljb2RlCiAgICAqIHN0cmluZyBzb3VyY2UsIHRoZW4gc291cmNlIHdpbGwgYmUgcmV0dXJuZWQuIE90aGVyd2lzZSwgYSBuZXcgU3RyaW5nIAogICAgKiBvYmplY3QgaXMgY3JlYXRlZCB0aGF0IHJlcHJlc2VudHMgYSBjb2RlcG9pbnQgc2VxdWVuY2UgaWRlbnRpY2FsIHRvIHRoZSAKICAgICogY29kZXBvaW50IHNlcXVlbmNlIHJlcHJlc2VudGVkIGJ5IHNvdXJjZSwgZXhjZXB0IHRoYXQgZXZlcnkgb2NjdXJyZW5jZSAKICAgICogb2Ygb2xkQ2hhcjMyIGlzIHJlcGxhY2VkIGJ5IGFuIG9jY3VycmVuY2Ugb2YgbmV3Q2hhcjMyLiAKICAgICogPHA+CiAgICAqIEV4YW1wbGVzOiA8YnI+CiAgICAqIFVURjE2LnJlcGxhY2UoIm1lc3F1aXRlIGluIHlvdXIgY2VsbGFyIiwgJ2UnLCAnbycpOzxicj4KICAgICogICAgICAgIHJldHVybnMgIm1vc3F1aXRvIGluIHlvdXIgY29sbGFyIjxicj4KICAgICogVVRGMTYucmVwbGFjZSgiSm9uTCIsICdxJywgJ3gnKTs8YnI+CiAgICAqICAgICAgICByZXR1cm5zICJKb25MIiAobm8gY2hhbmdlKTxicj4KICAgICogVVRGMTYucmVwbGFjZSgiU3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgXHVkODAwXHVkYzAwIiwgMHgxMDAwMCwgJyEnKTsKICAgICogPGJyPiAgIHJldHVybnMgIlN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyICEiPGJyPgogICAgKiBVVEYxNi5yZXBsYWNlKCJTdXBwbGVtZW50YXJ5IGNoYXJhY3RlciBcdWQ4MDBcdWRjMDAiLCAweGQ4MDAsICchJyk7CiAgICAqIDxicj4gICByZXR1cm5zICJTdXBwbGVtZW50YXJ5IGNoYXJhY3RlciBcdWQ4MDBcdWRjMDAiPGJyPgogICAgKiA8L3A+CiAgICAqIE5vdGUgdGhpcyBtZXRob2QgaXMgcHJvdmlkZWQgYXMgc3VwcG9ydCB0byBqZGsgMS4zLCB3aGljaCBkb2VzIG5vdCAKICAgICogc3VwcG9ydCBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcnMgdG8gaXRzIGZ1bGxlc3QuCiAgICAqIEBwYXJhbSBzb3VyY2UgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIHdoaWNoIHRoZSBjb2RlcG9pbnQgCiAgICAqICAgICAgICAgICAgICAgcmVwbGFjZW1lbnRzIHdpbGwgYmUgYmFzZWQgb24uCiAgICAqIEBwYXJhbSBvbGRDaGFyMzIgbm9uLXplcm8gb2xkIGNvZGVwb2ludCB0byBiZSByZXBsYWNlZC4KICAgICogQHBhcmFtIG5ld0NoYXIzMiB0aGUgbmV3IGNvZGVwb2ludCB0byByZXBsYWNlIG9sZENoYXIzMgogICAgKiBAcmV0dXJuIG5ldyBTdHJpbmcgZGVyaXZlZCBmcm9tIHNvdXJjZSBieSByZXBsYWNpbmcgZXZlcnkgb2NjdXJyZW5jZSAKICAgICogICAgICAgICBvZiBvbGRDaGFyMzIgd2l0aCBuZXdDaGFyMzIsIHVubGVzcyB3aGVuIG5vIG9sZENoYXIzMiBpcyBmb3VuZAogICAgKiAgICAgICAgIGluIHNvdXJjZSB0aGVuIHNvdXJjZSB3aWxsIGJlIHJldHVybmVkLgogICAgKiBAZHJhZnQgc2luY2UgcmVsZWFzZSAyLjEKICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyByZXBsYWNlKFN0cmluZyBzb3VyY2UsIGludCBvbGRDaGFyMzIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbmV3Q2hhcjMyKSAgCiAgICB7CiAgICAgICAgaWYgKG9sZENoYXIzMiA8PSAwIHx8IG9sZENoYXIzMiA+IENPREVQT0lOVF9NQVhfVkFMVUUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBcmd1bWVudCBvbGRDaGFyMzIgaXMgbm90IGEgdmFsaWQgY29kZXBvaW50Iik7CiAgICAgICAgfQogICAgICAgIGlmIChuZXdDaGFyMzIgPD0gMCB8fCBuZXdDaGFyMzIgPiBDT0RFUE9JTlRfTUFYX1ZBTFVFKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXJndW1lbnQgbmV3Q2hhcjMyIGlzIG5vdCBhIHZhbGlkIGNvZGVwb2ludCIpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpbnQgaW5kZXggICAgID0gaW5kZXhPZihzb3VyY2UsIG9sZENoYXIzMik7CiAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7CiAgICAgICAgICAgIHJldHVybiBzb3VyY2U7CiAgICAgICAgfQogICAgICAgIFN0cmluZyAgICAgICBuZXdDaGFyMzJTdHIgICAgPSB0b1N0cmluZyhuZXdDaGFyMzIpOwogICAgICAgIGludCAgICAgICAgICBvbGRDaGFyMzJTaXplICAgPSAxOwogICAgICAgIGludCAgICAgICAgICBuZXdDaGFyMzJTaXplICAgPSBuZXdDaGFyMzJTdHIubGVuZ3RoKCk7CiAgICAgICAgU3RyaW5nQnVmZmVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWZmZXIoc291cmNlKTsKICAgICAgICBpbnQgICAgICAgICAgcmVzdWx0SW5kZXggICAgID0gaW5kZXg7CiAgICAgICAgCiAgICAgICAgaWYgKG9sZENoYXIzMiA+PSBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkgewogICAgICAgICAgICBvbGRDaGFyMzJTaXplID0gMjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgd2hpbGUgKGluZGV4ICE9IC0xKSB7CiAgICAgICAgICAgIGludCBlbmRSZXN1bHRJbmRleCAgPSByZXN1bHRJbmRleCArIG9sZENoYXIzMlNpemU7CiAgICAgICAgICAgIHJlc3VsdC5yZXBsYWNlKHJlc3VsdEluZGV4LCBlbmRSZXN1bHRJbmRleCwgbmV3Q2hhcjMyU3RyKTsKICAgICAgICAgICAgaW50IGxhc3RFbmRJbmRleCAgICA9IGluZGV4ICsgb2xkQ2hhcjMyU2l6ZTsKICAgICAgICAgICAgaW5kZXggICAgICAgPSBpbmRleE9mKHNvdXJjZSwgb2xkQ2hhcjMyLCBsYXN0RW5kSW5kZXgpOwogICAgICAgICAgICByZXN1bHRJbmRleCArPSBuZXdDaGFyMzJTaXplICsgaW5kZXggLSBsYXN0RW5kSW5kZXg7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAqIFJldHVybnMgYSBuZXcgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nIHJlc3VsdGluZyBmcm9tIHJlcGxhY2luZyBhbGwgCiAgICAqIG9jY3VycmVuY2VzIG9mIG9sZFN0ciBpbiBzb3VyY2Ugd2l0aCBuZXdTdHIuIAogICAgKiBJZiB0aGUgY2hhcmFjdGVyIG9sZFN0ciBkb2VzIG5vdCBvY2N1ciBpbiB0aGUgVVRGMTYgZm9ybWF0IFVuaWNvZGUKICAgICogc3RyaW5nIHNvdXJjZSwgdGhlbiBzb3VyY2Ugd2lsbCBiZSByZXR1cm5lZC4gT3RoZXJ3aXNlLCBhIG5ldyBTdHJpbmcgCiAgICAqIG9iamVjdCBpcyBjcmVhdGVkIHRoYXQgcmVwcmVzZW50cyBhIGNvZGVwb2ludCBzZXF1ZW5jZSBpZGVudGljYWwgdG8gdGhlIAogICAgKiBjb2RlcG9pbnQgc2VxdWVuY2UgcmVwcmVzZW50ZWQgYnkgc291cmNlLCBleGNlcHQgdGhhdCBldmVyeSBvY2N1cnJlbmNlIAogICAgKiBvZiBvbGRTdHIgaXMgcmVwbGFjZWQgYnkgYW4gb2NjdXJyZW5jZSBvZiBuZXdTdHIuIAogICAgKiA8cD4KICAgICogRXhhbXBsZXM6IDxicj4KICAgICogVVRGMTYucmVwbGFjZSgibWVzcXVpdGUgaW4geW91ciBjZWxsYXIiLCAiZSIsICJvIik7PGJyPgogICAgKiAgICAgICAgcmV0dXJucyAibW9zcXVpdG8gaW4geW91ciBjb2xsYXIiPGJyPgogICAgKiBVVEYxNi5yZXBsYWNlKCJtZXNxdWl0ZSBpbiB5b3VyIGNlbGxhciIsICJtZXNxdWl0ZSIsICJjYXQiKTs8YnI+CiAgICAqICAgICAgICByZXR1cm5zICJjYXQgaW4geW91ciBjb2xsYXIiPGJyPgogICAgKiBVVEYxNi5yZXBsYWNlKCJKb25MIiwgInEiLCAieCIpOzxicj4KICAgICogICAgICAgIHJldHVybnMgIkpvbkwiIChubyBjaGFuZ2UpPGJyPgogICAgKiBVVEYxNi5yZXBsYWNlKCJTdXBwbGVtZW50YXJ5IGNoYXJhY3RlciBcdWQ4MDBcdWRjMDAiLCAiXHVkODAwXHVkYzAwIiwKICAgICogICAgICAgICAgICAgICAnIScpOwogICAgKiA8YnI+ICAgcmV0dXJucyAiU3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgISI8YnI+CiAgICAqIFVURjE2LnJlcGxhY2UoIlN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIFx1ZDgwMFx1ZGMwMCIsICJcdWQ4MDAiLCAnIScpOwogICAgKiA8YnI+ICAgcmV0dXJucyAiU3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgXHVkODAwXHVkYzAwIjxicj4KICAgICogPC9wPgogICAgKiBOb3RlIHRoaXMgbWV0aG9kIGlzIHByb3ZpZGVkIGFzIHN1cHBvcnQgdG8gamRrIDEuMywgd2hpY2ggZG9lcyBub3QgCiAgICAqIHN1cHBvcnQgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIHRvIGl0cyBmdWxsZXN0LgogICAgKiBAcGFyYW0gc291cmNlIFVURjE2IGZvcm1hdCBVbmljb2RlIHN0cmluZyB3aGljaCB0aGUgY29kZXBvaW50IAogICAgKiAgICAgICAgICAgICAgIHJlcGxhY2VtZW50cyB3aWxsIGJlIGJhc2VkIG9uLgogICAgKiBAcGFyYW0gb2xkQ2hhcjMyIG5vbi16ZXJvIG9sZCBjb2RlcG9pbnQgdG8gYmUgcmVwbGFjZWQuCiAgICAqIEBwYXJhbSBuZXdDaGFyMzIgdGhlIG5ldyBjb2RlcG9pbnQgdG8gcmVwbGFjZSBvbGRDaGFyMzIKICAgICogQHJldHVybiBuZXcgU3RyaW5nIGRlcml2ZWQgZnJvbSBzb3VyY2UgYnkgcmVwbGFjaW5nIGV2ZXJ5IG9jY3VycmVuY2UgCiAgICAqICAgICAgICAgb2Ygb2xkQ2hhcjMyIHdpdGggbmV3Q2hhcjMyLCB1bmxlc3Mgd2hlbiBubyBvbGRDaGFyMzIgaXMgZm91bmQKICAgICogICAgICAgICBpbiBzb3VyY2UgdGhlbiBzb3VyY2Ugd2lsbCBiZSByZXR1cm5lZC4KICAgICogQGRyYWZ0IHNpbmNlIHJlbGVhc2UgMi4xCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgcmVwbGFjZShTdHJpbmcgc291cmNlLCBTdHJpbmcgb2xkU3RyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5ld1N0cikgIAogICAgewogICAgICAgIGludCBpbmRleCAgICAgPSBpbmRleE9mKHNvdXJjZSwgb2xkU3RyKTsKICAgICAgICBpZiAoaW5kZXggPT0gLTEpIHsKICAgICAgICAgICAgcmV0dXJuIHNvdXJjZTsKICAgICAgICB9CiAgICAgICAgaW50ICAgICAgICAgIG9sZFN0clNpemUgICA9IG9sZFN0ci5sZW5ndGgoKTsKICAgICAgICBpbnQgICAgICAgICAgbmV3U3RyU2l6ZSAgID0gbmV3U3RyLmxlbmd0aCgpOwogICAgICAgIFN0cmluZ0J1ZmZlciByZXN1bHQgICAgICAgPSBuZXcgU3RyaW5nQnVmZmVyKHNvdXJjZSk7CiAgICAgICAgaW50ICAgICAgICAgIHJlc3VsdEluZGV4ICAgICA9IGluZGV4OwogICAgICAgIAogICAgICAgIHdoaWxlIChpbmRleCAhPSAtMSkgewogICAgICAgICAgICBpbnQgZW5kUmVzdWx0SW5kZXggID0gcmVzdWx0SW5kZXggKyBvbGRTdHJTaXplOwogICAgICAgICAgICByZXN1bHQucmVwbGFjZShyZXN1bHRJbmRleCwgZW5kUmVzdWx0SW5kZXgsIG5ld1N0cik7CiAgICAgICAgICAgIGludCBsYXN0RW5kSW5kZXggICAgPSBpbmRleCArIG9sZFN0clNpemU7CiAgICAgICAgICAgIGluZGV4ICAgICAgID0gaW5kZXhPZihzb3VyY2UsIG9sZFN0ciwgbGFzdEVuZEluZGV4KTsKICAgICAgICAgICAgcmVzdWx0SW5kZXggKz0gbmV3U3RyU2l6ZSArIGluZGV4IC0gbGFzdEVuZEluZGV4OwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CiAgICB9CiAgICAKICAgIC8qKiAKICAgICogUmV2ZXJzZXMgYSBVVEYxNiBmb3JtYXQgVW5pY29kZSBzdHJpbmcgYW5kIHJlcGxhY2VzIHNvdXJjZSdzIGNvbnRlbnQgCiAgICAqIHdpdGggaXQuCiAgICAqIFRoaXMgbWV0aG9kIHdpbGwgcmV2ZXJzZSBzdXJyb2dhdGUgY2hhcmFjdGVycyBjb3JyZWN0bHksIGluc3RlYWQgb2YgCiAgICAqIGJsaW5kbHkgcmV2ZXJzaW5nIGV2ZXJ5IGNoYXJhY3Rlci4KICAgICogPHA+CiAgICAqIEV4YW1wbGVzOjxicj4KICAgICogVVRGMTYucmV2ZXJzZShuZXcgU3RyaW5nQnVmZmVyKAogICAgKiAgICAgICAgICAgICAiU3VwcGxlbWVudGFyeSBjaGFyYWN0ZXJzIFx1ZDgwMFx1ZGMwMFx1ZDgwMVx1ZGMwMSIpKTxicj4KICAgICogcmV0dXJucyAiXHVkODAxXHVkYzAxXHVkODAwXHVkYzAwIHNyZXRjYXJhaGMgeXJhdG5lbWVscHB1UyIuCiAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBTdHJpbmdCdWZmZXIgdGhhdCBjb250YWlucyBVVEYxNiBmb3JtYXQgCiAgICAqICAgICAgICBVbmljb2RlIHN0cmluZyB0byBiZSByZXZlcnNlZAogICAgKiBAcmV0dXJuIGEgbW9kaWZpZWQgc291cmNlIHdpdGggcmV2ZXJzZWQgVVRGMTYgZm9ybWF0IFVuaWNvZGUgc3RyaW5nLgogICAgKiBAZHJhZnQgc2luY2UgcmVsZWFzZSAyLjEKICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZ0J1ZmZlciByZXZlcnNlKFN0cmluZ0J1ZmZlciBzb3VyY2UpICAgICAgCiAgICB7CiAgICAgICAgU3RyaW5nQnVmZmVyIHJlc3VsdCA9IHNvdXJjZS5yZXZlcnNlKCk7CiAgICAgICAgaW50IHJlc3VsdExlbmd0aCAgPSByZXN1bHQubGVuZ3RoKCk7CiAgICAgICAgaW50IG1heExlYWRMZW5ndGggPSByZXN1bHRMZW5ndGggLSAyOwogICAgICAgIGludCBpID0gMDsKICAgICAgICB3aGlsZSAoaSA8IHJlc3VsdExlbmd0aCkgewogICAgICAgICAgICBpZiAoaSA8PSBtYXhMZWFkTGVuZ3RoICYmIGlzVHJhaWxTdXJyb2dhdGUocmVzdWx0LmNoYXJBdChpKSkgJiYKICAgICAgICAgICAgICAgIGlzTGVhZFN1cnJvZ2F0ZShyZXN1bHQuY2hhckF0KGkgKyAxKSkpIHsKICAgICAgICAgICAgICAgIGNoYXIgdHJhaWwgPSByZXN1bHQuY2hhckF0KGkpOwogICAgICAgICAgICAgICAgcmVzdWx0LmRlbGV0ZUNoYXJBdChpKTsKICAgICAgICAgICAgICAgIHJlc3VsdC5pbnNlcnQoaSArIDEsIHRyYWlsKTsKICAgICAgICAgICAgICAgIGkgKz0gMjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGkgKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICAvKioKICAgICogQ29tcGFyZSBzdHJpbmdzIHVzaW5nIFVuaWNvZGUgY29kZSBwb2ludCBvcmRlciwgaW5zdGVhZCBvZiBVVEYtMTYgY29kZSAKICAgICogdW5pdCBvcmRlci4KICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFN0cmluZ0NvbXBhcmF0b3IgaW1wbGVtZW50cyBqYXZhLnV0aWwuQ29tcGFyYXRvciAKICAgIHsKICAgICAgICAvKioKICAgICAgICAqIFN0YW5kYXJkIFN0cmluZyBjb21wYXJlLiBPbmx5IG9uZSBzbWFsbCBzZWN0aW9uIGlzIGRpZmZlcmVudCwgbWFya2VkIGluIAogICAgICAgICogdGhlIGNvZGUuCiAgICAgICAgKi8KICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoT2JqZWN0IGEsIE9iamVjdCBiKSAKICAgICAgICB7CgkgICAgICAgIGlmIChhID09IGIpIHsKCSAgICAgICAgcmV0dXJuIDA7CgkgICAgICAgIH0KICAgICAgICBpZiAoYSA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgaWYgKGIgPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgICAgICAgCiAgICAgICAgU3RyaW5nIHNhID0gKFN0cmluZykgYTsKICAgICAgICBTdHJpbmcgc2IgPSAoU3RyaW5nKSBiOwogICAgICAgIGludCBsZW5hID0gc2EubGVuZ3RoKCk7CiAgICAgICAgaW50IGxlbmIgPSBzYi5sZW5ndGgoKTsKICAgICAgICBpbnQgbGVuID0gbGVuYTsKICAgICAgICBpZiAobGVuID4gbGVuYikgewogICAgICAgICAgICBsZW4gPSBsZW5iOwogICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47ICsraSkgCiAgICAgICAgewogICAgICAgICAgICBjaGFyIGNhID0gc2EuY2hhckF0KGkpOwogICAgICAgICAgICBjaGFyIGNiID0gc2IuY2hhckF0KGkpOwogICAgICAgICAgICBpZiAoY2EgPT0gY2IpIHsKICAgICAgICAgICAgY29udGludWU7IC8vIHNraXAgcmVtYXAgaWYgZXF1YWwKICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAvLyBzdGFydCBvZiBvbmx5IGRpZmZlcmVudCBzZWN0aW9uCiAgICAgICAgICAgIC8vIHdoYXQgdGhpcyBwYXJ0IGRvZXMgaXMgdG8gcmVhcnJhbmdlIHRoZSBjaGFyYWN0ZXJzIDB4RTAwMCB0byAweEZGRkYKICAgICAgICAgICAgLy8gdG8gdGhlIHJlZ2lvbiBzdGFydGluZyBmcm9tIDB4RDgwMAogICAgICAgICAgICAvLyBhbmQgc2hpZnQgdGhlIHN1cnJvZ2F0ZSBjaGFyYWN0ZXJzIHRvIGFib3ZlIHRoaXMgcmVnaW9uCiAgICAgICAgICAgIGlmIChjYSA+PSBMRUFEX1NVUlJPR0FURV9NSU5fVkFMVUUpIHsKICAgICAgICAgICAgY2EgKz0gKGNhIDw9IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUUpID8gMHgyMDAwIDogLTB4ODAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjYiA+PSBMRUFEX1NVUlJPR0FURV9NSU5fVkFMVUUpIHsKICAgICAgICAgICAgY2IgKz0gKGNiIDw9IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUUpID8gMHgyMDAwIDogLTB4ODAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGVuZCBvZiBvbmx5IGRpZmZlcmVudCBzZWN0aW9uCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChjYSA8IGNiKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gMTsgLy8gd2Fzbid0IGVxdWFsLCBzbyByZXR1cm4gMQogICAgICAgIH0KICAgICAgICAgIAogICAgICAgIGlmIChsZW5hIDwgbGVuYikgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICBpZiAobGVuYSA+IGxlbmIpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvLyBwcml2YXRlIGRhdGEgbWVtYmVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAvKioKICAgICogU2hpZnQgdmFsdWUgZm9yIGxlYWQgc3Vycm9nYXRlIHRvIGZvcm0gYSBzdXBwbGVtZW50YXJ5IGNoYXJhY3Rlci4KICAgICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEVBRF9TVVJST0dBVEVfU0hJRlRfID0gMTA7CgkvKioKICAgICogTWFzayB0byByZXRyaWV2ZSB0aGUgc2lnbmlmaWNhbnQgdmFsdWUgZnJvbSBhIHRyYWlsIHN1cnJvZ2F0ZS4KICAgICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFJBSUxfU1VSUk9HQVRFX01BU0tfICAgICA9IDB4M0ZGOyAgIAogICAgLyoqCiAgICAgKiBWYWx1ZSB0aGF0IGFsbCBsZWFkIHN1cnJvZ2F0ZSBzdGFydHMgd2l0aAogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTEVBRF9TVVJST0dBVEVfT0ZGU0VUXyA9IAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFIC0gCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4+IExFQURfU1VSUk9HQVRFX1NISUZUXyk7IAkgICAgICAgICAgICAgICAgICAKICAgIAogICAgLy8gcHJpdmF0ZSBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgCiAgICAvKioKICAgICogPHA+Q29udmVydHMgYXJndW1lbnQgY29kZSBwb2ludCBhbmQgcmV0dXJucyBhIFN0cmluZyBvYmplY3QgcmVwcmVzZW50aW5nIAogICAgKiB0aGUgY29kZSBwb2ludCdzIHZhbHVlIGluIFVURjE2IGZvcm1hdC48L3A+CiAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgbm90IGNoZWNrIGZvciB0aGUgdmFsaWRpdHkgb2YgdGhlIGNvZGVwb2ludCwgdGhlCiAgICAqIHJlc3VsdHMgYXJlIG5vdCBndWFyYW50ZWVkIGlmIGEgaW52YWxpZCBjb2RlcG9pbnQgaXMgcGFzc2VkIGFzIAogICAgKiBhcmd1bWVudC48L3A+CiAgICAqIDxwPlRoZSByZXN1bHQgaXMgYSBzdHJpbmcgd2hvc2UgbGVuZ3RoIGlzIDEgZm9yIG5vbi1zdXBwbGVtZW50YXJ5IGNvZGUgCiAgICAqIHBvaW50cywgMiBvdGhlcndpc2UuPC9wPgogICAgKiBAcGFyYW0gY2ggY29kZSBwb2ludAogICAgKiBAcmV0dXJuIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY29kZSBwb2ludAogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGludCBjaCkKICAgIHsgICAKICAgICAgICBpZiAoY2ggPCBTVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkgewogICAgICAgICAgICByZXR1cm4gU3RyaW5nLnZhbHVlT2YoKGNoYXIpY2gpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBTdHJpbmdCdWZmZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOwogICAgICAgIHJlc3VsdC5hcHBlbmQoZ2V0TGVhZFN1cnJvZ2F0ZShjaCkpOwogICAgICAgIHJlc3VsdC5hcHBlbmQoZ2V0VHJhaWxTdXJyb2dhdGUoY2gpKTsKICAgICAgICByZXR1cm4gcmVzdWx0LnRvU3RyaW5nKCk7CiAgICB9Cn0K