LyoNCglGaWxlOgkJaVR1bmVzQVBJLmMNCgkNCglDb3B5cmlnaHQ6IAmpIENvcHlyaWdodCAyMDAzIEFwcGxlIENvbXB1dGVyLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQoJDQoJRGlzY2xhaW1lcjoJSU1QT1JUQU5UOiAgVGhpcyBBcHBsZSBzb2Z0d2FyZSBpcyBzdXBwbGllZCB0byB5b3UgYnkgQXBwbGUgQ29tcHV0ZXIsIEluYy4NCgkJCQkoIkFwcGxlIikgaW4gY29uc2lkZXJhdGlvbiBvZiB5b3VyIGFncmVlbWVudCB0byB0aGUgZm9sbG93aW5nIHRlcm1zLCBhbmQgeW91cg0KCQkJCXVzZSwgaW5zdGFsbGF0aW9uLCBtb2RpZmljYXRpb24gb3IgcmVkaXN0cmlidXRpb24gb2YgdGhpcyBBcHBsZSBzb2Z0d2FyZQ0KCQkJCWNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlc2UgdGVybXMuICBJZiB5b3UgZG8gbm90IGFncmVlIHdpdGggdGhlc2UgdGVybXMsDQoJCQkJcGxlYXNlIGRvIG5vdCB1c2UsIGluc3RhbGwsIG1vZGlmeSBvciByZWRpc3RyaWJ1dGUgdGhpcyBBcHBsZSBzb2Z0d2FyZS4NCg0KCQkJCUluIGNvbnNpZGVyYXRpb24gb2YgeW91ciBhZ3JlZW1lbnQgdG8gYWJpZGUgYnkgdGhlIGZvbGxvd2luZyB0ZXJtcywgYW5kIHN1YmplY3QNCgkJCQl0byB0aGVzZSB0ZXJtcywgQXBwbGUgZ3JhbnRzIHlvdSBhIHBlcnNvbmFsLCBub24tZXhjbHVzaXZlIGxpY2Vuc2UsIHVuZGVyIEFwcGxl1XMNCgkJCQljb3B5cmlnaHRzIGluIHRoaXMgb3JpZ2luYWwgQXBwbGUgc29mdHdhcmUgKHRoZSAiQXBwbGUgU29mdHdhcmUiKSwgdG8gdXNlLA0KCQkJCXJlcHJvZHVjZSwgbW9kaWZ5IGFuZCByZWRpc3RyaWJ1dGUgdGhlIEFwcGxlIFNvZnR3YXJlLCB3aXRoIG9yIHdpdGhvdXQNCgkJCQltb2RpZmljYXRpb25zLCBpbiBzb3VyY2UgYW5kL29yIGJpbmFyeSBmb3JtczsgcHJvdmlkZWQgdGhhdCBpZiB5b3UgcmVkaXN0cmlidXRlDQoJCQkJdGhlIEFwcGxlIFNvZnR3YXJlIGluIGl0cyBlbnRpcmV0eSBhbmQgd2l0aG91dCBtb2RpZmljYXRpb25zLCB5b3UgbXVzdCByZXRhaW4NCgkJCQl0aGlzIG5vdGljZSBhbmQgdGhlIGZvbGxvd2luZyB0ZXh0IGFuZCBkaXNjbGFpbWVycyBpbiBhbGwgc3VjaCByZWRpc3RyaWJ1dGlvbnMgb2YNCgkJCQl0aGUgQXBwbGUgU29mdHdhcmUuICBOZWl0aGVyIHRoZSBuYW1lLCB0cmFkZW1hcmtzLCBzZXJ2aWNlIG1hcmtzIG9yIGxvZ29zIG9mDQoJCQkJQXBwbGUgQ29tcHV0ZXIsIEluYy4gbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGUNCgkJCQlBcHBsZSBTb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBmcm9tIEFwcGxlLiAgRXhjZXB0IGFzDQoJCQkJZXhwcmVzc2x5IHN0YXRlZCBpbiB0aGlzIG5vdGljZSwgbm8gb3RoZXIgcmlnaHRzIG9yIGxpY2Vuc2VzLCBleHByZXNzIG9yIGltcGxpZWQsDQoJCQkJYXJlIGdyYW50ZWQgYnkgQXBwbGUgaGVyZWluLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGFueSBwYXRlbnQgcmlnaHRzIHRoYXQNCgkJCQltYXkgYmUgaW5mcmluZ2VkIGJ5IHlvdXIgZGVyaXZhdGl2ZSB3b3JrcyBvciBieSBvdGhlciB3b3JrcyBpbiB3aGljaCB0aGUgQXBwbGUNCgkJCQlTb2Z0d2FyZSBtYXkgYmUgaW5jb3Jwb3JhdGVkLg0KDQoJCQkJVGhlIEFwcGxlIFNvZnR3YXJlIGlzIHByb3ZpZGVkIGJ5IEFwcGxlIG9uIGFuICJBUyBJUyIgYmFzaXMuICBBUFBMRSBNQUtFUyBOTw0KCQkJCVdBUlJBTlRJRVMsIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBUSEUgSU1QTElFRA0KCQkJCVdBUlJBTlRJRVMgT0YgTk9OLUlORlJJTkdFTUVOVCwgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVINCgkJCQlQVVJQT1NFLCBSRUdBUkRJTkcgVEhFIEFQUExFIFNPRlRXQVJFIE9SIElUUyBVU0UgQU5EIE9QRVJBVElPTiBBTE9ORSBPUiBJTg0KCQkJCUNPTUJJTkFUSU9OIFdJVEggWU9VUiBQUk9EVUNUUy4NCg0KCQkJCUlOIE5PIEVWRU5UIFNIQUxMIEFQUExFIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNULCBJTkNJREVOVEFMIE9SDQoJCQkJQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURQ0KCQkJCUdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKQ0KCQkJCUFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSwgUkVQUk9EVUNUSU9OLCBNT0RJRklDQVRJT04gQU5EL09SIERJU1RSSUJVVElPTg0KCQkJCU9GIFRIRSBBUFBMRSBTT0ZUV0FSRSwgSE9XRVZFUiBDQVVTRUQgQU5EIFdIRVRIRVIgVU5ERVIgVEhFT1JZIE9GIENPTlRSQUNULCBUT1JUDQoJCQkJKElOQ0xVRElORyBORUdMSUdFTkNFKSwgU1RSSUNUIExJQUJJTElUWSBPUiBPVEhFUldJU0UsIEVWRU4gSUYgQVBQTEUgSEFTIEJFRU4NCgkJCQlBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4NCgkJCQkNCiovDQoNCiNpbmNsdWRlICJpVHVuZXNBUEkuaCIKI2luY2x1ZGUgImlUdW5lc1Zpc3VhbEFQSS5oIgoKCi8vIE1lbUNsZWFyCi8vCnN0YXRpYyB2b2lkIE1lbUNsZWFyIChMb2dpY2FsQWRkcmVzcyBkZXN0LCBTSW50MzIgbGVuZ3RoKQp7CglyZWdpc3RlciB1bnNpZ25lZCBjaGFyCSpwdHI7CgoJcHRyID0gKHVuc2lnbmVkIGNoYXIgKikgZGVzdDsKCQoJaWYoIGxlbmd0aCA+IDE2ICkKCXsKCQlyZWdpc3RlciB1bnNpZ25lZCBsb25nCSpsb25nUHRyOwoJCQoJCXdoaWxlKCAoKHVuc2lnbmVkIGxvbmcpIHB0ciAmIDMpICE9IDAgKQoJCXsKCQkJKnB0cisrID0gMDsKCQkJLS1sZW5ndGg7CgkJfQoJCQoJCWxvbmdQdHIgPSAodW5zaWduZWQgbG9uZyAqKSBwdHI7CgkJCgkJd2hpbGUoIGxlbmd0aCA+PSA0ICkKCQl7CgkJCSpsb25nUHRyKysgCT0gMDsKCQkJbGVuZ3RoCQktPSA0OwoJCX0KCQkKCQlwdHIgPSAodW5zaWduZWQgY2hhciAqKSBsb25nUHRyOwoJfQoJCgl3aGlsZSggLS1sZW5ndGggPj0gMCApCgl7CgkJKnB0cisrID0gMDsKCX0KfQoKCi8vIFNldE51bVZlcnNpb24KLy8Kdm9pZCBTZXROdW1WZXJzaW9uIChOdW1WZXJzaW9uICpudW1WZXJzaW9uLCBVSW50OCBtYWpvclJldiwgVUludDggbWlub3JBbmRCdWdSZXYsIFVJbnQ4IHN0YWdlLCBVSW50OCBub25SZWxSZXYpCnsKCW51bVZlcnNpb24tPm1ham9yUmV2CQk9IG1ham9yUmV2OwoJbnVtVmVyc2lvbi0+bWlub3JBbmRCdWdSZXYJPSBtaW5vckFuZEJ1Z1JldjsKCW51bVZlcnNpb24tPnN0YWdlCQkJPSBzdGFnZTsKCW51bVZlcnNpb24tPm5vblJlbFJldgkJPSBub25SZWxSZXY7Cn0KCgovLyBJVENhbGxBcHBsaWNhdGlvbgovLwpzdGF0aWMgT1NTdGF0dXMgSVRDYWxsQXBwbGljYXRpb25JbnRlcm5hbCAodm9pZCAqYXBwQ29va2llLCBJVEFwcFByb2NQdHIgaGFuZGxlciwgT1NUeXBlIG1lc3NhZ2UsIFVJbnQzMiBtZXNzYWdlTWFqb3JWZXJzaW9uLCBVSW50MzIgbWVzc2FnZU1pbm9yVmVyc2lvbiwgUGxheWVyTWVzc2FnZUluZm8gKm1lc3NhZ2VJbmZvKQp7CglQbGF5ZXJNZXNzYWdlSW5mbwlsb2NhbE1lc3NhZ2VJbmZvOwoJCglpZiAobWVzc2FnZUluZm8gPT0gbmlsKQoJewoJCU1lbUNsZWFyKCZsb2NhbE1lc3NhZ2VJbmZvLCBzaXplb2YobG9jYWxNZXNzYWdlSW5mbykpOwoJCQoJCW1lc3NhZ2VJbmZvID0gJmxvY2FsTWVzc2FnZUluZm87Cgl9CgkKCW1lc3NhZ2VJbmZvLT5tZXNzYWdlTWFqb3JWZXJzaW9uID0gbWVzc2FnZU1ham9yVmVyc2lvbjsKCW1lc3NhZ2VJbmZvLT5tZXNzYWdlTWlub3JWZXJzaW9uID0gbWVzc2FnZU1pbm9yVmVyc2lvbjsKCW1lc3NhZ2VJbmZvLT5tZXNzYWdlSW5mb1NpemUJID0gc2l6ZW9mKFBsYXllck1lc3NhZ2VJbmZvKTsKCQoJcmV0dXJuIGhhbmRsZXIoYXBwQ29va2llLCBtZXNzYWdlLCBtZXNzYWdlSW5mbyk7Cn0KCi8vIElUQ2FsbEFwcGxpY2F0aW9uCi8vCk9TU3RhdHVzIElUQ2FsbEFwcGxpY2F0aW9uICh2b2lkICphcHBDb29raWUsIElUQXBwUHJvY1B0ciBoYW5kbGVyLCBPU1R5cGUgbWVzc2FnZSwgUGxheWVyTWVzc2FnZUluZm8gKm1lc3NhZ2VJbmZvKQp7CglyZXR1cm4gSVRDYWxsQXBwbGljYXRpb25JbnRlcm5hbChhcHBDb29raWUsIGhhbmRsZXIsIG1lc3NhZ2UsIGtJVFBsdWdpbk1ham9yTWVzc2FnZVZlcnNpb24sIGtJVFBsdWdpbk1pbm9yTWVzc2FnZVZlcnNpb24sIG1lc3NhZ2VJbmZvKTsKfQoKCi8vIFBsYXllclNldEZ1bGxTY3JlZW4KLy8KT1NTdGF0dXMgUGxheWVyU2V0RnVsbFNjcmVlbiAodm9pZCAqYXBwQ29va2llLCBJVEFwcFByb2NQdHIgYXBwUHJvYywgQm9vbGVhbiBmdWxsU2NyZWVuKQp7CglQbGF5ZXJNZXNzYWdlSW5mbwltZXNzYWdlSW5mbzsKCQoJTWVtQ2xlYXIoJm1lc3NhZ2VJbmZvLCBzaXplb2YobWVzc2FnZUluZm8pKTsKCQoJbWVzc2FnZUluZm8udS5zZXRGdWxsU2NyZWVuTWVzc2FnZS5mdWxsU2NyZWVuID0gZnVsbFNjcmVlbjsKCglyZXR1cm4gSVRDYWxsQXBwbGljYXRpb24oYXBwQ29va2llLCBhcHBQcm9jLCBrUGxheWVyU2V0RnVsbFNjcmVlbk1lc3NhZ2UsICZtZXNzYWdlSW5mbyk7Cn0KCgovLyBQbGF5ZXJTZXRGdWxsU2NyZWVuT3B0aW9ucwovLwpPU1N0YXR1cyBQbGF5ZXJTZXRGdWxsU2NyZWVuT3B0aW9ucyAodm9pZCAqYXBwQ29va2llLCBJVEFwcFByb2NQdHIgYXBwUHJvYywgU0ludDE2IG1pbkJpdERlcHRoLCBTSW50MTYgbWF4Qml0RGVwdGgsIFNJbnQxNiBwcmVmZXJyZWRCaXREZXB0aCwgU0ludDE2IGRlc2lyZWRXaWR0aCwgU0ludDE2IGRlc2lyZWRIZWlnaHQpCnsKCVBsYXllck1lc3NhZ2VJbmZvCW1lc3NhZ2VJbmZvOwoJCglNZW1DbGVhcigmbWVzc2FnZUluZm8sIHNpemVvZihtZXNzYWdlSW5mbykpOwoJCgltZXNzYWdlSW5mby51LnNldEZ1bGxTY3JlZW5PcHRpb25zTWVzc2FnZS5taW5CaXREZXB0aAkJPSBtaW5CaXREZXB0aDsKCW1lc3NhZ2VJbmZvLnUuc2V0RnVsbFNjcmVlbk9wdGlvbnNNZXNzYWdlLm1heEJpdERlcHRoCQk9IG1heEJpdERlcHRoOwoJbWVzc2FnZUluZm8udS5zZXRGdWxsU2NyZWVuT3B0aW9uc01lc3NhZ2UucHJlZmVycmVkQml0RGVwdGggPSBwcmVmZXJyZWRCaXREZXB0aDsKCW1lc3NhZ2VJbmZvLnUuc2V0RnVsbFNjcmVlbk9wdGlvbnNNZXNzYWdlLmRlc2lyZWRXaWR0aAkJPSBkZXNpcmVkV2lkdGg7CgltZXNzYWdlSW5mby51LnNldEZ1bGxTY3JlZW5PcHRpb25zTWVzc2FnZS5kZXNpcmVkSGVpZ2h0CQk9IGRlc2lyZWRIZWlnaHQ7CgoJcmV0dXJuIElUQ2FsbEFwcGxpY2F0aW9uKGFwcENvb2tpZSwgYXBwUHJvYywga1BsYXllclNldEZ1bGxTY3JlZW5PcHRpb25zTWVzc2FnZSwgJm1lc3NhZ2VJbmZvKTsKfQoKLy8gUGxheWVyR2V0Q3VycmVudFRyYWNrQ292ZXJBcnQKLy8KT1NTdGF0dXMgUGxheWVyR2V0Q3VycmVudFRyYWNrQ292ZXJBcnQgKHZvaWQgKmFwcENvb2tpZSwgSVRBcHBQcm9jUHRyIGFwcFByb2MsIEhhbmRsZSAqY292ZXJBcnQsIE9TVHlwZSAqY292ZXJBcnRGb3JtYXQpCnsKCU9TU3RhdHVzCQkJc3RhdHVzOwoJUGxheWVyTWVzc2FnZUluZm8JbWVzc2FnZUluZm87CgkKCU1lbUNsZWFyKCZtZXNzYWdlSW5mbywgc2l6ZW9mKG1lc3NhZ2VJbmZvKSk7CgkKCW1lc3NhZ2VJbmZvLnUuZ2V0Q3VycmVudFRyYWNrQ292ZXJBcnRNZXNzYWdlLmNvdmVyQXJ0ID0gbmlsOwoKCXN0YXR1cyA9IElUQ2FsbEFwcGxpY2F0aW9uKGFwcENvb2tpZSwgYXBwUHJvYywga1BsYXllckdldEN1cnJlbnRUcmFja0NvdmVyQXJ0TWVzc2FnZSwgJm1lc3NhZ2VJbmZvKTsKCgkqY292ZXJBcnQgPSBtZXNzYWdlSW5mby51LmdldEN1cnJlbnRUcmFja0NvdmVyQXJ0TWVzc2FnZS5jb3ZlckFydDsKCWlmIChjb3ZlckFydEZvcm1hdCkKCQkqY292ZXJBcnRGb3JtYXQgPSBtZXNzYWdlSW5mby51LmdldEN1cnJlbnRUcmFja0NvdmVyQXJ0TWVzc2FnZS5jb3ZlckFydEZvcm1hdDsKCXJldHVybiBzdGF0dXM7Cn0KCi8vIFBsYXllckdldFBsdWdpbkRhdGEKLy8KT1NTdGF0dXMgUGxheWVyR2V0UGx1Z2luRGF0YSAodm9pZCAqYXBwQ29va2llLCBJVEFwcFByb2NQdHIgYXBwUHJvYywgdm9pZCAqZGF0YVB0ciwgVUludDMyIGRhdGFCdWZmZXJTaXplLCBVSW50MzIgKmRhdGFTaXplKQp7CglPU1N0YXR1cwkJCXN0YXR1czsKCVBsYXllck1lc3NhZ2VJbmZvCW1lc3NhZ2VJbmZvOwoJCglNZW1DbGVhcigmbWVzc2FnZUluZm8sIHNpemVvZihtZXNzYWdlSW5mbykpOwoJCgltZXNzYWdlSW5mby51LmdldFBsdWdpbkRhdGFNZXNzYWdlLmRhdGFQdHIJCQk9IGRhdGFQdHI7CgltZXNzYWdlSW5mby51LmdldFBsdWdpbkRhdGFNZXNzYWdlLmRhdGFCdWZmZXJTaXplCT0gZGF0YUJ1ZmZlclNpemU7CgkKCXN0YXR1cyA9IElUQ2FsbEFwcGxpY2F0aW9uKGFwcENvb2tpZSwgYXBwUHJvYywga1BsYXllckdldFBsdWdpbkRhdGFNZXNzYWdlLCAmbWVzc2FnZUluZm8pOwoJCglpZiAoZGF0YVNpemUgIT0gbmlsKQoJCSpkYXRhU2l6ZSA9IG1lc3NhZ2VJbmZvLnUuZ2V0UGx1Z2luRGF0YU1lc3NhZ2UuZGF0YVNpemU7CgkKCXJldHVybiBzdGF0dXM7Cn0KCgovLyBQbGF5ZXJTZXRQbHVnaW5EYXRhCi8vCk9TU3RhdHVzIFBsYXllclNldFBsdWdpbkRhdGEgKHZvaWQgKmFwcENvb2tpZSwgSVRBcHBQcm9jUHRyIGFwcFByb2MsIHZvaWQgKmRhdGFQdHIsIFVJbnQzMiBkYXRhU2l6ZSkKewoJUGxheWVyTWVzc2FnZUluZm8JbWVzc2FnZUluZm87CgkKCU1lbUNsZWFyKCZtZXNzYWdlSW5mbywgc2l6ZW9mKG1lc3NhZ2VJbmZvKSk7CgkKCW1lc3NhZ2VJbmZvLnUuc2V0UGx1Z2luRGF0YU1lc3NhZ2UuZGF0YVB0cgk9IGRhdGFQdHI7CgltZXNzYWdlSW5mby51LnNldFBsdWdpbkRhdGFNZXNzYWdlLmRhdGFTaXplCT0gZGF0YVNpemU7CgkKCXJldHVybiBJVENhbGxBcHBsaWNhdGlvbihhcHBDb29raWUsIGFwcFByb2MsIGtQbGF5ZXJTZXRQbHVnaW5EYXRhTWVzc2FnZSwgJm1lc3NhZ2VJbmZvKTsKfQoKCi8vIFBsYXllckdldFBsdWdpbk5hbWVkRGF0YQovLwpPU1N0YXR1cyBQbGF5ZXJHZXRQbHVnaW5OYW1lZERhdGEgKHZvaWQgKmFwcENvb2tpZSwgSVRBcHBQcm9jUHRyIGFwcFByb2MsIENvbnN0U3RyaW5nUHRyIGRhdGFOYW1lLCB2b2lkICpkYXRhUHRyLCBVSW50MzIgZGF0YUJ1ZmZlclNpemUsIFVJbnQzMiAqZGF0YVNpemUpCnsKCU9TU3RhdHVzCQkJc3RhdHVzOwoJUGxheWVyTWVzc2FnZUluZm8JbWVzc2FnZUluZm87CgkKCU1lbUNsZWFyKCZtZXNzYWdlSW5mbywgc2l6ZW9mKG1lc3NhZ2VJbmZvKSk7CgkKCW1lc3NhZ2VJbmZvLnUuZ2V0UGx1Z2luTmFtZWREYXRhTWVzc2FnZS5kYXRhTmFtZQkJPSBkYXRhTmFtZTsKCW1lc3NhZ2VJbmZvLnUuZ2V0UGx1Z2luTmFtZWREYXRhTWVzc2FnZS5kYXRhUHRyCQkJPSBkYXRhUHRyOwoJbWVzc2FnZUluZm8udS5nZXRQbHVnaW5OYW1lZERhdGFNZXNzYWdlLmRhdGFCdWZmZXJTaXplCT0gZGF0YUJ1ZmZlclNpemU7CgkKCXN0YXR1cyA9IElUQ2FsbEFwcGxpY2F0aW9uKGFwcENvb2tpZSwgYXBwUHJvYywga1BsYXllckdldFBsdWdpbk5hbWVkRGF0YU1lc3NhZ2UsICZtZXNzYWdlSW5mbyk7CgkKCWlmIChkYXRhU2l6ZSAhPSBuaWwpCgkJKmRhdGFTaXplID0gbWVzc2FnZUluZm8udS5nZXRQbHVnaW5OYW1lZERhdGFNZXNzYWdlLmRhdGFTaXplOwoJCglyZXR1cm4gc3RhdHVzOwp9CgoKLy8gUGxheWVyU2V0UGx1Z2luTmFtZWREYXRhCi8vCk9TU3RhdHVzIFBsYXllclNldFBsdWdpbk5hbWVkRGF0YSAodm9pZCAqYXBwQ29va2llLCBJVEFwcFByb2NQdHIgYXBwUHJvYywgQ29uc3RTdHJpbmdQdHIgZGF0YU5hbWUsIHZvaWQgKmRhdGFQdHIsIFVJbnQzMiBkYXRhU2l6ZSkKewoJUGxheWVyTWVzc2FnZUluZm8JbWVzc2FnZUluZm87CgkKCU1lbUNsZWFyKCZtZXNzYWdlSW5mbywgc2l6ZW9mKG1lc3NhZ2VJbmZvKSk7CgkKCW1lc3NhZ2VJbmZvLnUuc2V0UGx1Z2luTmFtZWREYXRhTWVzc2FnZS5kYXRhTmFtZQk9IGRhdGFOYW1lOwoJbWVzc2FnZUluZm8udS5zZXRQbHVnaW5OYW1lZERhdGFNZXNzYWdlLmRhdGFQdHIJCT0gZGF0YVB0cjsKCW1lc3NhZ2VJbmZvLnUuc2V0UGx1Z2luTmFtZWREYXRhTWVzc2FnZS5kYXRhU2l6ZQk9IGRhdGFTaXplOwoJCglyZXR1cm4gSVRDYWxsQXBwbGljYXRpb24oYXBwQ29va2llLCBhcHBQcm9jLCBrUGxheWVyU2V0UGx1Z2luTmFtZWREYXRhTWVzc2FnZSwgJm1lc3NhZ2VJbmZvKTsKfQoKCi8vIFBsYXllcklkbGUKLy8KT1NTdGF0dXMgUGxheWVySWRsZSAodm9pZCAqYXBwQ29va2llLCBJVEFwcFByb2NQdHIgYXBwUHJvYykKewoJcmV0dXJuIElUQ2FsbEFwcGxpY2F0aW9uKGFwcENvb2tpZSwgYXBwUHJvYywga1BsYXllcklkbGVNZXNzYWdlLCBuaWwpOwp9CgoKLy8gUGxheWVyU2hvd0Fib3V0Ci8vCnZvaWQgUGxheWVyU2hvd0Fib3V0ICh2b2lkICphcHBDb29raWUsIElUQXBwUHJvY1B0ciBhcHBQcm9jKQp7CglJVENhbGxBcHBsaWNhdGlvbihhcHBDb29raWUsIGFwcFByb2MsIGtQbGF5ZXJTaG93QWJvdXRNZXNzYWdlLCBuaWwpOwp9CgoKLy8gUGxheWVyT3BlblVSTAovLwp2b2lkIFBsYXllck9wZW5VUkwgKHZvaWQgKmFwcENvb2tpZSwgSVRBcHBQcm9jUHRyIGFwcFByb2MsIFNJbnQ4ICpzdHJpbmcsIFVJbnQzMiBsZW5ndGgpCnsKCVBsYXllck1lc3NhZ2VJbmZvCW1lc3NhZ2VJbmZvOwoJCglNZW1DbGVhcigmbWVzc2FnZUluZm8sIHNpemVvZihtZXNzYWdlSW5mbykpOwoJCgltZXNzYWdlSW5mby51Lm9wZW5VUkxNZXNzYWdlLnVybAk9IHN0cmluZzsKCW1lc3NhZ2VJbmZvLnUub3BlblVSTE1lc3NhZ2UubGVuZ3RoCT0gbGVuZ3RoOwoKCUlUQ2FsbEFwcGxpY2F0aW9uKGFwcENvb2tpZSwgYXBwUHJvYywga1BsYXllck9wZW5VUkxNZXNzYWdlLCAmbWVzc2FnZUluZm8pOwp9CgovLyBQbGF5ZXJVbnJlZ2lzdGVyUGx1Z2luCi8vCk9TU3RhdHVzIFBsYXllclVucmVnaXN0ZXJQbHVnaW4gKHZvaWQgKmFwcENvb2tpZSwgSVRBcHBQcm9jUHRyIGFwcFByb2MsIFBsYXllck1lc3NhZ2VJbmZvICptZXNzYWdlSW5mbykKewoJcmV0dXJuIElUQ2FsbEFwcGxpY2F0aW9uKGFwcENvb2tpZSwgYXBwUHJvYywga1BsYXllclVucmVnaXN0ZXJQbHVnaW5NZXNzYWdlLCBtZXNzYWdlSW5mbyk7Cn0KCgovLyBQbGF5ZXJSZWdpc3RlclZpc3VhbFBsdWdpbgovLwpPU1N0YXR1cyBQbGF5ZXJSZWdpc3RlclZpc3VhbFBsdWdpbiAodm9pZCAqYXBwQ29va2llLCBJVEFwcFByb2NQdHIgYXBwUHJvYywgUGxheWVyTWVzc2FnZUluZm8gKm1lc3NhZ2VJbmZvKQp7CglyZXR1cm4gSVRDYWxsQXBwbGljYXRpb25JbnRlcm5hbChhcHBDb29raWUsIGFwcFByb2MsIGtQbGF5ZXJSZWdpc3RlclZpc3VhbFBsdWdpbk1lc3NhZ2UsIGtJVFZpc3VhbFBsdWdpbk1ham9yTWVzc2FnZVZlcnNpb24sIGtJVFZpc3VhbFBsdWdpbk1pbm9yTWVzc2FnZVZlcnNpb24sIG1lc3NhZ2VJbmZvKTsKfQoKCi8vIFBsYXllckdldFBsdWdpbklURmlsZVNwZWMKLy8KT1NTdGF0dXMgUGxheWVyR2V0UGx1Z2luSVRGaWxlU3BlYyAodm9pZCAqYXBwQ29va2llLCBJVEFwcFByb2NQdHIgYXBwUHJvYywgSVRGaWxlU3BlYyAqcGx1Z2luRmlsZVNwZWMpCnsKCVBsYXllck1lc3NhZ2VJbmZvCW1lc3NhZ2VJbmZvOwoJCglNZW1DbGVhcigmbWVzc2FnZUluZm8sIHNpemVvZihtZXNzYWdlSW5mbykpOwoJCgltZXNzYWdlSW5mby51LmdldFBsdWdpbklURmlsZVNwZWNNZXNzYWdlLmZpbGVTcGVjID0gcGx1Z2luRmlsZVNwZWM7CgkKCXJldHVybiBJVENhbGxBcHBsaWNhdGlvbihhcHBDb29raWUsIGFwcFByb2MsIGtQbGF5ZXJHZXRQbHVnaW5JVEZpbGVTcGVjTWVzc2FnZSwgJm1lc3NhZ2VJbmZvKTsKfQoKCi8vIFBsYXllckdldEZpbGVUcmFja0luZm8KLy8KT1NTdGF0dXMgUGxheWVyR2V0RmlsZVRyYWNrSW5mbyAodm9pZCAqYXBwQ29va2llLCBJVEFwcFByb2NQdHIgYXBwUHJvYywgY29uc3QgSVRGaWxlU3BlYyAqZmlsZVNwZWMsIElUVHJhY2tJbmZvICp0cmFja0luZm8pCnsKCVBsYXllck1lc3NhZ2VJbmZvCW1lc3NhZ2VJbmZvOwoJCglNZW1DbGVhcigmbWVzc2FnZUluZm8sIHNpemVvZihtZXNzYWdlSW5mbykpOwoJCgltZXNzYWdlSW5mby51LmdldEZpbGVUcmFja0luZm9NZXNzYWdlLmZpbGVTcGVjIAk9IGZpbGVTcGVjOwoJbWVzc2FnZUluZm8udS5nZXRGaWxlVHJhY2tJbmZvTWVzc2FnZS50cmFja0luZm8gPSB0cmFja0luZm87CgkKCXJldHVybiBJVENhbGxBcHBsaWNhdGlvbihhcHBDb29raWUsIGFwcFByb2MsIGtQbGF5ZXJHZXRGaWxlVHJhY2tJbmZvTWVzc2FnZSwgJm1lc3NhZ2VJbmZvKTsKfQoKLy8gUGxheWVyU2V0RmlsZVRyYWNrSW5mbwovLwpPU1N0YXR1cyBQbGF5ZXJTZXRGaWxlVHJhY2tJbmZvICh2b2lkICphcHBDb29raWUsIElUQXBwUHJvY1B0ciBhcHBQcm9jLCBjb25zdCBJVEZpbGVTcGVjICpmaWxlU3BlYywgY29uc3QgSVRUcmFja0luZm8gKnRyYWNrSW5mbykKewoJUGxheWVyTWVzc2FnZUluZm8JbWVzc2FnZUluZm87CgkKCU1lbUNsZWFyKCZtZXNzYWdlSW5mbywgc2l6ZW9mKG1lc3NhZ2VJbmZvKSk7CgkKCW1lc3NhZ2VJbmZvLnUuc2V0RmlsZVRyYWNrSW5mb01lc3NhZ2UuZmlsZVNwZWMgCT0gZmlsZVNwZWM7CgltZXNzYWdlSW5mby51LnNldEZpbGVUcmFja0luZm9NZXNzYWdlLnRyYWNrSW5mbyA9IHRyYWNrSW5mbzsKCQoJcmV0dXJuIElUQ2FsbEFwcGxpY2F0aW9uKGFwcENvb2tpZSwgYXBwUHJvYywga1BsYXllclNldEZpbGVUcmFja0luZm9NZXNzYWdlLCAmbWVzc2FnZUluZm8pOwp9CgovLyBQbGF5ZXJHZXRJVFRyYWNrSW5mb1NpemUKLy8KT1NTdGF0dXMgUGxheWVyR2V0SVRUcmFja0luZm9TaXplICh2b2lkICphcHBDb29raWUsIElUQXBwUHJvY1B0ciBhcHBQcm9jLCBVSW50MzIgYXBwUGx1Z2luTWFqb3JWZXJzaW9uLCBVSW50MzIgYXBwUGx1Z2luTWlub3JWZXJzaW9uLCBVSW50MzIgKml0VHJhY2tJbmZvU2l6ZSkKewoJUGxheWVyTWVzc2FnZUluZm8JbWVzc2FnZUluZm87CglPU1N0YXR1cwkJCXN0YXR1czsKCQoJLyoKCQlOb3RlOiBhcHBQbHVnaW5NYWpvclZlcnNpb24gYW5kIGFwcFBsdWdpbk1pbm9yVmVyc2lvbiBhcmUgdGhlIHZlcnNpb25zIGdpdmVuIHRvIHRoZSBwbHVnaW4gYnkgaVR1bmVzIGluIHRoZSBwbHVnaW4ncyBpbml0IG1lc3NhZ2UuCgkJCSAgVGhlc2UgdmVyc2lvbnMgYXJlICpub3QqIHRoZSB2ZXJzaW9uIG9mIHRoZSBBUEkgdXNlZCB3aGVuIHRoZSBwbHVnaW4gd2FzIGNvbXBpbGVkLgoJKi8KCQoJKml0VHJhY2tJbmZvU2l6ZSA9IDA7CgkKCU1lbUNsZWFyKCZtZXNzYWdlSW5mbywgc2l6ZW9mKG1lc3NhZ2VJbmZvKSk7CgkKCXN0YXR1cyA9IElUQ2FsbEFwcGxpY2F0aW9uKGFwcENvb2tpZSwgYXBwUHJvYywga1BsYXllckdldElUVHJhY2tJbmZvU2l6ZU1lc3NhZ2UsICZtZXNzYWdlSW5mbyk7CglpZiggc3RhdHVzID09IG5vRXJyICkKCXsKCQkqaXRUcmFja0luZm9TaXplID0gbWVzc2FnZUluZm8udS5nZXRJVFRyYWNrSW5mb1NpemVNZXNzYWdlLml0VHJhY2tJbmZvU2l6ZTsKCX0KCWVsc2UgaWYoIGFwcFBsdWdpbk1ham9yVmVyc2lvbiA9PSAxMCAmJiBhcHBQbHVnaW5NaW5vclZlcnNpb24gPT0gMiApCgl7CgkJLy8gaVR1bmVzIDIuMC54CgkJCgkJKml0VHJhY2tJbmZvU2l6ZSA9ICgoVUludDMyKSAmKChJVFRyYWNrSW5mbyAqKSAwKS0+Y29tcG9zZXIpOwoJCQoJCXN0YXR1cyA9IG5vRXJyOwoJfQoJZWxzZSBpZiggYXBwUGx1Z2luTWFqb3JWZXJzaW9uID09IDEwICYmIGFwcFBsdWdpbk1pbm9yVmVyc2lvbiA9PSAzICkKCXsKCQkvLyBpVHVuZXMgMy4wLngKCQkKCQkqaXRUcmFja0luZm9TaXplID0gKChVSW50MzIpICYoKElUVHJhY2tJbmZvICopIDApLT5iZWF0c1Blck1pbnV0ZSk7CgkJCgkJc3RhdHVzID0gbm9FcnI7Cgl9CgllbHNlCgl7CgkJLy8gaVR1bmVzIDQuMCBhbmQgbGF0ZXIgaW1wbGVtZW50IHRoZSBrUGxheWVyR2V0SVRUcmFja0luZm9TaXplTWVzc2FnZSBtZXNzYWdlLiBJZiB5b3UgZ290IGhlcmUKCQkvLyB0aGVuIHRoZSBhcHBQbHVnaW5NYWpvclZlcnNpb24gb3IgYXBwUGx1Z2luTWlub3JWZXJzaW9uIGFyZSBpbmNvcnJlY3QuCgkJCgkJc3RhdHVzID0gcGFyYW1FcnI7Cgl9CgkKCWlmKCBzdGF0dXMgPT0gbm9FcnIgJiYgKCppdFRyYWNrSW5mb1NpemUpID4gc2l6ZW9mKElUVHJhY2tJbmZvKSApCgl7CgkJLy8gaVR1bmVzIGlzIHVzaW5nIGEgbGFyZ2VyIElUVHJhY2tJbmZvIHRoYW4gdGhlIG9uZSB3aGVuIHRoaXMgcGx1Z2luIHdhcyBjb21waWxlZC4gUGluICppdFRyYWNrSW5mb1NpemUgdG8gdGhlIHBsdWdpbidzIGtub3duIHNpemUKCQkKCQkqaXRUcmFja0luZm9TaXplID0gc2l6ZW9mKElUVHJhY2tJbmZvKTsKCX0KCQoJcmV0dXJuIHN0YXR1czsKfQ==