LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgovL1RCRDogVG9vbEJveCBoYW5kbGluZyBwcmp2aWV3L2JhY2sKCiNpbmNsdWRlIDxvc2wvZmlsZS5oeHg+CiNpbmNsdWRlIDxydGwvdXN0cmluZy5oeHg+CiNpbmNsdWRlIDx0b29scy9kZWJ1Zy5oeHg+CiNpbmNsdWRlIDxzb2xkZXAvc3N0cmluZy5oeHg+CiNpbmNsdWRlIDxzdnRvb2xzL2ZpbGVkbGcuaHh4PgojaW5jbHVkZSA8dG9vbHMvaXBhcnNlci5oeHg+CiNpbmNsdWRlIDx0b29scy9nZW5pbmZvLmh4eD4KI2luY2x1ZGUgPHZjbC9nZGltdGYuaHh4PgojaW5jbHVkZSA8dmNsL2JpdG1hcC5oeHg+CiNpbmNsdWRlIDxzb2xkZXAvYXBwZGVmLmh4eD4KI2luY2x1ZGUgInRpbWUuaCIKI2luY2x1ZGUgPHNvbGRlcC9kZXBwZXIuaHh4PgojaW5jbHVkZSA8c29sZGVwL3NvbGRlcC5oeHg+CiNpbmNsdWRlIDxzb2xkZXAvc29sZGxnLmh4eD4KI2luY2x1ZGUgImR0c29kY21wLmhyYyIKCklNUExFTUVOVF9IQVNIVEFCTEVfT1dORVIoIFNvbElkTWFwcGVyLCBCeXRlU3RyaW5nLCBzYWxfdUludFB0ciogKTsKLy9JTVBMRU1FTlRfSEFTSFRBQkxFX09XTkVSKCBQcmpJZE1hcHBlciwgQnl0ZVN0cmluZywgc2FsX3VJbnRQdHIqICk7CiNkZWZpbmUgRVZFTlRfUkVTSVpFICAgICAgICAgICAgICAgIDB4MDAwMDAwMDEKI2RlZmluZSBNSU4oYSxiKSAoYSk8KGIpPyhhKTooYikKI2RlZmluZSBNQVgoYSxiKSAoYSk+KGIpPyhhKTooYikKCgovL0J5dGVTdHJpbmcgc0RlbGltaXRlckxpbmUoIiM9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpOwoKCi8vCi8vIGNsYXNzIFNvbERlcAovLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpTb2xEZXA6OlNvbERlcCggV2luZG93KiBwQmFzZVdpbmRvdyApCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCQkJCTogRGVwcGVyKCBwQmFzZVdpbmRvdyApLAogICAgICAgICAgICAgICAgbWJCU2VydmVyKHNhbF9GYWxzZSksCiAgICAgICAgICAgICAgICBtcFRyYXZlbGxlckxpc3QoIE5VTEwgKSwKICAgICAgICAgICAgICAgIG1iSXNIaWRlKCBzYWxfRmFsc2UgKQp7CiAgICBtblNvbFdpbkNvdW50ID0gMDsKCW1uU29sTGFzdElkID0gMDsKLy8gICAgbXBQcmpJZE1hcHBlciA9IG5ldyBTb2xJZE1hcHBlciggNjM5OTcgKTsKICAgIG1hVGFza0JhckZyYW1lLkVuYWJsZUFsd2F5c09uVG9wKCk7CiAgICBtYVRhc2tCYXJGcmFtZS5TaG93KCk7CiAgICBtYVRvb2xCb3guU2V0UG9zU2l6ZVBpeGVsKCBQb2ludCggMCwwICksIFNpemUoIDExMDAsMzUgKSk7CgltYVRvb2xCb3guU2V0U2VsZWN0SGRsKCBMSU5LICggdGhpcywgU29sRGVwLCBUb29sU2VsZWN0ICkpOwogICAgbWFUb29sQm94LlNob3coKTsKCgltcEJhc2VXaW4tPkFkZENoaWxkRXZlbnRMaXN0ZW5lciggTElOSyggdGhpcywgU29sRGVwLCBDaGlsZFdpbmRvd0V2ZW50TGlzdGVuZXIgKSk7CgogICAgLy8gS29udGV4dC1NZW51ZSAoZ2Vo9nJ0IHp1IHNvbGRlcC5jeHgpCiAgICBJbml0Q29udGV4dE1lbnVlTWFpblduZCgpOwogICAgSW5pdENvbnRleHRNZW51ZVByalZpZXdXbmQoIG1wQmFzZVByaldpbiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovClNvbERlcDo6flNvbERlcCgpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewogICAgbXBCYXNlV2luLT5SZW1vdmVDaGlsZEV2ZW50TGlzdGVuZXIoIExJTksoIHRoaXMsIFNvbERlcCwgQ2hpbGRXaW5kb3dFdmVudExpc3RlbmVyICkgKTsKCWRlbGV0ZSBtcFNvbElkTWFwcGVyOwoJZGVsZXRlIG1wU3RhcldyaXRlcjsKCWRlbGV0ZSBtcFN0YW5kTHN0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQgU29sRGVwOjpJbml0KCkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CglJbmZvcm1hdGlvblBhcnNlciBhUGFyc2VyOwoJU3RyaW5nIHNTdGFuZExzdCggR2V0RGVmU3RhbmRMaXN0KCksIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCW1wU3RhbmRMc3QgPSBhUGFyc2VyLkV4ZWN1dGUoIHNTdGFuZExzdCApOwogICAgQnl0ZVN0cmluZyBhVXBkYXRlciggZ2V0ZW52KCJVUERBVEVSIikgKTsKCWlmICggbXBTdGFuZExzdCAmJiAoYVVwZGF0ZXIgPT0gIllFUyIpICkgewoJCWlmICggR2V0VmVyc2lvbigpICkKCQkJUmVhZFNvdXJjZSggc2FsX1RydWUgKTsKCX0gZWxzZQoJewoJCVJlYWRTb3VyY2UoKTsgICAvLyBpZiBzdGFuZC5sc3QgaXNuJ3QgYXZhaWxhYmxlCgl9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZCBTb2xEZXA6OkluaXQoIEJ5dGVTdHJpbmcgJnJWZXJzaW9uLCBHZW5lcmljSW5mb3JtYXRpb25MaXN0ICpwVmVyc2lvbkxpc3QgKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICAgIC8vIEludGVyZmFjZSBmb3IgYnMKICAgIG1iQlNlcnZlcj1zYWxfVHJ1ZTsKCWlmICggcFZlcnNpb25MaXN0ICkKCQltcFN0YW5kTHN0ID0gbmV3IEdlbmVyaWNJbmZvcm1hdGlvbkxpc3QoICpwVmVyc2lvbkxpc3QgKTsKCWVsc2UgewoJCUluZm9ybWF0aW9uUGFyc2VyIGFQYXJzZXI7CgkJU3RyaW5nIHNTdGFuZExzdCggR2V0RGVmU3RhbmRMaXN0KCksIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCQltcFN0YW5kTHN0ID0gYVBhcnNlci5FeGVjdXRlKCBzU3RhbmRMc3QgKTsKCX0KCWlmICggbXBTdGFuZExzdCApIHsKCQltc1ZlcnNpb25NYWpvciA9IEJ5dGVTdHJpbmcoIHJWZXJzaW9uICk7CgkJUmVhZFNvdXJjZShzYWxfVHJ1ZSk7IC8vY2FsbCBmcm9tIGJ1aWxkIHNlcnZlciBzZXQgVVBEQVRFUiB0byBUUlVFCgl9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSU1QTF9MSU5LKCBTb2xEZXAsIENoaWxkV2luZG93RXZlbnRMaXN0ZW5lciwgVmNsU2ltcGxlRXZlbnQqLCBwRXZlbnQgKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKCWlmICggcEV2ZW50ICYmIHBFdmVudC0+SVNBKCBWY2xXaW5kb3dFdmVudCApICkKCXsKCQlQcm9jZXNzQ2hpbGRXaW5kb3dFdmVudCggKnN0YXRpY19jYXN0PCBWY2xXaW5kb3dFdmVudCogPiggcEV2ZW50ICkgKTsKCX0KCXJldHVybiAwOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkIFNvbERlcDo6UHJvY2Vzc0NoaWxkV2luZG93RXZlbnQoIGNvbnN0IFZjbFdpbmRvd0V2ZW50JiBfclZjbFdpbmRvd0V2ZW50ICkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgICBXaW5kb3cqIHBDaGlsZFdpbiA9IF9yVmNsV2luZG93RXZlbnQuR2V0V2luZG93KCk7Ci8vICAgIFdpbmRvdyogcFBhcmVudFdpbiA9IHBDaGlsZFdpbi0+R2V0UGFyZW50KCk7Ci8vUmVzaXplKCk7CiAgICBpZiAoIGlzQWxpdmUoKSApCgkJewogICAgICAgICAgICBzYWxfdUludFB0ciBpZCA9IF9yVmNsV2luZG93RXZlbnQuR2V0SWQoKTsKCQkJc3dpdGNoICggaWQgKQoJCQl7CgkJCQljYXNlIFZDTEVWRU5UX1VTRVJfTU9VU0VCVVRUT05fRE9XTjoKCQkJCQl7CgkJCQkJCU9iamVjdFdpbiogcE9ialdpbiA9IGR5bmFtaWNfY2FzdDxPYmplY3RXaW4qPihwQ2hpbGRXaW4pOwoJCQkJCQlpZiggcE9ialdpbiApCgkJCQkJCXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBtb3VzZSBjbGljayBvbiBPYmplY3RXaW4gb2JqZWN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXaW4qIHBXaW4gPSAoT2JqZWN0V2luKikgcENoaWxkV2luOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9HZXRPYmplY3RMaXN0KCktPlJlc2V0U2VsZWN0ZWRPYmplY3QoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChJc0hpZGVNb2RlKCkpICAgICAgLy8gc2ltcGxlIG1vdXNlIGNsaWNrIGxlZnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwV2luLT5DYXB0dXJlTW91c2UoKTsKCQkJICAgICAgICAgICAgICAgICAgICBwV2luLT5TZXRNYXJrTW9kZSggTUFSS01PREVfU0VMRUNURUQgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwV2luLT5NYXJrTmVlZGVkKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFdpbi0+TWFya0RlcGVuZGluZygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBXaW4tPkludmFsaWRhdGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBXaW4tPkxvc2VGb2N1cygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBXaW4tPlNldE1hcmtNb2RlKCBNQVJLTU9ERV9TRUxFQ1RFRCApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBXaW4tPlVuc2V0TWFya01vZGUoIE1BUktNT0RFX0FDVElWQVRFRCApOwoJCQkgICAgICAgICAgICAgICAgICAgIHBXaW4tPk1hcmtOZWVkZWQoIHNhbF9UcnVlICk7CgkJCSAgICAgICAgICAgICAgICAgICAgcFdpbi0+TWFya0RlcGVuZGluZyggc2FsX1RydWUgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCgkJCQkJCX0KCQkJCQl9CgkJCQkJYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFZDTEVWRU5UX1VTRVJfTU9VU0VCVVRUT05fRE9XTl9BTFQ6CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXaW4qIHBPYmpXaW4gPSBkeW5hbWljX2Nhc3Q8T2JqZWN0V2luKj4ocENoaWxkV2luKTsKCQkJCQkJaWYoIHBPYmpXaW4gKQoJCQkJCQl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXaW4qIHBXaW4gPSAoT2JqZWN0V2luKikgcENoaWxkV2luOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFya09iamVjdHMoIHBXaW4gKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgVkNMRVZFTlRfVVNFUl9NT1VTRUJVVFRPTl9ET1dOX0RCTENMSUNLOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0V2luKiBwT2JqV2luID0gZHluYW1pY19jYXN0PE9iamVjdFdpbio+KHBDaGlsZFdpbik7CgkJCQkJCWlmKCBwT2JqV2luICkKCQkJCQkJewoJCQkJCQkJaWYgKElzSGlkZU1vZGUoKSkgVG9nZ2xlSGlkZURlcGVuZGVuY3koKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5dGVTdHJpbmcgdGV4dCA9ICgoT2JqZWN0V2luKikgcENoaWxkV2luKS0+R2V0Qm9keVRleHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZpZXdDb250ZW50KHRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBWQ0xFVkVOVF9VU0VSX01PVVNFQlVUVE9OX1VQX1NIRlQ6CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXaW4qIHBPYmpXaW4gPSBkeW5hbWljX2Nhc3Q8T2JqZWN0V2luKj4ocENoaWxkV2luKTsKCQkJCQkJaWYoIHBPYmpXaW4gKQoJCQkJCQl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RXaW4qIHBXaW4gPSAoT2JqZWN0V2luKikgcENoaWxkV2luOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0RGVwV2luKCktPk5ld0Nvbm5lY3RvciggcFdpbiApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBWQ0xFVkVOVF9VU0VSX01PVVNFQlVUVE9OX1VQOgogICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFdpbiogcE9ialdpbiA9IGR5bmFtaWNfY2FzdDxPYmplY3RXaW4qPihwQ2hpbGRXaW4pOwoJCQkJCQlpZiggcE9ialdpbiApCgkJCQkJCXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFdpbiogcFdpbiA9IChPYmplY3RXaW4qKSBwQ2hpbGRXaW47CiAgICAgICAgICAgICAgICAJCQlwV2luLT5SZWxlYXNlTW91c2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBXaW4tPlNldE1hcmtNb2RlKE1BUktNT0RFX1NFTEVDVEVEKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldERlcFdpbigpLT5JbnZhbGlkYXRlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICBicmVhazsKCQkJfSAgICAvLyBzd2l0Y2gKCQl9ICAvLyBpZiBpc0FsaXZlCiAgICAgICAgLy9mcHJpbnRmKHN0ZG91dCwiQkxBOjpSZXNpemU6ICVkXG4iLHBDaGlsZFdpbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSU1QTF9MSU5LKCBTb2xEZXAsIFRvb2xTZWxlY3QsIFNvbGRlcFRvb2xCb3gqICwgcEJveCkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CglzYWxfdUludDE2IG5JdGVtSWQgPSBwQm94LT5HZXRDdXJJdGVtSWQoKTsKCXN3aXRjaCAoIG5JdGVtSWQgKQoJewoJCWNhc2UgVElEX1NPTERFUF9GSU5EOgoJCQlGaW5kUHJvamVjdCgpOwoJCQlicmVhazsKICAgICAgICBjYXNlIFRJRF9TT0xERVBfQ1JFQVRFTUVUQSA6CiAgICAgICAgewogICAgICAgICAgICBWaXJ0dWFsRGV2aWNlICAgYVZEZXY7CgkJCWFWRGV2LlNldE1hcE1vZGUoIE1BUF8xMDBUSF9NTSApOwogICAgICAgICAgICBHRElNZXRhRmlsZSAgICAgYU10ZjsKICAgICAgICAgICAgYVZEZXYuRW5hYmxlT3V0cHV0KCBzYWxfRmFsc2UgKTsKICAgICAgICAgICAgYU10Zi5SZWNvcmQoICZhVkRldiApOwoKCQkJYVZEZXYuU2V0TGluZUNvbG9yKCBDb2xvciggQ09MX0JMQUNLICkgKTsKCQkJYVZEZXYuU2V0VGV4dEFsaWduKCBBTElHTl9UT1AgKTsKCgkJCVNpemUgYVNpemUoIEdldERlcFdpbigpLT5HZXRPdXRwdXRTaXplUGl4ZWwoKSApOwoJCQlsb25nIG5YTWluID0gYVNpemUuV2lkdGgoKTsKCQkJbG9uZyBuWE1heCA9IDA7CgkJCWxvbmcgbllNYXggPSAwOwoJCQlsb25nIG5ZTWluID0gYVNpemUuSGVpZ2h0KCk7CgoJCQlmb3IgKCBzYWxfdUludDE2IGk9MDsgaTxtcE9iamVjdExpc3QtPkNvdW50KCk7IGkrKyApCgkJCXsKCQkJCVBvaW50IGFQb2ludCA9IG1wT2JqZWN0TGlzdC0+R2V0T2JqZWN0KGkpLT5HZXRQb3NQaXhlbCgpOwoJCQkJU2l6ZSBhU2l6ZSA9IG1wT2JqZWN0TGlzdC0+R2V0T2JqZWN0KGkpLT5HZXRTaXplUGl4ZWwoKTsKCQkJCW5YTWluID0gTUlOKCBhUG9pbnQuWCgpLCBuWE1pbiApOwoJCQkJblhNYXggPSBNQVgoIGFQb2ludC5YKCkgKyBhU2l6ZS5XaWR0aCgpLCBuWE1heCApOwoJCQkJbllNaW4gPSBNSU4oIGFQb2ludC5ZKCksIG5ZTWluICk7CgkJCQluWU1heCA9IE1BWCggYVBvaW50LlkoKSArIGFTaXplLkhlaWdodCgpLCBuWU1heCApOwoJCQl9CgoJCQlQb2ludCBhT2Zmc2V0KCBuWE1pbiwgbllNaW4gKTsKCQkJYU9mZnNldCA9IGFWRGV2LlBpeGVsVG9Mb2dpYyggYU9mZnNldCApOwoKICAgICAgICAgICAgR2V0RGVwV2luKCktPkRyYXdPdXRwdXQoICZhVkRldiwgYU9mZnNldCApOwoJCQlmb3IgKCBzYWxfdUludDE2IGk9MDsgaTxtcE9iamVjdExpc3QtPkNvdW50KCk7IGkrKyApCgkJCQlpZiAoIG1wT2JqZWN0TGlzdC0+R2V0T2JqZWN0KGkpLT5Jc1Zpc2libGUoKSApCgkJCQkJbXBPYmplY3RMaXN0LT5HZXRPYmplY3QoaSktPkRyYXdPdXRwdXQoICZhVkRldiwgYU9mZnNldCApOwoKICAgICAgICAgICAgYU10Zi5TdG9wKCk7CiAgICAgICAgICAgIGFNdGYuV2luZFN0YXJ0KCk7CiAgICAgICAgICAgIGFNdGYuU2V0UHJlZk1hcE1vZGUoIGFWRGV2LkdldE1hcE1vZGUoKSApOwoJCQlTaXplIGFEZXZTaXplKCBuWE1heC1uWE1pbiArIDEwLCBuWU1heC1uWU1pbiArIDEwKTsKCQkJYURldlNpemUgPQlhVkRldi5QaXhlbFRvTG9naWMoIGFEZXZTaXplICk7CiAgICAgICAgICAgIGFNdGYuU2V0UHJlZlNpemUoIGFEZXZTaXplICk7CgkJCVN2RmlsZVN0cmVhbSBhU3RyZWFtKCBTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSgiZDpcXG91dC5zdm0iKSwgU1RSRUFNX1NURF9SRUFEV1JJVEUgKTsKCQkJYU10Zi5Xcml0ZSggYVN0cmVhbSApOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgkJY2FzZSBUSURfU09MREVQX0hJREVfSU5ERVBFTkRFTkQ6CgkJCXsKICAgICAgICAgICAgICAgIFRvZ2dsZUhpZGVEZXBlbmRlbmN5KCk7CgkJCQlmb3IgKCBzYWxfdUludDE2IGk9MDsgaTxtcE9iamVjdExpc3QtPkNvdW50KCk7IGkrKyApCgkJCQkJbXBPYmplY3RMaXN0LT5HZXRPYmplY3QoaSktPlNldFZpZXdNYXNrKCFtYklzSGlkZSk7CgogICAJICAgIAkgICAgbWFUb29sQm94LkNoZWNrSXRlbShUSURfU09MREVQX0hJREVfSU5ERVBFTkRFTkQsIElzSGlkZU1vZGUoKSk7CiAgICAgICAJICAgIAlHZXREZXBXaW4oKS0+SW52YWxpZGF0ZSgpOyAvL3JlcGFpbnQgTWFpbi1WaWV3CgkJCX0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUSURfU09MREVQX1NFTEVDVF9XT1JLU1BBQ0U6CgkJCWlmIChtcFN0YW5kTHN0KQoJCQl7CgkJCQlpZiAoR2V0VmVyc2lvbigpKSAvLyBWZXJzaW9uIGRpYWxvZyBib3gKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkZWxldGUgbXBTb2xJZE1hcHBlcjsKCSAgICAgICAgICAgICAgICBkZWxldGUgbXBTdGFyV3JpdGVyOwogICAgICAgICAgICAgICAgICAgIG1wT2JqZWN0TGlzdC0+Q2xlYXJBbmREZWxldGUoKTsKCQkJCSAgICBSZWFkU291cmNlKHNhbF9UcnVlKTsKICAgICAgICAgICAgICAgIH0KCQkJfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRJRF9TT0xERVBfQkFDSzoKICAgICAgICAgICAgbWFUb29sQm94LkhpZGVJdGVtKFRJRF9TT0xERVBfQkFDSyk7CgkJCW1hVG9vbEJveC5TaG93SXRlbShUSURfU09MREVQX1NFTEVDVF9XT1JLU1BBQ0UpOyAgLy9kaXNhYmxlZCBmb3IgcHJqIHZpZXcgKGRvdWJsZWNsaWNrIE9ialdpbikKICAgICAgICAgICAgbWFUb29sQm94LlNob3dJdGVtKFRJRF9TT0xERVBfSElERV9JTkRFUEVOREVORCk7ICAvL2Rpc2FibGVkIGZvciBwcmogdmlldyAoZG91YmxlY2xpY2sgT2JqV2luKQogICAgICAgICAgICBtYVRvb2xCb3guU2hvd0l0ZW0oVElEX1NPTERFUF9GSU5EKTsgICAgICAgICAgICAgIC8vZGlzYWJsZWQgZm9yIHByaiB2aWV3IChkb3VibGVjbGljayBPYmpXaW4pCiAgICAgICAgICAgIG1hVG9vbEJveC5SZXNpemUoKTsKCQkJVG9nZ2xlUHJqVmlld1N0YXR1cygpOwogICAgICAgICAgICBicmVhazsKCX0KCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQgU29sRGVwOjpUb2dnbGVIaWRlRGVwZW5kZW5jeSgpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewoJbWJJc0hpZGUgPSAhbWJJc0hpZGU7CgltYVRvb2xCb3guQ2hlY2tJdGVtKFRJRF9TT0xERVBfSElERV9JTkRFUEVOREVORCwgSXNIaWRlTW9kZSgpKTsKCU9iamVjdFdpbiogcFdpbiA9IEdldE9iamVjdExpc3QoKS0+R2V0T2JqZWN0KCAwICk7CglwV2luLT5Ub2dnbGVIaWRlTW9kZSgpOwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzYWxfQm9vbCBTb2xEZXA6OkdldFZlcnNpb24oKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKCVNvbFNlbGVjdFZlcnNpb25EbGcgYVZlcnNpb25EbGcoIEdldERlcFdpbigpLCBtcFN0YW5kTHN0ICk7CglpZiAoIGFWZXJzaW9uRGxnLkV4ZWN1dGUoKSA9PSBSRVRfT0sgKSB7CgkJbXNWZXJzaW9uTWFqb3IgPSBhVmVyc2lvbkRsZy5HZXRWZXJzaW9uTWFqb3IoKTsKICAgICAgICBtc1ZlcnNpb25NaW5vciA9IGFWZXJzaW9uRGxnLkdldFZlcnNpb25NaW5vcigpOwoJCXJldHVybiBzYWxfVHJ1ZTsKCX0KCXJldHVybiBzYWxfRmFsc2U7Cn0KCnZvaWQgU29sRGVwOjpJbml0Q29udGV4dE1lbnVlTWFpblduZCgpCnsKICAgIEluaXRDb250ZXh0TWVudWVQcmpWaWV3V25kKCBtcEJhc2VXaW4gKTsKICAgIHJldHVybjsgLy8gRGlzYWJsZSBub3QgYWN0dWFsbHkgc3VwcG9ydGVkIGl0ZW1zCgogICAgbXBCYXNlV2luLT5tcFBvcHVwLT5JbnNlcnRJdGVtKCBERVBQT1BVUF9BVVRPQVJSQU5HRSwgU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoIkF1dG9hcnJhbmdlIikpIDsKICAgIG1wQmFzZVdpbi0+bXBQb3B1cC0+SW5zZXJ0U2VwYXJhdG9yKCk7CgltcEJhc2VXaW4tPm1wUG9wdXAtPkluc2VydEl0ZW0oIERFUFBPUFVQX1JFQURfU09VUkNFLCBTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSgiUmV2ZXJ0IGFsbCBjaGFuZ2VzIikgKTsKCW1wQmFzZVdpbi0+bXBQb3B1cC0+SW5zZXJ0U2VwYXJhdG9yKCk7CgltcEJhc2VXaW4tPm1wUG9wdXAtPkluc2VydEl0ZW0oIERFUFBPUFVQX09QRU5fU09VUkNFLCBTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSgiT3BlbiIpICk7CgltcEJhc2VXaW4tPm1wUG9wdXAtPkluc2VydEl0ZW0oIERFUFBPUFVQX1dSSVRFX1NPVVJDRSwgU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoIlNhdmUiKSApOwp9Cgp2b2lkIFNvbERlcDo6SW5pdENvbnRleHRNZW51ZVByalZpZXdXbmQoRGVwV2luKiBwQmFzZVdpbiApCnsKICAgIC8vIHRlbXAuIGRpc2FibGVkIHBCYXNlV2luLT5tcFBvcHVwLT5JbnNlcnRJdGVtKCBERVBQT1BVUF9ORVcsIFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCJOZXcgb2JqZWN0IikgKTsKCXBCYXNlV2luLT5tcFBvcHVwLT5JbnNlcnRJdGVtKCBERVBQT1BVUF9aT09NSU4sIFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCJab29tIGluIikgKTsKCXBCYXNlV2luLT5tcFBvcHVwLT5JbnNlcnRJdGVtKCBERVBQT1BVUF9aT09NT1VULCBTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSgiWm9vbSBvdXQiKSApOwoJcEJhc2VXaW4tPm1wUG9wdXAtPkluc2VydFNlcGFyYXRvcigpOwoJLy8gdGVtcCBkaXNhYmxlZCBwQmFzZVdpbi0+bXBQb3B1cC0+SW5zZXJ0SXRlbSggREVQUE9QVVBfQ0xFQVIsIFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCJDbGVhciIpICk7CiAgICBwQmFzZVdpbi0+bXBQb3B1cC0+SW5zZXJ0SXRlbSggREVQUE9QVVBfU0hPV19UT09MQk9YLCBTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSgiU2hvdyBUb29sYm94IikgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpPYmplY3RXaW4gKlNvbERlcDo6UmVtb3ZlT2JqZWN0KCBzYWxfdUludDE2IG5JZCwgc2FsX0Jvb2wgYkRlbGV0ZSApCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewoJUHJqKiBwUHJqOwoKLy9oc2h0YWJsZSBhdWYgc3RhbmQgaGFsdGVuCglPYmplY3RXaW4qIHBXaW4gPSBSZW1vdmVPYmplY3RGcm9tTGlzdCggbXBPYmplY3RMaXN0LCBtblNvbFdpbkNvdW50LCBuSWQsIHNhbF9GYWxzZSApOwoJaWYgKCBwV2luICkKCXsKCQlCeXRlU3RyaW5nIGFCb2R5VGV4dCggcFdpbi0+R2V0Qm9keVRleHQoKSApOwoJCWlmKCAocFByaiA9IG1wU3RhcldyaXRlci0+R2V0UHJqKCBhQm9keVRleHQgKSkgKQoJCXsKCQkJbXBTdGFyV3JpdGVyLT5SZW1vdmUoIHBQcmogKTsKLy9jbGVhbnVwIGlzdCB0ZXVlci4uLgoJCQltcFN0YXJXcml0ZXItPkNsZWFuVXAoKTsKCQkJZGVsZXRlIHBQcmo7CgkJfQoJCWVsc2UKCQkJREJHX0FTU0VSVCggc2FsX0ZhbHNlLCAicHJvamVjdCBub3QgZm91bmQgLSB3cml0ZSIgKTsKCgkJbXBTb2xJZE1hcHBlci0+RGVsZXRlKCBhQm9keVRleHQgKTsKCQlpZiAoIGJEZWxldGUgKQoJCQlkZWxldGUgcFdpbjsKCQlyZXR1cm4gcFdpbjsKCX0KCWVsc2UKCQlyZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzYWxfdUludFB0ciBTb2xEZXA6OkFkZE9iamVjdCggQnl0ZVN0cmluZyYgckJvZHlUZXh0LCBzYWxfQm9vbCBiSW50ZXJhY3QgKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKICAgIHNhbF91SW50UHRyIG5PYmplY3RJZDsKCWlmICggYkludGVyYWN0ICkKCXsKCQluT2JqZWN0SWQgPSBIYW5kbGVOZXdQcmpEaWFsb2coIHJCb2R5VGV4dCApOwoJfQoJZWxzZQoJewovL2hhc2h0YWJsZSBhdWYgc3RhbmQgaGFsdGVuCgkJTXlIYXNoT2JqZWN0KiBwSE9iamVjdDsKCQluT2JqZWN0SWQgPSBBZGRPYmplY3RUb0xpc3QoIG1wQmFzZVdpbiwgbXBPYmplY3RMaXN0LCBtblNvbExhc3RJZCwgbW5Tb2xXaW5Db3VudCwgckJvZHlUZXh0LCBzYWxfRmFsc2UgKTsKCQlwSE9iamVjdCA9IG5ldyBNeUhhc2hPYmplY3QoIG5PYmplY3RJZCwgT2JqSWRUb1B0cihtcE9iamVjdExpc3QsIG5PYmplY3RJZCApKTsKCQltcFNvbElkTWFwcGVyLT5JbnNlcnQoIHJCb2R5VGV4dCwgcEhPYmplY3QgKTsKCX0KICAgIHJldHVybiBuT2JqZWN0SWQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc2FsX3VJbnRQdHIgU29sRGVwOjpBZGRQcmpPYmplY3QoIEJ5dGVTdHJpbmcmIHJCb2R5VGV4dCwgc2FsX0Jvb2wgYkludGVyYWN0ICkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CiAgICBzYWxfdUludFB0ciBuT2JqZWN0SWQ7CglpZiAoIGJJbnRlcmFjdCApCgl7CiAgICAgICAgbk9iamVjdElkID0gSGFuZGxlTmV3RGlyZWN0b3J5RGlhbG9nKCByQm9keVRleHQgKTsKCX0KCWVsc2UKCXsKLy9oc2h0YWJsZSBhdWYgc3RhbmQgaGFsdGVuCgkJTXlIYXNoT2JqZWN0KiBwSE9iamVjdDsKCQluT2JqZWN0SWQgPSBBZGRPYmplY3RUb0xpc3QoIG1wQmFzZVByaldpbiwgbXBPYmplY3RQcmpMaXN0LCBtblByakxhc3RJZCwgbW5QcmpXaW5Db3VudCwgckJvZHlUZXh0ICk7CgkJcEhPYmplY3QgPSBuZXcgTXlIYXNoT2JqZWN0KCBuT2JqZWN0SWQsIE9iaklkVG9QdHIoIG1wT2JqZWN0UHJqTGlzdCwgbk9iamVjdElkICkpOwoJCW1wUHJqSWRNYXBwZXItPkluc2VydCggckJvZHlUZXh0LCBwSE9iamVjdCApOyAvLyBtcFByaklkTWFwcGVyCgl9CiAgICByZXR1cm4gbk9iamVjdElkOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnNhbF91SW50MTYgU29sRGVwOjpBZGRDb25uZWN0b3IoIE9iamVjdFdpbiogcFN0YXJ0V2luLCBPYmplY3RXaW4qIHBFbmRXaW4gKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKLy8JREJHX0FTU0VSVCggRkFMU0UgLCAibm90IHlldCIgKTsKCUJ5dGVTdHJpbmcgc0VuZE5hbWUgPSBwRW5kV2luLT5HZXRCb2R5VGV4dCgpOwoJQnl0ZVN0cmluZyBzU3RhcnROYW1lID0gcFN0YXJ0V2luLT5HZXRCb2R5VGV4dCgpOwoKCVByaiogcFByaiA9IG1wU3RhcldyaXRlci0+R2V0UHJqKCBzRW5kTmFtZSApOwoJaWYgKCBwUHJqICkKCXsKCQlwUHJqLT5BZGREZXBlbmRlbmNpZXMoIHNTdGFydE5hbWUgKTsKCQlyZXR1cm4gQWRkQ29ubmVjdG9yVG9PYmplY3RzKCBwU3RhcnRXaW4sIHBFbmRXaW4gKTsKCX0KCWVsc2UKCXsKCQlEQkdfQVNTRVJUKCBzYWxfRmFsc2UgLCAibm9uIGV4aXN0aW5nIFByb2plY3QiICk7CgkJcmV0dXJuIDE7Cgl9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc2FsX3VJbnQxNiBTb2xEZXA6OlJlbW92ZUNvbm5lY3RvciggT2JqZWN0V2luKiBwU3RhcnRXaW4sIE9iamVjdFdpbiogcEVuZFdpbiApCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewoJU0J5dGVTdHJpbmdMaXN0KiBwUHJqRGVwcyA9IE5VTEw7CglCeXRlU3RyaW5nIHNFbmROYW1lID0gcEVuZFdpbi0+R2V0Qm9keVRleHQoKTsKCUJ5dGVTdHJpbmcgc1N0YXJ0TmFtZSA9IHBTdGFydFdpbi0+R2V0Qm9keVRleHQoKTsKCglQcmoqIHBQcmogPSBtcFN0YXJXcml0ZXItPkdldFByaiggc0VuZE5hbWUgKTsKCXBQcmpEZXBzID0gcFByai0+R2V0RGVwZW5kZW5jaWVzKCBzYWxfRmFsc2UgKTsKCWlmICggcFByakRlcHMgKQoJewoJCUJ5dGVTdHJpbmcqIHBTdHJpbmc7CgkJc2FsX3VJbnRQdHIgblByakRlcHNDb3VudCA9IHBQcmpEZXBzLT5Db3VudCgpOwoJCWZvciAoIHNhbF91SW50UHRyIGogPSBuUHJqRGVwc0NvdW50OyBqID4gMDsgai0tICkKCQl7CgkJCXBTdHJpbmcgPSBwUHJqRGVwcy0+R2V0T2JqZWN0KCBqIC0gMSApOwoJCQlpZiAoIHBTdHJpbmctPkdldFRva2VuKCAwLCAnLicpID09IHNTdGFydE5hbWUgKQoJCQkJcFByakRlcHMtPlJlbW92ZSggcFN0cmluZyApOwoJCX0KCX0KCglyZXR1cm4gUmVtb3ZlQ29ubmVjdG9yRnJvbU9iamVjdHMoIHBTdGFydFdpbiwgcEVuZFdpbiApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQgU29sRGVwOjpSZW1vdmVBbGxPYmplY3RzKCBPYmplY3RMaXN0KiBwT2JqTHN0ICkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CgoJRGVwcGVyOjpSZW1vdmVBbGxPYmplY3RzKCBwT2JqTHN0ICk7CgoJaWYgKCBtcFNvbElkTWFwcGVyICkKCXsKCQlkZWxldGUgbXBTb2xJZE1hcHBlcjsKCQltcFNvbElkTWFwcGVyID0gTlVMTDsKCX0KCWlmICggbXBTdGFyV3JpdGVyICkKCXsKCQlkZWxldGUgbXBTdGFyV3JpdGVyOwoJCW1wU3RhcldyaXRlciA9IE5VTEw7Cgl9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc2FsX3VJbnRQdHIgU29sRGVwOjpHZXRTdGFydChTb2xJZE1hcHBlciogcElkTWFwcGVyLCBPYmplY3RMaXN0KiBwT2JqTGlzdCkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7Ci8vCURCR19BU1NFUlQoIEZBTFNFICwgInNvbGRlcCIgKTsKCU15SGFzaE9iamVjdCogcEhPYmplY3QgPSBwSWRNYXBwZXItPkZpbmQoICJudWxsIiApOy8vbnVsbF9wcm9qZWN0CgoJaWYgKCAhcEhPYmplY3QgKSB7CgkJQnl0ZVN0cmluZyBzTnVsbFByaiA9ICJudWxsIjsvL251bGxfcHJvamVjdAoJCXNhbF91SW50UHRyIG5PYmplY3RJZCA9IEFkZE9iamVjdCggc051bGxQcmosIHNhbF9GYWxzZSApOwoJCU9iaklkVG9QdHIoIHBPYmpMaXN0LCBuT2JqZWN0SWQgKS0+U2V0Vmlld01hc2soIDEgKTsKCQlyZXR1cm4gbk9iamVjdElkOwoJfQoKCXJldHVybiBwSE9iamVjdC0+R2V0SWQoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzYWxfdUludFB0ciBTb2xEZXA6OkdldFN0YXJ0UHJqKFNvbElkTWFwcGVyKiAsIE9iamVjdExpc3QqICkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7Ci8vCURCR19BU1NFUlQoIEZBTFNFICwgInByamRlcCIgKTsKCU15SGFzaE9iamVjdCogcEhPYmplY3QgPSBtcFByaklkTWFwcGVyLT5GaW5kKCBCeXRlU3RyaW5nKCAibnVsbCIgKSApOyAvL251bGxfZGlyCglpZiAoICFwSE9iamVjdCApCgl7CgkJQnl0ZVN0cmluZyBic051bGwoIm51bGwiKTsKCQlzYWxfdUludFB0ciBuT2JqZWN0SWQgPSBBZGRQcmpPYmplY3QoIGJzTnVsbCwgc2FsX0ZhbHNlKTsgLy9udWxsX2RpcgoJCXJldHVybiBuT2JqZWN0SWQ7Cgl9CgllbHNlCgkJcmV0dXJuIHBIT2JqZWN0LT5HZXRJZCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnNhbF91SW50MTYgU29sRGVwOjpPcGVuU291cmNlKCkKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CglpZiAoIG1wU3RhbmRMc3QgKSB7CgkJaWYgKCBHZXRWZXJzaW9uKCkpCgkJCXJldHVybiBSZWFkU291cmNlKCk7Cgl9CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzYWxfdUludDE2IFNvbERlcDo6UmVhZFNvdXJjZShzYWxfQm9vbCBiVXBkYXRlcikKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp7CgltcEJhc2VXaW4tPkVuYWJsZVBhaW50KCBzYWxfRmFsc2UgKTsKICAgIG1wQmFzZVdpbi0+SGlkZSgpOwoJc2FsX3VJbnRQdHIgbk9iamVjdElkLCBuSGFzaGVkSWQ7CglzYWxfdUludFB0ciBpOwoJTXlIYXNoT2JqZWN0KiBwSE9iamVjdDsKCUJ5dGVTdHJpbmcqIHBTdHI7CglPYmplY3RXaW4gKnBTdGFydFdpbiwgKnBFbmRXaW47CgogICAgbXBTb2xJZE1hcHBlciA9IG5ldyBTb2xJZE1hcHBlciggNjM5OTcgKTsKICAgIGlmIChtcFN0YW5kTHN0ICYmIGJVcGRhdGVyKQogICAgewogICAgICAgIG1wU3RhcldyaXRlciA9IG5ldyBTdGFyV3JpdGVyKCBtcFN0YW5kTHN0LCBtc1ZlcnNpb25NYWpvciwgbXNWZXJzaW9uTWlub3IsIHNhbF9UcnVlICk7CiAgICB9IGVsc2UKICAgIHsKICAgICAgICBTb2xhckZpbGVMaXN0KiBwU29sYXJGaWxlTGlzdDsKICAgICAgICBwU29sYXJGaWxlTGlzdCA9IEdldFByakxpc3RGcm9tRGlyKCk7CiAgICAgICAgbXBTdGFyV3JpdGVyID0gbmV3IFN0YXJXcml0ZXIoIHBTb2xhckZpbGVMaXN0LCBzYWxfVHJ1ZSApOwogICAgfQoJQnl0ZVN0cmluZyBzVGl0bGUoIFNPTERFUExfTkFNRSApOwoJaWYgKCBtcFN0YXJXcml0ZXItPkdldE1vZGUoKSA9PSBTVEFSX01PREVfU0lOR0xFX1BBUlNFICkgewoJCXNUaXRsZSArPSBCeXRlU3RyaW5nKCAiIC0gbW9kZTogc2luZ2xlIGZpbGUgWyIgKTsKCSAgIAlzVGl0bGUgKz0gKEJ5dGVTdHJpbmcpIG1wU3RhcldyaXRlci0+R2V0TmFtZSgpOwoJCXNUaXRsZSArPSBCeXRlU3RyaW5nKCAiXSIgKTsKCX0KCWVsc2UgaWYgKCBtcFN0YXJXcml0ZXItPkdldE1vZGUoKSA9PSBTVEFSX01PREVfTVVMVElQTEVfUEFSU0UgKSB7CgkJc1RpdGxlICs9IEJ5dGVTdHJpbmcoICIgLSBtb2RlOiBtdWx0aXBsZSBmaWxlcyBbIiApOwoJCXNUaXRsZSArPSBCeXRlU3RyaW5nKCAiXSIgKTsKCX0KCVNldFRpdGxlKCBTdHJpbmcoIHNUaXRsZSwgUlRMX1RFWFRFTkNPRElOR19VVEY4KSApOwoKCXNhbF91SW50UHRyIG5Db3VudCA9IG1wU3RhcldyaXRlci0+Q291bnQoKTsKCWZvciAoIGk9MDsgaTxuQ291bnQ7IGkrKyApCgl7CgkJUHJqICpwUHJqID0gbXBTdGFyV3JpdGVyLT5HZXRPYmplY3QoaSk7CgkJQnl0ZVN0cmluZyBzUHJqTmFtZSA9IHBQcmotPkdldFByb2plY3ROYW1lKCk7CgkJbk9iamVjdElkID0gQWRkT2JqZWN0KCBzUHJqTmFtZSwgc2FsX0ZhbHNlICk7CgkJT2JqSWRUb1B0ciggbXBPYmplY3RMaXN0LCBuT2JqZWN0SWQgKS0+U2V0Vmlld01hc2soIDEgKTsKCX0KCWZvciAoIGk9MDsgaTxuQ291bnQ7IGkrKyApCgl7CgkJUHJqICpwUHJqID0gbXBTdGFyV3JpdGVyLT5HZXRPYmplY3QoaSk7CgkJU0J5dGVTdHJpbmdMaXN0ICpwTHN0ID0gcFByai0+R2V0RGVwZW5kZW5jaWVzKCBzYWxfRmFsc2UgKTsKCQlpZiAoIHBMc3QgKQoJCXsKCQkJc2FsX3VJbnRQdHIgbkRlcENvdW50ID0gcExzdC0+Q291bnQoKTsKCQkJZm9yICggc2FsX3VJbnRQdHIgbT0wOyBtPG5EZXBDb3VudDsgbSsrKQoJCQl7CgkJCQlwU3RyID0gcExzdC0+R2V0T2JqZWN0KG0pOwoJCQkJcEhPYmplY3QgPSBtcFNvbElkTWFwcGVyLT5GaW5kKCAqcFN0ciApOwoJCQkJLyppZiAoICFwSE9iamVjdCApCgkJCQl7CgkvLyBjcmVhdGUgbmV3IHByagoJCQkJCVByaiAqcE5ld1ByaiA9IG5ldyBQcmooICpwU3RyICk7CgkJCQkJQnl0ZVN0cmluZyBzUHJqTmFtZSA9IHBOZXdQcmotPkdldFByb2plY3ROYW1lKCk7CgkJCQkJbk9iamVjdElkID0gQWRkT2JqZWN0KCBzUHJqTmFtZSwgc2FsX0ZhbHNlICk7CgkJCQkJcEhPYmplY3QgPSBtcFNvbElkTWFwcGVyLT5GaW5kKCAqcFN0ciApOwoJCQkJCU9iaklkVG9QdHIoIG1wT2JqZWN0TGlzdCwgbk9iamVjdElkICktPlNldFZpZXdNYXNrKCAyICk7CgkJCQl9Ki8KCgkJCQlpZiAoIHBIT2JqZWN0ICkKCQkJCXsKCQkJCW5IYXNoZWRJZCA9IHBIT2JqZWN0LT5HZXRJZCgpOwoJCQkJQnl0ZVN0cmluZyBzRl9PczIgPSBwUHJqLT5HZXRQcm9qZWN0TmFtZSgpOwoJCQkJcFN0ciA9ICZzRl9PczI7CgkJCQlwSE9iamVjdCA9IG1wU29sSWRNYXBwZXItPkZpbmQoICpwU3RyICk7CgkJCQluT2JqZWN0SWQgPSBwSE9iamVjdC0+R2V0SWQoKTsKCQkJCXBTdGFydFdpbiA9IE9iaklkVG9QdHIoIG1wT2JqZWN0TGlzdCwgbkhhc2hlZElkICk7CgkJCQlwRW5kV2luID0gT2JqSWRUb1B0ciggbXBPYmplY3RMaXN0LCBuT2JqZWN0SWQgKTsKCQkJCUFkZENvbm5lY3RvclRvT2JqZWN0cyggcFN0YXJ0V2luLCBwRW5kV2luICk7CgkJCX0KCQl9Cgl9Cgl9CiAgICBpZiAoIUlzUHJqVmlldygpKQogICAgewoJICAgIEF1dG9BcnJhbmdlKCBtcFNvbElkTWFwcGVyLCBtcE9iamVjdExpc3QsIEdldFN0YXJ0KG1wU29sSWRNYXBwZXIsbXBPYmplY3RMaXN0KSwgMCwgR2V0U3RhcnQobXBTb2xJZE1hcHBlcixtcE9iamVjdExpc3QpICk7CgkgICAgR2V0RGVwV2luKCktPkVuYWJsZVBhaW50KCBzYWxfVHJ1ZSApOwogICAgfQoJcmV0dXJuIDA7Cn0KClNvbGFyRmlsZUxpc3QqIFNvbERlcDo6R2V0UHJqTGlzdEZyb21EaXIoKQp7CiAgICBTb2xhckZpbGVMaXN0KiBwU29sYXJGaWxlTGlzdCA9IG5ldyBTb2xhckZpbGVMaXN0KCk7CiAgICBTdHJpbmcgc1ByakRpciggU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoICJwcmoiICkpOwoJU3RyaW5nIHNCdWlsZExzdCggU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoICJidWlsZC5sc3QiICkpOwogICAgRGlyRW50cnkgYUN1cnJlbnQoIGdldGVudiggU09VUkNFUk9PVCApICk7CgogICAgYUN1cnJlbnQuVG9BYnMoKTsKICAgIERpciBhRGlyKCBhQ3VycmVudCwgRlNZU19LSU5EX0RJUiApOwoKCXNhbF91SW50MTYgbkVudHJpZXMgPSBhRGlyLkNvdW50KCk7CglpZiggbkVudHJpZXMgKQoJewoJCVVuaVN0cmluZ0xpc3QgYVNvcnREaXJMaXN0OwoJCWZvciAoIHNhbF91SW50MTYgbiA9IDA7IG4gPCBuRW50cmllczsgbisrICkKCQl7CgkJCURpckVudHJ5JiByRW50cnkgPSBhRGlyW25dOwoJCQlVbmlTdHJpbmcgYU5hbWUoIHJFbnRyeS5HZXROYW1lKCkgKTsKCQkJaWYoIGFOYW1lLkxlbigpICYmICggYU5hbWUuR2V0Q2hhcigwKSAhPSAnLicgKSAmJiByRW50cnkuRXhpc3RzKCkgKQoJCQl7CiAgICAgICAgICAgICAgICByRW50cnkgKz0gRGlyRW50cnkoIHNQcmpEaXIgKTsKICAgICAgICAgICAgICAgIHJFbnRyeSArPSBEaXJFbnRyeSggc0J1aWxkTHN0ICk7CiAgICAgICAgICAgICAgICBpZiAockVudHJ5LkV4aXN0cygpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHBTb2xhckZpbGVMaXN0LT5JbnNlcnQoIG5ldyBTdHJpbmcoIHJFbnRyeS5HZXRGdWxsKCkgKSwgTElTVF9BUFBFTkQgKTsKICAgICAgICAgICAgICAgICAgICBCeXRlU3RyaW5nIGFOYW1lX2RiZyhyRW50cnkuR2V0RnVsbCgpLFJUTF9URVhURU5DT0RJTkdfVVRGOCk7CiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRvdXQsICJibGE6JXNcbiIsIGFOYW1lX2RiZy5HZXRCdWZmZXIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBpZiAoICFwU29sYXJGaWxlTGlzdC0+Q291bnQoKSApCiAgICB7CiAgICAgICAgIC8vaXMgZW1wdHkhISBUQkQKICAgICAgICAgZGVsZXRlIHBTb2xhckZpbGVMaXN0OwogICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHJldHVybiBwU29sYXJGaWxlTGlzdDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzYWxfdUludDE2IFNvbERlcDo6V3JpdGVTb3VyY2UoKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKLyogenVyIFNpY2hlcmhlaXQgZGVha3RpdmllcnQKCXNhbF91SW50MTYgbk1vZGUgPSBtcFN0YXJXcml0ZXItPkdldE1vZGUoKTsKCWlmICggbk1vZGUgPT0gU1RBUl9NT0RFX1NJTkdMRV9QQVJTRSApIHsKCQlCeXRlU3RyaW5nIHNGaWxlTmFtZSA9IG1wU3RhcldyaXRlci0+R2V0TmFtZSgpOwoJCWlmICggc0ZpbGVOYW1lLkxlbigpKSB7CgkJCW1wU3RhcldyaXRlci0+V3JpdGUoIFN0cmluZyggc0ZpbGVOYW1lLCBSVExfVEVYVEVOQ09ESU5HX1VURjgpICk7CgkJCW1wU3RhcldyaXRlci0+UmVtb3ZlUHJvamVjdCggQnl0ZVN0cmluZyggIm51bGwiKSk7ICAvL251bGxfcHJvamVjdAoJCX0KCX0KCWVsc2UgaWYgKCBuTW9kZSA9PSBTVEFSX01PREVfTVVMVElQTEVfUEFSU0UgKSB7CgkvLyAqT0JPKgoJLy9TdHJpbmcgc1Jvb3QgPSBtcFN0YXJXcml0ZXItPkdldFNvdXJjZVJvb3QoKTsKCS8vbmljaHQgbWVociB1bnRlcnN0/HR6dCBtcFN0YXJXcml0ZXItPkdldFNvdXJjZVJvb3QoKQoJCUJ5dGVTdHJpbmcgc0ZpbGVOYW1lID0gbXBTdGFyV3JpdGVyLT5HZXROYW1lKCk7CgkJRGlyRW50cnkgYUVudHJ5KCBzRmlsZU5hbWUgKTsKCQlhRW50cnkuVG9BYnMoKTsKCQlhRW50cnkgPSBhRW50cnkuR2V0UGF0aCgpLkdldFBhdGgoKS5HZXRQYXRoKCk7CgkJU3RyaW5nIHNSb290ID0gYUVudHJ5LkdldEZ1bGwoKTsKCgkJaWYgKCBzUm9vdC5MZW4oKSkgewoJCQltcFN0YXJXcml0ZXItPlJlbW92ZVByb2plY3QoIEJ5dGVTdHJpbmcoICJudWxsIikpOyAvL251bGxfcHJvamVjdAoJCQltcFN0YXJXcml0ZXItPldyaXRlTXVsdGlwbGUoIHNSb290ICk7CgkJfQoJfQoqLwoJcmV0dXJuIDE7Cn0KCnNhbF91SW50MTYgU29sRGVwOjpMb2FkKCBjb25zdCBCeXRlU3RyaW5nJiByRmlsZU5hbWUgKQp7Ci8vIG1vdmVkIGZyb20gZGVwcGVyIGNsYXNzCglEQkdfQVNTRVJUKCBzYWxfRmFsc2UgLCAieW91IGFyZSBkZWFkISIgKTsKCVN2RmlsZVN0cmVhbSBhSW5GaWxlKCBTdHJpbmcoIHJGaWxlTmFtZSwgUlRMX1RFWFRFTkNPRElOR19VVEY4ICksIFNUUkVBTV9SRUFEICk7CglkZXBwZXJfaGVhZCBkaDsKCXNhbF91SW50UHRyIGk7CglzYWxfdUludFB0ciBuTG9hZE9mZnMgPSBtblNvbExhc3RJZDsgICAgIC8vb3IgUHJqPz8KCU9iamVjdFdpbiogcE5ld1dpbjsKCWFJbkZpbGUuUmVhZCggJmRoLCBzaXplb2YoIGRoICkpOwoKCXNhbF91SW50UHRyIG5PYmpDb3VudCA9IGRoLm5PYmplY3RDb3VudDsKCXNhbF91SW50UHRyIG5DbmN0ckNvdW50ID0gZGgubkNuY3RyQ291bnQ7CgoJZm9yICggaT0wOyBpIDwgbk9iakNvdW50IDsgaSsrICkKCXsKCQlPYmplY3RXaW4qIHBXaW4gPSBuZXcgT2JqZWN0V2luKCBtcEJhc2VXaW4sIFdCX0JPUkRFUiApOwoJCXBXaW4tPkxvYWQoIGFJbkZpbGUgKTsKCQlwTmV3V2luID0gT2JqSWRUb1B0ciggbXBPYmplY3RMaXN0LCBBZGRPYmplY3RUb0xpc3QoIG1wQmFzZVdpbiwgbXBPYmplY3RMaXN0LCBtblNvbExhc3RJZCwgbW5Tb2xXaW5Db3VudCwgcFdpbi0+R2V0Qm9keVRleHQoKSwgc2FsX0ZhbHNlICkpOwoJCXBOZXdXaW4tPlNldElkKCBuTG9hZE9mZnMgKyBwV2luLT5HZXRJZCgpKTsKCQlwTmV3V2luLT5TZXRQb3NQaXhlbCggcFdpbi0+R2V0UG9zUGl4ZWwoKSk7CgkJcE5ld1dpbi0+U2V0U2l6ZVBpeGVsKCBwV2luLT5HZXRTaXplUGl4ZWwoKSk7Cgl9CgoJc2FsX3VJbnRQdHIgblN0YXJ0SWQ7CglzYWxfdUludFB0ciBuRW5kSWQ7Ci8vCXVlYmVyIGFkZGNvbm5lY3RvciBmdWVocmVuIQoJZm9yICggaT0wOyBpIDwgbkNuY3RyQ291bnQgOyBpKysgKQoJewoJCUNvbm5lY3RvciogcENvbiA9IG5ldyBDb25uZWN0b3IoIG1wQmFzZVdpbiwgV0JfTk9CT1JERVIgKTsKCQlwQ29uLT5Mb2FkKCBhSW5GaWxlICk7CgoJCW5TdGFydElkID0gbkxvYWRPZmZzICsgcENvbi0+R2V0U3RhcnRJZCgpOwoJCW5FbmRJZCA9IG5Mb2FkT2ZmcyArIHBDb24tPkdldEVuZElkKCk7CgoJCU9iamVjdFdpbiogcFN0YXJ0V2luID0gT2JqSWRUb1B0ciggbXBPYmplY3RMaXN0LCBuU3RhcnRJZCApOwoJCU9iamVjdFdpbiogcEVuZFdpbiA9IE9iaklkVG9QdHIoIG1wT2JqZWN0TGlzdCwgbkVuZElkICk7CgoJCXBDb24tPkluaXRpYWxpemUoIHBTdGFydFdpbiwgcEVuZFdpbiApOwoJfQoKCglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzYWxfQm9vbCBTb2xEZXA6OlZpZXdDb250ZW50KCBCeXRlU3RyaW5nJiByT2JqZWN0TmFtZSApCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewoJbXBGb2N1c1dpbiA9IE5VTEw7CglTZXRQcmpWaWV3U3RhdHVzKHNhbF9UcnVlKTsKCglmb3IgKCBzYWxfdUludFB0ciBpID0gMDsgaSA8IG1wT2JqZWN0TGlzdC0+Q291bnQoKSAmJiAhbXBGb2N1c1dpbjsgaSsrICkKCQlpZiAoIG1wT2JqZWN0TGlzdC0+R2V0T2JqZWN0KCBpICktPkhhc0ZvY3VzKCkpCgkJCW1wRm9jdXNXaW4gPSBtcE9iamVjdExpc3QtPkdldE9iamVjdCggaSApOwogICAgLy9IaWRlT2JqZWN0c0FuZENvbm5lY3Rpb25zKCBtcE9iamVjdExpc3QgKTsKCW1wUHJvY2Vzc1dpbi0+UmVzaXplKCk7CiAgICBHZXREZXBXaW4oKS0+U2hvdygpOwoJcmV0dXJuIEluaXRQcmooIHJPYmplY3ROYW1lICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc2FsX0Jvb2wgU29sRGVwOjpJbml0UHJqKCBCeXRlU3RyaW5nJiByTGlzdE5hbWUgKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKCXNhbF91SW50UHRyIG5PYmplY3RJZCwgbkhhc2hlZElkOwoJc2FsX3VJbnRQdHIgaSwgajsKCU15SGFzaE9iamVjdCogcEhPYmplY3Q7CglCeXRlU3RyaW5nICpwRGVwTmFtZTsKCUJ5dGVTdHJpbmcgKnBGbGFnTmFtZTsKCVByaiogcFByajsKCU9iamVjdFdpbiAqcFN0YXJ0V2luLCAqcEVuZFdpbjsKCW1hVG9vbEJveC5IaWRlSXRlbShUSURfU09MREVQX1NFTEVDVF9XT1JLU1BBQ0UpOwoJbWFUb29sQm94LkhpZGVJdGVtKFRJRF9TT0xERVBfSElERV9JTkRFUEVOREVORCk7CgltYVRvb2xCb3guSGlkZUl0ZW0oVElEX1NPTERFUF9GSU5EKTsKCW1hVG9vbEJveC5TaG93SXRlbShUSURfU09MREVQX0JBQ0spOwoJbWFUb29sQm94LkludmFsaWRhdGUoKTsKCiAgICAvL2NsZWFuIHVwCiAgICBtcE9iamVjdFByakxpc3QtPkNsZWFyQW5kRGVsZXRlKCk7CiAgICBHZXREZXBXaW4oKS0+Q2xlYXJDb25uZWN0b3JMaXN0KCk7CiAgICBpZiAobXBQcmpJZE1hcHBlcikgZGVsZXRlIG1wUHJqSWRNYXBwZXI7CiAgICBtcFByaklkTWFwcGVyID0gbmV3IFNvbElkTWFwcGVyKCA2Mzk5NyApOyAvL2dlbmVyYXRlIGNsZWFuIG1hcHBlcgogICAgbW5QcmpXaW5Db3VudCA9IDA7CgltblByakxhc3RJZCA9IDA7CgoJc2FsX3VJbnRQdHIgbkNvdW50ID0gbXBTdGFyV3JpdGVyLT5Db3VudCgpOwoJR2V0RGVwV2luKCktPkVuYWJsZVBhaW50KCBzYWxfRmFsc2UgKTsKICAgIFBvaW50IGFQbnQgPSBHZXRHcmFwaFdpbigpLT5HZXRQb3NQaXhlbCgpOwogICAgU2l6ZSBhU2l6ZSA9IEdldEdyYXBoV2luKCktPkdldFNpemVQaXhlbCgpOwoKICAgIEdldEdyYXBoV2luKCktPlNldFBvc1NpemVQaXhlbCggYVBudCwgYVNpemUgKTsgICAgICAgICAvLyBIaWVyIHdpcmQgZGFzIFdpbmRvdyBnZXNldHp0CgoJc2FsX0Jvb2wgYlJldHVybiA9IHNhbF9GYWxzZTsKCglmb3IgKCBpPTA7IGk8bkNvdW50OyBpKysgKQoJewovLyBwUHJqLT5HZXRQcm9qZWN0TmFtZSgpIHJldHVybnMgdGhlIG5hbWUgb2YKLy8gdGhlIHByb2plY3QgZS5nLiBzdnRvb2xzCgkJcFByaiA9IG1wU3RhcldyaXRlci0+R2V0T2JqZWN0KGkpOwoJCUJ5dGVTdHJpbmcgc1Byak5hbWUgPSBwUHJqLT5HZXRQcm9qZWN0TmFtZSgpOwoJCWlmICggc1Byak5hbWUgPT0gckxpc3ROYW1lICkKCQl7CgkJCWJSZXR1cm4gPSBzYWxfVHJ1ZTsKCgkJCW1wUHJqID0gbXBTdGFyV3JpdGVyLT5HZXRPYmplY3QoaSk7CgkJCXNhbF91SW50UHRyIG5EaXJDb3VudCA9IG1wUHJqLT5Db3VudCgpOwoJCQlmb3IgKCBqPTA7IGo8bkRpckNvdW50OyBqKysgKQoJCQl7CgkJCQlDb21tYW5kRGF0YSAqcERhdGEgPSBtcFByai0+R2V0T2JqZWN0KGopOwoJCQkJZnByaW50Ziggc3Rkb3V0LCAiXHRQcm9qZWN0RGlyIDogJXNcbiIsCgkJCQkJCXBEYXRhLT5HZXRMb2dGaWxlKCkuR2V0QnVmZmVyKCkpOwovLyBwRGF0YS0+R2V0TG9nRmlsZSgpIGNvbnRhaW5zIGludGVybmFsIHByb2plY3QgSURzCi8vIGUuZy4gc3RfbWtvdXQgZXRjLgoJCQkJaWYgKCBwRGF0YS0+R2V0TG9nRmlsZSgpICE9ICIiICkKCQkJCXsKCQkJCQlCeXRlU3RyaW5nIHNJdGVtID0gcERhdGEtPkdldExvZ0ZpbGUoKTsKCQkJCQluT2JqZWN0SWQgPSBBZGRQcmpPYmplY3QoIHNJdGVtLCBzYWxfRmFsc2UpOwovLyB0aGVyZSBtYXkgYmUgZmFzdGVyIHdheXMuLi4uLi4KCQkJCQlPYmplY3RXaW4gKnBXaW4gPSBPYmpJZFRvUHRyKCBtcE9iamVjdFByakxpc3QsIG5PYmplY3RJZCApOwoJCQkJCXBXaW4tPlNldFZpZXdNYXNrKCAweDAwMDEgKTsKLy8gcERhdGEtPkdldFBhdGgoKSBjb250YWlucyBpbnRlcm5hbCBwcm9qZWN0IGRpcmVjdG9yaWVzCi8vIGUuZy4gc3Z0b29scy9pbmMgZXRjLgogICAgICAgICAgICAgICAgICAgIEJ5dGVTdHJpbmcgc1BhdGggPSBwRGF0YS0+R2V0UGF0aCgpOwoJCQkJCXBXaW4tPlNldFRpcFRleHQoIHNQYXRoICk7CgkJCQl9CgkJCX0KCi8vIHNldCBjb25uZWN0b3JzIGZvciBkZXBlbmRlbmNpZXMgaGVyZQoJCQlmb3IgKCBqPTA7IGo8bkRpckNvdW50OyBqKysgKQoJCQl7CgkJCQlDb21tYW5kRGF0YSAqcERhdGEgPSBtcFByai0+R2V0T2JqZWN0KGopOwoJCQkJU0J5dGVTdHJpbmdMaXN0ICpwRGVwcyA9IHBEYXRhLT5HZXREZXBlbmRlbmNpZXMoKTsKCQkJCWlmICggcERlcHMgKQoJCQkJewoJCQkJCUJ5dGVTdHJpbmcgc0ZsYWdOYW1lID0gcERhdGEtPkdldExvZ0ZpbGUoKTsKCQkJCQlwRmxhZ05hbWUgPSAmc0ZsYWdOYW1lOwoJCQkJCS8vcEhPYmplY3QgPSBtcFByaklkTWFwcGVyLT5GaW5kKCAoKnBGbGFnTmFtZSkuR2V0VG9rZW4oIDAsICcuJykpOy8vbXBTb2xJZE1hcHBlciBzZWUgUmVhZFNvdXJjZSgpCiAgICAgICAgICAgICAgICAgICAgcEhPYmplY3QgPSBtcFByaklkTWFwcGVyLT5GaW5kKCBzRmxhZ05hbWUuR2V0VG9rZW4oIDAsICcuJykpOwogICAgICAgICAgICAgICAgICAgIGlmIChwSE9iamVjdCkKICAgICAgICAgICAgICAgICAgICB7CgogICAgCQkJCQluT2JqZWN0SWQgPSBwSE9iamVjdC0+R2V0SWQoKTsKCgkgICAgCQkJCXNhbF91SW50UHRyIG5EZXBDb3VudCA9IHBEZXBzLT5Db3VudCgpOwoJCSAgICAJCQlmb3IgKCBzYWxfdUludFB0ciBrPTA7IGs8bkRlcENvdW50OyBrKysgKQoJCQkgICAgCQl7CgkJCQkgICAgCQlwRGVwTmFtZSA9IHBEZXBzLT5HZXRPYmplY3Qoayk7CgkJCQkJICAgIAlwSE9iamVjdCA9IG1wUHJqSWRNYXBwZXItPkZpbmQoICgqcERlcE5hbWUpLkdldFRva2VuKCAwLCAnLicpKTsKCQkJCQkJICAgIGlmIChwSE9iamVjdCApCiAgICAJCQkJCQl7CgkgICAgCQkJCQkJbkhhc2hlZElkID0gcEhPYmplY3QtPkdldElkKCk7CgkJICAgIAkJCQkJcFN0YXJ0V2luID0gT2JqSWRUb1B0ciggbXBPYmplY3RQcmpMaXN0LCBuSGFzaGVkSWQgKTsKCQkJICAgIAkJCQlwRW5kV2luID0gT2JqSWRUb1B0ciggbXBPYmplY3RQcmpMaXN0LCBuT2JqZWN0SWQgKTsKCgkJCQkgICAgCQkJQWRkQ29ubmVjdG9yVG9PYmplY3RzKCBwU3RhcnRXaW4sIHBFbmRXaW4gKTsKCQkJCQkgICAgCX0KCQkJCQkJICAgIGVsc2UKICAgIAkJCQkJCXsKCSAgICAJCQkJCQlTdHJpbmcgc01lc3NhZ2U7CgkJICAgIAkJCQkJc01lc3NhZ2UgKz0gU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoImNhbid0IGZpbmQgIik7CgkJCSAgICAJCQkJc01lc3NhZ2UgKz0gU3RyaW5nKCAqcERlcE5hbWUsIFJUTF9URVhURU5DT0RJTkdfVVRGOCApOwoJCQkJICAgIAkJCXNNZXNzYWdlICs9IFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCIuXG5kZXBlbmRlbmN5IGlnbm9yZWQiKTsKCQkJCQkgICAgCQlXYXJuaW5nQm94IGFCb3goIEdldERlcFdpbigpLCBXQl9PSywgc01lc3NhZ2UpOwoJCQkJCQkgICAgCWFCb3guRXhlY3V0ZSgpOwoJCQkJCQkgICAgfQoJCQkJCSAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoJCQkJfQoKCQkJfQoKCQkJYnJlYWs7CgkJfQoJfQoJQnl0ZVN0cmluZyBzTnVsbERpciA9ICJudWxsIjsKCW5PYmplY3RJZCA9IEFkZFByak9iamVjdCggc051bGxEaXIsIHNhbF9GYWxzZSk7CglPYmplY3RXaW4gKnBXaW4gPSBPYmpJZFRvUHRyKCBtcE9iamVjdFByakxpc3QsIG5PYmplY3RJZCApOwoJcFdpbi0+U2V0Vmlld01hc2soIDB4MDAwMSApOwoJbXBHcmFwaFByaldpbi0+RW5hYmxlUGFpbnQoIHNhbF9UcnVlICk7CiAgICAvL2RlYnVnCi8vICAgIGludCB0ZXN0X2wgPSBHZXRTdGFydFByaihtcFByaklkTWFwcGVyLCBtcE9iamVjdFByakxpc3QpOwovLyAgICBPYmplY3RXaW4gKnBUZXN0V2luID0gT2JqSWRUb1B0ciggbXBPYmplY3RQcmpMaXN0LCB0ZXN0X2wgKTsKCUF1dG9BcnJhbmdlKCBtcFByaklkTWFwcGVyLCBtcE9iamVjdFByakxpc3QsIEdldFN0YXJ0UHJqKG1wUHJqSWRNYXBwZXIsIG1wT2JqZWN0UHJqTGlzdCksIDAsIEdldFN0YXJ0UHJqKG1wUHJqSWRNYXBwZXIsIG1wT2JqZWN0UHJqTGlzdCkgKTsKICAgIG1wR3JhcGhXaW4tPkhpZGUoKTsKICAgIG1wR3JhcGhQcmpXaW4tPlNob3coKTsKCW1wR3JhcGhQcmpXaW4tPkludmFsaWRhdGUoKTsKCglyZXR1cm4gYlJldHVybjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzYWxfdUludDE2IFNvbERlcDo6Q2xvc2VXaW5kb3coKQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnsKCgkoKFN5c3RlbVdpbmRvdyopbXBQcm9jZXNzV2luKS0+Q2xvc2UoKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQgU29sRGVwOjpTaG93SGVscCgpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewoJU3ZGaWxlU3RyZWFtIGFIZWxwRmlsZSggU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoICJnOlxcc29sZGVwLmhscCIgKSwgU1RSRUFNX1JFQUQgKTsKCVN0cmluZyBhSGVscFRleHQ7CglCeXRlU3RyaW5nIGFHZXRTdHI7CgoJaWYgKCBhSGVscEZpbGUuSXNPcGVuKCkgKQoJewoJCXdoaWxlICggYUhlbHBGaWxlLlJlYWRMaW5lKCBhR2V0U3RyICkgKQoJCXsKCQkJYUhlbHBUZXh0ICs9IFN0cmluZyAoYUdldFN0ciwgUlRMX1RFWFRFTkNPRElOR19VVEY4KTsKCQkJYUhlbHBUZXh0ICs9IFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCJcbiIpOwoJCX0KCX0KCWVsc2UKCQlhSGVscFRleHQgPSBTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSgiTm8gSGVscGZpbGUgZm91bmQuIik7CgoJU29sSGVscERsZyBhSGVscERsZyggbXBCYXNlV2luLCBEdFNvZFJlc0lkKCBSSURfU0RfRElBTE9HX0hFTFAgKSk7CglhSGVscERsZy5tYU1MRUhlbHAuU2V0VGV4dCggYUhlbHBUZXh0ICk7CglhSGVscERsZy5tYU1MRUhlbHAuU2V0UmVhZE9ubHkoKTsKCWFIZWxwRGxnLm1hTUxFSGVscC5FbmFibGVGb2N1c1NlbGVjdGlvbkhpZGUoIHNhbF9UcnVlICk7CglhSGVscERsZy5FeGVjdXRlKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc2FsX0Jvb2wgU29sRGVwOjpGaW5kUHJvamVjdCgpCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KewoJU29sRmluZFByb2plY3REbGcgYUZpbmRQcm9qZWN0RGxnKCBHZXREZXBXaW4oKSwgR2V0T2JqZWN0TGlzdCgpICk7CglPYmplY3RXaW4qIHBPYmplY3RXaW4gPSBOVUxMOwogICAgbXBPYmplY3RMaXN0LT5SZXNldFNlbGVjdGVkT2JqZWN0KCk7CiAgICBpZiAoSXNIaWRlTW9kZSgpKQogICAgewogICAgICAgIEdldERlcFdpbigpLT5JbnZhbGlkYXRlKCk7CiAgICB9CgogICAgbXBGb2N1c1dpbj1OVUxMOwoKCWlmICggYUZpbmRQcm9qZWN0RGxnLkV4ZWN1dGUoKSA9PSBSRVRfT0sgKSB7CgkJbXNQcm9qZWN0ID0gYUZpbmRQcm9qZWN0RGxnLkdldFByb2plY3QoKTsKCQkvL25vdyB3ZSBoYXZlIGEgcHJvamVjdCBzdHJpbmcKCiAgICAgICAgcE9iamVjdFdpbiA9IG1wT2JqZWN0TGlzdC0+R2V0UHRyQnlOYW1lKCBtc1Byb2plY3QgKTsKCQlpZiAocE9iamVjdFdpbikKCQl7CgkJCW1wT2JqZWN0TGlzdC0+UmVzZXRTZWxlY3RlZE9iamVjdCgpOwoJCQlNYXJrT2JqZWN0cyggcE9iamVjdFdpbiApOwoJCX0KCQllbHNlCgkJewoJCQltcE9iamVjdExpc3QtPlJlc2V0U2VsZWN0ZWRPYmplY3QoKTsKCQkJZm9yICggc2FsX3VJbnQxNiBpPTA7IGk8bXBPYmplY3RMaXN0LT5Db3VudCgpOyBpKysgKQoJCQl7CgkJCSAgIE9iamVjdFdpbiogcE9iamVjdFdpbiA9IG1wT2JqZWN0TGlzdC0+R2V0T2JqZWN0KCBpICk7CgkJCSAgIGlmICggIXBPYmplY3RXaW4tPklzVG9wKCkgKQoJCQkJCXBPYmplY3RXaW4tPlNldFZpZXdNYXNrKHNhbF9GYWxzZSk7CgkJCX0KCQl9Cgl9CglyZXR1cm4gc2FsX0ZhbHNlOwp9CgpzYWxfQm9vbCBTb2xEZXA6Ok1hcmtPYmplY3RzKCBPYmplY3RXaW4qIHBPYmplY3RXaW4gKQp7CiAgICBpZiAocE9iamVjdFdpbikKICAgIHsKICAgICAgICBpZiAoIShwT2JqZWN0V2luLT5Jc051bGxPYmplY3QoKSkpCiAgICAgICAgewogICAgICAgICAgICBwT2JqZWN0V2luLT5TZXRNYXJrTW9kZSggTUFSS01PREVfU0VMRUNURUQgKTsKCSAgCSAgICBwT2JqZWN0V2luLT5NYXJrTmVlZGVkKCk7CgkgICAgICAgIHBPYmplY3RXaW4tPk1hcmtEZXBlbmRpbmcoKTsKICAgICAgICAgICAgaWYgKElzSGlkZU1vZGUoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgR2V0RGVwV2luKCktPkludmFsaWRhdGUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZQogICAgICAgIHsKICAgICAgICAgICAgZnByaW50ZihzdGRvdXQsIm51bGxcbiIpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBzYWxfVHJ1ZTsKfQoKdm9pZCBTb2xEZXA6OlJlc2l6ZSgpCnsKLy9mdW56dCEgbXXfIGFiZXIgdm9uIGRlciBhcHBsaWthdGlvbiBhdWZnZXJ1ZmVuIHdlcmRlbi4KICAgIFBvaW50IGFPdXRQb3MgPSBQb2ludCggMCwgMCApOwoJU2l6ZSBhT3V0U2l6ZSA9IG1wUHJvY2Vzc1dpbi0+R2V0T3V0cHV0U2l6ZVBpeGVsKCk7CgkJLy8gY2FsY3VsYXRlIG91dHB1dCBzaXplCiAgICBzYWxfdUludFB0ciBuVGFza0hlaWdodCA9IG1hVG9vbEJveC5DYWxjV2luZG93U2l6ZVBpeGVsKCkuSGVpZ2h0KCk7CiAgICBzYWxfdUludFB0ciBuVGFza1dpZHRoICA9IG1hVG9vbEJveC5DYWxjV2luZG93U2l6ZVBpeGVsKCkuV2lkdGgoKTsKCVNpemUgYVNpemUoIGFPdXRTaXplLldpZHRoKCksIG5UYXNrSGVpZ2h0ICk7CgovLwlzYWxfdUludFB0ciBuTWVudUhlaWdodCA9IDA7CiAgICBQb2ludCBhR3JhcGhXaW5Qb3MgPSBQb2ludCgwLDApOwogICAgU2l6ZSAgYUdyYXBoV2luU2l6ZSA9IFNpemUoMCwwKTsKCi8vd2Vp3yBuaWNodCB3aWU6ICAgIG5NZW51SGVpZ2h0ID0gYU1lbnVCYXIuR2V0V2luZG93KCktPkdldFNpemVQaXhlbCgpLkhlaWdodCgpOyAvL0j2aGUgZGVzIE1lbnVlcwoKICAgIC8vYUluUmVjdCA9IHBUQk1hbmFnZXItPlJlc2l6ZSggUmVjdGFuZ2xlKCBhT3V0UG9zLCBhT3V0U2l6ZSApOwogICAgLy8gU2V0IERvY2tpbmctUmVjdGFuZ2xlIGZvciBUb29sQmFyCiAgICBSZWN0YW5nbGUgYUluUmVjdDsKCiAgICBpZiAoKCAhbWFUb29sQm94LklzRmxvYXRpbmdNb2RlKCkgKSAmJiAoIG1hVG9vbEJveC5HZXRBbGlnbigpID09IFdJTkRPV0FMSUdOX1RPUCApKQogICAgewogICAgICAgIC8vIHdhYWdlcmVjaHRlIFRvb2xiYXIgb2JlbgogICAgICAgIG1hVG9vbEJveC5TZXRQb3NTaXplUGl4ZWwoIGFPdXRQb3MsIFNpemUoIGFPdXRTaXplLldpZHRoKCksIG1hVG9vbEJveC5DYWxjV2luZG93U2l6ZVBpeGVsKCkuSGVpZ2h0KCkpKTsKICAgICAgICBpZiggbWFUb29sQm94LklzVmlzaWJsZSgpKQogICAgICAgIHsKICAgICAgICAgICAgUG9pbnQgYU91dFBvc1RtcDsKICAgICAgICAgICAgU2l6ZSBhT3V0U2l6ZVRtcDsKICAgICAgICAgICAgYU91dFBvc1RtcCA9IFBvaW50KCBhT3V0UG9zLlgoKSwgYU91dFBvcy5ZKCkgKyBtYVRvb2xCb3guQ2FsY1dpbmRvd1NpemVQaXhlbCgpLkhlaWdodCgpKTsKICAgICAgICAgICAgYU91dFNpemVUbXAgPSBTaXplKCBhT3V0U2l6ZS5XaWR0aCgpLCBhT3V0U2l6ZS5IZWlnaHQoKSAtIG1hVG9vbEJveC5DYWxjV2luZG93U2l6ZVBpeGVsKCkuSGVpZ2h0KCkpOwogICAgICAgICAgICBhSW5SZWN0ID0gUmVjdGFuZ2xlKCBhT3V0UG9zVG1wLCBhT3V0U2l6ZVRtcCApOwogICAgICAgICAgICBhR3JhcGhXaW5Qb3MgPSBQb2ludCggMCwgblRhc2tIZWlnaHQgKTsKICAgICAgICAgICAgYUdyYXBoV2luU2l6ZSA9IFNpemUoIGFPdXRTaXplLldpZHRoKCksIGFPdXRTaXplLkhlaWdodCgpIC0gblRhc2tIZWlnaHQpOwogICAgICAgIH0KICAgIH0KICAgIGlmICgoICFtYVRvb2xCb3guSXNGbG9hdGluZ01vZGUoKSApICYmICggbWFUb29sQm94LkdldEFsaWduKCkgPT0gV0lORE9XQUxJR05fQk9UVE9NICkpCiAgICB7CiAgICAgICAgLy8gd2FhZ2VyZWNodGUgVG9vbGJhciB1bnRlbgogICAgICAgIFBvaW50IGFUYlBvcyAgPSBQb2ludCggYU91dFBvcy5YKCksIGFPdXRQb3MuWSgpICsgYU91dFNpemUuSGVpZ2h0KCkgLSBtYVRvb2xCb3guQ2FsY1dpbmRvd1NpemVQaXhlbCgpLkhlaWdodCgpKTsKICAgICAgICBTaXplICBhVGJTaXplID0gU2l6ZSggYU91dFNpemUuV2lkdGgoKSwgbWFUb29sQm94LkNhbGNXaW5kb3dTaXplUGl4ZWwoKS5IZWlnaHQoKSk7CiAgICAgICAgbWFUb29sQm94LlNldFBvc1NpemVQaXhlbCggYVRiUG9zLCBhVGJTaXplICk7CiAgICAgICAgaWYoIG1hVG9vbEJveC5Jc1Zpc2libGUoKSkKICAgICAgICB7CiAgICAgICAgICAgIFBvaW50IGFPdXRQb3NUbXA7CiAgICAgICAgICAgIFNpemUgYU91dFNpemVUbXA7CiAgICAgICAgICAgIGFPdXRQb3NUbXAgPSBQb2ludCggYU91dFBvcy5YKCksIGFPdXRQb3MuWSgpICsgbWFUb29sQm94LkNhbGNXaW5kb3dTaXplUGl4ZWwoKS5IZWlnaHQoKSk7CiAgICAgICAgICAgIGFPdXRTaXplVG1wID0gU2l6ZSggYU91dFNpemUuV2lkdGgoKSwgYU91dFNpemUuSGVpZ2h0KCkgLSBtYVRvb2xCb3guQ2FsY1dpbmRvd1NpemVQaXhlbCgpLkhlaWdodCgpKTsKICAgICAgICAgICAgYUluUmVjdCA9IFJlY3RhbmdsZSggYU91dFBvc1RtcCwgYU91dFNpemVUbXAgKTsKICAgICAgICAgICAgYUdyYXBoV2luUG9zID0gUG9pbnQoIDAsIDAgKTsKICAgICAgICAgICAgYUdyYXBoV2luU2l6ZSA9IFNpemUoIGFPdXRTaXplLldpZHRoKCksIGFPdXRTaXplLkhlaWdodCgpIC0gblRhc2tIZWlnaHQpOwogICAgICAgIH0KICAgIH0KICAgIGlmICgoICFtYVRvb2xCb3guSXNGbG9hdGluZ01vZGUoKSApICYmICggbWFUb29sQm94LkdldEFsaWduKCkgPT0gV0lORE9XQUxJR05fTEVGVCApKQogICAgewogICAgICAgIC8vIHNlbmtyZWNodGUgVG9vbEJhciBsaW5rcwogICAgICAgIG1hVG9vbEJveC5TZXRQb3NTaXplUGl4ZWwoIGFPdXRQb3MsIFNpemUoIG1hVG9vbEJveC5DYWxjV2luZG93U2l6ZVBpeGVsKCkuV2lkdGgoKSwgYU91dFNpemUuSGVpZ2h0KCkpKTsKICAgICAgICBpZiggbWFUb29sQm94LklzVmlzaWJsZSgpKQogICAgICAgIHsKICAgICAgICAgICAgUG9pbnQgYU91dFBvc1RtcDsKICAgICAgICAgICAgU2l6ZSBhT3V0U2l6ZVRtcDsKICAgICAgICAgICAgYU91dFBvc1RtcCA9IFBvaW50KCBhT3V0UG9zLlgoKSArIG1hVG9vbEJveC5DYWxjV2luZG93U2l6ZVBpeGVsKCkuV2lkdGgoKSwgYU91dFBvcy5ZKCkpOwogICAgICAgICAgICBhT3V0U2l6ZVRtcCA9IFNpemUoIGFPdXRTaXplLldpZHRoKCktIG1hVG9vbEJveC5DYWxjV2luZG93U2l6ZVBpeGVsKCkuV2lkdGgoKSwgYU91dFNpemUuSGVpZ2h0KCkpOwogICAgICAgICAgICBhSW5SZWN0ID0gUmVjdGFuZ2xlKCBhT3V0UG9zVG1wLCBhT3V0U2l6ZVRtcCApOwogICAgICAgICAgICBhR3JhcGhXaW5Qb3MgPSBQb2ludCggblRhc2tXaWR0aCwgMCApOwogICAgICAgICAgICBhR3JhcGhXaW5TaXplID0gU2l6ZSggYU91dFNpemUuV2lkdGgoKSAtIG5UYXNrV2lkdGgsIGFPdXRTaXplLkhlaWdodCgpKTsKICAgICAgICB9CiAgICB9CiAgICBpZiAoKCAhbWFUb29sQm94LklzRmxvYXRpbmdNb2RlKCkgKSAmJiAoIG1hVG9vbEJveC5HZXRBbGlnbigpID09IFdJTkRPV0FMSUdOX1JJR0hUICkpCiAgICB7CiAgICAgICAgLy8gc2Vua3JlY2h0ZSBUb29sQmFyIHJlY2h0cwogICAgICAgIFBvaW50IGFUYlBvcyA9IFBvaW50KCBhT3V0UG9zLlgoKSArIGFPdXRTaXplLldpZHRoKCkgLSBtYVRvb2xCb3guQ2FsY1dpbmRvd1NpemVQaXhlbCgpLldpZHRoKCksIGFPdXRQb3MuWSgpKTsKICAgICAgICBTaXplICBhVGJTaXplPSBTaXplKCBtYVRvb2xCb3guQ2FsY1dpbmRvd1NpemVQaXhlbCgpLldpZHRoKCksIGFPdXRTaXplLkhlaWdodCgpKTsKICAgICAgICBtYVRvb2xCb3guU2V0UG9zU2l6ZVBpeGVsKCBhVGJQb3MsIGFUYlNpemUpOwogICAgICAgIGlmKCBtYVRvb2xCb3guSXNWaXNpYmxlKCkpCiAgICAgICAgewogICAgICAgICAgICBQb2ludCBhT3V0UG9zVG1wOwogICAgICAgICAgICBTaXplIGFPdXRTaXplVG1wOwogICAgICAgICAgICBhT3V0UG9zVG1wID0gUG9pbnQoIGFPdXRQb3MuWCgpICsgbWFUb29sQm94LkNhbGNXaW5kb3dTaXplUGl4ZWwoKS5XaWR0aCgpLCBhT3V0UG9zLlkoKSk7CiAgICAgICAgICAgIGFPdXRTaXplVG1wID0gU2l6ZSggYU91dFNpemUuV2lkdGgoKS0gbWFUb29sQm94LkNhbGNXaW5kb3dTaXplUGl4ZWwoKS5XaWR0aCgpLCBhT3V0U2l6ZS5IZWlnaHQoKSk7CiAgICAgICAgICAgIGFJblJlY3QgPSBSZWN0YW5nbGUoIGFPdXRQb3NUbXAsIGFPdXRTaXplVG1wICk7CiAgICAgICAgICAgIGFHcmFwaFdpblBvcyA9IFBvaW50KCAwLCAwICk7CiAgICAgICAgICAgIGFHcmFwaFdpblNpemUgPSBTaXplKCBhT3V0U2l6ZS5XaWR0aCgpIC0gblRhc2tXaWR0aCwgYU91dFNpemUuSGVpZ2h0KCkpOwogICAgICAgIH0KICAgIH0KCglSZWN0YW5nbGUgcm91dCA9IFJlY3RhbmdsZSggUG9pbnQoIDAsMCApLCBhT3V0U2l6ZSApOyAvL091dHB1dFRvU2NyZWVuUGl4ZWwoIGFPdXRQb3MgKQogICAgUmVjdGFuZ2xlIHJpbiAgPSBSZWN0YW5nbGUoIFBvaW50KCAwLDAgKSwvL091dHB1dFRvU2NyZWVuUGl4ZWwoIFBvaW50KCBhT3V0UG9zLlgoKSAtIDIwLCBhSW5SZWN0LlRvcCgpKQogICAgICAgICAgICAgICAgU2l6ZSggYU91dFNpemUuV2lkdGgoKSwgYU91dFNpemUuSGVpZ2h0KCkpKTsKLyoKCVJlY3RhbmdsZSByb3V0ID0gbXBQcm9jZXNzV2luLT5PdXRwdXRUb1NjcmVlblBpeGVsKCBhT3V0UG9zICk7CiAgICBSZWN0YW5nbGUgcmluICA9IFJlY3RhbmdsZSggUG9pbnQoIDAsMCApLC8vT3V0cHV0VG9TY3JlZW5QaXhlbCggUG9pbnQoIGFPdXRQb3MuWCgpIC0gMjAsIGFJblJlY3QuVG9wKCkpCiAgICAgICAgICAgICAgICBTaXplKCBhT3V0U2l6ZS5XaWR0aCgpLCBhT3V0U2l6ZS5IZWlnaHQoKSkpOwoqLwogICAgbWFUb29sQm94LlNldERvY2tpbmdSZWN0cyggcm91dCwgcmluICk7CgogICAgc2FsX0Jvb2wgYkZsb2F0aW5nID0gbWFUb29sQm94LklzRmxvYXRpbmdNb2RlKCk7CgogICAgaWYgKCBiRmxvYXRpbmcgKQogICAgewogICAgICAgIEdldEdyYXBoV2luKCktPlNldFBvc1NpemVQaXhlbChQb2ludCgwLDApLGFPdXRTaXplKTsKICAgICAgICAvL2lmIChJc1ByalZpZXcoKSAmJiAobXBQcmpEZXApKSBtcFByakRlcC0+UmVzaXplKCk7CiAgICAgICAgaWYgKG1hVG9vbEJveC5Jc1Zpc2libGUoKSkgbWFUb29sQm94LlNob3coKTsKICAgIH0gZWxzZQogICAgewogICAgICAgIEdldEdyYXBoV2luKCktPlNldFBvc1NpemVQaXhlbCggYUdyYXBoV2luUG9zLCBhR3JhcGhXaW5TaXplICk7CiAgICB9CiAgICBpZiAobWFUb29sQm94LklzVmlzaWJsZSgpKSBtYVRvb2xCb3guU2hvdygpOwp9CgpzYWxfdUludDE2IFNvbERlcDo6QWRkQ29ubmVjdG9yUHJqVmlldyggT2JqZWN0V2luKiBwU3RhcnRXaW4sIE9iamVjdFdpbiogcEVuZFdpbiApCnsKLy8JREJHX0FTU0VSVCggRkFMU0UgLCAibm90IHlldCIgKTsKCUJ5dGVTdHJpbmcgc0VuZE5hbWUgPSBwRW5kV2luLT5HZXRCb2R5VGV4dCgpOwoJQnl0ZVN0cmluZyBzU3RhcnROYW1lID0gcFN0YXJ0V2luLT5HZXRCb2R5VGV4dCgpOwoJaWYgKCBzU3RhcnROYW1lICE9IEJ5dGVTdHJpbmcoIm51bGwiKSkKCXsKCQlDb21tYW5kRGF0YSogcEVuZERhdGEgPSBtcFByai0+R2V0RGlyZWN0b3J5RGF0YSggc0VuZE5hbWUgKTsKCQlTQnl0ZVN0cmluZ0xpc3QqIHBEZXBzID0gcEVuZERhdGEtPkdldERlcGVuZGVuY2llcygpOwoJCWlmICggcERlcHMgKQoJCQlwRGVwcy0+UHV0U3RyaW5nKCAmc1N0YXJ0TmFtZSApOwoJCWVsc2UKCQl7CgkJCXBEZXBzID0gbmV3IFNCeXRlU3RyaW5nTGlzdCgpOwoJCQlwRW5kRGF0YS0+U2V0RGVwZW5kZW5jaWVzKCBwRGVwcyApOwoJCQlwRGVwcy0+UHV0U3RyaW5nKCAmc1N0YXJ0TmFtZSApOwoJCQlwRW5kRGF0YS0+R2V0RGVwZW5kZW5jaWVzKCk7CgkJfQoJfQoJcmV0dXJuIEFkZENvbm5lY3RvclRvT2JqZWN0cyggcFN0YXJ0V2luLCBwRW5kV2luICk7Cn0KCnNhbF91SW50MTYgU29sRGVwOjpSZW1vdmVDb25uZWN0b3JQcmpWaWV3KCBPYmplY3RXaW4qIHBTdGFydFdpbiwgT2JqZWN0V2luKiBwRW5kV2luICkKewoJQnl0ZVN0cmluZyBzRW5kTmFtZSA9IHBFbmRXaW4tPkdldEJvZHlUZXh0KCk7CglCeXRlU3RyaW5nIHNTdGFydE5hbWUgPSBwU3RhcnRXaW4tPkdldEJvZHlUZXh0KCk7CglDb21tYW5kRGF0YSogcEVuZERhdGEgPSBtcFByai0+R2V0RGlyZWN0b3J5RGF0YSggc0VuZE5hbWUgKTsKCVNCeXRlU3RyaW5nTGlzdCogcERlcHMgPSBwRW5kRGF0YS0+R2V0RGVwZW5kZW5jaWVzKCk7CglpZiAoIHBEZXBzICkKCXsKCQlCeXRlU3RyaW5nKiBwU3RyaW5nOwoJCXNhbF91SW50UHRyIG5EZXBzQ291bnQgPSBwRGVwcy0+Q291bnQoKTsKCQlmb3IgKCBzYWxfdUludFB0ciBqID0gbkRlcHNDb3VudDsgaiA+IDA7IGotLSApCgkJewoJCQlwU3RyaW5nID0gcERlcHMtPkdldE9iamVjdCggaiAtIDEgKTsKCQkJaWYgKCBwU3RyaW5nLT5HZXRUb2tlbiggMCwgJy4nKSA9PSBzU3RhcnROYW1lICkKCQkJCXBEZXBzLT5SZW1vdmUoIHBTdHJpbmcgKTsKCQl9Cgl9CglyZXR1cm4gUmVtb3ZlQ29ubmVjdG9yRnJvbU9iamVjdHMoIHBTdGFydFdpbiwgcEVuZFdpbiApOwp9CgpzYWxfdUludDE2IFNvbERlcDo6QXV0b0FycmFuZ2UoIFNvbElkTWFwcGVyKiBwSWRNYXBwZXIsIE9iamVjdExpc3QqIHBPYmpMc3QsIHNhbF91SW50UHRyIG5Ub3BJZCwgc2FsX3VJbnRQdHIgbkJvdHRtSWQsIHNhbF91SW50UHRyIGFPYmpJRCApCnsKICAgIEF1dG9BcnJhbmdlRGxnU3RhcnQoKTsKCU9wdGltaXplUG9zKHBJZE1hcHBlciwgcE9iakxzdCwgblRvcElkLCBuQm90dG1JZCwgYU9iaklEICk7CiAgICBBdXRvQXJyYW5nZURsZ1N0b3AoKTsKCXJldHVybiAwOwp9CgpQb2ludCBTb2xEZXA6OkNhbGNQb3MoIHNhbF91SW50MTYgblNldCwgc2FsX3VJbnQxNiBuSW5kZXggKQp7CglpbnQgblJvd0luZGV4ID0gbkluZGV4IC8gREVQUEVSX01BWF9XSURUSDsKCXNhbF91SW50UHRyIG5Qb3NYID0gbW5YT2Zmc2V0ICsgblJvd0luZGV4ICUgMyAqIEdldERlZlNpemUoKS5XaWR0aCgpIC8gMyArICggbkluZGV4IC0gKCBERVBQRVJfTUFYX1dJRFRIICogblJvd0luZGV4ICkpICogKEdldERlZlNpemUoKS5XaWR0aCgpICsgT0JKV0lOX1hfU1BBQ0lORyApOwoKCXNhbF91SW50UHRyIG5Qb3NZID0gKCBuU2V0ICsgbW5MZXZlbE9mZnNldCArIG5Sb3dJbmRleCApICogKCBHZXREZWZTaXplKCkuSGVpZ2h0KCkgKyBPQkpXSU5fWV9TUEFDSU5HICkgKyBPQkpXSU5fWV9TUEFDSU5HOwoJUG9pbnQgYVBvcyggblBvc1gsIG5Qb3NZICk7CglyZXR1cm4gYVBvczsKfQoKc2FsX3VJbnRQdHIgU29sRGVwOjpDYWxjWE9mZnNldCggc2FsX3VJbnRQdHIgbk9iamVjdHNUb0ZpdCApCnsKCWxvbmcgbkR5blhPZmZzOwoJbG9uZyBuWE1pZGRsZTsKCXNhbF91SW50UHRyIG5UcmlnZ2VyOwoKCW5YTWlkZGxlID0gR2V0RGVwV2luKCktPlBpeGVsVG9Mb2dpYyggR2V0RGVwV2luKCktPkdldFNpemVQaXhlbCgpKS5XaWR0aCgpIC8gMjsKCWlmICggbk9iamVjdHNUb0ZpdCA+IERFUFBFUl9NQVhfV0lEVEggKQoJCW5PYmplY3RzVG9GaXQgPSBERVBQRVJfTUFYX1dJRFRIIC0gMSArIERFUFBFUl9NQVhfV0lEVEggJSAyOwoJblRyaWdnZXIgPSAoIG5PYmplY3RzVG9GaXQgLSAxICkgLyAyOwoJbkR5blhPZmZzID0gKCBHZXREZWZTaXplKCkuV2lkdGgoKSArIE9CSldJTl9YX1NQQUNJTkcgKSAqIG5UcmlnZ2VyOwoJc2FsX3VJbnRQdHIgblhPZmZzID0gblhNaWRkbGUgLSBuRHluWE9mZnM7CgoJaWYgKCBzYWxfdUludFB0cihuWE1pZGRsZSAtIG5EeW5YT2ZmcykgPCBtbk1pbkR5blhPZmZzICkKCQltbk1pbkR5blhPZmZzID0gblhNaWRkbGUgLSBuRHluWE9mZnM7CgoJcmV0dXJuIG5YT2ZmczsKCn0KCmRvdWJsZSBTb2xEZXA6OkNhbGNEaXN0U3VtKCBPYmpXaW5MaXN0KiBwT2JqTGlzdCwgRGlzdFR5cGUgZURpc3RUeXBlICkKewoJT2JqZWN0V2luKiBwV2luOwoJQ29ubmVjdG9yKiBwQ29uOwoJc2FsX3VJbnRQdHIgbk9iakNvdW50ID0gcE9iakxpc3QtPkNvdW50KCk7Cglkb3VibGUgZFJldFZhbCA9IDA7Cglkb3VibGUgZFdpblZhbDsKCXNhbF91SW50MTYgaSwgajsKCXNhbF9Cb29sIGJJc1N0YXJ0OwoKCWZvciAoIGkgPSAwOyBpIDwgbk9iakNvdW50OyBpKysgKQoJewoJCXBXaW4gPSBwT2JqTGlzdC0+R2V0T2JqZWN0KCBpICk7CgoJCWlmICggcFdpbiAmJiBwV2luLT5Jc1Zpc2libGUoKSkKCQl7CgkJCWogPSAwOwoJCQlkV2luVmFsID0gMDsKCQkJd2hpbGUgKCAocENvbiA9IHBXaW4tPkdldENvbm5lY3RvciggaiApKSApCgkJCXsKCQkJCWlmICggcENvbi0+SXNWaXNpYmxlKCkpIHsKCQkJCQliSXNTdGFydCA9IHBDb24tPklzU3RhcnQoIHBXaW4gKTsKCQkJCQlpZiAoIGVEaXN0VHlwZSAhPSBCT1RIICkKCQkJCQkJaWYgKCBlRGlzdFR5cGUgPT0gVE9QRE9XTiApCgkJCQkJCXsKCQkJCQkJCWlmICggYklzU3RhcnQgKQoJCQkJCQkJewoJCQkJCQkJCXBDb24tPlVwZGF0ZVBvc2l0aW9uKCBwV2luLCBzYWxfRmFsc2UgKTsKCQkJCQkJCQlkV2luVmFsICs9IHBDb24tPkdldExlbigpICogcFdpbi0+bW5IZWFkRGlzdDsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQllbHNlCgkJCQkJCXsKCQkJCQkJCWlmICggIWJJc1N0YXJ0ICkKCQkJCQkJCXsKCQkJCQkJCQlwQ29uLT5VcGRhdGVQb3NpdGlvbiggcFdpbiwgc2FsX0ZhbHNlICk7CgkJCQkJCQkJZFdpblZhbCArPSBwQ29uLT5HZXRMZW4oKSAqIHBXaW4tPm1uUm9vdERpc3Q7CgkJCQkJCQl9CgoJCQkJCQl9CgkJCQkJZWxzZQoJCQkJCXsKCQkJCQkJcENvbi0+VXBkYXRlUG9zaXRpb24oIHBXaW4sIHNhbF9GYWxzZSApOwoJCQkJCQlpZiAoICFiSXNTdGFydCApCgkJCQkJCQlkV2luVmFsICs9IHBDb24tPkdldExlbigpICogKCBwV2luLT5tbkhlYWREaXN0ICsgMSApOwoJCQkJCQllbHNlCgkJCQkJCQlkV2luVmFsICs9IHBDb24tPkdldExlbigpICogcFdpbi0+bW5Sb290RGlzdDsKCQkJCQl9CgkJCQl9CgkJCQlqKys7CgkJCX0KLy8JCQlpZiAoIGogIT0gMCApCi8vCQkJCWRXaW5WYWwgLz0gajsKCQkJZFJldFZhbCArPSBkV2luVmFsOwoJCX0KCX0KCglyZXR1cm4gZFJldFZhbDsKfQoKc2FsX3VJbnQxNiBTb2xEZXA6OkltcGxfVHJhdmVsbGVyKCBPYmplY3RXaW4qIHBXaW4sIHNhbF91SW50MTYgbkRlcHRoICkKewoJc2FsX3VJbnQxNiBpID0gMDsKCU9iamVjdFdpbiogcE5ld1dpbjsKCUNvbm5lY3RvciogcENvbjsKCgluRGVwdGgrKzsKCglzYWxfdUludDE2IG5NYXhEZXB0aCA9IG5EZXB0aDsKCglwV2luLT5tYlZpc2l0ZWQgPSBzYWxfVHJ1ZTsKCXBXaW4tPm1uUm9vdERpc3QgPSBNYXggKCBuRGVwdGgsIHBXaW4tPiBtblJvb3REaXN0ICk7CglpZiAoIG5EZXB0aCA+IERFUFBFUl9NQVhfREVQVEggKQoJewoJCURCR19BU1NFUlQoIG5EZXB0aCAhPSBERVBQRVJfTUFYX0RFUFRIICsgMSwgIlJpbmdhYmjkbmdpZ2tlaXQhIiApOwoJCW5EZXB0aCsrOwoJCXJldHVybiBERVBfRU5ETEVTX1JFQ1VSU0lPTl9GT1VORDsKCX0KCgl3aGlsZSAoIChwQ29uID0gcFdpbi0+R2V0Q29ubmVjdG9yKCBpICkpICkKCXsKCQlpZiAoIHBDb24tPklzU3RhcnQoIHBXaW4gKSYmIHBDb24tPklzVmlzaWJsZSgpICkgLy9yZW1vdmVkOiBkb24ndCBzaG93IG51bGxfcHJvamVjdAoJCXsKCQkJcE5ld1dpbiA9IHBDb24tPkdldE90aGVyV2luKCBwV2luICk7CgkJCW5NYXhEZXB0aCA9IE1heCggSW1wbF9UcmF2ZWxsZXIoIHBOZXdXaW4sIG5EZXB0aCApLCBuTWF4RGVwdGggKTsKCQkJaWYoIG5NYXhEZXB0aCA9PSBERVBfRU5ETEVTX1JFQ1VSU0lPTl9GT1VORCApCgkJCXsKCQkJCW1wVHJhdmVsbGVyTGlzdC0+SW5zZXJ0KCBwV2luLCBMSVNUX0FQUEVORCApOwoJCQkJcmV0dXJuIERFUF9FTkRMRVNfUkVDVVJTSU9OX0ZPVU5EOwoJCQl9CgkJfQoJCWkrKzsKCX0KCXBXaW4tPm1uSGVhZERpc3QgPSBNQVgoIHBXaW4tPm1uSGVhZERpc3QsIG5NYXhEZXB0aCAtIG5EZXB0aCApOwoJcmV0dXJuIG5NYXhEZXB0aDsKfQoKCmRvdWJsZSBTb2xEZXA6OkltcGxfUGVybXV0ZU1pbiggT2JqV2luTGlzdCYgck9iakxpc3QsIFBvaW50KiBwUG9zQXJyYXksIE9ialdpbkxpc3QmIHJSZXN1bHRMaXN0LCBkb3VibGUgZE1pbkRpc3QsIHNhbF91SW50UHRyIG5TdGFydCwgc2FsX3VJbnRQdHIgblNpemUsIERpc3RUeXBlIGVEaXN0VHlwZSApCnsKCglzYWxfdUludFB0ciBpLCBqLCBsOwoJc2FsX3VJbnRQdHIgbkVuZCA9IG5TdGFydCArIG5TaXplOwoJT2JqZWN0V2luKiBwU3dhcFdpbjsKCXNhbF91SW50UHRyIG5MZXZlbE9iakNvdW50ID0gck9iakxpc3QuQ291bnQoKTsKCi8vZG9udCB1c2UgZnVsbCByZWN1c2lvbiBmb3IgbW9yZSB0aGFuIDYgb2JqZWN0cwoJaWYgKCBuTGV2ZWxPYmpDb3VudCA+IDYgKQoJewoJCXNyYW5kKCggdW5zaWduZWQgKSB0aW1lKCBOVUxMICkpOwoKCQlzYWxfdUludFB0ciBuSWR4MSwgbklkeDI7CgkJZm9yICggaSA9IDA7IGkgPCAxMDE7IGkrKyApCgkJewogICAgICAgICAgICBVcGRhdGVTdWJQcm9ncnNzQmFyKGkpOwoJCQlmb3IgKCBqID0gMDsgaiA8IDEwMDsgaisrICkKCQkJewoJCQkJbklkeDEgPSAoc2FsX3VJbnRQdHIpICggZG91YmxlKCByYW5kKCkgKSAvIFJBTkRfTUFYICogbkxldmVsT2JqQ291bnQgKTsKCQkJCXdoaWxlICggck9iakxpc3QuR2V0T2JqZWN0KCBuSWR4MSApID09IE5VTEwgKQoJCQkJCW5JZHgxID0gKHNhbF91SW50UHRyKSAoIGRvdWJsZSggcmFuZCgpICkgLyBSQU5EX01BWCAqIG5MZXZlbE9iakNvdW50ICk7CgkJCQluSWR4MiA9IChzYWxfdUludFB0cikgKCBkb3VibGUoIHJhbmQoKSApIC8gUkFORF9NQVggKiBuTGV2ZWxPYmpDb3VudCApOwoJCQkJd2hpbGUgKCBuSWR4MSA9PSBuSWR4MiB8fCBuSWR4MiA9PSBuTGV2ZWxPYmpDb3VudCApCgkJCQkJbklkeDIgPSAoc2FsX3VJbnRQdHIpICggZG91YmxlKCByYW5kKCkgKSAvIFJBTkRfTUFYICogbkxldmVsT2JqQ291bnQgKTsKCgkJCQlwU3dhcFdpbiA9IHJPYmpMaXN0LkdldE9iamVjdCggbklkeDEgKTsKCQkJCWlmICggcFN3YXBXaW4gKQoJCQkJCXBTd2FwV2luLT5TZXRDYWxjUG9zUGl4ZWwoIHBQb3NBcnJheVsgbklkeDIgXSApOwoJCQkJcFN3YXBXaW4gPSByT2JqTGlzdC5SZXBsYWNlKCBwU3dhcFdpbiwgbklkeDIgKTsKCQkJCWlmICggcFN3YXBXaW4gKQoJCQkJCXBTd2FwV2luLT5TZXRDYWxjUG9zUGl4ZWwoIHBQb3NBcnJheVsgbklkeDEgXSApOwoJCQkJck9iakxpc3QuUmVwbGFjZSggcFN3YXBXaW4sIG5JZHgxICk7CgoJCQkJZG91YmxlIGRDdXJEaXN0ID0gQ2FsY0Rpc3RTdW0oICZyT2JqTGlzdCwgZURpc3RUeXBlICk7CgoJCQkJaWYgKCBkQ3VyRGlzdCA8IGRNaW5EaXN0ICkKCQkJCXsKCQkJCQlkTWluRGlzdCA9IGRDdXJEaXN0OwoJCQkJCXJSZXN1bHRMaXN0LkNsZWFyKCk7CgkJCQkJZm9yICggbCA9IDA7IGwgPCBuTGV2ZWxPYmpDb3VudDsgbCsrICkKCQkJCQl7CgkJCQkJCXBTd2FwV2luID0gck9iakxpc3QuR2V0T2JqZWN0KCBsICk7CgkJCQkJCXJSZXN1bHRMaXN0Lkluc2VydCggcFN3YXBXaW4sIExJU1RfQVBQRU5EKTsKCQkJCQl9CgkJCQl9Ci8vCQkJCWlmICggZEN1ckRpc3QgPiBkTWluRGlzdCAqIDEuNSApCgkJCQlpZiAoIGRDdXJEaXN0ID4gZE1pbkRpc3QgKiAxNSApCgkJCQl7CgkJCQkJcFN3YXBXaW4gPSByT2JqTGlzdC5HZXRPYmplY3QoIG5JZHgxICk7CgkJCQkJaWYgKCBwU3dhcFdpbiApCgkJCQkJCXBTd2FwV2luLT5TZXRDYWxjUG9zUGl4ZWwoIHBQb3NBcnJheVsgbklkeDIgXSApOwoJCQkJCXBTd2FwV2luID0gck9iakxpc3QuUmVwbGFjZSggcFN3YXBXaW4sIG5JZHgyICk7CgkJCQkJaWYgKCBwU3dhcFdpbiApCgkJCQkJCXBTd2FwV2luLT5TZXRDYWxjUG9zUGl4ZWwoIHBQb3NBcnJheVsgbklkeDEgXSApOwoJCQkJCXJPYmpMaXN0LlJlcGxhY2UoIHBTd2FwV2luLCBuSWR4MSApOwoJCQkJfQoJCQl9CgkJfQoJfQoJZWxzZQoJewoJCWZvciAoIGkgPSBuU3RhcnQgOyBpIDwgbkVuZDsgaSsrKQoJCXsKCQkJaWYgKCBuU2l6ZSA+IDEgKQoJCQl7CgkJCQlwU3dhcFdpbiA9IHJPYmpMaXN0LkdldE9iamVjdCggaSApOwoJCQkJcFN3YXBXaW4gPSByT2JqTGlzdC5SZXBsYWNlKCBwU3dhcFdpbiwgblN0YXJ0ICk7CgkJCQlyT2JqTGlzdC5SZXBsYWNlKCBwU3dhcFdpbiwgaSApOwogICAgICAgICAgICAgICAgZG91YmxlIGRQZXJtdXRlRGlzdCA9IEltcGxfUGVybXV0ZU1pbiggck9iakxpc3QsIHBQb3NBcnJheSwgclJlc3VsdExpc3QsIGRNaW5EaXN0LCBuU3RhcnQgKyAxLCBuU2l6ZSAtIDEsIGVEaXN0VHlwZSApOwoJCQkJZE1pbkRpc3QgPSBNSU4oIGRNaW5EaXN0LCBkUGVybXV0ZURpc3QpOwoJCQkJcFN3YXBXaW4gPSByT2JqTGlzdC5HZXRPYmplY3QoIGkgKTsKCQkJCXBTd2FwV2luID0gck9iakxpc3QuUmVwbGFjZSggcFN3YXBXaW4sIG5TdGFydCApOwoJCQkJck9iakxpc3QuUmVwbGFjZSggcFN3YXBXaW4sIGkgKTsKCgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlmb3IgKCBsID0gMDsgbCA8IG5MZXZlbE9iakNvdW50OyBsKysgKQoJCQkJewoJCQkJCXBTd2FwV2luID0gck9iakxpc3QuR2V0T2JqZWN0KCBsICk7CgkJCQkJaWYgKCBwU3dhcFdpbiApCgkJCQkJCXBTd2FwV2luLT5TZXRDYWxjUG9zUGl4ZWwoIHBQb3NBcnJheVsgbCBdICk7CgkJCQl9CgoJCQkJZG91YmxlIGRDdXJEaXN0ID0gQ2FsY0Rpc3RTdW0oICZyT2JqTGlzdCwgZURpc3RUeXBlICk7CgoJCQkJaWYgKCBkQ3VyRGlzdCA8IGRNaW5EaXN0ICkKCQkJCXsKCQkJCQlkTWluRGlzdCA9IGRDdXJEaXN0OwoJCQkJCXJSZXN1bHRMaXN0LkNsZWFyKCk7CgkJCQkJZm9yICggbCA9IDA7IGwgPCBuTGV2ZWxPYmpDb3VudDsgbCsrICkKCQkJCQl7CgkJCQkJCXBTd2FwV2luID0gck9iakxpc3QuR2V0T2JqZWN0KCBsICk7CgkJCQkJCXJSZXN1bHRMaXN0Lkluc2VydCggcFN3YXBXaW4sIExJU1RfQVBQRU5EKTsKCQkJCQl9CgkJCQl9CgoJCQl9CgkJfQoJfQoKCXJldHVybiBkTWluRGlzdDsKfQoKCnNhbF91SW50MTYgU29sRGVwOjpPcHRpbWl6ZVBvcyhTb2xJZE1hcHBlciogcElkTWFwcGVyLCBPYmplY3RMaXN0KiBwT2JqTHN0LCBzYWxfdUludFB0ciBuVG9wSWQsIHNhbF91SW50UHRyIG5Cb3R0bUlkLCBzYWxfdUludFB0ciBhT2JqSUQgKQp7CglPYmpXaW5MaXN0IGFXb3JrTGlzdDsKCU9iamVjdFdpbiogcFdpbjsKCUNvbm5lY3RvciogcENvbjsKCXNhbF91SW50MTYgblJvb3REaXN0ID0gKHNhbF91SW50MTYpIC0xOwoJc2FsX3VJbnQxNiBpLCBqLCBrLCBsLCBuUmV0VmFsOwoJc2FsX3VJbnQxNiBMZXZlbFVzZVsgREVQUEVSX01BWF9ERVBUSCBdOwoJc2FsX3VJbnQxNiBMZXZlbFNlY1VzZVsgREVQUEVSX01BWF9ERVBUSCBdOwoJT2JqV2luTGlzdCogTGV2ZWxMaXN0WyBERVBQRVJfTUFYX0RFUFRIIF07CglPYmpXaW5MaXN0KiBMZXZlbFNlY0xpc3RbIERFUFBFUl9NQVhfREVQVEggXTsKCVBvaW50IGFQb3NBcnJheVsgREVQUEVSX01BWF9MRVZFTF9XSURUSCAqIERFUFBFUl9NQVhfV0lEVEggXTsKCgltbk1pbkR5blhPZmZzID0gMHhmZmZmOwoKCWZvciAoIGkgPSAwOyBpIDwgREVQUEVSX01BWF9ERVBUSDsgaSsrICkKCXsKCQlMZXZlbFVzZVsgaSBdID0gMDsKCQlMZXZlbExpc3RbIGkgXSA9IE5VTEw7CgkJTGV2ZWxTZWNVc2VbIGkgXSA9IDA7CgkJTGV2ZWxTZWNMaXN0WyBpIF0gPSBOVUxMOwoJfQoKICAgIEdldERlcFdpbigpLT5FbmFibGVQYWludCggc2FsX0ZhbHNlICk7CgoJc2FsX3VJbnRQdHIgbk9iakNvdW50ID0gcE9iakxzdC0+Q291bnQoKTsKCWZvciAoIGkgPSAwOyBpIDwgbk9iakNvdW50OyBpKysgKQoJewoJCXBXaW4gPSBwT2JqTHN0LT5HZXRPYmplY3QoIGkgKTsKCQlpZiAoIHBXaW4tPklzVmlzaWJsZSgpKSB7CgkJCXBXaW4tPm1iVmlzaXRlZCA9IHNhbF9GYWxzZTsKCQkJcFdpbi0+bW5IZWFkRGlzdCA9IDA7CgkJCXBXaW4tPm1uUm9vdERpc3QgPSAwOwoKCQkJLy8gZmluZCBpbml0aWFsIG9iamVjdHMgd2hpY2ggbmVlZCB0byBiZSBjb25uZWN0ZWQgd2l0aAoJCQkvLyByb290IG9iamVjdAoJCQlqID0gMDsKCQkJc2FsX3VJbnQxNiBuU3RhcnRDb3VudCA9IDA7CgkJCXNhbF91SW50MTYgbkVuZENvdW50ID0gMDsKCQkJd2hpbGUgKCAocENvbiA9IHBXaW4tPkdldENvbm5lY3RvciggaiApKSApCgkJCXsKCQkJCWlmICggcENvbi0+SXNWaXNpYmxlKCkpIHsgICAgICAgICAgICAgICAgICAgLy9udWxsX3Byb2plY3QKCQkJCQlpZiggcENvbi0+SXNTdGFydCggcFdpbiApKQoJCQkJCQluU3RhcnRDb3VudCsrOwoJCQkJCWVsc2UKCQkJCQl7CgkJCQkJCW5FbmRDb3VudCA9IDE7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJCWorKzsKCQkJfQoKCQkJaWYgKCBuU3RhcnRDb3VudCA+IDAgJiYgbkVuZENvdW50ID09IDAgKQoJCQkJaWYgKCBuVG9wSWQgIT0gcFdpbi0+R2V0SWQoKSkKCQkJCQlBZGRDb25uZWN0b3JUb09iamVjdHMoIHBPYmpMc3QsIG5Ub3BJZCwgcFdpbi0+R2V0SWQoKSk7CgoJCX0KCX0KCglwV2luID0gT2JqSWRUb1B0ciggcE9iakxzdCwgblRvcElkICk7CgoJaWYgKCBtcFRyYXZlbGxlckxpc3QgKQoJewoJCW1wVHJhdmVsbGVyTGlzdC0+Q2xlYXIoKTsKCQlkZWxldGUgbXBUcmF2ZWxsZXJMaXN0OwoJfQoJbXBUcmF2ZWxsZXJMaXN0ID0gbmV3IE9ialdpbkxpc3QoKTsKCS8vIHNldCByb290IGFuZCB0b3AgZGlzdGFuY2UKCW5SZXRWYWwgPSBJbXBsX1RyYXZlbGxlciggcFdpbiwgblJvb3REaXN0ICk7CgoJREJHX0FTU0VSVCggblJldFZhbCA8IERFUFBFUl9NQVhfREVQVEggLCAienUgdGllZiIgKTsKCWlmICggblJldFZhbCA9PSBERVBfRU5ETEVTX1JFQ1VSU0lPTl9GT1VORCApCgl7CiAgICAgICAgV3JpdGVUb0Vycm9yRmlsZSgpOwoJCXJldHVybiBuUmV0VmFsOwoJfQoKCXNhbF91SW50UHRyIG5VbnZpc2l0ZWQgPSAwOwoJc2FsX3VJbnRQdHIgblVudmlzWU9mZnMgPSAwOwoKCS8vIHNlcGVyYXRlIG1haW5zdHJlYW0sIHNlY29uZGFyeSBhbmQgdW5jb25uZWN0ZWQKCWZvciAoIGkgPSAwOyBpIDwgbk9iakNvdW50OyBpKysgKQoJewoJCXBXaW4gPSBwT2JqTHN0LT5HZXRPYmplY3QoIGkgKTsKCQlpZiAoIHBXaW4tPklzVmlzaWJsZSgpKSB7CgkJCWlmICgoIHBXaW4tPm1uSGVhZERpc3QgKyBwV2luLT5tblJvb3REaXN0ICkgPT0gblJldFZhbCApCgkJCXsKCQkJCWlmICggIUxldmVsTGlzdFsgcFdpbi0+bW5IZWFkRGlzdCBdICkKCQkJCQkJTGV2ZWxMaXN0WyBwV2luLT5tbkhlYWREaXN0IF0gPSBuZXcgT2JqV2luTGlzdDsKICAgIAkJCUxldmVsTGlzdFsgcFdpbi0+bW5IZWFkRGlzdCBdLT5JbnNlcnQoIHBXaW4gKTsKCQkJCUxldmVsVXNlWyBwV2luLT5tbkhlYWREaXN0IF0rKzsKCQkJfQoJCQllbHNlCgkJCQlpZiAoIHBXaW4tPm1iVmlzaXRlZCApCgkJCQl7CgkJCQkJaWYgKCAhTGV2ZWxTZWNMaXN0WyBuUmV0VmFsIC0gcFdpbi0+bW5Sb290RGlzdCBdICkKCQkJCQkJTGV2ZWxTZWNMaXN0WyBuUmV0VmFsIC0gcFdpbi0+bW5Sb290RGlzdCBdID0gbmV3IE9ialdpbkxpc3Q7CgkJCQkJTGV2ZWxTZWNMaXN0WyBuUmV0VmFsIC0gcFdpbi0+bW5Sb290RGlzdCBdLT5JbnNlcnQoIHBXaW4gKTsKCQkJCQlMZXZlbFNlY1VzZVsgblJldFZhbCAtIHBXaW4tPm1uUm9vdERpc3QgXSsrOwoJCQkJfQoJCQkJZWxzZQoJCQkJewoJLy8JCQkJbmVlZCB0byBiZSBhcnJhbmdlZCBtb3JlIGludGVsbGlnZW50Li4uCgkJCQkJUG9pbnQgYVBvcyggNSwgblVudmlzWU9mZnMgKTsKCQkJCQlwV2luLT5TZXRDYWxjUG9zUGl4ZWwoIGFQb3MgKTsKCgkJCQkJUG9pbnQgYVRtcFBvcyA9IHBXaW4tPkdldENhbGNQb3NQaXhlbCgpOwoJCQkJCXBXaW4tPlNldFBvc1BpeGVsKCBtcEJhc2VXaW4tPkxvZ2ljVG9QaXhlbCggYVRtcFBvcyApKTsKCgkJCQkJblVudmlzWU9mZnMgKz0gcFdpbi0+UGl4ZWxUb0xvZ2ljKCBwV2luLT5HZXRTaXplUGl4ZWwoKSkuSGVpZ2h0KCk7CgkJCQkJblVudmlzaXRlZCsrOwoJCQkJfQoJCX0KCX0KCgltbkxldmVsT2Zmc2V0ID0gMDsKCglzYWxfdUludDE2IG5TY2FsZVZhbDsKCglpZiAoIG5SZXRWYWwgPT0gMCApCgkJblNjYWxlVmFsID0gMTsKCWVsc2UKCQluU2NhbGVWYWwgPSBuUmV0VmFsOwoKCWkgPSAwOwoKCXNhbF91SW50MTYgblN0ZXAgPSAwOwoKCXdoaWxlICggTGV2ZWxMaXN0WyBpIF0gKQoJewogICAgICAgIFVwZGF0ZU1haW5Qcm9ncmVzc0JhcihpLCBuU2NhbGVWYWwsIG5TdGVwKTsKCQlEQkdfQVNTRVJUKCBMZXZlbFVzZVsgaSBdID09IExldmVsTGlzdFsgaSBdLT5Db3VudCgpICwgImxldmVsIGluZGV4IGltIGEuLi4iICk7CgkJT2JqZWN0V2luKiBwU3dhcFdpbjsKCQlzYWxfdUludFB0ciBuTGV2ZWxPYmpDb3VudCA9IExldmVsTGlzdFsgaSBdLT5Db3VudCgpOwoKCQlpZiAoIG5MZXZlbE9iakNvdW50ICUgMiA9PSAwICkKCQl7CgkJCUxldmVsTGlzdFsgaSBdLT5JbnNlcnQoIE5VTEwsIExJU1RfQVBQRU5EICk7CgkJCW5MZXZlbE9iakNvdW50Kys7Ci8vCQkJTGV2ZWxVc2UgYmxlaWJ0IG9yZ2luYWwuLi4KLy8JCQlMZXZlbFVzZVsgaSBdKys7CgkJfQoKLy8gY2F0Y2ggdG9vIGJpZyBsaXN0cwoJCURCR19BU1NFUlQoIG5MZXZlbE9iakNvdW50IDwgREVQUEVSX01BWF9MRVZFTF9XSURUSCAqIERFUFBFUl9NQVhfV0lEVEggLCAiZ3JhcGggenUgYnJlaXQhIGRhdCBnZWlodCBuaWNoIGd1dC4gYnJlYWtpbmciICk7CgkJaWYgKCBuTGV2ZWxPYmpDb3VudCA+PSBERVBQRVJfTUFYX0xFVkVMX1dJRFRIICogREVQUEVSX01BWF9XSURUSCApCgkJewoJCQlXYXJuaW5nQm94IGFXQm94KCBtcEJhc2VXaW4sIFdCX09LLCBTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSgiZ3JhcGggenUgYnJlaXQhIGRhdCBnZWlodCBuaWNoIGd1dC4gYnJlYWtpbmciKSk7CgkJCWFXQm94LkV4ZWN1dGUoKTsKCQkJYnJlYWs7CgkJfQoJCW1uWE9mZnNldCA9IENhbGNYT2Zmc2V0KCBuTGV2ZWxPYmpDb3VudCApOwoJCWFXb3JrTGlzdC5DbGVhcigpOwoKCQkvLyBpbml0aWFsIHBvc2l0aW9uaW5nIGZvciBtYWluc3RyZWFtCgkJZm9yICggaiA9IDA7IGogPCBuTGV2ZWxPYmpDb3VudDsgaisrICkKCQl7CgkJCXBTd2FwV2luID0gTGV2ZWxMaXN0WyBpIF0tPkdldE9iamVjdCggaiApOwoJCQlhV29ya0xpc3QuSW5zZXJ0KCBwU3dhcFdpbiwgTElTVF9BUFBFTkQpOwoJCQlQb2ludCBhUG9zID0gQ2FsY1BvcyggaSwgaiApOwoJCQlhUG9zQXJyYXlbIGogXSA9IGFQb3M7CgkJCWlmICggcFN3YXBXaW4gKQoJCQkJcFN3YXBXaW4tPlNldENhbGNQb3NQaXhlbCggYVBvc0FycmF5WyBqIF0gKTsKCQl9CgoJCWRvdWJsZSBkTWluRGlzdCA9IENhbGNEaXN0U3VtKCBMZXZlbExpc3RbIGkgXSApOwoKCQkvLyBvcHRpbWl6ZSBtYWluc3RyZWFtIG9yZGVyIGFuZCByZXR1cm4gYmVzdCBtYXRjaGluZyBsaXN0IGluICJhV29ya0xpc3QiCgkJZE1pbkRpc3QgPSBNSU4oIGRNaW5EaXN0LCBJbXBsX1Blcm11dGVNaW4oICooTGV2ZWxMaXN0WyBpIF0pLCBhUG9zQXJyYXksIGFXb3JrTGlzdCwgZE1pbkRpc3QsIDAsIG5MZXZlbE9iakNvdW50ICkpOwoKCQkvLyBzZXQgb3B0aW1pemVkIHBvc2l0aW9ucyAtIG1heSBzdGlsbCBiZSB3cm9uZyBmcm9tIGxhdGVyIHRyaWVzCgkJZm9yICggaiA9IDA7IGogPCBuTGV2ZWxPYmpDb3VudDsgaisrICkKCQl7CgkJCXBTd2FwV2luID0gYVdvcmtMaXN0LkdldE9iamVjdCggaiApOwoJCQlpZiAoIHBTd2FwV2luICkKCQkJCXBTd2FwV2luLT5TZXRDYWxjUG9zUGl4ZWwoICBhUG9zQXJyYXlbIGogXSApOwoJCX0KCgkJaWYgKCBMZXZlbFNlY0xpc3RbIGkgXSAhPSBOVUxMICkKCQl7CgkJCXNhbF91SW50UHRyIG5MZXZlbFNlY09iakNvdW50ID0gTGV2ZWxTZWNMaXN0WyBpIF0tPkNvdW50KCk7CgkJCS8vIGV4cGFuZCBsaXN0IGZvciBiZXR0ZXIgcG9zaXRpb25pbmcKCQkJd2hpbGUgKCBuTGV2ZWxTZWNPYmpDb3VudCArIExldmVsVXNlWyBpIF0gPCBERVBQRVJfTUFYX1dJRFRIIC0gMSApCgkJCXsKCQkJCUxldmVsU2VjTGlzdFsgaSBdLT5JbnNlcnQoIE5VTEwsIExJU1RfQVBQRU5EICk7CgkJCQluTGV2ZWxTZWNPYmpDb3VudCsrOwoJCQl9CgkJCWlmICggKCBuTGV2ZWxTZWNPYmpDb3VudCArIExldmVsVXNlWyBpIF0pJSAyID09IDAgKQoJCQl7CgkJCQlMZXZlbFNlY0xpc3RbIGkgXS0+SW5zZXJ0KCBOVUxMLCBMSVNUX0FQUEVORCApOwoJCQkJbkxldmVsU2VjT2JqQ291bnQrKzsKCQkJfQoKCQkJREJHX0FTU0VSVCggbkxldmVsU2VjT2JqQ291bnQgPCBERVBQRVJfTUFYX0xFVkVMX1dJRFRIICogREVQUEVSX01BWF9XSURUSCAsICJncmFwaCB6dSBicmVpdCEgZGF0IGdlaWh0IG5pY2ggZ3V0LiBicmVha2luZyIgKTsKCQkJaWYgKCBuTGV2ZWxPYmpDb3VudCA+PSBERVBQRVJfTUFYX0xFVkVMX1dJRFRIICogREVQUEVSX01BWF9XSURUSCApCgkJCXsKCQkJCVdhcm5pbmdCb3ggYVdCb3goIG1wQmFzZVdpbiwgV0JfT0ssIFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCJncmFwaCB6dSBicmVpdCEgZGF0IGdlaWh0IG5pY2ggZ3V0LiBicmVha2luZyIpKTsKCQkJCWFXQm94LkV4ZWN1dGUoKTsKCQkJCWJyZWFrOwoJCQl9CgkJCW1uWE9mZnNldCA9IENhbGNYT2Zmc2V0KCBMZXZlbFVzZVsgaSBdICsgbkxldmVsU2VjT2JqQ291bnQgKTsKCQkJYVdvcmtMaXN0LkNsZWFyKCk7CgoJCQlsID0gMDsKCQkJc2FsX0Jvb2wgYlVzZWRQb3M7CgoJCQkvLyBmaW5kIGZyZWUgcG9zaXRpb25zIGZvciBzZWNvbmRhcnkgb2JqZWN0cwoJCQlmb3IgKCBqID0gMDsgaiA8ICggTGV2ZWxVc2VbIGkgXSArIG5MZXZlbFNlY09iakNvdW50ICkgOyBqKysgKQoJCQl7CgkJCQlQb2ludCBhUG9zID0gQ2FsY1BvcyggaSwgaiApOwoJCQkJYlVzZWRQb3MgPSBzYWxfRmFsc2U7CgkJCQkvLyBpcyBhbHJlYWR5IG9jY3VwaWVkPwoJCQkJZm9yICggayA9IDA7IGsgPCBuTGV2ZWxPYmpDb3VudDsgaysrICkKCQkJCXsKCQkJCQlpZiAoIExldmVsTGlzdFsgaSBdLT5HZXRPYmplY3QoIGsgKSApCgkJCQkJCWlmICggYVBvcyA9PSBMZXZlbExpc3RbIGkgXS0+R2V0T2JqZWN0KCBrICktPkdldENhbGNQb3NQaXhlbCgpICkKCQkJCQkJCWJVc2VkUG9zID0gc2FsX1RydWU7CgkJCQl9CgkJCQkvLyBpZiBpdHMgZnJlZSwgYWRkIHRvIHBvb2wKCQkJCWlmICggIWJVc2VkUG9zICkKCQkJCXsKCQkJCQlhUG9zQXJyYXlbIGwgXSA9IGFQb3M7CgkJCQkJbCsrOwoJCQkJfQoJCQl9CgoJCQkvLyBpbml0aWFsIHBvc2l0aW9uaW5nIGZvciBzZWNvZGFyaWVzCgkJCWZvciAoIGogPSAwIDsgaiA8IG5MZXZlbFNlY09iakNvdW50IDsgaisrICkKCQkJewoJCQkJcFN3YXBXaW4gPSBMZXZlbFNlY0xpc3RbIGkgXS0+R2V0T2JqZWN0KCBqICk7CgkJCQlhV29ya0xpc3QuSW5zZXJ0KCBwU3dhcFdpbiwgTElTVF9BUFBFTkQpOwoJCQkJaWYgKCBwU3dhcFdpbiApCgkJCQkJcFN3YXBXaW4tPlNldENhbGNQb3NQaXhlbCggYVBvc0FycmF5WyBqIF0gKTsKCQkJfQoJCQlkTWluRGlzdCA9IENhbGNEaXN0U3VtKCBMZXZlbFNlY0xpc3RbIGkgXSApOwoKCQkJZE1pbkRpc3QgPSBNSU4oIGRNaW5EaXN0LCBJbXBsX1Blcm11dGVNaW4oICooTGV2ZWxTZWNMaXN0WyBpIF0pLCBhUG9zQXJyYXksIGFXb3JrTGlzdCwgZE1pbkRpc3QsIDAsIG5MZXZlbFNlY09iakNvdW50ICkpOwoKCQkJLy8gc2V0IG9wdGltaXplZCBwb3NpdGlvbnMgLSBtYXkgc3RpbGwgYmUgd3JvbmcgZnJvbSBsYXRlciB0cmllcwoJCQlmb3IgKCBqID0gMDsgaiA8IG5MZXZlbFNlY09iakNvdW50OyBqKysgKQoJCQl7CgkJCQlwU3dhcFdpbiA9IGFXb3JrTGlzdC5HZXRPYmplY3QoIGogKTsKCQkJCWlmICggcFN3YXBXaW4gKQoJCQkJCXBTd2FwV2luLT5TZXRDYWxjUG9zUGl4ZWwoICBhUG9zQXJyYXlbIGogXSApOwoJCQl9CgkJCWlmICggTGV2ZWxVc2VbIGkgXSArIExldmVsU2VjVXNlWyBpIF0gPiBERVBQRVJfTUFYX1dJRFRIICkKCQkJCW1uTGV2ZWxPZmZzZXQrKzsKCQl9CgkJaWYgKCBMZXZlbFVzZVsgaSBdICsgTGV2ZWxTZWNVc2VbIGkgXSA+IERFUFBFUl9NQVhfV0lEVEggKQoJCQltbkxldmVsT2Zmc2V0Kz0gKCBMZXZlbFVzZVsgaSBdICsgTGV2ZWxTZWNVc2VbIGkgXSApIC8gREVQUEVSX01BWF9XSURUSCA7CgkJaSsrOwoJfQoKCW1uTWluRHluWE9mZnMgPSAweGZmZmY7CgovLyBhbmQgYmFjayBhZ2Fpbi4uLgoJLy8gZ2V0IGJldHRlciByZXN1bHRzIGZvcm0gYWxyZWFkeSBwcmVvcHRpbWl6ZWQgdXBwZXIgYW5kIGxvd2VyIHJvd3MKCglkbwoJewoJCWktLTsKICAgICAgICBVcGRhdGVNYWluUHJvZ3Jlc3NCYXIoaSwgblNjYWxlVmFsLCBuU3RlcCwgc2FsX1RydWUpOyAvLyBzYWxfVHJ1ZSB+IGNvdW50aW5nIGRvd24KCQlpZiAoIExldmVsVXNlWyBpIF0gKyBMZXZlbFNlY1VzZVsgaSBdID4gREVQUEVSX01BWF9XSURUSCApCgkJCW1uTGV2ZWxPZmZzZXQtPSAoIExldmVsVXNlWyBpIF0gKyBMZXZlbFNlY1VzZVsgaSBdICkgLyBERVBQRVJfTUFYX1dJRFRIIDsKCQlPYmplY3RXaW4qIHBTd2FwV2luOwoJCXNhbF91SW50UHRyIG5MZXZlbE9iakNvdW50ID0gTGV2ZWxMaXN0WyBpIF0tPkNvdW50KCk7CgkJbW5YT2Zmc2V0ID0gQ2FsY1hPZmZzZXQoIG5MZXZlbE9iakNvdW50ICk7CgkJYVdvcmtMaXN0LkNsZWFyKCk7CgoJCWZvciAoIGogPSAwOyBqIDwgbkxldmVsT2JqQ291bnQ7IGorKyApCgkJewoJCQlwU3dhcFdpbiA9IExldmVsTGlzdFsgaSBdLT5HZXRPYmplY3QoIGogKTsKCQkJYVdvcmtMaXN0Lkluc2VydCggcFN3YXBXaW4sIExJU1RfQVBQRU5EKTsKCQkJUG9pbnQgYVBvcyA9IENhbGNQb3MoIGksIGogKTsKCQkJYVBvc0FycmF5WyBqIF0gPSBhUG9zOwovL25vIG5lZWQgdG8gZG8gdGhpcyBzdHVmZi4uLi4uLi4gCT8/Pz8/CgkJCWlmICggcFN3YXBXaW4gKQoJCQkJcFN3YXBXaW4tPlNldENhbGNQb3NQaXhlbCggYVBvc0FycmF5WyBqIF0gKTsKCQl9CgoJCWRvdWJsZSBkTWluRGlzdCA9IENhbGNEaXN0U3VtKCBMZXZlbExpc3RbIGkgXSwgQk9USCApOwoKCQlkTWluRGlzdCA9IE1JTiggZE1pbkRpc3QsIEltcGxfUGVybXV0ZU1pbiggKihMZXZlbExpc3RbIGkgXSksIGFQb3NBcnJheSwgYVdvcmtMaXN0LCBkTWluRGlzdCwgMCwgbkxldmVsT2JqQ291bnQsIEJPVEggKSk7Ci8vIHdyb25nIHBvc2l0aW9uIGZvciByZW1hcGluZyAtIGtlZXAgb2xkIHBvc2l0aW9ucyBmb3IgY29tcGFyaW5nCgkJZm9yICggaiA9IDA7IGogPCBuTGV2ZWxPYmpDb3VudDsgaisrICkKCQl7CgkJCXBTd2FwV2luID0gYVdvcmtMaXN0LkdldE9iamVjdCggaiApOwoJCQlpZiAoIHBTd2FwV2luICkKLy8JCQkJcFN3YXBXaW4tPlNldENhbGNQb3NQaXhlbCggbXBCYXNlV2luLT5Mb2dpY1RvUGl4ZWwoIGFQb3NBcnJheVsgaiBdICkpOwoJCQkJcFN3YXBXaW4tPlNldENhbGNQb3NQaXhlbCggYVBvc0FycmF5WyBqIF0gKTsKCQl9CgoJCWlmICggTGV2ZWxTZWNMaXN0WyBpIF0gIT0gTlVMTCApCgkJewoJCQlzYWxfdUludFB0ciBuTGV2ZWxTZWNPYmpDb3VudCA9IExldmVsU2VjTGlzdFsgaSBdLT5Db3VudCgpOwoJCQltblhPZmZzZXQgPSBDYWxjWE9mZnNldCggTGV2ZWxVc2VbIGkgXSArIG5MZXZlbFNlY09iakNvdW50ICk7CgkJCWFXb3JrTGlzdC5DbGVhcigpOwoKCQkJbCA9IDA7CgkJCXNhbF9Cb29sIGJVc2VkUG9zOwoKCQkJZm9yICggaiA9IDA7IGogPCAoIExldmVsVXNlWyBpIF0gKyBuTGV2ZWxTZWNPYmpDb3VudCApIDsgaisrICkKCQkJewoJCQkJUG9pbnQgYVBvcyA9IENhbGNQb3MoIGksIGogKTsKCQkJCWJVc2VkUG9zID0gc2FsX0ZhbHNlOwovLyBjb3VsZCBiZSBmYXN0ZXIKCQkJCWZvciAoIGsgPSAwOyBrIDwgbkxldmVsT2JqQ291bnQ7IGsrKyApCgkJCQl7CgkJCQkJaWYgKCBMZXZlbExpc3RbIGkgXS0+R2V0T2JqZWN0KCBrICkgKQoJCQkJCQlpZiAoIGFQb3MgPT0gTGV2ZWxMaXN0WyBpIF0tPkdldE9iamVjdCggayApLT5HZXRDYWxjUG9zUGl4ZWwoKSApCgkJCQkJCQliVXNlZFBvcyA9IHNhbF9UcnVlOwoJCQkJfQoJCQkJaWYgKCAhYlVzZWRQb3MgKQoJCQkJewoJCQkJCWFQb3NBcnJheVsgbCBdID0gYVBvczsKCQkJCQlsKys7CgkJCQl9CgkJCX0KCgkJCWZvciAoIGogPSAwIDsgaiA8IG5MZXZlbFNlY09iakNvdW50IDsgaisrICkKCQkJewoJCQkJcFN3YXBXaW4gPSBMZXZlbFNlY0xpc3RbIGkgXS0+R2V0T2JqZWN0KCBqICk7CgkJCQlhV29ya0xpc3QuSW5zZXJ0KCBwU3dhcFdpbiwgTElTVF9BUFBFTkQpOwoJCQkJaWYgKCBwU3dhcFdpbiApCgkJCQkJcFN3YXBXaW4tPlNldENhbGNQb3NQaXhlbCggYVBvc0FycmF5WyBqIF0gKTsKCQkJfQoJCQlkTWluRGlzdCA9IENhbGNEaXN0U3VtKCBMZXZlbFNlY0xpc3RbIGkgXSwgQk9USCApOwoKCQkJZE1pbkRpc3QgPSBNSU4oIGRNaW5EaXN0LCBJbXBsX1Blcm11dGVNaW4oICooTGV2ZWxTZWNMaXN0WyBpIF0pLCBhUG9zQXJyYXksIGFXb3JrTGlzdCwgZE1pbkRpc3QsIDAsIG5MZXZlbFNlY09iakNvdW50LCBCT1RIICkpOwovLyB3cm9uZyBwb3NpdGlvbiBmb3IgcmVtYXBpbmcgLSBrZWVwIG9sZCBwb3NpdGlvbnMgZm9yIGNvbXBhcmluZwoJCQlmb3IgKCBqID0gMDsgaiA8IG5MZXZlbFNlY09iakNvdW50OyBqKysgKQoJCQl7CgkJCQlwU3dhcFdpbiA9IGFXb3JrTGlzdC5HZXRPYmplY3QoIGogKTsKCQkJCWlmICggcFN3YXBXaW4gKQoJCQkJCXBTd2FwV2luLT5TZXRDYWxjUG9zUGl4ZWwoIGFQb3NBcnJheVsgaiBdICk7CgkJCX0KCQl9Ci8vCQlpLS07Cgl9IHdoaWxlICggaSAhPSAwICk7CiAgICBTZXRNYWluUHJvZ3Jlc3NCYXIoIDEwMCApOwoKCXNhbF91SW50UHRyIG5OZXdYU2l6ZSA9ICggREVQUEVSX01BWF9XSURUSCArIDEgKSAgKiAoIE9CSldJTl9YX1NQQUNJTkcgKyBHZXREZWZTaXplKCkuV2lkdGgoKSApOwoKICAgIC8vICAgIHNhbF91SW50UHRyIGFPYmpJRCA9IEdldFN0YXJ0KHBJZE1hcHBlciwgcE9iakxzdCkgLy9oaWVyIG113yBtYW4gc3dpdGNoZW4gR2V0U3RhcnQvR2V0UHJqU3RhcnQgb2RlciBzbwoKICAgIE9iamVjdFdpbiogcE9ialdpbiA9IE9iaklkVG9QdHIoIHBPYmpMc3QsIGFPYmpJRCk7CgoJc2FsX3VJbnRQdHIgbk5ld1lTaXplID0gcE9ialdpbi0+R2V0Q2FsY1Bvc1BpeGVsKCkuWSgpICsgR2V0RGVmU2l6ZSgpLkhlaWdodCgpICsgMiAqIE9CSldJTl9ZX1NQQUNJTkc7CglpZiAoKCBuVW52aXNZT2ZmcyArIEdldERlZlNpemUoKS5IZWlnaHQoKSkgPiBuTmV3WVNpemUgKQoJCW5OZXdZU2l6ZSA9IG5VbnZpc1lPZmZzICsgR2V0RGVmU2l6ZSgpLkhlaWdodCgpOwoKCU1hcE1vZGUgYU1hcE1vZGUgPSBHZXREZXBXaW4oKS0+R2V0TWFwTW9kZSgpOwoJU2l6ZSBhVG1wU2l6ZSggKHNhbF91SW50UHRyKSAoZG91YmxlKG5OZXdYU2l6ZSkgKiBkb3VibGUoIGFNYXBNb2RlLkdldFNjYWxlWCgpKSksIChzYWxfdUludFB0cikgKGRvdWJsZSggbk5ld1lTaXplKSAqIGRvdWJsZSggYU1hcE1vZGUuR2V0U2NhbGVZKCkpKSk7CgoJU2l6ZSBhTm93U2l6ZSggR2V0R3JhcGhXaW4oKS0+R2V0U2l6ZVBpeGVsKCkpOwoKCWlmICggR2V0RGVwV2luKCktPkxvZ2ljVG9QaXhlbCggYU5vd1NpemUgKS5XaWR0aCgpID4gYVRtcFNpemUuV2lkdGgoKSApCgkJYVRtcFNpemUuV2lkdGgoKSA9IEdldERlcFdpbigpLT5Mb2dpY1RvUGl4ZWwoIGFOb3dTaXplICkuV2lkdGgoKSA7CgoJaWYgKCBHZXREZXBXaW4oKS0+TG9naWNUb1BpeGVsKCBhTm93U2l6ZSApLkhlaWdodCgpICA+IGFUbXBTaXplLkhlaWdodCgpICkKCQlhVG1wU2l6ZS5IZWlnaHQoKSA9IEdldERlcFdpbigpLT5Mb2dpY1RvUGl4ZWwoIGFOb3dTaXplICkuSGVpZ2h0KCkgOwoKLy8JaWYgKCBuWm9vbWVkIDw9IDAgKQovLwl7Ci8vCQltcEJhc2VXaW4tPlNldFNpemVQaXhlbCggYVRtcFNpemUgKTsKLy8JCW1wR3JhcGhXaW4tPlNldFRvdGFsU2l6ZSggYVRtcFNpemUgKTsKLy8JCW1wR3JhcGhXaW4tPkVuZFNjcm9sbCggMCwgMCApOwovLwl9CgovLyBub3cgcmVtYXAgYWxsIG9iamVjdHMKCXNhbF91SW50UHRyIG5BbGxPYmpDb3VudCA9IHBPYmpMc3QtPkNvdW50KCk7CglQb2ludCBhVG1wUG9zOwoJZm9yICggaiA9IDA7IGogPCBuQWxsT2JqQ291bnQ7IGorKyApCgl7CgkJcFdpbiA9IHBPYmpMc3QtPkdldE9iamVjdCggaiApOwoJCWlmICggcFdpbi0+SXNWaXNpYmxlKCkpIHsKCQkJYVRtcFBvcyA9IHBXaW4tPkdldENhbGNQb3NQaXhlbCgpOwoJCQlpZiAoIHBXaW4tPm1iVmlzaXRlZCApCgkJCXsKLy8gcmVzZXJ2ZSBzcGFjZSBmb3IgdW5jb25uZWN0ZWQKCQkJCWFUbXBQb3MuWCgpIC09IG1uTWluRHluWE9mZnM7CgkJCQlhVG1wUG9zLlgoKSArPSBHZXREZWZTaXplKCkuV2lkdGgoKSArIE9CSldJTl9YX1NQQUNJTkc7Ci8vIGNlbnRlciB3aW5kb3cKCQkJCWFUbXBQb3MuWCgpICs9IEdldERlZlNpemUoKS5XaWR0aCgpIC8gMjsKCQkJCWFUbXBQb3MuWCgpIC09IHBXaW4tPlBpeGVsVG9Mb2dpYyggcFdpbi0+R2V0U2l6ZVBpeGVsKCkpLldpZHRoKCkgLyAyIDsKCQkJfQoJCQlwV2luLT5TZXRQb3NQaXhlbCggR2V0RGVwV2luKCktPkxvZ2ljVG9QaXhlbCggYVRtcFBvcyApKTsKCQl9Cgl9CglhV29ya0xpc3QuQ2xlYXIoKTsKCUdldERlcFdpbigpLT5FbmFibGVQYWludCggc2FsX1RydWUgKTsKCUdldERlcFdpbigpLT5JbnZhbGlkYXRlKCk7Ci8vTGV2ZWxMaXN0ZW4gbG9lc2NoZW4JICAgICAgICAgICAgICAgIEjkPyBXZWxjaGUgTGV2ZWxsaXN0ZW4/CgovL1VwZGF0ZSBhbGwgQ29ubmVjdG9ycwovLyAtLT4gVG8gYmUgZG9uZTogRG9uJ3QgY2FsbCB0d2ljZSBPYmplY3QxLUNvbm5lY3Rvci1PYmplY3QyCglPYmplY3RXaW4qIHBPYmplY3QxOwoJZm9yICggaSA9IDAgOyBpIDwgbk9iakNvdW50IDsgaSsrKQoJewoJICAgIHBPYmplY3QxID0gcE9iakxzdC0+R2V0T2JqZWN0KCBpICk7CgkJaWYgKCBwT2JqZWN0MS0+SXNWaXNpYmxlKCkpCgkJCXBPYmplY3QxLT5VcGRhdGVDb25uZWN0b3JzKCk7Cgl9OwoJcmV0dXJuIDA7Cn0KCnZvaWQgU29sRGVwOjpXcml0ZVRvRXJyb3JGaWxlKCkKewovL05lZWRzIHNvbWUgaW1wcm92ZW1lbnQKICAgIE9iamVjdFdpbiogcFdpbjsKICAgIFdhcm5pbmdCb3ggYVdCb3goIG1wQmFzZVdpbiwgV0JfT0ssIFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCJncmFwaCB0b28gZGVlcCEgZGF0IGdlaWh0IG5pY2ggZ3V0LlxubG9vayBhdCBkZXBwZXIuZXJyIGluIHlvdXIgVG1wLWRpcmVjdG9yeVxuZm9yIGxpc3Qgb2Ygb2JqZWN0cyIpKTsKCWFXQm94LkV4ZWN1dGUoKTsKCWNoYXIgKnRtcGRpciA9IGdldGVudigiVE1QIik7CgljaGFyICplcnJmaWxlYmFzZW5hbWUgPSAiZGVwcGVyLmVyciI7CgljaGFyICpFcnJGaWxlTmFtZSA9IChjaGFyKikgbWFsbG9jKCBzdHJsZW4oIHRtcGRpciApICsgc3RybGVuKCBlcnJmaWxlYmFzZW5hbWUpICsgMyApOwoJKkVyckZpbGVOYW1lID0gJ1wwJzsKCXN0cmNhdCggRXJyRmlsZU5hbWUsIHRtcGRpciApOwoJc3RyY2F0KCBFcnJGaWxlTmFtZSwgIlxcIiApOwoJc3RyY2F0KCBFcnJGaWxlTmFtZSwgZXJyZmlsZWJhc2VuYW1lICk7CglGSUxFKiBwRXJyRmlsZSA9IGZvcGVuKCAiZGVwcGVyLmVyciIsICJ3KyIgKTsKCWlmICggcEVyckZpbGUgKQoJewoJCWZvciAoIHNhbF91SW50MTYgaSA9IDA7IGkgPCBtcFRyYXZlbGxlckxpc3QtPkNvdW50KCk7IGkrKyApCgkJewoJCQlwV2luID0gbXBUcmF2ZWxsZXJMaXN0LT5HZXRPYmplY3QoIGkgKTsKCQkJZnByaW50ZiggcEVyckZpbGUsICIgJXMgLT4gXG4iLCAocFdpbi0+R2V0Qm9keVRleHQoKSkuR2V0QnVmZmVyKCkpOwoJCX0KCQlmY2xvc2UoIHBFcnJGaWxlICk7Cgl9Cn0K