LyoKICogc2NoZW1hcy5jIDogaW1wbGVtZW50YXRpb24gb2YgdGhlIFhNTCBTY2hlbWEgaGFuZGxpbmcgYW5kCiAqICAgICAgICAgICAgIHNjaGVtYSB2YWxpZGl0eSBjaGVja2luZwogKgogKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIERhbmllbCBWZWlsbGFyZCA8dmVpbGxhcmRAcmVkaGF0LmNvbT4KICovCgovKgogKiBUT0RPOgogKiAgIC0gd2hlbiB0eXBlcyBhcmUgcmVkZWZpbmVkIGluIGluY2x1ZGVzLCBjaGVjayB0aGF0IGFsbAogKiAgICAgdHlwZXMgaW4gdGhlIHJlZGVmIGxpc3QgYXJlIGVxdWFsCiAqICAgICAtPiBuZWVkIGEgdHlwZSBlcXVhbGl0eSBvcGVyYXRpb24uCiAqLwojZGVmaW5lIElOX0xJQlhNTAojaW5jbHVkZSAibGlieG1sLmgiCgojaWZkZWYgTElCWE1MX1NDSEVNQVNfRU5BQkxFRAoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8bGlieG1sL3htbG1lbW9yeS5oPgojaW5jbHVkZSA8bGlieG1sL3BhcnNlci5oPgojaW5jbHVkZSA8bGlieG1sL3BhcnNlckludGVybmFscy5oPgojaW5jbHVkZSA8bGlieG1sL2hhc2guaD4KI2luY2x1ZGUgPGxpYnhtbC91cmkuaD4KCiNpbmNsdWRlIDxsaWJ4bWwveG1sc2NoZW1hcy5oPgojaW5jbHVkZSA8bGlieG1sL3NjaGVtYXNJbnRlcm5hbHMuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxzY2hlbWFzdHlwZXMuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxhdXRvbWF0YS5oPgojaW5jbHVkZSA8bGlieG1sL3htbHJlZ2V4cC5oPgojaW5jbHVkZSA8bGlieG1sL2RpY3QuaD4KCi8qICNkZWZpbmUgREVCVUcgMSAqLwoKLyogI2RlZmluZSBERUJVR19DT05URU5UIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfVFlQRSAxICovCgovKiAjZGVmaW5lIERFQlVHX0NPTlRFTlRfUkVHRVhQIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfQVVUT01BVEEgMSAqLwoKLyogI2RlZmluZSBERUJVR19BVFRSX1ZBTElEQVRJT04gMSAqLwoKI2RlZmluZSBVTkJPVU5ERUQgKDEgPDwgMzApCiNkZWZpbmUgVE9ETyAJCQkJCQkJCVwKICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAkJCQlcCgkgICAgIlVuaW1wbGVtZW50ZWQgYmxvY2sgYXQgJXM6JWRcbiIsCQkJCVwKICAgICAgICAgICAgX19GSUxFX18sIF9fTElORV9fKTsKCiNkZWZpbmUgWE1MX1NDSEVNQVNfREVGQVVMVF9OQU1FU1BBQ0UgKGNvbnN0IHhtbENoYXIgKikidGhlIGRlZmF1bHQgbmFtZXNwYWNlIgoKLyoKICogVGhlIFhNTCBTY2hlbWFzIG5hbWVzcGFjZXMKICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFOcyA9IChjb25zdCB4bWxDaGFyICopCiAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiOwoKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYUluc3RhbmNlTnMgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIjsKCiNkZWZpbmUgSVNfU0NIRU1BKG5vZGUsIHR5cGUpCQkJCQkJXAogICAoKG5vZGUgIT0gTlVMTCkgJiYgKG5vZGUtPm5zICE9IE5VTEwpICYmCQkJCVwKICAgICh4bWxTdHJFcXVhbChub2RlLT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSB0eXBlKSkgJiYJCVwKICAgICh4bWxTdHJFcXVhbChub2RlLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSkKCiNkZWZpbmUgWE1MX1NDSEVNQVNfUEFSU0VfRVJST1IJCTEKCiNkZWZpbmUgU0NIRU1BU19QQVJTRV9PUFRJT05TIFhNTF9QQVJTRV9OT0VOVAoKc3RydWN0IF94bWxTY2hlbWFQYXJzZXJDdHh0IHsKICAgIHZvaWQgKnVzZXJEYXRhOyAgICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIGRhdGEgYmxvY2sgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVycm9yOyAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIGVycm9ycyAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuaW5nOyAgICAgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiB3YXJuaW5nICovCiAgICB4bWxTY2hlbWFWYWxpZEVycm9yIGVycjsKICAgIGludCBuYmVycm9yczsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2Vycm9yOwoKICAgIHhtbFNjaGVtYVB0ciB0b3BzY2hlbWE7CS8qIFRoZSBtYWluIHNjaGVtYSAqLwogICAgeG1sSGFzaFRhYmxlUHRyIG5hbWVzcGFjZXM7CS8qIEhhc2ggdGFibGUgb2YgbmFtZXNwYWNlcyB0byBzY2hlbWFzICovCgogICAgeG1sU2NoZW1hUHRyIHNjaGVtYTsgICAgICAgIC8qIFRoZSBzY2hlbWEgaW4gdXNlICovCiAgICBjb25zdCB4bWxDaGFyICpjb250YWluZXI7ICAgLyogdGhlIGN1cnJlbnQgZWxlbWVudCwgZ3JvdXAsIC4uLiAqLwogICAgaW50IGNvdW50ZXI7CgogICAgY29uc3QgeG1sQ2hhciAqVVJMOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIGludCBwcmVzZXJ2ZTsJCS8qIFdoZXRoZXIgdGhlIGRvYyBzaG91bGQgYmUgZnJlZWQgICovCgogICAgY29uc3QgY2hhciAqYnVmZmVyOwogICAgaW50IHNpemU7CgogICAgLyoKICAgICAqIFVzZWQgdG8gYnVpbGQgY29tcGxleCBlbGVtZW50IGNvbnRlbnQgbW9kZWxzCiAgICAgKi8KICAgIHhtbEF1dG9tYXRhUHRyIGFtOwogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydDsKICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgZW5kOwogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGF0ZTsKCiAgICB4bWxEaWN0UHRyIGRpY3Q7CQkvKiBkaWN0aW9ubmFyeSBmb3IgaW50ZXJuZWQgc3RyaW5nIG5hbWVzICovCiAgICBpbnQgICAgICAgIGluY2x1ZGVzOwkvKiB0aGUgaW5jbHVzaW9uIGxldmVsLCAwIGZvciByb290IG9yIGltcG9ydHMgKi8KfTsKCgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTiAxCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEIDIKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQgMwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfTUlTU0lORyA0CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX1ZBTFVFIDUKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1RZUEVfTk9UX1JFU09MVkVEIDYKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRyU3RhdGUgeG1sU2NoZW1hQXR0clN0YXRlOwp0eXBlZGVmIHhtbFNjaGVtYUF0dHJTdGF0ZSAqeG1sU2NoZW1hQXR0clN0YXRlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUF0dHJTdGF0ZSB7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgbmV4dDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCBzdGF0ZTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBkZWNsOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dDoKICoKICogQSBTY2hlbWFzIHZhbGlkYXRpb24gY29udGV4dAogKi8KCnN0cnVjdCBfeG1sU2NoZW1hVmFsaWRDdHh0IHsKICAgIHZvaWQgKnVzZXJEYXRhOyAgICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIGRhdGEgYmxvY2sgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVycm9yOyAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIGVycm9ycyAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuaW5nOyAgICAgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiB3YXJuaW5nICovCiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNlcnJvcjsKCiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOyAgICAgICAgLyogVGhlIHNjaGVtYSBpbiB1c2UgKi8KICAgIHhtbERvY1B0ciBkb2M7CiAgICB4bWxQYXJzZXJJbnB1dEJ1ZmZlclB0ciBpbnB1dDsKICAgIHhtbENoYXJFbmNvZGluZyBlbmM7CiAgICB4bWxTQVhIYW5kbGVyUHRyIHNheDsKICAgIHZvaWQgKnVzZXJfZGF0YTsKCiAgICB4bWxEb2NQdHIgbXlEb2M7CiAgICBpbnQgZXJyOwogICAgaW50IG5iZXJyb3JzOwoKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIHhtbE5vZGVQdHIgY3VyOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKICAgIHhtbFJlZ0V4ZWNDdHh0UHRyIHJlZ2V4cDsKICAgIHhtbFNjaGVtYVZhbFB0ciB2YWx1ZTsKCiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgYXR0clRvcDsKICAgIC8qIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBhdHRyQmFzZTsgKi8KICAgIC8qIGludCBhdHRyTWF4OyAqLwogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGF0dHI7Cn07CgovKgogKiBUaGVzZSBhcmUgdGhlIGVudHJpZXMgaW4gdGhlIHNjaGVtYXMgaW1wb3J0U2NoZW1hcyBoYXNoIHRhYmxlCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSW1wb3J0IHhtbFNjaGVtYUltcG9ydDsKdHlwZWRlZiB4bWxTY2hlbWFJbXBvcnQgKnhtbFNjaGVtYUltcG9ydFB0cjsKc3RydWN0IF94bWxTY2hlbWFJbXBvcnQgewogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb247CiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOwp9OwoKLyoKICogVGhlc2UgYXJlIHRoZSBlbnRyaWVzIGFzc29jaWF0ZWQgdG8gaW5jbHVkZXMgaW4gYSBzY2hlbWFzCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSW5jbHVkZSB4bWxTY2hlbWFJbmNsdWRlOwp0eXBlZGVmIHhtbFNjaGVtYUluY2x1ZGUgKnhtbFNjaGVtYUluY2x1ZGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSW5jbHVkZSB7CiAgICB4bWxTY2hlbWFJbmNsdWRlUHRyIG5leHQ7CgogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb247CiAgICB4bWxEb2NQdHIgZG9jOwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVNvbWUgcHJlZGVjbGFyYXRpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgaW50IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogdmFsdWUpOwoKc3RhdGljIGludCB4bWxTY2hlbWFQYXJzZUluY2x1ZGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWVJbnRlcm5hbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICAgY29uc3QgeG1sQ2hhciAqIHZhbHVlLAoJCQkgICAgIGludCBmaXJlRXJyb3JzKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJCQkJCQkqCiAqIAkJCURhdGF0eXBlIGVycm9yIGhhbmRsZXJzCQkJCSoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hUEVyck1lbW9yeToKICogQG5vZGU6IGEgY29udGV4dCBub2RlCiAqIEBleHRyYTogIGV4dHJhIGluZm9ybWF0aW9ucwogKgogKiBIYW5kbGUgYW4gb3V0IG9mIG1lbW9yeSBjb25kaXRpb24KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBFcnJNZW1vcnkoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmV4dHJhLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGlmIChjdHh0ICE9IE5VTEwpCiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgIF9feG1sU2ltcGxlRXJyb3IoWE1MX0ZST01fU0NIRU1BU1AsIFhNTF9FUlJfTk9fTUVNT1JZLCBub2RlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICBleHRyYSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQRXJyOgogKiBAY3R4dDogdGhlIHBhcnNpbmcgY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBtc2c6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBleHRyYSBkYXRhCiAqIEBzdHIyOiBleHRyYSBkYXRhCiAqIAogKiBIYW5kbGUgYSBwYXJzZXIgZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIGludCBlcnJvciwKICAgICAgICAgICAgICBjb25zdCBjaGFyICptc2csIGNvbnN0IHhtbENoYXIgKiBzdHIxLCBjb25zdCB4bWxDaGFyICogc3RyMikKewogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgdm9pZCAqZGF0YSA9IE5VTEw7CgogICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPm5iZXJyb3JzKys7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKCXNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgfQogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLCBOVUxMLCAwLCAwLAogICAgICAgICAgICAgICAgICAgIG1zZywgc3RyMSwgc3RyMik7Cn0KCi8qKgogKiB4bWxTY2hlbWFQRXJyMjoKICogQGN0eHQ6IHRoZSBwYXJzaW5nIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQG5vZGU6IHRoZSBjdXJyZW50IGNoaWxkCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVycjIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgY2hpbGQsIGludCBlcnJvciwKICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgY29uc3QgeG1sQ2hhciAqIHN0cjIpCnsKICAgIGlmIChjaGlsZCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY2hpbGQsIGVycm9yLCBtc2csIHN0cjEsIHN0cjIpOwogICAgZWxzZQogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIG1zZywgc3RyMSwgc3RyMik7Cn0KCiNpZiAwCi8qKgogKiB4bWxTY2hlbWFQRXJyRXh0OgogKiBAY3R4dDogdGhlIHBhcnNpbmcgY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlIAogKiBAc3RyRGF0YTE6IGV4dHJhIGRhdGEKICogQHN0ckRhdGEyOiBleHRyYSBkYXRhCiAqIEBzdHJEYXRhMzogZXh0cmEgZGF0YQogKiBAbXNnOiB0aGUgbWVzc2FnZQogKiBAc3RyMTogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyMjogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyMzogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyNDogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyNTogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiAKICogSGFuZGxlIGEgcGFyc2VyIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQRXJyRXh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLCBpbnQgZXJyb3IsCgkJY29uc3QgeG1sQ2hhciAqIHN0ckRhdGExLCBjb25zdCB4bWxDaGFyICogc3RyRGF0YTIsIAoJCWNvbnN0IHhtbENoYXIgKiBzdHJEYXRhMywgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgCgkJY29uc3QgeG1sQ2hhciAqIHN0cjIsIGNvbnN0IHhtbENoYXIgKiBzdHIzLCBjb25zdCB4bWxDaGFyICogc3RyNCwKCQljb25zdCB4bWxDaGFyICogc3RyNSkKewoKICAgIHhtbEdlbmVyaWNFcnJvckZ1bmMgY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+dXNlckRhdGE7CglzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgIH0KICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwgbm9kZSwgWE1MX0ZST01fU0NIRU1BU1AsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IsIFhNTF9FUlJfRVJST1IsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKikgc3RyRGF0YTEsIChjb25zdCBjaGFyICopIHN0ckRhdGEyLCAKCQkgICAgKGNvbnN0IGNoYXIgKikgc3RyRGF0YTMsIDAsIDAsIG1zZywgc3RyMSwgc3RyMiwgCgkJICAgIHN0cjMsIHN0cjQsIHN0cjUpOwp9CiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYVZUeXBlRXJyTWVtb3J5OgogKiBAbm9kZTogYSBjb250ZXh0IG5vZGUKICogQGV4dHJhOiAgZXh0cmEgaW5mb3JtYXRpb25zCiAqCiAqIEhhbmRsZSBhbiBvdXQgb2YgbWVtb3J5IGNvbmRpdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkVyck1lbW9yeSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpleHRyYSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgICAgICBjdHh0LT5lcnIgPSBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUw7CiAgICB9CiAgICBfX3htbFNpbXBsZUVycm9yKFhNTF9GUk9NX1NDSEVNQVNWLCBYTUxfRVJSX05PX01FTU9SWSwgbm9kZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgZXh0cmEpOwp9CgovKioKICogeG1sU2NoZW1hVkVycjM6CiAqIEBjdHh0OiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogQHN0cjM6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHZhbGlkYXRpb24gZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZFcnIzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIGludCBlcnJvciwKICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICpzdHIxLCBjb25zdCB4bWxDaGFyICpzdHIyLAoJICAgICAgIGNvbnN0IHhtbENoYXIgKnN0cjMpCnsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwoJY3R4dC0+ZXJyID0gZXJyb3I7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIHNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKICAgIH0KICAgIC8qIHJlYWp1c3QgdG8gZ2xvYmFsIGVycm9yIG51bWJlcnMgKi8KICAgIGVycm9yICs9IFhNTF9TQ0hFTUFWX05PUk9PVCAtIFhNTF9TQ0hFTUFTX0VSUl9OT1JPT1Q7CiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNWLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopIHN0cjEsIChjb25zdCBjaGFyICopIHN0cjIsCgkJICAgIChjb25zdCBjaGFyICopIHN0cjMsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgbXNnLCBzdHIxLCBzdHIyLCBzdHIzKTsKfQovKioKICogeG1sU2NoZW1hVkVycjoKICogQGN0eHQ6IHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbXNnOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogZXh0cmEgZGF0YQogKiBAc3RyMjogZXh0cmEgZGF0YQogKiAKICogSGFuZGxlIGEgdmFsaWRhdGlvbiBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLCBpbnQgZXJyb3IsCiAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgY29uc3QgeG1sQ2hhciAqIHN0cjIpCnsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwoJY3R4dC0+ZXJyID0gZXJyb3I7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKICAgICAgICBzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgIH0KICAgIC8qIHJlYWp1c3QgdG8gZ2xvYmFsIGVycm9yIG51bWJlcnMgKi8KICAgIGVycm9yICs9IFhNTF9TQ0hFTUFWX05PUk9PVCAtIFhNTF9TQ0hFTUFTX0VSUl9OT1JPT1Q7CiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNWLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopIHN0cjEsIChjb25zdCBjaGFyICopIHN0cjIsIE5VTEwsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgbXNnLCBzdHIxLCBzdHIyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCUFsbG9jYXRpb24gZnVuY3Rpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYU5ld1NjaGVtYToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQWxsb2NhdGUgYSBuZXcgU2NoZW1hIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQdHIKeG1sU2NoZW1hTmV3U2NoZW1hKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBzY2hlbWEiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgcmV0LT5kaWN0ID0gY3R4dC0+ZGljdDsKICAgIHhtbERpY3RSZWZlcmVuY2UocmV0LT5kaWN0KTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdGYWNldDoKICoKICogQWxsb2NhdGUgYSBuZXcgRmFjZXQgc3RydWN0dXJlLgogKgogKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvciBlcnJvcgogKi8KeG1sU2NoZW1hRmFjZXRQdHIKeG1sU2NoZW1hTmV3RmFjZXQodm9pZCkKewogICAgeG1sU2NoZW1hRmFjZXRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFGYWNldFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld0Fubm90OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgbm9kZQogKgogKiBBbGxvY2F0ZSBhIG5ldyBhbm5vdGF0aW9uIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFOZXdBbm5vdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hQW5ub3RQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFBbm5vdFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhbm5vdGF0aW9uIiwgbm9kZSk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgcmV0LT5jb250ZW50ID0gbm9kZTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBbm5vdDoKICogQGFubm90OiAgYSBzY2hlbWEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIGFubm90YXRpb24gc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQW5ub3QoeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3QpCnsKICAgIGlmIChhbm5vdCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIHhtbEZyZWUoYW5ub3QpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUltcG9ydDoKICogQGltcG9ydDogIGEgc2NoZW1hIGltcG9ydCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhbiBpbXBvcnQgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW1wb3J0KHhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQpCnsKICAgIGlmIChpbXBvcnQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgeG1sU2NoZW1hRnJlZShpbXBvcnQtPnNjaGVtYSk7CiAgICB4bWxGcmVlKGltcG9ydCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSW5jbHVkZToKICogQGluY2x1ZGU6ICBhIHNjaGVtYSBpbmNsdWRlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGFuIGluY2x1ZGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW5jbHVkZSh4bWxTY2hlbWFJbmNsdWRlUHRyIGluY2x1ZGUpCnsKICAgIGlmIChpbmNsdWRlID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIHhtbEZyZWVEb2MoaW5jbHVkZS0+ZG9jKTsKICAgIHhtbEZyZWUoaW5jbHVkZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSW5jbHVkZUxpc3Q6CiAqIEBpbmNsdWRlczogIGEgc2NoZW1hIGluY2x1ZGUgbGlzdAogKgogKiBEZWFsbG9jYXRlIGFuIGluY2x1ZGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW5jbHVkZUxpc3QoeG1sU2NoZW1hSW5jbHVkZVB0ciBpbmNsdWRlcykKewogICAgeG1sU2NoZW1hSW5jbHVkZVB0ciBuZXh0OwoKICAgIHdoaWxlIChpbmNsdWRlcyAhPSBOVUxMKSB7CiAgICAgICAgbmV4dCA9IGluY2x1ZGVzLT5uZXh0OwoJeG1sU2NoZW1hRnJlZUluY2x1ZGUoaW5jbHVkZXMpOwoJaW5jbHVkZXMgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZU5vdGF0aW9uOgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgbm90YXRpb24gc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgTm90YXRpb24gc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZU5vdGF0aW9uKHhtbFNjaGVtYU5vdGF0aW9uUHRyIG5vdGEpCnsKICAgIGlmIChub3RhID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgeG1sRnJlZShub3RhKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGU6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBhdHRyaWJ1dGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgQXR0cmlidXRlIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGUoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIpCnsKICAgIGlmIChhdHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgeG1sRnJlZShhdHRyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0OgogKiBzZXQ6ICBhIHNjaGVtYSB3aWxkY2FyZCBuYW1lc3BhY2UKICoKICogRGVhbGxvY2F0ZSBhIGxpc3Qgb2Ygd2lsZGNhcmQgY29uc3RyYWludCBzdHJ1Y3R1cmVzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBzZXQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgbmV4dDsKCiAgICB3aGlsZSAoc2V0ICE9IE5VTEwpIHsKCW5leHQgPSBzZXQtPm5leHQ7Cgl4bWxGcmVlKHNldCk7CglzZXQgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZVdpbGRjYXJkOgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgYXR0cmlidXRlIGdyb3VwIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIEF0dHJpYnV0ZSBHcm91cCBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlV2lsZGNhcmQoeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZGNhcmQpCnsKICAgIGlmICh3aWxkY2FyZCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmICh3aWxkY2FyZC0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3Qod2lsZGNhcmQtPmFubm90KTsKICAgIGlmICh3aWxkY2FyZC0+bnNTZXQgIT0gTlVMTCkgCgl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldCh3aWxkY2FyZC0+bnNTZXQpOyAgICAKICAgIGlmICh3aWxkY2FyZC0+bmVnTnNTZXQgIT0gTlVMTCkgCgl4bWxGcmVlKHdpbGRjYXJkLT5uZWdOc1NldCk7ICAgIAogICAgeG1sRnJlZSh3aWxkY2FyZCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlQXR0cmlidXRlR3JvdXA6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBhdHRyaWJ1dGUgZ3JvdXAgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgQXR0cmlidXRlIEdyb3VwIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBhdHRyKQp7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChhdHRyLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChhdHRyLT5hbm5vdCk7CiAgICBpZiAoKGF0dHItPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX0dMT0JBTCkgJiYgCgkoYXR0ci0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkpCgl4bWxTY2hlbWFGcmVlV2lsZGNhcmQoYXR0ci0+YXR0cmlidXRlV2lsZGNhcmQpOwoKICAgIHhtbEZyZWUoYXR0cik7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlQXR0cmlidXRlVXNlTGlzdDoKICogQGF0dHJVc2U6ICBhIHNjaGVtYSBhdHRyaWJ1dGUgbGluayBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIGxpc3Qgb2Ygc2NoZW1hIGF0dHJpYnV0ZSB1c2VzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QoeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBhdHRyVXNlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyIG5leHQ7CgogICAgd2hpbGUgKGF0dHJVc2UgIT0gTlVMTCkgewoJbmV4dCA9IGF0dHJVc2UtPm5leHQ7Cgl4bWxGcmVlKGF0dHJVc2UpOwoJYXR0clVzZSA9IG5leHQ7CiAgICB9ICAgIAp9CgovKioKICogeG1sU2NoZW1hRnJlZUVsZW1lbnQ6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBlbGVtZW50IHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIEVsZW1lbnQgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUVsZW1lbnQoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtKQp7CiAgICBpZiAoZWxlbSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChlbGVtLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChlbGVtLT5hbm5vdCk7CiAgICBpZiAoZWxlbS0+Y29udE1vZGVsICE9IE5VTEwpCiAgICAgICAgeG1sUmVnRnJlZVJlZ2V4cChlbGVtLT5jb250TW9kZWwpOwogICAgeG1sRnJlZShlbGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVGYWNldDoKICogQGZhY2V0OiAgYSBzY2hlbWEgZmFjZXQgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgRmFjZXQgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlRmFjZXQoeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIGlmIChmYWNldCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChmYWNldC0+dmFsICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGZhY2V0LT52YWwpOwogICAgaWYgKGZhY2V0LT5yZWdleHAgIT0gTlVMTCkKICAgICAgICB4bWxSZWdGcmVlUmVnZXhwKGZhY2V0LT5yZWdleHApOwogICAgaWYgKGZhY2V0LT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChmYWNldC0+YW5ub3QpOwogICAgeG1sRnJlZShmYWNldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlVHlwZToKICogQHR5cGU6ICBhIHNjaGVtYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIFR5cGUgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHR5cGUtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KHR5cGUtPmFubm90KTsKICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LCBuZXh0OwoKICAgICAgICBmYWNldCA9IHR5cGUtPmZhY2V0czsKICAgICAgICB3aGlsZSAoZmFjZXQgIT0gTlVMTCkgewogICAgICAgICAgICBuZXh0ID0gZmFjZXQtPm5leHQ7CiAgICAgICAgICAgIHhtbFNjaGVtYUZyZWVGYWNldChmYWNldCk7CiAgICAgICAgICAgIGZhY2V0ID0gbmV4dDsKICAgICAgICB9CiAgICB9CiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCWlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QodHlwZS0+YXR0cmlidXRlVXNlcyk7CglpZiAoKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpICYmIAoJICAgICgodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgfHwKCSAgICAoKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpICYmIAoJICAgICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfT1dORURfQVRUUl9XSUxEQ0FSRCkpKSkgeyAKCSAgICB4bWxTY2hlbWFGcmVlV2lsZGNhcmQodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpOwoJfQogICAgfQogICAgeG1sRnJlZSh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlTGlzdDoKICogQHR5cGU6ICBhIHNjaGVtYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIFR5cGUgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZVR5cGVMaXN0KHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBuZXh0OwoKICAgIHdoaWxlICh0eXBlICE9IE5VTEwpIHsKICAgICAgICBuZXh0ID0gdHlwZS0+cmVkZWY7Cgl4bWxTY2hlbWFGcmVlVHlwZSh0eXBlKTsKCXR5cGUgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZToKICogQHNjaGVtYTogIGEgc2NoZW1hIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIHN0cnVjdHVyZS4KICovCnZvaWQKeG1sU2NoZW1hRnJlZSh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICBpZiAoc2NoZW1hID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChzY2hlbWEtPm5vdGFEZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT5ub3RhRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlTm90YXRpb24pOwogICAgaWYgKHNjaGVtYS0+YXR0ckRlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmF0dHJEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGUpOwogICAgaWYgKHNjaGVtYS0+YXR0cmdycERlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmF0dHJncnBEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVHcm91cCk7CiAgICBpZiAoc2NoZW1hLT5lbGVtRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZUVsZW1lbnQpOwogICAgaWYgKHNjaGVtYS0+dHlwZURlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPnR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVUeXBlTGlzdCk7CiAgICBpZiAoc2NoZW1hLT5ncm91cERlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmdyb3VwRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlVHlwZSk7CiAgICBpZiAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cyAhPSBOVUxMKQoJeG1sSGFzaEZyZWUoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywKCQkgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZUltcG9ydCk7CiAgICBpZiAoc2NoZW1hLT5pbmNsdWRlcyAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hRnJlZUluY2x1ZGVMaXN0KCh4bWxTY2hlbWFJbmNsdWRlUHRyKSBzY2hlbWEtPmluY2x1ZGVzKTsKICAgIH0KICAgIGlmIChzY2hlbWEtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KHNjaGVtYS0+YW5ub3QpOwogICAgaWYgKHNjaGVtYS0+ZG9jICE9IE5VTEwgJiYgIXNjaGVtYS0+cHJlc2VydmUpCiAgICAgICAgeG1sRnJlZURvYyhzY2hlbWEtPmRvYyk7CiAgICB4bWxEaWN0RnJlZShzY2hlbWEtPmRpY3QpOwoKICAgIHhtbEZyZWUoc2NoZW1hKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCURlYnVnIGZ1bmN0aW9ucwkJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaWZkZWYgTElCWE1MX09VVFBVVF9FTkFCTEVECgovKioKICogeG1sU2NoZW1hRWxlbWVudER1bXA6CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqCiAqIER1bXAgdGhlIGVsZW1lbnQKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUVsZW1lbnREdW1wKHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbSwgRklMRSAqIG91dHB1dCwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIGNvbnRleHQgQVRUUklCVVRFX1VOVVNFRCwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICBpZiAoZWxlbSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICBmcHJpbnRmKG91dHB1dCwgIkVsZW1lbnQgIik7CiAgICBpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgImdsb2JhbCAiKTsKICAgIGZwcmludGYob3V0cHV0LCAiOiAlcyAiLCBlbGVtLT5uYW1lKTsKICAgIGlmIChuYW1lc3BhY2UgIT0gTlVMTCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm5hbWVzcGFjZSAnJXMnICIsIG5hbWVzcGFjZSk7CgogICAgaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRSkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm5pbGxhYmxlICIpOwogICAgaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9ERUZBVUxUKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiZGVmYXVsdCAiKTsKICAgIGlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJmaXhlZCAiKTsKICAgIGlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1QpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJhYnN0cmFjdCAiKTsKICAgIGlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fUkVGKQogICAgICAgIGZwcmludGYob3V0cHV0LCAicmVmICclcycgIiwgZWxlbS0+cmVmKTsKICAgIGlmIChlbGVtLT5pZCAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiaWQgJyVzJyAiLCBlbGVtLT5pZCk7CiAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICBpZiAoKGVsZW0tPm1pbk9jY3VycyAhPSAxKSB8fCAoZWxlbS0+bWF4T2NjdXJzICE9IDEpKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgICIpOwogICAgICAgIGlmIChlbGVtLT5taW5PY2N1cnMgIT0gMSkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtaW46ICVkICIsIGVsZW0tPm1pbk9jY3Vycyk7CiAgICAgICAgaWYgKGVsZW0tPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAibWF4OiB1bmJvdW5kZWRcbiIpOwogICAgICAgIGVsc2UgaWYgKGVsZW0tPm1heE9jY3VycyAhPSAxKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm1heDogJWRcbiIsIGVsZW0tPm1heE9jY3Vycyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICB9CiAgICBpZiAoZWxlbS0+bmFtZWRUeXBlICE9IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgdHlwZTogJXMiLCBlbGVtLT5uYW1lZFR5cGUpOwogICAgICAgIGlmIChlbGVtLT5uYW1lZFR5cGVOcyAhPSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiBucyAlc1xuIiwgZWxlbS0+bmFtZWRUeXBlTnMpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQogICAgaWYgKGVsZW0tPnN1YnN0R3JvdXAgIT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiICBzdWJzdGl0dXRpb25Hcm91cDogJXMiLCBlbGVtLT5zdWJzdEdyb3VwKTsKICAgICAgICBpZiAoZWxlbS0+c3Vic3RHcm91cE5zICE9IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiIG5zICVzXG4iLCBlbGVtLT5zdWJzdEdyb3VwTnMpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQogICAgaWYgKGVsZW0tPnZhbHVlICE9IE5VTEwpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIGRlZmF1bHQ6ICVzIiwgZWxlbS0+dmFsdWUpOwp9CgovKioKICogeG1sU2NoZW1hQW5ub3REdW1wOgogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqIEBhbm5vdDogIGEgYW5ub3RhdGlvbgogKgogKiBEdW1wIHRoZSBhbm5vdGF0aW9uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFBbm5vdER1bXAoRklMRSAqIG91dHB1dCwgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3QpCnsKICAgIHhtbENoYXIgKmNvbnRlbnQ7CgogICAgaWYgKGFubm90ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGNvbnRlbnQgPSB4bWxOb2RlR2V0Q29udGVudChhbm5vdC0+Y29udGVudCk7CiAgICBpZiAoY29udGVudCAhPSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIEFubm90OiAlc1xuIiwgY29udGVudCk7CiAgICAgICAgeG1sRnJlZShjb250ZW50KTsKICAgIH0gZWxzZQogICAgICAgIGZwcmludGYob3V0cHV0LCAiICBBbm5vdDogZW1wdHlcbiIpOwp9CgovKioKICogeG1sU2NoZW1hVHlwZUR1bXA6CiAqIEBvdXRwdXQ6ICB0aGUgZmlsZSBvdXRwdXQKICogQHR5cGU6ICBhIHR5cGUgc3RydWN0dXJlCiAqCiAqIER1bXAgYSBTY2hlbWFUeXBlIHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVHlwZUR1bXAoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBGSUxFICogb3V0cHV0KQp7CiAgICBpZiAodHlwZSA9PSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICJUeXBlOiBOVUxMXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgIlR5cGU6ICIpOwogICAgaWYgKHR5cGUtPm5hbWUgIT0gTlVMTCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiVzLCAiLCB0eXBlLT5uYW1lKTsKICAgIGVsc2UKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm5vIG5hbWUiKTsKICAgIHN3aXRjaCAodHlwZS0+dHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgImJhc2ljICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAic2ltcGxlICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgImNvbXBsZXggIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgInNlcXVlbmNlICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiY2hvaWNlICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiYWxsICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9VUjoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJ1ciAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAicmVzdHJpY3Rpb24gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTjoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJleHRlbnNpb24gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAidW5rbm93bnR5cGUlZCAiLCB0eXBlLT50eXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBpZiAodHlwZS0+YmFzZSAhPSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICJiYXNlICVzLCAiLCB0eXBlLT5iYXNlKTsKICAgIH0KICAgIHN3aXRjaCAodHlwZS0+Y29udGVudFR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgInVua25vd24gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgImVtcHR5ICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJlbGVtZW50ICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtaXhlZCAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRURfT1JfRUxFTUVOVFM6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAibWl4ZWRfb3JfZWxlbXMgIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgImJhc2ljICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAic2ltcGxlICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9BTlk6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiYW55ICIpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIGlmICgodHlwZS0+bWluT2NjdXJzICE9IDEpIHx8ICh0eXBlLT5tYXhPY2N1cnMgIT0gMSkpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgIik7CiAgICAgICAgaWYgKHR5cGUtPm1pbk9jY3VycyAhPSAxKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm1pbjogJWQgIiwgdHlwZS0+bWluT2NjdXJzKTsKICAgICAgICBpZiAodHlwZS0+bWF4T2NjdXJzID49IFVOQk9VTkRFRCkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtYXg6IHVuYm91bmRlZFxuIik7CiAgICAgICAgZWxzZSBpZiAodHlwZS0+bWF4T2NjdXJzICE9IDEpCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAibWF4OiAlZFxuIiwgdHlwZS0+bWF4T2NjdXJzKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KICAgIGlmICh0eXBlLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUFubm90RHVtcChvdXRwdXQsIHR5cGUtPmFubm90KTsKICAgIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBzdWIgPSB0eXBlLT5zdWJ0eXBlczsKCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIHN1YnR5cGVzOiAiKTsKICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICIlcyAiLCBzdWItPm5hbWUpOwogICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgfQogICAgICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KCn0KCi8qKgogKiB4bWxTY2hlbWFEdW1wOgogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBzdHJ1Y3R1cmUKICoKICogRHVtcCBhIFNjaGVtYSBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUR1bXAoRklMRSAqIG91dHB1dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSkKewogICAgaWYgKHNjaGVtYSA9PSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICJTY2hlbWFzOiBOVUxMXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgIlNjaGVtYXM6ICIpOwogICAgaWYgKHNjaGVtYS0+bmFtZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiJXMsICIsIHNjaGVtYS0+bmFtZSk7CiAgICBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJubyBuYW1lLCAiKTsKICAgIGlmIChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiJXMiLCAoY29uc3QgY2hhciAqKSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CiAgICBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJubyB0YXJnZXQgbmFtZXNwYWNlIik7CiAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICBpZiAoc2NoZW1hLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUFubm90RHVtcChvdXRwdXQsIHNjaGVtYS0+YW5ub3QpOwoKICAgIHhtbEhhc2hTY2FuKHNjaGVtYS0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hVHlwZUR1bXAsCiAgICAgICAgICAgICAgICBvdXRwdXQpOwogICAgeG1sSGFzaFNjYW5GdWxsKHNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hTY2FubmVyRnVsbCkgeG1sU2NoZW1hRWxlbWVudER1bXAsIG91dHB1dCk7Cn0KI2VuZGlmIC8qIExJQlhNTF9PVVRQVVRfRU5BQkxFRCAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCQkJCQkJCSoKICogCQkJVXRpbGl0aWVzCQkJCQkqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUdldFByb3A6CiAqIEBjdHh0OiB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5vZGU6IHRoZSBub2RlCiAqIEBuYW1lOiB0aGUgcHJvcGVydHkgbmFtZQogKiAKICogUmVhZCBhIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgaW50ZXJuYWxpemUgdGhlIHN0cmluZwogKgogKiBSZXR1cm5zIHRoZSBzdHJpbmcgb3IgTlVMTCBpZiBub3QgcHJlc2VudC4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0UHJvcCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lKQp7CiAgICB4bWxDaGFyICp2YWw7CiAgICBjb25zdCB4bWxDaGFyICpyZXQ7CgogICAgdmFsID0geG1sR2V0UHJvcChub2RlLCBCQURfQ0FTVCBuYW1lKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4oTlVMTCk7CiAgICByZXQgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbCwgLTEpOwogICAgeG1sRnJlZSh2YWwpOwogICAgcmV0dXJuKHJldCk7Cn0KCiNpZiAwCi8qKgogKiB4bWxTY2hlbWFHZXROYW1lc3BhY2U6CiAqIEBjdHh0OiB0aGUgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogdGhlIHNjaGVtYXMgY29udGFpbmluZyB0aGUgZGVjbGFyYXRpb24KICogQG5vZGU6IHRoZSBub2RlCiAqIEBxbmFtZTogdGhlIFFOYW1lIHRvIGFuYWx5emUKICogCiAqIEZpbmQgdGhlIG5hbWVzcGFjZSBuYW1lIGZvciB0aGUgZ2l2ZW4gZGVjbGFyYXRpb24uCiAqCiAqIFJldHVybnMgdGhlIGxvY2FsIG5hbWUgZm9yIHRoYXQgZGVjbGFyYXRpb24sIGFzIHdlbGwgYXMgdGhlIG5hbWVzcGFjZSBuYW1lCiAqIE5PVEU6IFRoaXMgZnVuY3Rpb24gaXMgbm8gbG9uZ2VyIHVzZWQgKEJ1Y2hjaWssIE1heSAnMDQpIAogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXROYW1lc3BhY2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIGNvbnN0IHhtbENoYXIgKnFuYW1lLAoJICAgICBjb25zdCB4bWxDaGFyICoqbmFtZXNwYWNlKSB7CiAgICBpbnQgbGVuOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZSwgKnByZWZpeCwgKmRlZiA9IE5VTEw7CiAgICB4bWxOc1B0ciBuczsKCiAgICAqbmFtZXNwYWNlID0gTlVMTDsKICAgIAogICAgLyogVE9ETzogVGhlIGZvbGxvd2luZyBzZWVtcyB0byBiZSBub3QgY29ycmVjdCBoZXJlOgogICAgICogMS4gVGhlIG5hbWUgb2YgYSBkZWNsYXJhdGlvbiBpcyBhIE5DTmFtZSwgbm90IGEgUU5hbWUuCiAgICAgKiAyLiBUaGUgYXR0cmlidXRlICJ0YXJnZXROYW1lc3BhY2UiIGlzIGFsbG93ZWQgZm9yIHRoZQogICAgICogICAgPHNjaGVtYT4gRWxlbWVudCBJbmZvcm1hdGlvbiBJdGVtIG9ubHkuCiAgICAgKiAzLiBPbmUgY2Fubm90IGV2YWx1YXRlIHRoZSB0YXJnZXQgbmFtZXNwYWNlLCBieSB0aGUgdHlwZQogICAgICogICAgb2YgZGVjbGFyYXRpb24sIHNpbmNlIGl0IGlzIGRlcGVuZGFudCBvbiB0aGUgeHh4Rm9ybURlZmF1bHQKICAgICAqICAgIG9mIDxzY2hlbWE+IGFuZCB0aGUgZm9ybSBhdHRyaWJ1dGUgb2YgYW4gPGVsZW1lbnQ+IG9yIDxhdHRyaWJ1dGU+LgogICAgICovCiAgIAogICAgaWYgKHhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIEJBRF9DQVNUICJlbGVtZW50IikgfHwKICAgICAgICB4bWxTdHJFcXVhbChub2RlLT5uYW1lLCBCQURfQ0FTVCAiYXR0cmlidXRlIikgfHwKCXhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIEJBRF9DQVNUICJzaW1wbGVUeXBlIikgfHwKCXhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIEJBRF9DQVNUICJjb21wbGV4VHlwZSIpKSB7CglkZWYgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJ0YXJnZXROYW1lc3BhY2UiKTsKICAgIH0KCgogICAgcW5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHFuYW1lLCAtMSk7IC8qIGludGVybiB0aGUgc3RyaW5nICovCiAgICBuYW1lID0geG1sU3BsaXRRTmFtZTMocW5hbWUsICZsZW4pOwogICAgaWYgKG5hbWUgPT0gTlVMTCkgewogICAgICAgIGlmIChkZWYgPT0gTlVMTCkgewoJICAgIGlmICh4bWxTdHJFcXVhbChub2RlLT5uYW1lLCBCQURfQ0FTVCAiZWxlbWVudCIpKSB7CgkJaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkKCQkgICAgKm5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgQkFEX0NBU1QgImF0dHJpYnV0ZSIpKSB7CgkJaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfQVRUUikKCQkgICAgKm5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJICAgIH0gZWxzZSBpZiAoKHhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIEJBRF9DQVNUICJzaW1wbGVUeXBlIikpIHx8CgkgICAgICAgICAgICAgICAoeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgQkFEX0NBU1QgImNvbXBsZXhUeXBlIikpKSB7CgkJKm5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJICAgIH0KCX0gZWxzZSB7CgkgICAgKm5hbWVzcGFjZSA9IGRlZjsKCX0KCXJldHVybihxbmFtZSk7CiAgICB9CgogICAgbmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgcHJlZml4ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBxbmFtZSwgbGVuKTsKICAgIGlmIChkZWYgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVBfREVGX0FORF9QUkVGSVgsCiAgICAgICAgICAgICAgICAgICAgICAiJXM6IHByZXNlbmNlIG9mIGJvdGggcHJlZml4ICVzIGFuZCB0YXJnZXROYW1lc3BhY2VcbiIsCiAgICAgICAgICAgICAgICAgICAgICBub2RlLT5uYW1lLCBwcmVmaXgpOwogICAgfQogICAgbnMgPSB4bWxTZWFyY2hOcyhub2RlLT5kb2MsIG5vZGUsIHByZWZpeCk7CiAgICBpZiAobnMgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVBfUFJFRklYX1VOREVGSU5FRCwKICAgICAgICAgICAgICAgICAgICAgICIlczogdGhlIFFOYW1lIHByZWZpeCAlcyBpcyB1bmRlZmluZWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICBub2RlLT5uYW1lLCBwcmVmaXgpOwoJcmV0dXJuKG5hbWUpOwogICAgfQogICAgKm5hbWVzcGFjZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbnMtPmhyZWYsIC0xKTsKICAgIHJldHVybihuYW1lKTsKfQojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlQYXJzaW5nIGZ1bmN0aW9ucwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFHZXRFbGVtOgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYXMgY29udGV4dAogKiBAbmFtZTogIHRoZSBlbGVtZW50IG5hbWUKICogQG5zOiAgdGhlIGVsZW1lbnQgbmFtZXNwYWNlCiAqIEBsZXZlbDogaG93IGRlZXAgaXMgdGhlIHJlcXVlc3QKICoKICogTG9va3VwIGEgYW4gZWxlbWVudCBpbiB0aGUgc2NoZW1hcyBvciB0aGUgYWNjZXNzaWJsZSBzY2hlbWFzCiAqCiAqIFJldHVybnMgdGhlIGVsZW1lbnQgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFFbGVtZW50UHRyCnhtbFNjaGVtYUdldEVsZW0oeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSwgaW50IGxldmVsKQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHJldDsKICAgIHhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQgPSBOVUxMOwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAKICAgIAogICAgICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+ZWxlbURlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICAgICAgaWYgKChyZXQgIT0gTlVMTCkgJiYKCSgobGV2ZWwgPT0gMCkgfHwgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkpKSB7CiAgICAgICAgICAgIHJldHVybiAocmV0KTsKICAgIH0gZWxzZQoJcmV0ID0gTlVMTDsKICAgIC8qCiAgICAgKiBUaGlzIG9uZSB3YXMgcmVtb3ZlZCwgc2luY2UgdG9wIGxldmVsIGVsZW1lbnQgZGVjbGFyYXRpb25zIGhhdmUKICAgICAqIHRoZSB0YXJnZXQgbmFtZXNwYWNlIHNwZWNpZmllZCBpbiB0YXJnZXROYW1lc3BhY2Ugb2YgdGhlIDxzY2hlbWE+CiAgICAgKiBpbmZvcm1hdGlvbiBlbGVtZW50LCBldmVuIGlmIGVsZW1lbnRGb3JtRGVmYXVsdCBpcyAidW5xdWFsaWZpZWQiLgogICAgICovCiAgICAKICAgIC8qIGVsc2UgaWYgKChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0VMRU0pID09IDApIHsKICAgICAgICBpZiAoeG1sU3RyRXF1YWwobmFtZXNwYWNlLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSkpCgkgICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwgTlVMTCk7CgllbHNlCgkgICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKICAgICAgICBpZiAoKHJldCAhPSBOVUxMKSAmJgoJICAgICgobGV2ZWwgPT0gMCkgfHwgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX1RPUExFVkVMKSkpIHsKICAgICAgICAgICAgcmV0dXJuIChyZXQpOwoJfQogICAgKi8KICAgIAogICAgLyogaWYgKGxldmVsID4gMCkgKi8KICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfREVGQVVMVF9OQU1FU1BBQ0UpOwogICAgZWxzZQogICAgaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBuYW1lc3BhY2UpOwogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRFbGVtKGltcG9ydC0+c2NoZW1hLCBuYW1lLCBuYW1lc3BhY2UsIGxldmVsICsgMSk7CglpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKSkgewoJICAgIHJldHVybiAocmV0KTsKCX0gZWxzZQoJICAgIHJldCA9IE5VTEw7CiAgICB9CiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgdHlwZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIHR5cGUgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0VHlwZToKICogQHNjaGVtYTogIHRoZSBzY2hlbWFzIGNvbnRleHQKICogQG5hbWU6ICB0aGUgdHlwZSBuYW1lCiAqIEBuczogIHRoZSB0eXBlIG5hbWVzcGFjZQogKgogKiBMb29rdXAgYSB0eXBlIGluIHRoZSBzY2hlbWFzIG9yIHRoZSBwcmVkZWZpbmVkIHR5cGVzCiAqCiAqIFJldHVybnMgdGhlIGdyb3VwIGRlZmluaXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRUeXBlKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgcmV0OwogICAgeG1sU2NoZW1hSW1wb3J0UHRyIGltcG9ydDsKCiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKICAgICAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPnR5cGVEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgICAgIGlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKQogICAgICAgICAgICByZXR1cm4gKHJldCk7CiAgICB9CiAgICByZXQgPSB4bWxTY2hlbWFHZXRQcmVkZWZpbmVkVHlwZShuYW1lLCBuYW1lc3BhY2UpOwogICAgaWYgKHJldCAhPSBOVUxMKQoJcmV0dXJuIChyZXQpOwogICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBYTUxfU0NIRU1BU19ERUZBVUxUX05BTUVTUEFDRSk7CiAgICBlbHNlCiAgICBpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUdldFR5cGUoaW1wb3J0LT5zY2hlbWEsIG5hbWUsIG5hbWVzcGFjZSk7CglpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkgewoJICAgIHJldHVybiAocmV0KTsKCX0gZWxzZQoJICAgIHJldCA9IE5VTEw7CiAgICB9CiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgdHlwZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIHR5cGUgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0QXR0cmlidXRlOgogKiBAc2NoZW1hOiAgdGhlIGNvbnRleHQgb2YgdGhlIHNjaGVtYSAKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBuczogIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBhdHRyaWJ1dGUgCiAqCiAqIExvb2t1cCBhIGFuIGF0dHJpYnV0ZSBpbiB0aGUgc2NoZW1hIG9yIGltcG9ydGVkIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHJldDsKICAgIHhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQgPSBOVUxMOwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAKICAgIAogICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5hdHRyRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKICAgIGlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9HTE9CQUwpKQoJcmV0dXJuIChyZXQpOyAKICAgIGVsc2UKCXJldCA9IE5VTEw7CiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX0RFRkFVTFRfTkFNRVNQQUNFKTsKICAgIGVsc2UKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsJCiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZShpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9HTE9CQUwpKSB7CgkgICAgcmV0dXJuIChyZXQpOwoJfSBlbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBhdHRyaWJ1dGUgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBhdHRyaWJ1dGUgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0QXR0cmlidXRlR3JvdXA6CiAqIEBzY2hlbWE6ICB0aGUgY29udGV4dCBvZiB0aGUgc2NoZW1hIAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgZ3JvdXAKICogQG5zOiAgdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGF0dHJpYnV0ZSBncm91cCAKICoKICogTG9va3VwIGEgYW4gYXR0cmlidXRlIGdyb3VwIGluIHRoZSBzY2hlbWEgb3IgaW1wb3J0ZWQgc2NoZW1hcwogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZXQ7CiAgICB4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0ID0gTlVMTDsKCiAgICBpZiAoKG5hbWUgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgCiAgICAKICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+YXR0cmdycERlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICBpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9HTE9CQUwpKQoJcmV0dXJuIChyZXQpOyAgCiAgICBlbHNlCglyZXQgPSBOVUxMOwogICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBYTUxfU0NIRU1BU19ERUZBVUxUX05BTUVTUEFDRSk7CiAgICBlbHNlCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CQogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cChpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX0dMT0JBTCkpCgkgICAgcmV0dXJuIChyZXQpOwoJZWxzZQoJICAgIHJldCA9IE5VTEw7CiAgICB9CiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlIGdyb3VwICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlIGdyb3VwICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEdyb3VwOgogKiBAc2NoZW1hOiAgdGhlIGNvbnRleHQgb2YgdGhlIHNjaGVtYSAKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgZ3JvdXAKICogQG5zOiAgdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGdyb3VwIAogKgogKiBMb29rdXAgYSBncm91cCBpbiB0aGUgc2NoZW1hIG9yIGltcG9ydGVkIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldEdyb3VwKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgcmV0OwogICAgeG1sU2NoZW1hSW1wb3J0UHRyIGltcG9ydCA9IE5VTEw7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIAogICAgCiAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmdyb3VwRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKICAgIGlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKQoJcmV0dXJuIChyZXQpOyAgCiAgICBlbHNlCglyZXQgPSBOVUxMOwogICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBYTUxfU0NIRU1BU19ERUZBVUxUX05BTUVTUEFDRSk7CiAgICBlbHNlCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CQogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRHcm91cChpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKQoJICAgIHJldHVybiAocmV0KTsKCWVsc2UKCSAgICByZXQgPSBOVUxMOwogICAgfQojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGdyb3VwICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgZ3JvdXAgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJUGFyc2luZyBmdW5jdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIElTX0JMQU5LX05PREUobikJCQkJCQlcCiAgICAoKChuKS0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSAmJiAoeG1sU2NoZW1hSXNCbGFuaygobiktPmNvbnRlbnQpKSkKCi8qKgogKiB4bWxTY2hlbWFJc0JsYW5rOgogKiBAc3RyOiAgYSBzdHJpbmcKICoKICogQ2hlY2sgaWYgYSBzdHJpbmcgaXMgaWdub3JhYmxlCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgc3RyaW5nIGlzIE5VTEwgb3IgbWFkZSBvZiBibGFua3MgY2hhcnMsIDAgb3RoZXJ3aXNlCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlzQmxhbmsoeG1sQ2hhciAqIHN0cikKewogICAgaWYgKHN0ciA9PSBOVUxMKQogICAgICAgIHJldHVybiAoMSk7CiAgICB3aGlsZSAoKnN0ciAhPSAwKSB7CiAgICAgICAgaWYgKCEoSVNfQkxBTktfQ0goKnN0cikpKQogICAgICAgICAgICByZXR1cm4gKDApOwogICAgICAgIHN0cisrOwogICAgfQogICAgcmV0dXJuICgxKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZE5vdGF0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgQXR0cnJpYnV0ZSBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFOb3RhdGlvblB0cgp4bWxTY2hlbWFBZGROb3RhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICB4bWxTY2hlbWFOb3RhdGlvblB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmIChzY2hlbWEtPm5vdGFEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5ub3RhRGVjbCA9IHhtbEhhc2hDcmVhdGUoMTApOwogICAgaWYgKHNjaGVtYS0+bm90YURlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFOb3RhdGlvblB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFOb3RhdGlvbikpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWRkIGFubm90YXRpb24iLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYU5vdGF0aW9uKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTIoc2NoZW1hLT5ub3RhRGVjbCwgbmFtZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGN0eHQtPmRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9SRURFRklORURfTk9UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAiTm90YXRpb24gJXMgYWxyZWFkeSBkZWZpbmVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgbmFtZSwgTlVMTCk7CiAgICAgICAgeG1sRnJlZShyZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCgovKioKICogeG1sU2NoZW1hQWRkQXR0cmlidXRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgQXR0cnJpYnV0ZSBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIKeG1sU2NoZW1hQWRkQXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiNpZmRlZiBERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJBZGRpbmcgYXR0cmlidXRlICVzXG4iLCBuYW1lKTsKICAgIGlmIChuYW1lc3BhY2UgIT0gTlVMTCkKCWZwcmludGYoc3RkZXJyLCAiICB0YXJnZXQgbmFtZXNwYWNlICVzXG4iLCBuYW1lc3BhY2UpOwojZW5kaWYKCiAgICBpZiAoc2NoZW1hLT5hdHRyRGVjbCA9PSBOVUxMKQogICAgICAgIHNjaGVtYS0+YXR0ckRlY2wgPSB4bWxIYXNoQ3JlYXRlKDEwKTsKICAgIGlmIChzY2hlbWEtPmF0dHJEZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhdHRyaWJ1dGUiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZSkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZXNwYWNlLCAtMSk7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkzKHNjaGVtYS0+YXR0ckRlY2wsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCBjdHh0LT5jb250YWluZXIsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGN0eHQtPmRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9SRURFRklORURfQVRUUiwKICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGUgJXMgYWxyZWFkeSBkZWZpbmVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgbmFtZSwgTlVMTCk7CiAgICAgICAgeG1sRnJlZShyZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgaXRlbSBuYW1lCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIEF0dHJyaWJ1dGUgR3JvdXAgZGVjbGFyYXRpb24KICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYUFkZEF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKHNjaGVtYS0+YXR0cmdycERlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmF0dHJncnBEZWNsID0geG1sSGFzaENyZWF0ZSgxMCk7CiAgICBpZiAoc2NoZW1hLT5hdHRyZ3JwRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0KICAgICAgICAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpCiAgICAgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhdHRyaWJ1dGUgZ3JvdXAiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5hdHRyZ3JwRGVjbCwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsIGN0eHQtPmNvbnRhaW5lciwgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX1JFREVGSU5FRF9BVFRSR1JPVVAsCiAgICAgICAgICAgICAgICAgICAgICAiQXR0cmlidXRlIGdyb3VwICVzIGFscmVhZHkgZGVmaW5lZFxuIiwKICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIE5VTEwpOwogICAgICAgIHhtbEZyZWUocmV0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkRWxlbWVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgdHlwZSBuYW1lCiAqIEBuYW1lc3BhY2U6ICB0aGUgdHlwZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgRWxlbWVudCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFFbGVtZW50UHRyCnhtbFNjaGVtYUFkZEVsZW1lbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgojaWZkZWYgREVCVUcKICAgIGZwcmludGYoc3RkZXJyLCAiQWRkaW5nIGVsZW1lbnQgJXNcbiIsIG5hbWUpOwogICAgaWYgKG5hbWVzcGFjZSAhPSBOVUxMKQoJZnByaW50ZihzdGRlcnIsICIgIHRhcmdldCBuYW1lc3BhY2UgJXNcbiIsIG5hbWVzcGFjZSk7CiNlbmRpZgoKICAgIGlmIChzY2hlbWEtPmVsZW1EZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5lbGVtRGVjbCA9IHhtbEhhc2hDcmVhdGUoMTApOwogICAgaWYgKHNjaGVtYS0+ZWxlbURlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUVsZW1lbnQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgZWxlbWVudCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hRWxlbWVudCkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZXNwYWNlLCAtMSk7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkzKHNjaGVtYS0+ZWxlbURlY2wsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSwgY3R4dC0+Y29udGFpbmVyLCByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7CiAgICAgICAgY2hhciBidWZbMTAwXTsKCiAgICAgICAgc25wcmludGYoYnVmLCA5OSwgInByaXZhdGllZWxlbSAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwgKHhtbENoYXIgKikgYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlLCByZXQpOwogICAgICAgIGlmICh2YWwgIT0gMCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGN0eHQtPmRvYywKCQkJICBYTUxfU0NIRU1BUF9SRURFRklORURfRUxFTUVOVCwKCQkJICAiRWxlbWVudCAlcyBhbHJlYWR5IGRlZmluZWRcbiIsCgkJCSAgbmFtZSwgTlVMTCk7CiAgICAgICAgICAgIHhtbEZyZWUocmV0KTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgU2ltcGxlIFR5cGUgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUFkZFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgojaWZkZWYgREVCVUcKICAgIGZwcmludGYoc3RkZXJyLCAiQWRkaW5nIHR5cGUgJXNcbiIsIG5hbWUpOwogICAgaWYgKG5hbWVzcGFjZSAhPSBOVUxMKQoJZnByaW50ZihzdGRlcnIsICIgIHRhcmdldCBuYW1lc3BhY2UgJXNcbiIsIG5hbWVzcGFjZSk7CiNlbmRpZgoKICAgIGlmIChzY2hlbWEtPnR5cGVEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT50eXBlRGVjbCA9IHhtbEhhc2hDcmVhdGUoMTApOwogICAgaWYgKHNjaGVtYS0+dHlwZURlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFUeXBlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgdHlwZSIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVHlwZSkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICByZXQtPnJlZGVmID0gTlVMTDsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTIoc2NoZW1hLT50eXBlRGVjbCwgbmFtZSwgbmFtZXNwYWNlLCByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7CiAgICAgICAgaWYgKGN0eHQtPmluY2x1ZGVzID09IDApIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBjdHh0LT5kb2MsCgkJCSAgWE1MX1NDSEVNQVBfUkVERUZJTkVEX1RZUEUsCgkJCSAgIlR5cGUgJXMgYWxyZWFkeSBkZWZpbmVkXG4iLAoJCQkgIG5hbWUsIE5VTEwpOwoJICAgIHhtbEZyZWUocmV0KTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFUeXBlUHRyIHByZXY7CgoJICAgIHByZXYgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPnR5cGVEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwoJICAgIGlmIChwcmV2ID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBjdHh0LT5kb2MsCgkJCSAgICAgIFhNTF9FUlJfSU5URVJOQUxfRVJST1IsCgkJCSAgICAgICJJbnRlcm5hbCBlcnJvciBvbiB0eXBlICVzIGRlZmluaXRpb25cbiIsCgkJCSAgICAgIG5hbWUsIE5VTEwpOwoJCXhtbEZyZWUocmV0KTsKCQlyZXR1cm4gKE5VTEwpOwoJICAgIH0KCSAgICByZXQtPnJlZGVmID0gcHJldi0+cmVkZWY7CgkgICAgcHJldi0+cmVkZWYgPSByZXQ7Cgl9CiAgICB9CiAgICByZXQtPm1pbk9jY3VycyA9IDE7CiAgICByZXQtPm1heE9jY3VycyA9IDE7CiAgICByZXQtPmF0dHJpYnV0ZVVzZXMgPSBOVUxMOwogICAgcmV0LT5hdHRyaWJ1dGVXaWxkY2FyZCA9IE5VTEw7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGdyb3VwIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgR3JvdXAgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFBZGRHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKHNjaGVtYS0+Z3JvdXBEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5ncm91cERlY2wgPSB4bWxIYXNoQ3JlYXRlKDEwKTsKICAgIGlmIChzY2hlbWEtPmdyb3VwRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVR5cGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVHlwZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWRkaW5nIGdyb3VwIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFUeXBlKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHZhbCA9CiAgICAgICAgeG1sSGFzaEFkZEVudHJ5MihzY2hlbWEtPmdyb3VwRGVjbCwgbmFtZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBjdHh0LT5kb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfUkVERUZJTkVEX0dST1VQLAogICAgICAgICAgICAgICAgICAgICAgIkdyb3VwICVzIGFscmVhZHkgZGVmaW5lZFxuIiwKICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIE5VTEwpOwogICAgICAgIHhtbEZyZWUocmV0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0LT5taW5PY2N1cnMgPSAxOwogICAgcmV0LT5tYXhPY2N1cnMgPSAxOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld1dpbGRjYXJkTnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIENyZWF0ZXMgYSBuZXcgd2lsZGNhcmQgbmFtZXNwYWNlIGNvbnN0cmFpbnQuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyCnhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIpIAoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFXaWxkY2FyZE5zKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImNyZWF0aW5nIHdpbGRjYXJkIG5hbWVzcGFjZSBjb25zdHJhaW50IiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOyAgICAKICAgIH0KICAgIHJldC0+dmFsdWUgPSBOVUxMOwogICAgcmV0LT5uZXh0ID0gTlVMTDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZFdpbGRjYXJkOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBncm91cCBuYW1lCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIEdyb3VwIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVdpbGRjYXJkUHRyCnhtbFNjaGVtYUFkZFdpbGRjYXJkKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgcmV0ID0gTlVMTDsKCiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVdpbGRjYXJkKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhZGRpbmcgd2lsZGNhcmQiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVdpbGRjYXJkKSk7CiAgICByZXQtPm1pbk9jY3VycyA9IDE7CiAgICByZXQtPm1heE9jY3VycyA9IDE7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICoJCVV0aWxpdGllcyBmb3IgcGFyc2luZwkJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sR2V0UU5hbWVQcm9wOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqIEBuYW1lOiAgdGhlIGF0dHJpYnV0ZSBuYW1lCiAqIEBuYW1lc3BhY2U6ICB0aGUgcmVzdWx0IG5hbWVzcGFjZSBpZiBhbnkKICoKICogRXh0cmFjdCBhIFFOYW1lIEF0dHJpYnV0ZSB2YWx1ZQogKgogKiBSZXR1cm5zIHRoZSBOQ05hbWUgb3IgTlVMTCBpZiBub3QgZm91bmQsIGFuZCBhbHNvIHVwZGF0ZSBAbmFtZXNwYWNlCiAqICAgIHdpdGggdGhlIG5hbWVzcGFjZSBVUkkKICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sR2V0UU5hbWVQcm9wKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAogICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSwgY29uc3QgeG1sQ2hhciAqKiBuYW1lc3BhY2UpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbDsKICAgIHhtbE5zUHRyIG5zOwogICAgY29uc3QgeG1sQ2hhciAqcmV0LCAqcHJlZml4OwogICAgaW50IGxlbjsKCiAgICAqbmFtZXNwYWNlID0gTlVMTDsKICAgIHZhbCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgbmFtZSk7CiAgICBpZiAodmFsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBpZiAoIXN0cmNocigoY2hhciAqKSB2YWwsICc6JykpIHsKCW5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCAwKTsKCWlmIChucykgewoJICAgICpuYW1lc3BhY2UgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5zLT5ocmVmLCAtMSk7CgkgICAgcmV0dXJuICh2YWwpOwoJfQogICAgfQogICAgcmV0ID0geG1sU3BsaXRRTmFtZTModmFsLCAmbGVuKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAodmFsKTsKICAgIH0KICAgIHJldCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgcmV0LCAtMSk7CiAgICBwcmVmaXggPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbCwgbGVuKTsKCiAgICBucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgcHJlZml4KTsKICAgIGlmIChucyA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9QUkVGSVhfVU5ERUZJTkVELAogICAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZSAlczogdGhlIFFOYW1lIHByZWZpeCAlcyBpcyB1bmRlZmluZWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgeG1sQ2hhciAqKSBuYW1lLCBwcmVmaXgpOwogICAgfSBlbHNlIHsKICAgICAgICAqbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sR2V0TWF4T2NjdXJzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIEdldCB0aGUgbWF4T2NjdXJzIHByb3BlcnR5CiAqCiAqIFJldHVybnMgdGhlIGRlZmF1bHQgaWYgbm90IGZvdW5kLCBvciB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQKeG1sR2V0TWF4T2NjdXJzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWwsICpjdXI7CiAgICBpbnQgcmV0ID0gMDsKCiAgICB2YWwgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJtYXhPY2N1cnMiKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKDEpOwoKICAgIGlmICh4bWxTdHJFcXVhbCh2YWwsIChjb25zdCB4bWxDaGFyICopICJ1bmJvdW5kZWQiKSkgewogICAgICAgIHJldHVybiAoVU5CT1VOREVEKTsgIC8qIGVuY29kaW5nIGl0IHdpdGggLTEgbWlnaHQgYmUgYW5vdGhlciBvcHRpb24gKi8KICAgIH0KCiAgICBjdXIgPSB2YWw7CiAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgY3VyKys7CiAgICB3aGlsZSAoKCpjdXIgPj0gJzAnKSAmJiAoKmN1ciA8PSAnOScpKSB7CiAgICAgICAgcmV0ID0gcmV0ICogMTAgKyAoKmN1ciAtICcwJyk7CiAgICAgICAgY3VyKys7CiAgICB9CiAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgY3VyKys7CiAgICBpZiAoKmN1ciAhPSAwKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9JTlZBTElEX01BWE9DQ1VSUywKICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIHZhbHVlIGZvciBtYXhPY2N1cnM6ICVzXG4iLCB2YWwsIE5VTEwpOwogICAgICAgIHJldHVybiAoMSk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxHZXRNaW5PY2N1cnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogR2V0IHRoZSBtaW5PY2N1cnMgcHJvcGVydHkKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIG9yIHRoZSB2YWx1ZQogKi8Kc3RhdGljIGludAp4bWxHZXRNaW5PY2N1cnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbCwgKmN1cjsKICAgIGludCByZXQgPSAwOwoKICAgIHZhbCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm1pbk9jY3VycyIpOwogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoMSk7CgogICAgY3VyID0gdmFsOwogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgd2hpbGUgKCgqY3VyID49ICcwJykgJiYgKCpjdXIgPD0gJzknKSkgewogICAgICAgIHJldCA9IHJldCAqIDEwICsgKCpjdXIgLSAnMCcpOwogICAgICAgIGN1cisrOwogICAgfQogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgaWYgKCpjdXIgIT0gMCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsCiAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCB2YWx1ZSBmb3IgbWluT2NjdXJzOiAlc1xuIiwgdmFsLCBOVUxMKTsKICAgICAgICByZXR1cm4gKDEpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sR2V0Qm9vbGVhblByb3A6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICogQGRlZjogIHRoZSBkZWZhdWx0IHZhbHVlCiAqCiAqIEdldCBpcyBhIGJvbGVhbiBwcm9wZXJ0eSBpcyBzZXQKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIDAgaWYgZm91bmQgdG8gYmUgZmFsc2UsCiAqICAgICAgICAgMSBpZiBmb3VuZCB0byBiZSB0cnVlCiAqLwpzdGF0aWMgaW50CnhtbEdldEJvb2xlYW5Qcm9wKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAogICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lLCBpbnQgZGVmKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CgogICAgdmFsID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCBuYW1lKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKGRlZik7CgogICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInRydWUiKSkKICAgICAgICBkZWYgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiZmFsc2UiKSkKICAgICAgICBkZWYgPSAwOwogICAgZWxzZSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9JTlZBTElEX0JPT0xFQU4sCiAgICAgICAgICAgICAgICAgICAgICAiQXR0cmlidXRlICVzOiB0aGUgdmFsdWUgJXMgaXMgbm90IGJvb2xlYW5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgeG1sQ2hhciAqKSBuYW1lLCB2YWwpOwogICAgfQogICAgcmV0dXJuIChkZWYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICoJCVNoZW1hIGV4dHJhY3Rpb24gZnJvbSBhbiBJbmZvc2V0CQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkJCQkgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgCgkJCQkJCSAgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2ltcGxlKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VTZXF1ZW5jZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZUFsbCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCQkJCSAgICAgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgICBpbnQgdG9wTGV2ZWwpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZUNob2ljZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlTGlzdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIHhtbFNjaGVtYVdpbGRjYXJkUHRyCnhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlKTsKCi8qKgogKiB4bWxTY2hlbWFQYXJzZUF0dHJEZWNsczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKiBAdHlwZTogIHRoZSBob3N0aW5nIHR5cGUKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIGF0dHJEZWNscyBkZWNsYXJhdGlvbiBjb3JyZXNwb25kaW5nIHRvCiAqIDwhRU5USVRZICUgYXR0ckRlY2xzICAKICogICAgICAgJygoJWF0dHJpYnV0ZTt8ICVhdHRyaWJ1dGVHcm91cDspKiwoJWFueUF0dHJpYnV0ZTspPyknPgogKi8Kc3RhdGljIHhtbE5vZGVQdHIKeG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIGNoaWxkLCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBsYXN0YXR0ciwgYXR0cjsKCiAgICBsYXN0YXR0ciA9IE5VTEw7CiAgICB3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZSIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGVHcm91cCIpKSkgewogICAgICAgIGF0dHIgPSBOVUxMOwogICAgICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGUiKSkgewogICAgICAgICAgICBhdHRyID0geG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGVHcm91cCIpKSB7CiAgICAgICAgICAgIGF0dHIgPSAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICB9CiAgICAgICAgaWYgKGF0dHIgIT0gTlVMTCkgewogICAgICAgICAgICBpZiAobGFzdGF0dHIgPT0gTlVMTCkgewoJCWlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkKCQkgICAgKCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgdHlwZSktPmF0dHJpYnV0ZXMgPSBhdHRyOwoJCWVsc2UKICAgICAgICAgICAgICAgIHR5cGUtPmF0dHJpYnV0ZXMgPSBhdHRyOwogICAgICAgICAgICAgICAgbGFzdGF0dHIgPSBhdHRyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbGFzdGF0dHItPm5leHQgPSBhdHRyOwogICAgICAgICAgICAgICAgbGFzdGF0dHIgPSBhdHRyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55QXR0cmlidXRlIikpIHsKCXhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRjYXJkOwoKICAgICAgICB3aWxkY2FyZCA9IHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGlmICh3aWxkY2FyZCAhPSBOVUxMKSB7CgkgICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKQoJCSgoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIHR5cGUpLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHdpbGRjYXJkOwoJICAgIGVsc2UKCQl0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHdpbGRjYXJkOwogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgcmV0dXJuIChjaGlsZCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUFubm90YXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEF0dHJyaWJ1dGUgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYUFubm90UHRyCnhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYUFubm90UHRyIHJldDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgcmV0ID0geG1sU2NoZW1hTmV3QW5ub3QoY3R4dCwgbm9kZSk7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VGYWNldDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgRmFjZXQgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBuZXcgdHlwZSBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hRmFjZXRQdHIKeG1sU2NoZW1hUGFyc2VGYWNldCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqdmFsdWU7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBmYWNldCA9IHhtbFNjaGVtYU5ld0ZhY2V0KCk7CiAgICBpZiAoZmFjZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgZmFjZXQiLCBub2RlKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgZmFjZXQtPm5vZGUgPSBub2RlOwogICAgdmFsdWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJ2YWx1ZSIpOwogICAgaWYgKHZhbHVlID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfRkFDRVRfTk9fVkFMVUUsCiAgICAgICAgICAgICAgICAgICAgICAgIkZhY2V0ICVzIGhhcyBubyB2YWx1ZVxuIiwgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgeG1sU2NoZW1hRnJlZUZhY2V0KGZhY2V0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgaWYgKElTX1NDSEVNQShub2RlLCAibWluSW5jbHVzaXZlIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1pbkV4Y2x1c2l2ZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJtYXhJbmNsdXNpdmUiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibWF4RXhjbHVzaXZlIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgInRvdGFsRGlnaXRzIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAiZnJhY3Rpb25EaWdpdHMiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJwYXR0ZXJuIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJlbnVtZXJhdGlvbiIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIndoaXRlU3BhY2UiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgImxlbmd0aCIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJtYXhMZW5ndGgiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibWluTGVuZ3RoIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9GQUNFVF9UWVBFLAogICAgICAgICAgICAgICAgICAgICAgICJVbmtub3duIGZhY2V0IHR5cGUgJXNcbiIsIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHhtbFNjaGVtYUZyZWVGYWNldChmYWNldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGZhY2V0LT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICBmYWNldC0+dmFsdWUgPSB2YWx1ZTsKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CgogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIGZhY2V0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9GQUNFVF9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiRmFjZXQgJXMgaGFzIHVuZXhwZWN0ZWQgY2hpbGQgY29udGVudFxuIiwKICAgICAgICAgICAgICAgICAgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiAoZmFjZXQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBbnk6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEFueSBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyB0eXBlIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQW55KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiYW55ICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FOWTsKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICB0eXBlLT5taW5PY2N1cnMgPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSk7CiAgICB0eXBlLT5tYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSk7CgogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fU0VRVUVOQ0VfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgIlNlcXVlbmNlICVzIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsIHR5cGUtPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICB9CgogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlTm90YXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIE5vdGF0aW9uIGRlY2xhcmF0aW9uCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hTm90YXRpb25QdHIKeG1sU2NoZW1hUGFyc2VOb3RhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgeG1sU2NoZW1hTm90YXRpb25QdHIgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIG5hbWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lIik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX05PVEFUSU9OX05PX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgIk5vdGF0aW9uIGhhcyBubyBuYW1lXG4iLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0ID0geG1sU2NoZW1hQWRkTm90YXRpb24oY3R4dCwgc2NoZW1hLCBuYW1lKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHJldC0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9OT1RBVElPTl9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAibm90YXRpb24gJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgbmFtZSwgTlVMTCk7CiAgICB9CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBbnlBdHRyaWJ1dGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEFueUF0dHJyaWJ1dGUgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIGFuIGF0dHJpYnV0ZSBkZWYgc3RydWN0dXJlIG9yIE5VTEwKICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZFB0cgp4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgY29uc3QgeG1sQ2hhciAqcHJvY2Vzc0NvbnRlbnRzLCAqbnNDb25zdHJhaW50LCAqZW5kLCAqY3VyLCAqZGljdE1lbWJlcjsKICAgIHhtbENoYXIgKm1lbWJlcjsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHJldDsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgdG1wLCBsYXN0TnMgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSB4bWxTY2hlbWFBZGRXaWxkY2FyZChjdHh0KTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURTsKICAgIHJldC0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgcHJvY2Vzc0NvbnRlbnRzID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAicHJvY2Vzc0NvbnRlbnRzIik7CiAgICBpZiAoKHByb2Nlc3NDb250ZW50cyA9PSBOVUxMKQogICAgICAgIHx8ICh4bWxTdHJFcXVhbChwcm9jZXNzQ29udGVudHMsIChjb25zdCB4bWxDaGFyICopICJzdHJpY3QiKSkpIHsKICAgICAgICByZXQtPnByb2Nlc3NDb250ZW50cyA9IFhNTF9TQ0hFTUFTX0FOWUFUVFJfU1RSSUNUOwogICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChwcm9jZXNzQ29udGVudHMsIChjb25zdCB4bWxDaGFyICopICJza2lwIikpIHsKICAgICAgICByZXQtPnByb2Nlc3NDb250ZW50cyA9IFhNTF9TQ0hFTUFTX0FOWUFUVFJfU0tJUDsKICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwocHJvY2Vzc0NvbnRlbnRzLCAoY29uc3QgeG1sQ2hhciAqKSAibGF4IikpIHsKICAgICAgICByZXQtPnByb2Nlc3NDb250ZW50cyA9IFhNTF9TQ0hFTUFTX0FOWUFUVFJfTEFYOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIAogICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fUFJPQ0VTU0NPTlRFTlRfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgImFueUF0dHJpYnV0ZSBoYXMgdW5leHBlY3RlZCBjb250ZW50ICIKCQkgICAgICAgImZvciBwcm9jZXNzQ29udGVudHM6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NDb250ZW50cywgTlVMTCk7CiAgICAgICAgcmV0LT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllBVFRSX1NUUklDVDsKICAgIH0KICAgIC8qCiAgICAgKiBCdWlsZCB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzLgogICAgICovCiAgICBuc0NvbnN0cmFpbnQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lc3BhY2UiKTsKICAgIGlmICgobnNDb25zdHJhaW50ID09IE5VTEwpIHx8ICh4bWxTdHJFcXVhbChuc0NvbnN0cmFpbnQsIEJBRF9DQVNUICIjI2FueSIpKSkKCXJldC0+YW55ID0gMTsKICAgIGVsc2UgaWYgKHhtbFN0ckVxdWFsKG5zQ29uc3RyYWludCwgQkFEX0NBU1QgIiMjb3RoZXIiKSkgewoJcmV0LT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKHJldC0+bmVnTnNTZXQgPT0gTlVMTCkgewkgICAgCgkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkKHJldCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCXJldC0+bmVnTnNTZXQtPnZhbHVlID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7IAogICAgfSBlbHNlIHsgICAgCgljdXIgPSBuc0NvbnN0cmFpbnQ7CglkbyB7CgkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCWN1cisrOwoJICAgIGVuZCA9IGN1cjsKCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQllbmQrKzsKCSAgICBpZiAoZW5kID09IGN1cikKCQlicmVhazsKCSAgICBtZW1iZXIgPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsgICAgCSAgICAKCSAgICBpZiAoKHhtbFN0ckVxdWFsKG1lbWJlciwgQkFEX0NBU1QgIiMjb3RoZXIiKSkgfHwKCQkgICAgKHhtbFN0ckVxdWFsKG1lbWJlciwgQkFEX0NBU1QgIiMjYW55IikpKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCByZXQtPm5vZGUsIFhNTF9TQ0hFTUFQX1dJTERDQVJEX0lOVkFMSURfTlNfTUVNQkVSLAoJCSAgICAiVGhlIG5hbWVzcGFjZSBjb25zdHJhaW50IG9mIGFuIGFueUF0dHJpYnV0ZSAiCgkJICAgICJpcyBhIHNldCBhbmQgbXVzdCBub3QgY29udGFpbiBcIiVzXCJcbiIsCgkJICAgIG1lbWJlciwgTlVMTCk7CQkJICAgIAkJICAgIAoJICAgIH0gZWxzZSB7CQkKCQkvKgoJCSogVE9ETzogVmFsaWRhdGUgdGhlIHZhbHVlIChhbnlVUkkpLgoJCSovCQkKCQlpZiAoeG1sU3RyRXF1YWwobWVtYmVyLCBCQURfQ0FTVCAiIyN0YXJnZXROYW1lc3BhY2UiKSkgewoJCSAgICBkaWN0TWVtYmVyID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChtZW1iZXIsIEJBRF9DQVNUICIjI2xvY2FsIikpIHsKCQkgICAgZGljdE1lbWJlciA9IE5VTEw7CgkJfSBlbHNlCgkJICAgIGRpY3RNZW1iZXIgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG1lbWJlciwgLTEpOwoJCS8qCgkJKiBBdm9pZCBkdWJsaWNhdGUgbmFtZXNwYWNlcy4KCQkqLwoJCXRtcCA9IHJldC0+bnNTZXQ7CgkJd2hpbGUgKHRtcCAhPSBOVUxMKSB7CgkJICAgIGlmIChkaWN0TWVtYmVyID09IHRtcC0+dmFsdWUpCgkJCWJyZWFrOwoJCSAgICB0bXAgPSB0bXAtPm5leHQ7CgkJfQoJCWlmICh0bXAgPT0gTlVMTCkgewoJCSAgICB0bXAgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQkgICAgaWYgKHRtcCA9PSBOVUxMKSB7CgkJCXhtbEZyZWUobWVtYmVyKTsKCQkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkKHJldCk7CgkJCXJldHVybiAoTlVMTCk7CgkJICAgIH0KCQkgICAgdG1wLT52YWx1ZSA9IGRpY3RNZW1iZXI7CgkJICAgIHRtcC0+bmV4dCA9IE5VTEw7CgkJICAgIGlmIChyZXQtPm5zU2V0ID09IE5VTEwpIAoJCQlyZXQtPm5zU2V0ID0gdG1wOwoJCSAgICBlbHNlCgkJCWxhc3ROcy0+bmV4dCA9IHRtcDsKCQkgICAgbGFzdE5zID0gdG1wOwoJCX0KCgkgICAgfQkKCSAgICB4bWxGcmVlKG1lbWJlcik7CgkgICAgY3VyID0gZW5kOwoJfSB3aGlsZSAoKmN1ciAhPSAwKTsgICAgCiAgICB9CgogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICByZXQtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQU5ZQVRUUklCVVRFX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJhbnlBdHRyaWJ1dGUgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gKHJldCk7Cn0KCgovKioKICogeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEF0dHJyaWJ1dGUgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlUHRyCnhtbFNjaGVtYVBhcnNlQXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsICpyZWZOcyA9IE5VTEwsICpyZWYgPSBOVUxMLCAqYXR0clZhbDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNoYXIgYnVmWzEwMF07CiAgICBpbnQgaGFzUmVmVHlwZSA9IDA7CgogICAgLyoKICAgICAqIE5vdGUgdGhhdCB0aGUgdzNjIHNwZWMgYXNzdW1lcyB0aGUgc2NoZW1hIHRvIGJlIHZhbGlkYXRlZCB3aXRoIHNjaGVtYQogICAgICogZm9yIHNjaGVtYXMgYmVmb3JlaGFuZC4KICAgICAqCiAgICAgKiAzLjIuMyBDb25zdHJhaW50cyBvbiBYTUwgUmVwcmVzZW50YXRpb25zIG9mIEF0dHJpYnV0ZSBEZWNsYXJhdGlvbnMKICAgICAqCiAgICAgKiBUT0RPOiBDb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZjogCiAgICAgKiAzLjIuNiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IEF0dHJpYnV0ZSBEZWNsYXJhdGlvbiBQcm9wZXJ0aWVzCiAgICAgKiAgICAgICBDb3JyZWN0IAogICAgICovCgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIAogICAgbmFtZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm5hbWUiKTsKICAgIGlmIChuYW1lID09IE5VTEwpIHsKICAgICAgICByZWYgPSB4bWxHZXRRTmFtZVByb3AoY3R4dCwgbm9kZSwgInJlZiIsICZyZWZOcyk7CgkvKiAzLjIuMyA6IDMuMQoJICogT25lIG9mIHJlZiBvciBuYW1lIG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoIAoJICovCiAgICAgICAgaWYgKHJlZiA9PSBOVUxMKSB7CSAgICAKICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCAKCQkJICBYTUxfU0NIRU1BUF9BVFRSX05PTkFNRV9OT1JFRiwKCQkJICAiQXR0cmlidXRlIGRlY2xhcmF0aW9uIGhhcyBubyBcIm5hbWVcIiBvciBcInJlZlwiXG4iLAoJCQkgIE5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQoJaGFzUmVmVHlwZSA9IDE7CiAgICAgICAgc25wcmludGYoYnVmLCA5OSwgImFub25hdHRyICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICAgICAgbmFtZSA9IChjb25zdCB4bWxDaGFyICopIGJ1ZjsKCXJldCA9IHhtbFNjaGVtYUFkZEF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwpOwoJaWYgKCF0b3BMZXZlbCkgewoJICAgIC8qIDMuMi4zIDogMy4yCgkgICAgICogSWYgcmVmIGlzIHByZXNlbnQsIHRoZW4gYWxsIG9mIDxzaW1wbGVUeXBlPiwKCSAgICAgKiBmb3JtIGFuZCB0eXBlIG11c3QgYmUgYWJzZW50LiAKCSAgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZm9ybSIpICE9IE5VTEwpIHsJCQoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgCgkJICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0FUVFJfQ09NQklOQVRJT04sCgkJCSAgICAgICJBdHRyaWJ1dGUgZGVjbGFyYXRpb24gJXMgaGFzIFwicmVmXCIsIHRodXMgIgoJCQkgICAgICAiXCJmb3JtXCIgbXVzdCBiZSBhYnNlbnRcbiIsIG5hbWUsIE5VTEwpOwoJICAgIH0KCSAgICBpZiAoeG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAidHlwZSIpICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIAoJCSAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9BVFRSX0NPTUJJTkFUSU9OLAoJCQkgICAgICAiQXR0cmlidXRlIGRlY2xhcmF0aW9uICVzIGhhcyBcInJlZlwiLCB0aHVzICIKCQkJICAgICAgIlwidHlwZVwiIG11c3QgYmUgYWJzZW50XG4iLCBuYW1lLCBOVUxMKTsKCSAgICB9Cgl9CiAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IHhtbENoYXIgKm5zID0gTlVMTDsKCS8qIDMuMi4zIDogMy4xCgkgKiBPbmUgb2YgcmVmIG9yIG5hbWUgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGggCgkgKi8KCWlmICgoIXRvcExldmVsKSAmJiAoeG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAicmVmIikgIT0gTlVMTCkpIHsJICAgIAoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9BVFRSX0NPTUJJTkFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGUgZGVjbGFyYXRpb24gXCIlc1wiIGhhcyBib3RoLCBcIm5hbWVcIiBhbmQgIgoJCQkgICJcInJlZlwiXG4iLCBuYW1lLCBOVUxMKTsKCX0KCiAgICAgICAgLyogbG9jYWwgPSB4bWxTY2hlbWFHZXROYW1lc3BhY2UoY3R4dCwgc2NoZW1hLCBub2RlLCBuYW1lLCAmbnMpOyAqLwoJLyogRXZhbHVhdGUgdGhlIHRhcmdldCBuYW1lc3BhY2UgKi8KCWlmIChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKSB7CgkgICAgaWYgKHRvcExldmVsKSB7CgkJbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCSAgICB9IGVsc2UgaWYgKHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImZvcm0iKSAhPSBOVUxMKSB7CgkJaWYgKHhtbFN0ckVxdWFsKCB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmb3JtIiksCgkJCQkgQkFEX0NBU1QgInF1YWxpZmllZCIpKSB7CgkJICAgIG5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CgkJfQoJICAgIH0gZWxzZSBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSKSB7CgkJbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsJCQoJICAgIH0KCX0KCXJldCA9IHhtbFNjaGVtYUFkZEF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIG5hbWUsIG5zKTsKCWlmIChyZXQgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJLyogMy4yLjYgU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiB4bWxucyBOb3QgQWxsb3dlZCAqLwoJaWYgKHhtbFN0ckVxdWFsKG5hbWUsIEJBRF9DQVNUICJ4bWxucyIpKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCAKICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9OQU1FLAogICAgICAgICAgICAgICAgICAgICAgIlRoZSBuYW1lIG9mIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBtdXN0IG5vdCBtYXRjaCAiCgkJICAgICAgIlwieG1sbnNcIi5cbiIsIE5VTEwsIE5VTEwpOwoJfQkKCQoJLyogMy4yLjYgU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiB4c2k6IE5vdCBBbGxvd2VkICovCQoJaWYgKHhtbFN0ckVxdWFsKHJldC0+dGFyZ2V0TmFtZXNwYWNlLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9BVFRSX05BTUUsCgkgICAgICAgICAgICAgICAgICAiVGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uLCAiCgkJCSAgIm11c3Qgbm90IG1hdGNoIFwiaHR0cDovL3d3dy53My5vcmcvMjAwMS8iCgkJCSAgIlhNTFNjaGVtYS1pbnN0YW5jZVwiIiwgTlVMTCwgTlVMTCk7Cgl9CQogICAgfQogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU7CiAgICBpZiAodG9wTGV2ZWwpIAogICAgICAgIHJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUl9HTE9CQUw7CiAgICAKICAgIC8qIEhhbmRsZSB0aGUgInVzZSIgYXR0cmlidXRlLiAqLwogICAgYXR0clZhbCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInVzZSIpOwogICAgaWYgKGF0dHJWYWwgIT0gTlVMTCkgewoJaWYgKHhtbFN0ckVxdWFsKGF0dHJWYWwsIEJBRF9DQVNUICJvcHRpb25hbCIpKQoJICAgIHJldC0+b2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUw7CgllbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyVmFsLCBCQURfQ0FTVCAicHJvaGliaXRlZCIpKQoJICAgIHJldC0+b2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUFJPSElCSVRFRDsKCWVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHJWYWwsIEJBRF9DQVNUICJyZXF1aXJlZCIpKQoJICAgIHJldC0+b2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQ7CgllbHNlCgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLAoJCQkgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9VU0UsCgkJCSAgIkF0dHJpYnV0ZSBkZWNsYXJhdGlvbiAlcyBoYXMgYW4gaW52YWxpZCAiCgkJCSAgInZhbHVlIGZvciBcInVzZVwiXG4iLCBuYW1lLCBOVUxMKTsKICAgIH0gZWxzZQoJcmV0LT5vY2N1cnMgPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTDsKCiAgICAKICAgIGlmICh4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJkZWZhdWx0IikgIT0gTlVMTCkgewoJLyogMy4yLjMgOiAxCgkgKiBkZWZhdWx0IGFuZCBmaXhlZCBtdXN0IG5vdCBib3RoIGJlIHByZXNlbnQuIAoJICovCglpZiAoeG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZml4ZWQiKSAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0FUVFJfQ09NQklOQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBoYXMgYm90aCwgXCJkZWZhdWx0XCIgIgoJCQkgICJhbmQgXCJmaXhlZFwiXG4iLCBOVUxMLCBOVUxMKTsKCX0KCS8qIDMuMi4zIDogMgoJICogSWYgZGVmYXVsdCBhbmQgdXNlIGFyZSBib3RoIHByZXNlbnQsIHVzZSBtdXN0IGhhdmUKCSAqIHRoZSBhY3R1YWwgdmFsdWUgb3B0aW9uYWwuCgkgKi8KCWlmIChyZXQtPm9jY3VycyAhPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9BVFRSX0NPTUJJTkFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGUgZGVjbGFyYXRpb24gaGFzIFwiZGVmYXVsdFwiIGJ1dCAiCgkJCSAgIlwidXNlXCIgaXMgbm90IFwib3B0aW9uYWxcIlxuIiwgTlVMTCwgTlVMTCk7Cgl9CQogICAgfSAgICAKCiAgICByZXQtPnJlZiA9IHJlZjsKICAgIHJldC0+cmVmTnMgPSByZWZOczsKICAgIC8qIAogICAgICogVGhlIHNldHRpbmcgb2YgWE1MX1NDSEVNQVNfQVRUUl9OU0RFRkFVTFQgaXMgbm90IG5lZWRlZCBhbnltb3JlLAogICAgICogc2luY2UgdGhlIHRhcmdldCBuYW1lc3BhY2Ugd2FzIGFscmVhZHkgZXZhbHVhdGVkIGFuZCB0b29rCiAgICAgKiBhdHRyaWJ1dGVGb3JtRGVmYXVsdCBpbnRvIGFjY291bnQuCiAgICAgKi8KICAgIC8qCiAgICBpZiAoKHJldC0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpICYmCiAgICAgICAgKChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0FUVFIpID09IDApICYmCgkoeG1sU3RyRXF1YWwocmV0LT50YXJnZXROYW1lc3BhY2UsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKSkpCglyZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJfTlNERUZBVUxUOwogICAgKi8KICAgIHJldC0+dHlwZU5hbWUgPSB4bWxHZXRRTmFtZVByb3AoY3R4dCwgbm9kZSwgInR5cGUiLCAmKHJldC0+dHlwZU5zKSk7CiAgICBpZiAocmV0LT50eXBlTmFtZSAhPSBOVUxMKQoJaGFzUmVmVHlwZSA9IDE7CiAgICByZXQtPm5vZGUgPSBub2RlOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICByZXQtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CglpZiAoaGFzUmVmVHlwZSkgewoJICAgIC8qIDMuMi4zIDogNAoJICAgICAqIHR5cGUgYW5kIDxzaW1wbGVUeXBlPiBtdXN0IG5vdCBib3RoIGJlIHByZXNlbnQuIAoJICAgICAqCgkgICAgICogVE9ETzogWE1MX1NDSEVNQVBfSU5WQUxJRF9BVFRSX0NPTUJJTkFUSU9OIHNlZW1zIG5vdCB0byBiZQoJICAgICAqIGEgcHJvcGVyIGVycm9yIHR5cGUgaGVyZS4gCgkgICAgICovCgkgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIAoJICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9DT01CSU5BVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZSBkZWNsYXJhdGlvbiAlcyBoYXMgYm90aCAoXCJyZWZcIiBvciAiCgkJCSAgICJcInR5cGVcIikgYW5kIDxzaW1wbGVUeXBlPlxuIiwgbmFtZSwgTlVMTCk7Cgl9IGVsc2UKCSAgICByZXQtPnN1YnR5cGVzID0geG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0FUVFJfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgImF0dHJpYnV0ZSAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEF0dHJpYnV0ZSBHcm91cCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBncm91cCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIKeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlLAoJCQkgICAgIGludCB0b3BMZXZlbCkKewogICAgY29uc3QgeG1sQ2hhciAqbmFtZSwgKnJlZk5zID0gTlVMTCwgKnJlZiA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lcjsKICAgIGNoYXIgYnVmWzEwMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgIG5hbWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lIik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgcmVmID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJyZWYiLCAmcmVmTnMpOwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfQVRUUkdSUF9OT05BTUVfTk9SRUYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGVHcm91cCBoYXMgbm8gbmFtZSBub3IgcmVmXG4iLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICAgICAgc25wcmludGYoYnVmLCA5OSwgImFub25hdHRyZ3JvdXAgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgICAgICBuYW1lID0gKGNvbnN0IHhtbENoYXIgKikgYnVmOwogICAgICAgIGlmIChuYW1lID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJjcmVhdGluZyBhdHRyaWJ1dGUgZ3JvdXAiLCBub2RlKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICB9CiAgICByZXQgPSB4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cChjdHh0LCBzY2hlbWEsIG5hbWUpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+cmVmID0gcmVmOwogICAgcmV0LT5yZWZOcyA9IHJlZk5zOwogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOwogICAgaWYgKHRvcExldmVsKSAKICAgICAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9HTE9CQUw7CiAgICByZXQtPm5vZGUgPSBub2RlOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGN0eHQtPmNvbnRhaW5lciA9IG5hbWU7CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgY2hpbGQgPSB4bWxTY2hlbWFQYXJzZUF0dHJEZWNscyhjdHh0LCBzY2hlbWEsIGNoaWxkLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0KTsgCiAgICAvKiBTZWVtcyB0aGF0IHRoaXMgY2FuIGJlIHJlbW92ZWQuICovCiAgICAvKgogICAgd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGUiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkpIHsKICAgICAgICBhdHRyID0gTlVMTDsKICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlIikpIHsKICAgICAgICAgICAgYXR0ciA9IHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkgewogICAgICAgICAgICBhdHRyID0gKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfQogICAgICAgIGlmIChhdHRyICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKGxhc3QgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgcmV0LT5hdHRyaWJ1dGVzID0gYXR0cjsKICAgICAgICAgICAgICAgIGxhc3QgPSBhdHRyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbGFzdC0+bmV4dCA9IGF0dHI7CiAgICAgICAgICAgICAgICBsYXN0ID0gYXR0cjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CiAgICAgICAgVE9ETwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgICovCiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQVRUUkdSUF9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiYXR0cmlidXRlIGdyb3VwICVzIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICB9CiAgICBjdHh0LT5jb250YWluZXIgPSBvbGRjb250YWluZXI7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEVsZW1lbnQgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBwYXJzZWQgZWxlbWVudCBkZWNsYXJhdGlvbi4KICovCnN0YXRpYyB4bWxTY2hlbWFFbGVtZW50UHRyCnhtbFNjaGVtYVBhcnNlRWxlbWVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgY29uc3QgeG1sQ2hhciAqbmFtZSwgKmZpeGVkOwogICAgY29uc3QgeG1sQ2hhciAqcmVmTnMgPSBOVUxMLCAqcmVmID0gTlVMTDsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpvbGRjb250YWluZXI7CiAgICBjaGFyIGJ1ZlsxMDBdOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIC8qIDMuMy4zIENvbnN0cmFpbnRzIG9uIFhNTCBSZXByZXNlbnRhdGlvbnMgb2YgRWxlbWVudCBEZWNsYXJhdGlvbnMgKi8KICAgIC8qIFRPRE86IENvbXBsZXRlIGltcGxlbWVudGF0aW9uIG9mIDMuMy42ICovCgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgIG5hbWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lIik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgcmVmID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJyZWYiLCAmcmVmTnMpOwoJLyogMy4zLjMgOiAyLjEKCSAqIE9uZSBvZiByZWYgb3IgbmFtZSBtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aCAKCSAqLwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9FTEVNX05PTkFNRV9OT1JFRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVsZW1lbnQgZGVjbGFyYXRpb24gaGFzIG5vIG5hbWUgbm9yIHJlZlxuIiwgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQkKICAgICAgICAKICAgICAgICBzbnByaW50ZihidWYsIDk5LCAiYW5vbmVsZW0gJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgICAgICBuYW1lID0gKGNvbnN0IHhtbENoYXIgKikgYnVmOwoJcmV0ID0geG1sU2NoZW1hQWRkRWxlbWVudChjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwpOwogICAgfSBlbHNlIHsKCWNvbnN0IHhtbENoYXIgKm5zID0gTlVMTDsKCgkvKiBFdmFsdWF0ZSB0aGUgdGFyZ2V0IG5hbWVzcGFjZSAqLwoJaWYgKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsKCSAgICBpZiAodG9wTGV2ZWwpIHsKCQlucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJICAgIH0gZWxzZSBpZiAoeG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZm9ybSIpICE9IE5VTEwpIHsKCQlpZiAoeG1sU3RyRXF1YWwoIHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImZvcm0iKSwKCQkJCSBCQURfQ0FTVCAicXVhbGlmaWVkIikpIHsKCQkgICAgbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCQl9CgkgICAgfSBlbHNlIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0FUVFIpIHsKCQlucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJICAgIH0KCX0KCS8qbG9jYWwgPSB4bWxTY2hlbWFHZXROYW1lc3BhY2UoY3R4dCwgc2NoZW1hLCBub2RlLCBuYW1lLCAmbnMpOyAqLwoJcmV0ID0geG1sU2NoZW1hQWRkRWxlbWVudChjdHh0LCBzY2hlbWEsIG5hbWUsIG5zKTsKCS8qIDMuMy4zIDogMi4xCgkgKiBPbmUgb2YgcmVmIG9yIG5hbWUgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGggCgkgKi8KCWlmICgoIXRvcExldmVsKSAmJiAoeG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAicmVmIikgIT0gTlVMTCkpIHsJICAgIAoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9BVFRSX0NPTUJJTkFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICJFbGVtZW50IGRlY2xhcmF0aW9uIGhhcyBib3RoLCBcIm5hbWVcIiBhbmQgIgoJCQkgICJcInJlZlwiXG4iLCBOVUxMLCBOVUxMKTsKCX0KICAgIH0KICAgIGlmIChyZXQgIT0gTlVMTCkKCXJldC0+bm9kZSA9IG5vZGU7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ7CiAgICByZXQtPnJlZiA9IHJlZjsKICAgIHJldC0+cmVmTnMgPSByZWZOczsKICAgIGlmIChyZWYgIT0gTlVMTCkKICAgICAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fUkVGOwoKICAgIC8qIDMuMy4zIDogMi4yICovICAgICAKICAgIGlmICgoIXRvcExldmVsKSAmJiAocmVmICE9IE5VTEwpKSB7CglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoKGF0dHItPm5zID09IE5VTEwpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmIikpICYmIAoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWF4T2NjdXJzIikpICYmIAoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSkgewoKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9DT01CSU5BVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudCBkZWNsYXJhdGlvbiAlczogb25seSBtaW5PY2N1cnMsIG1heE9jY3VycyAiCgkJICAgICAgICJhbmQgaWQgYXJlIGFsbG93ZWQgaW4gYWRkaXRpb24gdG8gcmVmXG4iLAoJCSAgICAgICByZXQtPm5hbWUsIE5VTEwpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KICAgIH0KCiAgICBpZiAodG9wTGV2ZWwpIHsKICAgICAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMOwogICAgICAgIHJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9UT1BMRVZFTDsKICAgIH0KICAgIGlmICh4bWxHZXRCb29sZWFuUHJvcChjdHh0LCBub2RlLCAibmlsbGFibGUiLCAwKSkKICAgICAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEU7CiAgICBpZiAoeG1sR2V0Qm9vbGVhblByb3AoY3R4dCwgbm9kZSwgImFic3RyYWN0IiwgMCkpCiAgICAgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUOwogICAgY3R4dC0+Y29udGFpbmVyID0gbmFtZTsKCiAgICByZXQtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKICAgIHJldC0+bmFtZWRUeXBlID0KICAgICAgICB4bWxHZXRRTmFtZVByb3AoY3R4dCwgbm9kZSwgInR5cGUiLCAmKHJldC0+bmFtZWRUeXBlTnMpKTsgCiAgICByZXQtPnN1YnN0R3JvdXAgPQogICAgICAgIHhtbEdldFFOYW1lUHJvcChjdHh0LCBub2RlLCAic3Vic3RpdHV0aW9uR3JvdXAiLAogICAgICAgICAgICAgICAgICAgICAgICAmKHJldC0+c3Vic3RHcm91cE5zKSk7CiAgICBpZiAoKHJldC0+c3Vic3RHcm91cCAhPSBOVUxMKSAmJiAoIXRvcExldmVsKSkgewoJLyogMy4zLjYgOiAzICovCgkvKgoJICogVE9ETzogVGhpcyBzZWVtcyB0byBiZSByZWR1bmRhbnQsIHNpbmNlIHRoZSBzY2hlbWEgZm9yIHNjaGVtYXMKCSAqIGFscmVhZHkgcHJvaGliaXRzIHRoZSB1c2Ugb2YgdGhlICJzdWJzdGl0dXRpb25Hcm91cCIgYXR0cmlidXRlCgkgKiBpbiBsb2NhbCBlbGVtZW50IGRlY2xhcmF0aW9ucy4KCSAqLwogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVBfSU5WQUxJRF9BVFRSX0NPTUJJTkFUSU9OLAoJICAgICAgICAgICAgICAiRWxlbWVudCBkZWNsYXJhdGlvbiAlczogc3Vic3RpdHV0aW9uR3JvdXAgaXMgYWxsb3dlZCAiCgkJICAgICAgIm9uIHRvcC1sZXZlbCBkZWNsYXJhdGlvbnMgb25seVxuIiwgcmV0LT5uYW1lLCBOVUxMKTsKCQogICAgfQogICAgZml4ZWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmaXhlZCIpOwogICAgcmV0LT5taW5PY2N1cnMgPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSk7CiAgICByZXQtPm1heE9jY3VycyA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlKTsKCiAgICByZXQtPnZhbHVlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZGVmYXVsdCIpOwogICAgaWYgKChyZXQtPnZhbHVlICE9IE5VTEwpICYmIChmaXhlZCAhPSBOVUxMKSkgewoJLyogMy4zLjMgOiAxIAoJICogZGVmYXVsdCBhbmQgZml4ZWQgbXVzdCBub3QgYm90aCBiZSBwcmVzZW50LiAKCSAqLwogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9FTEVNX0RFRkFVTFRfRklYRUQsCiAgICAgICAgICAgICAgICAgICAgICAgIkVsZW1lbnQgJXMgaGFzIGJvdGggZGVmYXVsdCBhbmQgZml4ZWRcbiIsCgkJICAgICAgIHJldC0+bmFtZSwgTlVMTCk7CiAgICB9IGVsc2UgaWYgKGZpeGVkICE9IE5VTEwpIHsKICAgICAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQ7CiAgICAgICAgcmV0LT52YWx1ZSA9IGZpeGVkOwogICAgfQoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgCiAgICBpZiAocmVmICE9IE5VTEwpIHsKCS8qIDMuMy4zICgyLjIpICovIAoJd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsKCSAgICBpZiAoKElTX1NDSEVNQShjaGlsZCwgImNvbXBsZXhUeXBlIikpIHx8CgkJKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgfHwKCQkoSVNfU0NIRU1BKGNoaWxkLCAidW5pcXVlIikpIHx8CgkgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJrZXkiKSkgfHwgCgkJKElTX1NDSEVNQShjaGlsZCwgImtleXJlZiIpKSkgewoKCQl4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfUkVGX0FORF9DT05URU5ULAoJCSAgICAgICAgICAgICAgICJFbGVtZW50IGRlY2xhcmF0aW9uICVzOiBvbmx5IGFubm90YXRpb24gaXMgIgoJCQkgICAgICAgImFsbG93ZWQgYXMgY29udGVudCBpbiBhZGRpdGlvbiB0byByZWZcbiIsCgkJCSAgICAgICByZXQtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZSB7CgkJeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1VOS05PV05fRUxFTV9DSElMRCwKCQkgICAgICAgICAgICJlbGVtZW50ICVzIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsIG5hbWUsIE5VTEwpOwoJICAgIH0KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfSBlbHNlIHsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpKSB7CgkgICAgLyogMy4zLjMgOiAzIAoJICAgICAqIHR5cGUgYW5kIGVpdGhlciA8c2ltcGxlVHlwZT4gb3IgPGNvbXBsZXhUeXBlPiBhcmUgbXV0dWFsbHkKCSAgICAgKiBleGNsdXNpdmUgCgkgICAgICovCgkgICAgaWYgKHJldC0+bmFtZWRUeXBlICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKCQkJICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9JTkxJTkVfQ09NQklOQVRJT04sCgkJICAgICAgICAgICAgICAgIkVsZW1lbnQgZGVjbGFyYXRpb24gJXMgaGFzIGJvdGggXCJ0eXBlXCIgIgoJCQkgICAgICAgImFuZCBhIGxvY2FsIGNvbXBsZXggdHlwZVxuIiwKCQkJICAgICAgIHJldC0+bmFtZSwgTlVMTCk7CgkgICAgfSBlbHNlCgkJcmV0LT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CgkgICAgLyogMy4zLjMgOiAzIAoJICAgICAqIHR5cGUgYW5kIGVpdGhlciA8c2ltcGxlVHlwZT4gb3IgPGNvbXBsZXhUeXBlPiBhcmUKCSAgICAgKiBtdXR1YWxseSBleGNsdXNpdmUgCgkgICAgICovCgkgICAgaWYgKHJldC0+bmFtZWRUeXBlICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKCQkJICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9JTkxJTkVfQ09NQklOQVRJT04sCgkJICAgICAgICAgICAgICAgIkVsZW1lbnQgZGVjbGFyYXRpb24gJXMgaGFzIGJvdGggXCJ0eXBlXCIgIgoJCQkgICAgICAgImFuZCBhIGxvY2FsIHNpbXBsZSB0eXBlXG4iLAoJCQkgICAgICAgcmV0LT5uYW1lLCBOVUxMKTsKCSAgICB9IGVsc2UKCQlyZXQtPnN1YnR5cGVzID0geG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICAKCXdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAidW5pcXVlIikpIHx8CgkgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImtleSIpKSB8fCAoSVNfU0NIRU1BKGNoaWxkLCAia2V5cmVmIikpKSB7CgkgICAgVE9ETyBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJaWYgKGNoaWxkICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9FTEVNX0NISUxELAoJCSAgICAgICAgICAgImVsZW1lbnQgJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgbmFtZSwgTlVMTCk7Cgl9CiAgICB9CgogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VVbmlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgVW5pb24gZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVVuaW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgbGFzdCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICJ1bmlvbiAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9VTklPTjsKICAgIHR5cGUtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKICAgIHR5cGUtPnJlZiA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm1lbWJlclR5cGVzIik7CgogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgd2hpbGUgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKGxhc3QgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsYXN0LT5uZXh0ID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxhc3QtPm5leHQgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9VTklPTl9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiVW5pb24gJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgdHlwZS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUxpc3Q6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIExpc3QgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUxpc3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgImxpc3QgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfTElTVDsKICAgIHR5cGUtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKICAgIHR5cGUtPnJlZiA9IHhtbEdldFFOYW1lUHJvcChjdHh0LCBub2RlLCAicmVmIiwgJih0eXBlLT5yZWZOcykpOwoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIAogICAgc3VidHlwZSA9IE5VTEw7CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0xJU1RfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgIkxpc3QgJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgdHlwZS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFNpbXBsZSBUeXBlIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCgogICAgbmFtZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm5hbWUiKTsKICAgIGlmIChuYW1lID09IE5VTEwpIHsKICAgICAgICBjaGFyIGJ1ZlsxMDBdOwoKICAgICAgICBzbnByaW50ZihidWYsIDk5LCAic2ltcGxlVHlwZSAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCAoY29uc3QgeG1sQ2hhciAqKWJ1ZiwgTlVMTCk7CiAgICB9IGVsc2UgewkKICAgICAgICAvKiBsb2NhbCA9IHhtbFNjaGVtYUdldE5hbWVzcGFjZShjdHh0LCBzY2hlbWEsIG5vZGUsIG5hbWUsICZucyk7ICovCgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKTsKICAgIH0KICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU7CiAgICBpZiAodG9wTGV2ZWwpIAogICAgICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHN1YnR5cGUgPSBOVUxMOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlc3RyaWN0aW9uIikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAibGlzdCIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZUxpc3QoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAidW5pb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VVbmlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgaWYgKHN1YnR5cGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfTUlTU0lOR19TSU1QTEVUWVBFX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJTaW1wbGVUeXBlICVzIGRvZXMgbm90IGRlZmluZSBhIHZhcmlldHlcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fU0lNUExFVFlQRV9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiU2ltcGxlVHlwZSAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLAogICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPm5hbWUsIE5VTEwpOwogICAgfQoKICAgIHJldHVybiAodHlwZSk7Cn0KCgovKioKICogeG1sU2NoZW1hUGFyc2VHcm91cDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgR3JvdXAgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgY29uc3QgeG1sQ2hhciAqcmVmID0gTlVMTCwgKnJlZk5zID0gTlVMTDsKICAgIGNoYXIgYnVmWzEwMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCgogICAgbmFtZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm5hbWUiKTsKICAgIGlmIChuYW1lID09IE5VTEwpIHsKICAgICAgICByZWYgPSB4bWxHZXRRTmFtZVByb3AoY3R4dCwgbm9kZSwgInJlZiIsICZyZWZOcyk7CiAgICAgICAgaWYgKHJlZiA9PSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9HUk9VUF9OT05BTUVfTk9SRUYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJHcm91cCBoYXMgbm8gbmFtZSBub3IgcmVmXG4iLCBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CglpZiAocmVmTnMgPT0gTlVMTCkKCSAgICByZWZOcyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwogICAgICAgIHNucHJpbnRmKGJ1ZiwgOTksICJhbm9uZ3JvdXAgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgICAgICBuYW1lID0gKGNvbnN0IHhtbENoYXIgKikgYnVmOwogICAgfQogICAgdHlwZSA9IHhtbFNjaGVtYUFkZEdyb3VwKGN0eHQsIHNjaGVtYSwgbmFtZSk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA7CiAgICBpZiAodG9wTGV2ZWwpIAogICAgICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgdHlwZS0+cmVmID0gcmVmOwogICAgdHlwZS0+cmVmTnMgPSByZWZOczsKICAgIHR5cGUtPm1pbk9jY3VycyA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlKTsKICAgIHR5cGUtPm1heE9jY3VycyA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlKTsKCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBzdWJ0eXBlID0gTlVMTDsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VBbGwoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VDaG9pY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VTZXF1ZW5jZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0dST1VQX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJHcm91cCAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCB0eXBlLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQoKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUFsbDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQWxsIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VBbGwoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgbGFzdCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICJhbGwlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BTEw7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICB0eXBlLT5taW5PY2N1cnMgPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSk7CiAgICBpZiAodHlwZS0+bWluT2NjdXJzID4gMSkKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLAoJICAgICJpbnZhbGlkIHZhbHVlIGZvciBtaW5PY2N1cnMgKG11c3QgYmUgMCBvciAxKVxuIiwgTlVMTCwgTlVMTCk7CiAgICB0eXBlLT5tYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSk7CiAgICBpZiAodHlwZS0+bWF4T2NjdXJzID4gMSkKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUFYT0NDVVJTLAoJICAgICJpbnZhbGlkIHZhbHVlIGZvciBtYXhPY2N1cnMgKG11c3QgYmUgMCBvciAxKVxuIiwgTlVMTCwgTlVMTCk7CgogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgd2hpbGUgKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VFbGVtZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpIHsKCSAgICBpZiAoc3VidHlwZS0+bWluT2NjdXJzID4gMSkKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY2hpbGQsIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLAoJICAgICAgICAgICAgICJpbnZhbGlkIHZhbHVlIGZvciBtaW5PY2N1cnMgKG11c3QgYmUgMCBvciAxKVxuIiwKCQkgICAgIE5VTEwsIE5VTEwpOwoJICAgIGlmIChzdWJ0eXBlLT5tYXhPY2N1cnMgPiAxKQoJICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGNoaWxkLCBYTUxfU0NIRU1BUF9JTlZBTElEX01BWE9DQ1VSUywKCSAgICAgICAgICAgICAiaW52YWxpZCB2YWx1ZSBmb3IgbWF4T2NjdXJzIChtdXN0IGJlIDAgb3IgMSlcbiIsCgkJICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgaWYgKGxhc3QgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsYXN0LT5uZXh0ID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxhc3QtPm5leHQgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9BTExfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgIkFsbCAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCB0eXBlLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQoKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJbXBvcnRTY2hlbWEKICogCiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWFMb2NhdGlvbjogIGFuIFVSSSBkZWZpbmluZyB3aGVyZSB0byBmaW5kIHRoZSBpbXBvcnRlZCBzY2hlbWEKICoKICogaW1wb3J0IGEgWE1MIHNjaGVtYQogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciBhbmQgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hSW1wb3J0UHRyCnhtbFNjaGVtYUltcG9ydFNjaGVtYSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbikKewogICAgeG1sU2NoZW1hSW1wb3J0UHRyIGltcG9ydDsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgbmV3Y3R4dDsKCiAgICBuZXdjdHh0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgaWYgKG5ld2N0eHQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQobmV3Y3R4dCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIC8qIEtlZXAgdGhlIHNhbWUgZGljdGlvbm5hcnkgZm9yIHBhcnNpbmcsIHJlYWxseSAqLwogICAgeG1sRGljdFJlZmVyZW5jZShjdHh0LT5kaWN0KTsKICAgIG5ld2N0eHQtPmRpY3QgPSBjdHh0LT5kaWN0OwogICAgbmV3Y3R4dC0+aW5jbHVkZXMgPSAwOwogICAgbmV3Y3R4dC0+VVJMID0geG1sRGljdExvb2t1cChuZXdjdHh0LT5kaWN0LCBzY2hlbWFMb2NhdGlvbiwgLTEpOwoKICAgIHhtbFNjaGVtYVNldFBhcnNlckVycm9ycyhuZXdjdHh0LCBjdHh0LT5lcnJvciwgY3R4dC0+d2FybmluZywKCSAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnVzZXJEYXRhKTsKCiAgICBpbXBvcnQgPSAoeG1sU2NoZW1hSW1wb3J0KikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJbXBvcnQpKTsKICAgIGlmIChpbXBvcnQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgaW1wb3J0ZWQgc2NoZW1hIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwoJeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQobmV3Y3R4dCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KCiAgICBtZW1zZXQoaW1wb3J0LCAwLCBzaXplb2YoeG1sU2NoZW1hSW1wb3J0KSk7CiAgICBpbXBvcnQtPnNjaGVtYUxvY2F0aW9uID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBzY2hlbWFMb2NhdGlvbiwgLTEpOwogICAgaW1wb3J0LT5zY2hlbWEgPSB4bWxTY2hlbWFQYXJzZShuZXdjdHh0KTsKCiAgICBpZiAoaW1wb3J0LT5zY2hlbWEgPT0gTlVMTCkgewogICAgICAgIC8qIEZJWE1FIHVzZSBhbm90aGVyIGVycm9yIGVudW0gaGVyZSA/ICovCiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkgICAgICAgICAgICAgICJmYWlsZWQgdG8gaW1wb3J0IHNjaGVtYSBhdCBsb2NhdGlvbiAlc1xuIiwKCQkgICAgICBzY2hlbWFMb2NhdGlvbiwgTlVMTCk7CgoJeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQobmV3Y3R4dCk7CglpZiAoaW1wb3J0LT5zY2hlbWFMb2NhdGlvbiAhPSBOVUxMKQoJICAgIHhtbEZyZWUoKHhtbENoYXIgKilpbXBvcnQtPnNjaGVtYUxvY2F0aW9uKTsKCXhtbEZyZWUoaW1wb3J0KTsKCXJldHVybiBOVUxMOwogICAgfQoKICAgIHhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KG5ld2N0eHQpOwogICAgcmV0dXJuIGltcG9ydDsKfQoKCi8qKgogKiB4bWxTY2hlbWFQYXJzZUltcG9ydDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgSW1wb3J0IGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUltcG9ydCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0ID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZTsKICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uOwogICAgY29uc3QgeG1sQ2hhciAqcHJldmlvdXM7CiAgICB4bWxVUklQdHIgY2hlY2s7CgoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIG5hbWVzcGFjZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm5hbWVzcGFjZSIpOwogICAgaWYgKG5hbWVzcGFjZSAhPSBOVUxMKSB7CiAgICAgICAgY2hlY2sgPSB4bWxQYXJzZVVSSSgoY29uc3QgY2hhciAqKSBuYW1lc3BhY2UpOwogICAgICAgIGlmIChjaGVjayA9PSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9JTVBPUlRfTkFNRVNQQUNFX05PVF9VUkksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbXBvcnQgbmFtZXNwYWNlIGF0dHJpYnV0ZSBpcyBub3QgYW4gVVJJOiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuICgtMSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgeG1sRnJlZVVSSShjaGVjayk7CiAgICAgICAgfQogICAgfQogICAgc2NoZW1hTG9jYXRpb24gPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJzY2hlbWFMb2NhdGlvbiIpOwogICAgaWYgKHNjaGVtYUxvY2F0aW9uICE9IE5VTEwpIHsKICAgICAgICB4bWxDaGFyICpiYXNlID0gTlVMTDsKICAgICAgICB4bWxDaGFyICpVUkkgPSBOVUxMOwogICAgICAgIGNoZWNrID0geG1sUGFyc2VVUkkoKGNvbnN0IGNoYXIgKikgc2NoZW1hTG9jYXRpb24pOwogICAgICAgIGlmIChjaGVjayA9PSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9JTVBPUlRfU0NIRU1BX05PVF9VUkksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbXBvcnQgc2NoZW1hTG9jYXRpb24gYXR0cmlidXRlIGlzIG5vdCBhbiBVUkk6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFMb2NhdGlvbiwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoLTEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHhtbEZyZWVVUkkoY2hlY2spOwogICAgICAgIH0KCWJhc2UgPSB4bWxOb2RlR2V0QmFzZShub2RlLT5kb2MsIG5vZGUpOwoJaWYgKGJhc2UgPT0gTlVMTCkgewoJICAgIFVSSSA9IHhtbEJ1aWxkVVJJKHNjaGVtYUxvY2F0aW9uLCBub2RlLT5kb2MtPlVSTCk7Cgl9IGVsc2UgewoJICAgIFVSSSA9IHhtbEJ1aWxkVVJJKHNjaGVtYUxvY2F0aW9uLCBiYXNlKTsKCSAgICB4bWxGcmVlKGJhc2UpOwoJfQoJaWYgKFVSSSAhPSBOVUxMKSB7CgkgICAgc2NoZW1hTG9jYXRpb24gPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIFVSSSwgLTEpOwoJICAgIHhtbEZyZWUoVVJJKTsKCX0KICAgIH0KICAgIGlmIChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzID09IE5VTEwpIHsKICAgICAgICBzY2hlbWEtPnNjaGVtYXNJbXBvcnRzID0geG1sSGFzaENyZWF0ZSgxMCk7CiAgICAgICAgaWYgKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfRkFJTEVEX0JVSUxEX0lNUE9SVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIkludGVybmFsOiBmYWlsZWQgdG8gYnVpbGQgaW1wb3J0IHRhYmxlXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuICgtMSk7CiAgICAgICAgfQogICAgfQogICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKSB7CiAgICAgICAgaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFTX0RFRkFVTFRfTkFNRVNQQUNFKTsKCWlmIChpbXBvcnQgIT0gTlVMTCkKICAgICAgICAgICAgcHJldmlvdXMgPSBpbXBvcnQtPnNjaGVtYUxvY2F0aW9uOwoJZWxzZQoJICAgIHByZXZpb3VzID0gTlVMTDsKCiAgICAgICAgaWYgKHNjaGVtYUxvY2F0aW9uICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKHByZXZpb3VzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGlmICgheG1sU3RyRXF1YWwoc2NoZW1hTG9jYXRpb24sIHByZXZpb3VzKSkgewogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lNUE9SVF9SRURFRklORV9OU05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlZGVmaW5pbmcgaW1wb3J0IGZvciBkZWZhdWx0IG5hbWVzcGFjZSAiCgkJCQkgICAid2l0aCBhIGRpZmZlcmVudCBVUkk6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYUxvY2F0aW9uLCBOVUxMKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKCSAgICAgICAgaW1wb3J0ID0geG1sU2NoZW1hSW1wb3J0U2NoZW1hKGN0eHQsIHNjaGVtYUxvY2F0aW9uKTsKCQlpZiAoaW1wb3J0ID09IE5VTEwpIHsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQogICAgICAgICAgICAgICAgeG1sSGFzaEFkZEVudHJ5KHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVNfREVGQVVMVF9OQU1FU1BBQ0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wb3J0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBuYW1lc3BhY2UpOwoJaWYgKGltcG9ydCAhPSBOVUxMKQoJICAgIHByZXZpb3VzID0gaW1wb3J0LT5zY2hlbWFMb2NhdGlvbjsKCWVsc2UKCSAgICBwcmV2aW91cyA9IE5VTEw7CgogICAgICAgIGlmIChzY2hlbWFMb2NhdGlvbiAhPSBOVUxMKSB7CiAgICAgICAgICAgIGlmIChwcmV2aW91cyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBpZiAoIXhtbFN0ckVxdWFsKHNjaGVtYUxvY2F0aW9uLCBwcmV2aW91cykpIHsKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9JTVBPUlRfUkVERUZJTkVfTlNOQU1FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWRlZmluaW5nIGltcG9ydCBmb3IgbmFtZXNwYWNlICVzIHdpdGggIgoJCQkJICAgImEgZGlmZmVyZW50IFVSSTogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlLCBzY2hlbWFMb2NhdGlvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CgkgICAgICAgIGltcG9ydCA9IHhtbFNjaGVtYUltcG9ydFNjaGVtYShjdHh0LCBzY2hlbWFMb2NhdGlvbik7CgkJaWYgKGltcG9ydCA9PSBOVUxMKSB7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQlpZiAoIXhtbFN0ckVxdWFsKGltcG9ydC0+c2NoZW1hLT50YXJnZXROYW1lc3BhY2UsIG5hbWVzcGFjZSkpIHsKCQkgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKSB7CgkJCWlmIChpbXBvcnQtPnNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsKCQkJICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMiwKCQkJICAgICJUaGVyZSBpcyBubyBuYW1lc3BhY2UgYXR0cmlidXRlIG9uIHRoZSA8aW1wb3J0PiAiCgkJCSAgICAiZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtLCBzbyB0aGUgaW1wb3J0ZWQgZG9jdW1lbnQgIgoJCQkgICAgIm11c3QgaGF2ZSBubyB0YXJnZXROYW1lc3BhY2UgYXR0cmlidXRlLlxuIiwgCgkJCSAgICBOVUxMLCBOVUxMKTsgCgkJCX0KCQkgICAgfSBlbHNlIHsKCQkJaWYgKGltcG9ydC0+c2NoZW1hLT50YXJnZXROYW1lc3BhY2UgIT0gTlVMTCkgewoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMSwKCQkJCSJUaGUgbmFtZXNwYWNlIGF0dHJpYnV0ZSBcIiVzXCIgb2YgYW4gPGltcG9ydD4gIgoJCQkJImVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlIGlkZW50aWNhbCB0byB0aGUgIgoJCQkJInRhcmdldE5hbWVzcGFjZSBhdHRyaWJ1dGUgXCIlc1wiIG9mIHRoZSAiCgkJCQkiaW1wb3J0ZWQgZG9jdW1lbnQuXG4iLCAKCQkJCW5hbWVzcGFjZSwgaW1wb3J0LT5zY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CgkJCX0gZWxzZSB7CgkJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfM18xLAoJCQkJIlRoZSBuYW1lc3BhY2UgYXR0cmlidXRlIG9uIHRoZSA8aW1wb3J0PiAiCgkJCQkiZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtLCByZXF1aXJlcyB0aGUgaW1wb3J0ZWQgIgoJCQkJImRvY3VtZW50IHRvIGhhdmUgYSB0YXJnZXROYW1lc3BhY2UgYXR0cmlidXRlICIKCQkJCSJ3aXRoIHRoZSB2YWx1ZSBcIiVzXCIuXG4iLCAKCQkJCW5hbWVzcGFjZSwgTlVMTCk7CgkJCX0KCQkgICAgfQoJCSAgICB4bWxTY2hlbWFGcmVlSW1wb3J0KGltcG9ydCk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCiAgICAgICAgICAgICAgICB4bWxIYXNoQWRkRW50cnkoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UsIGltcG9ydCk7CgkJCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIHdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICAvKgogICAgICAgICAqIHRoZSBhbm5vdGF0aW9ucyBoZXJlIGFyZSBzaW1wbHkgZGlzY2FyZGVkIC4uLgogICAgICAgICAqLwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0lNUE9SVF9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiSW1wb3J0IGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgcmV0dXJuICgxKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNsZWFudXBEb2M6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHJvb3Qgb2YgdGhlIGRvY3VtZW50LgogKgogKiByZW1vdmVzIHVud2FudGVkIG5vZGVzIGluIGEgc2NoZW1hcyBkb2N1bWVudCB0cmVlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhbnVwRG9jKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciByb290KQp7CiAgICB4bWxOb2RlUHRyIGRlbGV0ZSwgY3VyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAocm9vdCA9PSBOVUxMKSkgcmV0dXJuOwoKICAgIC8qCiAgICAgKiBSZW1vdmUgYWxsIHRoZSBibGFuayB0ZXh0IG5vZGVzCiAgICAgKi8KICAgIGRlbGV0ZSA9IE5VTEw7CiAgICBjdXIgPSByb290OwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CiAgICAgICAgaWYgKGRlbGV0ZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFVubGlua05vZGUoZGVsZXRlKTsKICAgICAgICAgICAgeG1sRnJlZU5vZGUoZGVsZXRlKTsKICAgICAgICAgICAgZGVsZXRlID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgaWYgKGN1ci0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSB7CiAgICAgICAgICAgIGlmIChJU19CTEFOS19OT0RFKGN1cikpIHsKICAgICAgICAgICAgICAgIGlmICh4bWxOb2RlR2V0U3BhY2VQcmVzZXJ2ZShjdXIpICE9IDEpIHsKICAgICAgICAgICAgICAgICAgICBkZWxldGUgPSBjdXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKChjdXItPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYKICAgICAgICAgICAgICAgICAgIChjdXItPnR5cGUgIT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkpIHsKICAgICAgICAgICAgZGVsZXRlID0gY3VyOwogICAgICAgICAgICBnb3RvIHNraXBfY2hpbGRyZW47CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIFNraXAgdG8gbmV4dCBub2RlCiAgICAgICAgICovCiAgICAgICAgaWYgKGN1ci0+Y2hpbGRyZW4gIT0gTlVMTCkgewogICAgICAgICAgICBpZiAoKGN1ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX0VOVElUWV9ERUNMKSAmJgogICAgICAgICAgICAgICAgKGN1ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgJiYKICAgICAgICAgICAgICAgIChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfTk9ERSkpIHsKICAgICAgICAgICAgICAgIGN1ciA9IGN1ci0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgc2tpcF9jaGlsZHJlbjoKICAgICAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgY3VyID0gY3VyLT5uZXh0OwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGRvIHsKICAgICAgICAgICAgY3VyID0gY3VyLT5wYXJlbnQ7CiAgICAgICAgICAgIGlmIChjdXIgPT0gTlVMTCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBpZiAoY3VyID09IHJvb3QpIHsKICAgICAgICAgICAgICAgIGN1ciA9IE5VTEw7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfQogICAgaWYgKGRlbGV0ZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sVW5saW5rTm9kZShkZWxldGUpOwogICAgICAgIHhtbEZyZWVOb2RlKGRlbGV0ZSk7CiAgICAgICAgZGVsZXRlID0gTlVMTDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWw6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hcwogKiBAbm9kZXM6ICB0aGUgbGlzdCBvZiB0b3AgbGV2ZWwgbm9kZXMKICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZXMpCnsKICAgIHhtbE5vZGVQdHIgY2hpbGQ7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZXMgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuOwoKICAgIGNoaWxkID0gbm9kZXM7CiAgICB3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgImluY2x1ZGUiKSkgfHwKCSAgIChJU19TQ0hFTUEoY2hpbGQsICJpbXBvcnQiKSkgfHwKCSAgIChJU19TQ0hFTUEoY2hpbGQsICJyZWRlZmluZSIpKSB8fAoJICAgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkpIHsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCSAgICBhbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBpZiAoc2NoZW1hLT5hbm5vdCA9PSBOVUxMKQoJCXNjaGVtYS0+YW5ub3QgPSBhbm5vdDsKCSAgICBlbHNlCgkJeG1sU2NoZW1hRnJlZUFubm90KGFubm90KTsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiaW1wb3J0IikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZUltcG9ydChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiaW5jbHVkZSIpKSB7CgkgICAgY3R4dC0+aW5jbHVkZXMrKzsKCSAgICB4bWxTY2hlbWFQYXJzZUluY2x1ZGUoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY3R4dC0+aW5jbHVkZXMtLTsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVkZWZpbmUiKSkgewoJICAgIFRPRE8KCX0KCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB3aGlsZSAoY2hpbGQgIT0gTlVMTCkgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgImNvbXBsZXhUeXBlIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZUVsZW1lbnQoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGVHcm91cCIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJub3RhdGlvbiIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VOb3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBOVUxMLCBjaGlsZCwKCQkJICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9TQ0hFTUFTX0NISUxELAoJCQkgICAiU2NoZW1hczogdW5leHBlY3RlZCBlbGVtZW50ICVzIGhlcmUgXG4iLAoJCQkgICBjaGlsZC0+bmFtZSwgTlVMTCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCXdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCSAgICBhbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBpZiAoc2NoZW1hLT5hbm5vdCA9PSBOVUxMKQoJCXNjaGVtYS0+YW5ub3QgPSBhbm5vdDsKCSAgICBlbHNlCgkJeG1sU2NoZW1hRnJlZUFubm90KGFubm90KTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hUGFyc2VJbmNsdWRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBJbmNsdWRlIGRlZmluaXRpb24KICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbmNsdWRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbjsKICAgIHhtbFVSSVB0ciBjaGVjazsKICAgIHhtbERvY1B0ciBkb2M7CiAgICB4bWxOb2RlUHRyIHJvb3Q7CiAgICB4bWxTY2hlbWFJbmNsdWRlUHRyIGluY2x1ZGU7CgoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIC8qCiAgICAgKiBQcmVsaW1pbmFyeSBzdGVwLCBleHRyYWN0IHRoZSBVUkktUmVmZXJlbmNlIGZvciB0aGUgaW5jbHVkZSBhbmQKICAgICAqIG1ha2UgYW4gVVJJIGZyb20gdGhlIGJhc2UuCiAgICAgKi8KICAgIHNjaGVtYUxvY2F0aW9uID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAic2NoZW1hTG9jYXRpb24iKTsKICAgIGlmIChzY2hlbWFMb2NhdGlvbiAhPSBOVUxMKSB7CiAgICAgICAgeG1sQ2hhciAqYmFzZSA9IE5VTEw7CiAgICAgICAgeG1sQ2hhciAqVVJJID0gTlVMTDsKICAgICAgICBjaGVjayA9IHhtbFBhcnNlVVJJKChjb25zdCBjaGFyICopIHNjaGVtYUxvY2F0aW9uKTsKICAgICAgICBpZiAoY2hlY2sgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5DTFVERV9TQ0hFTUFfTk9UX1VSSSwKCQkgICAgICAgIkluY2x1ZGUgc2NoZW1hTG9jYXRpb24gYXR0cmlidXRlIGlzIG5vdCBhbiBVUkk6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFMb2NhdGlvbiwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoLTEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHhtbEZyZWVVUkkoY2hlY2spOwogICAgICAgIH0KCWJhc2UgPSB4bWxOb2RlR2V0QmFzZShub2RlLT5kb2MsIG5vZGUpOwoJaWYgKGJhc2UgPT0gTlVMTCkgewoJICAgIFVSSSA9IHhtbEJ1aWxkVVJJKHNjaGVtYUxvY2F0aW9uLCBub2RlLT5kb2MtPlVSTCk7Cgl9IGVsc2UgewoJICAgIFVSSSA9IHhtbEJ1aWxkVVJJKHNjaGVtYUxvY2F0aW9uLCBiYXNlKTsKCSAgICB4bWxGcmVlKGJhc2UpOwoJfQoJaWYgKFVSSSAhPSBOVUxMKSB7CgkgICAgc2NoZW1hTG9jYXRpb24gPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIFVSSSwgLTEpOwoJICAgIHhtbEZyZWUoVVJJKTsKCX0KICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKCQkgICAgICAgWE1MX1NDSEVNQVBfSU5DTFVERV9TQ0hFTUFfTk9fVVJJLAoJCSAgICJJbmNsdWRlIHNjaGVtYUxvY2F0aW9uIGF0dHJpYnV0ZSBtaXNzaW5nXG4iLAoJCSAgICAgICBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGUgYW5ub3RhdGlvbnMgaGVyZSBhcmUgc2ltcGx5IGRpc2NhcmRlZCAuLi4KICAgICAgICAgKi8KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9JTkNMVURFX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJJbmNsdWRlIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIC8qCiAgICAgKiBGaXJzdCBzdGVwIGlzIHRvIHBhcnNlIHRoZSBpbnB1dCBkb2N1bWVudCBpbnRvIGFuIERPTS9JbmZvc2V0CiAgICAgKi8KICAgIGRvYyA9IHhtbFJlYWRGaWxlKChjb25zdCBjaGFyICopIHNjaGVtYUxvY2F0aW9uLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgIGlmIChkb2MgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLAoJCSAgICAgIFhNTF9TQ0hFTUFQX0ZBSUxFRF9MT0FELAoJCSAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IGxvYWQgJXNcbiIsCgkJICAgICAgY3R4dC0+VVJMLCBOVUxMKTsKCXJldHVybigtMSk7CiAgICB9CgogICAgLyoKICAgICAqIFRoZW4gZXh0cmFjdCB0aGUgcm9vdCBvZiB0aGUgc2NoZW1hCiAgICAgKi8KICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwogICAgaWYgKHJvb3QgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PUk9PVCwKCQkgICAgICAic2NoZW1hcyAlcyBoYXMgbm8gcm9vdCIsIHNjaGVtYUxvY2F0aW9uLCBOVUxMKTsKCXhtbEZyZWVEb2MoZG9jKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICB4bWxTY2hlbWFDbGVhbnVwRG9jKGN0eHQsIHJvb3QpOwoKICAgIC8qCiAgICAgKiBDaGVjayB0aGUgc2NoZW1hcyB0b3AgbGV2ZWwgZWxlbWVudAogICAgICovCiAgICBpZiAoIUlTX1NDSEVNQShyb290LCAic2NoZW1hIikpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9OT1RfU0NIRU1BLAoJCSAgICAgICJGaWxlICVzIGlzIG5vdCBhIHNjaGVtYXMiLCBzY2hlbWFMb2NhdGlvbiwgTlVMTCk7Cgl4bWxGcmVlRG9jKGRvYyk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CgogICAgLyoKICAgICAqIHJlZ2lzdGVyIHRoZSBpbmNsdWRlCiAgICAgKi8KICAgIGluY2x1ZGUgPSAoeG1sU2NoZW1hSW5jbHVkZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJbmNsdWRlKSk7CiAgICBpZiAoaW5jbHVkZSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBpbmNsdWRlZCBzY2hlbWEiLCBOVUxMKTsKCXhtbEZyZWVEb2MoZG9jKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KCiAgICBtZW1zZXQoaW5jbHVkZSwgMCwgc2l6ZW9mKHhtbFNjaGVtYUluY2x1ZGUpKTsKICAgIGluY2x1ZGUtPnNjaGVtYUxvY2F0aW9uID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBzY2hlbWFMb2NhdGlvbiwgLTEpOwogICAgaW5jbHVkZS0+ZG9jID0gZG9jOwogICAgaW5jbHVkZS0+bmV4dCA9IHNjaGVtYS0+aW5jbHVkZXM7CiAgICBzY2hlbWEtPmluY2x1ZGVzID0gaW5jbHVkZTsKCgogICAgLyoKICAgICAqIHBhcnNlIHRoZSBkZWNsYXJhdGlvbnMgaW4gdGhlIGluY2x1ZGVkIGZpbGUgbGlrZSBpZiB0aGV5CiAgICAgKiB3ZXJlIGluIHRoZSBvcmlnaW5hbCBmaWxlLgogICAgICovCiAgICB4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsKGN0eHQsIHNjaGVtYSwgcm9vdC0+Y2hpbGRyZW4pOwoKICAgIHJldHVybiAoMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUNob2ljZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQ2hvaWNlIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VDaG9pY2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgbGFzdCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICJjaG9pY2UgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgdHlwZS0+bWluT2NjdXJzID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUpOwogICAgdHlwZS0+bWF4T2NjdXJzID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUpOwoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJhbnkiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpKSB7CiAgICAgICAgc3VidHlwZSA9IE5VTEw7CiAgICAgICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZUVsZW1lbnQoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55IikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQW55KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VTZXF1ZW5jZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUNob2ljZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9CiAgICAgICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkgewogICAgICAgICAgICBpZiAobGFzdCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICBsYXN0ID0gc3VidHlwZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxhc3QtPm5leHQgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGFzdC0+bmV4dCA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0NIT0lDRV9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiQ2hvaWNlICVzIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsIHR5cGUtPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICB9CgogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2VxdWVuY2U6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFNlcXVlbmNlIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VTZXF1ZW5jZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGUsIGxhc3QgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAic2VxdWVuY2UgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICB0eXBlLT5taW5PY2N1cnMgPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSk7CiAgICB0eXBlLT5tYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSk7CgogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImFueSIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkpIHsKICAgICAgICBzdWJ0eXBlID0gTlVMTDsKICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlRWxlbWVudChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnkiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VBbnkoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VDaG9pY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIH0KICAgICAgICBpZiAoc3VidHlwZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIGlmIChsYXN0ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbGFzdC0+bmV4dCA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICBsYXN0ID0gc3VidHlwZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsYXN0LT5uZXh0ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9TRVFVRU5DRV9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiU2VxdWVuY2UgJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgdHlwZS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKiBAc2ltcGxlOiAgaXMgdGhhdCBwYXJ0IG9mIGEgc2ltcGxlIHR5cGUuCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBSZXN0cmljdGlvbiBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgc2ltcGxlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGU7CiAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwgbGFzdGZhY2V0ID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lcjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKCiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgInJlc3RyaWN0aW9uICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgdHlwZS0+YmFzZSA9IHhtbEdldFFOYW1lUHJvcChjdHh0LCBub2RlLCAiYmFzZSIsICYodHlwZS0+YmFzZU5zKSk7CiAgICBpZiAoKCFzaW1wbGUpICYmICh0eXBlLT5iYXNlID09IE5VTEwpKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfUkVTVFJJQ1RJT05fTk9OQU1FX05PUkVGLAogICAgICAgICAgICAgICAgICAgICAgICJSZXN0cmljdGlvbiAlcyBoYXMgbm8gYmFzZVxuIiwgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9CiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHN1YnR5cGUgPSBOVUxMOwoKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VBbGwoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQ2hvaWNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZUdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICAgICAgdHlwZS0+YmFzZVR5cGUgPSBzdWJ0eXBlOwogICAgICAgIH0KICAgICAgICAvKgogICAgICAgICAqIEZhY2V0cwogICAgICAgICAqLwogICAgICAgIHdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAibWluSW5jbHVzaXZlIikpIHx8CiAgICAgICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJtaW5FeGNsdXNpdmUiKSkgfHwKICAgICAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgIm1heEluY2x1c2l2ZSIpKSB8fAogICAgICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWF4RXhjbHVzaXZlIikpIHx8CiAgICAgICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJ0b3RhbERpZ2l0cyIpKSB8fAogICAgICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiZnJhY3Rpb25EaWdpdHMiKSkgfHwKICAgICAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgInBhdHRlcm4iKSkgfHwKICAgICAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImVudW1lcmF0aW9uIikpIHx8CiAgICAgICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJ3aGl0ZVNwYWNlIikpIHx8CiAgICAgICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJsZW5ndGgiKSkgfHwKICAgICAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgIm1heExlbmd0aCIpKSB8fAogICAgICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWluTGVuZ3RoIikpKSB7CiAgICAgICAgICAgIGZhY2V0ID0geG1sU2NoZW1hUGFyc2VGYWNldChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICAgICAgaWYgKGZhY2V0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGlmIChsYXN0ZmFjZXQgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIHR5cGUtPmZhY2V0cyA9IGZhY2V0OwogICAgICAgICAgICAgICAgICAgIGxhc3RmYWNldCA9IGZhY2V0OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBsYXN0ZmFjZXQtPm5leHQgPSBmYWNldDsKICAgICAgICAgICAgICAgICAgICBsYXN0ZmFjZXQgPSBmYWNldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxhc3RmYWNldC0+bmV4dCA9IE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9CiAgICB9CiAgICAvKiBUT0RPOiBhIHJlc3RyaWN0aW9uIG9mIHNpbXBsZVR5cGUgZG9lcyBub3QgY29udGFpbiBhbnkgCiAgICAgKiBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zLgogICAgICovCiAgICBjaGlsZCA9IHhtbFNjaGVtYVBhcnNlQXR0ckRlY2xzKGN0eHQsIHNjaGVtYSwgY2hpbGQsIHR5cGUpOwogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX1JFU1RSSUNUSU9OX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJSZXN0cmljdGlvbiAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLAogICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPm5hbWUsIE5VTEwpOwogICAgfQogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlRXh0ZW5zaW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBFeHRlbnNpb24gZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlRXh0ZW5zaW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CiAgICBjb25zdCB4bWxDaGFyICpvbGRjb250YWluZXI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICJleHRlbnNpb24gJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgY3R4dC0+Y29udGFpbmVyID0gbmFtZTsKCiAgICB0eXBlLT5iYXNlID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJiYXNlIiwgJih0eXBlLT5iYXNlTnMpKTsKICAgIGlmICh0eXBlLT5iYXNlID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfRVhURU5TSU9OX05PX0JBU0UsCiAgICAgICAgICAgICAgICAgICAgICAgIkV4dGVuc2lvbiAlcyBoYXMgbm8gYmFzZVxuIiwgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBzdWJ0eXBlID0gTlVMTDsKCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VBbGwoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VDaG9pY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewogICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICBjaGlsZCA9IHhtbFNjaGVtYVBhcnNlQXR0ckRlY2xzKGN0eHQsIHNjaGVtYSwgY2hpbGQsIHR5cGUpOwogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0VYVEVOU0lPTl9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiRXh0ZW5zaW9uICVzIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsIHR5cGUtPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICB9CiAgICBjdHh0LT5jb250YWluZXIgPSBvbGRjb250YWluZXI7CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VTaW1wbGVDb250ZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBTaW1wbGVDb250ZW50IGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSB0eXBlIGRlZmluaXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVNpbXBsZUNvbnRlbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgInNpbXBsZUNvbnRlbnQgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQ7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CgogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgc3VidHlwZSA9IE5VTEw7CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJleHRlbnNpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VFeHRlbnNpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9TSU1QTEVDT05URU5UX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJTaW1wbGVDb250ZW50ICVzIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VDb21wbGV4Q29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQ29tcGxleENvbnRlbnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ29tcGxleENvbnRlbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiY29tcGxleENvbnRlbnQgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHN1YnR5cGUgPSBOVUxMOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlc3RyaWN0aW9uIikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZXh0ZW5zaW9uIikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlRXh0ZW5zaW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQ09NUExFWENPTlRFTlRfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgIkNvbXBsZXhDb250ZW50ICVzIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQ29tcGxleCBUeXBlIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSB0eXBlIGRlZmluaXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOyAgICAKICAgIGNoYXIgYnVmWzEwMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CiAgICBuYW1lID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAibmFtZSIpOwogICAgaWYgKG5hbWUgPT0gTlVMTCkgewogICAgICAgIHNucHJpbnRmKGJ1ZiwgOTksICJjb21wbGV4VHlwZSAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJbmFtZSA9IChjb25zdCB4bWxDaGFyICopYnVmOwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMKTsKICAgIH0gZWxzZSB7CgogICAgICAgIC8qIGxvY2FsID0geG1sU2NoZW1hR2V0TmFtZXNwYWNlKGN0eHQsIHNjaGVtYSwgbm9kZSwgbmFtZSwgJm5zKTsgKi8KCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UpOwogICAgfQogICAgaWYgKHR5cGUgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAoeG1sR2V0Qm9vbGVhblByb3AoY3R4dCwgbm9kZSwgIm1peGVkIiwgMCkpIAoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsgICAgCgogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg7CiAgICBpZiAodG9wTGV2ZWwpIAogICAgICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgY3R4dC0+Y29udGFpbmVyID0gbmFtZTsKCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlQ29udGVudCIpKSB7CgkvKiAzLjQuMyA6IDIuMiAgCgkgKiBTcGVjaWZ5aW5nIG1peGVkPSd0cnVlJyB3aGVuIHRoZSA8c2ltcGxlQ29udGVudD4KCSAqIGFsdGVybmF0aXZlIGlzIGNob3NlbiBoYXMgbm8gZWZmZWN0CgkgKi8KCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCgkgICAgdHlwZS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlU2ltcGxlQ29udGVudChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4Q29udGVudCIpKSB7CiAgICAgICAgdHlwZS0+c3VidHlwZXMgPSB4bWxTY2hlbWFQYXJzZUNvbXBsZXhDb250ZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgewogICAgICAgIHN1YnR5cGUgPSBOVUxMOwoKICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQWxsKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQ2hvaWNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VTZXF1ZW5jZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfQogICAgICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpCiAgICAgICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgICAgICBjaGlsZCA9IHhtbFNjaGVtYVBhcnNlQXR0ckRlY2xzKGN0eHQsIHNjaGVtYSwgY2hpbGQsIHR5cGUpOwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0NPTVBMRVhUWVBFX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJDb21wbGV4VHlwZSAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLAogICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPm5hbWUsIE5VTEwpOwogICAgfQogICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpCgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQ7CiAgICBjdHh0LT5jb250YWluZXIgPSBvbGRjb250YWluZXI7CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VTY2hlbWE6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIGRlZmluaXRpb24gZnJvbSBhIG5vZGUgc2V0CiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQdHIKeG1sU2NoZW1hUGFyc2VTY2hlbWEoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CiAgICBpbnQgbmJlcnJvcnM7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAKICAgIG5iZXJyb3JzID0gY3R4dC0+bmJlcnJvcnM7CiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICBpZiAoSVNfU0NIRU1BKG5vZGUsICJzY2hlbWEiKSkgewogICAgICAgIHNjaGVtYSA9IHhtbFNjaGVtYU5ld1NjaGVtYShjdHh0KTsKICAgICAgICBpZiAoc2NoZW1hID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7Cgl2YWwgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJ0YXJnZXROYW1lc3BhY2UiKTsKCWlmICh2YWwgIT0gTlVMTCkgewoJICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKCX0gZWxzZSB7CgkgICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSBOVUxMOwoJfQogICAgICAgIHNjaGVtYS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgICAgIHNjaGVtYS0+dmVyc2lvbiA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInZlcnNpb24iKTsKICAgICAgICB2YWwgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJlbGVtZW50Rm9ybURlZmF1bHQiKTsKICAgICAgICBpZiAodmFsICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInF1YWxpZmllZCIpKQogICAgICAgICAgICAgICAgc2NoZW1hLT5mbGFncyB8PSBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTTsKICAgICAgICAgICAgZWxzZSBpZiAoIXhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInVucXVhbGlmaWVkIikpIHsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfRUxFTUZPUk1ERUZBVUxUX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgdmFsdWUgJXMgZm9yIGVsZW1lbnRGb3JtRGVmYXVsdFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbCwgTlVMTCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewoJICAgIHNjaGVtYS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfUVVBTElGX0VMRU07Cgl9CiAgICAgICAgdmFsID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiYXR0cmlidXRlRm9ybURlZmF1bHQiKTsKICAgICAgICBpZiAodmFsICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInF1YWxpZmllZCIpKQogICAgICAgICAgICAgICAgc2NoZW1hLT5mbGFncyB8PSBYTUxfU0NIRU1BU19RVUFMSUZfQVRUUjsKICAgICAgICAgICAgZWxzZSBpZiAoIXhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInVucXVhbGlmaWVkIikpIHsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfQVRUUkZPUk1ERUZBVUxUX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgdmFsdWUgJXMgZm9yIGF0dHJpYnV0ZUZvcm1EZWZhdWx0XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsLCBOVUxMKTsKICAgICAgICAgICAgfQogICAgICAgIH0gCgogICAgICAgIHhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwoY3R4dCwgc2NoZW1hLCBub2RlLT5jaGlsZHJlbik7CiAgICB9IGVsc2UgewogICAgICAgIHhtbERvY1B0ciBkb2M7CgoJZG9jID0gbm9kZS0+ZG9jOwoKICAgICAgICBpZiAoKGRvYyAhPSBOVUxMKSAmJiAoZG9jLT5VUkwgIT0gTlVMTCkpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9UX1NDSEVNQSwKCQkgICAgICAiRmlsZSAlcyBpcyBub3QgYSBzY2hlbWFzIiwgZG9jLT5VUkwsIE5VTEwpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9UX1NDSEVNQSwKCQkgICAgICAiRmlsZSBpcyBub3QgYSBzY2hlbWFzIiwgTlVMTCwgTlVMTCk7Cgl9CglyZXR1cm4oTlVMTCk7CiAgICB9CiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkgewogICAgICAgIGlmIChzY2hlbWEgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFGcmVlKHNjaGVtYSk7CiAgICAgICAgICAgIHNjaGVtYSA9IE5VTEw7CiAgICAgICAgfQogICAgfQogICAgY3R4dC0+bmJlcnJvcnMgPSBuYmVycm9yczsKI2lmZGVmIERFQlVHCiAgICBpZiAoc2NoZW1hID09IE5VTEwpCiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFQYXJzZSgpIGZhaWxlZFxuIik7CiNlbmRpZgogICAgcmV0dXJuIChzY2hlbWEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJVmFsaWRhdGluZyB1c2luZyBTY2hlbWFzCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJUmVhZGluZy9Xcml0aW5nIFNjaGVtYXMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dDoKICogQFVSTDogIHRoZSBsb2NhdGlvbiBvZiB0aGUgc2NoZW1hCiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IGZpbGUvcmVzb3VyY2UgZXhwZWN0ZWQKICogdG8gY29udGFpbiBhbiBYTUwgU2NoZW1hcyBmaWxlLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dChjb25zdCBjaGFyICpVUkwpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmIChVUkwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoYW1hIHBhcnNlciBjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgcmV0LT5VUkwgPSB4bWxEaWN0TG9va3VwKHJldC0+ZGljdCwgKGNvbnN0IHhtbENoYXIgKikgVVJMLCAtMSk7CiAgICByZXQtPmluY2x1ZGVzID0gMDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld01lbVBhcnNlckN0eHQ6CiAqIEBidWZmZXI6ICBhIHBvaW50ZXIgdG8gYSBjaGFyIGFycmF5IGNvbnRhaW5pbmcgdGhlIHNjaGVtYXMKICogQHNpemU6ICB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgbWVtb3J5IGJ1ZmZlciBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdNZW1QYXJzZXJDdHh0KGNvbnN0IGNoYXIgKmJ1ZmZlciwgaW50IHNpemUpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmICgoYnVmZmVyID09IE5VTEwpIHx8IChzaXplIDw9IDApKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBzY2hhbWEgcGFyc2VyIGNvbnRleHQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICByZXQtPmJ1ZmZlciA9IGJ1ZmZlcjsKICAgIHJldC0+c2l6ZSA9IHNpemU7CiAgICByZXQtPmRpY3QgPSB4bWxEaWN0Q3JlYXRlKCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdEb2NQYXJzZXJDdHh0OgogKiBAZG9jOiAgYSBwcmVwYXJzZWQgZG9jdW1lbnQgdHJlZQogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgcGFyc2UgY29udGV4dCBmb3IgdGhhdCBkb2N1bWVudC4KICogTkIuIFRoZSBkb2N1bWVudCBtYXkgYmUgbW9kaWZpZWQgZHVyaW5nIHRoZSBwYXJzaW5nIHByb2Nlc3MuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdEb2NQYXJzZXJDdHh0KHhtbERvY1B0ciBkb2MpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmIChkb2MgPT0gTlVMTCkKICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBzY2hlbWEgcGFyc2VyIGNvbnRleHQiLAoJCQkgIE5VTEwpOwogICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIHJldC0+ZG9jID0gZG9jOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgLyogVGhlIGFwcGxpY2F0aW9uIGhhcyByZXNwb25zaWJpbGl0eSBmb3IgdGhlIGRvY3VtZW50ICovCiAgICByZXQtPnByZXNlcnZlID0gMTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZyZWUgdGhlIHJlc291cmNlcyBhc3NvY2lhdGVkIHRvIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChjdHh0LT5kb2MgIT0gTlVMTCAmJiAhY3R4dC0+cHJlc2VydmUpCiAgICAgICAgeG1sRnJlZURvYyhjdHh0LT5kb2MpOwogICAgeG1sRGljdEZyZWUoY3R4dC0+ZGljdCk7CiAgICB4bWxGcmVlKGN0eHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKgkJCUJ1aWxkaW5nIHRoZSBjb250ZW50IG1vZGVscwkJCSoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsOgogKiBAdHlwZTogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBlbGVtZW50IG5hbWUgd2hvc2UgY29udGVudCBpcyBiZWluZyBidWlsdAogKgogKiBHZW5lcmF0ZSB0aGUgYXV0b21hdGEgc2VxdWVuY2UgbmVlZGVkIGZvciB0aGF0IHR5cGUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiRm91bmQgdW5leHBlY3RlZCB0eXBlID0gTlVMTCBpbiAlcyBjb250ZW50IG1vZGVsXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBzd2l0Y2ggKHR5cGUtPnR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CiAgICAgICAgICAgIC8qIFRPRE8gOiBoYW5kbGUgdGhlIG5hbWVzcGFjZSB0b28gKi8KICAgICAgICAgICAgLyogVE9ETyA6IG1ha2UgdGhhdCBhIHNwZWNpZmljIHRyYW5zaXRpb24gdHlwZSAqLwogICAgICAgICAgICBUT0RPIGN0eHQtPnN0YXRlID0KICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQkFEX0NBU1QgIioiLCBOVUxMKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDp7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW0gPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgdHlwZTsKCiAgICAgICAgICAgICAgICAvKiBUT0RPIDogaGFuZGxlIHRoZSBuYW1lc3BhY2UgdG9vICovCiAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIG9sZHN0YXRlID0gY3R4dC0+c3RhdGU7CgogICAgICAgICAgICAgICAgaWYgKGVsZW0tPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbS0+bWluT2NjdXJzID4gMSkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CgogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSA9IGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5taW5PY2N1cnMgLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIFVOQk9VTkRFRCk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbS0+cmVmRGVjbCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+cmVmRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPnJlZkRlY2wtPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbihjdHh0LT5hbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPm5hbWUsIHR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgdG1wLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCB0bXAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0tPnJlZkRlY2wgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKCh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPnJlZkRlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5yZWZEZWNsLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24oY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5uYW1lLCB0eXBlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGJhc2ljYWxseSBhbiBlbGVtKiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChlbGVtLT5tYXhPY2N1cnMgPiAxKSB8fCAoZWxlbS0+bWluT2NjdXJzID4gMSkpIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKCiAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlID0gY3R4dC0+c3RhdGU7CgogICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5taW5PY2N1cnMgLSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bWF4T2NjdXJzIC0gMSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChlbGVtLT5yZWZEZWNsICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKCh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+cmVmRGVjbCwgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPnJlZkRlY2wtPm5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRtcCA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCB0bXAsIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMoY3R4dC0+YW0sIHRtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogYmFzaWNhbGx5IGFuIGVsZW0/ICovCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0tPnJlZkRlY2wgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5yZWZEZWNsLCBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+cmVmRGVjbC0+bmFtZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24oY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0tPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGJhc2ljYWxseSBhbiBlbGVtPyAqLwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6ewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlczsKCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogSWYgbWF4IGFuZCBtaW4gb2NjdXJhbmNlcyBhcmUgZGVmYXVsdCAoMSkgdGhlbgogICAgICAgICAgICAgICAgICogc2ltcGx5IGl0ZXJhdGUgb3ZlciB0aGUgc3VidHlwZXMKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKCh0eXBlLT5taW5PY2N1cnMgPT0gMSkgJiYgKHR5cGUtPm1heE9jY3VycyA9PSAxKSkgewogICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUtPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUtPm1pbk9jY3VycyA+IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgdG1wOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluT2NjdXJzIC0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVU5CT1VOREVEKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCB0bXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSwgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMoY3R4dC0+YW0sIHRtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBjb3VudGVyKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHR5cGUtPm1heE9jY3VycyA+IDEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAodHlwZS0+bWluT2NjdXJzID4gMSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciB0bXA7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwoKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bWluT2NjdXJzIC0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPm1heE9jY3VycyAtCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSk7CgogICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMoY3R4dC0+YW0sIHRtcCwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhjdHh0LT5hbSwgdG1wLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOnsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgc3VidHlwZXM7CiAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0LCBlbmQ7CgogICAgICAgICAgICAgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgIGVuZCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUoY3R4dC0+YW0pOwoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBpdGVyYXRlIG92ZXIgdGhlIHN1YnR5cGVzIGFuZCByZW1lcmdlIHRoZSBlbmQgd2l0aCBhbgogICAgICAgICAgICAgICAgICogZXBzaWxvbiB0cmFuc2l0aW9uCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICh0eXBlLT5tYXhPY2N1cnMgPT0gMSkgewogICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSBzdGFydDsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgaG9wOwogICAgICAgICAgICAgICAgICAgIGludCBtYXhPY2N1cnMgPSB0eXBlLT5tYXhPY2N1cnMgPT0gVU5CT1VOREVEID8KICAgICAgICAgICAgICAgICAgICAgICAgVU5CT1VOREVEIDogdHlwZS0+bWF4T2NjdXJzIC0gMTsKICAgICAgICAgICAgICAgICAgICBpbnQgbWluT2NjdXJzID0KICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bWluT2NjdXJzIDwgMSA/IDAgOiB0eXBlLT5taW5PY2N1cnMgLSAxOwoKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIHVzZSBhIGNvdW50ZXIgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIHRyYW5zdGlvbnMKICAgICAgICAgICAgICAgICAgICAgKiB3aGljaCB3ZW50IHRocm91Z2ggdGhlIGNob2ljZS4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBjb3VudGVyID0KICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyKGN0eHQtPmFtLCBtaW5PY2N1cnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhPY2N1cnMpOwogICAgICAgICAgICAgICAgICAgIGhvcCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUoY3R4dC0+YW0pOwoKICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0gc3RhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGhvcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCBob3AsIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCBob3AsIGVuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgc3RhcnQsIGVuZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IGVuZDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOnsKICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQ7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHN1YnR5cGVzOwoJCS8qIAoJCSAqIENoYW5nZWQsIHNpbmNlIHR5cGUgaW4gbm90IGFuIHhtbFNjaGVtYUVsZW1lbnQgaGVyZS4KCQkgKi8KICAgICAgICAgICAgICAgIC8qIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbSA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSB0eXBlOyAqLwoJCXhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbTsKICAgICAgICAgICAgICAgIGludCBsYXg7CgogICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgIGlmIChzdWJ0eXBlcyA9PSBOVUxMKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSBzdGFydDsKCQkgICAgLyoKCQkgICAgICogdGhlIGZvbGxvd2luZyAnaWYnIHdhcyBuZWVkZWQgdG8gZml4IGJ1ZyAxMzk4OTcKCQkgICAgICogbm90IHF1aXRlIHN1cmUgd2h5IGl0IG9ubHkgbmVlZHMgdG8gYmUgZG9uZSBmb3IKCQkgICAgICogZWxlbWVudHMgd2l0aCBhICdyZWYnLCBidXQgaXQgc2VlbXMgdG8gd29yayBvay4KCQkgICAgICovCgkJICAgIGlmIChzdWJ0eXBlcy0+cmVmICE9IE5VTEwpCgkJICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgIGVsZW0gPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgc3VidHlwZXM7CQkgICAgCiAgICAgICAgICAgICAgICAgICAgLyogVE9ETyA6IGhhbmRsZSB0aGUgbmFtZXNwYWNlIHRvbyAqLwogICAgICAgICAgICAgICAgICAgIGlmICgoZWxlbS0+bWluT2NjdXJzID09IDEpICYmIChlbGVtLT5tYXhPY2N1cnMgPT0gMSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdPbmNlVHJhbnMoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSwgZWxlbS0+bmFtZSwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgc3VidHlwZXMpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRUcmFucyhjdHh0LT5hbSwgY3R4dC0+c3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSwgZWxlbS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPm1pbk9jY3VycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPm1heE9jY3VycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxheCA9IHR5cGUtPm1pbk9jY3VycyA9PSAwOwogICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3QWxsVHJhbnMoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF4KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046CiAgICAgICAgICAgIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHR5cGUtPnN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOgogICAgICAgICAgICBpZiAodHlwZS0+YmFzZVR5cGUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlczsKCgkJaWYgKHR5cGUtPnJlY3Vyc2UpIHsgCgkJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwgCgkJICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9CQVNFX1RZUEUsIAoJCQkgICAgIlNjaGVtYXM6IGV4dGVuc2lvbiB0eXBlICVzIGlzIHJlY3Vyc2l2ZVxuIiwgCgkJCQkgIHR5cGUtPm5hbWUsIE5VTEwpOyAKCQkgICAgcmV0dXJuOyAKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHR5cGUtPnJlY3Vyc2UgPSAxOyAKICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCh0eXBlLT5iYXNlVHlwZSwgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgIAl0eXBlLT5yZWN1cnNlID0gMDsKICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHR5cGUtPnN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CiAgICAgICAgICAgIGlmICh0eXBlLT5zdWJ0eXBlcyA9PSBOVUxMKSB7CgkgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgcmdyb3VwOwoJCWlmICh0eXBlLT5yZWYgIT0gTlVMTCkgewoJCSAgICByZ3JvdXAgPSB4bWxTY2hlbWFHZXRHcm91cChjdHh0LT5zY2hlbWEsIHR5cGUtPnJlZiwKCQkgICAgCQkJICAgdHlwZS0+cmVmTnMpOwoJCSAgICBpZiAocmdyb3VwID09IE5VTEwpIHsKCQkgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQkJCSAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fUkVGLAoJCQkJIlNjaGVtYXM6IGdyb3VwICVzIHJlZmVyZW5jZSAlcyBpcyBub3QgZm91bmQiLAoJCQkJbmFtZSwgdHlwZS0+cmVmKTsKCQkJcmV0dXJuOwoJCSAgICB9CgkJICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChyZ3JvdXAsIGN0eHQsIG5hbWUpOwoJCSAgICBicmVhazsKCQl9CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVDoKICAgICAgICAgICAgaWYgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwodHlwZS0+c3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGb3VuZCB1bmV4cGVjdGVkIHR5cGUgJWQgaW4gJXMgY29udGVudCBtb2RlbFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPnR5cGUsIG5hbWUpOwogICAgICAgICAgICByZXR1cm47CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbDoKICogQGVsZW06ICB0aGUgZWxlbWVudAogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgZWxlbWVudCBuYW1lCiAqCiAqIEJ1aWxkcyB0aGUgY29udGVudCBtb2RlbCBvZiB0aGUgZWxlbWVudC4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsKHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydDsKCiAgICBpZiAoZWxlbS0+Y29udE1vZGVsICE9IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGVsZW0tPnN1YnR5cGVzID09IE5VTEwpIHsKICAgICAgICBlbGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9BTlk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKGVsZW0tPnN1YnR5cGVzLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKQogICAgICAgIHJldHVybjsKICAgIGlmICgoZWxlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQykgfHwKICAgICAgICAoZWxlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpKQogICAgICAgIHJldHVybjsKCiNpZmRlZiBERUJVR19DT05URU5UCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAiQnVpbGRpbmcgY29udGVudCBtb2RlbCBmb3IgJXNcbiIsIG5hbWUpOwojZW5kaWYKCiAgICBjdHh0LT5hbSA9IHhtbE5ld0F1dG9tYXRhKCk7CiAgICBpZiAoY3R4dC0+YW0gPT0gTlVMTCkgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IGNyZWF0ZSBhdXRvbWF0YSBmb3IgZWxlbSAlc1xuIiwgbmFtZSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgc3RhcnQgPSBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhR2V0SW5pdFN0YXRlKGN0eHQtPmFtKTsKICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChlbGVtLT5zdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICB4bWxBdXRvbWF0YVNldEZpbmFsU3RhdGUoY3R4dC0+YW0sIGN0eHQtPnN0YXRlKTsKICAgIGVsZW0tPmNvbnRNb2RlbCA9IHhtbEF1dG9tYXRhQ29tcGlsZShjdHh0LT5hbSk7CiAgICBpZiAoZWxlbS0+Y29udE1vZGVsID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGVsZW0tPm5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKICAgICAgICAgICAgICAgICAgICAgICJmYWlsZWQgdG8gY29tcGlsZSAlcyBjb250ZW50IG1vZGVsXG4iLCBuYW1lLCBOVUxMKTsKICAgIH0gZWxzZSBpZiAoeG1sUmVnZXhwSXNEZXRlcm1pbmlzdChlbGVtLT5jb250TW9kZWwpICE9IDEpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGVsZW0tPm5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9OT1RERVRFUk1JTklTVCwKICAgICAgICAgICAgICAgICAgICAgICJDb250ZW50IG1vZGVsIG9mICVzIGlzIG5vdCBkZXRlcm1pbmlzdDpcbiIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0gZWxzZSB7CiNpZmRlZiBERUJVR19DT05URU5UX1JFR0VYUAogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiQ29udGVudCBtb2RlbCBvZiAlczpcbiIsIG5hbWUpOwogICAgICAgIHhtbFJlZ2V4cFByaW50KHN0ZGVyciwgZWxlbS0+Y29udE1vZGVsKTsKI2VuZGlmCiAgICB9CiAgICBjdHh0LT5zdGF0ZSA9IE5VTEw7CiAgICB4bWxGcmVlQXV0b21hdGEoY3R4dC0+YW0pOwogICAgY3R4dC0+YW0gPSBOVUxMOwp9CgovKioKICogeG1sU2NoZW1hUmVmRml4dXBDYWxsYmFjazoKICogQGVsZW06ICB0aGUgc2NoZW1hIGVsZW1lbnQgY29udGV4dAogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogRnJlZSB0aGUgcmVzb3VyY2VzIGFzc29jaWF0ZWQgdG8gdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUmVmRml4dXBDYWxsYmFjayh4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBjb250ZXh0IEFUVFJJQlVURV9VTlVTRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGVsZW0gPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChlbGVtLT5yZWYgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2w7CgogICAgICAgIGlmIChlbGVtLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgZWxlbS0+bm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9JTlZBTElEX1JFRl9BTkRfU1VCVFlQRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAiU2NoZW1hczogZWxlbWVudCAlcyBoYXMgYm90aCByZWYgYW5kIHN1YnR5cGVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgZWxlbURlY2wgPSB4bWxTY2hlbWFHZXRFbGVtKGN0eHQtPnNjaGVtYSwgZWxlbS0+cmVmLCBlbGVtLT5yZWZOcywgMCk7CgogICAgICAgIGlmIChlbGVtRGVjbCA9PSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgZWxlbS0+bm9kZSwgWE1MX1NDSEVNQVBfVU5LTk9XTl9SRUYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IGVsZW1lbnQgJXMgcmVmIHRvICVzIG5vdCBmb3VuZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBlbGVtLT5yZWYpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGVsZW0tPnJlZkRlY2wgPSBlbGVtRGVjbDsKICAgIH0gZWxzZSBpZiAoZWxlbS0+bmFtZWRUeXBlICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsOwoKICAgICAgICBpZiAoZWxlbS0+c3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGVsZW0tPm5vZGUsIFhNTF9TQ0hFTUFQX1RZUEVfQU5EX1NVQlRZUEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IGVsZW1lbnQgJXMgaGFzIGJvdGggdHlwZSBhbmQgc3VidHlwZVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICB0eXBlRGVjbCA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCBlbGVtLT5uYW1lZFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPm5hbWVkVHlwZU5zKTsKCiAgICAgICAgaWYgKHR5cGVEZWNsID09IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBlbGVtLT5ub2RlLCBYTUxfU0NIRU1BUF9VTktOT1dOX1RZUEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IGVsZW1lbnQgJXMgdHlwZSAlcyBub3QgZm91bmRcbiIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bmFtZWRUeXBlKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBlbGVtLT5zdWJ0eXBlcyA9IHR5cGVEZWNsOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hUGFyc2VMaXN0UmVmRml4dXA6CiAqIEB0eXBlOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZpeHVwIG9mIHRoZSBpdGVtVHlwZSByZWZlcmVuY2Ugb2YgdGhlIGxpc3QgdHlwZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBhcnNlTGlzdFJlZkZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICBjb25zdCB4bWxDaGFyICppdGVtVHlwZSwgKm5hbWVzcGFjZTsKICAgIHhtbFNjaGVtYVR5cGVQdHIgc3VidHlwZTsKICAgIAogICAgLyogSGFuZGxlIHRoZSAiaXRlbVR5cGUiIGF0dHJpYnV0ZS4gKi8KICAgIGl0ZW1UeXBlID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIHR5cGUtPm5vZGUsICJpdGVtVHlwZSIsICZuYW1lc3BhY2UpOwogICAgaWYgKGl0ZW1UeXBlICE9IE5VTEwpIHsKICAgICAgICAvKiBEbyBub3QgYWxsb3cgbW9yZSB0aGF0IG9uZSBpdGVtIHR5cGUuICovCiAgICAgICAgaWYgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJICAgIAkJICBYTUxfU0NIRU1BUF9TVVBFUk5VTUVST1VTX0xJU1RfSVRFTV9UWVBFLAogICAgICAgICAgICAgICAgICAgICAgICAgICJMaXN0ICVzIGhhcyBtb3JlIHRoYW4gb25lIGl0ZW0gdHlwZSBkZWZpbmVkXG4iLAoJCQkgIHR5cGUtPm5hbWUsIE5VTEwpOwogICAgICAgIH0KICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGl0ZW1UeXBlLCBuYW1lc3BhY2UpOwogICAgICAgIGlmIChzdWJ0eXBlID09IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9VTktOT1dOX1RZUEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkxpc3QgJXMgcmVmZXJlbmNlcyBhbiB1bmtub3duIGl0ZW0gdHlwZTogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bmFtZSwgeG1sU2NoZW1hR2V0UHJvcChjdHh0LCB0eXBlLT5ub2RlLAoJCQkgICJpdGVtVHlwZSIpKTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hUGFyc2VVbmlvblJlZkNoZWNrOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogQ2hlY2tzIHRoZSBtZW1iZXJUeXBlcyByZWZlcmVuY2VzIG9mIHRoZSB1bmlvbiB0eXBlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUGFyc2VVbmlvblJlZkNoZWNrKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgY29uc3QgeG1sQ2hhciAqY3VyLCAqZW5kLCAqcHJlZml4LCAqbmNOYW1lLCAqbmFtZXNwYWNlOwogICAgeG1sQ2hhciAqdG1wOwogICAgeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlOwogICAgeG1sTnNQdHIgbnM7CiAgICBpbnQgbGVuOwoKICAgICBpZiAoKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1VOSU9OKSB8fCAodHlwZS0+cmVmID09IE5VTEwpKQogICAgICAgIHJldHVybjsKCiAgICBjdXIgPSB0eXBlLT5yZWY7CiAgICBkbyB7CiAgICAgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgICAgICBjdXIrKzsKICAgICAgICBlbmQgPSBjdXI7CiAgICAgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCiAgICAgICAgICAgIGVuZCsrOwogICAgICAgIGlmIChlbmQgPT0gY3VyKQogICAgICAgICAgICBicmVhazsKICAgICAgICB0bXAgPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKICAgICAgICBuY05hbWUgPSB4bWxTcGxpdFFOYW1lMyh0bXAsICZsZW4pOwogICAgICAgIGlmIChuY05hbWUgIT0gTlVMTCkgewogICAgICAgICAgICBwcmVmaXggPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHRtcCwgbGVuKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcmVmaXggPSBOVUxMOwogICAgICAgICAgICBuY05hbWUgPSB0bXA7CiAgICAgICAgfQogICAgICAgIG5zID0geG1sU2VhcmNoTnModHlwZS0+bm9kZS0+ZG9jLCB0eXBlLT5ub2RlLCBwcmVmaXgpOwogICAgICAgIGlmIChucyA9PSBOVUxMKSB7CiAgICAgICAgICAgIGlmIChwcmVmaXggIT0gTlVMTCkgewogICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9QUkVGSVhfVU5ERUZJTkVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pb24gJXM6IHRoZSBuYW1lc3BhY2UgcHJlZml4IG9mIG1lbWJlciB0eXBlICIKCQkJICAgICAgIiVzIGlzIHVuZGVmaW5lZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bmFtZSwgKGNvbnN0IHhtbENoYXIgKikgdG1wKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBuYW1lc3BhY2UgPSBOVUxMOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG5hbWVzcGFjZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbnMtPmhyZWYsIC0xKTsKICAgICAgICB9CiAgICAgICAgLyogTG9va3VwIHRoZSByZWZlcmVuY2VkIHR5cGUgKi8KICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIG5jTmFtZSwgbmFtZXNwYWNlKTsKICAgICAgICBpZiAoc3VidHlwZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwgWE1MX1NDSEVNQVBfVU5LTk9XTl9NRU1CRVJfVFlQRSwKICAgICAgICAgICAgICAgICAgICAgICAiVW5pb24gJXMgcmVmZXJlbmNlcyBhbiB1bmtub3duIG1lbWJlciB0eXBlICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPm5hbWUsICAoY29uc3QgeG1sQ2hhciAqKSB0bXApOwogICAgICAgIH0gCiAgICAgICAgeG1sRnJlZSh0bXApOwogICAgICAgIGN1ciA9IGVuZDsKICAgIH0gd2hpbGUgKCpjdXIgIT0gMCk7ICAgIAp9CgovKioKICogeG1sU2NoZW1hR2V0T255bW91c1R5cGVOYW1lOgogKiBAYXR0cjogIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24vdXNlCiAqCiAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZTsgaWYgdGhlIGF0dHJpYnV0ZQogKiBpcyBhIHJlZmVyZW5jZSwgdGhlIG5hbWUgb2YgdGhlIHJlZmVyZW5jZWQgZ2xvYmFsIHR5cGUgd2lsbCBiZSByZXR1cm5lZC4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyKSAKewogICAgaWYgKGF0dHItPnJlZiAhPSBOVUxMKSAKCXJldHVybihhdHRyLT5yZWYpOwogICAgZWxzZQoJcmV0dXJuKGF0dHItPm5hbWUpOwkKfQoKLyoqCiAqIHhtbFNjaGVtYUdldE9ueW1vdXNUYXJnZXROc1VSSToKICogQHR5cGU6ICB0aGUgdHlwZSAoZWxlbWVudCBvciBhdHRyaWJ1dGUpCiAqCiAqIFJldHVybnMgdGhlIHRhcmdldCBuYW1lc3BhY2UgVVJJIG9mIHRoZSB0eXBlOyBpZiB0aGUgdHlwZSBpcyBhIHJlZmVyZW5jZSwKICogdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIHJlZmVyZW5jZWQgdHlwZSB3aWxsIGJlIHJldHVybmVkLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRPbnltb3VzVGFyZ2V0TnNVUkkoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVCkgewoJaWYgKHR5cGUtPnJlZiAhPSBOVUxMKQoJICAgIHJldHVybigoKHhtbFNjaGVtYUVsZW1lbnRQdHIpKCh4bWxTY2hlbWFFbGVtZW50UHRyKSAKCQl0eXBlKS0+c3VidHlwZXMpLT50YXJnZXROYW1lc3BhY2UpOwoJZWxzZQoJICAgIHJldHVybigoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHR5cGUpLT50YXJnZXROYW1lc3BhY2UpOwogICAgfSBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEUpIHsKCWlmICh0eXBlLT5yZWYgIT0gTlVMTCkKCSAgICByZXR1cm4oKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIAoJCXR5cGUpLT5zdWJ0eXBlcyktPnRhcmdldE5hbWVzcGFjZSk7CgllbHNlCgkgICAgcmV0dXJuKCgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSB0eXBlKS0+dGFyZ2V0TmFtZXNwYWNlKTsKICAgIH0gZWxzZSAKCXJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGU6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGRlZmluaXRpb24KICogQHZhbFR5cGU6IHRoZSB2YWx1ZSB0eXBlCiAqIAogKgogKiBSZXR1cm5zIDEgaWYgdGhlIHR5cGUgaGFzIHRoZSBnaXZlbiB2YWx1ZSB0eXBlLCBvcgogKiBpcyBkZXJpdmVkIGZyb20gc3VjaCBhIHR5cGUuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGludCB2YWxUeXBlKQp7CiAgICAvKiBUT0RPOiBDaGVjayBpZiB0aGlzIHdvcmtzIGluIGV2ZXJ5IGNhc2UuICovCglpZiAoKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJgoJCSh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpKSB7CgkJaWYgKHR5cGUtPmZsYWdzID09IHZhbFR5cGUpCgkJCXJldHVybigxKTsKICAgIH0gZWxzZSBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFKSB7CglpZiAoKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIHR5cGUpLT5zdWJ0eXBlcyAhPSBOVUxMKSAKCSAgICByZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKGN0eHQsIAoJCSgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSB0eXBlKS0+c3VidHlwZXMsIHZhbFR5cGUpKTsKICAgIH0gZWxzZSBpZiAoKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OKSB8fAoJKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTikpIHsKCWlmICh0eXBlLT5iYXNlVHlwZSAhPSBOVUxMKSAKCSAgICByZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKGN0eHQsIHR5cGUtPmJhc2VUeXBlLCAKCQl2YWxUeXBlKSk7CiAgICB9IGVsc2UgaWYgKCh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJgoJKCh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgfHwKCSAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkgfHwKCSAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgfHwKCSAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSkpIHsKCXJldHVybih4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoY3R4dCwgdHlwZS0+c3VidHlwZXMsIAoJICAgIHZhbFR5cGUpKTsKICAgIH0KCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKiBAY3VyOiB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIGxpc3QKICogQGxhc3RVc2U6IHRoZSB0b3Agb2YgdGhlIGF0dHJpYnV0ZSB1c2UgbGlzdAogKgogKiBCdWlsZHMgdGhlIGF0dHJpYnV0ZSB1c2VzIGxpc3Qgb24gdGhlIGdpdmVuIGNvbXBsZXggdHlwZS4KICogVGhpcyBvbmUgaXMgc3VwcG9zZWQgdG8gYmUgY2FsbGVkIGJ5IAogKiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24gb25seS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJCSB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgY3VyLAoJCQkJIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgKnVzZXMsCgkJCQkgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciAqbGFzdFVzZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciB0bXA7CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCWlmIChjdXItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSB7CgkgICAgLyogCgkgICAgICogVzNDOiAiMiBUaGUge2F0dHJpYnV0ZSB1c2VzfSBvZiB0aGUgYXR0cmlidXRlIGdyb3VwcyC3cmVzb2x2ZWS3IAoJICAgICAqIHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVlt3Mgb2YgdGhlIHJlZiBbYXR0cmlidXRlXSBvZiB0aGUgCgkgICAgICogPGF0dHJpYnV0ZUdyb3VwPiBbY2hpbGRyZW5dLCBpZiBhbnkuIgoJICAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVVzZXNPd25lZChjdHh0LCAKCQkoKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBjdXIpLT5hdHRyaWJ1dGVzLCB1c2VzLCAKCQlsYXN0VXNlKSA9PSAtMSkgewoJCXJldHVybiAoLTEpOwkgICAgCgkgICAgfQoJfSBlbHNlIHsKCSAgICAvKiBXM0M6ICIxIFRoZSBzZXQgb2YgYXR0cmlidXRlIHVzZXMgY29ycmVzcG9uZGluZyB0byB0aGUgCgkgICAgICogPGF0dHJpYnV0ZT4gW2NoaWxkcmVuXSwgaWYgYW55LiIKCSAgICAgKi8JICAgIAkgICAgCgkgICAgdG1wID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIpIAoJCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlTGluaykpOwoJICAgIGlmICh0bXAgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImJ1aWxkaW5nIGF0dHJpYnV0ZSB1c2VzIiwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIHRtcC0+YXR0ciA9IGN1cjsKCSAgICB0bXAtPm5leHQgPSBOVUxMOwoJICAgIGlmICgqdXNlcyA9PSBOVUxMKQoJCSp1c2VzID0gdG1wOwkJICAgIAoJICAgIGVsc2UgCgkJKCpsYXN0VXNlKS0+bmV4dCA9IHRtcDsKCSAgICAqbGFzdFVzZSA9IHRtcDsJICAgIAoJfQkKCWN1ciA9IGN1ci0+bmV4dDsKICAgIH0JCiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciAqZGVzdCwKCQkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBzb3VyY2UpCQkJCSAgICAKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIHRtcCwgbGFzdDsKCiAgICBpZiAoKHNvdXJjZSA9PSBOVUxMKSB8fCAoKmRlc3QgPT0gTlVMTCkpCglyZXR1cm4oLTEpOyAgICAKICAgICgqZGVzdCktPmFueSA9IHNvdXJjZS0+YW55OwogICAgY3VyID0gc291cmNlLT5uc1NldDsKICAgIGxhc3QgPSBOVUxMOwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7Cgl0bXAgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCWlmICh0bXAgPT0gTlVMTCkKCSAgICByZXR1cm4oLTEpOwoJdG1wLT52YWx1ZSA9IGN1ci0+dmFsdWU7CglpZiAobGFzdCA9PSBOVUxMKQoJICAgICgqZGVzdCktPm5zU2V0ID0gdG1wOwoJZWxzZSAKCSAgICBsYXN0LT5uZXh0ID0gdG1wOwoJbGFzdCA9IHRtcDsKCWN1ciA9IGN1ci0+bmV4dDsKICAgIH0gICAgCiAgICBpZiAoKCpkZXN0KS0+bmVnTnNTZXQgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KCgqZGVzdCktPm5lZ05zU2V0KTsJICAgCiAgICBpZiAoc291cmNlLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkoKmRlc3QpLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKCgqZGVzdCktPm5lZ05zU2V0ID09IE5VTEwpCgkgICAgcmV0dXJuKC0xKTsKCSgqZGVzdCktPm5lZ05zU2V0LT52YWx1ZSA9IHNvdXJjZS0+bmVnTnNTZXQtPnZhbHVlOwkgICAgCiAgICB9IGVsc2UKCSgqZGVzdCktPm5lZ05zU2V0ID0gTlVMTDsKICAgIHJldHVybigwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFVbmlvbldpbGRjYXJkcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAkJCSAgICAKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGNvbXBsZXRlV2lsZCwKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGN1cldpbGQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCBjdXJCLCB0bXA7CgogICAgLyoKICAgICogMSBJZiBPMSBhbmQgTzIgYXJlIHRoZSBzYW1lIHZhbHVlLCB0aGVuIHRoYXQgdmFsdWUgbXVzdCBiZSB0aGUgCiAgICAqIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5hbnkgPT0gY3VyV2lsZC0+YW55KSAmJgoJKChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uc1NldCA9PSBOVUxMKSkgJiYKCSgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkpKSB7CgkKCWlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB8fAoJICAgIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpKSB7CgkgICAgCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCWludCBmb3VuZCA9IDA7CgkJCgkJLyogCgkJKiBDaGVjayBlcXVhbGl0eSBvZiBzZXRzLiAKCQkqLwoJCWN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJICAgIGZvdW5kID0gMDsKCQkgICAgY3VyQiA9IGN1cldpbGQtPm5zU2V0OwoJCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJCWlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJCSAgICBmb3VuZCA9IDE7CgkJCSAgICBicmVhazsKCQkJfQoJCQljdXJCID0gY3VyQi0+bmV4dDsKCQkgICAgfQoJCSAgICBpZiAoIWZvdW5kKQoJCQlicmVhazsKCQkgICAgY3VyID0gY3VyLT5uZXh0OwoJCX0KCQlpZiAoZm91bmQpCgkJICAgIHJldHVybigwKTsKCSAgICB9IGVsc2UKCQlyZXR1cm4oMCk7Cgl9CiAgICB9CSAgICAgICAgCiAgICAvKgogICAgKiAyIElmIGVpdGhlciBPMSBvciBPMiBpcyBhbnksIHRoZW4gYW55IG11c3QgYmUgdGhlIHZhbHVlCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSAhPSBjdXJXaWxkLT5hbnkpICYmIChjb21wbGV0ZVdpbGQtPmFueSkpIHsJCglpZiAoY29tcGxldGVXaWxkLT5hbnkgPT0gMCkgewoJICAgIGNvbXBsZXRlV2lsZC0+YW55ID0gMTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQl4bWxGcmVlKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAqIDMgSWYgYm90aCBPMSBhbmQgTzIgYXJlIHNldHMgb2YgKG5hbWVzcGFjZSBuYW1lcyBvciC3YWJzZW50tyksIAogICAgKiB0aGVuIHRoZSB1bmlvbiBvZiB0aG9zZSBzZXRzIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHsJCQoJaW50IGZvdW5kOwoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBzdGFydDsKCQoJY3VyID0gY3VyV2lsZC0+bnNTZXQ7CglzdGFydCA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBmb3VuZCA9IDA7CgkgICAgY3VyQiA9IHN0YXJ0OwoJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCSAgICBmb3VuZCA9IDE7CgkJICAgIGJyZWFrOwoJCX0KCQljdXJCID0gY3VyQi0+bmV4dDsKCSAgICB9CgkgICAgaWYgKCFmb3VuZCkgewoJCXRtcCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmICh0bXAgPT0gTlVMTCkgCgkJICAgIHJldHVybiAoLTEpOwoJCXRtcC0+dmFsdWUgPSBjdXItPnZhbHVlOwoJCXRtcC0+bmV4dCA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CQkgICAgCQkgICAgCgkJY29tcGxldGVXaWxkLT5uc1NldCA9IHRtcDsKCSAgICB9CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQkKCQkgICAgCQkKCXJldHVybigwKTsKICAgIH0gICAgCiAgICAvKgogICAgKiA0IElmIHRoZSB0d28gYXJlIG5lZ2F0aW9ucyBvZiBkaWZmZXJlbnQgdmFsdWVzIChuYW1lc3BhY2UgbmFtZXMgCiAgICAqIG9yILdhYnNlbnS3KSwgdGhlbiBhIHBhaXIgb2Ygbm90IGFuZCC3YWJzZW50tyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpKSB7Cgljb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7CiAgICB9CiAgICAvKiAKICAgICAqIDUuCiAgICAgKi8KICAgIGlmICgoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCglpbnQgbnNGb3VuZCwgYWJzZW50Rm91bmQgPSAwOwoJCglpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCSAgICBjdXJCID0gY3VyV2lsZC0+bmVnTnNTZXQ7Cgl9IGVsc2UgewoJICAgIGN1ciA9IGN1cldpbGQtPm5zU2V0OwoJICAgIGN1ckIgPSBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0OwoJfQoJbnNGb3VuZCA9IDA7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBOVUxMKSAKCQlhYnNlbnRGb3VuZCA9IDE7CgkgICAgZWxzZSBpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkKCQluc0ZvdW5kID0gMTsKCSAgICBpZiAobnNGb3VuZCAmJiBhYnNlbnRGb3VuZCkKCQlicmVhazsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CQoKCWlmIChuc0ZvdW5kICYmIGFic2VudEZvdW5kKSB7CgkgICAgLyoKCSAgICAqIDUuMSBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgYm90aCB0aGUgbmVnYXRlZCBuYW1lc3BhY2UgCgkgICAgKiBuYW1lIGFuZCC3YWJzZW50tywgdGhlbiBhbnkgbXVzdCBiZSB0aGUgdmFsdWUuCgkgICAgKi8gICAgCgkgICAgY29tcGxldGVXaWxkLT5hbnkgPSAxOwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCSAgICB9CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCXhtbEZyZWUoY29tcGxldGVXaWxkLT5uZWdOc1NldCk7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IE5VTEw7CgkgICAgfQoJfSBlbHNlIGlmIChuc0ZvdW5kICYmICghYWJzZW50Rm91bmQpKSB7CgkgICAgLyogCgkgICAgKiA1LjIgSWYgdGhlIHNldCBTIGluY2x1ZGVzIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSBuYW1lIAoJICAgICogYnV0IG5vdCC3YWJzZW50tywgdGhlbiBhIHBhaXIgb2Ygbm90IGFuZCC3YWJzZW50tyBtdXN0IAoJICAgICogYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpCgkJICAgIHJldHVybiAoLTEpOwoJICAgIH0KCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7Cgl9IGVsc2UgaWYgKCghbnNGb3VuZCkgJiYgYWJzZW50Rm91bmQpIHsKCSAgICAvKgoJICAgICogNS4zIElmIHRoZSBzZXQgUyBpbmNsdWRlcyC3YWJzZW50tyBidXQgbm90IHRoZSBuZWdhdGVkIAoJICAgICogbmFtZXNwYWNlIG5hbWUsIHRoZW4gdGhlIHVuaW9uIGlzIG5vdCBleHByZXNzaWJsZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY29tcGxldGVXaWxkLT5ub2RlLCAKCQlYTUxfU0NIRU1BUF9VTklPTl9OT1RfRVhQUkVTU0lCTEUsCgkJIlRoZSB1bmlvbiBvZiB0aGUgd2lsY2FyZCBpcyBub3QgZXhwcmVzc2libGVcbiIsCgkJTlVMTCwgTlVMTCk7CQoJcmV0dXJuKDApOwoJfSBlbHNlIGlmICgoIW5zRm91bmQpICYmICghYWJzZW50Rm91bmQpKSB7CgkgICAgLyogCgkgICAgKiA1LjQgSWYgdGhlIHNldCBTIGRvZXMgbm90IGluY2x1ZGUgZWl0aGVyIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSAKCSAgICAqIG5hbWUgb3Igt2Fic2VudLcsIHRoZW4gd2hpY2hldmVyIG9mIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QgCgkgICAgKiBhbmQgYSBuYW1lc3BhY2UgbmFtZSBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCQlpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCQl9CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpCgkJICAgIHJldHVybiAoLTEpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICAvKiAKICAgICAqIDYuCiAgICAgKi8KICAgIGlmICgoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCglpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCX0gZWxzZSB7CgkgICAgY3VyID0gY3VyV2lsZC0+bnNTZXQ7Cgl9CQoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkgewoJCS8qCgkJKiA2LjEgSWYgdGhlIHNldCBTIGluY2x1ZGVzILdhYnNlbnS3LCB0aGVuIGFueSBtdXN0IGJlIHRoZSAKCQkqIHZhbHVlLgoJCSovCgkJY29tcGxldGVXaWxkLT5hbnkgPSAxOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJCX0KCQlpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbEZyZWUoY29tcGxldGVXaWxkLT5uZWdOc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJCX0KCQlyZXR1cm4gKDApOwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CQkJCglpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIDYuMiBJZiB0aGUgc2V0IFMgZG9lcyBub3QgaW5jbHVkZSC3YWJzZW50tywgdGhlbiBhIHBhaXIgb2Ygbm90IAoJICAgICogYW5kILdhYnNlbnS3IG11c3QgYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQlyZXR1cm4gKC0xKTsKCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7Cgl9CglyZXR1cm4gKDApOwogICAgfQogICAgcmV0dXJuICgwKTsKCn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hSW50ZXJzZWN0V2lsZGNhcmRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCQkJICAgIAoJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgY29tcGxldGVXaWxkLAoJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgY3VyV2lsZCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIGN1ckIsIHByZXYsICB0bXA7CgogICAgLyoKICAgICogMSBJZiBPMSBhbmQgTzIgYXJlIHRoZSBzYW1lIHZhbHVlLCB0aGVuIHRoYXQgdmFsdWUgbXVzdCBiZSB0aGUgCiAgICAqIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5hbnkgPT0gY3VyV2lsZC0+YW55KSAmJgoJKChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uc1NldCA9PSBOVUxMKSkgJiYKCSgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkpKSB7CgkKCWlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB8fAoJICAgIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpKSB7CgkgICAgCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCWludCBmb3VuZCA9IDA7CgkJCgkJLyogCgkJKiBDaGVjayBlcXVhbGl0eSBvZiBzZXRzLiAKCQkqLwoJCWN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJICAgIGZvdW5kID0gMDsKCQkgICAgY3VyQiA9IGN1cldpbGQtPm5zU2V0OwoJCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJCWlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJCSAgICBmb3VuZCA9IDE7CgkJCSAgICBicmVhazsKCQkJfQoJCQljdXJCID0gY3VyQi0+bmV4dDsKCQkgICAgfQoJCSAgICBpZiAoIWZvdW5kKQoJCQlicmVhazsKCQkgICAgY3VyID0gY3VyLT5uZXh0OwoJCX0KCQlpZiAoZm91bmQpCgkJICAgIHJldHVybigwKTsKCSAgICB9IGVsc2UKCQlyZXR1cm4oMCk7Cgl9CiAgICB9CSAgICAgICAgCiAgICAvKgogICAgKiAyIElmIGVpdGhlciBPMSBvciBPMiBpcyBhbnksIHRoZW4gdGhlIG90aGVyIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5hbnkgIT0gY3VyV2lsZC0+YW55KSAmJiAoY29tcGxldGVXaWxkLT5hbnkpKSB7CQkgICAgCglpZiAoeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoY3R4dCwgJmNvbXBsZXRlV2lsZCwgY3VyV2lsZCkgPT0gLTEpCgkgICAgcmV0dXJuKC0xKTsJICAgIAoJcmV0dXJuKDApOwogICAgfQkgICAgICAgICAgICAKICAgIC8qCiAgICAqIDMgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QgYW5kIGEgdmFsdWUgKGEgbmFtZXNwYWNlIAogICAgKiBuYW1lIG9yILdhYnNlbnS3KSBhbmQgdGhlIG90aGVyIGlzIGEgc2V0IG9mIChuYW1lc3BhY2UgbmFtZXMgb3IgCiAgICAqILdhYnNlbnS3KSwgdGhlbiB0aGF0IHNldCwgbWludXMgdGhlIG5lZ2F0ZWQgdmFsdWUgaWYgaXQgd2FzIGluIAogICAgKiB0aGUgc2V0LCBtaW51cyC3YWJzZW50tyBpZiBpdCB3YXMgaW4gdGhlIHNldCwgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHx8CgkoKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoJY29uc3QgeG1sQ2hhciAqbmVnOwoJCglpZiAoY29tcGxldGVXaWxkLT5uc1NldCA9PSBOVUxMKSB7CgkgICAgbmVnID0gY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWU7CgkgICAgaWYgKHhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKGN0eHQsICZjb21wbGV0ZVdpbGQsIGN1cldpbGQpID09IC0xKQoJCXJldHVybigtMSk7Cgl9IGVsc2UKCSAgICBuZWcgPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWU7CgkvKgoJKiBSZW1vdmUgYWJzZW50IGFuZCBuZWdhdGVkLgoJKi8KCXByZXYgPSBOVUxMOwoJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmIChjdXItPnZhbHVlID09IE5VTEwpIHsKCQlpZiAocHJldiA9PSBOVUxMKSAKCQkgICAgY29tcGxldGVXaWxkLT5uc1NldCA9IGN1ci0+bmV4dDsKCQllbHNlIAoJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCXhtbEZyZWUoY3VyKTsKCQlicmVhazsKCSAgICB9CgkgICAgcHJldiA9IGN1cjsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CglpZiAobmVnICE9IE5VTEwpIHsKCSAgICBwcmV2ID0gTlVMTDsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJCWlmIChjdXItPnZhbHVlID09IG5lZykgewoJCSAgICBpZiAocHJldiA9PSBOVUxMKSAKCQkJY29tcGxldGVXaWxkLT5uc1NldCA9IGN1ci0+bmV4dDsKCQkgICAgZWxzZSAKCQkJcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQkgICAgeG1sRnJlZShjdXIpOwoJCSAgICBicmVhazsKCQl9CgkJcHJldiA9IGN1cjsKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfQoJfQoKCXJldHVybigwKTsKICAgIH0JICAgICAgICAKICAgIC8qCiAgICAqIDQgSWYgYm90aCBPMSBhbmQgTzIgYXJlIHNldHMgb2YgKG5hbWVzcGFjZSBuYW1lcyBvciC3YWJzZW50tyksIAogICAgKiB0aGVuIHRoZSBpbnRlcnNlY3Rpb24gb2YgdGhvc2Ugc2V0cyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB7CQkKCWludCBmb3VuZDsKCQoJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCXByZXYgPSBOVUxMOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgZm91bmQgPSAwOwoJICAgIGN1ckIgPSBjdXJXaWxkLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkgICAgZm91bmQgPSAxOwoJCSAgICBicmVhazsKCQl9CgkJY3VyQiA9IGN1ckItPm5leHQ7CgkgICAgfQoJICAgIGlmICghZm91bmQpIHsKCQlpZiAocHJldiA9PSBOVUxMKQoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCWVsc2UgCgkJICAgIHByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJdG1wID0gY3VyLT5uZXh0OwoJCXhtbEZyZWUoY3VyKTsKCQljdXIgPSB0bXA7CQkKCQljb250aW51ZTsKCSAgICB9CgkgICAgcHJldiA9IGN1cjsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CQoJCSAgICAJCQoJcmV0dXJuKDApOwogICAgfSAgICAKICAgIC8qIDUgSWYgdGhlIHR3byBhcmUgbmVnYXRpb25zIG9mIGRpZmZlcmVudCBuYW1lc3BhY2UgbmFtZXMsIAogICAgKiB0aGVuIHRoZSBpbnRlcnNlY3Rpb24gaXMgbm90IGV4cHJlc3NpYmxlCiAgICAqLwkgICAgCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpKSB7CgoJeG1sU2NoZW1hUEVycihjdHh0LCBjb21wbGV0ZVdpbGQtPm5vZGUsIFhNTF9TQ0hFTUFQX0lOVEVSU0VDVElPTl9OT1RfRVhQUkVTU0lCTEUsCgkgICAgIlRoZSBpbnRlcnNlY3Rpb24gb2YgdGhlIHdpbGNhcmQgaXMgbm90IGV4cHJlc3NpYmxlXG4iLAoJICAgIE5VTEwsIE5VTEwpOwkKCXJldHVybigwKTsKICAgIH0JCSAgICAKICAgIC8qIAogICAgKiA2IElmIHRoZSBvbmUgaXMgYSBuZWdhdGlvbiBvZiBhIG5hbWVzcGFjZSBuYW1lIGFuZCB0aGUgb3RoZXIgCiAgICAqIGlzIGEgbmVnYXRpb24gb2Ygt2Fic2VudLcsIHRoZW4gdGhlIG9uZSB3aGljaCBpcyB0aGUgbmVnYXRpb24gCiAgICAqIG9mIGEgbmFtZXNwYWNlIG5hbWUgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKSkgewkKCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gIGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZTsgCiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCgpzdGF0aWMgeG1sU2NoZW1hV2lsZGNhcmRQdHIKeG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCQkJCSAgIAoJCQkJICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHJzLAkJCQkgICAKCQkJCSAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGNvbXBsZXRlV2lsZCkJCQkJCQp7ICAgICAgICAKICAgIHdoaWxlIChhdHRycyAhPSBOVUxMKSB7CglpZiAoYXR0cnMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSB7CgkgICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgZ3JvdXA7CgoJICAgIGdyb3VwID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBhdHRyczsJICAKCSAgICBpZiAoKGdyb3VwLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9XSUxEQ0FSRF9CVUlMREVEKSA9PSAwKSB7CgkJaWYgKGdyb3VwLT5hdHRyaWJ1dGVzICE9IE5VTEwpIHsKCQkgICAgaWYgKGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKQkJCQoJCQl4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQoY3R4dCwgCgkJCSAgICBncm91cC0+YXR0cmlidXRlcywgZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkKTsKCQkgICAgZWxzZQoJCQlncm91cC0+YXR0cmlidXRlV2lsZGNhcmQgPSAKCQkJICAgIHhtbFNjaGVtYUJ1aWxkQ29tcGxldGVBdHRyaWJ1dGVXaWxkY2FyZChjdHh0LCAKCQkJCWdyb3VwLT5hdHRyaWJ1dGVzLCBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQpOwoJCX0KCQlncm91cC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX1dJTERDQVJEX0JVSUxERUQ7CgkgICAgfQkJCgkgICAgaWYgKGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CQkKCQlpZiAoY29tcGxldGVXaWxkID09IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgKiBDb3B5IHRoZSBmaXJzdCBlbmNvdW50ZXJlZCB3aWxkY2FyZCBhcyBjb250ZXh0LCBleGNlcHQgZm9yIHRoZSBhbm5vdGF0aW9uLgoJCSAgICAqLwoJCSAgICBjb21wbGV0ZVdpbGQgPSB4bWxTY2hlbWFBZGRXaWxkY2FyZChjdHh0KTsKCQkgICAgY29tcGxldGVXaWxkLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEU7CSAgIAoJCSAgICBpZiAoIXhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKGN0eHQsIAoJCQkmY29tcGxldGVXaWxkLCBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQpKQoJCQlyZXR1cm4oTlVMTCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+cHJvY2Vzc0NvbnRlbnRzID0gZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHM7CgkJICAgIC8qCgkJICAgICogQWx0aG91Z2ggdGhlIGNvbXBsZXRlIHdpbGRjYXJkIG1pZ2h0IG5vdCBjb3JyZXNwb25kIHRvIGFueQoJCSAgICAqIG5vZGUgaW4gdGhlIHNjaGVtYSwgd2Ugd2lsbCBzYXZlIHRoaXMgY29udGV4dCBub2RlLgoJCSAgICAqLwoJCSAgICBjb21wbGV0ZVdpbGQtPm5vZGUgPSBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQtPm5vZGU7ICAKCQkgICAgcmV0dXJuKGNvbXBsZXRlV2lsZCk7CgkJfSAJCQkJCgkJaWYgKHhtbFNjaGVtYUludGVyc2VjdFdpbGRjYXJkcyhjdHh0LCBjb21wbGV0ZVdpbGQsIGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkKGNvbXBsZXRlV2lsZCk7CgkJICAgIHJldHVybihOVUxMKTsKCQl9CQkKCSAgICB9Cgl9CglhdHRycyA9IGF0dHJzLT5uZXh0OwogICAgfQogICAJCSAgICAgICAgICAgICAgICAgCiAgICByZXR1cm4gKGNvbXBsZXRlV2lsZCk7ICAgCn0KCi8qKgogKiB4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROczoKICogQHdpbGQ6ICB0aGUgd2lsZGNhcmQKICogQG5zOiAgdGhlIG5hbWVzcGFjZQogKiAKICoKICogUmV0dXJucyAxIGlmIHRoZSBnaXZlbiBuYW1lc3BhY2UgbWF0Y2hlcyB0aGUgd2lsZGNhcmQsCiAqIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkLCBjb25zdCB4bWxDaGFyKiBucykKewogICAgaWYgKHdpbGQgPT0gTlVMTCkKCXJldHVybigwKTsKCiAgICBpZiAod2lsZC0+YW55KQoJcmV0dXJuKDEpOwogICAgZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXI7CgoJY3VyID0gd2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoY3VyLT52YWx1ZSwgbnMpKQoJCXJldHVybigxKTsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CiAgICB9IGVsc2UgaWYgKCh3aWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAobnMgIT0gTlVMTCkgJiYgCgkoIXhtbFN0ckVxdWFsKHdpbGQtPm5lZ05zU2V0LT52YWx1ZSwgbnMpKSkKCXJldHVybigxKTsJCgkKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqIAogKgogKiBCdWlsZHMgdGhlIHdpbGRjYXJkIGFuZCB0aGUgYXR0cmlidXRlIHVzZXMgb24gdGhlIGdpdmVuIGNvbXBsZXggdHlwZS4KICogUmV0dXJucyAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBjdXIsIGJhc2UsIHRtcCwgaWQgPSBOVUxMLCBwcmV2ID0gTlVMTCwgdXNlcyA9IE5VTEwsIAoJbGFzdFVzZSA9IE5VTEwsIGxhc3RCYXNlVXNlID0gTlVMTDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyczsKICAgIGludCBiYXNlSXNBbnlUeXBlID0gMDsgICAgCgogICAgLyogCiAgICAgKiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiB3aXRoIGNvbXBsZXggY29udGVudCBTY2hlbWEgQ29tcG9uZW50LgogICAgICoKICAgICAqIEF0dHJpYnV0ZSB1c2VzLgogICAgICovCiAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJICAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFQYXJzZUJ1aWxkQXR0cmlidXRlVXNlczogIgoJCSAgICAgICJhdHRyaWJ1dGUgdXNlcyBhbHJlYWR5IGJ1aWxkZWQuXG4iLAoJCSAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgaWYgKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB8fCAKCSh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pKSB7CQoJLyoKCSAqIEluaGVyaXQgdGhlIGF0dHJpYnV0ZSB1c2VzIG9mIHRoZSBiYXNlIHR5cGUuCgkgKi8KCWJhc2VUeXBlID0gdHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzLT5iYXNlVHlwZTsKCS8qCgkgKiBUT0RPOiBVUkdFTlQ6IFRoaXMgaXMgbm90IG5pY2UsIGJ1dCBjdXJyZW50bHkgCgkgKiB4bWxTY2hlbWFUeXBlQW55VHlwZURlZiBpcyBzdGF0aWMgaW4geG1sc2NoZW1hdHlwZXMuYy4KCSAqLwoJaWYgKChiYXNlVHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpICYmCgkgICAgeG1sU3RyRXF1YWwoYmFzZVR5cGUtPm5hbWUsIEJBRF9DQVNUICJhbnlUeXBlIikpIHsJICAgIAoJICAgIGJhc2VJc0FueVR5cGUgPSAxOwoJfQoJLyoKCSAqIFRPRE86IERvZXMgdGhlIHNwZWMgc3RhdGUgdGhhdCBpdCBpcyBhbiBlcnJvciB0byAiZXh0ZW5kIiB0aGUgCgkgKiBhbnlUeXBlPwoJICovCglpZiAoIWJhc2VJc0FueVR5cGUpIHsKCSAgICBpZiAoYmFzZVR5cGUgIT0gTlVMTCkgewoJCWZvciAoY3VyID0gYmFzZVR5cGUtPmF0dHJpYnV0ZVVzZXM7IGN1ciAhPSBOVUxMOyBjdXIgPSBjdXItPm5leHQpIHsKCQkgICAgdG1wID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIpIAoJCQl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmspKTsKCQkgICAgaWYgKHRtcCA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgCgkJCSAgICAiYnVpbGRpbmcgYXR0cmlidXRlIHVzZXMgb2YgY29tcGxleFR5cGUiLCBOVUxMKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgdG1wLT5hdHRyID0gY3VyLT5hdHRyOwoJCSAgICB0bXAtPm5leHQgPSBOVUxMOwoJCSAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSB7CgkJCXR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB0bXA7CgkJICAgIH0gZWxzZSAKCQkJbGFzdEJhc2VVc2UtPm5leHQgPSB0bXA7CgkJICAgIGxhc3RCYXNlVXNlID0gdG1wOyAKCQl9CgkgICAgfQoJfQoJYXR0cnMgPSB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMtPmF0dHJpYnV0ZXM7CQoJLyoKCSogSGFuZGxlIGF0dHJpYnV0ZSB3aWxkY2FyZHMuCgkqLwoJdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPSAKCSAgICB4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQoY3R4dCwgCgkJYXR0cnMsIAoJCXR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+YXR0cmlidXRlV2lsZGNhcmQpOwoJaWYgKCh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSAmJgoJICAgICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMtPmF0dHJpYnV0ZVdpbGRjYXJkKSkKCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQ7CgoJaWYgKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSAmJiAKCSAgICAoYmFzZVR5cGUgIT0gTlVMTCkgJiYgKGJhc2VUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSAmJiAKCSAgICAoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpKSB7CSAgICAKCSAgICBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewoJCS8qCgkJKiBVbmlvbiB0aGUgY29tcGxldGUgd2lsZGNhcmQgd2l0aCB0aGUgYmFzZSB3aWxkY2FyZC4KCQkqLwoJCWlmICh4bWxTY2hlbWFVbmlvbldpbGRjYXJkcyhjdHh0LCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgCgkJICAgIGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpCgkJICAgIHJldHVybiAoLTEpOwoJICAgIH0gZWxzZSB7CgkJLyoKCQkqIEp1c3QgaW5oZXJpdCB0aGUgd2lsZGNhcmQuCgkJKi8KCQl0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZDsKCSAgICB9Cgl9CiAgICB9IGVsc2UgewoJLyoKCSAqIEFsdGhvdWdoIHRoZSBjb21wbGV4VHlwZSBpcyBpbXBsaWNpdGVseSBkZXJpdmVkIGJ5ICJyZXN0cmljdGlvbiIKCSAqIGZyb20gdGhlIHVyLXR5cGUsIHRoaXMgaXMgbm90ICh5ZXQ/KSByZWZsZWN0ZWQgYnkgbGlieG1sMi4KCSAqLwoJYmFzZVR5cGUgPSBOVUxMOwoJYXR0cnMgPSB0eXBlLT5hdHRyaWJ1dGVzOwoJaWYgKGF0dHJzICE9IE5VTEwpCgkgICAgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPQoJCXhtbFNjaGVtYUJ1aWxkQ29tcGxldGVBdHRyaWJ1dGVXaWxkY2FyZChjdHh0LCBhdHRycywgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpOwogICAgfQogICAgLyoKICAgICAqIEdhdGhlciBhdHRyaWJ1dGUgdXNlcyBkZWZpbmVkIGJ5IHRoaXMgdHlwZS4KICAgICAqLwogICAgaWYgKGF0dHJzICE9IE5VTEwpIHsKCWlmICh4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVVzZXNPd25lZChjdHh0LCBhdHRycywgCgkgICAgJnVzZXMsICZsYXN0VXNlKSA9PSAtMSkgewoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfQogICAgLyogMy40LjYgLT4gQ29tcGxleCBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0IDQuCiAgICAgKiAiVHdvIGRpc3RpbmN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gbXVzdCAKICAgICAqIG5vdCBoYXZlIGlkZW50aWNhbCB7bmFtZX1zIGFuZCB7dGFyZ2V0IG5hbWVzcGFjZX1zLiIKICAgICAqCiAgICAgKiBGb3IgImV4dGVuc2lvbiIgdGhpcyBpcyBkb25lIGZ1cnRoZXIgZG93bi4KICAgICAqLwogICAgaWYgKCh1c2VzICE9IE5VTEwpICYmICgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgPT0gMCkpIHsKCWN1ciA9IHVzZXM7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICB0bXAgPSBjdXItPm5leHQ7CgkgICAgd2hpbGUgKHRtcCAhPSBOVUxMKSB7CSAgICAKCQlpZiAoKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShjdXItPmF0dHIpLCAKCQkgICAgeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKHRtcC0+YXR0cikpKSAmJgoJCSAgICAoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0T255bW91c1RhcmdldE5zVVJJKCh4bWxTY2hlbWFUeXBlUHRyKSBjdXItPmF0dHIgKSwgCgkJICAgIHhtbFNjaGVtYUdldE9ueW1vdXNUYXJnZXROc1VSSSgoeG1sU2NoZW1hVHlwZVB0cikgdG1wLT5hdHRyKSkpKSB7CgkJICAgIAoJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGN1ci0+YXR0ci0+bm9kZSwgWE1MX1NDSEVNQVBfQ1RfUFJPUFNfQ09SUkVDVF80LAoJCQkiY3QtcHJvcHMtY29ycmVjdC40OiBEdXBsaWNhdGUgYXR0cmlidXRlIHVzZSB3aXRoIHRoZSBuYW1lIFwiJXNcIiBzcGVjaWZpZWRcbiIsCgkJCXhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShjdXItPmF0dHIpLCAgTlVMTCk7CgkJICAgIGJyZWFrOwoJCX0KCQl0bXAgPSB0bXAtPm5leHQ7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KICAgIH0JCiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSB7CQoJLyoKCSAqIERlcml2ZSBieSByZXN0cmljdGlvbi4KCSAqLwoJaWYgKGJhc2VJc0FueVR5cGUpIHsKCSAgICB0eXBlLT5hdHRyaWJ1dGVVc2VzID0gdXNlczsKCX0gZWxzZSB7CgkgICAgaW50IGZvdW5kOwoKCSAgICBjdXIgPSB1c2VzOwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJCWZvdW5kID0gMDsKCQliYXNlID0gdHlwZS0+YXR0cmlidXRlVXNlczsKCQl3aGlsZSAoYmFzZSAhPSBOVUxMKSB7CgkJICAgIGlmICgoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGN1ci0+YXR0ciksIAoJCQl4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoYmFzZS0+YXR0cikpKSAmJgoJCQkoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0T255bW91c1RhcmdldE5zVVJJKCh4bWxTY2hlbWFUeXBlUHRyKSBjdXItPmF0dHIpLCAKCQkJeG1sU2NoZW1hR2V0T255bW91c1RhcmdldE5zVVJJKCh4bWxTY2hlbWFUeXBlUHRyKSBiYXNlLT5hdHRyKSkpKSB7CgkJCQoJCQlmb3VuZCA9IDE7CSAgICAKCQkJaWYgKChjdXItPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTCkgJiYKCQkJICAgIChiYXNlLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQpKSB7CgkJCSAgICAvKgoJCQkgICAgKiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uIDIuMS4xCgkJCSAgICAqLwkJCQoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjdXItPmF0dHItPm5vZGUsIAoJCQkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8yXzFfMSwKCQkJCSJkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjIuMS4xOiAiCgkJCQkiVGhlIFwib3B0aW9uYWxcIiBhdHRyaWJ1dGUgIgoJCQkJInVzZSBcIiVzXCIgaXMgaW5jb25zaXN0ZW50IHdpdGggYSBtYXRjaGluZyAiCgkJCQkiXCJyZXF1aXJlZFwiIGF0dHJpYnV0ZSB1c2Ugb2YgdGhlIGJhc2UgdHlwZVxuIiwKCQkJCXhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShjdXItPmF0dHIpLCBOVUxMKTsJCQkJCQoJCQl9IGVsc2UgaWYgKChjdXItPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSAmJgoJCQkgICAgKGJhc2UtPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkpIHsKCQkJICAgIC8qCgkJCSAgICAqIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gMyAKCQkJICAgICovCgkJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGN1ci0+YXR0ci0+bm9kZSwgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8zLAoJCQkJImRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMzogIgoJCQkJIlRoZSBcInJlcXVpcmVkXCIgYXR0cmlidXRlIHVzZSBcIiVzXCIgb2YgdGhlIGJhc2UgdHlwZSAiCgkJCQkiZG9lcyBub3QgaGF2ZSBhIG1hdGNoaW5nIGF0dHJpYnV0ZSB1c2UgaW4gdGhlIGRlcml2ZWQgdHlwZVxuIiwJCQoJCQkJeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGN1ci0+YXR0ciksIE5VTEwpOwoJCQkgICAgCgkJCX0gZWxzZSB7CgkJCSAgICAvKgoJCQkgICAgKiBPdmVycmlkZSB0aGUgYXR0cmlidXRlIHVzZS4KCQkJICAgICovCgkJCSAgICBiYXNlLT5hdHRyID0gY3VyLT5hdHRyOwoJCQl9CgkJCS8qCgkJCSogVE9ETzogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAgMi4xLjIgKHt0eXBlIGRlZmluaXRpb259IG11c3QgYmUgdmFsaWRseSBkZXJpdmVkKQoJCQkqLwoJCQlicmVhazsKCQkgICAgfQkJCQkKCQkgICAgYmFzZSA9IGJhc2UtPm5leHQ7CgkJfQoJCQoJCWlmICghZm91bmQpIHsKCQkgICAgaWYgKGN1ci0+YXR0ci0+b2NjdXJzICE9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpIHsKCQkJLyoKCQkJKiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uICAyLjIKCQkJKi8KCQkJaWYgKCh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSAmJgoJCQkgICAgeG1sU2NoZW1hTWF0Y2hlc1dpbGRjYXJkTnModHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsCgkJCQljdXItPmF0dHItPnRhcmdldE5hbWVzcGFjZSkpCgkJCSAgICBmb3VuZCA9IDE7CgoJCQlpZiAoIWZvdW5kKSB7CgkJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGN1ci0+YXR0ci0+bm9kZSwgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8yXzIsCgkJCQkiZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjI6ICIKCQkJCSJUaGUgYXR0cmlidXRlIHVzZSBcIiVzXCIgaGFzIG5laXRoZXIgYSBtYXRjaGluZyBhdHRyaWJ1dGUgdXNlLCAiCgkJCQkibm9yIGEgbWF0Y2hpbmcgd2lsZGNhcmQgaW4gdGhlIGJhc2UgdHlwZVxuIiwJCQoJCQkJeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGN1ci0+YXR0ciksIE5VTEwpOwoJCQl9IGVsc2UgewoJCQkgICAgLyogCgkJCSAgICAqIEFkZCB0aGUgYXR0cmlidXRlIHVzZS4KCQkJICAgICoKCQkJICAgICogTm90ZSB0aGF0IHRoaXMgbWF5IGxlYWQgdG8gZnVubnkgZGVyaXZhdGlvbiBlcnJvciByZXBvcnRzLCBpZgoJCQkgICAgKiBtdWx0aXBsZSBlcXVhbCBhdHRyaWJ1dGUgdXNlcyBleGlzdDsgYnV0IHRoaXMgaXMgbm90CgkJCSAgICAqIGFsbG93ZWQgYW55d2F5LCBhbmQgaXQgd2lsbCBiZSByZXBvcnRlZCBiZWZvcmVoYW5kLgoJCQkgICAgKi8KCQkJICAgIHRtcCA9IGN1cjsKCQkJICAgIGlmIChwcmV2ICE9IE5VTEwpCgkJCQlwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCQkgICAgZWxzZSAKCQkJCXVzZXMgPSBjdXItPm5leHQ7CgkJCSAgICBjdXIgPSBjdXItPm5leHQ7ICAgIAkJCQoJCQkgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgPT0gTlVMTCkgewoJCQkJdHlwZS0+YXR0cmlidXRlVXNlcyA9IHRtcDsKCQkJICAgIH0gZWxzZSAKCQkJCWxhc3RCYXNlVXNlLT5uZXh0ID0gdG1wOwoJCQkgICAgbGFzdEJhc2VVc2UgPSB0bXA7CQkKCQkJICAgIAoJCQkgICAgY29udGludWU7CgkJCX0KCQkgICAgfQoJCX0JCSAgICAJICAgIAoJCXByZXYgPSBjdXI7CQoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9CgkgICAgaWYgKHVzZXMgIT0gTlVMTCkKCQl4bWxTY2hlbWFGcmVlQXR0cmlidXRlVXNlTGlzdCh1c2VzKTsKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgeyAKCS8qCgkgKiBUaGUgc3BlYyBhbGxvd3Mgb25seSBhcHBlbmRpbmcsIGFuZCBub3Qgb3RoZXIga2luZHMgb2YgZXh0ZW5zaW9ucy4KCSAqCgkgKiBUaGlzIGVuc3VyZXM6IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRGVyaXZhdGlvbiBWYWxpZCAoRXh0ZW5zaW9uKSA6IDEuMiAKCSAqLwoJaWYgKHVzZXMgIT0gTlVMTCkgewoJICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzID09IE5VTEwpIHsKCQl0eXBlLT5hdHRyaWJ1dGVVc2VzID0gdXNlczsKCSAgICB9IGVsc2UgCgkJbGFzdEJhc2VVc2UtPm5leHQgPSB1c2VzOwogICAgfQogICAgfSBlbHNlIHsKCS8qIAoJICogRGVyaXZlIGltcGxpY2l0ZWx5IGZyb20gdGhlIHVyLXR5cGUuCgkgKi8KCXR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB1c2VzOwp9CiAgICAvKgogICAgICogMy40LjYgLT4gQ29tcGxleCBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0CiAgICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpIHsKCWN1ciA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CglwcmV2ID0gTlVMTDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiA0LiBUd28gZGlzdGluY3QgYXR0cmlidXRlIGRlY2xhcmF0aW9ucyBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IAoJICAgICogbm90IGhhdmUgaWRlbnRpY2FsIHtuYW1lfXMgYW5kIHt0YXJnZXQgbmFtZXNwYWNlfXMuCiAqCgkgICAgKiBOb3RlIHRoYXQgdGhpcyB3YXMgYWxyZWFkeSBkb25lIGZvciAicmVzdHJpY3Rpb24iIGFuZCB0eXBlcyBkZXJpdmVkIGZyb20KCSAgICAqIHRoZSB1ci10eXBlLgogKi8KCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgewoJCXRtcCA9IGN1ci0+bmV4dDsKCQl3aGlsZSAodG1wICE9IE5VTEwpIHsJICAgIAoJCSAgICBpZiAoKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShjdXItPmF0dHIpLCAKCQkJeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKHRtcC0+YXR0cikpKSAmJgoJCQkoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0T255bW91c1RhcmdldE5zVVJJKCh4bWxTY2hlbWFUeXBlUHRyKSBjdXItPmF0dHIgKSwgCgkJCXhtbFNjaGVtYUdldE9ueW1vdXNUYXJnZXROc1VSSSgoeG1sU2NoZW1hVHlwZVB0cikgdG1wLT5hdHRyKSkpKSB7CgoJCQl4bWxTY2hlbWFQRXJyKGN0eHQsIGN1ci0+YXR0ci0+bm9kZSwgWE1MX1NDSEVNQVBfQ1RfUFJPUFNfQ09SUkVDVF80LAoJCQkgICAgImN0LXByb3BzLWNvcnJlY3QuNDogRHVwbGljYXRlIGF0dHJpYnV0ZSB1c2Ugd2l0aCB0aGUgbmFtZSBcIiVzXCIgc3BlY2lmaWVkXG4iLAoJCQkgICAgeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGN1ci0+YXR0ciksICBOVUxMKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoJCSAgICB0bXAgPSB0bXAtPm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgkgICAgLyoKCSAgICAqIDUuIFR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG11c3QgCgkgICAgKiBub3QgaGF2ZSB7dHlwZSBkZWZpbml0aW9ufXMgd2hpY2ggYXJlIG9yIGFyZSBkZXJpdmVkIGZyb20gSUQuCgkgICAgKi8KCSAgICBpZiAoKGN1ci0+YXR0ci0+c3VidHlwZXMgIT0gTlVMTCkgJiYgCgkJLyoKCQkqIFRPRE86IEZJWE1FOiBYTUxfU0NIRU1BU19JRCBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mICIyMyIgISEhLCAKCQkqIGJ1dCB0aGUgeG1sU2NoZW1hVmFsVHlwZSBpcyBub3QgbWFkZSBwdWJsaWMgeWV0LgoJCSovCgkJKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgY3VyLT5hdHRyLCAyMykpKSB7CgkJaWYgKGlkICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjdXItPmF0dHItPm5vZGUsIFhNTF9TQ0hFTUFQX0NUX1BST1BTX0NPUlJFQ1RfNSwgCgkJCSJjdC1wcm9wcy1jb3JyZWN0LjU6IFR3byBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zLCAiCgkJCSJcIiVzXCIgYW5kIFwiJXNcIiBoYXZlIHR5cGVzIHdoaWNoIGRlcml2ZWQgZnJvbSBJRFxuIiwKCQkJeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGlkLT5hdHRyKSwgCgkJCXhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShjdXItPmF0dHIpKTsKICAgICAgICB9IAoJCWlkID0gY3VyOwoJICAgIH0KCSAgICAvKgoJICAgICogUmVtb3ZlICJwcm9oaWJpdGVkIiBhdHRyaWJ1dGUgdXNlcy4gVGhlIHJlYXNvbiB0aGlzIGlzIGRvbmUgYXQgdGhpcyBsYXRlIAoJICAgICogc3RhZ2UgaXMgdG8gYmUgYWJsZSB0byBjYXRjaCBkdWJsaWNhdGUgYXR0cmlidXRlIHVzZXMuIFNvIHdlIGhhZCB0byBrZWVwCgkgICAgKiBwcm9oaWJpdGVkIHVzZXMgaW4gdGhlIGxpc3QgYXMgd2VsbC4KCSAgICAqLwoJICAgIGlmIChjdXItPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSB7CgkJdG1wID0gY3VyOwoJCWlmIChwcmV2ID09IE5VTEwpCgkJICAgIHR5cGUtPmF0dHJpYnV0ZVVzZXMgPSBjdXItPm5leHQ7CgkJZWxzZQoJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCWN1ciA9IGN1ci0+bmV4dDsKICAgICAgICB4bWxGcmVlKHRtcCk7CgkgICAgfSBlbHNlIHsKCQlwcmV2ID0gY3VyOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9Cgl9ICAgIAogICAgfQogICAgLyoJCiAgICAgKiBUT0RPOiBUaGlzIGNoZWNrIHNob3VsZCBiZSByZW1vdmVkIGlmIHdlIGFyZSAxMDAlIHN1cmUgb2YKICAgICAqIHRoZSBiYXNlIHR5cGUgYXR0cmlidXRlIHVzZXMgYWxyZWFkeSBiZWluZyBidWlsdC4KICAgICAqLwogICAgaWYgKChiYXNlVHlwZSAhPSBOVUxMKSAmJiAoIWJhc2VJc0FueVR5cGUpICYmCgkoYmFzZVR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpICYmCgkoYmFzZVR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSkgewoJeG1sU2NoZW1hUEVycihjdHh0LCBiYXNlVHlwZS0+bm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUGFyc2VCdWlsZEF0dHJpYnV0ZVVzZXM6ICIKCSAgICAiYXR0cmlidXRlIHVzZXMgbm90IGJ1aWxkZWQgb24gYmFzZSB0eXBlIFwiJXNcIi5cbiIsCgkgICAgYmFzZVR5cGUtPm5hbWUsIE5VTEwpOwogICAgfSAgICAKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFUeXBlRml4dXA6CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBGaXhlcyB0aGUgY29udGVudCBtb2RlbCBvZiB0aGUgdHlwZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVR5cGVGaXh1cCh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKHR5cGVEZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gdHlwZURlY2wtPm5hbWU7CiAgICBpZiAodHlwZURlY2wtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CiAgICAgICAgc3dpdGNoICh0eXBlRGVjbC0+dHlwZSkgewogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVDp7CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGVEZWNsLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPnN1YnR5cGVzLT5jb250ZW50VHlwZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046ewogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGVEZWNsLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CgogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+YmFzZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGU7CgogICAgICAgICAgICAgICAgICAgICAgICBiYXNlVHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgdHlwZURlY2wtPmJhc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5iYXNlTnMpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmFzZVR5cGUgPT0gTlVMTCkgewoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlRGVjbC0+bm9kZSwKCQkJICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9CQVNFX1RZUEUsCgkJCQkiU2NoZW1hczogdHlwZSAlcyBiYXNlIHR5cGUgJXMgbm90IGZvdW5kXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCB0eXBlRGVjbC0+YmFzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYmFzZVR5cGUtPmNvbnRlbnRUeXBlID09IAoJCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pIHsKCQkJICAgIC8qIAoJCQkgICAgICogVGhlIGJhc2UgdHlwZSBtaWdodCBiZSBub3QgInR5cGUgZml4ZWQiIHlldCwKCQkJICAgICAqIHNvIGRvIGl0IG5vdy4gKi8KCQkJICAgIC8qIAoJCQkgICAgICogVE9ETzogSXMgYSBjaGVjayBmb3IgY2lyY3VsYXIgZGVyaXZhdGlvbiBhbHJlYWR5CgkJCSAgICAgKiBkb25lPwoJCQkgICAgICovCgkJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoYmFzZVR5cGUsIGN0eHQsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5iYXNlVHlwZSA9IGJhc2VUeXBlOwogICAgICAgICAgICAgICAgICAgIH0KCQkgICAgaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcyA9PSBOVUxMKQoJCQlpZiAodHlwZURlY2wtPmJhc2VUeXBlICE9IE5VTEwpIHsKCQkJICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9CgkJCSAgICAgICAgICAgICB0eXBlRGVjbC0+YmFzZVR5cGUtPmNvbnRlbnRUeXBlOwoJCQl9IGVsc2UgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAxLjEuMSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCh0eXBlRGVjbC0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCh0eXBlRGVjbC0+c3VidHlwZXMtPnR5cGUgPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfVFlQRV9BTEwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICh0eXBlRGVjbC0+c3VidHlwZXMtPnR5cGUgPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSkpKQogICAgICAgICAgICAgICAgICAgICAgICAvKiAxLjEuMiAqLwogICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICh0eXBlRGVjbC0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpKQogICAgICAgICAgICAgICAgICAgICAgICAvKiAxLjEuMyAqLwogICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIDEuMiBhbmQgMi5YIGFyZSBhcHBsaWVkIGF0IHRoZSBvdGhlciBsYXllciAqLwogICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOnsKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFDb250ZW50VHlwZSBleHBsaWNpdENvbnRlbnRUeXBlOwogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5iYXNlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCB0eXBlRGVjbC0+YmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmJhc2VOcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiYXNlVHlwZSA9PSBOVUxMKSB7CgkJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGVEZWNsLT5ub2RlLAoJCQkgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0JBU0VfVFlQRSwKCQkJCSJTY2hlbWFzOiB0eXBlICVzIGJhc2UgdHlwZSAlcyBub3QgZm91bmRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIHR5cGVEZWNsLT5iYXNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChiYXNlVHlwZS0+Y29udGVudFR5cGUgPT0gCgkJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgewoJCQkgICAgLyogCgkJCSAgICAgKiBUaGUgYmFzZSB0eXBlIG1pZ2h0IGJlIG5vdCAidHlwZSBmaXhlZCIgeWV0LAoJCQkgICAgICogc28gZG8gaXQgbm93LiAqLwoJCQkgICAgLyogCgkJCSAgICAgKiBUT0RPOiBJcyBhIGNoZWNrIGZvciBjaXJjdWxhciBkZXJpdmF0aW9uIGFscmVhZHkKCQkJICAgICAqIGRvbmU/CgkJCSAgICAgKi8KCQkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlVHlwZSwgY3R4dCwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmJhc2VUeXBlID0gYmFzZVR5cGU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGVEZWNsLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CgogICAgICAgICAgICAgICAgICAgIGV4cGxpY2l0Q29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcyA9PSBOVUxMKQogICAgICAgICAgICAgICAgICAgICAgICAvKiAxLjEuMSAqLwogICAgICAgICAgICAgICAgICAgICAgICBleHBsaWNpdENvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCh0eXBlRGVjbC0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCh0eXBlRGVjbC0+c3VidHlwZXMtPnR5cGUgPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfVFlQRV9BTEwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICh0eXBlRGVjbC0+c3VidHlwZXMtPnR5cGUgPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSkpKQogICAgICAgICAgICAgICAgICAgICAgICAvKiAxLjEuMiAqLwogICAgICAgICAgICAgICAgICAgICAgICBleHBsaWNpdENvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCh0eXBlRGVjbC0+c3VidHlwZXMtPnR5cGUgPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAodHlwZURlY2wtPnN1YnR5cGVzLT5zdWJ0eXBlcyA9PSBOVUxMKSkKICAgICAgICAgICAgICAgICAgICAgICAgLyogMS4xLjMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgZXhwbGljaXRDb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCiAgICAgICAgICAgICAgICAgICAgYmFzZSA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCB0eXBlRGVjbC0+YmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+YmFzZU5zKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYmFzZSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9CQVNFX1RZUEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IGJhc2UgdHlwZSAlcyBvZiB0eXBlICVzIG5vdCBmb3VuZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+YmFzZSwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5yZWN1cnNlKSB7CgkJCS8qIFRPRE86IFRoZSB3b3JkICJyZWN1cnNpdmUiIHNob3VsZCBiZSBjaGFuZ2VkIHRvICJjaXJjdWxhciIgaGVyZS4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlRGVjbC0+bm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0JBU0VfVFlQRSwKCQkJCSAgIlNjaGVtYXM6IGV4dGVuc2lvbiB0eXBlICVzIGlzIHJlY3Vyc2l2ZVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwoJCSAgICB9CgkJICAgIHR5cGVEZWNsLT5yZWN1cnNlID0gMTsKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlRml4dXAoYmFzZSwgY3R4dCwgTlVMTCk7CgkJICAgIHR5cGVEZWNsLT5yZWN1cnNlID0gMDsKICAgICAgICAgICAgICAgICAgICBpZiAoZXhwbGljaXRDb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogMi4xICovCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9IGJhc2UtPmNvbnRlbnRUeXBlOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYmFzZS0+Y29udGVudFR5cGUgPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiAyLjIgaW1iaXRhYmxlICEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvKiAyLjMgaW1iaXRhYmxlIHBhcmVpbCAhICovCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOnsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPnN1YnR5cGVzID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlRml4dXAodHlwZURlY2wtPnN1YnR5cGVzLCBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5zdWJ0eXBlcy0+Y29udGVudFR5cGU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCQkJLyogRXZhbHVhdGUgdGhlIGRlcml2YXRpb24gbWV0aG9kLiAqLwoJCQlpZiAoKHR5cGVEZWNsLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJgoJCQkgICAgKCh0eXBlRGVjbC0+c3VidHlwZXMtPnR5cGUgPT0gCgkJCQlYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB8fAoJCQkgICAgKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PSAKCQkJCVhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkpICYmCgkJCSAgICAodHlwZURlY2wtPnN1YnR5cGVzLT5zdWJ0eXBlcyAhPSBOVUxMKSkgewkJCSAgICAJCQkgICAgCgkJCSAgICBpZiAodHlwZURlY2wtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+dHlwZSA9PSAKCQkJCSAgICBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OKSB7CgkJCQl0eXBlRGVjbC0+ZmxhZ3MgfD0gCgkJCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT047CgkJCSAgICB9IGVsc2UgaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcy0+c3VidHlwZXMtPnR5cGUgPT0gCgkJCQkgICAgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OKSB7CgkJCQl0eXBlRGVjbC0+ZmxhZ3MgfD0gCgkJCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTjsKICAgICAgICAgICAgICAgICAgICB9CgkJCX0KICAgICAgICAgICAgICAgICAgICB9CgkJICAgIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbihjdHh0LCB0eXBlRGVjbCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVDp7CiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcyA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlRml4dXAodHlwZURlY2wtPnN1YnR5cGVzLCBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5zdWJ0eXBlcy0+Y29udGVudFR5cGU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCQkJLyogCgkJCSAqIFJlbW92ZWQgZHVlIHRvIGltcGxlbWVudGF0aW9uIG9mIHRoZSBidWlsZCBvZiBhdHRyaWJ1dGUgdXNlcy4gCgkJCSAqLwoJCQkvKgoJCQlpZiAodHlwZURlY2wtPmF0dHJpYnV0ZXMgPT0gTlVMTCkKCQkJICAgIHR5cGVEZWNsLT5hdHRyaWJ1dGVzID0KCQkJICAgICAgICB0eXBlRGVjbC0+c3VidHlwZXMtPmF0dHJpYnV0ZXM7CgkJCSovCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgogICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0xJU1Q6CgkJeG1sU2NoZW1hUGFyc2VMaXN0UmVmRml4dXAodHlwZURlY2wsIGN0eHQpOwoJCS8qIG5vIGJyZWFrIG9uIHB1cnBvc2UgKi8KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVU5JT046CgkJaWYgKHR5cGVEZWNsLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9VTklPTikKCQkgICAgeG1sU2NoZW1hUGFyc2VVbmlvblJlZkNoZWNrKHR5cGVEZWNsLCBjdHh0KTsKCQkvKiBubyBicmVhayBvbiBwdXJwb3NlICovCiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0ZBQ0VUOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1VSOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9OT1RBVElPTjoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgogICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCQlpZiAodHlwZURlY2wtPnN1YnR5cGVzICE9IE5VTEwpCgkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cCh0eXBlRGVjbC0+c3VidHlwZXMsIGN0eHQsIE5VTEwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQojaWZkZWYgREVCVUdfVFlQRQogICAgaWYgKHR5cGVEZWNsLT5ub2RlICE9IE5VTEwpIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIlR5cGUgb2YgJXMgOiAlczolZCA6IiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPm5vZGUtPmRvYy0+VVJMLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxHZXRMaW5lTm8odHlwZURlY2wtPm5vZGUpKTsKICAgIH0gZWxzZSB7CiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJUeXBlIG9mICVzIDoiLCBuYW1lKTsKICAgIH0KICAgIHN3aXRjaCAodHlwZURlY2wtPmNvbnRlbnRUeXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgInNpbXBsZVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgImVsZW1lbnRzXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTjoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJ1bmtub3duICEhIVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgImVtcHR5XG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAibWl4ZWRcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRF9PUl9FTEVNRU5UUzoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJtaXhlZCBvciBlbGVtc1xuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgImJhc2ljXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm90IHJlZ2lzdGVyZWQgISEhXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiNlbmRpZgp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tGYWNldDoKICogQGZhY2V0OiAgdGhlIGZhY2V0CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dCBvciBOVUxMCiAqIEBuYW1lOiBuYW1lIG9mIHRoZSB0eXBlCiAqCiAqIENoZWNrcyB0aGUgZGVmYXVsdCB2YWx1ZXMgdHlwZXMsIGVzcGVjaWFsbHkgZm9yIGZhY2V0cyAKICoKICogUmV0dXJucyAwIGlmIG9rYXkgb3IgLTEgaW4gY2FlIG9mIGVycm9yCiAqLwppbnQKeG1sU2NoZW1hQ2hlY2tGYWNldCh4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIHN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUgPSBOVUxMOwogICAgaW50IHJldCA9IDA7CgogICAgaWYgKG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUgPT0gTlVMTCkgewogICAgICAgIG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUgPQogICAgICAgICAgICB4bWxTY2hlbWFHZXRQcmVkZWZpbmVkVHlwZShCQURfQ0FTVCAibm9uTmVnYXRpdmVJbnRlZ2VyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hTnMpOwogICAgfQogICAgc3dpdGNoIChmYWNldC0+dHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6ewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIE9rYXkgd2UgbmVlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUKICAgICAgICAgICAgICAgICAqIGF0IHRoYXQgcG9pbnQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dDsKCiAgICAgICAgICAgICAgICB2Y3R4dCA9IHhtbFNjaGVtYU5ld1ZhbGlkQ3R4dChOVUxMKTsKICAgICAgICAgICAgICAgIGlmICh2Y3R4dCA9PSBOVUxMKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZSh2Y3R4dCwgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICBmYWNldC0+dmFsID0gdmN0eHQtPnZhbHVlOwogICAgICAgICAgICAgICAgdmN0eHQtPnZhbHVlID0gTlVMTDsKICAgICAgICAgICAgICAgIGlmIChmYWNldC0+dmFsID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAvKiBlcnJvciBjb2RlICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGZhY2V0LT5ub2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IHR5cGUgJXMgZmFjZXQgdmFsdWUgJXMgaW52YWxpZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBmYWNldC0+dmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXQgPSAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHhtbFNjaGVtYUZyZWVWYWxpZEN0eHQodmN0eHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046ewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIE9rYXkgd2UgbmVlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUKICAgICAgICAgICAgICAgICAqIGF0IHRoYXQgcG9pbnQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dDsKICAgICAgICAgICAgICAgIGludCB0bXA7CgogICAgICAgICAgICAgICAgdmN0eHQgPSB4bWxTY2hlbWFOZXdWYWxpZEN0eHQoTlVMTCk7CiAgICAgICAgICAgICAgICBpZiAodmN0eHQgPT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIHRtcCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWUodmN0eHQsIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldC0+dmFsdWUpOwogICAgICAgICAgICAgICAgaWYgKHRtcCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGZhY2V0LT5ub2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfRU5VTSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2NoZW1hczogdHlwZSAlcyBlbnVtZXJhdGlvbiB2YWx1ZSAlcyBpbnZhbGlkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dCh2Y3R4dCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgogICAgICAgICAgICBmYWNldC0+cmVnZXhwID0geG1sUmVnZXhwQ29tcGlsZShmYWNldC0+dmFsdWUpOwogICAgICAgICAgICBpZiAoZmFjZXQtPnJlZ2V4cCA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlRGVjbC0+bm9kZSwKCQkJICAgICAgWE1MX1NDSEVNQVBfUkVHRVhQX0lOVkFMSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTY2hlbWFzOiB0eXBlICVzIGZhY2V0IHJlZ2V4cCAlcyBpbnZhbGlkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBmYWNldC0+dmFsdWUpOwogICAgICAgICAgICAgICAgcmV0ID0gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDp7CiAgICAgICAgICAgICAgICBpbnQgdG1wOwoKICAgICAgICAgICAgICAgIHRtcCA9CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVQcmVkZWZpbmVkVHlwZShub25OZWdhdGl2ZUludGVnZXJUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjZXQtPnZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZhY2V0LT52YWwpOwogICAgICAgICAgICAgICAgaWYgKHRtcCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgLyogZXJyb3IgY29kZSAqLwogICAgICAgICAgICAgICAgICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBmYWNldC0+bm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTY2hlbWFzOiB0eXBlICVzIGZhY2V0IHZhbHVlICVzIGludmFsaWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOnsKICAgICAgICAgICAgICAgIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJwcmVzZXJ2ZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9QUkVTRVJWRTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoZmFjZXQtPnZhbHVlLCBCQURfQ0FTVCAicmVwbGFjZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9SRVBMQUNFOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJjb2xsYXBzZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGZhY2V0LT5ub2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfV0hJVEVfU1BBQ0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IHR5cGUgJXMgd2hpdGVTcGFjZSB2YWx1ZSAlcyBpbnZhbGlkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0RlZmF1bHRzOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogQ2hlY2tzIHRoZSBkZWZhdWx0IHZhbHVlcyB0eXBlcywgZXNwZWNpYWxseSBmb3IgZmFjZXRzIAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tEZWZhdWx0cyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIGlmIChuYW1lID09IE5VTEwpCiAgICAgICAgbmFtZSA9IHR5cGVEZWNsLT5uYW1lOwogICAgaWYgKHR5cGVEZWNsLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTikgewogICAgICAgIGlmICh0eXBlRGVjbC0+ZmFjZXRzICE9IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQgPSB0eXBlRGVjbC0+ZmFjZXRzOwoKICAgICAgICAgICAgd2hpbGUgKGZhY2V0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYUNoZWNrRmFjZXQoZmFjZXQsIHR5cGVEZWNsLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFBdHRyR3JwRml4dXA6CiAqIEBhdHRyZ3JwRGVjbDogIHRoZSBzY2hlbWEgYXR0cmlidXRlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIGF0dHJpYnV0ZSBuYW1lCiAqCiAqIEZpeGVzIGZpbmlzaCBkb2luZyB0aGUgY29tcHV0YXRpb25zIG9uIHRoZSBhdHRyaWJ1dGVzIGRlZmluaXRpb25zCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFBdHRyR3JwRml4dXAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgYXR0cmdycCwKICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIGlmIChuYW1lID09IE5VTEwpCiAgICAgICAgbmFtZSA9IGF0dHJncnAtPm5hbWU7CiAgICBpZiAoYXR0cmdycC0+YXR0cmlidXRlcyAhPSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChhdHRyZ3JwLT5yZWYgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIHJlZjsKCiAgICAgICAgcmVmID0geG1sU2NoZW1hR2V0QXR0cmlidXRlR3JvdXAoY3R4dC0+c2NoZW1hLCBhdHRyZ3JwLT5yZWYsIGF0dHJncnAtPnJlZk5zKTsKICAgICAgICBpZiAocmVmID09IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBhdHRyZ3JwLT5ub2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQVRUUklCVVRFX0dST1VQLAogICAgICAgICAgICAgICAgICAgICAgICAgICJTY2hlbWFzOiBhdHRyaWJ1dGUgZ3JvdXAgJXMgcmVmZXJlbmNlICVzIG5vdCBmb3VuZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBhdHRyZ3JwLT5yZWYpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHhtbFNjaGVtYUF0dHJHcnBGaXh1cChyZWYsIGN0eHQsIE5VTEwpOwogICAgICAgIGF0dHJncnAtPmF0dHJpYnV0ZXMgPSByZWYtPmF0dHJpYnV0ZXM7CglhdHRyZ3JwLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHJlZi0+YXR0cmlidXRlV2lsZGNhcmQ7CiAgICB9CiAgICAvKiAKICAgICogUmVtb3ZlZCwgc2luY2UgYSBnbG9iYWwgYXR0cmlidXRlIGdyb3VwIGRvZXMgbm90IG5lZWQgdG8gaG9sZCBhbnkKICAgICogYXR0cmlidXRlcyBvciB3aWxkY2FyZCAKICAgICovCiAgICAvKgogICAgZWxzZSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBhdHRyZ3JwLT5ub2RlLCBYTUxfU0NIRU1BUF9OT0FUVFJfTk9SRUYsCiAgICAgICAgICAgICAgICAgICAgICAiU2NoZW1hczogYXR0cmlidXRlIGdyb3VwICVzIGhhcyBubyBhdHRyaWJ1dGVzIG5vciByZWZlcmVuY2VcbiIsCiAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBOVUxMKTsKICAgIH0KICAgICovCn0KCi8qKgogKiB4bWxTY2hlbWFBdHRyRml4dXA6CiAqIEBhdHRyRGVjbDogIHRoZSBzY2hlbWEgYXR0cmlidXRlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIGF0dHJpYnV0ZSBuYW1lCiAqCiAqIEZpeGVzIGZpbmlzaCBkb2luZyB0aGUgY29tcHV0YXRpb25zIG9uIHRoZSBhdHRyaWJ1dGVzIGRlZmluaXRpb25zCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFBdHRyRml4dXAoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHJEZWNsLAogICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gYXR0ckRlY2wtPm5hbWU7CiAgICBpZiAoYXR0ckRlY2wtPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHJEZWNsLT50eXBlTmFtZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKICAgICAgICB0eXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGF0dHJEZWNsLT50eXBlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyRGVjbC0+dHlwZU5zKTsKICAgICAgICBpZiAodHlwZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgYXR0ckRlY2wtPm5vZGUsIFhNTF9TQ0hFTUFQX1VOS05PV05fVFlQRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAiU2NoZW1hczogYXR0cmlidXRlICVzIHR5cGUgJXMgbm90IGZvdW5kXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIGF0dHJEZWNsLT50eXBlTmFtZSk7CiAgICAgICAgfQogICAgICAgIGF0dHJEZWNsLT5zdWJ0eXBlcyA9IHR5cGU7CiAgICB9IGVsc2UgaWYgKGF0dHJEZWNsLT5yZWYgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZWY7CgoJcmVmID0geG1sU2NoZW1hR2V0QXR0cmlidXRlKGN0eHQtPnNjaGVtYSwgYXR0ckRlY2wtPnJlZiwgYXR0ckRlY2wtPnJlZk5zKTsKICAgICAgICBpZiAocmVmID09IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBhdHRyRGVjbC0+bm9kZSwgWE1MX1NDSEVNQVBfVU5LTk9XTl9SRUYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IGF0dHJpYnV0ZSAlcyByZWZlcmVuY2UgJXMgbm90IGZvdW5kXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIGF0dHJEZWNsLT5yZWYpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHhtbFNjaGVtYUF0dHJGaXh1cChyZWYsIGN0eHQsIE5VTEwpOwogICAgICAgIGF0dHJEZWNsLT5zdWJ0eXBlcyA9IHJlZi0+c3VidHlwZXM7CiAgICB9IGVsc2UgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgYXR0ckRlY2wtPm5vZGUsIFhNTF9TQ0hFTUFQX05PVFlQRV9OT1JFRiwKICAgICAgICAgICAgICAgICAgICAgICJTY2hlbWFzOiBhdHRyaWJ1dGUgJXMgaGFzIG5vIHR5cGUgbm9yIHJlZmVyZW5jZVxuIiwKICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIE5VTEwpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hUGFyc2U6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIHBhcnNlIGEgc2NoZW1hIGRlZmluaXRpb24gcmVzb3VyY2UgYW5kIGJ1aWxkIGFuIGludGVybmFsCiAqIFhNTCBTaGVtYSBzdHJ1dHVyZSB3aGljaCBjYW4gYmUgdXNlZCB0byB2YWxpZGF0ZSBpbnN0YW5jZXMuCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVB0cgp4bWxTY2hlbWFQYXJzZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVB0ciByZXQgPSBOVUxMOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbE5vZGVQdHIgcm9vdDsKICAgIGludCBuYmVycm9yczsKICAgIGludCBwcmVzZXJ2ZSA9IDA7CgogICAgeG1sU2NoZW1hSW5pdFR5cGVzKCk7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIG5iZXJyb3JzID0gY3R4dC0+bmJlcnJvcnM7CiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICBjdHh0LT5jb3VudGVyID0gMDsKICAgIGN0eHQtPmNvbnRhaW5lciA9IE5VTEw7CgogICAgLyoKICAgICAqIEZpcnN0IHN0ZXAgaXMgdG8gcGFyc2UgdGhlIGlucHV0IGRvY3VtZW50IGludG8gYW4gRE9NL0luZm9zZXQKICAgICAqLwogICAgaWYgKGN0eHQtPlVSTCAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0geG1sUmVhZEZpbGUoKGNvbnN0IGNoYXIgKikgY3R4dC0+VVJMLCBOVUxMLCAKCSAgICAgICAgICAgICAgICAgIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyk7CiAgICAgICAgaWYgKGRvYyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLAoJCQkgIFhNTF9TQ0hFTUFQX0ZBSUxFRF9MT0FELAogICAgICAgICAgICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IGxvYWQgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+VVJMLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYgKGN0eHQtPmJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0geG1sUmVhZE1lbW9yeShjdHh0LT5idWZmZXIsIGN0eHQtPnNpemUsIE5VTEwsIE5VTEwsCgkgICAgICAgICAgICAgICAgICAgIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyk7CiAgICAgICAgaWYgKGRvYyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLAoJCQkgIFhNTF9TQ0hFTUFQX0ZBSUxFRF9QQVJTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hUGFyc2U6IGNvdWxkIG5vdCBwYXJzZVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICAgICAgZG9jLT5VUkwgPSB4bWxTdHJkdXAoQkFEX0NBU1QgImluX21lbW9yeV9idWZmZXIiKTsKICAgICAgICBjdHh0LT5VUkwgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIEJBRF9DQVNUICJpbl9tZW1vcnlfYnVmZmVyIiwgLTEpOwogICAgfSBlbHNlIGlmIChjdHh0LT5kb2MgIT0gTlVMTCkgewogICAgICAgIGRvYyA9IGN0eHQtPmRvYzsKCXByZXNlcnZlID0gMTsKICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9USElOR19UT19QQVJTRSwKCQkgICAgICAieG1sU2NoZW1hUGFyc2U6IGNvdWxkIG5vdCBwYXJzZVxuIiwKCQkgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQoKICAgIC8qCiAgICAgKiBUaGVuIGV4dHJhY3QgdGhlIHJvb3QgYW5kIFNjaGVtYSBwYXJzZSBpdAogICAgICovCiAgICByb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKICAgIGlmIChyb290ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9OT1JPT1QsCgkJICAgICAgInNjaGVtYXMgaGFzIG5vIHJvb3QiLCBOVUxMLCBOVUxMKTsKCWlmICghcHJlc2VydmUpIHsKCSAgICB4bWxGcmVlRG9jKGRvYyk7Cgl9CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICB4bWxTY2hlbWFDbGVhbnVwRG9jKGN0eHQsIHJvb3QpOwoKICAgIC8qCiAgICAgKiBUaGVuIGRvIHRoZSBwYXJzaW5nIGZvciBnb29kCiAgICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVBhcnNlU2NoZW1hKGN0eHQsIHJvb3QpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKCFwcmVzZXJ2ZSkgewoJICAgIHhtbEZyZWVEb2MoZG9jKTsKCX0KICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0LT5kb2MgPSBkb2M7CiAgICByZXQtPnByZXNlcnZlID0gcHJlc2VydmU7CgogICAgLyoKICAgICAqIFRoZW4gZml4IGFsbCB0aGUgcmVmZXJlbmNlcy4KICAgICAqLwogICAgY3R4dC0+c2NoZW1hID0gcmV0OwogICAgeG1sSGFzaFNjYW5GdWxsKHJldC0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hTY2FubmVyRnVsbCkgeG1sU2NoZW1hUmVmRml4dXBDYWxsYmFjaywgY3R4dCk7CgogICAgLyoKICAgICAqIFRoZW4gZml4dXAgYWxsIGF0dHJpYnV0ZXMgZGVjbGFyYXRpb25zCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+YXR0ckRlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQXR0ckZpeHVwLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBmaXh1cCBhbGwgYXR0cmlidXRlcyBncm91cCBkZWNsYXJhdGlvbnMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5hdHRyZ3JwRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFBdHRyR3JwRml4dXAsCiAgICAgICAgICAgICAgICBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBmaXh1cCBhbGwgdHlwZXMgcHJvcGVydGllcwogICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPnR5cGVEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYVR5cGVGaXh1cCwgY3R4dCk7CgogICAgLyoKICAgICAqIFRoZW4gYnVpbGQgdGhlIGNvbnRlbnQgbW9kZWwgZm9yIGFsbCBlbGVtZW50cwogICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbCwgY3R4dCk7CgogICAgLyoKICAgICAqIFRoZW4gY2hlY2sgdGhlIGRlZmF1bHRzIHBhcnQgb2YgdGhlIHR5cGUgbGlrZSBmYWNldHMgdmFsdWVzCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQ2hlY2tEZWZhdWx0cywKICAgICAgICAgICAgICAgIGN0eHQpOwoKICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKSB7CiAgICAgICAgeG1sU2NoZW1hRnJlZShyZXQpOwogICAgICAgIHJldCA9IE5VTEw7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnI6ICB0aGUgZXJyb3IgY2FsbGJhY2sKICogQHdhcm46ICB0aGUgd2FybmluZyBjYWxsYmFjawogKiBAY3R4OiAgY29udGV4dHVhbCBkYXRhIGZvciB0aGUgY2FsbGJhY2tzCiAqCiAqIFNldCB0aGUgY2FsbGJhY2sgZnVuY3Rpb25zIHVzZWQgdG8gaGFuZGxlIGVycm9ycyBmb3IgYSB2YWxpZGF0aW9uIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2Fybiwgdm9pZCAqY3R4KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGN0eHQtPmVycm9yID0gZXJyOwogICAgY3R4dC0+d2FybmluZyA9IHdhcm47CiAgICBjdHh0LT51c2VyRGF0YSA9IGN0eDsKfQoKLyoqCiAqIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nOgogKiBAdHlwZTogIHRoZSBmYWNldCB0eXBlCiAqCiAqIENvbnZlcnQgdGhlIHhtbFNjaGVtYVR5cGVUeXBlIHRvIGEgY2hhciBzdHJpbmcuCiAqCiAqIFJldHVybnMgdGhlIGNoYXIgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBmYWNldCB0eXBlIGlmIHRoZQogKiAgICAgdHlwZSBpcyBhIGZhY2V0IGFuZCBhbiAiSW50ZXJuYWwgRXJyb3IiIHN0cmluZyBvdGhlcndpc2UuCiAqLwpzdGF0aWMgY29uc3QgY2hhciAqCnhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUpCnsKICAgIHN3aXRjaCAodHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgogICAgICAgICAgICByZXR1cm4gKCJwYXR0ZXJuIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuICgibWF4RXhjbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuICgibWF4SW5jbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuICgibWluRXhjbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuICgibWluSW5jbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CiAgICAgICAgICAgIHJldHVybiAoIndoaXRlU3BhY2UiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CiAgICAgICAgICAgIHJldHVybiAoImVudW1lcmF0aW9uIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKICAgICAgICAgICAgcmV0dXJuICgibGVuZ3RoIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICAgICAgcmV0dXJuICgibWF4TGVuZ3RoIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKICAgICAgICAgICAgcmV0dXJuICgibWluTGVuZ3RoIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgogICAgICAgICAgICByZXR1cm4gKCJ0b3RhbERpZ2l0cyIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKICAgICAgICAgICAgcmV0dXJuICgiZnJhY3Rpb25EaWdpdHMiKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAoIkludGVybmFsIEVycm9yIik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAYmFzZTogIHRoZSBiYXNlIHR5cGUKICogQGZhY2V0czogIHRoZSBsaXN0IG9mIGZhY2V0cyB0byBjaGVjawogKiBAdmFsdWU6ICB0aGUgbGV4aWNhbCByZXByIG9mIHRoZSB2YWx1ZSB0byB2YWxpZGF0ZQogKiBAdmFsOiAgdGhlIHByZWNvbXB1dGVkIHZhbHVlCiAqIEBmaXJlRXJyb3JzOiAgaWYgMCwgb25seSBpbnRlcm5hbCBlcnJvcnMgd2lsbCBiZSBmaXJlZDsKICoJCSBvdGhlcndpc2UgYWxsIGVycm9ycyB3aWxsIGJlIGZpcmVkLgogKgogKiBDaGVjayBhIHZhbHVlIGFnYWluc3QgYWxsIGZhY2V0IGNvbmRpdGlvbnMKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXRzLAoJCQljb25zdCB4bWxDaGFyICogdmFsdWUsIGludCBmaXJlRXJyb3JzKQp7CiAgICBpbnQgcmV0ID0gMDsKICAgIGludCB0bXAgPSAwOwogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0ID0gZmFjZXRzOwoKICAgIHdoaWxlIChmYWNldCAhPSBOVUxMKSB7CiAgICAgICAgdHlwZSA9IGZhY2V0LT50eXBlOwogICAgICAgIGlmICh0eXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT04pIHsKICAgICAgICAgICAgdG1wID0gMTsKCiAgICAgICAgICAgIHdoaWxlIChmYWNldCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICB0bXAgPQogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlRmFjZXQoYmFzZSwgZmFjZXQsIHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+dmFsdWUpOwogICAgICAgICAgICAgICAgaWYgKHRtcCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmYWNldCA9IGZhY2V0LT5uZXh0OwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlCiAgICAgICAgICAgIHRtcCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXQoYmFzZSwgZmFjZXQsIHZhbHVlLCBjdHh0LT52YWx1ZSk7CgogICAgICAgIGlmICh0bXAgIT0gMCkgewogICAgICAgICAgICByZXQgPSB0bXA7CiAgICAgICAgICAgIGlmIChmaXJlRXJyb3JzKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBjdHh0LT5jdXIsIFhNTF9TQ0hFTUFTX0VSUl9GQUNFVCwKCQkJICAgICAgIkZhaWxlZCB0byB2YWxpZGF0ZSB0eXBlIHdpdGggZmFjZXQgJXNcbiIsCgkJCSAgICAgIChjb25zdCB4bWxDaGFyICopIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKHR5cGUpLAoJCQkgICAgICBOVUxMKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZhY2V0ICE9IE5VTEwpCiAgICAgICAgICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0czoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGJhc2U6ICB0aGUgYmFzZSB0eXBlCiAqIEBmYWNldHM6ICB0aGUgbGlzdCBvZiBmYWNldHMgdG8gY2hlY2sKICogQHZhbHVlOiAgdGhlIGxleGljYWwgcmVwciBvZiB0aGUgdmFsdWUgdG8gdmFsaWRhdGUKICogQHZhbDogIHRoZSBwcmVjb21wdXRlZCB2YWx1ZQogKgogKiBDaGVjayBhIHZhbHVlIGFnYWluc3QgYWxsIGZhY2V0IGNvbmRpdGlvbnMKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0cywgY29uc3QgeG1sQ2hhciAqIHZhbHVlKQp7CiAgICByZXR1cm4oeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbChjdHh0LCBiYXNlLCBmYWNldHMsIHZhbHVlLCAxKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlTaW1wbGUgdHlwZSB2YWxpZGF0aW9uCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWVVbmlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHR5cGU6ICB0aGUgdHlwZSBkZWNsYXJhdGlvbgogKiBAdmFsdWU6ICB0aGUgdmFsdWUgdG8gdmFsaWRhdGUKICoKICogVmFsaWRhdGVzIGEgdmFsdWUgYWdhaW5zdCBhIHVuaW9uLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlVW5pb24oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBjb25zdCB4bWxDaGFyICogdmFsdWUpCnsKICAgIGludCByZXQgPSAwOwogICAgY29uc3QgeG1sQ2hhciAqY3VyLCAqZW5kLCAqcHJlZml4LCAqbmNOYW1lOwogICAgeG1sQ2hhciAqdG1wOwogICAgeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlOwogICAgeG1sTnNQdHIgbnM7CiAgICBpbnQgbGVuOwogICAKCiAgICAvKiBQcm9jZXNzIHJlZmVyZW5jZWQgbWVtYmVyVHlwZXMuICovCiAgICBjdXIgPSB0eXBlLT5yZWY7CiAgICBkbyB7CiAgICAgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgICAgICBjdXIrKzsKICAgICAgICBlbmQgPSBjdXI7CiAgICAgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCiAgICAgICAgICAgIGVuZCsrOwogICAgICAgIGlmIChlbmQgPT0gY3VyKQogICAgICAgICAgICBicmVhazsKICAgICAgICB0bXAgPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKICAgICAgICAgbmNOYW1lID0geG1sU3BsaXRRTmFtZTModG1wLCAmbGVuKTsKICAgICAgICBpZiAobmNOYW1lICE9IE5VTEwpIHsKICAgICAgICAgICAgcHJlZml4ID0geG1sU3RybmR1cCh0bXAsIGxlbik7CiAgICAgICAgICAgIC8qIHByZWZpeCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZG9jLT5kaWN0LCB0bXAsIGxlbik7ICovCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcHJlZml4ID0gTlVMTDsKICAgICAgICAgICAgbmNOYW1lID0gdG1wOwogICAgICAgIH0KICAgICAgICAvKiBXZSB3b24ndCBkbyBhZGRpdGlvbmFsIGNoZWNrcyBoZXJlLAoJICogc2luY2UgdGhleSBoYXZlIGJlZW4gcGVyZm9ybWVkIGR1cmluZyBwYXJzaW5nLiAqLwogICAgICAgIG5zID0geG1sU2VhcmNoTnModHlwZS0+bm9kZS0+ZG9jLCB0eXBlLT5ub2RlLCBwcmVmaXgpOwogICAgICAgIC8qIG5hbWVzcGFjZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZG9jLT5kaWN0LCBucy0+aHJlZiwgLTEpOyAqLwogICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgbmNOYW1lLCBucy0+aHJlZik7CglpZiAodG1wICE9IE5VTEwpCgkgICAgeG1sRnJlZSh0bXApOwoJaWYgKHByZWZpeCAhPSBOVUxMKQoJICAgIHhtbEZyZWUoKHZvaWQgKilwcmVmaXgpOwogICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWVJbnRlcm5hbChjdHh0LCBzdWJ0eXBlLCB2YWx1ZSwgMCk7CiAgICAgICAgaWYgKChyZXQgPT0gMCkgfHwgKHJldCA9PSAtMSkpIHsKICAgICAgICAgICAgcmV0dXJuIChyZXQpOwogICAgICAgIH0KICAgICAgICBjdXIgPSBlbmQ7CiAgICB9IHdoaWxlICgqY3VyICE9IDApOwoKICAgIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgc3VidHlwZSA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgIGRvIHsKICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZUludGVybmFsKGN0eHQsIHN1YnR5cGUsIHZhbHVlLCAwKTsKICAgICAgICAgICAgaWYgKChyZXQgPT0gMCkgfHwgKHJldCA9PSAtMSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAocmV0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdWJ0eXBlID0gc3VidHlwZS0+bmV4dDsKICAgICAgICB9IHdoaWxlIChzdWJ0eXBlICE9IE5VTEwpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHR5cGU6ICB0aGUgdHlwZSBkZWNsYXJhdGlvbgogKiBAdmFsdWU6ICB0aGUgdmFsdWUgdG8gdmFsaWRhdGUKICoKICogVmFsaWRhdGUgYSB2YWx1ZSBhZ2FpbnN0IGEgc2ltcGxlIHR5cGUKICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGNvbnN0IHhtbENoYXIgKiB2YWx1ZSkKewogIHJldHVybiAoeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZUludGVybmFsKGN0eHQsIHR5cGUsIHZhbHVlLCAxKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGRlY2xhcmF0aW9uCiAqIEB2YWx1ZTogIHRoZSB2YWx1ZSB0byB2YWxpZGF0ZQogKiBAZmlyZUVycm9yczogIGlmIDAsIG9ubHkgaW50ZXJuYWwgZXJyb3JzIHdpbGwgYmUgZmlyZWQ7CiAqCQkgb3RoZXJ3aXNlIGFsbCBlcnJvcnMgd2lsbCBiZSBmaXJlZC4KICoKICogVmFsaWRhdGUgYSB2YWx1ZSBhZ2FpbnN0IGEgc2ltcGxlIHR5cGUKICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZUludGVybmFsKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgICBjb25zdCB4bWxDaGFyICogdmFsdWUsCgkJCSAgICAgaW50IGZpcmVFcnJvcnMpCnsKICAgIGludCByZXQgPSAwOwoKICAgIC8qCiAgICAgKiBGaXJzdCBub3JtYWxpemUgdGhlIHZhbHVlIGFjY29yZGluZ2x5IHRvIFNjaGVtYSBEYXRhdHlwZQogICAgICogNC4zLjYgd2hpdGVTcGFjZSBkZWZpbml0aW9uIG9mIHRoZSB3aGl0ZVNwYWNlIGZhY2V0IG9mIHR5cGUKICAgICAqCiAgICAgKiBUaGVuIGNoZWNrIHRoZSBub3JtYWxpemVkIHZhbHVlIGFnYWluc3QgdGhlIGxleGljYWwgc3BhY2Ugb2YgdGhlCiAgICAgKiB0eXBlLgogICAgICovCiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKICAgICAgICBpZiAoY3R4dC0+dmFsdWUgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUoY3R4dC0+dmFsdWUpOwogICAgICAgICAgICBjdHh0LT52YWx1ZSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbFByZWRlZlR5cGVOb2RlKHR5cGUsIHZhbHVlLCAmKGN0eHQtPnZhbHVlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5jdXIpOwogICAgICAgIGlmICgoZmlyZUVycm9ycykgJiYgKHJldCAhPSAwKSkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgWE1MX1NDSEVNQVNfRVJSX1ZBTFVFLAoJICAgIAkJICAiRmFpbGVkIHRvIHZhbGlkYXRlIGJhc2ljIHR5cGUgJXNcbiIsCgkJCSAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgfQogICAgfSBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTikgewogICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZTsKICAgICAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCiAgICAgICAgYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgICAgIGlmIChiYXNlICE9IE5VTEwpIHsKICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZUludGVybmFsKGN0eHQsIGJhc2UsCgkgICAgCQkJdmFsdWUsIGZpcmVFcnJvcnMpOwogICAgICAgIH0gZWxzZSBpZiAodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkgewoJICAgIFRPRE8KICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogRG8gbm90IHZhbGlkYXRlIGZhY2V0cyBvciBhdHRyaWJ1dGVzIHdoZW4gd29ya2luZyBvbgoJICogYnVpbGRpbmcgdGhlIFNjaGVtYXMKICAgICAgICAgKi8KICAgICAgICBpZiAoY3R4dC0+c2NoZW1hICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKHJldCA9PSAwKSB7CiAgICAgICAgICAgICAgICBmYWNldCA9IHR5cGUtPmZhY2V0czsKICAgICAgICAgICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgYmFzZSwgZmFjZXQsCgkJCQl2YWx1ZSwgZmlyZUVycm9ycyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgewogICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZTsKCiAgICAgICAgYmFzZSA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgIGlmIChiYXNlICE9IE5VTEwpIHsKICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZUludGVybmFsKGN0eHQsIGJhc2UsCgkgICAgCQkJdmFsdWUsIGZpcmVFcnJvcnMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgVE9ET30KICAgIH0gZWxzZSBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfTElTVCkgewogICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZTsKICAgICAgICBjb25zdCB4bWxDaGFyICpjdXIsICplbmQ7Cgl4bWxDaGFyICp0bXA7CiAgICAgICAgaW50IHJldDI7CgogICAgICAgIGJhc2UgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICBpZiAoYmFzZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJCSJJbnRlcm5hbDogTGlzdCB0eXBlICVzIGhhcyBubyBiYXNlIHR5cGVcbiIsCgkJCXR5cGUtPm5hbWUsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKC0xKTsKICAgICAgICB9CiAgICAgICAgY3VyID0gdmFsdWU7CiAgICAgICAgZG8gewogICAgICAgICAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgICAgICAgICBjdXIrKzsKICAgICAgICAgICAgZW5kID0gY3VyOwogICAgICAgICAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKICAgICAgICAgICAgICAgIGVuZCsrOwogICAgICAgICAgICBpZiAoZW5kID09IGN1cikKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB0bXAgPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKICAgICAgICAgICAgcmV0MiA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWVJbnRlcm5hbChjdHh0LCBiYXNlLAoJICAgIAkJCXRtcCwgZmlyZUVycm9ycyk7CgkgICAgeG1sRnJlZSh0bXApOwogICAgICAgICAgICBpZiAocmV0MiAhPSAwKQogICAgICAgICAgICAgICAgcmV0ID0gMTsKICAgICAgICAgICAgY3VyID0gZW5kOwogICAgICAgIH0gd2hpbGUgKCpjdXIgIT0gMCk7CiAgICB9ICBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9VTklPTikgewogICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWVVbmlvbihjdHh0LCB0eXBlLCB2YWx1ZSk7CiAgICAgICAgaWYgKChmaXJlRXJyb3JzKSAmJiAocmV0ICE9IDApKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgY3R4dC0+Y3VyLCBYTUxfU0NIRU1BU19FUlJfVkFMVUUsCgkgICAgCQkgICJGYWlsZWQgdG8gdmFsaWRhdGUgdHlwZSAlc1xuIiwgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUT0RPCiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlET00gVmFsaWRhdGlvbiBjb2RlCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIGludCB4bWxTY2hlbWFWYWxpZGF0ZUNvbnRlbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyBpbnQgeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIGVsZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CnN0YXRpYyBpbnQgeG1sU2NoZW1hVmFsaWRhdGVUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIGVsZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CgoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyU3RhdGVzOgogKiBAc3RhdGU6ICBhIGxpc3Qgb2YgYXR0cmlidXRlIHN0YXRlcwogKgogKiBGcmVlIHRoZSBnaXZlbiBsaXN0IG9mIGF0dHJpYnV0ZSBzdGF0ZXMKICoKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVTdGF0ZXMoeG1sU2NoZW1hQXR0clN0YXRlUHRyIHN0YXRlKQp7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgdG1wOwogICAgd2hpbGUgKHN0YXRlICE9IE5VTEwpIHsKCXRtcCA9IHN0YXRlOwoJc3RhdGUgPSBzdGF0ZS0+bmV4dDsJCgl4bWxGcmVlKHRtcCk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFSZWdpc3RlckF0dHJpYnV0ZXM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBhdHRyczogIGEgbGlzdCBvZiBhdHRyaWJ1dGVzCiAqCiAqIFJlZ2lzdGVyIHRoZSBsaXN0IG9mIGF0dHJpYnV0ZXMgYXMgdGhlIHNldCB0byBiZSB2YWxpZGF0ZWQgb24gdGhhdCBlbGVtZW50CiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBvdGhlcndpc2UKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUmVnaXN0ZXJBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxBdHRyUHRyIGF0dHJzKQp7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgdG1wOwoKICAgIGN0eHQtPmF0dHIgPSBOVUxMOwogICAgY3R4dC0+YXR0clRvcCA9IE5VTEw7CiAgICB3aGlsZSAoYXR0cnMgIT0gTlVMTCkgewogICAgICAgIGlmICgoYXR0cnMtPm5zICE9IE5VTEwpICYmCiAgICAgICAgICAgICh4bWxTdHJFcXVhbChhdHRycy0+bnMtPmhyZWYsIHhtbFNjaGVtYUluc3RhbmNlTnMpKSkgewogICAgICAgICAgICBhdHRycyA9IGF0dHJzLT5uZXh0OwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgICAgIHRtcCA9ICh4bWxTY2hlbWFBdHRyU3RhdGVQdHIpCgkgICAgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyU3RhdGUpKTsKICAgICAgICAgICAgaWYgKHRtcCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KGN0eHQsICJyZWdpc3RlcmluZyBhdHRyaWJ1dGVzIiwgTlVMTCk7CiAgICAgICAgICAgICAgICByZXR1cm4gKC0xKTsKICAgICAgICAgICAgfQoJdG1wLT5hdHRyID0gYXR0cnM7Cgl0bXAtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOOwoJdG1wLT5uZXh0ID0gTlVMTDsKCWlmIChjdHh0LT5hdHRyID09IE5VTEwpIAogICAgICAgICAgICBjdHh0LT5hdHRyID0gdG1wOwoJZWxzZQoJICAgIGN0eHQtPmF0dHJUb3AtPm5leHQgPSB0bXA7CgljdHh0LT5hdHRyVG9wID0gdG1wOwogICAgICAgIGF0dHJzID0gYXR0cnMtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSBub2RlIGNhcnJ5aW5nIGl0LgogKgogKiBDaGVjayB0aGF0IHRoZSByZWdpc3RlcmVkIHNldCBvZiBhdHRyaWJ1dGVzIG9uIHRoZSBjdXJyZW50IG5vZGUKICogaGFzIGJlZW4gcHJvcGVybHkgdmFsaWRhdGVkLgogKgogKiBSZXR1cm5zIDAgaWYgdmFsaWRpdHkgY29uc3RyYWludHMgYXJlIG1ldCwgMSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQXR0cmlidXRlcyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBjdXI7ICAgIAoKICAgIGN1ciA9IGN0eHQtPmF0dHI7CiAgICB3aGlsZSAoKGN1ciAhPSBOVUxMKSAmJiAoY3VyICE9IGN0eHQtPmF0dHJUb3AtPm5leHQpKSB7CglpZiAoY3VyLT5zdGF0ZSAhPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQpIHsJICAgIAkgICAgCiAgICAgICAgICAgIHJldCA9IDE7CgkgICAgaWYgKGN1ci0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOKQogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9BVFRSVU5LTk9XTiwKCSAgICAJCSAgIkF0dHJpYnV0ZSAlcyBvbiAlcyBpcyB1bmtub3duXG4iLAoJCSAgICBjdXItPmF0dHItPm5hbWUsIG5vZGUtPm5hbWUpOwoJICAgIGVsc2UgaWYgKGN1ci0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9QUk9ISUJJVEVEKQoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0FUVFJVTktOT1dOLAoJCSAgICAiQXR0cmlidXRlICVzIG9uICVzIGlzIHByb2hpYml0ZWRcbiIsCgkJICAgIGN1ci0+YXR0ci0+bmFtZSwgbm9kZS0+bmFtZSk7CgkgICAgZWxzZSBpZiAoY3VyLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfVkFMVUUpCgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfQVRUUklOVkFMSUQsCgkJICAgICJBdHRyaWJ1dGUgJXMgb24gJXMgZG9lcyBub3QgbWF0Y2ggdHlwZVxuIiwKCQkgICAgY3VyLT5hdHRyLT5uYW1lLCBub2RlLT5uYW1lKTsKCSAgICBlbHNlIGlmIChjdXItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfTUlTU0lORykgewoJCWlmIChjdXItPmRlY2wtPnJlZiAhPSBOVUxMKQoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9NSVNTSU5HLAoJCQkiQXR0cmlidXRlICVzIG9uICVzIGlzIHJlcXVpcmVkIGJ1dCBtaXNzaW5nXG4iLCAKCQkJY3VyLT5kZWNsLT5yZWYsIG5vZGUtPm5hbWUpOwoJCWVsc2UKCQkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfTUlTU0lORywKCQkJIkF0dHJpYnV0ZSAlcyBvbiAlcyBpcyByZXF1aXJlZCBidXQgbWlzc2luZ1xuIiwgCgkJCWN1ci0+ZGVjbC0+bmFtZSwgbm9kZS0+bmFtZSk7CiAgICAgICAgfQogICAgfQoJY3VyID0gY3VyLT5uZXh0OwogICAgfQoKICAgIHJldHVybiAocmV0KTsKfQoKI2lmIDAJCS8qIE5vdCBjdXJyZW50bHkgdXNlZCAtIHJlbW92ZSBpZiBldmVyIG5lZWRlZCAqLwovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVDb250ZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQHR5cGU6ICB0aGUgdHlwZSBkZWNsYXJhdGlvbgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IGV4cGVjdGVkIHRvIGJlIGEgc2ltcGxlIHR5cGUKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlQ29udGVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBiYXNlOwogICAgeG1sQ2hhciAqdmFsdWU7CiAgICBpbnQgcmV0ID0gMDsKCiAgICBjaGlsZCA9IGN0eHQtPm5vZGU7CiAgICB0eXBlID0gY3R4dC0+dHlwZTsKCiAgICAvKgogICAgICogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKFR5cGUpOiAzLjEuMwogICAgICovCiAgICB2YWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KGNoaWxkKTsKICAgIC8qIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWUoY3R4dCwgdHlwZSwgdmFsdWUpOyAqLwogICAgc3dpdGNoICh0eXBlLT50eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046ewogICAgICAgICAgICAgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CgogICAgICAgICAgICAgICAgYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgICAgICAgICAgICAgaWYgKGJhc2UgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWUoY3R4dCwgYmFzZSwgdmFsdWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFRPRE99CiAgICAgICAgICAgICAgICBpZiAocmV0ID09IDApIHsKICAgICAgICAgICAgICAgICAgICBmYWNldCA9IHR5cGUtPmZhY2V0czsKICAgICAgICAgICAgICAgICAgICByZXQgPQogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyhjdHh0LCBiYXNlLCBmYWNldCwgdmFsdWUpOwogICAgICAgICAgICAgICAgfQoJCS8qIAoJCSAqIFRoaXMgc2hvdWxkIGF0dGVtcHQgdG8gdmFsaWRhdGUgdGhlIGF0dHJpYnV0ZXMgZXZlbgoJCSAqIHdoZW4gdmFsaWRhdGlvbiBvZiB0aGUgdmFsdWUgZmFpbGVkLgoJCSAqLwoJCS8qCgkJaWYgKHR5cGUtPmF0dHJpYnV0ZXMgIT0gTlVMTCkgewoJCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoY3R4dCwgbm9kZSwKCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmF0dHJpYnV0ZXMpOwoJCX0KCQkqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT046ewoJICAgICAgICBUT0RPCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CgkgICAgVE9ETwogICAgfQogICAgaWYgKHZhbHVlICE9IE5VTEwpCiAgICAgICAgeG1sRnJlZSh2YWx1ZSk7CgogICAgcmV0dXJuIChyZXQpOwp9CiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlQ2hlY2tOb2RlTGlzdAogKiBAbm9kZWxpc3Q6IHRoZSBsaXN0IG9mIG5vZGVzCiAqCiAqIENoZWNrIHRoZSBub2RlIGxpc3QgaXMgb25seSBtYWRlIG9mIHRleHQgbm9kZXMgYW5kIGVudGl0aWVzIHBvaW50aW5nCiAqIHRvIHRleHQgbm9kZXMKICoKICogUmV0dXJucyAxIGlmIHRydWUsIDAgaWYgZmFsc2UgYW5kIC0xIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVDaGVja05vZGVMaXN0KHhtbE5vZGVQdHIgbm9kZWxpc3QpCnsKICAgIHdoaWxlIChub2RlbGlzdCAhPSBOVUxMKSB7CiAgICAgICAgaWYgKG5vZGVsaXN0LT50eXBlID09IFhNTF9FTlRJVFlfUkVGX05PREUpIHsKICAgICAgICAgICAgVE9ETyAgICAgICAgICAgICAgICAvKiBpbXBsZW1lbnQgcmVjdXJzaW9uIGluIHRoZSBlbnRpdHkgY29udGVudCAqLwogICAgICAgIH0KICAgICAgICBpZiAoKG5vZGVsaXN0LT50eXBlICE9IFhNTF9URVhUX05PREUpICYmCiAgICAgICAgICAgIChub2RlbGlzdC0+dHlwZSAhPSBYTUxfQ09NTUVOVF9OT0RFKSAmJgogICAgICAgICAgICAobm9kZWxpc3QtPnR5cGUgIT0gWE1MX1BJX05PREUpICYmCiAgICAgICAgICAgIChub2RlbGlzdC0+dHlwZSAhPSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkgewogICAgICAgICAgICByZXR1cm4gKDApOwogICAgICAgIH0KICAgICAgICBub2RlbGlzdCA9IG5vZGVsaXN0LT5uZXh0OwogICAgfQogICAgcmV0dXJuICgxKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNraXBJZ25vcmVkOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAdHlwZTogIHRoZSBjdXJyZW50IHR5cGUgY29udGV4dAogKiBAbm9kZTogIHRoZSB0b3Agbm9kZS4KICoKICogU2tpcCBpZ25vcmFibGUgbm9kZXMgaW4gdGhhdCBjb250ZXh0CiAqCiAqIFJldHVybnMgdGhlIG5ldyBzaWJsaW5nCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyB4bWxOb2RlUHRyCnhtbFNjaGVtYVNraXBJZ25vcmVkKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0IEFUVFJJQlVURV9VTlVTRUQsCiAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpbnQgbWl4ZWQgPSAwOwoKICAgIC8qCiAgICAgKiBUT0RPIGNvbXBsZXRlIGFuZCBoYW5kbGUgZW50aXRpZXMKICAgICAqLwogICAgbWl4ZWQgPSAoKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgfHwKICAgICAgICAgICAgICh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRURfT1JfRUxFTUVOVFMpKTsKICAgIHdoaWxlICgobm9kZSAhPSBOVUxMKSAmJgogICAgICAgICAgICgobm9kZS0+dHlwZSA9PSBYTUxfQ09NTUVOVF9OT0RFKSB8fAogICAgICAgICAgICAoKG1peGVkID09IDEpICYmIChub2RlLT50eXBlID09IFhNTF9URVhUX05PREUpKSB8fAogICAgICAgICAgICAoKCh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpICYmCiAgICAgICAgICAgICAgKG5vZGUtPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgJiYgKElTX0JMQU5LX05PREUobm9kZSkpKSkpKSB7CiAgICAgICAgbm9kZSA9IG5vZGUtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKG5vZGUpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjazoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgZWxlbWVudCBkZXRlY3RlZCAobWlnaHQgYmUgTlVMTCkKICogQHR5cGU6ICB0aGUgdHlwZQogKgogKiBBIHRyYW5zaXRpb24gaGFzIGJlZW4gbWFkZSBpbiB0aGUgYXV0b21hdGEgYXNzb2NpYXRlZCB0byBhbiBlbGVtZW50CiAqIGNvbnRlbnQgbW9kZWwKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZhbGlkYXRlQ2FsbGJhY2soeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvbGR0eXBlID0gY3R4dC0+dHlwZTsKICAgIHhtbE5vZGVQdHIgb2xkbm9kZSA9IGN0eHQtPm5vZGU7CgojaWZkZWYgREVCVUdfQ09OVEVOVAogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVZhbGlkYXRlQ2FsbGJhY2s6ICVzLCAlcywgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgbmFtZSwgdHlwZS0+bmFtZSwgbm9kZS0+bmFtZSk7CiNlbmRpZgogICAgY3R4dC0+dHlwZSA9IHR5cGU7CiAgICBjdHh0LT5ub2RlID0gbm9kZTsKICAgIHhtbFNjaGVtYVZhbGlkYXRlQ29udGVudChjdHh0LCBub2RlKTsKICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwogICAgY3R4dC0+bm9kZSA9IG9sZG5vZGU7Cn0KCgojaWYgMAoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlUmVzdHJpY3Rpb25UeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSB0b3Agbm9kZS4KICoKICogVmFsaWRhdGUgdGhlIGNvbnRlbnQgb2YgYSByZXN0cmljdGlvbiB0eXBlLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVSZXN0cmljdGlvblR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIGludCByZXQ7CgogICAgY2hpbGQgPSBjdHh0LT5ub2RlOwogICAgdHlwZSA9IGN0eHQtPnR5cGU7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJICAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVJlc3RyaWN0aW9uVHlwZSAlc1xuIiwKCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qCiAgICAgKiBPbmx5IHRleHQgYW5kIHRleHQgYmFzZWQgZW50aXRpZXMgcmVmZXJlbmNlcyBzaGFsbCBiZSBmb3VuZCB0aGVyZQogICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUNoZWNrTm9kZUxpc3QoY2hpbGQpOwogICAgaWYgKHJldCA8IDApIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZSAlcyBjb250ZW50XG4iLAoJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfSBlbHNlIGlmIChyZXQgPT0gMCkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX05PVFNJTVBMRSwKCQkgICAgICAiRWxlbWVudCAlcyBjb250ZW50IGlzIG5vdCBhIHNpbXBsZSB0eXBlXG4iLAoJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgY3R4dC0+dHlwZSA9IHR5cGUtPnN1YnR5cGVzOwogICAgeG1sU2NoZW1hVmFsaWRhdGVDb250ZW50KGN0eHQsIG5vZGUpOwogICAgY3R4dC0+dHlwZSA9IHR5cGU7CiAgICByZXR1cm4gKHJldCk7Cn0KI2VuZGlmCgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSB0b3Agbm9kZS4KICoKICogVmFsaWRhdGUgdGhlIGNvbnRlbnQgb2YgYW4gc2ltcGxlIHR5cGUuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgYmFzZSwgdmFyaWV0eTsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCByZXQ7CiAgICB4bWxDaGFyICp2YWx1ZTsKICAgIAoKICAgIGNoaWxkID0gY3R4dC0+bm9kZTsKICAgIHR5cGUgPSBjdHh0LT50eXBlOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlICVzXG4iLAoJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgLyoKICAgICAqIE9ubHkgdGV4dCBhbmQgdGV4dCBiYXNlZCBlbnRpdGllcyByZWZlcmVuY2VzIHNoYWxsIGJlIGZvdW5kIHRoZXJlCiAgICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlQ2hlY2tOb2RlTGlzdChjaGlsZCk7CiAgICBpZiAocmV0IDwgMCkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlICVzIGNvbnRlbnRcbiIsCgkJICAgICAgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9IGVsc2UgaWYgKHJldCA9PSAwKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfTk9UU0lNUExFLAoJCSAgICAgICJFbGVtZW50ICVzIGNvbnRlbnQgaXMgbm90IGEgc2ltcGxlIHR5cGVcbiIsCgkJICAgICAgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKgogICAgICogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKFR5cGUpOiAzLjEuMQogICAgICovICAgIAogICAgCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKICAgICAgICBpZiAoKGF0dHItPm5zID09IE5VTEwpIHx8CiAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYUluc3RhbmNlTnMpKSB8fAogICAgICAgICAgICAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmlsIikpICYmCiAgICAgICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzY2hlbWFzTG9jYXRpb24iKSkgJiYKICAgICAgICAgICAgICgheG1sU3RyRXF1YWwKICAgICAgICAgICAgICAoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24iKSkpKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVkFMSURBVFRSLAoJICAgIAkJICAiRWxlbWVudCAlczogYXR0cmlidXRlICVzIHNob3VsZCBub3QgYmUgcHJlc2VudFxuIiwKCQkJICBub2RlLT5uYW1lLCBhdHRyLT5uYW1lKTsKICAgICAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgICAgIH0KICAgIH0KICAgIC8qIFRPRE86CiAgICAgKiBJZiB7dmFyaWV0eX0gaXMgt2F0b21pY7cgdGhlbiB0aGUge3ZhcmlldHl9IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0KICAgICAqIG11c3QgYmUgt2F0b21pY7cuIAogICAgICogSWYge3ZhcmlldHl9IGlzILdsaXN0tyB0aGVuIHRoZSB7dmFyaWV0eX0gb2Yge2l0ZW0gdHlwZSBkZWZpbml0aW9ufQogICAgICogbXVzdCBiZSBlaXRoZXIgt2F0b21pY7cgb3Igt3VuaW9uty4gCiAgICAgKiBJZiB7dmFyaWV0eX0gaXMgt3VuaW9utyB0aGVuIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gbXVzdCBiZSBhIGxpc3QKICAgICAqIG9mIGRhdGF0eXBlIGRlZmluaXRpb25zLiAKICAgICAqLwogICAgaWYgKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlOyAiCgkJICAgICAgInNpbXBsZSB0eXBlICVzIGRvZXMgbm90IGRlZmluZSBhIHZhcmlldHlcbiIsCgkJICAgICAgbm9kZS0+bmFtZSwgTlVMTCk7CglyZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAvKiBWYXJpZXRpZXM6IFJlc3RyaWN0aW9uIG9yIExpc3Qgb3IgVW5pb24uICovCiAgICB2YXJpZXR5ID0gdHlwZS0+c3VidHlwZXM7CiAgICBjdHh0LT50eXBlID0gdmFyaWV0eTsgICAgICAgIAogICAgdmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudChjaGlsZCk7CiAgICBzd2l0Y2ggKHZhcmlldHktPnR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTjp7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCiAgICAgICAgICAgICAgICBiYXNlID0gdmFyaWV0eS0+YmFzZVR5cGU7CiAgICAgICAgICAgICAgICBpZiAoYmFzZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZShjdHh0LCBiYXNlLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVE9ET30KICAgICAgICAgICAgICAgIGlmIChyZXQgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIGZhY2V0ID0gdmFyaWV0eS0+ZmFjZXRzOwogICAgICAgICAgICAgICAgICAgIHJldCA9CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzKGN0eHQsIGJhc2UsIGZhY2V0LCB2YWx1ZSk7CiAgICAgICAgICAgICAgICB9CgkJLyogUmVtb3ZlZCBkdWUgdG8gY2hhbmdlcyBvZiBhdHRyaWJ1dGUgdmFsaWRhdGlvbjoKCQlpZiAoKHJldCA9PSAwKSAmJiAodmFyaWV0eS0+YXR0cmlidXRlcyAhPSBOVUxMKSkgewoJCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoY3R4dCwgbm9kZSwKCQkgICAgCQl2YXJpZXR5LT5hdHRyaWJ1dGVzKTsKCQl9CgkJKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfTElTVDoKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1VOSU9OOiB7CgkgICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWUoY3R4dCwgdmFyaWV0eSwgdmFsdWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBkZWZhdWx0OnsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkJICAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGU7ICIKCQkJICAgICAgInNpbXBsZSB0eXBlICVzIGRlZmluZXMgdW5rbm93biBjb250ZW50OiAlc1xuIiwKCQkJICAgICAgdmFyaWV0eS0+bmFtZSwgTlVMTCk7CgkJcmV0ID0gY3R4dC0+ZXJyOwoJICAgIH0KICAgIH0KICAgIGlmICh2YWx1ZSAhPSBOVUxMKQogICAgICAgIHhtbEZyZWUodmFsdWUpOwoKICAgIC8qIFRoaXMgd2FzIHJlbW92ZWQsIHNpbmNlIGEgc2ltcGxlIGNvbnRlbnQgaXMgbm90IGEgY29udGVudCBvZiBhCiAgICAgKiBzaW1wbGUgdHlwZSwgYnV0IG9mIGEgY29tcGxleCB0eXBlLgogICAgICogcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVDb250ZW50KGN0eHQsIG5vZGUpOwogICAgICovCiAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudFR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IHR5cGUuCiAqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChDb21wbGV4IFR5cGUpCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbE5vZGVQdHIgY2hpbGQ7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxSZWdFeGVjQ3R4dFB0ciBvbGRyZWdleHA7ICAgICAgICAvKiBjb250IG1vZGVsIG9mIHRoZSBwYXJlbnQgKi8KICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZGVjbDsKICAgIGludCByZXQ7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgYXR0cnMgPSBOVUxMLCBhdHRyVG9wID0gTlVMTDsKCiAgICAvKiAKICAgICAqIFRPRE86IExvb2sgaW50byAieG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50IiBmb3IgbWlzc2luZyBwYXJ0cywgd2hpY2ggc2hvdWxkCiAgICAgKiBnbyBpbiBoZXJlIGFzIHdlbGwuCiAgICAgKi8KCiAgICAvKiBUT0RPOiBJcyB0aGlzIG9uZSBjYWxsZWQgYWx3YXlzIHdpdGggYW4gZWxlbWVudCBkZWNsYXJhdGlvbiBhcyB0aGUgCiAgICAgKiBjb250ZXh0J3MgdHlwZT8KICAgICAqLwoKICAgIG9sZHJlZ2V4cCA9IGN0eHQtPnJlZ2V4cDsKCiAgICBjaGlsZCA9IGN0eHQtPm5vZGU7CiAgICB0eXBlID0gY3R4dC0+dHlwZTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudFR5cGVcbiIsCgkJICAgICAgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICBpZiAoY2hpbGQgPT0gTlVMTCkgewogICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPiAwKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX01JU1NJTkcsCgkgICAgCQkgICJFbGVtZW50ICVzOiBtaXNzaW5nIGNoaWxkICVzXG4iLAoJCQkgIG5vZGUtPm5hbWUsIHR5cGUtPm5hbWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CgogICAgLyoKICAgICAqIFZlcmlmeSB0aGUgZWxlbWVudCBtYXRjaGVzCiAgICAgKi8KICAgIGlmICgheG1sU3RyRXF1YWwoY2hpbGQtPm5hbWUsIHR5cGUtPm5hbWUpKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycjMoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX1dST05HRUxFTSwKCQkgICAgICAgIkVsZW1lbnQgJXM6IG1pc3NpbmcgY2hpbGQgJXMgZm91bmQgJXNcbiIsCgkJICAgICAgIG5vZGUtPm5hbWUsIHR5cGUtPm5hbWUsIGNoaWxkLT5uYW1lKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAvKgogICAgICogVmVyaWZ5IHRoZSBhdHRyaWJ1dGVzCiAgICAgKi8KICAgIAogICAgYXR0cnMgPSBjdHh0LT5hdHRyOyAgICAKICAgIGF0dHJUb3AgPSBjdHh0LT5hdHRyVG9wOwogICAgCiAgICB4bWxTY2hlbWFSZWdpc3RlckF0dHJpYnV0ZXMoY3R4dCwgY2hpbGQtPnByb3BlcnRpZXMpOwogICAgICAgIAogICAgLyogCiAgICAgKiBBbiBlbGVtZW50IGRlY2xhcmF0aW9uIGRvZXMgbm90IGhvbGQgYW55IGluZm9ybWF0aW9uIGFib3V0CiAgICAgKiBhdHRyaWJ1dGVzOyB0aHVzLCB0aGUgZm9sbG93aW5nIHdhcyByZW1vdmVkLgogICAgICovCiAgICAvKiB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoY3R4dCwgY2hpbGQsIHR5cGUtPmF0dHJpYnV0ZXMpOyAqLwoKICAgIC8qCiAgICAgKiBWZXJpZnkgdGhlIGVsZW1lbnQgY29udGVudCByZWN1cnNpdmVseQogICAgICovCiAgICBkZWNsID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHR5cGU7CiAgICBvbGRyZWdleHAgPSBjdHh0LT5yZWdleHA7CiAgICBpZiAoZGVjbC0+Y29udE1vZGVsICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5yZWdleHAgPSB4bWxSZWdOZXdFeGVjQ3R4dChkZWNsLT5jb250TW9kZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHhtbFJlZ0V4ZWNDYWxsYmFja3MpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjaywgY3R4dCk7CiNpZmRlZiBERUJVR19BVVRPTUFUQQogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiPT09PT4gJXNcbiIsIG5vZGUtPm5hbWUpOwojZW5kaWYKICAgIH0KICAgIHhtbFNjaGVtYVZhbGlkYXRlVHlwZShjdHh0LCBjaGlsZCwgKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMpOwoKICAgIGlmIChkZWNsLT5jb250TW9kZWwgIT0gTlVMTCkgewogICAgICAgIHJldCA9IHhtbFJlZ0V4ZWNQdXNoU3RyaW5nKGN0eHQtPnJlZ2V4cCwgTlVMTCwgTlVMTCk7CiNpZmRlZiBERUJVR19BVVRPTUFUQQogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiPT09PT4gJXMgOiAlZFxuIiwgbm9kZS0+bmFtZSwgcmV0KTsKI2VuZGlmCiAgICAgICAgaWYgKHJldCA9PSAwKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0VMRU1DT05ULAoJICAgIAkJICAiRWxlbWVudCAlcyBjb250ZW50IGNoZWNrIGZhaWxlZFxuIiwKCQkJICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICB9IGVsc2UgaWYgKHJldCA8IDApIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfRUxFTUNPTlQsCgkgICAgCQkgICJFbGVtZW50ICVzIGNvbnRlbnQgY2hlY2sgZmFpbHVyZVxuIiwKCQkJICBub2RlLT5uYW1lLCBOVUxMKTsKI2lmZGVmIERFQlVHX0NPTlRFTlQKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbGVtZW50ICVzIGNvbnRlbnQgY2hlY2sgc3VjY2VlZGVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS0+bmFtZSk7CgojZW5kaWYKICAgICAgICB9CiAgICAgICAgeG1sUmVnRnJlZUV4ZWNDdHh0KGN0eHQtPnJlZ2V4cCk7CiAgICB9CiAgICAvKgogICAgICogVmVyaWZ5IHRoYXQgYWxsIGF0dHJpYnV0ZXMgd2VyZSBTY2hlbWFzLXZhbGlkYXRlZAogICAgICovCiAgICB4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZXMoY3R4dCwgbm9kZSk7CiAgICBpZiAoY3R4dC0+YXR0ciAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVN0YXRlcyhjdHh0LT5hdHRyKTsKICAgIGN0eHQtPmF0dHIgPSBhdHRyczsgICAgCiAgICBjdHh0LT5hdHRyVG9wID0gYXR0clRvcDsKICAgIGN0eHQtPnJlZ2V4cCA9IG9sZHJlZ2V4cDsKICAgIGN0eHQtPm5vZGUgPSBjaGlsZDsKICAgIGN0eHQtPnR5cGUgPSB0eXBlOwogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVCYXNpY1R5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IGV4cGVjdGVkIHRvIGJlIGEgYmFzaWMgdHlwZSB0eXBlCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUJhc2ljVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpbnQgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCwgY3VyOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgeG1sQ2hhciAqdmFsdWU7ICAgICAgICAgICAgIC8qIGxleGljYWwgcmVwcmVzZW50YXRpb24gKi8KCiAgICBjaGlsZCA9IGN0eHQtPm5vZGU7CiAgICB0eXBlID0gY3R4dC0+dHlwZTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQmFzaWNUeXBlXG4iLAoJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgLyoKICAgICAqIEZpcnN0IGNoZWNrIHRoZSBjb250ZW50IG1vZGVsIG9mIHRoZSBub2RlLgogICAgICovCiAgICBjdXIgPSBjaGlsZDsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewogICAgICAgIHN3aXRjaCAoY3VyLT50eXBlKSB7CiAgICAgICAgICAgIGNhc2UgWE1MX1RFWFRfTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9QSV9OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9DT01NRU5UX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX1hJTkNMVURFX1NUQVJUOgogICAgICAgICAgICBjYXNlIFhNTF9YSU5DTFVERV9FTkQ6CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBYTUxfRU5USVRZX1JFRl9OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9FTlRJVFlfTk9ERToKICAgICAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgICAgIGNhc2UgWE1MX0VMRU1FTlRfTk9ERToKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVkFMSURFTEVNLAoJCQkgICAgICAiRWxlbWVudCAlczogY2hpbGQgJXMgc2hvdWxkIG5vdCBiZSBwcmVzZW50XG4iLAoJCQkgICAgICBub2RlLT5uYW1lLCBjdXItPm5hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgICAgICAgICBjYXNlIFhNTF9BVFRSSUJVVEVfTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfRE9DVU1FTlRfTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfRE9DVU1FTlRfVFlQRV9OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9ET0NVTUVOVF9GUkFHX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX05PVEFUSU9OX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX0hUTUxfRE9DVU1FTlRfTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfRFREX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX0VMRU1FTlRfREVDTDoKICAgICAgICAgICAgY2FzZSBYTUxfQVRUUklCVVRFX0RFQ0w6CiAgICAgICAgICAgIGNhc2UgWE1MX0VOVElUWV9ERUNMOgogICAgICAgICAgICBjYXNlIFhNTF9OQU1FU1BBQ0VfREVDTDoKI2lmZGVmIExJQlhNTF9ET0NCX0VOQUJMRUQKICAgICAgICAgICAgY2FzZSBYTUxfRE9DQl9ET0NVTUVOVF9OT0RFOgojZW5kaWYKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVkFMSURFTEVNLAoJCQkgICAgICAiRWxlbWVudCAlczogbm9kZSB0eXBlIG9mIG5vZGUgdW5leHBlY3RlZCBoZXJlXG4iLAoJCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICAgICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgICAgICB9CiAgICAgICAgY3VyID0gY3VyLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkID09IE5VTEwpCiAgICAgICAgdmFsdWUgPSBOVUxMOwogICAgZWxzZQogICAgICAgIHZhbHVlID0geG1sTm9kZUdldENvbnRlbnQoY2hpbGQtPnBhcmVudCk7CgogICAgaWYgKGN0eHQtPnZhbHVlICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUoY3R4dC0+dmFsdWUpOwogICAgICAgIGN0eHQtPnZhbHVlID0gTlVMTDsKICAgIH0KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlUHJlZGVmaW5lZFR5cGUodHlwZSwgdmFsdWUsICYoY3R4dC0+dmFsdWUpKTsKICAgIGlmICh2YWx1ZSAhPSBOVUxMKQogICAgICAgIHhtbEZyZWUodmFsdWUpOwogICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfVkFMVUUsCgkJICAgICAgIkVsZW1lbnQgJXM6IGZhaWxlZCB0byB2YWxpZGF0ZSBiYXNpYyB0eXBlICVzXG4iLAoJCSAgICAgIG5vZGUtPm5hbWUsIHR5cGUtPm5hbWUpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgZXhwZWN0ZWQgdG8gYmUgYSBjb21wbGV4IHR5cGUgdHlwZQogKiB4bWxzY2hlbWEtMS5odG1sI2N2Yy1jb21wbGV4LXR5cGUKICogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKENvbXBsZXggVHlwZSkKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZTsKICAgIGludCByZXQ7CgogICAgLyogVE9ETzogSGFuZGxlIHhzZDpyZXN0cmljdGlvbiAmIHhzZDpleHRlbnNpb24gKi8KCiAgICBjaGlsZCA9IGN0eHQtPm5vZGU7CiAgICB0eXBlID0gY3R4dC0+dHlwZTsKICAgIGN0eHQtPmN1ciA9IG5vZGU7CgogICAgc3dpdGNoICh0eXBlLT5jb250ZW50VHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOgoJICAgIGlmICh0eXBlLT5iYXNlVHlwZSAhPSBOVUxMKSB7CgkgICAgfSBlbHNlIGlmIChjaGlsZCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfTk9URU1QVFksCgkJCSAgICAgICJFbGVtZW50ICVzIGlzIHN1cHBvc2VkIHRvIGJlIGVtcHR5XG4iLAoJCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICAgICAgfQoJICAgIC8qIFJlbW92ZWQgZHVlIHRvIGNoYW5nZXMgb2YgYXR0cmlidXRlIHZhbGlkYXRpb246CiAgICAgICAgICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBub2RlLCB0eXBlLT5hdHRyaWJ1dGVzKTsKICAgICAgICAgICAgfQoJICAgICovCiAgICAgICAgICAgIHN1YnR5cGUgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgY3R4dC0+dHlwZSA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZUNvbXBsZXhUeXBlKGN0eHQsIG5vZGUpOwogICAgICAgICAgICAgICAgc3VidHlwZSA9IHN1YnR5cGUtPm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRURfT1JfRUxFTUVOVFM6CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNraXAgaWdub3JhYmxlIG5vZGVzIGluIHRoYXQgY29udGV4dAogICAgICAgICAgICAgKi8KCSAgICAvKiBDb21wbGV4VHlwZSwgQ29tcGxleENvbnRlbnQgKi8KCSAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgICAgICBjaGlsZCA9IHhtbFNjaGVtYVNraXBJZ25vcmVkKGN0eHQsIHR5cGUsIGNoaWxkKTsKICAgICAgICAgICAgd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGlmIChjaGlsZC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcoY3R4dC0+cmVnZXhwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLT5uYW1lLCBjaGlsZCk7CiNpZmRlZiBERUJVR19BVVRPTUFUQQogICAgICAgICAgICAgICAgICAgIGlmIChyZXQgPCAwKQogICAgICAgICAgICAgICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIC0tPiAlcyBFcnJvclxuIiwgY2hpbGQtPm5hbWUpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAtLT4gJXNcbiIsIGNoaWxkLT5uYW1lKTsKI2VuZGlmCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFNraXAgaWdub3JhYmxlIG5vZGVzIGluIHRoYXQgY29udGV4dAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBjaGlsZCA9IHhtbFNjaGVtYVNraXBJZ25vcmVkKGN0eHQsIHR5cGUsIGNoaWxkKTsKICAgICAgICAgICAgfQoJICAgIH0KCSAgICAKCSAgICBpZiAoKCh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpIHx8CgkJKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRF9PUl9FTEVNRU5UUykpICYmCgkJKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpKSB7CgkJVE9ETwoJICAgIH0KCgkgICAgLyogUmVtb3ZlZCBkdWUgdG8gY2hhbmdlcyBvZiBhdHRyaWJ1dGUgdmFsaWRhdGlvbjoKICAgICAgICAgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKGN0eHQsIG5vZGUsIHR5cGUtPmF0dHJpYnV0ZXMpOwogICAgICAgICAgICB9CgkgICAgKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6ewogICAgICAgICAgICAgICAgaWYgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBjdHh0LT50eXBlID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZShjdHh0LCBub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh0eXBlLT5iYXNlVHlwZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgY3R4dC0+dHlwZSA9IHR5cGUtPmJhc2VUeXBlOwoJCSAgICBpZiAodHlwZS0+YmFzZVR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKQoJCQl4bWxTY2hlbWFWYWxpZGF0ZUJhc2ljVHlwZShjdHh0LCBub2RlKTsKCQkgICAgZWxzZSBpZiAodHlwZS0+YmFzZVR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpCgkJCXhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUoY3R4dCwgbm9kZSk7CgkJICAgIC8qIFRPRE86IFRoaXMgbWlnaHQgYmUgaW5jb3JyZWN0LiAqLwoJCSAgICBlbHNlIGlmICh0eXBlLT5iYXNlVHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSAKCQkJeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlKGN0eHQsIG5vZGUpOwoJCSAgICBlbHNlCgkJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5leHBlY3RlZCBjb250ZW50IHR5cGUgb2YgYmFzZTogJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmNvbnRlbnRUeXBlKTsKICAgICAgICAgICAgICAgIH0KCQkvKiBSZW1vdmVkIGR1ZSB0byBjaGFuZ2VzIG9mIGF0dHJpYnV0ZSB2YWxpZGF0aW9uOgogICAgICAgICAgICAgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBub2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5hdHRyaWJ1dGVzKTsKICAgICAgICAgICAgICAgIH0KCQkqLwogICAgICAgICAgICAgICAgY3R4dC0+dHlwZSA9IHR5cGU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTp7CiAgICAgICAgICAgICAgICBpZiAodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGN0eHQtPnR5cGUgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZUNvbXBsZXhUeXBlKGN0eHQsIG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHR5cGUtPmJhc2VUeXBlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBjdHh0LT50eXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZShjdHh0LCBub2RlKTsKICAgICAgICAgICAgICAgIH0KCQkvKiBSZW1vdmVkIGR1ZSB0byBjaGFuZ2VzIG9mIGF0dHJpYnV0ZSB2YWxpZGF0aW9uOgogICAgICAgICAgICAgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBub2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5hdHRyaWJ1dGVzKTsKICAgICAgICAgICAgICAgIH0KCQkqLwogICAgICAgICAgICAgICAgY3R4dC0+dHlwZSA9IHR5cGU7CiAgICAgICAgICAgICAgICBicmVhazsKCX0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBUT0RPIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5pbXBsZW1lbnRlZCBjb250ZW50IHR5cGUgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmNvbnRlbnRUeXBlKTsKICAgIH0KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKQoJeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKGN0eHQsIG5vZGUsIHR5cGUpOwogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVDb250ZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQHR5cGU6ICB0aGUgdHlwZSBkZWNsYXJhdGlvbgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IGFnYWluc3QgdGhlIHR5cGUuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUNvbnRlbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKCiAgICBjaGlsZCA9IGN0eHQtPm5vZGU7CiAgICB0eXBlID0gY3R4dC0+dHlwZTsKICAgIGN0eHQtPmN1ciA9IG5vZGU7CgogICAgLyogCiAgICAgKiBSZW1vdmVkLCBzaW5jZSByZWR1bmRhbnQuIAogICAgICovCiAgICAvKiB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoY3R4dCwgbm9kZSwgdHlwZS0+YXR0cmlidXRlcyk7ICovCiAgICBjdHh0LT5jdXIgPSBub2RlOwoKICAgIHN3aXRjaCAodHlwZS0+dHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWToKICAgICAgICAgICAgLyogQW55IHR5cGUgd2lsbCBkbyBpdCwgZmluZSAqLwogICAgICAgICAgICBUT0RPICAgICAgICAgICAgICAgIC8qIGhhbmRsZSByZWN1cnNpdml0eSAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZShjdHh0LCBub2RlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDp7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGRlY2wgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgdHlwZTsKCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogSGFuZGxlIGVsZW1lbnQgcmVmZXJlbmNlIGhlcmUKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKGRlY2wtPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRlY2wtPnJlZkRlY2wgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogZWxlbWVudCByZWZlcmVuY2UgJXMgIgoJCQkJICAgICAgIm5vdCByZXNvbHZlZFxuIiwgZGVjbC0+cmVmLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgtMSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGN0eHQtPnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikgZGVjbC0+cmVmRGVjbDsKICAgICAgICAgICAgICAgICAgICBkZWNsID0gZGVjbC0+cmVmRGVjbDsKICAgICAgICAgICAgICAgIH0KCQkvKiBUT0RPOiBTaG91bGQgInhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudCIgYmUgY2FsbGVkIGluc3RlYWQ/ICovCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRUeXBlKGN0eHQsIG5vZGUpOwogICAgICAgICAgICAgICAgY3R4dC0+dHlwZSA9IHR5cGU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgogICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZUJhc2ljVHlwZShjdHh0LCBub2RlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRkFDRVQ6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgogICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGUoY3R4dCwgbm9kZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQ6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1VSOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOgogICAgICAgICAgICAvKnhtbFNjaGVtYVZhbGlkYXRlUmVzdHJpY3Rpb25UeXBlKGN0eHQsIG5vZGUpOyAqLwogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTjoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfTk9UQVRJT046CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfTElTVDoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9VTklPTjoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRToKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEU6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICB9CiAgICAvKiAKICAgICAqIFJlbW92ZWQsIHNpbmNlIHJlZHVuZGFudC4gCiAgICAgKi8KICAgIC8qIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBub2RlLCB0eXBlLT5hdHRyaWJ1dGVzKTsgKi8KCiAgICBpZiAoY3R4dC0+bm9kZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIGN0eHQtPm5vZGUgPSBjdHh0LT5ub2RlLT5uZXh0OwogICAgY3R4dC0+dHlwZSA9IHR5cGUtPm5leHQ7CiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAdHlwZTogIHRoZSBsaXN0IG9mIHR5cGUgZGVjbGFyYXRpb25zCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgYWdhaW5zdCB0aGUgdHlwZXMuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgZWxlbSwKICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wsIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sQ2hhciAqbmlsOwoKICAgIGlmICgoZWxlbSA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSB8fCAoZWxlbURlY2wgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgwKTsKCiAgICAvKiBUaGlzIG9uZSBpcyBjYWxsZWQgYnkgInhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudFR5cGUiIGFuZAogICAgICogInhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudCIuCiAgICAgKi8KCiAgICAvKgogICAgICogMy4zLjQgOiAyCiAgICAgKi8KICAgIGlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBlbGVtLCBYTUxfU0NIRU1BU19FUlJfSVNBQlNUUkFDVCwKCQkgICAgICAiRWxlbWVudCBkZWNsYXJhdGlvbiAlcyBpcyBhYnN0cmFjdFxuIiwKCQkgICAgICBlbGVtRGVjbC0+bmFtZSwgTlVMTCk7CgkvKiBDaGFuZ2VkLCBzaW5jZSB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiBpcyBhYnN0cmFjdCBhbmQgbm90CgkgKiB0aGUgZWxlbWVudCBpdHNlbGYuICovCgkvKiB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9JU0FCU1RSQUNULAoJCQkgIkVsZW1lbnQgJXMgaXMgYWJzdHJhY3RcbiIsIGVsZW0tPm5hbWUsIE5VTEwpOyAqLwogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KICAgIC8qCiAgICAgKiAzLjMuNDogMwogICAgICovCiAgICBuaWwgPSB4bWxHZXROc1Byb3AoZWxlbSwgQkFEX0NBU1QgIm5pbCIsIHhtbFNjaGVtYUluc3RhbmNlTnMpOwogICAgaWYgKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEUpIHsKICAgICAgICAvKiAzLjMuNDogMy4yICovCiAgICAgICAgaWYgKHhtbFN0ckVxdWFsKG5pbCwgQkFEX0NBU1QgInRydWUiKSkgewogICAgICAgICAgICBpZiAoZWxlbS0+Y2hpbGRyZW4gIT0gTlVMTCkgewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBlbGVtLCBYTUxfU0NIRU1BU19FUlJfTk9URU1QVFksCgkJCSAgICAgICJFbGVtZW50ICVzIGlzIG5vdCBlbXB0eVxuIiwgZWxlbS0+bmFtZSwgTlVMTCk7CiAgICAgICAgICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKSAmJgogICAgICAgICAgICAgICAgKGVsZW1EZWNsLT52YWx1ZSAhPSBOVUxMKSkgewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBlbGVtLCBYTUxfU0NIRU1BU19FUlJfSEFWRURFRkFVTFQsCgkJCSAgICAgICJFbXB0eSBlbGVtZW50ICVzIGNhbm5vdCBnZXQgYSBmaXhlZCB2YWx1ZVxuIiwKCQkJICAgICAgZWxlbS0+bmFtZSwgTlVMTCk7CiAgICAgICAgICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIDMuMy40OiAzLjEgKi8KICAgICAgICBpZiAobmlsICE9IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBlbGVtLCBYTUxfU0NIRU1BU19FUlJfTk9UTklMTEFCTEUsCgkgICAgCQkgICJFbGVtZW50ICVzIHdpdGggeHM6bmlsIGJ1dCBub3QgbmlsbGFibGVcbiIsCgkJCSAgZWxlbS0+bmFtZSwgTlVMTCk7CiAgICAgICAgICAgIHhtbEZyZWUobmlsKTsKICAgICAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBUT0RPIDMuMy40OiA0IGlmIHRoZSBlbGVtZW50IGNhcnJpZXMgeHM6dHlwZSAqLwoKICAgIGN0eHQtPnR5cGUgPSBlbGVtRGVjbC0+c3VidHlwZXM7CiAgICBjdHh0LT5ub2RlID0gZWxlbS0+Y2hpbGRyZW47CiAgICB4bWxTY2hlbWFWYWxpZGF0ZUNvbnRlbnQoY3R4dCwgZWxlbSk7CiAgICAvKiBSZW1vdmVkLCBzaW5jZSBhbiBlbGVtZW50IGRlY2xhcmF0aW9uIGRvZXMgbm90IGhvbGQgYW55IGF0dHJpYnV0ZQogICAgICogZGVjbGFyYXRpb25zICovCiAgICAvKiB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoY3R4dCwgZWxlbSwgZWxlbURlY2wtPmF0dHJpYnV0ZXMpOyAqLwoKICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAdHlwZTogIHRoZSBjb21wbGV4VHlwZSBob2xkaW5nIHRoZSBhdHRyaWJ1dGUgdXNlcwogKgogKiBWYWxpZGF0ZSB0aGUgYXR0cmlidXRlcyBvZiBhbiBlbGVtZW50LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGVsZW0sIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaW50IHJldDsKICAgIHhtbEF0dHJQdHIgYXR0cjsgLyogQW4gYXR0cmlidXRlIG9uIHRoZSBlbGVtZW50LiAqLwogICAgeG1sQ2hhciAqdmFsdWU7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyIGF0dHJVc2U7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0ckRlY2w7CiAgICBpbnQgZm91bmQ7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgY3VyU3RhdGUsIHJlcUF0dHJTdGF0ZXMgPSBOVUxMLCByZXFBdHRyU3RhdGVzVG9wID0gTlVMTDsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgogICAgaW50IHJlZHVuZGFudCA9IDA7CiNlbmRpZgogICAgaWYgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHsKCXhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlczogIgoJCQkgICAgICAiZ2l2ZW4gdHlwZSBcIiVzXCJpcyBub3QgYSBjb21wbGV4VHlwZVxuIiwKCQkJICAgICAgdHlwZS0+bmFtZSwgTlVMTCk7CglyZXR1cm4oLTEpOwogICAgfSAgICAKCiAgICBpZiAoKHR5cGUtPmF0dHJpYnV0ZVVzZXMgPT0gTlVMTCkgJiYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID09IE5VTEwpKQogICAgICAgIHJldHVybiAoMCk7CgogICAgYXR0clVzZSA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CgogICAgd2hpbGUgKGF0dHJVc2UgIT0gTlVMTCkgewogICAgICAgIGZvdW5kID0gMDsgICAgCglhdHRyRGVjbCA9IGF0dHJVc2UtPmF0dHI7CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCXByaW50ZigiYXR0ciB1c2UgLSBuYW1lOiAlc1xuIiwgeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGF0dHJEZWNsKSk7CglwcmludGYoImF0dHIgdXNlIC0gdXNlOiAlZFxuIiwgYXR0ckRlY2wtPm9jY3Vycyk7CiNlbmRpZgogICAgICAgIGZvciAoY3VyU3RhdGUgPSBjdHh0LT5hdHRyOyBjdXJTdGF0ZSAhPSBOVUxMOyBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0KSB7CQkgICAgCgoJICAgIGlmIChjdXJTdGF0ZS0+ZGVjbCA9PSBhdHRyVXNlLT5hdHRyKSB7CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCQlyZWR1bmRhbnQgPSAxOwojZW5kaWYKICAgICAgICB9CgkgICAgYXR0ciA9IGN1clN0YXRlLT5hdHRyOwojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgkgICAgcHJpbnRmKCJhdHRyIC0gbmFtZTogJXNcbiIsIGF0dHItPm5hbWUpOwoJICAgIGlmIChhdHRyLT5ucyAhPSBOVUxMKQoJCXByaW50ZigiYXR0ciAtIG5zOiAlc1xuIiwgYXR0ci0+bnMtPmhyZWYpOwoJICAgIGVsc2UKCQlwcmludGYoImF0dHIgLSBuczogbm9uZVxuIik7CiNlbmRpZgoJICAgIC8qIFRPRE86IENhbiB0aGlzIGV2ZXIgaGFwcGVuPyAqLwogICAgICAgICAgICBpZiAoYXR0ciA9PSBOVUxMKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGlmIChhdHRyRGVjbC0+cmVmICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGlmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgYXR0ckRlY2wtPnJlZikpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICBpZiAoYXR0ci0+bnMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGlmICgoYXR0ckRlY2wtPnJlZk5zID09IE5VTEwpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIGF0dHJEZWNsLT5yZWZOcykpKQogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXR0ckRlY2wtPnJlZk5zICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgYXR0ckRlY2wtPm5hbWUpKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGhhbmRsZSB0aGUgbmFtZXNwYWNlcyBjaGVja3MgaGVyZQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCSAgICAvKgoJCSAgICAgKiBhY2NlcHQgYW4gdW5xdWFsaWZpZWQgYXR0cmlidXRlIG9ubHkgaWYgdGhlIHRhcmdldAoJCSAgICAgKiBuYW1lc3BhY2Ugb2YgdGhlIGRlY2xhcmF0aW9uIGlzIGFic2VudC4KCQkgICAgICovCgkJICAgIGlmIChhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpCgkJCS8qIAoJCQkgKiBUaGlzIGNoZWNrIHdhcyByZW1vdmVkLCBzaW5jZSB0aGUgdGFyZ2V0IG5hbWVzcGFjZQoJCQkgKiB3YXMgZXZhbHVhdGVkIGR1cmluZyBwYXJzaW5nIGFuZCBhbHJlYWR5IHRvb2sKCQkJICogImF0dHJpYnV0ZUZvcm1EZWZhdWx0IiBpbnRvIGFjY291bnQuCgkJCSAqLwoJCSAgICAgICAgLyogKChhdHRyaWJ1dGVzLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfTlNERUZBVUxUKSA9PSAwKSkgKi8KCQkgICAgICAgIGNvbnRpbnVlOwoJCX0gZWxzZSB7CgkJICAgIGlmIChhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlID09IE5VTEwpCgkJICAgICAgICBjb250aW51ZTsKCQkgICAgaWYgKCF4bWxTdHJFcXVhbChhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAoJCSAgICAgICAgICAgICAgICAgICAgIGF0dHItPm5zLT5ocmVmKSkKCQkJY29udGludWU7CgkJfQogICAgICAgICAgICB9CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCSAgICBwcmludGYoImZvdW5kXG4iKTsKI2VuZGlmCiAgICAgICAgICAgIGZvdW5kID0gMTsKICAgICAgICAgICAgY3R4dC0+Y3VyID0gKHhtbE5vZGVQdHIpIGF0dHI7CgogICAgICAgICAgICBpZiAoYXR0ckRlY2wtPnN1YnR5cGVzID09IE5VTEwpIHsKCQljdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX1RZUEVfTk9UX1JFU09MVkVEOwoJCWN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CgkJLyogCgkJICogVGhpcyBjb3VsZCBiZSBwdXQgaW50byAieG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVzIiBhcyB3ZWxsLCBidXQKCQkgKiBzaW5jZSBpdCByZXBvcnRzIGFuIGludGVybmFsIGVycm9yLCBpdCBiZXR0ZXIgc3RheXMgaGVyZSB0byBlYXNlCgkJICogZGVidWdnaW5nLgoJCSAqLwogICAgICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IGF0dHJpYnV0ZSAlcyB0eXBlIG5vdCByZXNvbHZlZFxuIiwKCQkJICAgICAgYXR0ci0+bmFtZSwgTlVMTCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YWx1ZSA9IHhtbE5vZGVMaXN0R2V0U3RyaW5nKGVsZW0tPmRvYywgYXR0ci0+Y2hpbGRyZW4sIDEpOwogICAgICAgICAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlKGN0eHQsIGF0dHJEZWNsLT5zdWJ0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSk7CiAgICAgICAgICAgIGlmIChyZXQgIT0gMCkgCgkJY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX1ZBTFVFOyAgIAkJCQkKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEOwoJICAgIGN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CiAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICB4bWxGcmVlKHZhbHVlKTsKICAgICAgICAgICAgfQkgICAgCiAgICAgICAgfQogICAgICAgIGlmICgoIWZvdW5kKSAmJiAoYXR0ckRlY2wtPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkpIHsKCSAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgdG1wOwoKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJICAgIHByaW50ZigicmVxdWlyZWQgYXR0ciBub3QgZm91bmRcbiIpOwojZW5kaWYKCSAgICAvKgoJICAgICAqIEFkZCBhIG5ldyBkdW1teSBhdHRyaWJ1dGUgc3RhdGUuCgkgICAgICovCQoJICAgIHRtcCA9ICh4bWxTY2hlbWFBdHRyU3RhdGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0clN0YXRlKSk7CgkgICAgaWYgKHRtcCA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeShjdHh0LCAicmVnaXN0ZXJpbmcgcmVxdWlyZWQgYXR0cmlidXRlcyIsIE5VTEwpOwoJCXJldHVybiAoLTEpOwogICAgICAgICAgICB9ICAgICAgICAgICAgCgkgICAgdG1wLT5hdHRyID0gTlVMTDsKCSAgICB0bXAtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9NSVNTSU5HOwoJICAgIHRtcC0+ZGVjbCA9IGF0dHJEZWNsOwoJICAgIHRtcC0+bmV4dCA9IE5VTEw7CiAgICAgICAgIAoJICAgIGlmIChyZXFBdHRyU3RhdGVzID09IE5VTEwpIHsKCQlyZXFBdHRyU3RhdGVzID0gdG1wOwoJCXJlcUF0dHJTdGF0ZXNUb3AgPSB0bXA7CiAgICAgICAgICAgIH0gZWxzZSB7CgkJcmVxQXR0clN0YXRlc1RvcC0+bmV4dCA9IHRtcDsKCQlyZXFBdHRyU3RhdGVzVG9wID0gdG1wOwogICAgICAgICAgICB9CgkKCX0KICAgICAgICBhdHRyVXNlID0gYXR0clVzZS0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAgKiBBZGQgcmVxdWlyZWQgYXR0cmlidXRlcyB0byB0aGUgYXR0cmlidXRlIHN0YXRlcyBvZiB0aGUgY29udGV4dC4KICAgICAqLwogICAgaWYgKHJlcUF0dHJTdGF0ZXMgIT0gTlVMTCkgewoJaWYgKGN0eHQtPmF0dHIgPT0gTlVMTCkgewoJICAgIGN0eHQtPmF0dHIgPSByZXFBdHRyU3RhdGVzOwoJfSBlbHNlIHsJCQoJICAgIGN0eHQtPmF0dHJUb3AtPm5leHQgPSByZXFBdHRyU3RhdGVzOwoJfQoJY3R4dC0+YXR0clRvcCA9IHJlcUF0dHJTdGF0ZXNUb3A7CiAgICAgICAgICAgIH0KICAgIC8qCiAgICAqIFByb2Nlc3Mgd2lsZGNhcmRzLgogICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CQojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgl4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIG5zOwkKCXByaW50ZigibWF0Y2hpbmcgd2lsZGNhcmQ6IFslZF0gb2YgY29tcGxleFR5cGU6ICVzXG4iLCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgdHlwZS0+bmFtZSk7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPmFueSkKCSAgICBwcmludGYoInR5cGU6IGFueVxuIik7CgllbHNlIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJICAgIHByaW50ZigidHlwZTogbmVnYXRlZFxuIik7CgkgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkKCQlwcmludGYoIm5zOiAoYWJzZW50KVxuIik7CgkgICAgZWxzZQoJCXByaW50ZigibnM6ICVzXG4iLCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bmVnTnNTZXQtPnZhbHVlKTsKCX0gZWxzZSBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBwcmludGYoInR5cGU6IHNldFxuIik7CgkgICAgbnMgPSB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bnNTZXQ7CgkgICAgd2hpbGUgKG5zICE9IE5VTEwpIHsKCQlpZiAobnMtPnZhbHVlID09IE5VTEwpCgkJICAgIHByaW50ZigibnM6IChhYnNlbnQpXG4iKTsKCQllbHNlCgkJICAgIHByaW50ZigibnM6ICVzXG4iLCBucy0+dmFsdWUpOwoJCW5zID0gbnMtPm5leHQ7CgkgICAgfQkgICAgCgl9IGVsc2UKCSAgICBwcmludGYoImVtcHR5XG4iKTsKCiNlbmRpZgoJLyoKCSogVE9ETzogSW1wbGVtZW50IHByb2Nlc3NDb250ZW50cy4KCSovCgljdXJTdGF0ZSA9IGN0eHQtPmF0dHI7Cgl3aGlsZSAoY3VyU3RhdGUgIT0gTlVMTCkgewoJICAgIGlmICgoY3VyU3RhdGUtPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTikgJiYgCgkJKGN1clN0YXRlLT5hdHRyICE9IE5VTEwpKSB7CgkJaWYgKGN1clN0YXRlLT5hdHRyLT5ucyAhPSBOVUxMKSB7CgkJICAgIGlmICh4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgCgkJCWN1clN0YXRlLT5hdHRyLT5ucy0+aHJlZikpCgkJCWN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfQ0hFQ0tFRDsKCQl9IGVsc2UgaWYgKHhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCAKCQkgICAgTlVMTCkpCgkJICAgIGN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfQ0hFQ0tFRDsJCQogICAgICAgIH0KCSAgICBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0OwogICAgICAgIH0KICAgIH0KCiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KICAgIGlmIChyZWR1bmRhbnQpCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCSAgICAgICAgICAgICAgICAieG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzOiByZWR1bmRhbnQgY2FsbCBieSB0eXBlOiAlc1xuIiwKCSAgICAgICAgICAgICAgICB0eXBlLT5uYW1lKTsKI2VuZGlmCiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKgogKiBWYWxpZGF0ZSBhbiBlbGVtZW50IGluIGEgdHJlZQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGVsZW0pCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2w7CiAgICBpbnQgcmV0OwogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGF0dHJzLCBhdHRyVG9wOwoKICAgIGlmIChlbGVtLT5ucyAhPSBOVUxMKSB7CiAgICAgICAgZWxlbURlY2wgPSB4bWxIYXNoTG9va3VwMyhjdHh0LT5zY2hlbWEtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bmFtZSwgZWxlbS0+bnMtPmhyZWYsIE5VTEwpOwogICAgfSBlbHNlIHsKICAgICAgICBlbGVtRGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5uYW1lLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgIC8qCiAgICAgKiBzcGVjaWFsIGNhc2Ugd2hlIGVsZW1lbnRGb3JtRGVmYXVsdCBpcyB1bnF1YWxpZmllZCBmb3IgdG9wLWxldmVsIGVsZW0uCiAgICAgKi8KICAgIC8qCiAgICAgKiBUaGlzIHdhcyByZW1vdmVkLCBzaW5jZSBlbGVtZW50Rm9ybURlZmF1bHQgZG9lcyBub3QgYXBwbHkgdG8gdG9wLWxldmVsCiAgICAgKiBlbGVtZW50IGRlY2xhcmF0aW9ucy4KICAgICAqLwogICAgLyoKICAgIGlmICgoZWxlbURlY2wgPT0gTlVMTCkgJiYgKGVsZW0tPm5zICE9IE5VTEwpICYmCiAgICAgICAgKGVsZW0tPnBhcmVudCAhPSBOVUxMKSAmJiAoZWxlbS0+cGFyZW50LT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpICYmCiAgICAgICAgKHhtbFN0ckVxdWFsKGN0eHQtPnNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCBlbGVtLT5ucy0+aHJlZikpICYmCgkoKGN0eHQtPnNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkgPT0gMCkpIHsKICAgICAgICBlbGVtRGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5uYW1lLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgICovCgogICAgLyoKICAgICAqIDMuMy40IDogMQogICAgICovCiAgICBpZiAoZWxlbURlY2wgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgWE1MX1NDSEVNQVNfRVJSX1VOREVDTEFSRURFTEVNLAoJCSAgICAgICJFbGVtZW50ICVzIG5vdCBkZWNsYXJlZFxuIiwgZWxlbS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfQogICAgaWYgKGVsZW1EZWNsLT5zdWJ0eXBlcyA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBlbGVtLCBYTUxfU0NIRU1BU19FUlJfTk9UWVBFLAoJCSAgICAgICJFbGVtZW50ICVzIGhhcyBubyB0eXBlXG4iLCBlbGVtLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAvKgogICAgICogVmVyaWZ5IHRoZSBhdHRyaWJ1dGVzCiAgICAgKi8KICAgIGF0dHJzID0gY3R4dC0+YXR0cjsKICAgIGF0dHJUb3AgPSBjdHh0LT5hdHRyVG9wOwogICAgeG1sU2NoZW1hUmVnaXN0ZXJBdHRyaWJ1dGVzKGN0eHQsIGVsZW0tPnByb3BlcnRpZXMpOwogICAgLyoKICAgICAqIFZlcmlmeSB0aGUgZWxlbWVudCBjb250ZW50IHJlY3Vyc2l2ZWx5CiAgICAgKi8KICAgIGlmIChlbGVtRGVjbC0+Y29udE1vZGVsICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5yZWdleHAgPSB4bWxSZWdOZXdFeGVjQ3R4dChlbGVtRGVjbC0+Y29udE1vZGVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh4bWxSZWdFeGVjQ2FsbGJhY2tzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlQ2FsbGJhY2ssIGN0eHQpOwojaWZkZWYgREVCVUdfQVVUT01BVEEKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIj09PT0+ICVzXG4iLCBlbGVtLT5uYW1lKTsKI2VuZGlmCiAgICB9CiAgICB4bWxTY2hlbWFWYWxpZGF0ZVR5cGUoY3R4dCwgZWxlbSwgZWxlbURlY2wsIGVsZW1EZWNsLT5zdWJ0eXBlcyk7CiAgICBpZiAoZWxlbURlY2wtPmNvbnRNb2RlbCAhPSBOVUxMKSB7CiAgICAgICAgcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcoY3R4dC0+cmVnZXhwLCBOVUxMLCBOVUxMKTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICI9PT09PiAlcyA6ICVkXG4iLCBlbGVtLT5uYW1lLCByZXQpOwojZW5kaWYKICAgICAgICBpZiAocmV0ID09IDApIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBlbGVtLCBYTUxfU0NIRU1BU19FUlJfRUxFTUNPTlQsCgkgICAgCQkgICJFbGVtZW50ICVzIGNvbnRlbnQgY2hlY2sgZmFpbGVkXG4iLAoJCQkgIGVsZW0tPm5hbWUsIE5VTEwpOwogICAgICAgIH0gZWxzZSBpZiAocmV0IDwgMCkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9FTEVNQ09OVCwKCSAgICAJCSAgIkVsZW1lbnQgJXMgY29udGVudCBjaGVjayBmYWlsZWRcbiIsCgkJCSAgZWxlbS0+bmFtZSwgTlVMTCk7CiNpZmRlZiBERUJVR19DT05URU5UCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudCAlcyBjb250ZW50IGNoZWNrIHN1Y2NlZWRlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPm5hbWUpOwoKI2VuZGlmCiAgICAgICAgfQogICAgICAgIHhtbFJlZ0ZyZWVFeGVjQ3R4dChjdHh0LT5yZWdleHApOwogICAgfQogICAgLyoKICAgICAqIFZlcmlmeSB0aGF0IGFsbCBhdHRyaWJ1dGVzIHdlcmUgU2NoZW1hcy12YWxpZGF0ZWQKICAgICAqLwogICAgeG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVzKGN0eHQsIGVsZW0pOwogICAgaWYgKGN0eHQtPmF0dHIgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVTdGF0ZXMoY3R4dC0+YXR0cik7CiAgICBjdHh0LT5hdHRyID0gYXR0cnM7CiAgICBjdHh0LT5hdHRyVG9wID0gYXR0clRvcDsKCiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZURvY3VtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZG9jOiAgYSBwYXJzZWQgZG9jdW1lbnQgdHJlZQogKgogKiBWYWxpZGF0ZSBhIGRvY3VtZW50IHRyZWUgaW4gbWVtb3J5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRG9jdW1lbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbERvY1B0ciBkb2MpCnsKICAgIHhtbE5vZGVQdHIgcm9vdDsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2w7CgogICAgcm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CiAgICBpZiAocm9vdCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLCBYTUxfU0NIRU1BU19FUlJfTk9ST09ULAoJCSAgICAgICJkb2N1bWVudCBoYXMgbm8gcm9vdFxuIiwgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfQogICAgCiAgICBpZiAocm9vdC0+bnMgIT0gTlVMTCkKICAgICAgICBlbGVtRGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290LT5uYW1lLCByb290LT5ucy0+aHJlZiwgTlVMTCk7CiAgICBlbHNlCiAgICAgICAgZWxlbURlY2wgPSB4bWxIYXNoTG9va3VwMyhjdHh0LT5zY2hlbWEtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9vdC0+bmFtZSwgTlVMTCwgTlVMTCk7CgogICAgLyoKICAgICAqIHNwZWNpYWwgY2FzZSB3aGUgZWxlbWVudEZvcm1EZWZhdWx0IGlzIHVucXVhbGlmaWVkIGZvciB0b3AtbGV2ZWwgZWxlbS4KICAgICAqLwogICAgLyogUmVtb3ZlZCwgc2luY2UgZWxlbWVudEZvcm1EZWZhdWx0IGRvZXMgbm90IGFwcGx5IHRvIHRvcCBsZXZlbCAKICAgICogZWxlbWVudHMgKi8KICAgIC8qCiAgICBpZiAoKGVsZW1EZWNsID09IE5VTEwpICYmIChyb290LT5ucyAhPSBOVUxMKSAmJgogICAgICAgICh4bWxTdHJFcXVhbChjdHh0LT5zY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgcm9vdC0+bnMtPmhyZWYpKSAmJgoJKChjdHh0LT5zY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0VMRU0pID09IDApKSB7CiAgICAgICAgZWxlbURlY2wgPSB4bWxIYXNoTG9va3VwMyhjdHh0LT5zY2hlbWEtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9vdC0+bmFtZSwgTlVMTCwgTlVMTCk7CiAgICB9CiAgICAqLwoKICAgIGlmIChlbGVtRGVjbCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCByb290LCBYTUxfU0NIRU1BU19FUlJfVU5ERUNMQVJFREVMRU0sCgkJICAgICAgIkVsZW1lbnQgJXMgbm90IGRlY2xhcmVkXG4iLCByb290LT5uYW1lLCBOVUxMKTsKICAgIH0gZWxzZSBpZiAoKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKSA9PSAwKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCByb290LCBYTUxfU0NIRU1BU19FUlJfTk9UVE9QTEVWRUwsCgkJICAgICAgIlJvb3QgZWxlbWVudCAlcyBub3QgZ2xvYmFsXG4iLCByb290LT5uYW1lLCBOVUxMKTsKICAgIH0KICAgIC8qCiAgICAgKiBPa2F5LCBzdGFydCB0aGUgcmVjdXJzaXZlIHZhbGlkYXRpb24KICAgICAqLwogICAgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50KGN0eHQsIHJvb3QpOwoKICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVNBWCBWYWxpZGF0aW9uIGNvZGUJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJVmFsaWRhdGlvbiBpbnRlcmZhY2VzCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYU5ld1ZhbGlkQ3R4dDoKICogQHNjaGVtYTogIGEgcHJlY29tcGlsZWQgWE1MIFNjaGVtYXMKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHZhbGlkYXRpb24gY29udGV4dCBiYXNlZCBvbiB0aGUgZ2l2ZW4gc2NoZW1hCiAqCiAqIFJldHVybnMgdGhlIHZhbGlkYXRpb24gY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVZhbGlkQ3R4dFB0cgp4bWxTY2hlbWFOZXdWYWxpZEN0eHQoeG1sU2NoZW1hUHRyIHNjaGVtYSkKewogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVZhbGlkQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyB2YWxpZGF0aW9uIGNvbnRleHQiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVZhbGlkQ3R4dCkpOwogICAgcmV0LT5zY2hlbWEgPSBzY2hlbWE7CiAgICAvKiAKICAgICAqIFJlbW92ZWQgZHVlIHRvIGNoYW5nZXMgb2YgdGhlIGF0dHJpYnV0ZSBzdGF0ZSBsaXN0LgogICAgKi8KICAgIC8qIHJldC0+YXR0ck5yID0gMDsgKi8KICAgIC8qIHJldC0+YXR0ck1heCA9IDEwOyAqLwogICAgLyogcmV0LT5hdHRyQmFzZSA9IE5VTEw7ICovCiAgICByZXQtPmF0dHJUb3AgPSBOVUxMOwogICAgcmV0LT5hdHRyID0gTlVMTDsKICAgIC8qIAogICAgICogUmVtb3ZlZCBkdWUgdG8gY2hhbmdlcyBvZiB0aGUgYXR0cmlidXRlIHN0YXRlIGxpc3QuCiAgICAgKgogICAgcmV0LT5hdHRyID0gKHhtbFNjaGVtYUF0dHJTdGF0ZVB0cikgeG1sTWFsbG9jKHJldC0+YXR0ck1heCAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHhtbFNjaGVtYUF0dHJTdGF0ZSkpOwogICAgaWYgKHJldC0+YXR0ciA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyB2YWxpZGF0aW9uIGNvbnRleHQiLCBOVUxMKTsKICAgICAgICBmcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQtPmF0dHIsIDAsIHJldC0+YXR0ck1heCAqIHNpemVvZih4bWxTY2hlbWFBdHRyU3RhdGUpKTsKICAgICovCgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBGcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChjdHh0LT5hdHRyICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVN0YXRlcyhjdHh0LT5hdHRyKTsKICAgIGlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShjdHh0LT52YWx1ZSk7CiAgICB4bWxGcmVlKGN0eHQpOwp9CgovKioKICogeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnI6ICB0aGUgZXJyb3IgZnVuY3Rpb24KICogQHdhcm46IHRoZSB3YXJuaW5nIGZ1bmN0aW9uCiAqIEBjdHg6IHRoZSBmdW5jdGlvbnMgY29udGV4dAogKgogKiBTZXQgdGhlIGVycm9yIGFuZCB3YXJuaW5nIGNhbGxiYWNrIGluZm9ybWF0aW9ucwogKi8Kdm9pZAp4bWxTY2hlbWFTZXRWYWxpZEVycm9ycyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm4sIHZvaWQgKmN0eCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBjdHh0LT5lcnJvciA9IGVycjsKICAgIGN0eHQtPndhcm5pbmcgPSB3YXJuOwogICAgY3R4dC0+dXNlckRhdGEgPSBjdHg7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZURvYzoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGRvYzogIGEgcGFyc2VkIGRvY3VtZW50IHRyZWUKICoKICogVmFsaWRhdGUgYSBkb2N1bWVudCB0cmVlIGluIG1lbW9yeS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlRG9jKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxEb2NQdHIgZG9jKQp7CiAgICBpbnQgcmV0OwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZG9jID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIGN0eHQtPmRvYyA9IGRvYzsKICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRG9jdW1lbnQoY3R4dCwgZG9jKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU3RyZWFtOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAaW5wdXQ6ICB0aGUgaW5wdXQgdG8gdXNlIGZvciByZWFkaW5nIHRoZSBkYXRhCiAqIEBlbmM6ICBhbiBvcHRpb25hbCBlbmNvZGluZyBpbmZvcm1hdGlvbgogKiBAc2F4OiAgYSBTQVggaGFuZGxlciBmb3IgdGhlIHJlc3VsdGluZyBldmVudHMKICogQHVzZXJfZGF0YTogIHRoZSBjb250ZXh0IHRvIHByb3ZpZGUgdG8gdGhlIFNBWCBoYW5kbGVyLgogKgogKiBWYWxpZGF0ZSBhIGRvY3VtZW50IHRyZWUgaW4gbWVtb3J5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRhdGVTdHJlYW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFBhcnNlcklucHV0QnVmZmVyUHRyIGlucHV0LCB4bWxDaGFyRW5jb2RpbmcgZW5jLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTQVhIYW5kbGVyUHRyIHNheCwgdm9pZCAqdXNlcl9kYXRhKQp7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGlucHV0ID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwogICAgY3R4dC0+aW5wdXQgPSBpbnB1dDsKICAgIGN0eHQtPmVuYyA9IGVuYzsKICAgIGN0eHQtPnNheCA9IHNheDsKICAgIGN0eHQtPnVzZXJfZGF0YSA9IHVzZXJfZGF0YTsKICAgIFRPRE8gcmV0dXJuICgwKTsKfQoKI2VuZGlmIC8qIExJQlhNTF9TQ0hFTUFTX0VOQUJMRUQgKi8K