LyoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwMSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgICAgKgoqIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKgoqICRTb3VyY2U6IC94c3JsL05zdm4vaWN1L2ljdTRqL3NyYy9jb20vaWJtL3RleHQvQXR0aWMvVVRGMTYuamF2YSx2ICQgCiogJERhdGU6IDIwMDEvMDMvMjMgMTk6NTE6MzggJCAKKiAkUmV2aXNpb246IDEuMyAkCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKcGFja2FnZSBjb20uaWJtLnRleHQ7CgppbXBvcnQgY29tLmlibS50ZXh0LlVDaGFyYWN0ZXI7CgovKioKKiBTdGFuZGFsb25lIHV0aWxpdHkgY2xhc3MgcHJvdmlkaW5nIFVURjE2IGNoYXJhY3RlciBjb252ZXJzaW9ucyBhbmQgaW5kZXhpbmcgCiogY29udmVyc2lvbnMuCiogPHA+Q29kZSB0aGF0IHVzZXMgc3RyaW5ncyBhbG9uZSByYXJlbHkgbmVlZCBtb2RpZmljYXRpb24uIAoqIEJ5IGRlc2lnbiwgVVRGLTE2IGRvZXMgbm90IGFsbG93IG92ZXJsYXAsIHNvIHNlYXJjaGluZyBmb3Igc3RyaW5ncyBpcyBhIHNhZmUgCiogb3BlcmF0aW9uLiBTaW1pbGFybHksIGNvbmNhdGVuYXRpb24gaXMgYWx3YXlzIHNhZmUuIFN1YnN0cmluZ2luZyBpcyBzYWZlIGlmIAoqIHRoZSBzdGFydCBhbmQgZW5kIGFyZSBib3RoIG9uIFVURi0zMiBib3VuZGFyaWVzLiBJbiBub3JtYWwgY29kZSwgdGhlIHZhbHVlcyAKKiBmb3Igc3RhcnQgYW5kIGVuZCBhcmUgb24gdGhvc2UgYm91bmRhcmllcywgc2luY2UgdGhleSBhcm9zZSBmcm9tIG9wZXJhdGlvbnMgCiogbGlrZSBzZWFyY2hpbmcuIElmIG5vdCwgdGhlIG5lYXJlc3QgVVRGLTMyIGJvdW5kYXJpZXMgY2FuIGJlIGRldGVybWluZWQgCiogdXNpbmcgPGNvZGU+Ym91bmRzKCk8L2NvZGU+LgoqIDxzdHJvbmc+RXhhbXBsZXM6PC9zdHJvbmc+CiogPHA+VGhlIGZvbGxvd2luZyBleGFtcGxlcyBpbGx1c3RyYXRlIHVzZSBvZiBzb21lIG9mIHRoZXNlIG1ldGhvZHMuIAoqIDxwcmU+CiogLy8gaXRlcmF0aW9uIGZvcndhcmRzOiBPcmlnaW5hbAoqIGZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgKytpKSB7CiqgoKBjaGFyIGNoID0gcy5jaGFyQXQoaSk7CiqgoKBkb1NvbWV0aGluZ1dpdGgoY2gpOwoqIH0KKgoqIC8vIGl0ZXJhdGlvbiBmb3J3YXJkczogQ2hhbmdlcyBmb3IgVVRGLTMyCiogaW50IGNoOwoqIGZvciAoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgaSs9VVRGMTYuZ2V0Q2hhckNvdW50KGNoKSkgewoqoKCgY2ggPSBVVEYxNi5jaGFyQXQocyxpKTsKKqCgoGRvU29tZXRoaW5nV2l0aChjaCk7CiogfQoqCiogLy8gaXRlcmF0aW9uIGJhY2t3YXJkczogT3JpZ2luYWwKKiBmb3IgKGludCBpID0gcy5sZW5ndGgoKS0xOyBpID49IDA7IC0taSkgewoqoKCgY2hhciBjaCA9IHMuY2hhckF0KGkpOwoqoKCgZG9Tb21ldGhpbmdXaXRoKGNoKTsKKiB9CiogIAoqIC8vIGl0ZXJhdGlvbiBiYWNrd2FyZHM6IENoYW5nZXMgZm9yIFVURi0zMgoqIGludCBjaDsKKiBmb3IgKGludCBpID0gcy5sZW5ndGgoKS0xOyBpID4gMDsgaS09VVRGMTYuZ2V0Q2hhckNvdW50KGNoKSkgewoqoKCgY2ggPSBVVEYxNi5jaGFyQXQocyxpKTsKKqCgoGRvU29tZXRoaW5nV2l0aChjaCk7CiogfQoqIDwvcHJlPgoqIDxzdHJvbmc+Tm90ZXM6PC9zdHJvbmc+CiogPHVsPgoqICAgPGxpPgoqICAgPHN0cm9uZz5OYW1pbmc6PC9zdHJvbmc+IEZvciBjbGFyaXR5LCBIaWdoIGFuZCBMb3cgc3Vycm9nYXRlcyBhcmUgY2FsbGVkIAoqICAgPGNvZGU+TGVhZDwvY29kZT4gYW5kIDxjb2RlPlRyYWlsPC9jb2RlPiBpbiB0aGUgQVBJLCB3aGljaCBnaXZlcyBhIGJldHRlciAKKiAgIHNlbnNlIG9mIHRoZWlyIG9yZGVyaW5nIGluIGEgc3RyaW5nLiA8Y29kZT5vZmZzZXQxNjwvY29kZT4gYW5kIAoqICAgPGNvZGU+b2Zmc2V0MzI8L2NvZGU+IGFyZSB1c2VkIHRvIGRpc3Rpbmd1aXNoIG9mZnNldHMgdG8gVVRGLTE2IAoqICAgYm91bmRhcmllcyB2cyBvZmZzZXRzIHRvIFVURi0zMiBib3VuZGFyaWVzLiA8Y29kZT5pbnQgY2hhcjMyPC9jb2RlPiBpcyAKKiAgIHVzZWQgdG8gY29udGFpbiBVVEYtMzIgY2hhcmFjdGVycywgYXMgb3Bwb3NlZCB0byA8Y29kZT5jaGFyMTY8L2NvZGU+LCAKKiAgIHdoaWNoIGlzIGEgVVRGLTE2IGNvZGUgdW5pdC4KKiAgIDwvbGk+CiogICA8bGk+CiogICA8c3Ryb25nPlJvdW5kdHJpcHBpbmcgT2Zmc2V0czo8L3N0cm9uZz4gWW91IGNhbiBhbHdheXMgcm91bmR0cmlwIGZyb20gYSAKKiAgIFVURi0zMiBvZmZzZXQgdG8gYSBVVEYtMTYgb2Zmc2V0IGFuZCBiYWNrLiBCZWNhdXNlIG9mIHRoZSBkaWZmZXJlbmNlIGluIAoqICAgc3RydWN0dXJlLCB5b3UgY2FuIHJvdW5kdHJpcCBmcm9tIGEgVVRGLTE2IG9mZnNldCB0byBhIFVURi0zMiBvZmZzZXQgYW5kIAoqICAgYmFjayBpZiBhbmQgb25seSBpZiA8Y29kZT5ib3VuZHMoc3RyaW5nLCBvZmZzZXQxNikgIT0gVFJBSUw8L2NvZGU+LgoqICAgPC9saT4KKiAgIDxsaT4KKiAgIDxzdHJvbmc+RXhjZXB0aW9uczo8L3N0cm9uZz4gVGhlIGVycm9yIGNoZWNraW5nIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIAoqICAgaWYgaW5kaWNlcyBhcmUgb3V0IG9mIGJvdW5kcy4gT3RoZXIgdGhhbiB0aGFuIHRoYXQsIGFsbCBtZXRob2RzIHdpbGwgCiogICBiZWhhdmUgcmVhc29uYWJseSwgZXZlbiBpZiB1bm1hdGNoZWQgc3Vycm9nYXRlcyBvciBvdXQtb2YtYm91bmRzIFVURi0zMiAKKiAgIHZhbHVlcyBhcmUgcHJlc2VudC4gPGNvZGU+VUNoYXJhY3Rlci5pc0xlZ2FsKCk8L2NvZGU+IGNhbiBiZSB1c2VkIHRvIGNoZWNrIAoqICAgZm9yIHZhbGlkaXR5IGlmIGRlc2lyZWQuCiogICA8L2xpPgoqICAgPGxpPgoqICAgPHN0cm9uZz5Vbm1hdGNoZWQgU3Vycm9nYXRlczo8L3N0cm9uZz4gSWYgdGhlIHN0cmluZyBjb250YWlucyB1bm1hdGNoZWQgCiogICBzdXJyb2dhdGVzLCB0aGVuIHRoZXNlIGFyZSBjb3VudGVkIGFzIG9uZSBVVEYtMzIgdmFsdWUuIFRoaXMgbWF0Y2hlcyAKKiAgIHRoZWlyIGl0ZXJhdGlvbiBiZWhhdmlvciwgd2hpY2ggaXMgdml0YWwuIEl0IGFsc28gbWF0Y2hlcyBjb21tb24gZGlzcGxheSAKKiAgIHByYWN0aWNlIGFzIG1pc3NpbmcgZ2x5cGhzIChzZWUgdGhlIFVuaWNvZGUgU3RhbmRhcmQgU2VjdGlvbiA1LjQsIDUuNSkuCiogICA8L2xpPgoqICAgPGxpPgoqICAgICA8c3Ryb25nPk9wdGltaXphdGlvbjo8L3N0cm9uZz4gVGhlIG1ldGhvZCBpbXBsZW1lbnRhdGlvbnMgbWF5IG5lZWQgCiogICAgIG9wdGltaXphdGlvbiBpZiB0aGUgY29tcGlsZXIgZG9lc24ndCBmb2xkIHN0YXRpYyBmaW5hbCBtZXRob2RzLiBTaW5jZSAKKiAgICAgc3Vycm9nYXRlIHBhaXJzIHdpbGwgZm9ybSBhbiBleGNlZWRpbmcgc21hbGwgcGVyY2VudGFnZSBvZiBhbGwgdGhlIHRleHQgCiogICAgIGluIHRoZSB3b3JsZCwgdGhlIHNpbmdsZXRvbiBjYXNlIHNob3VsZCBhbHdheXMgYmUgb3B0aW1pemVkIGZvci4KKiAgIDwvbGk+CiogPC91bD4KKiBAYXV0aG9yIE1hcmsgRGF2aXMsIHdpdGggaGVscCBmcm9tIE1hcmt1cyBTY2hlcmVyCiogQHNpbmNlIE5vdjI0MDAKKi8KCnB1YmxpYyBmaW5hbCBjbGFzcyBVVEYxNgp7CiAgLy8gcHVibGljIHZhcmlhYmxlcyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAKICAvKioKICAqIFZhbHVlIHJldHVybmVkIGluIDxjb2RlPjxhIGhyZWY9IiNib3VuZHMoamF2YS5sYW5nLlN0cmluZywgaW50KSI+CiAgKiBib3VuZHMoKTwvYT48L2NvZGU+LgogICogVGhlc2UgdmFsdWVzIGFyZSBjaG9zZW4gc3BlY2lmaWNhbGx5IHNvIHRoYXQgaXQgYWN0dWFsbHkgcmVwcmVzZW50cyB0aGUgCiAgKiBwb3NpdGlvbiBvZiB0aGUgY2hhcmFjdGVyIAogICogW29mZnNldDE2IC0gKHZhbHVlID4+IDIpLCBvZmZzZXQxNiArICh2YWx1ZSAmIDMpXQogICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lOR0xFX0NIQVJfQk9VTkRBUlkgPSAxLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBMRUFEX1NVUlJPR0FURV9CT1VOREFSWSA9IDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWSA9IDU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgLy8gcHJpdmF0ZSB2YXJpYWJsZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCQogIC8qKiAKCSogTGVhZCBzdXJyb2dhdGVzIHZhbHVlcyBmcm9tIExFQURfU1VSUk9HQVRFX01JTl9WQUxVRV8gdG8gTEVBRF9TVVJST0dBVEVfTUFYX1ZBTFVFXwoJKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBMRUFEX1NVUlJPR0FURV9NSU5fVkFMVUVfID0gMHhEODAwOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExFQURfU1VSUk9HQVRFX01BWF9WQUxVRV8gPSAweERCRkY7CgkKCS8qKgoJKiBTdXJyb2dhdGUgbGVhZCBvZmZzZXQsIHRvIGJlIHVzZWQgd2hlbiBicmVha2luZyB1cCBVVEYzMiBpbnRvIHN1cnJvZ2F0ZQoJKiBwYWlyCgkqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExFQURfU1VSUk9HQVRFX09GRlNFVF8gPSBMRUFEX1NVUlJPR0FURV9NSU5fVkFMVUVfIC0gCgkgICAgKFVDaGFyYWN0ZXIuU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUgPj4gVUNoYXJhY3Rlci5MRUFEX1NVUlJPR0FURV9TSElGVF8pOwoJCgkvKiogCgkqIFRyYWlsIHN1cnJvZ2F0ZXMgdmFsdWVzIGZyb20gVFJBSUxfU1VSUk9HQVRFX01JTl9WQUxVRV8gdG8gCgkqIFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUVfCgkqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRSQUlMX1NVUlJPR0FURV9NSU5fVkFMVUVfID0gMHhEQzAwOyAKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUUkFJTF9TVVJST0dBVEVfTUFYX1ZBTFVFXyA9IDB4REZGRjsKICAgICAgICAgICAgICAgICAgICAgICAgICAKICAvLyBjb25zdHJ1Y3RvciA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogIAogIC8qKgogICogUHJldmVudCBpbnN0YW5jZSBmcm9tIGJlaW5nIGNyZWF0ZWQuCiAgKi8KICBwcml2YXRlIFVURjE2KCkgCiAgewogIH0KCiAgLy8gcHVibGljIG1ldGhvZCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAKICAvKioKICAqIEV4dHJhY3QgYSBzaW5nbGUgVVRGLTMyIHZhbHVlIGZyb20gYSBzdHJpbmcuCiAgKiBVc2VkIHdoZW4gaXRlcmF0aW5nIGZvcndhcmRzIG9yIGJhY2t3YXJkcyAod2l0aCAKICAqIDxjb2RlPlVURjE2LmdldENoYXJDb3VudCgpPC9jb2RlPiwgYXMgd2VsbCBhcyByYW5kb20gYWNjZXNzLiBJZiBhIHZhbGlkaXR5IAogICogY2hlY2sgaXMgcmVxdWlyZWQsIHVzZSA8Y29kZT48YSBocmVmPSIuLi9VQ2hhcmFjdGVyLmh0bWwjaXNMZWdhbChjaGFyKSI+CiAgKiBVQ2hhcmFjdGVyLmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIHRoZSByZXR1cm4gdmFsdWUuCiAgKiBJZiB0aGUgY2hhciByZXRyaWV2ZWQgaXMgcGFydCBvZiBhIHN1cnJvZ2F0ZSBwYWlyLCBpdHMgc3VwcGxlbWVudGFyeSAKICAqIGNoYXJhY3RlciB3aWxsIGJlIHJldHVybmVkLiBJZiBhIGNvbXBsZXRlIHN1cHBsZW1lbnRhcnkgY2hhcmFjdGVyIGlzIG5vdAogICogZm91bmQgdGhlIGluY29tcGxldGUgY2hhcmFjdGVyIHdpbGwgYmUgcmV0dXJuZWQKICAqIEBwYXJhbSBzb3VyY2UgYXJyYXkgb2YgVVRGLTE2IGNoYXJzCiAgKiBAcGFyYW0gb2Zmc2V0MTYgVVRGLTE2IG9mZnNldCB0byB0aGUgc3RhcnQgb2YgdGhlIGNoYXJhY3Rlci4KICAqIEByZXR1cm4gVVRGLTMyIHZhbHVlIGZvciB0aGUgVVRGLTMyIHZhbHVlIHRoYXQgY29udGFpbnMgdGhlIGNoYXIgYXQgCiAgKiAgICAgICAgIG9mZnNldDE2LCBvdGhlcndpc2UgLTEgaWYgdGhlcmUncyBhbiBlcnJvci4KICAqICAgICAgICAgVGhlIGJvdW5kYXJpZXMgb2YgdGhhdCBjb2RlcG9pbnQgYXJlIHRoZSBzYW1lIGFzIGluIAogICogICAgICAgICA8Y29kZT5ib3VuZHMzMigpPC9jb2RlPi4gCiAgKi8KICBwdWJsaWMgc3RhdGljIGludCBjaGFyQXQoU3RyaW5nIHNvdXJjZSwgaW50IG9mZnNldDE2KSAKICB7CiAgICBpZiAob2Zmc2V0MTYgPCAwIHx8IG9mZnNldDE2ID49IHNvdXJjZS5sZW5ndGgoKSkKICAgICAgcmV0dXJuIC0xOwogICAgICAKICAgIGNoYXIgc2luZ2xlID0gc291cmNlLmNoYXJBdChvZmZzZXQxNik7CiAgICBpZiAoIWlzU3Vycm9nYXRlKHNpbmdsZSkpIAogICAgICByZXR1cm4gc2luZ2xlOwoKICAgIC8vIENvbnZlcnQgdGhlIFVURi0xNiBzdXJyb2dhdGUgcGFpciBpZiBuZWNlc3NhcnkuCiAgICAvLyBGb3Igc2ltcGxpY2l0eSBpbiB1c2FnZSwgYW5kIGJlY2F1c2UgdGhlIGZyZXF1ZW5jeSBvZiBwYWlycyBpcyBsb3csCiAgICAvLyBsb29rIGJvdGggZGlyZWN0aW9ucy4KICAgICAgICAgICAgCgkgIGlmIChpc0xlYWRTdXJyb2dhdGUoc2luZ2xlKSkgCgkgIHsKCSAgICArKyBvZmZzZXQxNjsKCSAgICBpZiAoc291cmNlLmxlbmd0aCgpICE9IG9mZnNldDE2KQoJICAgIHsKCSAgICAgIGNoYXIgdHJhaWwgPSBzb3VyY2UuY2hhckF0KG9mZnNldDE2KTsKCSAgICAgIGlmIChpc1RyYWlsU3Vycm9nYXRlKHRyYWlsKSkKCSAgICAgICAgcmV0dXJuIFVDaGFyYWN0ZXIuZ2V0UmF3U3VwcGxlbWVudGFyeShzaW5nbGUsIHRyYWlsKTsKCSAgICB9CgkgIH0gCgkgIGVsc2UgCgkgIHsgCgkgICAgLS0gb2Zmc2V0MTY7CgkgICAgaWYgKG9mZnNldDE2ID49IDApCgkgICAgewoJICAgICAgLy8gc2luZ2xlIGlzIGEgdHJhaWwgc3Vycm9nYXRlIHNvCgkgICAgICBjaGFyIGxlYWQgPSBzb3VyY2UuY2hhckF0KG9mZnNldDE2KTsKCSAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUobGVhZCkpCgkgICAgICAgIHJldHVybiBVQ2hhcmFjdGVyLmdldFJhd1N1cHBsZW1lbnRhcnkobGVhZCwgc2luZ2xlKTsKCSAgICB9CgkgIH0gCgkgIHJldHVybiBzaW5nbGU7IC8vIHJldHVybiB1bm1hdGNoZWQgc3Vycm9nYXRlCiAgfQogIAogIC8qKgogICogRXh0cmFjdCBhIHNpbmdsZSBVVEYtMzIgdmFsdWUgZnJvbSBhIHN0cmluZy4KICAqIElmIGEgdmFsaWRpdHkgY2hlY2sgaXMgcmVxdWlyZWQsIHVzZSAKICAqIDxjb2RlPjxhIGhyZWY9Ii4uL1VDaGFyYWN0ZXIuaHRtbCNpc0xlZ2FsKGNoYXIpIj4KICAqIFVDaGFyYWN0ZXIuaXNMZWdhbCgpPC9hPjwvY29kZT4gb24gdGhlIHJldHVybiB2YWx1ZS4KICAqIElmIHRiZSBjaGFyIHJldHJpZXZlZCBpcyBwYXJ0IG9mIGEgc3Vycm9nYXRlIHBhaXIsIGl0cyBzdXBwbGVtZW50YXJ5IAogICogY2hhcmFjdGVyIHdpbGwgYmUgcmV0dXJuZWQuIElmIGEgY29tcGxldGUgc3VwcGxlbWVudGFyeSBjaGFyYWN0ZXIgaXMgbm90CiAgKiBmb3VuZCB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXIgd2lsbCBiZSByZXR1cm5lZAogICogQHJldHVybiBVVEYtMzIgdmFsdWUgZm9yIHRoZSBVVEYtMzIgdmFsdWUgdGhhdCBjb250YWlucyB0aGUgY2hhciBhdCAKICAqICAgICAgICAgb2Zmc2V0MTYuIFRoZSBib3VuZGFyaWVzIG9mIHRoYXQgY29kZXBvaW50IGFyZSB0aGUgc2FtZSBhcyBpbiAKICAqICAgICAgICAgPGNvZGU+Ym91bmRzMzIoKTwvY29kZT4uIAogICogQHBhcmFtIHNvdXJjZSBhcnJheSBvZiBVVEYtMTYgY2hhcnMKICAqIEBwYXJhbSBvZmZzZXQzMiBVVEYtMzIgb2Zmc2V0IHRvIHRoZSBzdGFydCBvZiB0aGUgY2hhcmFjdGVyLgogICogQHJldHVybiBhIHNpbmdsZSBVVEYzMiB2YWx1ZSwgb3RoZXJ3aXNlIC0xIGlmIHRoZXJlJ3MgYW4gZXJyb3IKICAqLwogIHB1YmxpYyBzdGF0aWMgaW50IGNoYXJBdENvZGVQb2ludE9mZnNldChTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0MzIpIAogIHsKICAgIGludCBvZmZzZXQxNiA9IGZpbmRPZmZzZXRGcm9tQ29kZVBvaW50KHNvdXJjZSwgb2Zmc2V0MzIpOwogICAgcmV0dXJuIGNoYXJBdChzb3VyY2UsIG9mZnNldDE2KTsKICB9CiAgCiAgLyoqCiAgKiBEZXRlcm1pbmVzIGhvdyBtYW55IGNoYXJzIHRoaXMgY2hhcjMyIHJlcXVpcmVzLgogICogSWYgYSB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIDxjb2RlPgogICogPGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIAogICogY2hhcjMyIGJlZm9yZSBjYWxsaW5nLgogICogQHBhcmFtIGNoIHRoZSBpbnB1dCBjaGFyYWN0ZXIuCiAgKiBAcmV0dXJuIDIgaWYgaXMgaW4gc3Vycm9nYXRlIHNwYWNlLCBvdGhlcndpc2UgMS4gCiAgKi8KICBwdWJsaWMgc3RhdGljIGludCBnZXRDaGFyQ291bnQoaW50IGNoYXIzMikgCiAgewogICAgaWYgKGNoYXIzMiA8IFVDaGFyYWN0ZXIuU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUpIHsKICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMjsKICB9CiAgCiAgLyoqCiAgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIHRoZSBib3VuZGFyaWVzIGFyb3VuZCB0aGUgY2hhciBhdCBvZmZzZXQxNi4KICAqIFVzZWQgZm9yIHJhbmRvbSBhY2Nlc3MuCiAgKiBAcGFyYW0gc291cmNlIHRleHQgdG8gYW5hbHlzZQogICogQHBhcmFtIG9mZnNldDE2IFVURi0xNiBvZmZzZXQKICAqIEByZXR1cm4gPHVsPgogICogICAgICAgICAgIDxsaT4gU0lOR0xFX0NIQVJfQk9VTkRBUlkgOiBhIHNpbmdsZSBjaGFyOyB0aGUgYm91bmRzIGFyZSAKICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29mZnNldDE2LCBvZmZzZXQxNisxXQogICogICAgICAgICAgIDxsaT4gTEVBRF9TVVJST0dBVEVfQk9VTkRBUlkgOiBhIHN1cnJvZ2F0ZSBwYWlyIHN0YXJ0aW5nIGF0IAogICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQxNjsgCiAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBib3VuZHMgYXJlIAogICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb2Zmc2V0MTYsIG9mZnNldDE2ICsgMl0KICAqICAgICAgICAgICA8bGk+IFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWSA6IGEgc3Vycm9nYXRlIHBhaXIgc3RhcnRpbmcgYXQgCiAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQxNiAtIDE7IHRoZSBib3VuZHMgYXJlIAogICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29mZnNldDE2IC0gMSwgb2Zmc2V0MTYgKyAxXQogICogICAgICAgICA8L3VsPgogICogICAgICAgICBGb3IgYml0LXR3aWRkbGVycywgdGhlIHJldHVybiB2YWx1ZXMgZm9yIHRoZXNlIGFyZSBjaG9zZW4gc28gdGhhdCAKICAqICAgICAgICAgdGhlIGJvdW5kYXJpZXMgY2FuIGJlIGdvdHRlbiBieToKICAqICAgICAgICAgW29mZnNldDE2IC0gKHZhbHVlID4+IDIpLCBvZmZzZXQxNiArICh2YWx1ZSAmIDMpXS4KICAqIEBleGNlcHRpb24gU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBvZmZzZXQxNiBpcyBvdXQgb2YgYm91bmRzLgogICovCiAgcHVibGljIHN0YXRpYyBpbnQgYm91bmRzKFN0cmluZyBzb3VyY2UsIGludCBvZmZzZXQxNikgCiAgewogICAgY2hhciBjaCA9IHNvdXJjZS5jaGFyQXQob2Zmc2V0MTYpOwogICAgaWYgKGlzU3Vycm9nYXRlKGNoKSkKICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShjaCkpIAogICAgICB7CiAgICAgICBpZiAoKysgb2Zmc2V0MTYgPCBzb3VyY2UubGVuZ3RoKCkgJiYgCiAgICAgICAgICAgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KG9mZnNldDE2KSkpIHsKICAgICAgICAgcmV0dXJuIExFQURfU1VSUk9HQVRFX0JPVU5EQVJZOwogICAgICAgfQogICAgICB9IAogICAgICBlbHNlIAogICAgICAgIC8vIGlzVHJhaWxTdXJyb2dhdGUoY2gpLCBzbwogICAgICAgIGlmICgtLSBvZmZzZXQxNiA+PSAwICYmIGlzTGVhZFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KG9mZnNldDE2KSkpIHsKICAgICAgICAgIHJldHVybiBUUkFJTF9TVVJST0dBVEVfQk9VTkRBUlk7CiAgICAgICAgfQogICAgICAgICAgCiAgICByZXR1cm4gU0lOR0xFX0NIQVJfQk9VTkRBUlk7CiAgfQogIAogIC8qKgogICogUmV0dXJucyB0aGUgdHlwZSBvZiB0aGUgYm91bmRhcmllcyBhcm91bmQgdGhlIGNoYXIgYXQgb2Zmc2V0MzIuCiAgKiBVc2VkIGZvciByYW5kb20gYWNjZXNzLgogICogQHBhcmFtIHNvdXJjZSB0ZXh0IHRvIGFuYWx5c2UKICAqIEBwYXJhbSBvZmZzZXQzMiBVVEYtMzIgb2Zmc2V0CiAgKiBAcmV0dXJuIDx1bD4KICAqICAgICAgICAgICA8bGk+IFNJTkdMRV9DSEFSX0JPVU5EQVJZIDogYSBzaW5nbGUgY2hhcjsgdGhlIGJvdW5kcyBhcmUgCiAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvZmZzZXQzMiwgb2Zmc2V0MzIgKyAxXQogICogICAgICAgICAgIDxsaT4gTEVBRF9TVVJST0dBVEVfQk9VTkRBUlkgOiBhIHN1cnJvZ2F0ZSBwYWlyIHN0YXJ0aW5nIGF0IAogICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQzMjsgCiAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBib3VuZHMgYXJlIAogICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb2Zmc2V0MzIsIG9mZnNldDMyICsgMl0KICAqICAgICAgICAgICA8bGk+IFRSQUlMX1NVUlJPR0FURV9CT1VOREFSWSA6IGEgc3Vycm9nYXRlIHBhaXIgc3RhcnRpbmcgYXQgCiAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQzMiAtIDE7IHRoZSBib3VuZHMgYXJlIAogICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29mZnNldDMyIC0gMSwgb2Zmc2V0MzIgKyAxXQogICogICAgICAgICA8L3VsPgogICogICAgICAgICBGb3IgYml0LXR3aWRkbGVycywgdGhlIHJldHVybiB2YWx1ZXMgZm9yIHRoZXNlIGFyZSBjaG9zZW4gc28gdGhhdCAKICAqICAgICAgICAgdGhlIGJvdW5kYXJpZXMgY2FuIGJlIGdvdHRlbiBieToKICAqICAgICAgICAgW29mZnNldDMyIC0gKHZhbHVlID4+IDIpLCBvZmZzZXQzMiArICh2YWx1ZSAmIDMpXS4KICAqIEBleGNlcHRpb24gU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBvZmZzZXQzMiBpcyBvdXQgb2YgYm91bmRzLgogICovCiAgcHVibGljIHN0YXRpYyBpbnQgYm91bmRzQXRDb2RlUG9pbnRPZmZzZXQoU3RyaW5nIHNvdXJjZSwgaW50IG9mZnNldDMyKSAKICB7CiAgICBpbnQgb2Zmc2V0MTYgPSBmaW5kT2Zmc2V0RnJvbUNvZGVQb2ludChzb3VyY2UsIG9mZnNldDMyKTsKICAgIHJldHVybiBib3VuZHMoc291cmNlLCBvZmZzZXQxNik7CiAgfQoKICAvKioKICAqIERldGVybWluZXMgd2hldGhlciB0aGUgPGI+Y29kZSB2YWx1ZSBpcyBhIHN1cnJvZ2F0ZS4KICAqIEBwYXJhbSBjaCB0aGUgaW5wdXQgY2hhcmFjdGVyLgogICogQHJldHVybiB0cnVlIGlmZiB0aGUgaW5wdXQgY2hhcmFjdGVyIGlzIGEgc3Vycm9nYXRlLgogICovCiAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU3Vycm9nYXRlKGNoYXIgY2hhcjE2KSAKICB7CiAgICByZXR1cm4gTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFXyA8PSBjaGFyMTYgJiYgCiAgICAgICAgICAgY2hhcjE2IDw9IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUVfOwogIH0KICAgIAogIC8qKgogICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBjaGFyYWN0ZXIgaXMgYSB0cmFpbCBzdXJyb2dhdGUuCiAgKiBAcGFyYW0gY2hhcjE2IHRoZSBpbnB1dCBjaGFyYWN0ZXIuCiAgKiBAcmV0dXJuIHRydWUgaWZmIHRoZSBpbnB1dCBjaGFyYWN0ZXIgaXMgYSB0cmFpbCBzdXJyb2dhdGUuCiAgKi8KICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNUcmFpbFN1cnJvZ2F0ZShjaGFyIGNoYXIxNikgCiAgewogICAgcmV0dXJuIChUUkFJTF9TVVJST0dBVEVfTUlOX1ZBTFVFXyA8PSBjaGFyMTYgJiYgCiAgICAgICAgICAgIGNoYXIxNiA8PSBUUkFJTF9TVVJST0dBVEVfTUFYX1ZBTFVFXyk7CiAgfQogICAgCiAgLyoqCiAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGNoYXJhY3RlciBpcyBhIGxlYWQgc3Vycm9nYXRlLgogICogQHBhcmFtIGNoYXIxNiB0aGUgaW5wdXQgY2hhcmFjdGVyLgogICogQHJldHVybiB0cnVlIGlmZiB0aGUgaW5wdXQgY2hhcmFjdGVyIGlzIGEgbGVhZCBzdXJyb2dhdGUKICAqLwogIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0xlYWRTdXJyb2dhdGUoY2hhciBjaGFyMTYpIAogIHsKICAgIHJldHVybiBMRUFEX1NVUlJPR0FURV9NSU5fVkFMVUVfIDw9IGNoYXIxNiAmJiAKICAgICAgICAgICBjaGFyMTYgPD0gTEVBRF9TVVJST0dBVEVfTUFYX1ZBTFVFXzsKICB9CiAgICAgICAgCiAgLyoqCiAgKiBSZXR1cm5zIHRoZSBsZWFkIHN1cnJvZ2F0ZS4KICAqIElmIGEgdmFsaWRpdHkgY2hlY2sgaXMgcmVxdWlyZWQsIHVzZSAKICAqIDxjb2RlPjxhIGhyZWY9Ii4uL1VDaGFyYWN0ZXIuaHRtbCNpc0xlZ2FsKGNoYXIpIj5pc0xlZ2FsKCk8L2E+PC9jb2RlPiBvbiAKICAqIGNoYXIzMiBiZWZvcmUgY2FsbGluZy4KICAqIEBwYXJhbSBjaGFyMzIgdGhlIGlucHV0IGNoYXJhY3Rlci4KICAqIEByZXR1cm4gbGVhZCBzdXJyb2dhdGUgaWYgdGhlIGdldENoYXJDb3VudChjaCkgaXMgMjsgPGJyPgogICogICAgICAgICBhbmQgMCBvdGhlcndpc2UgKG5vdGU6IDAgaXMgbm90IGEgdmFsaWQgbGVhZCBzdXJyb2dhdGUpLgogICovCiAgcHVibGljIHN0YXRpYyBpbnQgZ2V0TGVhZFN1cnJvZ2F0ZShpbnQgY2hhcjMyKSAKICB7CiAgICBpZiAoY2hhcjMyID49IFVDaGFyYWN0ZXIuU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUpIHsKICAgICAgcmV0dXJuIExFQURfU1VSUk9HQVRFX09GRlNFVF8gKyAKICAgICAgICAgICAgIChjaGFyMzIgPj4gVUNoYXJhY3Rlci5MRUFEX1NVUlJPR0FURV9TSElGVF8pOwogICAgfQogICAgICAgIAogICAgcmV0dXJuIDA7CiAgfQogICAgCiAgLyoqCiAgKiBSZXR1cm5zIHRoZSB0cmFpbCBzdXJyb2dhdGUuCiAgKiBJZiBhIHZhbGlkaXR5IGNoZWNrIGlzIHJlcXVpcmVkLCB1c2UgCiAgKiA8Y29kZT48YSBocmVmPSIuLi9VQ2hhcmFjdGVyLmh0bWwjaXNMZWdhbChjaGFyKSI+aXNMZWdhbCgpPC9hPjwvY29kZT4gb24gCiAgKiBjaGFyMzIgYmVmb3JlIGNhbGxpbmcuCiAgKiBAcGFyYW0gY2hhcjMyIHRoZSBpbnB1dCBjaGFyYWN0ZXIuCiAgKiBAcmV0dXJuIHRoZSB0cmFpbCBzdXJyb2dhdGUgaWYgdGhlIGdldENoYXJDb3VudChjaCkgaXMgMjsgPGJyPm90aGVyd2lzZSB0aGUgCiAgKiAgICAgICAgIGNoYXJhY3RlciBpdHNlbGYKICAqLwogIHB1YmxpYyBzdGF0aWMgaW50IGdldFRyYWlsU3Vycm9nYXRlKGludCBjaGFyMzIpIAogIHsKICAgIGlmIChjaGFyMzIgPj0gVUNoYXJhY3Rlci5TVVBQTEVNRU5UQVJZX01JTl9WQUxVRSkgewogICAgICByZXR1cm4gVFJBSUxfU1VSUk9HQVRFX01JTl9WQUxVRV8gKyAoY2hhcjMyICYgCiAgICAgICAgICAgICBVQ2hhcmFjdGVyLlRSQUlMX1NVUlJPR0FURV9NQVNLXyk7ICAgICAgIAogICAgfQogICAgICAKICAgIHJldHVybiAoY2hhciljaGFyMzI7CiAgfQogICAgCiAgLyoqCiAgKiBDb252ZW5pZW5jZSBtZXRob2QgY29ycmVzcG9uZGluZyB0byBTdHJpbmcudmFsdWVPZihjaGFyKS4gUmV0dXJucyBhIG9uZSAKICAqIG9yIHR3byBjaGFyIHN0cmluZyBjb250YWluaW5nIHRoZSBVVEYtMzIgdmFsdWUgaW4gVVRGMTYgZm9ybWF0LiBJZiB0aGUgCiAgKiBpbnB1dCB2YWx1ZSBjYW4ndCBiZSBjb252ZXJ0ZWQsIGl0IHN1YnN0aXR1dGVzIFJFUExBQ0VNRU5UX0NIQVIuIElmIGEgCiAgKiB2YWxpZGl0eSBjaGVjayBpcyByZXF1aXJlZCwgdXNlIAogICogPGEgaHJlZj0iLi4vVUNoYXJhY3Rlci5odG1sI2lzTGVnYWwoY2hhcikiPmlzTGVnYWwoKTwvYT48L2NvZGU+IG9uIAogICogY2hhcjMyIGJlZm9yZSBjYWxsaW5nLgogICogQHBhcmFtIGNoYXIzMiB0aGUgaW5wdXQgY2hhcmFjdGVyLgogICogQHJldHVybiBzdHJpbmcgdmFsdWUgb2YgY2hhcjMyIGluIFVURjE2IGZvcm1hdAogICovCiAgcHVibGljIHN0YXRpYyBTdHJpbmcgdmFsdWVPZihpbnQgY2hhcjMyKQogIHsKICAgIGlmIChjaGFyMzIgPCBVQ2hhcmFjdGVyLk1JTl9WQUxVRSB8fCBjaGFyMzIgPiBVQ2hhcmFjdGVyLk1BWF9WQUxVRSkgewogICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbGxlZ2FsIGNvZGVwb2ludCIpOwogICAgfQogICAgaWYgKGNoYXIzMiA8IFVDaGFyYWN0ZXIuU1VQUExFTUVOVEFSWV9NSU5fVkFMVUUpIHsKICAgICAgcmV0dXJuIFN0cmluZy52YWx1ZU9mKChjaGFyKWNoYXIzMik7CiAgICB9CiAgICBjaGFyIHN0cltdID0gbmV3IGNoYXJbMl07ICAgCiAgICBzdHJbMF0gPSAoY2hhcikoTEVBRF9TVVJST0dBVEVfT0ZGU0VUXyArIAogICAgICAgICAgICAgICAgICAgIChjaGFyMzIgPj4gVUNoYXJhY3Rlci5MRUFEX1NVUlJPR0FURV9TSElGVF8pKTsKICAgIHN0clsxXSA9IChjaGFyKShUUkFJTF9TVVJST0dBVEVfTUlOX1ZBTFVFXyArIAogICAgICAgICAgICAgICAgICAgIChjaGFyMzIgJiBVQ2hhcmFjdGVyLlRSQUlMX1NVUlJPR0FURV9NQVNLXykpOwogICAgcmV0dXJuIFN0cmluZy52YWx1ZU9mKHN0cik7CiAgfQogIAogIC8qKgogICogUmV0dXJucyB0aGUgVVRGLTE2IG9mZnNldCB0aGF0IGNvcnJlc3BvbmRzIHRvIGEgVVRGLTMyIG9mZnNldC4gCiAgKiBVc2VkIGZvciByYW5kb20gYWNjZXNzLiBTZWUgdGhlIDxhIG5hbWU9Il90b3BfIj5jbGFzcyBkZXNjcmlwdGlvbjwvYT4gZm9yIAogICogbm90ZXMgb24gcm91bmR0cmlwcGluZy4KICAqIEBwYXJhbSBzb3VyY2UgdGhlIFVURi0xNiBzdHJpbmcKICAqIEBwYXJhbSBvZmZzZXQzMiBVVEYtMzIgb2Zmc2V0CiAgKiBAcmV0dXJuIFVURi0xNiBvZmZzZXQgCiAgKiBAZXhjZXB0aW9uIFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24gaWYgb2Zmc2V0MzIgaXMgb3V0IG9mIGJvdW5kcy4KICAqLwogIHB1YmxpYyBzdGF0aWMgaW50IGZpbmRPZmZzZXRGcm9tQ29kZVBvaW50KFN0cmluZyBzb3VyY2UsIGludCBvZmZzZXQzMikgCiAgewogICAgY2hhciBjaDsKICAgIGludCBzaXplID0gc291cmNlLmxlbmd0aCgpLAogICAgICAgIHJlc3VsdCA9IDAsCiAgICAgICAgY291bnQgPSBvZmZzZXQzMjsKICAgIHdoaWxlIChyZXN1bHQgPCBzaXplICYmIGNvdW50ID4gMCkKICAgIHsKICAgICAgY2ggPSBzb3VyY2UuY2hhckF0KHJlc3VsdCk7CiAgICAgIGlmIChpc0xlYWRTdXJyb2dhdGUoY2gpICYmICgocmVzdWx0ICsgMSkgPCBzaXplKSAmJiAKICAgICAgICAgIGlzVHJhaWxTdXJyb2dhdGUoc291cmNlLmNoYXJBdChyZXN1bHQgKyAxKSkpIHsKICAgICAgICByZXN1bHQgKys7CiAgICAgIH0KICAgICAgICAKICAgICAgY291bnQgLS07CiAgICAgIHJlc3VsdCArKzsKICAgIH0KICAgIGlmIChyZXN1bHQgPj0gc2l6ZSkgewogICAgICB0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihvZmZzZXQzMik7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICAKICAvKioKICAqIFJldHVybnMgdGhlIFVURi0zMiBvZmZzZXQgY29ycmVzcG9uZGluZyB0byB0aGUgZmlyc3QgVVRGLTMyIGJvdW5kYXJ5IGF0IG9yIAogICogYWZ0ZXIgdGhlIGdpdmVuIFVURi0xNiBvZmZzZXQuIFVzZWQgZm9yIHJhbmRvbSBhY2Nlc3MuIFNlZSB0aGUgCiAgKiA8YSBuYW1lPSJfdG9wXyI+Y2xhc3MgZGVzY3JpcHRpb248L2E+IGZvciBub3RlcyBvbiByb3VuZHRyaXBwaW5nLjxicj4KICAqIDxpPk5vdGU6IElmIHRoZSBVVEYtMTYgb2Zmc2V0IGlzIGludG8gdGhlIG1pZGRsZSBvZiBhIHN1cnJvZ2F0ZSBwYWlyLCB0aGVuCiAgKiB0aGUgVVRGLTMyIG9mZnNldCBvZiB0aGUgPHN0cm9uZz5sZWFkPC9zdHJvbmc+IG9mIHRoZSBwYWlyIGlzIHJldHVybmVkLgogICogPC9pPgogICogPHA+CiAgKiBUbyBmaW5kIHRoZSBVVEYtMzIgbGVuZ3RoIG9mIGEgc3RyaW5nLCB1c2U6CiAgKiAgIDxwcmU+CiAgKiAgICAgbGVuMzIgPSBnZXRPZmZzZXQzMihzb3VyY2UsIHNvdXJjZS5sZW5ndGgoKSk7CiAgKiAgIDwvcHJlPgogICogPC9wPgogICogPHA+CiAgKiBAcGFyYW0gc291cmNlIHRleHQgdG8gYW5hbHlzZQogICogQHBhcmFtIG9mZnNldDE2IFVURi0xNiBvZmZzZXQgPCBzb3VyY2UgdGV4dCBsZW5ndGguCiAgKiBAcmV0dXJuIFVURi0zMiBvZmZzZXQKICAqIEBleGNlcHRpb24gU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiBpZiBvZmZzZXQxNiBpcyBvdXQgb2YgYm91bmRzLgogICovCiAgcHVibGljIHN0YXRpYyBpbnQgZmluZENvZGVQb2ludE9mZnNldChTdHJpbmcgc291cmNlLCBpbnQgb2Zmc2V0MTYpIAogIHsKICAgIGlmIChvZmZzZXQxNiA+PSBzb3VyY2UubGVuZ3RoKCkpIHsKICAgICAgdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24ob2Zmc2V0MTYpOwogICAgfQogICAgIAogICAgaW50IHJlc3VsdCA9IDA7CiAgICBjaGFyIGNoOwogICAgYm9vbGVhbiBoYWRMZWFkU3Vycm9nYXRlID0gZmFsc2U7CiAgICAKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgb2Zmc2V0MTY7ICsrIGkpIAogICAgewogICAgICBjaCA9IHNvdXJjZS5jaGFyQXQoaSk7CiAgICAgIGlmIChoYWRMZWFkU3Vycm9nYXRlICYmIGlzVHJhaWxTdXJyb2dhdGUoY2gpKSB7CiAgICAgICAgaGFkTGVhZFN1cnJvZ2F0ZSA9IGZhbHNlOyAgICAgICAgICAgLy8gY291bnQgdmFsaWQgdHJhaWwgYXMgemVybwogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgIGhhZExlYWRTdXJyb2dhdGUgPSBpc0xlYWRTdXJyb2dhdGUoY2gpOwogICAgICAgICsrIHJlc3VsdDsgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvdW50IG90aGVycyBhcyAxCiAgICAgIH0KICAgIH0KICAgIC8vIGVuZCBvZiBzb3VyY2UgYmVpbmcgYSBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcgogICAgLy8gc2hpZnQgcmVzdWx0IGJhY2sgdG8gdGhlIHN0YXJ0IG9mIHRoZSBzdXBwbGVtZW50YXJ5IGNoYXJhY3RlcgogICAgaWYgKGhhZExlYWRTdXJyb2dhdGUgJiYgaXNUcmFpbFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KG9mZnNldDE2KSkpIHsKICAgICAgcmVzdWx0IC0tOwogICAgfQogICAgICAKICAgIHJldHVybiByZXN1bHQ7CiAgfQoKICAvKioKICAqIEFwcGVuZCBhIHNpbmdsZSBVVEYtMzIgdmFsdWUgdG8gdGhlIGVuZCBvZiBhIFN0cmluZ0J1ZmZlci4KICAqIElmIGEgdmFsaWRpdHkgY2hlY2sgaXMgcmVxdWlyZWQsIHVzZSAKICAqIDxhIGhyZWY9Ii4uL1VDaGFyYWN0ZXIuaHRtbCNpc0xlZ2FsKGNoYXIpIj5pc0xlZ2FsKCk8L2E+PC9jb2RlPiBvbiAKICAqIGNoYXIzMiBiZWZvcmUgY2FsbGluZy4KICAqIEBwYXJhbSBjaGFyMzIgdmFsdWUgdG8gYXBwZW5kLiBJZiBvdXQgb2YgYm91bmRzLCBzdWJzdGl0dXRlcyAKICAqICAgICAgICAgICAgICAgVVRGMzIuUkVQTEFDRU1FTlRfQ0hBUi4KICAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgU3RyaW5nQnVmZmVyCiAgKi8KICBwdWJsaWMgc3RhdGljIFN0cmluZ0J1ZmZlciBhcHBlbmQoU3RyaW5nQnVmZmVyIHRhcmdldCwgaW50IGNoYXIzMikKICB7CiAgICAvLyBDaGVjayBmb3IgaXJyZWd1bGFyIHZhbHVlcwogICAgaWYgKGNoYXIzMiA8IFVDaGFyYWN0ZXIuTUlOX1ZBTFVFIHx8IGNoYXIzMiA+IFVDaGFyYWN0ZXIuTUFYX1ZBTFVFKSB7CiAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIklsbGVnYWwgY29kZXBvaW50Iik7CiAgICB9CiAgICAgICAgCiAgICAvLyBXcml0ZSB0aGUgVVRGLTE2IHZhbHVlcwogICAgaWYgKGNoYXIzMiA+PSBVQ2hhcmFjdGVyLlNVUFBMRU1FTlRBUllfTUlOX1ZBTFVFKSAKICAgIHsKICAgICAgdGFyZ2V0LmFwcGVuZCgoY2hhcikoTEVBRF9TVVJST0dBVEVfT0ZGU0VUXyArIAogICAgICAgICAgICAgICAgICAgIChjaGFyMzIgPj4gVUNoYXJhY3Rlci5MRUFEX1NVUlJPR0FURV9TSElGVF8pKSk7CgkgICAgdGFyZ2V0LmFwcGVuZCgoY2hhcikoVFJBSUxfU1VSUk9HQVRFX01JTl9WQUxVRV8gKyAKICAgICAgICAgICAgICAgICAgICAoY2hhcjMyICYgVUNoYXJhY3Rlci5UUkFJTF9TVVJST0dBVEVfTUFTS18pKSk7CgkgIH0gCgkgIGVsc2UgewoJICAgIHRhcmdldC5hcHBlbmQoKGNoYXIpY2hhcjMyKTsKCSAgfQoJICByZXR1cm4gdGFyZ2V0OwoJfQogICAgCiAgLyoqCiAgKiBDb21wYXJlIHN0cmluZ3MgdXNpbmcgVW5pY29kZSBjb2RlIHBvaW50IG9yZGVyLCBpbnN0ZWFkIG9mIFVURi0xNiBjb2RlIAogICogdW5pdCBvcmRlci4KICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nQ29tcGFyYXRvciBpbXBsZW1lbnRzIGphdmEudXRpbC5Db21wYXJhdG9yIAogIHsKICAgIC8qKgogICAgKiBTdGFuZGFyZCBTdHJpbmcgY29tcGFyZS4gT25seSBvbmUgc21hbGwgc2VjdGlvbiBpcyBkaWZmZXJlbnQsIG1hcmtlZCBpbiAKICAgICogdGhlIGNvZGUuCiAgICAqLwogICAgcHVibGljIGludCBjb21wYXJlKE9iamVjdCBhLCBPYmplY3QgYikgCiAgICB7CgkgICAgaWYgKGEgPT0gYikgewoJICAgICAgcmV0dXJuIDA7CgkgICAgfQogICAgICBpZiAoYSA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgICB9CiAgICAgIGlmIChiID09IG51bGwpIHsKICAgICAgICByZXR1cm4gMTsKICAgICAgfQogICAgICAgICAgCiAgICAgIFN0cmluZyBzYSA9IChTdHJpbmcpIGE7CiAgICAgIFN0cmluZyBzYiA9IChTdHJpbmcpIGI7CiAgICAgIGludCBsZW5hID0gc2EubGVuZ3RoKCk7CiAgICAgIGludCBsZW5iID0gc2IubGVuZ3RoKCk7CiAgICAgIGludCBsZW4gPSBsZW5hOwogICAgICBpZiAobGVuID4gbGVuYikgewogICAgICAgIGxlbiA9IGxlbmI7CiAgICAgIH0KICAgICAgICAKICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW47ICsraSkgCiAgICAgIHsKICAgICAgICBjaGFyIGNhID0gc2EuY2hhckF0KGkpOwogICAgICAgIGNoYXIgY2IgPSBzYi5jaGFyQXQoaSk7CiAgICAgICAgaWYgKGNhID09IGNiKSB7CiAgICAgICAgICBjb250aW51ZTsgLy8gc2tpcCByZW1hcCBpZiBlcXVhbAogICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgIC8vIHN0YXJ0IG9mIG9ubHkgZGlmZmVyZW50IHNlY3Rpb24KICAgICAgICAvLyB3aGF0IHRoaXMgcGFydCBkb2VzIGlzIHRvIHJlYXJyYW5nZSB0aGUgY2hhcmFjdGVycyAweEUwMDAgdG8gMHhGRkZGCiAgICAgICAgLy8gdG8gdGhlIHJlZ2lvbiBzdGFydGluZyBmcm9tIDB4RDgwMAogICAgICAgIC8vIGFuZCBzaGlmdCB0aGUgc3Vycm9nYXRlIGNoYXJhY3RlcnMgdG8gYWJvdmUgdGhpcyByZWdpb24KICAgICAgICBpZiAoY2EgPj0gTEVBRF9TVVJST0dBVEVfTUlOX1ZBTFVFXykgewogICAgICAgICAgY2EgKz0gKGNhIDw9IFRSQUlMX1NVUlJPR0FURV9NQVhfVkFMVUVfKSA/IDB4MjAwMCA6IC0weDgwMDsKICAgICAgICB9CiAgICAgICAgaWYgKGNiID49IExFQURfU1VSUk9HQVRFX01JTl9WQUxVRV8pIHsKICAgICAgICAgIGNiICs9IChjYiA8PSBUUkFJTF9TVVJST0dBVEVfTUFYX1ZBTFVFXykgPyAweDIwMDAgOiAtMHg4MDA7CiAgICAgICAgfQogICAgICAgIC8vIGVuZCBvZiBvbmx5IGRpZmZlcmVudCBzZWN0aW9uCiAgICAgICAgICAgICAgICAKICAgICAgICBpZiAoY2EgPCBjYikgewogICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICAgIAogICAgICAgIHJldHVybiAxOyAvLyB3YXNuJ3QgZXF1YWwsIHNvIHJldHVybiAxCiAgICAgIH0KICAgICAgCiAgICAgIGlmIChsZW5hIDwgbGVuYikgewogICAgICAgIHJldHVybiAtMTsKICAgICAgfQogICAgICAgIAogICAgICBpZiAobGVuYSA+IGxlbmIpIHsKICAgICAgICByZXR1cm4gMTsKICAgICAgfQogICAgICAgICAgICAKICAgICAgcmV0dXJuIDA7CiAgICB9CiAgfQkKICAKICAvKioKICAqIE51bWJlciBvZiBjb2RlcG9pbnRzIGluIGEgVVRGMTYgU3RyaW5nCiAgKiBAcGFyYW0gcyBVVEYxNiBzdHJpbmcKICAqIEByZXR1cm4gbnVtYmVyIG9mIGNvZGVwb2ludCBpbiBzdHJpbmcKICAqLwogIHB1YmxpYyBzdGF0aWMgaW50IGNvdW50Q29kZVBvaW50KFN0cmluZyBzKQogIHsKICAgIHJldHVybiBmaW5kQ29kZVBvaW50T2Zmc2V0KHMsIHMubGVuZ3RoKCkgLSAxKSArIDE7CiAgfQogIAogIC8qKgogICogU2V0cyBhIGNvZGUgcG9pbnQgaW50byBhIFVURjMyIHBvc2l0aW9uLgogICogQHBhcmFtIHN0ciBzdHJpbmdidWZmZXIKICAqIEBwYXJhbSBvZmZzZXQzMiBVVEYzMiBwb3NpdGlvbiB0byBpbnNlcnQgaW50bwogICogQHBhcmFtIGNoYXIzMiBjb2RlIHBvaW50CiAgKi8KICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0Q2hhckF0Q29kZVBvaW50T2Zmc2V0KFN0cmluZ0J1ZmZlciBzdHIsIGludCBvZmZzZXQzMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjaGFyMzIpCiAgewogICAgaW50IG9mZnNldDE2ID0gZmluZE9mZnNldEZyb21Db2RlUG9pbnQoc3RyLnRvU3RyaW5nKCksIG9mZnNldDMyKTsKICAgIHNldENoYXJBdChzdHIsIG9mZnNldDE2LCBjaGFyMzIpOwogIH0KICAKICAvKioKICAqIFNldCBhIGNvZGUgcG9pbnQgaW50byBhIFVURjE2IHBvc2l0aW9uLgogICogQHBhcmFtIHNvdXJjZSBzdHJpbmdidWZmZXIKICAqIEBwYXJhbSBvZmZzZXQxNiBVVEYxNiBwb3NpdGlvbiB0byBpbnNlcnQgaW50bwogICogQHBhcmFtIGNoYXIzMiBjb2RlIHBvaW50CiAgKi8KICBwdWJsaWMgc3RhdGljIHZvaWQgc2V0Q2hhckF0KFN0cmluZ0J1ZmZlciBzb3VyY2UsIGludCBvZmZzZXQxNiwgaW50IGNoYXIzMikKICB7CiAgICBpbnQgY291bnQgPSAxOwogICAgICAKICAgIGNoYXIgc2luZ2xlID0gc291cmNlLmNoYXJBdChvZmZzZXQxNik7CiAgICAKICAgIGlmIChpc1N1cnJvZ2F0ZShzaW5nbGUpKSAKICAgIHsKICAgICAgLy8gcGFpcnMgb2YgdGhlIHN1cnJvZ2F0ZSB3aXRoIG9mZnNldDE2IGF0IHRoZSBsZWFkIGNoYXIgZm91bmQKICAgICAgaWYgKGlzTGVhZFN1cnJvZ2F0ZShzaW5nbGUpICYmIChzb3VyY2UubGVuZ3RoKCkgPiBvZmZzZXQxNiArIDEpICYmCiAgICAgICAgICBpc1RyYWlsU3Vycm9nYXRlKHNvdXJjZS5jaGFyQXQob2Zmc2V0MTYgKyAxKSkpIHsKCSAgICAgIGNvdW50ICsrOwoJICAgIH0KCSAgICBlbHNlIHsKCSAgICAgIC8vIHBhaXJzIG9mIHRoZSBzdXJyb2dhdGUgd2l0aCBvZmZzZXQxNiBhdCB0aGUgdHJhaWwgY2hhciBmb3VuZAoJICAgICAgaWYgKGlzVHJhaWxTdXJyb2dhdGUoc2luZ2xlKSAmJiAob2Zmc2V0MTYgPiAwKSAmJgoJICAgICAgICAgIGlzTGVhZFN1cnJvZ2F0ZShzb3VyY2UuY2hhckF0KG9mZnNldDE2IC0xKSkpCgkgICAgICB7CgkgICAgICAgIG9mZnNldDE2IC0tOwoJICAgICAgICBjb3VudCArKzsKCSAgICAgIH0KCSAgICB9CgkgIH0KCSAgc291cmNlLnJlcGxhY2Uob2Zmc2V0MTYsIG9mZnNldDE2ICsgY291bnQsIHZhbHVlT2YoY2hhcjMyKSk7Cgl9Cn0K