LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAzIElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIAogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC5kZWJ1Zy5jb3JlOwoKIAppbXBvcnQgamF2YS51dGlsLio7CgovKioKICogQSBzdHJpbmcgcGF0dGVybiBtYXRjaGVyLCBzdXBwcG9ydGluZyAqIGFuZCA/IHdpbGRjYXJkcy4KICovCnB1YmxpYyBjbGFzcyBTdHJpbmdNYXRjaGVyIHsKCXByb3RlY3RlZCBTdHJpbmcgZlBhdHRlcm47Cglwcm90ZWN0ZWQgaW50IGZMZW5ndGg7IC8vIHBhdHRlcm4gbGVuZ3RoCglwcm90ZWN0ZWQgYm9vbGVhbiBmSWdub3JlV2lsZENhcmRzOwoJcHJvdGVjdGVkIGJvb2xlYW4gZklnbm9yZUNhc2U7Cglwcm90ZWN0ZWQgYm9vbGVhbiBmSGFzTGVhZGluZ1N0YXI7Cglwcm90ZWN0ZWQgYm9vbGVhbiBmSGFzVHJhaWxpbmdTdGFyOwoJcHJvdGVjdGVkIFN0cmluZyBmU2VnbWVudHNbXTsgLy90aGUgZ2l2ZW4gcGF0dGVybiBpcyBzcGxpdCBpbnRvICogc2VwYXJhdGVkIHNlZ21lbnRzCgoJLyogYm91bmRhcnkgdmFsdWUgYmV5b25kIHdoaWNoIHdlIGRvbid0IG5lZWQgdG8gc2VhcmNoIGluIHRoZSB0ZXh0ICovCglwcm90ZWN0ZWQgaW50IGZCb3VuZD0gMDsKCQoKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgY2hhciBmU2luZ2xlV2lsZENhcmQ9ICdcdTAwMDAnOwoJCglwdWJsaWMgc3RhdGljIGNsYXNzIFBvc2l0aW9uIHsKCQlpbnQgc3RhcnQ7IC8vaW5jbHVzaXZlCgkJaW50IGVuZDsgLy9leGNsdXNpdmUKCQlwdWJsaWMgUG9zaXRpb24oaW50IHN0YXJ0LCBpbnQgZW5kKSB7CgkJCXRoaXMuc3RhcnQ9IHN0YXJ0OwoJCQl0aGlzLmVuZD0gZW5kOwoJCX0KCQlwdWJsaWMgaW50IGdldFN0YXJ0KCkgewoJCQlyZXR1cm4gc3RhcnQ7CgkJfQoJCXB1YmxpYyBpbnQgZ2V0RW5kKCkgewoJCQlyZXR1cm4gZW5kOwoJCX0KCX0KCS8qKgoJICogU3RyaW5nTWF0Y2hlciBjb25zdHJ1Y3RvciB0YWtlcyBpbiBhIFN0cmluZyBvYmplY3QgdGhhdCBpcyBhIHNpbXBsZSAKCSAqIHBhdHRlcm4gd2hpY2ggbWF5IGNvbnRhaW4gJyonIGZvciAwIGFuZCBtYW55IGNoYXJhY3RlcnMgYW5kCgkgKiAnPycgZm9yIGV4YWN0bHkgb25lIGNoYXJhY3Rlci4gIAoJICoKCSAqIExpdGVyYWwgJyonIGFuZCAnPycgY2hhcmFjdGVycyBtdXN0IGJlIGVzY2FwZWQgaW4gdGhlIHBhdHRlcm4gCgkgKiBlLmcuLCAiXCoiIG1lYW5zIGxpdGVyYWwgIioiLCBldGMuCgkgKgoJICogRXNjYXBpbmcgYW55IG90aGVyIGNoYXJhY3RlciAoaW5jbHVkaW5nIHRoZSBlc2NhcGUgY2hhcmFjdGVyIGl0c2VsZiksIAoJICoganVzdCByZXN1bHRzIGluIHRoYXQgY2hhcmFjdGVyIGluIHRoZSBwYXR0ZXJuLgoJICogZS5nLiwgIlxhIiBtZWFucyAiYSIgYW5kICJcXCIgbWVhbnMgIlwiCgkgKgoJICogSWYgaW52b2tpbmcgdGhlIFN0cmluZ01hdGNoZXIgd2l0aCBzdHJpbmcgbGl0ZXJhbHMgaW4gSmF2YSwgZG9uJ3QgZm9yZ2V0CgkgKiBlc2NhcGUgY2hhcmFjdGVycyBhcmUgcmVwcmVzZW50ZWQgYnkgIlxcIi4KCSAqCgkgKiBAcGFyYW0gcGF0dGVybiB0aGUgcGF0dGVybiB0byBtYXRjaCB0ZXh0IGFnYWluc3QKCSAqIEBwYXJhbSBpZ25vcmVDYXNlIGlmIHRydWUsIGNhc2UgaXMgaWdub3JlZAoJICogQHBhcmFtIGlnbm9yZVdpbGRDYXJkcyBpZiB0cnVlLCB3aWxkIGNhcmRzIGFuZCB0aGVpciBlc2NhcGUgc2VxdWVuY2VzIGFyZSBpZ25vcmVkCgkgKiAJCSAgKGV2ZXJ5dGhpbmcgaXMgdGFrZW4gbGl0ZXJhbGx5KS4KCSAqLwoJcHVibGljIFN0cmluZ01hdGNoZXIoU3RyaW5nIHBhdHRlcm4sIGJvb2xlYW4gaWdub3JlQ2FzZSwgYm9vbGVhbiBpZ25vcmVXaWxkQ2FyZHMpIHsKCQlpZiAocGF0dGVybiA9PSBudWxsKQoJCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CgkJZklnbm9yZUNhc2U9IGlnbm9yZUNhc2U7CgkJZklnbm9yZVdpbGRDYXJkcz0gaWdub3JlV2lsZENhcmRzOwoJCWZQYXR0ZXJuPSBwYXR0ZXJuOwoJCWZMZW5ndGg9IHBhdHRlcm4ubGVuZ3RoKCk7CgkJCgkJaWYgKGZJZ25vcmVXaWxkQ2FyZHMpIHsKCQkJcGFyc2VOb1dpbGRDYXJkcygpOwoJCX0gZWxzZSB7CgkJCXBhcnNlV2lsZENhcmRzKCk7CgkJfQoJfQoJLyoqCgkgKiBGaW5kIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBwYXR0ZXJuIGJldHdlZW4gPGNvZGU+c3RhcnQ8L2NvZGUpKGluY2x1c2l2ZSkgCgkgKiBhbmQgPGNvZGU+ZW5kPC9jb2RlPihleGNsdXNpdmUpLiAgCgkgKiBAcGFyYW0gPGNvZGU+dGV4dDwvY29kZT4sIHRoZSBTdHJpbmcgb2JqZWN0IHRvIHNlYXJjaCBpbiAKCSAqIEBwYXJhbSA8Y29kZT5zdGFydDwvY29kZT4sIHRoZSBzdGFydGluZyBpbmRleCBvZiB0aGUgc2VhcmNoIHJhbmdlLCBpbmNsdXNpdmUKCSAqIEBwYXJhbSA8Y29kZT5lbmQ8L2NvZGU+LCB0aGUgZW5kaW5nIGluZGV4IG9mIHRoZSBzZWFyY2ggcmFuZ2UsIGV4Y2x1c2l2ZQoJICogQHJldHVybiBhbiA8Y29kZT5TdHJpbmdNYXRjaGVyLlBvc2l0aW9uPC9jb2RlPiBvYmplY3QgdGhhdCBrZWVwcyB0aGUgc3RhcnRpbmcgCgkgKiAoaW5jbHVzaXZlKSBhbmQgZW5kaW5nIHBvc2l0aW9ucyAoZXhjbHVzaXZlKSBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgCgkgKiBwYXR0ZXJuIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhlIHRleHQ7IHJldHVybiBudWxsIGlmIG5vdCBmb3VuZCBvciBzdWJ0ZXh0CgkgKiBpcyBlbXB0eSAoc3RhcnQ9PWVuZCkuIEEgcGFpciBvZiB6ZXJvcyBpcyByZXR1cm5lZCBpZiBwYXR0ZXJuIGlzIGVtcHR5IHN0cmluZwoJICogTm90ZSB0aGF0IGZvciBwYXR0ZXJuIGxpa2UgIiphYmMqIiB3aXRoIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHN0YXJzLCBwb3NpdGlvbiBvZiAiYWJjIgoJICogaXMgcmV0dXJuZWQuIEZvciBhIHBhdHRlcm4gbGlrZSIqPz8qIiBpbiB0ZXh0ICJhYmNkZiIsICgxLDMpIGlzIHJldHVybmVkCgkgKi8KCXB1YmxpYyBTdHJpbmdNYXRjaGVyLlBvc2l0aW9uIGZpbmQoU3RyaW5nIHRleHQsIGludCBzdGFydCwgaW50IGVuZCkgewoJCWlmICh0ZXh0ID09IG51bGwpCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCQkJCgkJaW50IHRsZW49IHRleHQubGVuZ3RoKCk7CgkJaWYgKHN0YXJ0IDwgMCkKCQkJc3RhcnQ9IDA7CgkJaWYgKGVuZCA+IHRsZW4pCgkJCWVuZD0gdGxlbjsKCQlpZiAoZW5kIDwgMCB8fHN0YXJ0ID49IGVuZCApCgkJCXJldHVybiBudWxsOwoJCWlmIChmTGVuZ3RoID09IDApCgkJCXJldHVybiBuZXcgUG9zaXRpb24oc3RhcnQsIHN0YXJ0KTsKCQlpZiAoZklnbm9yZVdpbGRDYXJkcykgewoJCQlpbnQgeD0gcG9zSW4odGV4dCwgc3RhcnQsIGVuZCk7CgkJCWlmICh4IDwgMCkKCQkJCXJldHVybiBudWxsOwoJCQlyZXR1cm4gbmV3IFBvc2l0aW9uKHgsIHgrZkxlbmd0aCk7CgkJfQoKCQlpbnQgc2VnQ291bnQ9IGZTZWdtZW50cy5sZW5ndGg7CgkJaWYgKHNlZ0NvdW50ID09IDApLy9wYXR0ZXJuIGNvbnRhaW5zIG9ubHkgJyonKHMpCgkJCXJldHVybiBuZXcgUG9zaXRpb24gKHN0YXJ0LCBlbmQpOwoJCQkJCQoJCWludCBjdXJQb3M9IHN0YXJ0OwoJCWludCBtYXRjaFN0YXJ0PSAtMTsKCQlpbnQgaTsKCQlmb3IgKGk9IDA7IGkgPCBzZWdDb3VudCAmJiBjdXJQb3MgPCBlbmQ7ICsraSkgewoJCQlTdHJpbmcgY3VycmVudD0gZlNlZ21lbnRzW2ldOwoJCQlpbnQgbmV4dE1hdGNoPSByZWdFeHBQb3NJbih0ZXh0LCBjdXJQb3MsIGVuZCwgY3VycmVudCk7CgkJCWlmIChuZXh0TWF0Y2ggPCAwICkKCQkJCXJldHVybiBudWxsOwoJCQlpZihpID09IDApCgkJCQltYXRjaFN0YXJ0PSBuZXh0TWF0Y2g7CgkJCWN1clBvcz0gbmV4dE1hdGNoICsgY3VycmVudC5sZW5ndGgoKTsKCQl9CgkJaWYgKGkgPCBzZWdDb3VudCkKCQkJcmV0dXJuIG51bGw7CgkJcmV0dXJuIG5ldyBQb3NpdGlvbihtYXRjaFN0YXJ0LCBjdXJQb3MpOwoJfQoJLyoqCgkgKiBtYXRjaCB0aGUgZ2l2ZW4gPGNvZGU+dGV4dDwvY29kZT4gd2l0aCB0aGUgcGF0dGVybiAKCSAqIEByZXR1cm4gdHJ1ZSBpZiBtYXRjaGVkIGVpdGhlcndpc2UgZmFsc2UKCSAqIEBwYXJhbSA8Y29kZT50ZXh0PC9jb2RlPiwgYSBTdHJpbmcgb2JqZWN0IAoJICovCglwdWJsaWMgYm9vbGVhbiBtYXRjaChTdHJpbmcgdGV4dCkgewoJCXJldHVybiBtYXRjaCh0ZXh0LCAwLCB0ZXh0Lmxlbmd0aCgpKTsKCX0KCS8qKgoJICogR2l2ZW4gdGhlIHN0YXJ0aW5nIChpbmNsdXNpdmUpIGFuZCB0aGUgZW5kaW5nIChleGNsdXNpdmUpIHBvc2l0aW9ucyBpbiB0aGUgICAKCSAqIDxjb2RlPnRleHQ8L2NvZGU+LCBkZXRlcm1pbmUgaWYgdGhlIGdpdmVuIHN1YnN0cmluZyBtYXRjaGVzIHdpdGggYVBhdHRlcm4gIAoJICogQHJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgcG9ydGlvbiBvZiB0aGUgdGV4dCBtYXRjaGVzIHRoZSBwYXR0ZXJuCgkgKiBAcGFyYW0gU3RyaW5nIDxjb2RlPnRleHQ8L2NvZGU+LCBhIFN0cmluZyBvYmplY3QgdGhhdCBjb250YWlucyB0aGUgc3Vic3RyaW5nIHRvIG1hdGNoIAoJICogQHBhcmFtIGludCA8Y29kZT5zdGFydDxjb2RlPiBtYXJrcyB0aGUgc3RhcnRpbmcgcG9zaXRpb24gKGluY2x1c2l2ZSkgb2YgdGhlIHN1YnN0cmluZwoJICogQHBhcmFtIGludCA8Y29kZT5lbmQ8Y29kZT4gbWFya3MgdGhlIGVuZGluZyBpbmRleCAoZXhjbHVzaXZlKSBvZiB0aGUgc3Vic3RyaW5nIAoJICovCglwdWJsaWMgYm9vbGVhbiBtYXRjaChTdHJpbmcgdGV4dCwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7CgkJaWYgKG51bGwgPT0gdGV4dCkKCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoKCQlpZiAoc3RhcnQgPiBlbmQpCgkJCXJldHVybiBmYWxzZTsKCgkJaWYgKGZJZ25vcmVXaWxkQ2FyZHMpCgkJCXJldHVybiAoZW5kIC0gc3RhcnQgPT0gZkxlbmd0aCkgJiYgZlBhdHRlcm4ucmVnaW9uTWF0Y2hlcyhmSWdub3JlQ2FzZSwgMCwgdGV4dCwgc3RhcnQsIGZMZW5ndGgpOwoJCWludCBzZWdDb3VudD0gZlNlZ21lbnRzLmxlbmd0aDsKCQlpZiAoc2VnQ291bnQgPT0gMCAmJiAoZkhhc0xlYWRpbmdTdGFyIHx8IGZIYXNUcmFpbGluZ1N0YXIpKSAgLy8gcGF0dGVybiBjb250YWlucyBvbmx5ICcqJyhzKQoJCQlyZXR1cm4gdHJ1ZTsKCQlpZiAoc3RhcnQgPT0gZW5kKQoJCQlyZXR1cm4gZkxlbmd0aCA9PSAwOwoJCWlmIChmTGVuZ3RoID09IDApCgkJCXJldHVybiBzdGFydCA9PSBlbmQ7CgoJCWludCB0bGVuPSB0ZXh0Lmxlbmd0aCgpOwoJCWlmIChzdGFydCA8IDApCgkJCXN0YXJ0PSAwOwoJCWlmIChlbmQgPiB0bGVuKQoJCQllbmQ9IHRsZW47CgoJCWludCB0Q3VyUG9zPSBzdGFydDsKCQlpbnQgYm91bmQ9IGVuZCAtIGZCb3VuZDsKCQlpZiAoIGJvdW5kIDwgMCkKCQkJcmV0dXJuIGZhbHNlOwoJCWludCBpPTA7CgkJU3RyaW5nIGN1cnJlbnQ9IGZTZWdtZW50c1tpXTsKCQlpbnQgc2VnTGVuZ3RoPSBjdXJyZW50Lmxlbmd0aCgpOwoKCQkvKiBwcm9jZXNzIGZpcnN0IHNlZ21lbnQgKi8KCQlpZiAoIWZIYXNMZWFkaW5nU3Rhcil7CgkJCWlmKCFyZWdFeHBSZWdpb25NYXRjaGVzKHRleHQsIHN0YXJ0LCBjdXJyZW50LCAwLCBzZWdMZW5ndGgpKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0gZWxzZSB7CgkJCQkrK2k7CgkJCQl0Q3VyUG9zPSB0Q3VyUG9zICsgc2VnTGVuZ3RoOwoJCQl9CgkJfQoJCWlmICgoZlNlZ21lbnRzLmxlbmd0aCA9PSAxKSAmJiAoIWZIYXNMZWFkaW5nU3RhcikgJiYgKCFmSGFzVHJhaWxpbmdTdGFyKSkgewoJCQkvLyBvbmx5IG9uZSBzZWdtZW50IHRvIG1hdGNoLCBubyB3aWxkY2FyZHMgc3BlY2lmaWVkCgkJCXJldHVybiB0Q3VyUG9zID09IGVuZDsKCQl9CgkJLyogcHJvY2VzcyBtaWRkbGUgc2VnbWVudHMgKi8KCQl3aGlsZSAoaSA8IHNlZ0NvdW50KSB7CgkJCWN1cnJlbnQ9IGZTZWdtZW50c1tpXTsKCQkJaW50IGN1cnJlbnRNYXRjaDsKCQkJaW50IGs9IGN1cnJlbnQuaW5kZXhPZihmU2luZ2xlV2lsZENhcmQpOwoJCQlpZiAoayA8IDApIHsKCQkJCWN1cnJlbnRNYXRjaD0gdGV4dFBvc0luKHRleHQsIHRDdXJQb3MsIGVuZCwgY3VycmVudCk7CgkJCQlpZiAoY3VycmVudE1hdGNoIDwgMCkKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCX0gZWxzZSB7CgkJCQljdXJyZW50TWF0Y2g9IHJlZ0V4cFBvc0luKHRleHQsIHRDdXJQb3MsIGVuZCwgY3VycmVudCk7CgkJCQlpZiAoY3VycmVudE1hdGNoIDwgMCkKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQkJdEN1clBvcz0gY3VycmVudE1hdGNoICsgY3VycmVudC5sZW5ndGgoKTsKCQkJaSsrOwoJCX0KCgkJLyogcHJvY2VzcyBmaW5hbCBzZWdtZW50ICovCgkJaWYgKCFmSGFzVHJhaWxpbmdTdGFyICYmIHRDdXJQb3MgIT0gZW5kKSB7CgkJCWludCBjbGVuPSBjdXJyZW50Lmxlbmd0aCgpOwoJCQlyZXR1cm4gcmVnRXhwUmVnaW9uTWF0Y2hlcyh0ZXh0LCBlbmQgLSBjbGVuLCBjdXJyZW50LCAwLCBjbGVuKTsKCQl9CgkJcmV0dXJuIGkgPT0gc2VnQ291bnQgOwoJfQoKCS8qKgoJICogVGhpcyBtZXRob2QgcGFyc2VzIHRoZSBnaXZlbiBwYXR0ZXJuIGludG8gc2VnbWVudHMgc2VwZXJhdGVkIGJ5IHdpbGRjYXJkICcqJyBjaGFyYWN0ZXJzLgoJICogU2luY2Ugd2lsZGNhcmRzIGFyZSBub3QgYmVpbmcgdXNlZCBpbiB0aGlzIGNhc2UsIHRoZSBwYXR0ZXJuIGNvbnNpc3RzIG9mIGEgc2luZ2xlIHNlZ21lbnQuCgkgKi8KCXByaXZhdGUgdm9pZCBwYXJzZU5vV2lsZENhcmRzKCkgewoJCWZTZWdtZW50cz0gbmV3IFN0cmluZ1sxXTsKCQlmU2VnbWVudHNbMF09IGZQYXR0ZXJuOwoJCWZCb3VuZD0gZkxlbmd0aDsKCX0KCS8qKgoJICogUGFyc2VzIHRoZSBnaXZlbiBwYXR0ZXJuIGludG8gc2VnbWVudHMgc2VwZXJhdGVkIGJ5IHdpbGRjYXJkICcqJyBjaGFyYWN0ZXJzLgoJICogQHBhcmFtIHAsIGEgU3RyaW5nIG9iamVjdCB0aGF0IGlzIGEgc2ltcGxlIHJlZ3VsYXIgZXhwcmVzc2lvbiB3aXRoIJEqkiBhbmQvb3IgkT+SCgkgKi8KCXByaXZhdGUgdm9pZCBwYXJzZVdpbGRDYXJkcygpIHsKCQlpZihmUGF0dGVybi5zdGFydHNXaXRoKCIqIikpLy8kTk9OLU5MUy0xJAoJCQlmSGFzTGVhZGluZ1N0YXI9IHRydWU7CgkJaWYoZlBhdHRlcm4uZW5kc1dpdGgoIioiKSkgey8vJE5PTi1OTFMtMSQKCQkJLyogbWFrZSBzdXJlIGl0J3Mgbm90IGFuIGVzY2FwZWQgd2lsZGNhcmQgKi8KCQkJaWYgKGZMZW5ndGggPiAxICYmIGZQYXR0ZXJuLmNoYXJBdChmTGVuZ3RoIC0gMikgIT0gJ1xcJykgewoJCQkJZkhhc1RyYWlsaW5nU3Rhcj0gdHJ1ZTsKCQkJfQoJCX0KCgkJVmVjdG9yIHRlbXA9IG5ldyBWZWN0b3IoKTsKCgkJaW50IHBvcz0gMDsKCQlTdHJpbmdCdWZmZXIgYnVmPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkJd2hpbGUgKHBvcyA8IGZMZW5ndGgpIHsKCQkJY2hhciBjPSBmUGF0dGVybi5jaGFyQXQocG9zKyspOwoJCQlzd2l0Y2ggKGMpIHsKCQkJCWNhc2UgJ1xcJzoKCQkJCQlpZiAocG9zID49IGZMZW5ndGgpIHsKCQkJCQkJYnVmLmFwcGVuZChjKTsKCQkJCQl9IGVsc2UgewoJCQkJCQljaGFyIG5leHQ9IGZQYXR0ZXJuLmNoYXJBdChwb3MrKyk7CgkJCQkJCS8qIGlmIGl0J3MgYW4gZXNjYXBlIHNlcXVlbmNlICovCgkJCQkJCWlmIChuZXh0ID09ICcqJyB8fCBuZXh0ID09ICc/JyB8fCBuZXh0ID09ICdcXCcpIHsKCQkJCQkJCWJ1Zi5hcHBlbmQobmV4dCk7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQkvKiBub3QgYW4gZXNjYXBlIHNlcXVlbmNlLCBqdXN0IGluc2VydCBsaXRlcmFsbHkgKi8KCQkJCQkJCWJ1Zi5hcHBlbmQoYyk7CgkJCQkJCQlidWYuYXBwZW5kKG5leHQpOwoJCQkJCQl9CgkJCQkJfQoJCQkJYnJlYWs7CgkJCQljYXNlICcqJzoKCQkJCQlpZiAoYnVmLmxlbmd0aCgpID4gMCkgewoJCQkJCQkvKiBuZXcgc2VnbWVudCAqLwoJCQkJCQl0ZW1wLmFkZEVsZW1lbnQoYnVmLnRvU3RyaW5nKCkpOwoJCQkJCQlmQm91bmQgKz0gYnVmLmxlbmd0aCgpOwoJCQkJCQlidWYuc2V0TGVuZ3RoKDApOwoJCQkJCX0KCQkJCWJyZWFrOwoJCQkJY2FzZSAnPyc6CgkJCQkJLyogYXBwZW5kIHNwZWNpYWwgY2hhcmFjdGVyIHJlcHJlc2VudGluZyBzaW5nbGUgbWF0Y2ggd2lsZGNhcmQgKi8KCQkJCQlidWYuYXBwZW5kKGZTaW5nbGVXaWxkQ2FyZCk7CgkJCQlicmVhazsKCQkJCWRlZmF1bHQ6CgkJCQkJYnVmLmFwcGVuZChjKTsKCQkJfQoJCX0KCgkJLyogYWRkIGxhc3QgYnVmZmVyIHRvIHNlZ21lbnQgbGlzdCAqLwoJCWlmIChidWYubGVuZ3RoKCkgPiAwKSB7CgkJCXRlbXAuYWRkRWxlbWVudChidWYudG9TdHJpbmcoKSk7CgkJCWZCb3VuZCArPSBidWYubGVuZ3RoKCk7CgkJfQoJCQkKCQlmU2VnbWVudHM9IG5ldyBTdHJpbmdbdGVtcC5zaXplKCldOwoJCXRlbXAuY29weUludG8oZlNlZ21lbnRzKTsKCX0KCS8qKiAKCSAqIEBwYXJhbSA8Y29kZT50ZXh0PC9jb2RlPiwgYSBzdHJpbmcgd2hpY2ggY29udGFpbnMgbm8gd2lsZGNhcmQKCSAqIEBwYXJhbSA8Y29kZT5zdGFydDwvY29kZT4sIHRoZSBzdGFydGluZyBpbmRleCBpbiB0aGUgdGV4dCBmb3Igc2VhcmNoLCBpbmNsdXNpdmUKCSAqIEBwYXJhbSA8Y29kZT5lbmQ8L2NvZGU+LCB0aGUgc3RvcHBpbmcgcG9pbnQgb2Ygc2VhcmNoLCBleGNsdXNpdmUKCSAqIEByZXR1cm4gdGhlIHN0YXJ0aW5nIGluZGV4IGluIHRoZSB0ZXh0IG9mIHRoZSBwYXR0ZXJuICwgb3IgLTEgaWYgbm90IGZvdW5kIAoJICovCglwcm90ZWN0ZWQgaW50IHBvc0luKFN0cmluZyB0ZXh0LCBpbnQgc3RhcnQsIGludCBlbmQpIHsvL25vIHdpbGQgY2FyZCBpbiBwYXR0ZXJuCgkJaW50IG1heD0gZW5kIC0gZkxlbmd0aDsKCQkKCQlpZiAoIWZJZ25vcmVDYXNlKSB7CgkJCWludCBpPSB0ZXh0LmluZGV4T2YoZlBhdHRlcm4sIHN0YXJ0KTsKCQkJaWYgKGkgPT0gLTEgfHwgaSA+IG1heCkKCQkJCXJldHVybiAtMTsKCQkJcmV0dXJuIGk7CgkJfQoJCQoJCWZvciAoaW50IGk9IHN0YXJ0OyBpIDw9IG1heDsgKytpKSB7CgkJCWlmICh0ZXh0LnJlZ2lvbk1hdGNoZXModHJ1ZSwgaSwgZlBhdHRlcm4sIDAsIGZMZW5ndGgpKQoJCQkJcmV0dXJuIGk7CgkJfQoJCQoJCXJldHVybiAtMTsKCX0KCS8qKiAKCSAqIEBwYXJhbSA8Y29kZT50ZXh0PC9jb2RlPiwgYSBzaW1wbGUgcmVndWxhciBleHByZXNzaW9uIHRoYXQgbWF5IG9ubHkgY29udGFpbiAnPycocykKCSAqIEBwYXJhbSA8Y29kZT5zdGFydDwvY29kZT4sIHRoZSBzdGFydGluZyBpbmRleCBpbiB0aGUgdGV4dCBmb3Igc2VhcmNoLCBpbmNsdXNpdmUKCSAqIEBwYXJhbSA8Y29kZT5lbmQ8L2NvZGU+LCB0aGUgc3RvcHBpbmcgcG9pbnQgb2Ygc2VhcmNoLCBleGNsdXNpdmUKCSAqIEBwYXJhbSA8Y29kZT5wPC9jb2RlPiwgYSBzaW1wbGUgcmVndWxhciBleHByZXNzaW9uIHRoYXQgbWF5IGNvbnRhaW5zICc/JwoJICogQHBhcmFtIDxjb2RlPmNhc2VJZ25vcmVkPC9jb2RlPiwgd2V0aGVyIHRoZSBwYXR0ZXJuIGlzIG5vdCBjYXNlc2Vuc2l0aXZlCgkgKiBAcmV0dXJuIHRoZSBzdGFydGluZyBpbmRleCBpbiB0aGUgdGV4dCBvZiB0aGUgcGF0dGVybiAsIG9yIC0xIGlmIG5vdCBmb3VuZCAKCSAqLwoJcHJvdGVjdGVkIGludCByZWdFeHBQb3NJbihTdHJpbmcgdGV4dCwgaW50IHN0YXJ0LCBpbnQgZW5kLCBTdHJpbmcgcCkgewoJCWludCBwbGVuPSBwLmxlbmd0aCgpOwoJCQoJCWludCBtYXg9IGVuZCAtIHBsZW47CgkJZm9yIChpbnQgaT0gc3RhcnQ7IGkgPD0gbWF4OyArK2kpIHsKCQkJaWYgKHJlZ0V4cFJlZ2lvbk1hdGNoZXModGV4dCwgaSwgcCwgMCwgcGxlbikpCgkJCQlyZXR1cm4gaTsKCQl9CgkJcmV0dXJuIC0xOwoJfQoJLyoqCgkgKiAKCSAqIEByZXR1cm4gYm9vbGVhbgoJICogQHBhcmFtIDxjb2RlPnRleHQ8L2NvZGU+LCBhIFN0cmluZyB0byBtYXRjaAoJICogQHBhcmFtIDxjb2RlPnN0YXJ0PC9jb2RlPiwgaW50IHRoYXQgaW5kaWNhdGVzIHRoZSBzdGFydGluZyBpbmRleCBvZiBtYXRjaCwgaW5jbHVzaXZlCgkgKiBAcGFyYW0gPGNvZGU+ZW5kPC9jb2RlPiBpbnQgdGhhdCBpbmRpY2F0ZXMgdGhlIGVuZGluZyBpbmRleCBvZiBtYXRjaCwgZXhjbHVzaXZlCgkgKiBAcGFyYW0gPGNvZGU+cDwvY29kZT4sIFN0cmluZywgIFN0cmluZywgYSBzaW1wbGUgcmVndWxhciBleHByZXNzaW9uIHRoYXQgbWF5IGNvbnRhaW4gJz8nCgkgKiBAcGFyYW0gPGNvZGU+aWdub3JlQ2FzZTwvY29kZT4sIGJvb2xlYW4gaW5kaWNhdGluZyB3ZXRoZXIgY29kZT5wPC9jb2RlPiBpcyBjYXNlIHNlbnNpdGl2ZQoJICovCglwcm90ZWN0ZWQgYm9vbGVhbiByZWdFeHBSZWdpb25NYXRjaGVzKFN0cmluZyB0ZXh0LCBpbnQgdFN0YXJ0LCBTdHJpbmcgcCwgaW50IHBTdGFydCwgaW50IHBsZW4pIHsKCQl3aGlsZSAocGxlbi0tID4gMCkgewoJCQljaGFyIHRjaGFyPSB0ZXh0LmNoYXJBdCh0U3RhcnQrKyk7CgkJCWNoYXIgcGNoYXI9IHAuY2hhckF0KHBTdGFydCsrKTsKCgkJCS8qIHByb2Nlc3Mgd2lsZCBjYXJkcyAqLwoJCQlpZiAoIWZJZ25vcmVXaWxkQ2FyZHMpIHsKCQkJCS8qIHNraXAgc2luZ2xlIHdpbGQgY2FyZHMgKi8KCQkJCWlmIChwY2hhciA9PSBmU2luZ2xlV2lsZENhcmQpIHsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJfQoJCQlpZiAocGNoYXIgPT0gdGNoYXIpCgkJCQljb250aW51ZTsKCQkJaWYgKGZJZ25vcmVDYXNlKSB7CgkJCQlpZiAoQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKHRjaGFyKSA9PSBDaGFyYWN0ZXIudG9VcHBlckNhc2UocGNoYXIpKQoJCQkJCWNvbnRpbnVlOwoJCQkJLy8gY29tcGFyaW5nIGFmdGVyIGNvbnZlcnRpbmcgdG8gdXBwZXIgY2FzZSBkb2Vzbid0IGhhbmRsZSBhbGwgY2FzZXM7CgkJCQkvLyBhbHNvIGNvbXBhcmUgYWZ0ZXIgY29udmVydGluZyB0byBsb3dlciBjYXNlCgkJCQlpZiAoQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKHRjaGFyKSA9PSBDaGFyYWN0ZXIudG9Mb3dlckNhc2UocGNoYXIpKQoJCQkJCWNvbnRpbnVlOwoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJcmV0dXJuIHRydWU7Cgl9CgkvKiogCgkgKiBAcGFyYW0gPGNvZGU+dGV4dDwvY29kZT4sIHRoZSBzdHJpbmcgdG8gbWF0Y2gKCSAqIEBwYXJhbSA8Y29kZT5zdGFydDwvY29kZT4sIHRoZSBzdGFydGluZyBpbmRleCBpbiB0aGUgdGV4dCBmb3Igc2VhcmNoLCBpbmNsdXNpdmUKCSAqIEBwYXJhbSA8Y29kZT5lbmQ8L2NvZGU+LCB0aGUgc3RvcHBpbmcgcG9pbnQgb2Ygc2VhcmNoLCBleGNsdXNpdmUKCSAqIEBwYXJhbSBjb2RlPnA8L2NvZGU+LCBhIHN0cmluZyB0aGF0IGhhcyBubyB3aWxkY2FyZAoJICogQHBhcmFtIDxjb2RlPmlnbm9yZUNhc2U8L2NvZGU+LCBib29sZWFuIGluZGljYXRpbmcgd2V0aGVyIGNvZGU+cDwvY29kZT4gaXMgY2FzZSBzZW5zaXRpdmUKCSAqIEByZXR1cm4gdGhlIHN0YXJ0aW5nIGluZGV4IGluIHRoZSB0ZXh0IG9mIHRoZSBwYXR0ZXJuICwgb3IgLTEgaWYgbm90IGZvdW5kIAoJICovCglwcm90ZWN0ZWQgaW50IHRleHRQb3NJbihTdHJpbmcgdGV4dCwgaW50IHN0YXJ0LCBpbnQgZW5kLCBTdHJpbmcgcCkgeyAKCQkKCQlpbnQgcGxlbj0gcC5sZW5ndGgoKTsKCQlpbnQgbWF4PSBlbmQgLSBwbGVuOwoJCQoJCWlmICghZklnbm9yZUNhc2UpIHsKCQkJaW50IGk9IHRleHQuaW5kZXhPZihwLCBzdGFydCk7CgkJCWlmIChpID09IC0xIHx8IGkgPiBtYXgpCgkJCQlyZXR1cm4gLTE7CgkJCXJldHVybiBpOwoJCX0KCQkKCQlmb3IgKGludCBpPSBzdGFydDsgaSA8PSBtYXg7ICsraSkgewoJCQlpZiAodGV4dC5yZWdpb25NYXRjaGVzKHRydWUsIGksIHAsIDAsIHBsZW4pKQoJCQkJcmV0dXJuIGk7CgkJfQoJCQoJCXJldHVybiAtMTsKCX0KfQo=