cGFja2FnZSBvcmcuZWNsaXBzZS51aS52aWV3cy5uYXZpZ2F0b3I7DQoNCi8qDQogKiAoYykgQ29weXJpZ2h0IElCTSBDb3JwLiAyMDAwLCAyMDAxLg0KICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4NCiAqLw0KaW1wb3J0IGphdmEudXRpbC4qOw0KDQovKioNCiAqIEEgc3RyaW5nIHBhdHRlcm4gbWF0Y2hlciwgc3VwcHBvcnRpbmcgKiBhbmQgPyB3aWxkY2FyZHMuDQogKi8NCi8qIHBhY2thZ2UgKi8gY2xhc3MgU3RyaW5nTWF0Y2hlciB7DQoJcHJvdGVjdGVkIFN0cmluZyBmUGF0dGVybjsNCglwcm90ZWN0ZWQgaW50IGZMZW5ndGg7IC8vIHBhdHRlcm4gbGVuZ3RoDQoJcHJvdGVjdGVkIGJvb2xlYW4gZklnbm9yZVdpbGRDYXJkczsNCglwcm90ZWN0ZWQgYm9vbGVhbiBmSWdub3JlQ2FzZTsNCglwcm90ZWN0ZWQgYm9vbGVhbiBmSGFzTGVhZGluZ1N0YXI7DQoJcHJvdGVjdGVkIGJvb2xlYW4gZkhhc1RyYWlsaW5nU3RhcjsNCglwcm90ZWN0ZWQgU3RyaW5nIGZTZWdtZW50c1tdOyAvL3RoZSBnaXZlbiBwYXR0ZXJuIGlzIHNwbGl0IGludG8gKiBzZXBhcmF0ZWQgc2VnbWVudHMNCg0KCS8qIGJvdW5kYXJ5IHZhbHVlIGJleW9uZCB3aGljaCB3ZSBkb24ndCBuZWVkIHRvIHNlYXJjaCBpbiB0aGUgdGV4dCAqLw0KCXByb3RlY3RlZCBpbnQgZkJvdW5kID0gMDsNCgkNCg0KCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgY2hhciBmU2luZ2xlV2lsZENhcmQgPSAnXHUwMDAwJzsNCgkNCglwdWJsaWMgc3RhdGljIGNsYXNzIFBvc2l0aW9uIHsNCgkJaW50IHN0YXJ0OyAvL2luY2x1c2l2ZQ0KCQlpbnQgZW5kOyAvL2V4Y2x1c2l2ZQ0KCQlwdWJsaWMgUG9zaXRpb24oaW50IHN0YXJ0LCBpbnQgZW5kKSB7DQoJCQl0aGlzLnN0YXJ0ID0gc3RhcnQ7DQoJCQl0aGlzLmVuZCA9IGVuZDsNCgkJfQ0KCQlwdWJsaWMgaW50IGdldFN0YXJ0KCkgew0KCQkJcmV0dXJuIHN0YXJ0Ow0KCQl9DQoJCXB1YmxpYyBpbnQgZ2V0RW5kKCkgew0KCQkJcmV0dXJuIGVuZDsNCgkJfQ0KCX0NCgkvKioNCgkgKiBTdHJpbmdNYXRjaGVyIGNvbnN0cnVjdG9yIHRha2VzIGluIGEgU3RyaW5nIG9iamVjdCB0aGF0IGlzIGEgc2ltcGxlIA0KCSAqIHBhdHRlcm4gd2hpY2ggbWF5IGNvbnRhaW4gkSqSIGZvciAwIGFuZCBtYW55IGNoYXJhY3RlcnMgYW5kDQoJICogkT+SIGZvciBleGFjdGx5IG9uZSBjaGFyYWN0ZXIuICANCgkgKg0KCSAqIExpdGVyYWwgJyonIGFuZCAnPycgY2hhcmFjdGVycyBtdXN0IGJlIGVzY2FwZWQgaW4gdGhlIHBhdHRlcm4gDQoJICogZS5nLiwgIlwqIiBtZWFucyBsaXRlcmFsICIqIiwgZXRjLg0KCSAqDQoJICogRXNjYXBpbmcgYW55IG90aGVyIGNoYXJhY3RlciAoaW5jbHVkaW5nIHRoZSBlc2NhcGUgY2hhcmFjdGVyIGl0c2VsZiksIA0KCSAqIGp1c3QgcmVzdWx0cyBpbiB0aGF0IGNoYXJhY3RlciBpbiB0aGUgcGF0dGVybi4NCgkgKiBlLmcuLCAiXGEiIG1lYW5zICJhIiBhbmQgIlxcIiBtZWFucyAiXCINCgkgKg0KCSAqIElmIGludm9raW5nIHRoZSBTdHJpbmdNYXRjaGVyIHdpdGggc3RyaW5nIGxpdGVyYWxzIGluIEphdmEsIGRvbid0IGZvcmdldA0KCSAqIGVzY2FwZSBjaGFyYWN0ZXJzIGFyZSByZXByZXNlbnRlZCBieSAiXFwiLg0KCSAqDQoJICogQHBhcmFtIGFQYXR0ZXJuIHRoZSBwYXR0ZXJuIHRvIG1hdGNoIHRleHQgYWdhaW5zdA0KCSAqIEBwYXJhbSBpZ25vcmVDYXNlIGlmIHRydWUsIGNhc2UgaXMgaWdub3JlZA0KCSAqIEBwYXJhbSBpZ25vcmVXaWxkQ2FyZHMgaWYgdHJ1ZSwgd2lsZCBjYXJkcyBhbmQgdGhlaXIgZXNjYXBlIHNlcXVlbmNlcyBhcmUgaWdub3JlZA0KCSAqIAkJICAoZXZlcnl0aGluZyBpcyB0YWtlbiBsaXRlcmFsbHkpLg0KCSAqLw0KCXB1YmxpYyBTdHJpbmdNYXRjaGVyKFN0cmluZyBhUGF0dGVybiwgYm9vbGVhbiBpZ25vcmVDYXNlLCBib29sZWFuIGlnbm9yZVdpbGRDYXJkcykgew0KCQlmSWdub3JlQ2FzZSA9IGlnbm9yZUNhc2U7DQoJCWZJZ25vcmVXaWxkQ2FyZHMgPSBpZ25vcmVXaWxkQ2FyZHM7DQoJCWZMZW5ndGggPSBhUGF0dGVybi5sZW5ndGgoKTsNCg0KCQkvKiBjb252ZXJ0IGNhc2UgKi8NCgkJaWYgKGZJZ25vcmVDYXNlKSB7DQoJCQlmUGF0dGVybiA9IGFQYXR0ZXJuLnRvVXBwZXJDYXNlKCk7DQoJCX0gZWxzZSB7DQoJCQlmUGF0dGVybiA9IGFQYXR0ZXJuOw0KCQl9DQoJCQ0KCQlpZiAoZklnbm9yZVdpbGRDYXJkcykgew0KCQkJcGFyc2VOb1dpbGRDYXJkcygpOw0KCQl9IGVsc2Ugew0KCQkJcGFyc2VXaWxkQ2FyZHMoKTsNCgkJfQ0KCX0NCgkvKioNCgkgKiBGaW5kIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBwYXR0ZXJuIGJldHdlZW4gPGNvZGU+c3RhcnQ8L2NvZGUpKGluY2x1c2l2ZSkgDQoJICogYW5kIDxjb2RlPmVuZDwvY29kZT4oZXhjbHVzaXZlKS4gIA0KCSAqIEBwYXJhbSA8Y29kZT50ZXh0PC9jb2RlPiwgdGhlIFN0cmluZyBvYmplY3QgdG8gc2VhcmNoIGluIA0KCSAqIEBwYXJhbSA8Y29kZT5zdGFydDwvY29kZT4sIHRoZSBzdGFydGluZyBpbmRleCBvZiB0aGUgc2VhcmNoIHJhbmdlLCBpbmNsdXNpdmUNCgkgKiBAcGFyYW0gPGNvZGU+ZW5kPC9jb2RlPiwgdGhlIGVuZGluZyBpbmRleCBvZiB0aGUgc2VhcmNoIHJhbmdlLCBleGNsdXNpdmUNCgkgKiBAcmV0dXJuIGFuIDxjb2RlPlN0cmluZ01hdGNoZXIuUG9zaXRpb248L2NvZGU+IG9iamVjdCB0aGF0IGtlZXBzIHRoZSBzdGFydGluZyANCgkgKiAoaW5jbHVzaXZlKSBhbmQgZW5kaW5nIHBvc2l0aW9ucyAoZXhjbHVzaXZlKSBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB0aGUgDQoJICogcGF0dGVybiBpbiB0aGUgc3BlY2lmaWVkIHJhbmdlIG9mIHRoZSB0ZXh0OyByZXR1cm4gbnVsbCBpZiBub3QgZm91bmQgb3Igc3VidGV4dA0KCSAqIGlzIGVtcHR5IChzdGFydD09ZW5kKS4gQSBwYWlyIG9mIHplcm9zIGlzIHJldHVybmVkIGlmIHBhdHRlcm4gaXMgZW1wdHkgc3RyaW5nDQoJICogTm90ZSB0aGF0IGZvciBwYXR0ZXJuIGxpa2UgIiphYmMqIiB3aXRoIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHN0YXJzLCBwb3NpdGlvbiBvZiAiYWJjIg0KCSAqIGlzIHJldHVybmVkLiBGb3IgYSBwYXR0ZXJuIGxpa2UiKj8/KiIgaW4gdGV4dCAiYWJjZGYiLCAoMSwzKSBpcyByZXR1cm5lZA0KCSAqLw0KDQoJcHVibGljIFN0cmluZ01hdGNoZXIuUG9zaXRpb24gZmluZChTdHJpbmcgdGV4dCwgaW50IHN0YXJ0LCBpbnQgZW5kKSB7DQoJCWlmIChmUGF0dGVybiAgPT0gbnVsbHx8IHRleHQgPT0gbnVsbCkNCgkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsNCgkJCQ0KCQlpbnQgdGxlbiA9IHRleHQubGVuZ3RoKCk7DQoJCWlmIChzdGFydCA8IDApDQoJCQlzdGFydCA9IDA7DQoJCWlmIChlbmQgPiB0bGVuKQ0KCQkJZW5kID0gdGxlbjsNCgkJaWYgKGVuZCA8IDAgfHxzdGFydCA+PSBlbmQgKQ0KCQkJcmV0dXJuIG51bGw7DQoJCWlmIChmTGVuZ3RoID09IDApDQoJCQlyZXR1cm4gbmV3IFBvc2l0aW9uKHN0YXJ0LCBzdGFydCk7DQoJCWlmIChmSWdub3JlV2lsZENhcmRzKSB7DQoJCQlpbnQgeCA9IHBvc0luKHRleHQsIHN0YXJ0LCBlbmQpOw0KCQkJaWYgKHggPCAwKQ0KCQkJCXJldHVybiBudWxsOw0KCQkJcmV0dXJuIG5ldyBQb3NpdGlvbih4LCB4K2ZMZW5ndGgpOw0KCQl9DQoNCgkJaW50IHNlZ0NvdW50ID0gZlNlZ21lbnRzLmxlbmd0aDsNCgkJaWYgKHNlZ0NvdW50ID09IDApLy9wYXR0ZXJuIGNvbnRhaW5zIG9ubHkgJyonKHMpDQoJCQlyZXR1cm4gbmV3IFBvc2l0aW9uIChzdGFydCwgZW5kKTsNCgkJCQkJDQoJCWludCBjdXJQb3MgPSBzdGFydDsNCgkJaW50IG1hdGNoU3RhcnQgPSAtMTsgIA0KCQlmb3IgKGludCBpID0gMDsgaSA8IHNlZ0NvdW50ICYmIGN1clBvcyA8IGVuZDsgKytpKSB7DQoJCQlTdHJpbmcgY3VycmVudCA9IGZTZWdtZW50c1tpXTsNCgkJCWludCBuZXh0TWF0Y2ggPSByZWdFeHBQb3NJbih0ZXh0LCBjdXJQb3MsIGVuZCwgY3VycmVudCk7DQoJCQlpZiAobmV4dE1hdGNoIDwgMCApDQoJCQkJcmV0dXJuIG51bGw7DQoJCQlpZihpID09IDApDQoJCQkJbWF0Y2hTdGFydCA9IG5leHRNYXRjaDsNCgkJCWN1clBvcyA9IG5leHRNYXRjaCArIGN1cnJlbnQubGVuZ3RoKCk7DQoJCX0NCgkJcmV0dXJuIG5ldyBQb3NpdGlvbihtYXRjaFN0YXJ0LCBjdXJQb3MpOw0KCX0NCgkvKioNCgkgKiBtYXRjaCB0aGUgZ2l2ZW4gPGNvZGU+dGV4dDwvY29kZT4gd2l0aCB0aGUgcGF0dGVybiANCgkgKiBAcmV0dXJuIHRydWUgaWYgbWF0Y2hlZCBlaXRoZXJ3aXNlIGZhbHNlDQoJICogQHBhcmFtIDxjb2RlPnRleHQ8L2NvZGU+LCBhIFN0cmluZyBvYmplY3QgDQoJICovDQoJcHVibGljIGJvb2xlYW4gIG1hdGNoKFN0cmluZyB0ZXh0KSB7DQoJCXJldHVybiBtYXRjaCh0ZXh0LCAwLCB0ZXh0Lmxlbmd0aCgpKTsNCgl9DQoJLyoqDQoJICogR2l2ZW4gdGhlIHN0YXJ0aW5nIChpbmNsdXNpdmUpIGFuZCB0aGUgZW5kaW5nIChleGNsdXNpdmUpIHBvaXNpdGlvbnMgaW4gdGhlICAgDQoJICogPGNvZGU+dGV4dDwvY29kZT4sIGRldGVybWluZSBpZiB0aGUgZ2l2ZW4gc3Vic3RyaW5nIG1hdGNoZXMgd2l0aCBhUGF0dGVybiAgDQoJICogQHJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgcG9ydGlvbiBvZiB0aGUgdGV4dCBtYXRjaGVzIHRoZSBwYXR0ZXJuDQoJICogQHBhcmFtIFN0cmluZyA8Y29kZT50ZXh0PC9jb2RlPiwgYSBTdHJpbmcgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhlIHN1YnN0cmluZyB0byBtYXRjaCANCgkgKiBAcGFyYW0gaW50IDxjb2RlPnN0YXJ0PGNvZGU+IG1hcmtzIHRoZSBzdGFydGluZyBwb3NpdGlvbiAoaW5jbHVzaXZlKSBvZiB0aGUgc3Vic3RyaW5nDQoJICogQHBhcmFtIGludCA8Y29kZT5lbmQ8Y29kZT4gbWFya3MgdGhlIGVuZGluZyBpbmRleCAoZXhjbHVzaXZlKSBvZiB0aGUgc3Vic3RyaW5nIA0KCSAqLw0KCXB1YmxpYyBib29sZWFuIG1hdGNoKFN0cmluZyB0ZXh0LCBpbnQgc3RhcnQsIGludCBlbmQpIHsNCgkJaWYgKG51bGwgPT0gZlBhdHRlcm4gfHwgbnVsbCA9PSB0ZXh0KQ0KCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOw0KCQkJDQoJCWlmIChzdGFydCA+IGVuZCkNCgkJCXJldHVybiBmYWxzZTsNCgkJDQoJCWlmIChmSWdub3JlV2lsZENhcmRzKQ0KCQkJcmV0dXJuIGZQYXR0ZXJuLnJlZ2lvbk1hdGNoZXMoZklnbm9yZUNhc2UsIDAsIHRleHQsIHN0YXJ0LCBmTGVuZ3RoKTsNCgkJaW50IHNlZ0NvdW50ID0gZlNlZ21lbnRzLmxlbmd0aDsNCgkJaWYgKHNlZ0NvdW50ID09IDApLy9wYXR0ZXJuIGNvbnRhaW5zIG9ubHkgJyonKHMpIG9yIGVtcHR5IHBhdHRlcm4NCgkJCXJldHVybiB0cnVlOw0KCQlpZiAoc3RhcnQgPT0gZW5kKQ0KCQkJcmV0dXJuIGZMZW5ndGggPT0gMDsNCgkJaWYgKGZMZW5ndGggPT0gMCkNCgkJCXJldHVybiBzdGFydCA9PSBlbmQ7CQ0KCQkgDQoJCWludCB0bGVuID0gdGV4dC5sZW5ndGgoKTsNCgkJaWYgKHN0YXJ0IDwgMCkNCgkJCXN0YXJ0ID0gMDsNCgkJaWYgKGVuZCA+IHRsZW4pDQoJCQllbmQgPSB0bGVuOyANCgkJCQkJDQoJCWludCB0Q3VyUG9zID0gc3RhcnQ7DQoJCWludCBib3VuZCA9IGVuZCAtIGZCb3VuZDsNCgkJaWYgKCBib3VuZCA8IDApDQoJCQlyZXR1cm4gZmFsc2U7DQoJCWludCBpPTA7DQoJCVN0cmluZyBjdXJyZW50ID0gZlNlZ21lbnRzW2ldOw0KCQlpbnQgc2VnTGVuZ3RoID0gY3VycmVudC5sZW5ndGgoKTsNCg0KCQkvKiBwcm9jZXNzIGZpcnN0IHNlZ21lbnQgKi8NCgkJaWYgKCFmSGFzTGVhZGluZ1N0YXIpeyANCgkJCWlmKCFyZWdFeHBSZWdpb25NYXRjaGVzKHRleHQsIHN0YXJ0LCBjdXJyZW50LCAwLCBzZWdMZW5ndGgpKSB7DQoJCQkJcmV0dXJuIGZhbHNlOw0KCQkJfSBlbHNlIHsNCgkJCQkrK2k7DQoJCQkJdEN1clBvcyA9IHRDdXJQb3MgKyBzZWdMZW5ndGg7DQoJCQl9DQoJCX0NCg0KCQkvKiBwcm9jZXNzIG1pZGRsZSBzZWdtZW50cyAqLwkNCgkJZm9yICggOyBpIDwgc2VnQ291bnQgJiYgdEN1clBvcyA8PSBib3VuZDsgKytpKSB7DQoJCQljdXJyZW50ID0gZlNlZ21lbnRzW2ldOw0KCQkJaW50IGN1cnJlbnRNYXRjaDsNCgkJCWludCBrID0gY3VycmVudC5pbmRleE9mKGZTaW5nbGVXaWxkQ2FyZCk7DQoJCQlpZiAoayA8IDApIHsNCgkJCQljdXJyZW50TWF0Y2ggPSB0ZXh0UG9zSW4odGV4dCwgdEN1clBvcywgZW5kLCBjdXJyZW50KTsNCgkJCQlpZiAoY3VycmVudE1hdGNoIDwgMCkNCgkJCQkJcmV0dXJuIGZhbHNlOw0KCQkJfSBlbHNlIHsgDQoJCQkJY3VycmVudE1hdGNoID0gcmVnRXhwUG9zSW4odGV4dCwgdEN1clBvcywgZW5kLCBjdXJyZW50KTsNCgkJCQlpZiAoY3VycmVudE1hdGNoIDwgMCkNCgkJCQkJcmV0dXJuIGZhbHNlOw0KCQkJfQ0KCQkJdEN1clBvcyA9IGN1cnJlbnRNYXRjaCArIGN1cnJlbnQubGVuZ3RoKCk7DQoJCX0NCg0KCQkvKiBwcm9jZXNzIGZpbmFsIHNlZ21lbnQgKi8NCgkJaWYgKCFmSGFzVHJhaWxpbmdTdGFyICYmIHRDdXJQb3MgIT0gZW5kKSB7DQoJCQlpbnQgY2xlbiA9IGN1cnJlbnQubGVuZ3RoKCk7DQoJCQlyZXR1cm4gcmVnRXhwUmVnaW9uTWF0Y2hlcyh0ZXh0LCBlbmQgLSBjbGVuLCBjdXJyZW50LCAwLCBjbGVuKTsNCgkJfQ0KCQlyZXR1cm4gaSA9PSBzZWdDb3VudCA7DQoJfQ0KCS8qKg0KCSAqIFRoaXMgbWV0aG9kIHBhcnNlcyB0aGUgZ2l2ZW4gcGF0dGVybiBpbnRvIHNlZ21lbnRzIHNlcGVyYXRlZCBieSB3aWxkY2FyZCAnKicgY2hhcmFjdGVycy4NCgkgKiBTaW5jZSB3aWxkY2FyZHMgYXJlIG5vdCBiZWluZyB1c2VkIGluIHRoaXMgY2FzZSwgdGhlIHBhdHRlcm4gY29uc2lzdHMgb2YgYSBzaW5nbGUgc2VnbWVudC4NCgkgKi8NCglwcml2YXRlIHZvaWQgcGFyc2VOb1dpbGRDYXJkcygpIHsNCgkJZlNlZ21lbnRzID0gbmV3IFN0cmluZ1sxXTsNCgkJZlNlZ21lbnRzWzBdID0gZlBhdHRlcm47DQoJCWZCb3VuZCA9IGZMZW5ndGg7DQoJfQ0KCS8qKg0KCSAqICBUaGlzIG1ldGhvZCBwYXJzZXMgdGhlIGdpdmVuIHBhdHRlcm4gaW50byBzZWdtZW50cyBzZXBlcmF0ZWQgYnkgd2lsZGNhcmQgJyonIGNoYXJhY3RlcnMuDQoJICogQHBhcmFtIHAsIGEgU3RyaW5nIG9iamVjdCB0aGF0IGlzIGEgc2ltcGxlIHJlZ3VsYXIgZXhwcmVzc2lvbiB3aXRoIJEqkiBhbmQvb3IgkT+SDQoJICovDQoJcHJpdmF0ZSB2b2lkIHBhcnNlV2lsZENhcmRzKCkgew0KCQlpZihmUGF0dGVybi5zdGFydHNXaXRoKCIqIikpLy8kTk9OLU5MUy0xJA0KCQkJZkhhc0xlYWRpbmdTdGFyID0gdHJ1ZTsNCgkJaWYoZlBhdHRlcm4uZW5kc1dpdGgoIioiKSkgey8vJE5PTi1OTFMtMSQNCgkJCS8qIG1ha2Ugc3VyZSBpdCdzIG5vdCBhbiBlc2NhcGVkIHdpbGRjYXJkICovDQoJCQlpZiAoZkxlbmd0aCA+IDEgJiYgZlBhdHRlcm4uY2hhckF0KGZMZW5ndGggLSAyKSAhPSAnXFwnKSB7DQoJCQkJZkhhc1RyYWlsaW5nU3RhciA9IHRydWU7DQoJCQl9DQoJCX0NCg0KCQlWZWN0b3IgdGVtcCA9IG5ldyBWZWN0b3IoKTsNCg0KCQlpbnQgcG9zID0gMDsNCgkJU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsNCgkJd2hpbGUgKHBvcyA8IGZMZW5ndGgpIHsNCgkJCWNoYXIgYyA9IGZQYXR0ZXJuLmNoYXJBdChwb3MrKyk7DQoJCQlzd2l0Y2ggKGMpIHsNCgkJCQljYXNlICdcXCc6DQoJCQkJCWlmIChwb3MgPj0gZkxlbmd0aCkgew0KCQkJCQkJYnVmLmFwcGVuZChjKTsNCgkJCQkJfSBlbHNlIHsNCgkJCQkJCWNoYXIgbmV4dCA9IGZQYXR0ZXJuLmNoYXJBdChwb3MrKyk7DQoJCQkJCQkvKiBpZiBpdCdzIGFuIGVzY2FwZSBzZXF1ZW5jZSAqLw0KCQkJCQkJaWYgKG5leHQgPT0gJyonIHx8IG5leHQgPT0gJz8nIHx8IG5leHQgPT0gJ1xcJykgew0KCQkJCQkJCWJ1Zi5hcHBlbmQobmV4dCk7DQoJCQkJCQl9IGVsc2Ugew0KCQkJCQkJCS8qIG5vdCBhbiBlc2NhcGUgc2VxdWVuY2UsIGp1c3QgaW5zZXJ0IGxpdGVyYWxseSAqLw0KCQkJCQkJCWJ1Zi5hcHBlbmQoYyk7DQoJCQkJCQkJYnVmLmFwcGVuZChuZXh0KTsNCgkJCQkJCX0NCgkJCQkJfQ0KCQkJCWJyZWFrOw0KCQkJCWNhc2UgJyonOg0KCQkJCQlpZiAoYnVmLmxlbmd0aCgpID4gMCkgew0KCQkJCQkJLyogbmV3IHNlZ21lbnQgKi8NCgkJCQkJCXRlbXAuYWRkRWxlbWVudChidWYudG9TdHJpbmcoKSk7DQoJCQkJCQlmQm91bmQgKz0gYnVmLmxlbmd0aCgpOw0KCQkJCQkJYnVmLnNldExlbmd0aCgwKTsNCgkJCQkJfQ0KCQkJCWJyZWFrOw0KCQkJCWNhc2UgJz8nOg0KCQkJCQkvKiBhcHBlbmQgc3BlY2lhbCBjaGFyYWN0ZXIgcmVwcmVzZW50aW5nIHNpbmdsZSBtYXRjaCB3aWxkY2FyZCAqLw0KCQkJCQlidWYuYXBwZW5kKGZTaW5nbGVXaWxkQ2FyZCk7DQoJCQkJYnJlYWs7DQoJCQkJZGVmYXVsdDoNCgkJCQkJYnVmLmFwcGVuZChjKTsNCgkJCX0NCgkJfQ0KDQoJCS8qIGFkZCBsYXN0IGJ1ZmZlciB0byBzZWdtZW50IGxpc3QgKi8NCgkJaWYgKGJ1Zi5sZW5ndGgoKSA+IDApIHsNCgkJCXRlbXAuYWRkRWxlbWVudChidWYudG9TdHJpbmcoKSk7DQoJCQlmQm91bmQgKz0gYnVmLmxlbmd0aCgpOw0KCQl9DQoJCQkNCgkJZlNlZ21lbnRzID0gbmV3IFN0cmluZ1t0ZW1wLnNpemUoKV07DQoJCXRlbXAuY29weUludG8oZlNlZ21lbnRzKTsNCgl9DQoJLyoqIA0KCSAqIEBwYXJhbSA8Y29kZT50ZXh0PC9jb2RlPiwgYSBzdHJpbmcgd2hpY2ggY29udGFpbnMgbm8gd2lsZGNhcmQNCgkgKiBAcGFyYW0gPGNvZGU+c3RhcnQ8L2NvZGU+LCB0aGUgc3RhcnRpbmcgaW5kZXggaW4gdGhlIHRleHQgZm9yIHNlYXJjaCwgaW5jbHVzaXZlDQoJICogQHBhcmFtIDxjb2RlPmVuZDwvY29kZT4sIHRoZSBzdG9wcGluZyBwb2ludCBvZiBzZWFyY2gsIGV4Y2x1c2l2ZQ0KCSAqIEByZXR1cm4gdGhlIHN0YXJ0aW5nIGluZGV4IGluIHRoZSB0ZXh0IG9mIHRoZSBwYXR0ZXJuICwgb3IgLTEgaWYgbm90IGZvdW5kIA0KCSAqLw0KCXByb3RlY3RlZCBpbnQgcG9zSW4oU3RyaW5nIHRleHQsIGludCBzdGFydCwgaW50IGVuZCkgey8vbm8gd2lsZCBjYXJkIGluIHBhdHRlcm4NCgkJaW50IG1heCA9IGVuZCAtIGZMZW5ndGg7DQoJCQ0KCQlpZiAoIWZJZ25vcmVDYXNlKSB7DQoJCQlpbnQgaSA9IHRleHQuaW5kZXhPZihmUGF0dGVybiwgc3RhcnQpOw0KCQkJaWYgKGkgPT0gLTEgfHwgaSA+IG1heCkNCgkJCQlyZXR1cm4gLTE7DQoJCQlyZXR1cm4gaTsNCgkJfQ0KCQkNCgkJZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDw9IG1heDsgKytpKSB7DQoJCQlpZiAodGV4dC5yZWdpb25NYXRjaGVzKHRydWUsIGksIGZQYXR0ZXJuLCAwLCBmTGVuZ3RoKSkNCgkJCQlyZXR1cm4gaTsNCgkJfQ0KCQkNCgkJcmV0dXJuIC0xOw0KCX0NCgkvKiogDQoJICogQHBhcmFtIDxjb2RlPnRleHQ8L2NvZGU+LCBhIHNpbXBsZSByZWd1bGFyIGV4cHJlc3Npb24gdGhhdCBtYXkgb25seSBjb250YWluICc/JyhzKQ0KCSAqIEBwYXJhbSA8Y29kZT5zdGFydDwvY29kZT4sIHRoZSBzdGFydGluZyBpbmRleCBpbiB0aGUgdGV4dCBmb3Igc2VhcmNoLCBpbmNsdXNpdmUNCgkgKiBAcGFyYW0gPGNvZGU+ZW5kPC9jb2RlPiwgdGhlIHN0b3BwaW5nIHBvaW50IG9mIHNlYXJjaCwgZXhjbHVzaXZlDQoJICogQHBhcmFtIDxjb2RlPnA8L2NvZGU+LCBhIHNpbXBsZSByZWd1bGFyIGV4cHJlc3Npb24gdGhhdCBtYXkgY29udGFpbnMgJz8nDQoJICogQHBhcmFtIDxjb2RlPmNhc2VJZ25vcmVkPC9jb2RlPiwgd2V0aGVyIHRoZSBwYXR0ZXJuIGlzIG5vdCBjYXNlc2Vuc2l0aXZlDQoJICogQHJldHVybiB0aGUgc3RhcnRpbmcgaW5kZXggaW4gdGhlIHRleHQgb2YgdGhlIHBhdHRlcm4gLCBvciAtMSBpZiBub3QgZm91bmQgDQoJICovDQoJcHJvdGVjdGVkIGludCByZWdFeHBQb3NJbihTdHJpbmcgdGV4dCwgaW50IHN0YXJ0LCBpbnQgZW5kLCBTdHJpbmcgcCkgew0KCQlpbnQgcGxlbiA9IHAubGVuZ3RoKCk7DQoJCQ0KCQlpbnQgbWF4ID0gZW5kIC0gcGxlbjsNCgkJZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDw9IG1heDsgKytpKSB7DQoJCQlpZiAocmVnRXhwUmVnaW9uTWF0Y2hlcyh0ZXh0LCBpLCBwLCAwLCBwbGVuKSkNCgkJCQlyZXR1cm4gaTsNCgkJfQ0KCQlyZXR1cm4gLTE7DQoJfQ0KCS8qKg0KCSAqIA0KCSAqIEByZXR1cm4gYm9vbGVhbg0KCSAqIEBwYXJhbSA8Y29kZT50ZXh0PC9jb2RlPiwgYSBTdHJpbmcgdG8gbWF0Y2gNCgkgKiBAcGFyYW0gPGNvZGU+c3RhcnQ8L2NvZGU+LCBpbnQgdGhhdCBpbmRpY2F0ZXMgdGhlIHN0YXJ0aW5nIGluZGV4IG9mIG1hdGNoLCBpbmNsdXNpdmUNCgkgKiBAcGFyYW0gPGNvZGU+ZW5kPC9jb2RlPiBpbnQgdGhhdCBpbmRpY2F0ZXMgdGhlIGVuZGluZyBpbmRleCBvZiBtYXRjaCwgZXhjbHVzaXZlDQoJICogQHBhcmFtIDxjb2RlPnA8L2NvZGU+LCBTdHJpbmcsICBTdHJpbmcsIGEgc2ltcGxlIHJlZ3VsYXIgZXhwcmVzc2lvbiB0aGF0IG1heSBjb250YWluICc/Jw0KCSAqIEBwYXJhbSA8Y29kZT5pZ25vcmVDYXNlPC9jb2RlPiwgYm9vbGVhbiBpbmRpY2F0aW5nIHdldGhlciBjb2RlPnA8L2NvZGU+IGlzIGNhc2Ugc2Vuc2l0aXZlDQoJICovDQoJcHJvdGVjdGVkIGJvb2xlYW4gcmVnRXhwUmVnaW9uTWF0Y2hlcyhTdHJpbmcgdGV4dCwgaW50IHRTdGFydCwgU3RyaW5nIHAsIGludCBwU3RhcnQsIGludCBwbGVuKSB7DQoJCXdoaWxlIChwbGVuLS0gPiAwKSB7DQoJCQljaGFyIHRjaGFyID0gdGV4dC5jaGFyQXQodFN0YXJ0KyspOw0KCQkJY2hhciBwY2hhciA9IHAuY2hhckF0KHBTdGFydCsrKTsNCg0KCQkJLyogcHJvY2VzcyB3aWxkIGNhcmRzICovDQoJCQlpZiAoIWZJZ25vcmVXaWxkQ2FyZHMpIHsNCgkJCQkvKiBza2lwIHNpbmdsZSB3aWxkIGNhcmRzICovDQoJCQkJaWYgKHBjaGFyID09IGZTaW5nbGVXaWxkQ2FyZCkgew0KCQkJCQljb250aW51ZTsNCgkJCQl9DQoJCQl9DQoJCQlpZiAocGNoYXIgPT0gdGNoYXIpDQoJCQkJY29udGludWU7DQoJCQlpZiAoZklnbm9yZUNhc2UpIHsNCgkJCQljaGFyIHRjID0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKHRjaGFyKTsNCgkJCQlpZiAodGMgPT0gcGNoYXIpDQoJCQkJCWNvbnRpbnVlOw0KCQkJfQ0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoJCXJldHVybiB0cnVlOw0KCX0NCgkvKiogDQoJICogQHBhcmFtIDxjb2RlPnRleHQ8L2NvZGU+LCB0aGUgc3RyaW5nIHRvIG1hdGNoDQoJICogQHBhcmFtIDxjb2RlPnN0YXJ0PC9jb2RlPiwgdGhlIHN0YXJ0aW5nIGluZGV4IGluIHRoZSB0ZXh0IGZvciBzZWFyY2gsIGluY2x1c2l2ZQ0KCSAqIEBwYXJhbSA8Y29kZT5lbmQ8L2NvZGU+LCB0aGUgc3RvcHBpbmcgcG9pbnQgb2Ygc2VhcmNoLCBleGNsdXNpdmUNCgkgKiBAcGFyYW0gY29kZT5wPC9jb2RlPiwgYSBzdHJpbmcgdGhhdCBoYXMgbm8gd2lsZGNhcmQNCgkgKiBAcGFyYW0gPGNvZGU+aWdub3JlQ2FzZTwvY29kZT4sIGJvb2xlYW4gaW5kaWNhdGluZyB3ZXRoZXIgY29kZT5wPC9jb2RlPiBpcyBjYXNlIHNlbnNpdGl2ZQ0KCSAqIEByZXR1cm4gdGhlIHN0YXJ0aW5nIGluZGV4IGluIHRoZSB0ZXh0IG9mIHRoZSBwYXR0ZXJuICwgb3IgLTEgaWYgbm90IGZvdW5kIA0KCSAqLw0KCXByb3RlY3RlZCBpbnQgdGV4dFBvc0luKFN0cmluZyB0ZXh0LCBpbnQgc3RhcnQsIGludCBlbmQsIFN0cmluZyBwKSB7IA0KCQkNCgkJaW50IHBsZW4gPSBwLmxlbmd0aCgpOw0KCQlpbnQgbWF4ID0gZW5kIC0gcGxlbjsNCgkJDQoJCWlmICghZklnbm9yZUNhc2UpIHsNCgkJCWludCBpID0gdGV4dC5pbmRleE9mKHAsIHN0YXJ0KTsNCgkJCWlmIChpID09IC0xIHx8IGkgPiBtYXgpDQoJCQkJcmV0dXJuIC0xOw0KCQkJcmV0dXJuIGk7DQoJCX0NCgkJDQoJCWZvciAoaW50IGkgPSAwOyBpIDw9IG1heDsgKytpKSB7DQoJCQlpZiAodGV4dC5yZWdpb25NYXRjaGVzKHRydWUsIGksIHAsIDAsIHBsZW4pKQ0KCQkJCXJldHVybiBpOw0KCQl9DQoJCQ0KCQlyZXR1cm4gLTE7DQoJfQ0KfQ0K