cGFja2FnZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwuZGVidWcuY29yZTsKCi8qCiAqIChjKSBDb3B5cmlnaHQgSUJNIENvcnAuIDIwMDAsIDIwMDEuCiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqLwoKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCnB1YmxpYyBjbGFzcyBTdHJpbmdNYXRjaGVyIHsKCXByb3RlY3RlZCBTdHJpbmcgZlBhdHRlcm47Cglwcm90ZWN0ZWQgaW50IGZMZW5ndGg7IC8vIHBhdHRlcm4gbGVuZ3RoCglwcm90ZWN0ZWQgYm9vbGVhbiBmSWdub3JlV2lsZENhcmRzOwoJcHJvdGVjdGVkIGJvb2xlYW4gZklnbm9yZUNhc2U7Cglwcm90ZWN0ZWQgYm9vbGVhbiBmSGFzTGVhZGluZ1N0YXI7Cglwcm90ZWN0ZWQgYm9vbGVhbiBmSGFzVHJhaWxpbmdTdGFyOwoJcHJvdGVjdGVkIFN0cmluZyBmU2VnbWVudHNbXTsgLy90aGUgZ2l2ZW4gcGF0dGVybiBpcyBzcGxpdCBpbnRvICogc2VwYXJhdGVkIHNlZ21lbnRzCgoJLyogYm91bmRhcnkgdmFsdWUgYmV5b25kIHdoaWNoIHdlIGRvbid0IG5lZWQgdG8gc2VhcmNoIGluIHRoZSB0ZXh0ICovCglwcm90ZWN0ZWQgaW50IGZCb3VuZD0gMDsKCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGNoYXIgZlNpbmdsZVdpbGRDYXJkPSAnXHUwMDAwJzsKCglwdWJsaWMgc3RhdGljIGNsYXNzIFBvc2l0aW9uIHsKCQlpbnQgc3RhcnQ7IC8vaW5jbHVzaXZlCgkJaW50IGVuZDsgLy9leGNsdXNpdmUKCQlwdWJsaWMgUG9zaXRpb24oaW50IHN0YXJ0LCBpbnQgZW5kKSB7CgkJCXRoaXMuc3RhcnQ9IHN0YXJ0OwoJCQl0aGlzLmVuZD0gZW5kOwoJCX0KCQlwdWJsaWMgaW50IGdldFN0YXJ0KCkgewoJCQlyZXR1cm4gc3RhcnQ7CgkJfQoJCXB1YmxpYyBpbnQgZ2V0RW5kKCkgewoJCQlyZXR1cm4gZW5kOwoJCX0KCX0KCgkvKioKCSAqIFN0cmluZ01hdGNoZXIgY29uc3RydWN0b3IgdGFrZXMgaW4gYSBTdHJpbmcgb2JqZWN0IHRoYXQgaXMgYSBzaW1wbGUgCgkgKiBwYXR0ZXJuIHdoaWNoIG1heSBjb250YWluIJEqkiBmb3IgMCBhbmQgbWFueSBjaGFyYWN0ZXJzIGFuZAoJICogkT+SIGZvciBleGFjdGx5IG9uZSBjaGFyYWN0ZXIuICAKCSAqCgkgKiBMaXRlcmFsICcqJyBhbmQgJz8nIGNoYXJhY3RlcnMgbXVzdCBiZSBlc2NhcGVkIGluIHRoZSBwYXR0ZXJuIAoJICogZS5nLiwgIlwqIiBtZWFucyBsaXRlcmFsICIqIiwgZXRjLgoJICoKCSAqIEVzY2FwaW5nIGFueSBvdGhlciBjaGFyYWN0ZXIgKGluY2x1ZGluZyB0aGUgZXNjYXBlIGNoYXJhY3RlciBpdHNlbGYpLCAKCSAqIGp1c3QgcmVzdWx0cyBpbiB0aGF0IGNoYXJhY3RlciBpbiB0aGUgcGF0dGVybi4KCSAqIGUuZy4sICJcYSIgbWVhbnMgImEiIGFuZCAiXFwiIG1lYW5zICJcIgoJICoKCSAqIElmIGludm9raW5nIHRoZSBTdHJpbmdNYXRjaGVyIHdpdGggc3RyaW5nIGxpdGVyYWxzIGluIEphdmEsIGRvbid0IGZvcmdldAoJICogZXNjYXBlIGNoYXJhY3RlcnMgYXJlIHJlcHJlc2VudGVkIGJ5ICJcXCIuCgkgKgoJICogQHBhcmFtIGFQYXR0ZXJuIHRoZSBwYXR0ZXJuIHRvIG1hdGNoIHRleHQgYWdhaW5zdAoJICogQHBhcmFtIGlnbm9yZUNhc2UgaWYgdHJ1ZSwgY2FzZSBpcyBpZ25vcmVkCgkgKiBAcGFyYW0gaWdub3JlV2lsZENhcmRzIGlmIHRydWUsIHdpbGQgY2FyZHMgYW5kIHRoZWlyIGVzY2FwZSBzZXF1ZW5jZXMgYXJlIGlnbm9yZWQKCSAqIAkJICAoZXZlcnl0aGluZyBpcyB0YWtlbiBsaXRlcmFsbHkpLgoJICovCglwdWJsaWMgU3RyaW5nTWF0Y2hlcihTdHJpbmcgYVBhdHRlcm4sIGJvb2xlYW4gaWdub3JlQ2FzZSwgYm9vbGVhbiBpZ25vcmVXaWxkQ2FyZHMpIHsKCQlmSWdub3JlQ2FzZT0gaWdub3JlQ2FzZTsKCQlmSWdub3JlV2lsZENhcmRzPSBpZ25vcmVXaWxkQ2FyZHM7CgkJZkxlbmd0aD0gYVBhdHRlcm4ubGVuZ3RoKCk7CgoJCS8qIGNvbnZlcnQgY2FzZSAqLwoJCWlmIChmSWdub3JlQ2FzZSkgewoJCQlmUGF0dGVybj0gYVBhdHRlcm4udG9VcHBlckNhc2UoKTsKCQl9IGVsc2UgewoJCQlmUGF0dGVybj0gYVBhdHRlcm47CgkJfQoKCQlpZiAoZklnbm9yZVdpbGRDYXJkcykgewoJCQlwYXJzZU5vV2lsZENhcmRzKCk7CgkJfSBlbHNlIHsKCQkJcGFyc2VXaWxkQ2FyZHMoKTsKCQl9Cgl9CgoJLyoqCgkgKiBGaW5kIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBwYXR0ZXJuIGJldHdlZW4gPGNvZGU+c3RhcnQ8L2NvZGUpKGluY2x1c2l2ZSkgCgkgKiBhbmQgPGNvZGU+ZW5kPC9jb2RlPihleGNsdXNpdmUpLiAgCgkgKiBAcGFyYW0gPGNvZGU+dGV4dDwvY29kZT4sIHRoZSBTdHJpbmcgb2JqZWN0IHRvIHNlYXJjaCBpbiAKCSAqIEBwYXJhbSA8Y29kZT5zdGFydDwvY29kZT4sIHRoZSBzdGFydGluZyBpbmRleCBvZiB0aGUgc2VhcmNoIHJhbmdlLCBpbmNsdXNpdmUKCSAqIEBwYXJhbSA8Y29kZT5lbmQ8L2NvZGU+LCB0aGUgZW5kaW5nIGluZGV4IG9mIHRoZSBzZWFyY2ggcmFuZ2UsIGV4Y2x1c2l2ZQoJICogQHJldHVybiBhbiA8Y29kZT5TdHJpbmdNYXRjaGVyLlBvc2l0aW9uPC9jb2RlPiBvYmplY3QgdGhhdCBrZWVwcyB0aGUgc3RhcnRpbmcgCgkgKiAoaW5jbHVzaXZlKSBhbmQgZW5kaW5nIHBvc2l0aW9ucyAoZXhjbHVzaXZlKSBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgCgkgKiBwYXR0ZXJuIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIHRleHQ7IHJldHVybiBudWxsIGlmIG5vdCBmb3VuZCBvciBzdWJ0ZXh0CgkgKiBpcyBlbXB0eSAoc3RhcnQ9PWVuZCkuIEEgcGFpciBvZiB6ZXJvcyBpcyByZXR1cm5lZCBpZiBwYXR0ZXJuIGlzIGVtcHR5IHN0cmluZwoJICogTm90ZSB0aGF0IGZvciBwYXR0ZXJuIGxpa2UgIiphYmMqIiB3aXRoIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHN0YXJzLCBwb3NpdGlvbiBvZiAiYWJjIgoJICogaXMgcmV0dXJuZWQuIEZvciBhIHBhdHRlcm4gbGlrZSIqPz8qIiBpbiB0ZXh0ICJhYmNkZiIsICgxLDMpIGlzIHJldHVybmVkCgkgKi8KCglwdWJsaWMgU3RyaW5nTWF0Y2hlci5Qb3NpdGlvbiBmaW5kKFN0cmluZyB0ZXh0LCBpbnQgc3RhcnQsIGludCBlbmQpIHsKCQlpZiAoZlBhdHRlcm4gPT0gbnVsbCB8fCB0ZXh0ID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCgkJaW50IHRsZW49IHRleHQubGVuZ3RoKCk7CgkJaWYgKHN0YXJ0IDwgMCkKCQkJc3RhcnQ9IDA7CgkJaWYgKGVuZCA+IHRsZW4pCgkJCWVuZD0gdGxlbjsKCQlpZiAoZW5kIDwgMCB8fCBzdGFydCA+PSBlbmQpCgkJCXJldHVybiBudWxsOwoJCWlmIChmTGVuZ3RoID09IDApCgkJCXJldHVybiBuZXcgUG9zaXRpb24oc3RhcnQsIHN0YXJ0KTsKCQlpZiAoZklnbm9yZVdpbGRDYXJkcykgewoJCQlpbnQgeD0gcG9zSW4odGV4dCwgc3RhcnQsIGVuZCk7CgkJCWlmICh4IDwgMCkKCQkJCXJldHVybiBudWxsOwoJCQlyZXR1cm4gbmV3IFBvc2l0aW9uKHgsIHggKyBmTGVuZ3RoKTsKCQl9CgoJCWludCBzZWdDb3VudD0gZlNlZ21lbnRzLmxlbmd0aDsKCQlpZiAoc2VnQ291bnQgPT0gMCkgLy9wYXR0ZXJuIGNvbnRhaW5zIG9ubHkgJyonKHMpCgkJCXJldHVybiBuZXcgUG9zaXRpb24oc3RhcnQsIGVuZCk7CgoJCWludCBjdXJQb3M9IHN0YXJ0OwoJCWludCBtYXRjaFN0YXJ0PSAtMTsKCQlpbnQgaTsKCQlmb3IgKGk9IDA7IGkgPCBzZWdDb3VudCAmJiBjdXJQb3MgPCBlbmQ7ICsraSkgewoJCQlTdHJpbmcgY3VycmVudD0gZlNlZ21lbnRzW2ldOwoJCQlpbnQgbmV4dE1hdGNoPSByZWdFeHBQb3NJbih0ZXh0LCBjdXJQb3MsIGVuZCwgY3VycmVudCk7CgkJCWlmIChuZXh0TWF0Y2ggPCAwKQoJCQkJcmV0dXJuIG51bGw7CgkJCWlmIChpID09IDApIHsKCQkJCW1hdGNoU3RhcnQ9IG5leHRNYXRjaDsKCQkJfQoJCQljdXJQb3M9IG5leHRNYXRjaCArIGN1cnJlbnQubGVuZ3RoKCk7CgkJfQoJCWlmIChpIDwgc2VnQ291bnQpIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoJCXJldHVybiBuZXcgUG9zaXRpb24obWF0Y2hTdGFydCwgY3VyUG9zKTsKCX0KCgkvKioKCSAqIG1hdGNoIHRoZSBnaXZlbiA8Y29kZT50ZXh0PC9jb2RlPiB3aXRoIHRoZSBwYXR0ZXJuIAoJICogQHJldHVybiB0cnVlIGlmIG1hdGNoZWQgZWl0aGVyd2lzZSBmYWxzZQoJICogQHBhcmFtIDxjb2RlPnRleHQ8L2NvZGU+LCBhIFN0cmluZyBvYmplY3QgCgkgKi8KCXB1YmxpYyBib29sZWFuIG1hdGNoKFN0cmluZyB0ZXh0KSB7CgkJcmV0dXJuIG1hdGNoKHRleHQsIDAsIHRleHQubGVuZ3RoKCkpOwoJfQoKCS8qKgoJICogR2l2ZW4gdGhlIHN0YXJ0aW5nIChpbmNsdXNpdmUpIGFuZCB0aGUgZW5kaW5nIChleGNsdXNpdmUpIHBvaXNpdGlvbnMgaW4gdGhlICAgCgkgKiA8Y29kZT50ZXh0PC9jb2RlPiwgZGV0ZXJtaW5lIGlmIHRoZSBnaXZlbiBzdWJzdHJpbmcgbWF0Y2hlcyB3aXRoIGFQYXR0ZXJuICAKCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHBvcnRpb24gb2YgdGhlIHRleHQgbWF0Y2hlcyB0aGUgcGF0dGVybgoJICogQHBhcmFtIFN0cmluZyA8Y29kZT50ZXh0PC9jb2RlPiwgYSBTdHJpbmcgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIHN1YnN0cmluZyB0byBtYXRjaCAKCSAqIEBwYXJhbSBpbnQgPGNvZGU+c3RhcnQ8Y29kZT4gbWFya3MgdGhlIHN0YXJ0aW5nIHBvc2l0aW9uIChpbmNsdXNpdmUpIG9mIHRoZSBzdWJzdHJpbmcKCSAqIEBwYXJhbSBpbnQgPGNvZGU+ZW5kPGNvZGU+IG1hcmtzIHRoZSBlbmRpbmcgaW5kZXggKGV4Y2x1c2l2ZSkgb2YgdGhlIHN1YnN0cmluZyAKCSAqLwoJcHVibGljIGJvb2xlYW4gbWF0Y2goU3RyaW5nIHRleHQsIGludCBzdGFydCwgaW50IGVuZCkgewoJCWlmIChudWxsID09IGZQYXR0ZXJuIHx8IG51bGwgPT0gdGV4dCkKCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoKCQlpZiAoc3RhcnQgPiBlbmQpCgkJCXJldHVybiBmYWxzZTsKCgkJaWYgKGZJZ25vcmVXaWxkQ2FyZHMpCgkJCXJldHVybiBmUGF0dGVybi5yZWdpb25NYXRjaGVzKGZJZ25vcmVDYXNlLCAwLCB0ZXh0LCBzdGFydCwgZkxlbmd0aCk7CgkJaW50IHNlZ0NvdW50PSBmU2VnbWVudHMubGVuZ3RoOwoJCWlmIChzZWdDb3VudCA9PSAwKSAvL3BhdHRlcm4gY29udGFpbnMgb25seSAnKicocykgb3IgZW1wdHkgcGF0dGVybgoJCQlyZXR1cm4gdHJ1ZTsKCQlpZiAoc3RhcnQgPT0gZW5kKQoJCQlyZXR1cm4gZkxlbmd0aCA9PSAwOwoJCWlmIChmTGVuZ3RoID09IDApCgkJCXJldHVybiBzdGFydCA9PSBlbmQ7CgoJCWludCB0bGVuPSB0ZXh0Lmxlbmd0aCgpOwoJCWlmIChzdGFydCA8IDApCgkJCXN0YXJ0PSAwOwoJCWlmIChlbmQgPiB0bGVuKQoJCQllbmQ9IHRsZW47CgoJCWludCB0Q3VyUG9zPSBzdGFydDsKCQlpbnQgYm91bmQ9IGVuZCAtIGZCb3VuZDsKCQlpZiAoYm91bmQgPCAwKQoJCQlyZXR1cm4gZmFsc2U7CgkJaW50IGk9IDA7CgkJU3RyaW5nIGN1cnJlbnQ9IGZTZWdtZW50c1tpXTsKCQlpbnQgc2VnTGVuZ3RoPSBjdXJyZW50Lmxlbmd0aCgpOwoKCQkvKiBwcm9jZXNzIGZpcnN0IHNlZ21lbnQgKi8KCQlpZiAoIWZIYXNMZWFkaW5nU3RhcikgewoJCQlpZiAoIXJlZ0V4cFJlZ2lvbk1hdGNoZXModGV4dCwgc3RhcnQsIGN1cnJlbnQsIDAsIHNlZ0xlbmd0aCkpIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfSBlbHNlIHsKCQkJCSsraTsKCQkJCXRDdXJQb3M9IHRDdXJQb3MgKyBzZWdMZW5ndGg7CgkJCX0KCQl9CgoJCS8qIHByb2Nlc3MgbWlkZGxlIHNlZ21lbnRzICovCgkJd2hpbGUgKGkgPCBzZWdDb3VudCkgewoJCQljdXJyZW50PSBmU2VnbWVudHNbaV07CgkJCWludCBjdXJyZW50TWF0Y2g7CgkJCWludCBrPSBjdXJyZW50LmluZGV4T2YoZlNpbmdsZVdpbGRDYXJkKTsKCQkJaWYgKGsgPCAwKSB7CgkJCQljdXJyZW50TWF0Y2g9IHRleHRQb3NJbih0ZXh0LCB0Q3VyUG9zLCBlbmQsIGN1cnJlbnQpOwoJCQkJaWYgKGN1cnJlbnRNYXRjaCA8IDApCgkJCQkJcmV0dXJuIGZhbHNlOwoJCQl9IGVsc2UgewoJCQkJY3VycmVudE1hdGNoPSByZWdFeHBQb3NJbih0ZXh0LCB0Q3VyUG9zLCBlbmQsIGN1cnJlbnQpOwoJCQkJaWYgKGN1cnJlbnRNYXRjaCA8IDApCgkJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJCXRDdXJQb3M9IGN1cnJlbnRNYXRjaCArIGN1cnJlbnQubGVuZ3RoKCk7CgkJfQoKCQkvKiBwcm9jZXNzIGZpbmFsIHNlZ21lbnQgKi8KCQlpZiAoIWZIYXNUcmFpbGluZ1N0YXIgJiYgdEN1clBvcyAhPSBlbmQpIHsKCQkJaW50IGNsZW49IGN1cnJlbnQubGVuZ3RoKCk7CgkJCXJldHVybiByZWdFeHBSZWdpb25NYXRjaGVzKHRleHQsIGVuZCAtIGNsZW4sIGN1cnJlbnQsIDAsIGNsZW4pOwoJCX0KCQlyZXR1cm4gaSA9PSBzZWdDb3VudDsKCX0KCgkvKioKCSAqIFRoaXMgbWV0aG9kIHBhcnNlcyB0aGUgZ2l2ZW4gcGF0dGVybiBpbnRvIHNlZ21lbnRzIHNlcGVyYXRlZCBieSB3aWxkY2FyZCAnKicgY2hhcmFjdGVycy4KCSAqIFNpbmNlIHdpbGRjYXJkcyBhcmUgbm90IGJlaW5nIHVzZWQgaW4gdGhpcyBjYXNlLCB0aGUgcGF0dGVybiBjb25zaXN0cyBvZiBhIHNpbmdsZSBzZWdtZW50LgoJICovCglwcml2YXRlIHZvaWQgcGFyc2VOb1dpbGRDYXJkcygpIHsKCQlmU2VnbWVudHM9IG5ldyBTdHJpbmdbMV07CgkJZlNlZ21lbnRzWzBdPSBmUGF0dGVybjsKCQlmQm91bmQ9IGZMZW5ndGg7Cgl9CgoJLyoqCgkgKiAgVGhpcyBtZXRob2QgcGFyc2VzIHRoZSBnaXZlbiBwYXR0ZXJuIGludG8gc2VnbWVudHMgc2VwZXJhdGVkIGJ5IHdpbGRjYXJkICcqJyBjaGFyYWN0ZXJzLgoJICogQHBhcmFtIHAsIGEgU3RyaW5nIG9iamVjdCB0aGF0IGlzIGEgc2ltcGxlIHJlZ3VsYXIgZXhwcmVzc2lvbiB3aXRoIJEqkiBhbmQvb3IgkT+SCgkgKi8KCXByaXZhdGUgdm9pZCBwYXJzZVdpbGRDYXJkcygpIHsKCQlpZiAoZlBhdHRlcm4uc3RhcnRzV2l0aCgiKiIpKSAvLyROT04tTkxTLTEkCgkJCWZIYXNMZWFkaW5nU3Rhcj0gdHJ1ZTsKCQlpZiAoZlBhdHRlcm4uZW5kc1dpdGgoIioiKSkgeyAvLyROT04tTkxTLTEkCgkJCS8qIG1ha2Ugc3VyZSBpdCdzIG5vdCBhbiBlc2NhcGVkIHdpbGRjYXJkICovCgkJCWlmIChmTGVuZ3RoID4gMSAmJiBmUGF0dGVybi5jaGFyQXQoZkxlbmd0aCAtIDIpICE9ICdcXCcpIHsKCQkJCWZIYXNUcmFpbGluZ1N0YXI9IHRydWU7CgkJCX0KCQl9CgoJCUxpc3QgdGVtcD0gbmV3IEFycmF5TGlzdCgpOwoKCQlpbnQgcG9zPSAwOwoJCVN0cmluZ0J1ZmZlciBidWY9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCQl3aGlsZSAocG9zIDwgZkxlbmd0aCkgewoJCQljaGFyIGM9IGZQYXR0ZXJuLmNoYXJBdChwb3MrKyk7CgkJCXN3aXRjaCAoYykgewoJCQkJY2FzZSAnXFwnIDoKCQkJCQlpZiAocG9zID49IGZMZW5ndGgpIHsKCQkJCQkJYnVmLmFwcGVuZChjKTsKCQkJCQl9IGVsc2UgewoJCQkJCQljaGFyIG5leHQ9IGZQYXR0ZXJuLmNoYXJBdChwb3MrKyk7CgkJCQkJCS8qIGlmIGl0J3MgYW4gZXNjYXBlIHNlcXVlbmNlICovCgkJCQkJCWlmIChuZXh0ID09ICcqJyB8fCBuZXh0ID09ICc/JyB8fCBuZXh0ID09ICdcXCcpIHsKCQkJCQkJCWJ1Zi5hcHBlbmQobmV4dCk7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQkvKiBub3QgYW4gZXNjYXBlIHNlcXVlbmNlLCBqdXN0IGluc2VydCBsaXRlcmFsbHkgKi8KCQkJCQkJCWJ1Zi5hcHBlbmQoYyk7CgkJCQkJCQlidWYuYXBwZW5kKG5leHQpOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSAnKicgOgoJCQkJCWlmIChidWYubGVuZ3RoKCkgPiAwKSB7CgkJCQkJCS8qIG5ldyBzZWdtZW50ICovCgkJCQkJCXRlbXAuYWRkKGJ1Zi50b1N0cmluZygpKTsKCQkJCQkJZkJvdW5kICs9IGJ1Zi5sZW5ndGgoKTsKCQkJCQkJYnVmLnNldExlbmd0aCgwKTsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQljYXNlICc/JyA6CgkJCQkJLyogYXBwZW5kIHNwZWNpYWwgY2hhcmFjdGVyIHJlcHJlc2VudGluZyBzaW5nbGUgbWF0Y2ggd2lsZGNhcmQgKi8KCQkJCQlidWYuYXBwZW5kKGZTaW5nbGVXaWxkQ2FyZCk7CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0IDoKCQkJCQlidWYuYXBwZW5kKGMpOwoJCQl9CgkJfQoKCQkvKiBhZGQgbGFzdCBidWZmZXIgdG8gc2VnbWVudCBsaXN0ICovCgkJaWYgKGJ1Zi5sZW5ndGgoKSA+IDApIHsKCQkJdGVtcC5hZGQoYnVmLnRvU3RyaW5nKCkpOwoJCQlmQm91bmQgKz0gYnVmLmxlbmd0aCgpOwoJCX0KCgkJZlNlZ21lbnRzPSBuZXcgU3RyaW5nW3RlbXAuc2l6ZSgpXTsKCQl0ZW1wLnRvQXJyYXkoZlNlZ21lbnRzKTsKCX0KCgkvKiogCgkgKiBAcGFyYW0gPGNvZGU+dGV4dDwvY29kZT4sIGEgc3RyaW5nIHdoaWNoIGNvbnRhaW5zIG5vIHdpbGRjYXJkCgkgKiBAcGFyYW0gPGNvZGU+c3RhcnQ8L2NvZGU+LCB0aGUgc3RhcnRpbmcgaW5kZXggaW4gdGhlIHRleHQgZm9yIHNlYXJjaCwgaW5jbHVzaXZlCgkgKiBAcGFyYW0gPGNvZGU+ZW5kPC9jb2RlPiwgdGhlIHN0b3BwaW5nIHBvaW50IG9mIHNlYXJjaCwgZXhjbHVzaXZlCgkgKiBAcmV0dXJuIHRoZSBzdGFydGluZyBpbmRleCBpbiB0aGUgdGV4dCBvZiB0aGUgcGF0dGVybiAsIG9yIC0xIGlmIG5vdCBmb3VuZCAKCSAqLwoJcHJvdGVjdGVkIGludCBwb3NJbihTdHJpbmcgdGV4dCwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7IC8vbm8gd2lsZCBjYXJkIGluIHBhdHRlcm4KCQlpbnQgbWF4PSBlbmQgLSBmTGVuZ3RoOwoKCQlpZiAoIWZJZ25vcmVDYXNlKSB7CgkJCWludCBpPSB0ZXh0LmluZGV4T2YoZlBhdHRlcm4sIHN0YXJ0KTsKCQkJaWYgKGkgPT0gLTEgfHwgaSA+IG1heCkKCQkJCXJldHVybiAtMTsKCQkJcmV0dXJuIGk7CgkJfQoKCQlmb3IgKGludCBpPSBzdGFydDsgaSA8PSBtYXg7ICsraSkgewoJCQlpZiAodGV4dC5yZWdpb25NYXRjaGVzKHRydWUsIGksIGZQYXR0ZXJuLCAwLCBmTGVuZ3RoKSkKCQkJCXJldHVybiBpOwoJCX0KCgkJcmV0dXJuIC0xOwoJfQoKCS8qKiAKCSAqIEBwYXJhbSA8Y29kZT50ZXh0PC9jb2RlPiwgYSBzaW1wbGUgcmVndWxhciBleHByZXNzaW9uIHRoYXQgbWF5IG9ubHkgY29udGFpbiAnPycocykKCSAqIEBwYXJhbSA8Y29kZT5zdGFydDwvY29kZT4sIHRoZSBzdGFydGluZyBpbmRleCBpbiB0aGUgdGV4dCBmb3Igc2VhcmNoLCBpbmNsdXNpdmUKCSAqIEBwYXJhbSA8Y29kZT5lbmQ8L2NvZGU+LCB0aGUgc3RvcHBpbmcgcG9pbnQgb2Ygc2VhcmNoLCBleGNsdXNpdmUKCSAqIEBwYXJhbSA8Y29kZT5wPC9jb2RlPiwgYSBzaW1wbGUgcmVndWxhciBleHByZXNzaW9uIHRoYXQgbWF5IGNvbnRhaW5zICc/JwoJICogQHBhcmFtIDxjb2RlPmNhc2VJZ25vcmVkPC9jb2RlPiwgd2V0aGVyIHRoZSBwYXR0ZXJuIGlzIG5vdCBjYXNlc2Vuc2l0aXZlCgkgKiBAcmV0dXJuIHRoZSBzdGFydGluZyBpbmRleCBpbiB0aGUgdGV4dCBvZiB0aGUgcGF0dGVybiAsIG9yIC0xIGlmIG5vdCBmb3VuZCAKCSAqLwoJcHJvdGVjdGVkIGludCByZWdFeHBQb3NJbihTdHJpbmcgdGV4dCwgaW50IHN0YXJ0LCBpbnQgZW5kLCBTdHJpbmcgcCkgewoJCWludCBwbGVuPSBwLmxlbmd0aCgpOwoKCQlpbnQgbWF4PSBlbmQgLSBwbGVuOwoJCWZvciAoaW50IGk9IHN0YXJ0OyBpIDw9IG1heDsgKytpKSB7CgkJCWlmIChyZWdFeHBSZWdpb25NYXRjaGVzKHRleHQsIGksIHAsIDAsIHBsZW4pKQoJCQkJcmV0dXJuIGk7CgkJfQoJCXJldHVybiAtMTsKCX0KCgkvKioKCSAqIAoJICogQHJldHVybiBib29sZWFuCgkgKiBAcGFyYW0gPGNvZGU+dGV4dDwvY29kZT4sIGEgU3RyaW5nIHRvIG1hdGNoCgkgKiBAcGFyYW0gPGNvZGU+c3RhcnQ8L2NvZGU+LCBpbnQgdGhhdCBpbmRpY2F0ZXMgdGhlIHN0YXJ0aW5nIGluZGV4IG9mIG1hdGNoLCBpbmNsdXNpdmUKCSAqIEBwYXJhbSA8Y29kZT5lbmQ8L2NvZGU+IGludCB0aGF0IGluZGljYXRlcyB0aGUgZW5kaW5nIGluZGV4IG9mIG1hdGNoLCBleGNsdXNpdmUKCSAqIEBwYXJhbSA8Y29kZT5wPC9jb2RlPiwgU3RyaW5nLCAgU3RyaW5nLCBhIHNpbXBsZSByZWd1bGFyIGV4cHJlc3Npb24gdGhhdCBtYXkgY29udGFpbiAnPycKCSAqIEBwYXJhbSA8Y29kZT5pZ25vcmVDYXNlPC9jb2RlPiwgYm9vbGVhbiBpbmRpY2F0aW5nIHdldGhlciBjb2RlPnA8L2NvZGU+IGlzIGNhc2Ugc2Vuc2l0aXZlCgkgKi8KCXByb3RlY3RlZCBib29sZWFuIHJlZ0V4cFJlZ2lvbk1hdGNoZXMoU3RyaW5nIHRleHQsIGludCB0U3RhcnQsIFN0cmluZyBwLCBpbnQgcFN0YXJ0LCBpbnQgcGxlbikgewoJCXdoaWxlIChwbGVuLS0gPiAwKSB7CgkJCWNoYXIgdGNoYXI9IHRleHQuY2hhckF0KHRTdGFydCsrKTsKCQkJY2hhciBwY2hhcj0gcC5jaGFyQXQocFN0YXJ0KyspOwoKCQkJLyogcHJvY2VzcyB3aWxkIGNhcmRzICovCgkJCWlmICghZklnbm9yZVdpbGRDYXJkcykgewoJCQkJLyogc2tpcCBzaW5nbGUgd2lsZCBjYXJkcyAqLwoJCQkJaWYgKHBjaGFyID09IGZTaW5nbGVXaWxkQ2FyZCkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQl9CgkJCWlmIChwY2hhciA9PSB0Y2hhcikKCQkJCWNvbnRpbnVlOwoJCQlpZiAoZklnbm9yZUNhc2UpIHsKCQkJCWNoYXIgdGM9IENoYXJhY3Rlci50b1VwcGVyQ2FzZSh0Y2hhcik7CgkJCQlpZiAodGMgPT0gcGNoYXIpCgkJCQkJY29udGludWU7CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKiogCgkgKiBAcGFyYW0gPGNvZGU+dGV4dDwvY29kZT4sIHRoZSBzdHJpbmcgdG8gbWF0Y2gKCSAqIEBwYXJhbSA8Y29kZT5zdGFydDwvY29kZT4sIHRoZSBzdGFydGluZyBpbmRleCBpbiB0aGUgdGV4dCBmb3Igc2VhcmNoLCBpbmNsdXNpdmUKCSAqIEBwYXJhbSA8Y29kZT5lbmQ8L2NvZGU+LCB0aGUgc3RvcHBpbmcgcG9pbnQgb2Ygc2VhcmNoLCBleGNsdXNpdmUKCSAqIEBwYXJhbSBjb2RlPnA8L2NvZGU+LCBhIHN0cmluZyB0aGF0IGhhcyBubyB3aWxkY2FyZAoJICogQHBhcmFtIDxjb2RlPmlnbm9yZUNhc2U8L2NvZGU+LCBib29sZWFuIGluZGljYXRpbmcgd2V0aGVyIGNvZGU+cDwvY29kZT4gaXMgY2FzZSBzZW5zaXRpdmUKCSAqIEByZXR1cm4gdGhlIHN0YXJ0aW5nIGluZGV4IGluIHRoZSB0ZXh0IG9mIHRoZSBwYXR0ZXJuICwgb3IgLTEgaWYgbm90IGZvdW5kIAoJICovCglwcm90ZWN0ZWQgaW50IHRleHRQb3NJbihTdHJpbmcgdGV4dCwgaW50IHN0YXJ0LCBpbnQgZW5kLCBTdHJpbmcgcCkgewoKCQlpbnQgcGxlbj0gcC5sZW5ndGgoKTsKCQlpbnQgbWF4PSBlbmQgLSBwbGVuOwoKCQlpZiAoIWZJZ25vcmVDYXNlKSB7CgkJCWludCBpPSB0ZXh0LmluZGV4T2YocCwgc3RhcnQpOwoJCQlpZiAoaSA9PSAtMSB8fCBpID4gbWF4KQoJCQkJcmV0dXJuIC0xOwoJCQlyZXR1cm4gaTsKCQl9CgoJCWZvciAoaW50IGk9IHN0YXJ0OyBpIDw9IG1heDsgKytpKSB7CgkJCWlmICh0ZXh0LnJlZ2lvbk1hdGNoZXModHJ1ZSwgaSwgcCwgMCwgcGxlbikpCgkJCQlyZXR1cm4gaTsKCQl9CgoJCXJldHVybiAtMTsKCX0KfQ==