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+bmV4dDsKICAgIH0JCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZGVzdDogIHRoZSBkZXN0aW5hdGlvbiB3aWxkY2FyZAogKiBAc291cmNlOiB0aGUgc291cmNlIHdpbGRjYXJkCiAqCiAqIENsb25lcyB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzIG9mIHNvdXJjZQogKiBhbmQgYXNzaWduZXMgdGhlbSB0byBkZXN0LgogKiBSZXR1cm5zIC0xIG9uIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyICpkZXN0LAoJCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHNvdXJjZSkJCQkJICAgIAp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgdG1wLCBsYXN0OwoKICAgIGlmICgoc291cmNlID09IE5VTEwpIHx8ICgqZGVzdCA9PSBOVUxMKSkKCXJldHVybigtMSk7ICAgIAogICAgKCpkZXN0KS0+YW55ID0gc291cmNlLT5hbnk7CiAgICBjdXIgPSBzb3VyY2UtPm5zU2V0OwogICAgbGFzdCA9IE5VTEw7CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCXRtcCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKHRtcCA9PSBOVUxMKQoJICAgIHJldHVybigtMSk7Cgl0bXAtPnZhbHVlID0gY3VyLT52YWx1ZTsKCWlmIChsYXN0ID09IE5VTEwpCgkgICAgKCpkZXN0KS0+bnNTZXQgPSB0bXA7CgllbHNlIAoJICAgIGxhc3QtPm5leHQgPSB0bXA7CglsYXN0ID0gdG1wOwoJY3VyID0gY3VyLT5uZXh0OwogICAgfSAgICAKICAgIGlmICgoKmRlc3QpLT5uZWdOc1NldCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoKCpkZXN0KS0+bmVnTnNTZXQpOwkgICAKICAgIGlmIChzb3VyY2UtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCSgqZGVzdCktPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CglpZiAoKCpkZXN0KS0+bmVnTnNTZXQgPT0gTlVMTCkKCSAgICByZXR1cm4oLTEpOwoJKCpkZXN0KS0+bmVnTnNTZXQtPnZhbHVlID0gc291cmNlLT5uZWdOc1NldC0+dmFsdWU7CSAgICAKICAgIH0gZWxzZQoJKCpkZXN0KS0+bmVnTnNTZXQgPSBOVUxMOwogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hVW5pb25XaWxkY2FyZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAY29tcGxldGVXaWxkOiAgdGhlIGZpcnN0IHdpbGRjYXJkCiAqIEBjdXJXaWxkOiB0aGUgc2Vjb25kIHdpbGRjYXJkIAogKgogKiBVbmlvbnMgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cyBvZiB0aGUgZ2l2ZW4gd2lsZGNhcmRzLgogKiBAY29tcGxldGVXaWxkIHdpbGwgaG9sZCB0aGUgcmVzdWx0aW5nIHVuaW9uLgogKiBSZXR1cm5zIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLCAtMSBpbiBjYXNlIG9mIGFuCiAqIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVW5pb25XaWxkY2FyZHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAJCQkgICAgCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjb21wbGV0ZVdpbGQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjdXJXaWxkKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgY3VyQiwgdG1wOwoKICAgIC8qCiAgICAqIDEgSWYgTzEgYW5kIE8yIGFyZSB0aGUgc2FtZSB2YWx1ZSwgdGhlbiB0aGF0IHZhbHVlIG11c3QgYmUgdGhlIAogICAgKiB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+YW55ID09IGN1cldpbGQtPmFueSkgJiYKCSgoY29tcGxldGVXaWxkLT5uc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bnNTZXQgPT0gTlVMTCkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5lZ05zU2V0ID09IE5VTEwpKSkgewoJCglpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgfHwKCSAgICAoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSkgewoJICAgIAoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQlpbnQgZm91bmQgPSAwOwoJCQoJCS8qIAoJCSogQ2hlY2sgZXF1YWxpdHkgb2Ygc2V0cy4gCgkJKi8KCQljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJCSAgICBmb3VuZCA9IDA7CgkJICAgIGN1ckIgPSBjdXJXaWxkLT5uc1NldDsKCQkgICAgd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQkgICAgZm91bmQgPSAxOwoJCQkgICAgYnJlYWs7CgkJCX0KCQkJY3VyQiA9IGN1ckItPm5leHQ7CgkJICAgIH0KCQkgICAgaWYgKCFmb3VuZCkKCQkJYnJlYWs7CgkJICAgIGN1ciA9IGN1ci0+bmV4dDsKCQl9CgkJaWYgKGZvdW5kKQoJCSAgICByZXR1cm4oMCk7CgkgICAgfSBlbHNlCgkJcmV0dXJuKDApOwoJfQogICAgfQkgICAgICAgIAogICAgLyoKICAgICogMiBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYW55LCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZQogICAgKi8KICAgIGlmIChjb21wbGV0ZVdpbGQtPmFueSAhPSBjdXJXaWxkLT5hbnkpIHsJCglpZiAoY29tcGxldGVXaWxkLT5hbnkgPT0gMCkgewoJICAgIGNvbXBsZXRlV2lsZC0+YW55ID0gMTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQl4bWxGcmVlKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgKiAzIElmIGJvdGggTzEgYW5kIE8yIGFyZSBzZXRzIG9mIChuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcpLCAKICAgICogdGhlbiB0aGUgdW5pb24gb2YgdGhvc2Ugc2V0cyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB7CQkKCWludCBmb3VuZDsKCXhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgc3RhcnQ7CgkKCWN1ciA9IGN1cldpbGQtPm5zU2V0OwoJc3RhcnQgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgZm91bmQgPSAwOwoJICAgIGN1ckIgPSBzdGFydDsKCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkgICAgZm91bmQgPSAxOwoJCSAgICBicmVhazsKCQl9CgkJY3VyQiA9IGN1ckItPm5leHQ7CgkgICAgfQoJICAgIGlmICghZm91bmQpIHsKCQl0bXAgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQlpZiAodG1wID09IE5VTEwpIAoJCSAgICByZXR1cm4gKC0xKTsKCQl0bXAtPnZhbHVlID0gY3VyLT52YWx1ZTsKCQl0bXAtPm5leHQgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwkJICAgIAkJICAgIAoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSB0bXA7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCgkJICAgIAkJCglyZXR1cm4oMCk7CiAgICB9ICAgIAogICAgLyoKICAgICogNCBJZiB0aGUgdHdvIGFyZSBuZWdhdGlvbnMgb2YgZGlmZmVyZW50IHZhbHVlcyAobmFtZXNwYWNlIG5hbWVzIAogICAgKiBvciC3YWJzZW50tyksIHRoZW4gYSBwYWlyIG9mIG5vdCBhbmQgt2Fic2VudLcgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIAoJKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSkgewoJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBOVUxMOwoKCXJldHVybigwKTsKICAgIH0KICAgIC8qIAogICAgICogNS4KICAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBOVUxMKSAmJgoJKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB8fAoJKChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoKCWludCBuc0ZvdW5kLCBhYnNlbnRGb3VuZCA9IDA7CgkKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJICAgIGN1ckIgPSBjdXJXaWxkLT5uZWdOc1NldDsKCX0gZWxzZSB7CgkgICAgY3VyID0gY3VyV2lsZC0+bnNTZXQ7CgkgICAgY3VyQiA9IGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQ7Cgl9Cgluc0ZvdW5kID0gMDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmIChjdXItPnZhbHVlID09IE5VTEwpIAoJCWFic2VudEZvdW5kID0gMTsKCSAgICBlbHNlIGlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKQoJCW5zRm91bmQgPSAxOwoJICAgIGlmIChuc0ZvdW5kICYmIGFic2VudEZvdW5kKQoJCWJyZWFrOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCgoJaWYgKG5zRm91bmQgJiYgYWJzZW50Rm91bmQpIHsKCSAgICAvKgoJICAgICogNS4xIElmIHRoZSBzZXQgUyBpbmNsdWRlcyBib3RoIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSAKCSAgICAqIG5hbWUgYW5kILdhYnNlbnS3LCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLyAgICAKCSAgICBjb21wbGV0ZVdpbGQtPmFueSA9IDE7CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJeG1sRnJlZShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0gTlVMTDsKCSAgICB9Cgl9IGVsc2UgaWYgKG5zRm91bmQgJiYgKCFhYnNlbnRGb3VuZCkpIHsKCSAgICAvKiAKCSAgICAqIDUuMiBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgdGhlIG5lZ2F0ZWQgbmFtZXNwYWNlIG5hbWUgCgkgICAgKiBidXQgbm90ILdhYnNlbnS3LCB0aGVuIGEgcGFpciBvZiBub3QgYW5kILdhYnNlbnS3IG11c3QgCgkgICAgKiBiZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQkgICAgcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gTlVMTDsKCX0gZWxzZSBpZiAoKCFuc0ZvdW5kKSAmJiBhYnNlbnRGb3VuZCkgewoJICAgIC8qCgkgICAgKiA1LjMgSWYgdGhlIHNldCBTIGluY2x1ZGVzILdhYnNlbnS3IGJ1dCBub3QgdGhlIG5lZ2F0ZWQgCgkgICAgKiBuYW1lc3BhY2UgbmFtZSwgdGhlbiB0aGUgdW5pb24gaXMgbm90IGV4cHJlc3NpYmxlLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjb21wbGV0ZVdpbGQtPm5vZGUsIAoJCVhNTF9TQ0hFTUFQX1VOSU9OX05PVF9FWFBSRVNTSUJMRSwKCQkiVGhlIHVuaW9uIG9mIHRoZSB3aWxjYXJkIGlzIG5vdCBleHByZXNzaWJsZVxuIiwKCQlOVUxMLCBOVUxMKTsJCgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFQX1VOSU9OX05PVF9FWFBSRVNTSUJMRSk7Cgl9IGVsc2UgaWYgKCghbnNGb3VuZCkgJiYgKCFhYnNlbnRGb3VuZCkpIHsKCSAgICAvKiAKCSAgICAqIDUuNCBJZiB0aGUgc2V0IFMgZG9lcyBub3QgaW5jbHVkZSBlaXRoZXIgdGhlIG5lZ2F0ZWQgbmFtZXNwYWNlIAoJICAgICogbmFtZSBvciC3YWJzZW50tywgdGhlbiB3aGljaGV2ZXIgb2YgTzEgb3IgTzIgaXMgYSBwYWlyIG9mIG5vdCAKCSAgICAqIGFuZCBhIG5hbWVzcGFjZSBuYW1lIG11c3QgYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgewoJCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJCX0KCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQkgICAgcmV0dXJuICgtMSk7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWU7CgkgICAgfQoJfQoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qIAogICAgICogNi4KICAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKSAmJgoJKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB8fAoJKChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJfSBlbHNlIHsKCSAgICBjdXIgPSBjdXJXaWxkLT5uc1NldDsKCX0JCgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBOVUxMKSB7CgkJLyoKCQkqIDYuMSBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgt2Fic2VudLcsIHRoZW4gYW55IG11c3QgYmUgdGhlIAoJCSogdmFsdWUuCgkJKi8KCQljb21wbGV0ZVdpbGQtPmFueSA9IDE7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQkgICAgY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkJfQoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sRnJlZShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0KTsKCQkgICAgY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IE5VTEw7CgkJfQoJCXJldHVybiAoMCk7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCQkKCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCSAgICAvKgoJICAgICogNi4yIElmIHRoZSBzZXQgUyBkb2VzIG5vdCBpbmNsdWRlILdhYnNlbnS3LCB0aGVuIGEgcGFpciBvZiBub3QgCgkgICAgKiBhbmQgt2Fic2VudLcgbXVzdCBiZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKQoJCXJldHVybiAoLTEpOwoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gTlVMTDsKCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICByZXR1cm4gKDApOwoKfQoKLyoqCiAqIHhtbFNjaGVtYUludGVyc2VjdFdpbGRjYXJkczoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBjb21wbGV0ZVdpbGQ6ICB0aGUgZmlyc3Qgd2lsZGNhcmQKICogQGN1cldpbGQ6IHRoZSBzZWNvbmQgd2lsZGNhcmQgCiAqCiAqIEludGVyc2VjdHMgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cyBvZiB0aGUgZ2l2ZW4gd2lsZGNhcmRzLgogKiBAY29tcGxldGVXaWxkIHdpbGwgaG9sZCB0aGUgcmVzdWx0aW5nIGludGVyc2VjdGlvbi4KICogUmV0dXJucyBhIHBvc2l0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZSwgLTEgaW4gY2FzZSBvZiBhbgogKiBpbnRlcm5hbCBlcnJvciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUludGVyc2VjdFdpbGRjYXJkcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAkJCSAgICAKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGNvbXBsZXRlV2lsZCwKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGN1cldpbGQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCBjdXJCLCBwcmV2LCAgdG1wOwoKICAgIC8qCiAgICAqIDEgSWYgTzEgYW5kIE8yIGFyZSB0aGUgc2FtZSB2YWx1ZSwgdGhlbiB0aGF0IHZhbHVlIG11c3QgYmUgdGhlIAogICAgKiB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+YW55ID09IGN1cldpbGQtPmFueSkgJiYKCSgoY29tcGxldGVXaWxkLT5uc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bnNTZXQgPT0gTlVMTCkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5lZ05zU2V0ID09IE5VTEwpKSkgewoJCglpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgfHwKCSAgICAoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSkgewoJICAgIAoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQlpbnQgZm91bmQgPSAwOwoJCQoJCS8qIAoJCSogQ2hlY2sgZXF1YWxpdHkgb2Ygc2V0cy4gCgkJKi8KCQljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJCSAgICBmb3VuZCA9IDA7CgkJICAgIGN1ckIgPSBjdXJXaWxkLT5uc1NldDsKCQkgICAgd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQkgICAgZm91bmQgPSAxOwoJCQkgICAgYnJlYWs7CgkJCX0KCQkJY3VyQiA9IGN1ckItPm5leHQ7CgkJICAgIH0KCQkgICAgaWYgKCFmb3VuZCkKCQkJYnJlYWs7CgkJICAgIGN1ciA9IGN1ci0+bmV4dDsKCQl9CgkJaWYgKGZvdW5kKQoJCSAgICByZXR1cm4oMCk7CgkgICAgfSBlbHNlCgkJcmV0dXJuKDApOwoJfQogICAgfQkgICAgICAgIAogICAgLyoKICAgICogMiBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYW55LCB0aGVuIHRoZSBvdGhlciBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+YW55ICE9IGN1cldpbGQtPmFueSkgJiYgKGNvbXBsZXRlV2lsZC0+YW55KSkgewkJICAgIAoJaWYgKHhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKGN0eHQsICZjb21wbGV0ZVdpbGQsIGN1cldpbGQpID09IC0xKQoJICAgIHJldHVybigtMSk7CSAgICAKCXJldHVybigwKTsKICAgIH0JICAgICAgICAgICAgCiAgICAvKgogICAgKiAzIElmIGVpdGhlciBPMSBvciBPMiBpcyBhIHBhaXIgb2Ygbm90IGFuZCBhIHZhbHVlIChhIG5hbWVzcGFjZSAKICAgICogbmFtZSBvciC3YWJzZW50tykgYW5kIHRoZSBvdGhlciBpcyBhIHNldCBvZiAobmFtZXNwYWNlIG5hbWVzIG9yIAogICAgKiC3YWJzZW50tyksIHRoZW4gdGhhdCBzZXQsIG1pbnVzIHRoZSBuZWdhdGVkIHZhbHVlIGlmIGl0IHdhcyBpbiAKICAgICogdGhlIHNldCwgbWludXMgt2Fic2VudLcgaWYgaXQgd2FzIGluIHRoZSBzZXQsIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB8fAoJKChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCWNvbnN0IHhtbENoYXIgKm5lZzsKCQoJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgPT0gTlVMTCkgewoJICAgIG5lZyA9IGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwoJICAgIGlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhjdHh0LCAmY29tcGxldGVXaWxkLCBjdXJXaWxkKSA9PSAtMSkKCQlyZXR1cm4oLTEpOwoJfSBlbHNlCgkgICAgbmVnID0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwoJLyoKCSogUmVtb3ZlIGFic2VudCBhbmQgbmVnYXRlZC4KCSovCglwcmV2ID0gTlVMTDsKCWN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBOVUxMKSB7CgkJaWYgKHByZXYgPT0gTlVMTCkgCgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBjdXItPm5leHQ7CgkJZWxzZSAKCQkgICAgcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQl4bWxGcmVlKGN1cik7CgkJYnJlYWs7CgkgICAgfQoJICAgIHByZXYgPSBjdXI7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQoJaWYgKG5lZyAhPSBOVUxMKSB7CgkgICAgcHJldiA9IE5VTEw7CgkgICAgY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBuZWcpIHsKCQkgICAgaWYgKHByZXYgPT0gTlVMTCkgCgkJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBjdXItPm5leHQ7CgkJICAgIGVsc2UgCgkJCXByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJICAgIHhtbEZyZWUoY3VyKTsKCQkgICAgYnJlYWs7CgkJfQoJCXByZXYgPSBjdXI7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCX0KCglyZXR1cm4oMCk7CiAgICB9CSAgICAgICAgCiAgICAvKgogICAgKiA0IElmIGJvdGggTzEgYW5kIE8yIGFyZSBzZXRzIG9mIChuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcpLCAKICAgICogdGhlbiB0aGUgaW50ZXJzZWN0aW9uIG9mIHRob3NlIHNldHMgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgewkJCglpbnQgZm91bmQ7CgkKCWN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CglwcmV2ID0gTlVMTDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGZvdW5kID0gMDsKCSAgICBjdXJCID0gY3VyV2lsZC0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCWlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJICAgIGZvdW5kID0gMTsKCQkgICAgYnJlYWs7CgkJfQoJCWN1ckIgPSBjdXJCLT5uZXh0OwoJICAgIH0KCSAgICBpZiAoIWZvdW5kKSB7CgkJaWYgKHByZXYgPT0gTlVMTCkKCQkgICAgY29tcGxldGVXaWxkLT5uc1NldCA9IGN1ci0+bmV4dDsKCQllbHNlIAoJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCXRtcCA9IGN1ci0+bmV4dDsKCQl4bWxGcmVlKGN1cik7CgkJY3VyID0gdG1wOwkJCgkJY29udGludWU7CgkgICAgfQoJICAgIHByZXYgPSBjdXI7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQkKCQkgICAgCQkKCXJldHVybigwKTsKICAgIH0gICAgCiAgICAvKiA1IElmIHRoZSB0d28gYXJlIG5lZ2F0aW9ucyBvZiBkaWZmZXJlbnQgbmFtZXNwYWNlIG5hbWVzLCAKICAgICogdGhlbiB0aGUgaW50ZXJzZWN0aW9uIGlzIG5vdCBleHByZXNzaWJsZQogICAgKi8JICAgIAogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIAoJKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpICYmIAoJKGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBOVUxMKSkgewoKCXhtbFNjaGVtYVBFcnIoY3R4dCwgY29tcGxldGVXaWxkLT5ub2RlLCBYTUxfU0NIRU1BUF9JTlRFUlNFQ1RJT05fTk9UX0VYUFJFU1NJQkxFLAoJICAgICJUaGUgaW50ZXJzZWN0aW9uIG9mIHRoZSB3aWxjYXJkIGlzIG5vdCBleHByZXNzaWJsZVxuIiwKCSAgICBOVUxMLCBOVUxMKTsJCglyZXR1cm4oWE1MX1NDSEVNQVBfSU5URVJTRUNUSU9OX05PVF9FWFBSRVNTSUJMRSk7CiAgICB9CQkgICAgCiAgICAvKiAKICAgICogNiBJZiB0aGUgb25lIGlzIGEgbmVnYXRpb24gb2YgYSBuYW1lc3BhY2UgbmFtZSBhbmQgdGhlIG90aGVyIAogICAgKiBpcyBhIG5lZ2F0aW9uIG9mILdhYnNlbnS3LCB0aGVuIHRoZSBvbmUgd2hpY2ggaXMgdGhlIG5lZ2F0aW9uIAogICAgKiBvZiBhIG5hbWVzcGFjZSBuYW1lIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkpIHsJCgljb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9ICBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWU7IAogICAgfQogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB3aWxkQTogIHRoZSBmaXJzdCB3aWxkY2FyZAogKiBAd2lsZEI6IHRoZSBzZWNvbmQgd2lsZGNhcmQgCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnQgb2YgQHdpbGRBIGlzIGFuIGludGVuc2lvbmFsIAogKiBzdWJzZXQgb2YgQHdpbGRCLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCBBVFRSSUJVVEVfVU5VU0VELCAKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRBLAoJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZEIpCnsgICAgCgogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBXaWxkY2FyZCBTdWJzZXQgCiAgICAqLwogICAgLyoKICAgICogMSBzdXBlciBtdXN0IGJlIGFueS4gCiAgICAqLwogICAgaWYgKHdpbGRCLT5hbnkpCglyZXR1cm4gKDEpOwogICAgLyoKICAgICogMi4xIHN1YiBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgb3Igt2Fic2VudLcuCiAgICAqIDIuMiBzdXBlciBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIHRoZSBzYW1lIHZhbHVlLgogICAgKi8KICAgIGlmICgod2lsZEEtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkod2lsZEItPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkod2lsZEEtPm5lZ05zU2V0LT52YWx1ZSA9PSB3aWxkQS0+bmVnTnNTZXQtPnZhbHVlKSkKCXJldHVybiAoMSk7ICAgIAogICAgLyogCiAgICAqIDMuMSBzdWIgbXVzdCBiZSBhIHNldCB3aG9zZSBtZW1iZXJzIGFyZSBlaXRoZXIgbmFtZXNwYWNlIG5hbWVzIG9yILdhYnNlbnS3LiAKICAgICovCiAgICBpZiAod2lsZEEtPm5zU2V0ICE9IE5VTEwpIHsKCS8qCgkqIDMuMi4xIHN1cGVyIG11c3QgYmUgdGhlIHNhbWUgc2V0IG9yIGEgc3VwZXJzZXQgdGhlcmVvZi4gCgkqLwoJaWYgKHdpbGRCLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIGN1ckI7CgkgICAgaW50IGZvdW5kID0gMDsKCSAgICAKCSAgICBjdXIgPSB3aWxkQS0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJZm91bmQgPSAwOwoJCWN1ckIgPSB3aWxkQi0+bnNTZXQ7CgkJd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQlmb3VuZCA9IDE7CgkJCWJyZWFrOwoJCSAgICB9CgkJICAgIGN1ckIgPSBjdXJCLT5uZXh0OwoJCX0KCQlpZiAoIWZvdW5kKQoJCSAgICByZXR1cm4gKDApOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9CgkgICAgaWYgKGZvdW5kKQoJCXJldHVybiAoMSk7IAoJfSBlbHNlIGlmICh3aWxkQi0+bmVnTnNTZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyOwoJICAgIC8qCgkgICAgKiAzLjIuMiBzdXBlciBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgb3IgCgkgICAgKiC3YWJzZW50tyBhbmQgdGhhdCB2YWx1ZSBtdXN0IG5vdCBiZSBpbiBzdWIncyBzZXQuIAoJICAgICovCgkgICAgY3VyID0gd2lsZEEtPm5zU2V0OwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewkJCgkJaWYgKGN1ci0+dmFsdWUgPT0gd2lsZEItPm5lZ05zU2V0LT52YWx1ZSkKCQkgICAgcmV0dXJuICgwKTsKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfSAgCgkgICAgcmV0dXJuICgxKTsKCX0KICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAYXR0cnM6IHRoZSBhdHRyaWJ1dGUgbGlzdCAKICogQGNvbXBsZXRlV2lsZDogdGhlIHJlc3VsdGluZyBjb21wbGV0ZSB3aWxkY2FyZAogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAJCQkJICAgIAoJCQkJICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHJzLAoJCQkJICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgKmNvbXBsZXRlV2lsZCkJCQkJCnsgICAgICAgIAogICAgd2hpbGUgKGF0dHJzICE9IE5VTEwpIHsKCWlmIChhdHRycy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApIHsKCSAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBncm91cDsKCgkgICAgZ3JvdXAgPSAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGF0dHJzOwkgIAoJICAgIGlmICgoZ3JvdXAtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX1dJTERDQVJEX0JVSUxERUQpID09IDApIHsKCQlpZiAoZ3JvdXAtPmF0dHJpYnV0ZXMgIT0gTlVMTCkgewoJCSAgICBpZiAoeG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkKGN0eHQsIAoJCQlncm91cC0+YXR0cmlidXRlcywgJmdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpCgkJCXJldHVybiAoLTEpOwoJCX0KCQlncm91cC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX1dJTERDQVJEX0JVSUxERUQ7CgkgICAgfQkJCgkgICAgaWYgKGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CQkKCQlpZiAoKmNvbXBsZXRlV2lsZCA9PSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICogQ29weSB0aGUgZmlyc3QgZW5jb3VudGVyZWQgd2lsZGNhcmQgYXMgY29udGV4dCwgZXhjZXB0IGZvciB0aGUgYW5ub3RhdGlvbi4KCQkgICAgKi8KCQkgICAgKmNvbXBsZXRlV2lsZCA9IHhtbFNjaGVtYUFkZFdpbGRjYXJkKGN0eHQpOwoJCSAgICAoKmNvbXBsZXRlV2lsZCktPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURTsJICAgCgkJICAgIGlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhjdHh0LCAKCQkJY29tcGxldGVXaWxkLCBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKQoJCQlyZXR1cm4gKC0xKTsKCQkgICAgKCpjb21wbGV0ZVdpbGQpLT5wcm9jZXNzQ29udGVudHMgPSBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50czsKCQkgICAgLyoKCQkgICAgKiBBbHRob3VnaCB0aGUgY29tcGxldGUgd2lsZGNhcmQgbWlnaHQgbm90IGNvcnJlc3BvbmQgdG8gYW55CgkJICAgICogbm9kZSBpbiB0aGUgc2NoZW1hLCB3ZSB3aWxsIHNhdmUgdGhpcyBjb250ZXh0IG5vZGUuCgkJICAgICovCgkJICAgICgqY29tcGxldGVXaWxkKS0+bm9kZSA9IGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bm9kZTsgIAoJCSAgICAKCQl9IGVsc2UgaWYgKHhtbFNjaGVtYUludGVyc2VjdFdpbGRjYXJkcyhjdHh0LCAqY29tcGxldGVXaWxkLCBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKSB7CgkJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZCgqY29tcGxldGVXaWxkKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQkJCgkgICAgfQoJfQoJYXR0cnMgPSBhdHRycy0+bmV4dDsKICAgIH0KICAgCQkgICAgICAgICAgICAgICAgIAogICAgcmV0dXJuICgwKTsgICAKfQoKLyoqCiAqIHhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zOgogKiBAd2lsZDogIHRoZSB3aWxkY2FyZAogKiBAbnM6ICB0aGUgbmFtZXNwYWNlCiAqIAogKgogKiBSZXR1cm5zIDEgaWYgdGhlIGdpdmVuIG5hbWVzcGFjZSBtYXRjaGVzIHRoZSB3aWxkY2FyZCwKICogMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zKHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGQsIGNvbnN0IHhtbENoYXIqIG5zKQp7CiAgICBpZiAod2lsZCA9PSBOVUxMKQoJcmV0dXJuKDApOwoKICAgIGlmICh3aWxkLT5hbnkpCglyZXR1cm4oMSk7CiAgICBlbHNlIGlmICh3aWxkLT5uc1NldCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1cjsKCgljdXIgPSB3aWxkLT5uc1NldDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmICh4bWxTdHJFcXVhbChjdXItPnZhbHVlLCBucykpCgkJcmV0dXJuKDEpOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KICAgIH0gZWxzZSBpZiAoKHdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChucyAhPSBOVUxMKSAmJiAKCSgheG1sU3RyRXF1YWwod2lsZC0+bmVnTnNTZXQtPnZhbHVlLCBucykpKQoJcmV0dXJuKDEpOwkKCQogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICogCiAqCiAqIEJ1aWxkcyB0aGUgd2lsZGNhcmQgYW5kIHRoZSBhdHRyaWJ1dGUgdXNlcyBvbiB0aGUgZ2l2ZW4gY29tcGxleCB0eXBlLgogKiBSZXR1cm5zIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VycywgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyIGN1ciwgYmFzZSwgdG1wLCBpZCA9IE5VTEwsIHByZXYgPSBOVUxMLCB1c2VzID0gTlVMTCwgCglsYXN0VXNlID0gTlVMTCwgbGFzdEJhc2VVc2UgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHJzOwogICAgaW50IGJhc2VJc0FueVR5cGUgPSAwOwoKICAgIC8qIAogICAgICogQ29tcGxleCBUeXBlIERlZmluaXRpb24gd2l0aCBjb21wbGV4IGNvbnRlbnQgU2NoZW1hIENvbXBvbmVudC4KICAgICAqCiAgICAgKiBBdHRyaWJ1dGUgdXNlcy4KICAgICAqLwogICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUGFyc2VCdWlsZEF0dHJpYnV0ZVVzZXM6ICIKCQkgICAgICAiYXR0cmlidXRlIHVzZXMgYWxyZWFkeSBidWlsZGVkLlxuIiwKCQkgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGlmICgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgfHwgCgkodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSkgewkKCQoJLyoKCSAqIEluaGVyaXQgdGhlIGF0dHJpYnV0ZSB1c2VzIG9mIHRoZSBiYXNlIHR5cGUuCgkgKi8KCWJhc2VUeXBlID0gdHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzLT5iYXNlVHlwZTsKCS8qCgkgKiBUT0RPOiBVUkdFTlQ6IFRoaXMgaXMgbm90IG5pY2UsIGJ1dCBjdXJyZW50bHkgCgkgKiB4bWxTY2hlbWFUeXBlQW55VHlwZURlZiBpcyBzdGF0aWMgaW4geG1sc2NoZW1hdHlwZXMuYy4KCSAqLwoJaWYgKChiYXNlVHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpICYmCgkgICAgeG1sU3RyRXF1YWwoYmFzZVR5cGUtPm5hbWUsIEJBRF9DQVNUICJhbnlUeXBlIikpIHsJICAgIAoJICAgIGJhc2VJc0FueVR5cGUgPSAxOwoJfQoJLyoKCSAqIFRPRE86IERvZXMgdGhlIHNwZWMgc3RhdGUgdGhhdCBpdCBpcyBhbiBlcnJvciB0byAiZXh0ZW5kIiB0aGUgCgkgKiBhbnlUeXBlPwoJICovCglpZiAoIWJhc2VJc0FueVR5cGUpIHsKCSAgICBpZiAoYmFzZVR5cGUgIT0gTlVMTCkgewoJCWZvciAoY3VyID0gYmFzZVR5cGUtPmF0dHJpYnV0ZVVzZXM7IGN1ciAhPSBOVUxMOyBjdXIgPSBjdXItPm5leHQpIHsKCQkgICAgdG1wID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIpIAoJCQl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmspKTsKCQkgICAgaWYgKHRtcCA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgCgkJCSAgICAiYnVpbGRpbmcgYXR0cmlidXRlIHVzZXMgb2YgY29tcGxleFR5cGUiLCBOVUxMKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgdG1wLT5hdHRyID0gY3VyLT5hdHRyOwoJCSAgICB0bXAtPm5leHQgPSBOVUxMOwoJCSAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSB7CgkJCXR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB0bXA7CgkJICAgIH0gZWxzZSAKCQkJbGFzdEJhc2VVc2UtPm5leHQgPSB0bXA7CgkJICAgIGxhc3RCYXNlVXNlID0gdG1wOyAKCQl9CgkgICAgfQoJfQoJYXR0cnMgPSB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMtPmF0dHJpYnV0ZXM7CQoJLyoKCSogSGFuZGxlIGF0dHJpYnV0ZSB3aWxkY2FyZHMuCgkqLwkKCXR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID0gdHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzLT5hdHRyaWJ1dGVXaWxkY2FyZDsKCglpZiAoeG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkKGN0eHQsIAoJICAgIGF0dHJzLCAmdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKSB7CgkgICAgaWYgKCh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSAmJgoJCSh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMtPmF0dHJpYnV0ZVdpbGRjYXJkKSkKCQl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQ7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglpZiAoKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpICYmCgkgICAgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+YXR0cmlidXRlV2lsZGNhcmQpKQoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfT1dORURfQVRUUl9XSUxEQ0FSRDsKCglpZiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pICYmIAoJICAgIChiYXNlVHlwZSAhPSBOVUxMKSAmJiAoYmFzZVR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpICYmIAoJICAgIChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkpIHsJICAgIAoJICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkJLyoKCQkqIFVuaW9uIHRoZSBjb21wbGV0ZSB3aWxkY2FyZCB3aXRoIHRoZSBiYXNlIHdpbGRjYXJkLgoJCSovCgkJaWYgKHhtbFNjaGVtYVVuaW9uV2lsZGNhcmRzKGN0eHQsIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCAKCQkgICAgYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkKCQkgICAgcmV0dXJuICgtMSk7CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogSnVzdCBpbmhlcml0IHRoZSB3aWxkY2FyZC4KCQkqLwoJCXR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID0gYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkOwoJICAgIH0KCX0KCWlmICghYmFzZUlzQW55VHlwZSkgewoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsKCQlpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewoJCSAgICAvKiAKCQkgICAgKiBEZXJpdmF0aW9uIFZhbGlkIChSZXN0cmljdGlvbiwgQ29tcGxleCkgCSAgICAKCQkgICAgKiA0LjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBhbHNvIGhhdmUgb25lLiAKCQkgICAgKi8KCQkgICAgaWYgKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9PSBOVUxMKSB7CSAgICAKCQkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzRfMSwKCQkJICAgICJUaGUgZGVyaXZlZCB0eXBlIFwiJXNcIiBoYXMgYW4gYXR0cmlidXRlIHdpbGRjYXJkLCAiCgkJCSAgICAiYnV0IHRoZSBiYXNlIHR5cGUgXCIlc1wiIGRvZXMgbm90IGhhdmUgb25lLlxuIiwKCQkJICAgIHR5cGUtPm5hbWUsIGJhc2VUeXBlLT5uYW1lKTsKCQkJcmV0dXJuICgxKTsKCQkgICAgfSBlbHNlIGlmICh4bWxTY2hlbWFJc1dpbGRjYXJkTnNDb25zdHJhaW50U3Vic2V0KGN0eHQsIAoJCQl0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAwKSB7CgkJCS8qIDQuMiAqLwoJCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fNF8yLAoJCQkgICAgIlRoZSB3aWxkY2FyZCBpbiB0aGUgZGVyaXZlZCB0eXBlIFwiJXNcIiBpcyBub3QgYSB2YWxpZCAiIAoJCQkgICAgInN1YnNldCBvZiB0aGUgb25lIGluIHRoZSBiYXNlIHR5cGUgXCIlc1wiLlxuIiwKCQkJICAgIHR5cGUtPm5hbWUsIGJhc2VUeXBlLT5uYW1lKTsJICAgIAoJCQlyZXR1cm4gKDEpOwoJCSAgICB9CgkJICAgIC8qIDQuMyBVbmxlc3MgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgdGhlILd1ci10eXBlIAoJCSAgICAqIGRlZmluaXRpb263LCB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24ncyB7YXR0cmlidXRlIAoJCSAgICAqIHdpbGRjYXJkfSdzIHtwcm9jZXNzIGNvbnRlbnRzfSBtdXN0IGJlIGlkZW50aWNhbCB0byBvciAKCQkgICAgKiBzdHJvbmdlciB0aGFuIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259J3Mge2F0dHJpYnV0ZSAKCQkgICAgKiB3aWxkY2FyZH0ncyB7cHJvY2VzcyBjb250ZW50c30sIHdoZXJlIHN0cmljdCBpcyBzdHJvbmdlciAKCQkgICAgKiB0aGFuIGxheCBpcyBzdHJvbmdlciB0aGFuIHNraXAuCgkJICAgICovCgkJICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzIDwgCgkJCWJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzKSB7CgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzMsCgkJCSAgICAiVGhlIHByb2Nlc3MgY29udGVudHMgb2YgdGhlIHdpbGRjYXJkIGluIHRoZSAiCgkJCSAgICAiZGVyaXZlZCB0eXBlIFwiJXNcIiBpcyB3ZWFrZXIgdGhhbiAiIAoJCQkgICAgInRoYXQgaW4gdGhlIGJhc2UgdHlwZSBcIiVzXCIuXG4iLAoJCQkgICAgdHlwZS0+bmFtZSwgYmFzZVR5cGUtPm5hbWUpOwoJCQlyZXR1cm4gKDEpOwoJCSAgICB9CgkJfQoJICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgewoJCS8qCgkJKiBEZXJpdmF0aW9uIFZhbGlkIChFeHRlbnNpb24pCgkJKiBBdCB0aGlzIHBvaW50IHRoZSB0eXBlIGFuZCB0aGUgYmFzZSBoYXZlIGJvdGgsIGVpdGhlcgoJCSogbm8gd2lsZGNhcmQgb3IgYSB3aWxkY2FyZC4KCQkqLwoJCWlmICgoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpICYmCgkJICAgIChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpKSB7CgkJICAgIC8qIDEuMyAqLwoJCSAgICBpZiAoeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldChjdHh0LCAKCQkJYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gMCkgewoJCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMywKCQkJICAgICJUaGUgd2lsZGNhcmQgaW4gdGhlIGRlcml2ZWQgdHlwZSBcIiVzXCIgaXMgbm90IGEgdmFsaWQgIiAKCQkJICAgICJzdXBlcnNldCBvZiB0aGUgb25lIGluIHRoZSBiYXNlIHR5cGUgXCIlc1wiLlxuIiwKCQkJICAgIHR5cGUtPm5hbWUsIGJhc2VUeXBlLT5uYW1lKTsKCQkJcmV0dXJuICgxKTsJCQoJCSAgICB9CgkJfQkJCgkgICAgfQoJfQogICAgfSBlbHNlIHsKCS8qCgkgKiBBbHRob3VnaCB0aGUgY29tcGxleFR5cGUgaXMgaW1wbGljaXRlbHkgZGVyaXZlZCBieSAicmVzdHJpY3Rpb24iCgkgKiBmcm9tIHRoZSB1ci10eXBlLCB0aGlzIGlzIG5vdCAoeWV0PykgcmVmbGVjdGVkIGJ5IGxpYnhtbDIuCgkgKi8KCWJhc2VUeXBlID0gTlVMTDsKCWF0dHJzID0gdHlwZS0+YXR0cmlidXRlczsKCWlmIChhdHRycyAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFNjaGVtYUJ1aWxkQ29tcGxldGVBdHRyaWJ1dGVXaWxkY2FyZChjdHh0LCAKCQlhdHRycywgJnR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkgewoJCWlmICgodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgJiYKCQkgICAgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+YXR0cmlidXRlV2lsZGNhcmQpKQoJCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQ7CgkJcmV0dXJuICgtMSk7CSAgICAKCSAgICB9CgkgICAgaWYgKCh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSAmJgoJCSgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQpID09IDApKQoJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfT1dORURfQVRUUl9XSUxEQ0FSRDsKCX0KICAgIH0KICAgIC8qCiAgICAgKiBHYXRoZXIgYXR0cmlidXRlIHVzZXMgZGVmaW5lZCBieSB0aGlzIHR5cGUuCiAgICAgKi8KICAgIGlmIChhdHRycyAhPSBOVUxMKSB7CglpZiAoeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQoY3R4dCwgYXR0cnMsIAoJICAgICZ1c2VzLCAmbGFzdFVzZSkgPT0gLTEpIHsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIC8qIDMuNC42IC0+IENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdCA0LgogICAgICogIlR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG11c3QgCiAgICAgKiBub3QgaGF2ZSBpZGVudGljYWwge25hbWV9cyBhbmQge3RhcmdldCBuYW1lc3BhY2V9cy4iCiAgICAgKgogICAgICogRm9yICJleHRlbnNpb24iIHRoaXMgaXMgZG9uZSBmdXJ0aGVyIGRvd24uCiAgICAgKi8KICAgIGlmICgodXNlcyAhPSBOVUxMKSAmJiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pID09IDApKSB7CgljdXIgPSB1c2VzOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgdG1wID0gY3VyLT5uZXh0OwoJICAgIHdoaWxlICh0bXAgIT0gTlVMTCkgewkgICAgCgkJaWYgKCh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoY3VyLT5hdHRyKSwgCgkJICAgIHhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZSh0bXAtPmF0dHIpKSkgJiYKCQkgICAgKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldE9ueW1vdXNUYXJnZXROc1VSSSgoeG1sU2NoZW1hVHlwZVB0cikgY3VyLT5hdHRyICksIAoJCSAgICB4bWxTY2hlbWFHZXRPbnltb3VzVGFyZ2V0TnNVUkkoKHhtbFNjaGVtYVR5cGVQdHIpIHRtcC0+YXR0cikpKSkgewoJCSAgICAKCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjdXItPmF0dHItPm5vZGUsIFhNTF9TQ0hFTUFQX0NUX1BST1BTX0NPUlJFQ1RfNCwKCQkJImN0LXByb3BzLWNvcnJlY3QuNDogRHVwbGljYXRlIGF0dHJpYnV0ZSB1c2Ugd2l0aCB0aGUgbmFtZSBcIiVzXCIgc3BlY2lmaWVkXG4iLAoJCQl4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoY3VyLT5hdHRyKSwgIE5VTEwpOwoJCSAgICBicmVhazsKCQl9CgkJdG1wID0gdG1wLT5uZXh0OwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CiAgICB9CQogICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgewkKCS8qCgkgKiBEZXJpdmUgYnkgcmVzdHJpY3Rpb24uCgkgKi8KCWlmIChiYXNlSXNBbnlUeXBlKSB7CgkgICAgdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7Cgl9IGVsc2UgewoJICAgIGludCBmb3VuZDsKCgkgICAgY3VyID0gdXNlczsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQlmb3VuZCA9IDA7CgkJYmFzZSA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CgkJd2hpbGUgKGJhc2UgIT0gTlVMTCkgewoJCSAgICBpZiAoKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShjdXItPmF0dHIpLCAKCQkJeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGJhc2UtPmF0dHIpKSkgJiYKCQkJKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldE9ueW1vdXNUYXJnZXROc1VSSSgoeG1sU2NoZW1hVHlwZVB0cikgY3VyLT5hdHRyKSwgCgkJCXhtbFNjaGVtYUdldE9ueW1vdXNUYXJnZXROc1VSSSgoeG1sU2NoZW1hVHlwZVB0cikgYmFzZS0+YXR0cikpKSkgewoJCQkKCQkJZm91bmQgPSAxOwkgICAgCgkJCWlmICgoY3VyLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpICYmCgkJCSAgICAoYmFzZS0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSkgewoJCQkgICAgLyoKCQkJICAgICogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAyLjEuMQoJCQkgICAgKi8JCQkKCQkJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY3VyLT5hdHRyLT5ub2RlLCAKCQkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8xXzEsCgkJCQkiZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMTogIgoJCQkJIlRoZSBcIm9wdGlvbmFsXCIgYXR0cmlidXRlICIKCQkJCSJ1c2UgXCIlc1wiIGlzIGluY29uc2lzdGVudCB3aXRoIGEgbWF0Y2hpbmcgIgoJCQkJIlwicmVxdWlyZWRcIiBhdHRyaWJ1dGUgdXNlIG9mIHRoZSBiYXNlIHR5cGVcbiIsCgkJCQl4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoY3VyLT5hdHRyKSwgTlVMTCk7CQkJCQkKCQkJfSBlbHNlIGlmICgoY3VyLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUFJPSElCSVRFRCkgJiYKCQkJICAgIChiYXNlLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQpKSB7CgkJCSAgICAvKgoJCQkgICAgKiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uIDMgCgkJCSAgICAqLwoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjdXItPmF0dHItPm5vZGUsIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMywKCQkJCSJkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjM6ICIKCQkJCSJUaGUgXCJyZXF1aXJlZFwiIGF0dHJpYnV0ZSB1c2UgXCIlc1wiIG9mIHRoZSBiYXNlIHR5cGUgIgoJCQkJImRvZXMgbm90IGhhdmUgYSBtYXRjaGluZyBhdHRyaWJ1dGUgdXNlIGluIHRoZSBkZXJpdmVkIHR5cGVcbiIsCQkKCQkJCXhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShjdXItPmF0dHIpLCBOVUxMKTsKCQkJICAgIAoJCQl9IGVsc2UgewoJCQkgICAgLyoKCQkJICAgICogT3ZlcnJpZGUgdGhlIGF0dHJpYnV0ZSB1c2UuCgkJCSAgICAqLwoJCQkgICAgYmFzZS0+YXR0ciA9IGN1ci0+YXR0cjsKCQkJfQoJCQkvKgoJCQkqIFRPRE86IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gIDIuMS4yICh7dHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCkKCQkJKiBUT0RPOiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uICAyLjEuMyAKCQkJKi8KCQkJYnJlYWs7CgkJICAgIH0JCQkJCgkJICAgIGJhc2UgPSBiYXNlLT5uZXh0OwoJCX0KCQkKCQlpZiAoIWZvdW5kKSB7CgkJICAgIGlmIChjdXItPmF0dHItPm9jY3VycyAhPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSB7CgkJCS8qCgkJCSogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAgMi4yCgkJCSovCgkJCWlmICgodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgJiYKCQkJICAgIHhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLAoJCQkJY3VyLT5hdHRyLT50YXJnZXROYW1lc3BhY2UpKQoJCQkgICAgZm91bmQgPSAxOwoKCQkJaWYgKCFmb3VuZCkgewoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjdXItPmF0dHItPm5vZGUsIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8yLAoJCQkJImRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yOiAiCgkJCQkiVGhlIGF0dHJpYnV0ZSB1c2UgXCIlc1wiIGhhcyBuZWl0aGVyIGEgbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSwgIgoJCQkJIm5vciBhIG1hdGNoaW5nIHdpbGRjYXJkIGluIHRoZSBiYXNlIHR5cGVcbiIsCQkKCQkJCXhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShjdXItPmF0dHIpLCBOVUxMKTsKCQkJfSBlbHNlIHsKCQkJICAgIC8qIAoJCQkgICAgKiBBZGQgdGhlIGF0dHJpYnV0ZSB1c2UuCgkJCSAgICAqCgkJCSAgICAqIE5vdGUgdGhhdCB0aGlzIG1heSBsZWFkIHRvIGZ1bm55IGRlcml2YXRpb24gZXJyb3IgcmVwb3J0cywgaWYKCQkJICAgICogbXVsdGlwbGUgZXF1YWwgYXR0cmlidXRlIHVzZXMgZXhpc3Q7IGJ1dCB0aGlzIGlzIG5vdAoJCQkgICAgKiBhbGxvd2VkIGFueXdheSwgYW5kIGl0IHdpbGwgYmUgcmVwb3J0ZWQgYmVmb3JlaGFuZC4KCQkJICAgICovCgkJCSAgICB0bXAgPSBjdXI7CgkJCSAgICBpZiAocHJldiAhPSBOVUxMKQoJCQkJcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQkJICAgIGVsc2UgCgkJCQl1c2VzID0gY3VyLT5uZXh0OwoJCQkgICAgY3VyID0gY3VyLT5uZXh0OyAgICAJCQkKCQkJICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzID09IE5VTEwpIHsKCQkJCXR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB0bXA7CgkJCSAgICB9IGVsc2UgCgkJCQlsYXN0QmFzZVVzZS0+bmV4dCA9IHRtcDsKCQkJICAgIGxhc3RCYXNlVXNlID0gdG1wOwkJCgkJCSAgICAKCQkJICAgIGNvbnRpbnVlOwoJCQl9CgkJICAgIH0KCQl9CQkgICAgCSAgICAKCQlwcmV2ID0gY3VyOwkKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfQoJICAgIGlmICh1c2VzICE9IE5VTEwpCgkJeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QodXNlcyk7Cgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pIHsgCgkvKgoJICogVGhlIHNwZWMgYWxsb3dzIG9ubHkgYXBwZW5kaW5nLCBhbmQgbm90IG90aGVyIGtpbmRzIG9mIGV4dGVuc2lvbnMuCgkgKgoJICogVGhpcyBlbnN1cmVzOiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IERlcml2YXRpb24gVmFsaWQgKEV4dGVuc2lvbikgOiAxLjIgCgkgKi8KCWlmICh1c2VzICE9IE5VTEwpIHsKCSAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSB7CgkJdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7CgkgICAgfSBlbHNlIAoJCWxhc3RCYXNlVXNlLT5uZXh0ID0gdXNlczsKCX0KICAgIH0gZWxzZSB7CgkvKiAKCSogRGVyaXZlIGltcGxpY2l0ZWx5IGZyb20gdGhlIHVyLXR5cGUuCgkqLwoJdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7CiAgICB9CiAgICAvKgogICAgICogMy40LjYgLT4gQ29tcGxleCBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0CiAgICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpIHsKCWN1ciA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CglwcmV2ID0gTlVMTDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiA0LiBUd28gZGlzdGluY3QgYXR0cmlidXRlIGRlY2xhcmF0aW9ucyBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IAoJICAgICogbm90IGhhdmUgaWRlbnRpY2FsIHtuYW1lfXMgYW5kIHt0YXJnZXQgbmFtZXNwYWNlfXMuCgkgICAgKgoJICAgICogTm90ZSB0aGF0IHRoaXMgd2FzIGFscmVhZHkgZG9uZSBmb3IgInJlc3RyaWN0aW9uIiBhbmQgdHlwZXMgZGVyaXZlZCBmcm9tCgkgICAgKiB0aGUgdXItdHlwZS4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB7CgkJdG1wID0gY3VyLT5uZXh0OwoJCXdoaWxlICh0bXAgIT0gTlVMTCkgewkgICAgCgkJICAgIGlmICgoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGN1ci0+YXR0ciksIAoJCQl4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUodG1wLT5hdHRyKSkpICYmCgkJCSh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRPbnltb3VzVGFyZ2V0TnNVUkkoKHhtbFNjaGVtYVR5cGVQdHIpIGN1ci0+YXR0ciApLCAKCQkJeG1sU2NoZW1hR2V0T255bW91c1RhcmdldE5zVVJJKCh4bWxTY2hlbWFUeXBlUHRyKSB0bXAtPmF0dHIpKSkpIHsKCgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgY3VyLT5hdHRyLT5ub2RlLCBYTUxfU0NIRU1BUF9DVF9QUk9QU19DT1JSRUNUXzQsCgkJCSAgICAiY3QtcHJvcHMtY29ycmVjdC40OiBEdXBsaWNhdGUgYXR0cmlidXRlIHVzZSB3aXRoIHRoZSBuYW1lIFwiJXNcIiBzcGVjaWZpZWRcbiIsCgkJCSAgICB4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoY3VyLT5hdHRyKSwgIE5VTEwpOwoJCQlicmVhazsKCQkgICAgfQoJCSAgICB0bXAgPSB0bXAtPm5leHQ7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogNS4gVHdvIGRpc3RpbmN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gbXVzdCAKCSAgICAqIG5vdCBoYXZlIHt0eXBlIGRlZmluaXRpb259cyB3aGljaCBhcmUgb3IgYXJlIGRlcml2ZWQgZnJvbSBJRC4KCSAgICAqLwoJICAgIGlmICgoY3VyLT5hdHRyLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJiAKCQkvKgoJCSogVE9ETzogRklYTUU6IFhNTF9TQ0hFTUFTX0lEIHNob3VsZCBiZSB1c2VkIGluc3RlYWQgb2YgIjIzIiAhISEsIAoJCSogYnV0IHRoZSB4bWxTY2hlbWFWYWxUeXBlIGlzIG5vdCBtYWRlIHB1YmxpYyB5ZXQuCgkJKi8KCQkoeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKGN0eHQsICh4bWxTY2hlbWFUeXBlUHRyKSBjdXItPmF0dHIsIDIzKSkpIHsKCQlpZiAoaWQgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGN1ci0+YXR0ci0+bm9kZSwgWE1MX1NDSEVNQVBfQ1RfUFJPUFNfQ09SUkVDVF81LCAKCQkJImN0LXByb3BzLWNvcnJlY3QuNTogVHdvIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMsICIKCQkJIlwiJXNcIiBhbmQgXCIlc1wiIGhhdmUgdHlwZXMgd2hpY2ggZGVyaXZlZCBmcm9tIElEXG4iLAoJCQl4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoaWQtPmF0dHIpLCAKCQkJeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGN1ci0+YXR0cikpOwoJCX0gCgkJaWQgPSBjdXI7CgkgICAgfQoJICAgIC8qCgkgICAgKiBSZW1vdmUgInByb2hpYml0ZWQiIGF0dHJpYnV0ZSB1c2VzLiBUaGUgcmVhc29uIHRoaXMgaXMgZG9uZSBhdCB0aGlzIGxhdGUgCgkgICAgKiBzdGFnZSBpcyB0byBiZSBhYmxlIHRvIGNhdGNoIGR1YmxpY2F0ZSBhdHRyaWJ1dGUgdXNlcy4gU28gd2UgaGFkIHRvIGtlZXAKCSAgICAqIHByb2hpYml0ZWQgdXNlcyBpbiB0aGUgbGlzdCBhcyB3ZWxsLgoJICAgICovCgkgICAgaWYgKGN1ci0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpIHsKCQl0bXAgPSBjdXI7CgkJaWYgKHByZXYgPT0gTlVMTCkKCQkgICAgdHlwZS0+YXR0cmlidXRlVXNlcyA9IGN1ci0+bmV4dDsKCQllbHNlCgkJICAgIHByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJY3VyID0gY3VyLT5uZXh0OwoJCXhtbEZyZWUodG1wKTsKCSAgICB9IGVsc2UgewoJCXByZXYgPSBjdXI7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCX0gICAgCiAgICB9CiAgICAvKgkKICAgICAqIFRPRE86IFRoaXMgY2hlY2sgc2hvdWxkIGJlIHJlbW92ZWQgaWYgd2UgYXJlIDEwMCUgc3VyZSBvZgogICAgICogdGhlIGJhc2UgdHlwZSBhdHRyaWJ1dGUgdXNlcyBhbHJlYWR5IGJlaW5nIGJ1aWx0LgogICAgICovCiAgICBpZiAoKGJhc2VUeXBlICE9IE5VTEwpICYmICghYmFzZUlzQW55VHlwZSkgJiYKCShiYXNlVHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgJiYKCShiYXNlVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIGJhc2VUeXBlLT5ub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFQYXJzZUJ1aWxkQXR0cmlidXRlVXNlczogIgoJICAgICJhdHRyaWJ1dGUgdXNlcyBub3QgYnVpbGRlZCBvbiBiYXNlIHR5cGUgXCIlc1wiLlxuIiwKCSAgICBiYXNlVHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9ICAgIAogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVR5cGVGaXh1cDoKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZpeGVzIHRoZSBjb250ZW50IG1vZGVsIG9mIHRoZSB0eXBlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVHlwZUZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICBpZiAodHlwZURlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIG5hbWUgPSB0eXBlRGVjbC0+bmFtZTsKICAgIGlmICh0eXBlRGVjbC0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pIHsKICAgICAgICBzd2l0Y2ggKHR5cGVEZWNsLT50eXBlKSB7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UOnsKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlRml4dXAodHlwZURlY2wtPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+c3VidHlwZXMtPmNvbnRlbnRUeXBlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTjp7CiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlRml4dXAodHlwZURlY2wtPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5iYXNlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCB0eXBlRGVjbC0+YmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmJhc2VOcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiYXNlVHlwZSA9PSBOVUxMKSB7CgkJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGVEZWNsLT5ub2RlLAoJCQkgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0JBU0VfVFlQRSwKCQkJCSJTY2hlbWFzOiB0eXBlICVzIGJhc2UgdHlwZSAlcyBub3QgZm91bmRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIHR5cGVEZWNsLT5iYXNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChiYXNlVHlwZS0+Y29udGVudFR5cGUgPT0gCgkJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgewoJCQkgICAgLyogCgkJCSAgICAgKiBUaGUgYmFzZSB0eXBlIG1pZ2h0IGJlIG5vdCAidHlwZSBmaXhlZCIgeWV0LAoJCQkgICAgICogc28gZG8gaXQgbm93LiAqLwoJCQkgICAgLyogCgkJCSAgICAgKiBUT0RPOiBJcyBhIGNoZWNrIGZvciBjaXJjdWxhciBkZXJpdmF0aW9uIGFscmVhZHkKCQkJICAgICAqIGRvbmU/CgkJCSAgICAgKi8KCQkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlVHlwZSwgY3R4dCwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmJhc2VUeXBlID0gYmFzZVR5cGU7CiAgICAgICAgICAgICAgICAgICAgfQoJCSAgICBpZiAodHlwZURlY2wtPnN1YnR5cGVzID09IE5VTEwpCgkJCWlmICh0eXBlRGVjbC0+YmFzZVR5cGUgIT0gTlVMTCkgewoJCQkgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KCQkJICAgICAgICAgICAgIHR5cGVEZWNsLT5iYXNlVHlwZS0+Y29udGVudFR5cGU7CgkJCX0gZWxzZSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIDEuMS4xICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoKHR5cGVEZWNsLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9UWVBFX0FMTCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIDEuMS4yICovCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICgodHlwZURlY2wtPnN1YnR5cGVzLT50eXBlID09CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKHR5cGVEZWNsLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkpCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIDEuMS4zICovCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogMS4yIGFuZCAyLlggYXJlIGFwcGxpZWQgYXQgdGhlIG90aGVyIGxheWVyICovCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT046ewogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUNvbnRlbnRUeXBlIGV4cGxpY2l0Q29udGVudFR5cGU7CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwoKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPmJhc2UgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlOwoKICAgICAgICAgICAgICAgICAgICAgICAgYmFzZVR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIHR5cGVEZWNsLT5iYXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+YmFzZU5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhc2VUeXBlID09IE5VTEwpIHsKCQkJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCgkJCSAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQkFTRV9UWVBFLAoJCQkJIlNjaGVtYXM6IHR5cGUgJXMgYmFzZSB0eXBlICVzIG5vdCBmb3VuZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgdHlwZURlY2wtPmJhc2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJhc2VUeXBlLT5jb250ZW50VHlwZSA9PSAKCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CgkJCSAgICAvKiAKCQkJICAgICAqIFRoZSBiYXNlIHR5cGUgbWlnaHQgYmUgbm90ICJ0eXBlIGZpeGVkIiB5ZXQsCgkJCSAgICAgKiBzbyBkbyBpdCBub3cuICovCgkJCSAgICAvKiAKCQkJICAgICAqIFRPRE86IElzIGEgY2hlY2sgZm9yIGNpcmN1bGFyIGRlcml2YXRpb24gYWxyZWFkeQoJCQkgICAgICogZG9uZT8KCQkJICAgICAqLwoJCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGJhc2VUeXBlLCBjdHh0LCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+YmFzZVR5cGUgPSBiYXNlVHlwZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlRml4dXAodHlwZURlY2wtPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKCiAgICAgICAgICAgICAgICAgICAgZXhwbGljaXRDb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPnN1YnR5cGVzID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIDEuMS4xICovCiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGxpY2l0Q29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoKHR5cGVEZWNsLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9UWVBFX0FMTCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIDEuMS4yICovCiAgICAgICAgICAgICAgICAgICAgICAgIGV4cGxpY2l0Q29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmICh0eXBlRGVjbC0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpKQogICAgICAgICAgICAgICAgICAgICAgICAvKiAxLjEuMyAqLwogICAgICAgICAgICAgICAgICAgICAgICBleHBsaWNpdENvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoKICAgICAgICAgICAgICAgICAgICBiYXNlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIHR5cGVEZWNsLT5iYXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5iYXNlTnMpOwogICAgICAgICAgICAgICAgICAgIGlmIChiYXNlID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlRGVjbC0+bm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0JBU0VfVFlQRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2NoZW1hczogYmFzZSB0eXBlICVzIG9mIHR5cGUgJXMgbm90IGZvdW5kXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5iYXNlLCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPnJlY3Vyc2UpIHsKCQkJLyogVE9ETzogVGhlIHdvcmQgInJlY3Vyc2l2ZSIgc2hvdWxkIGJlIGNoYW5nZWQgdG8gImNpcmN1bGFyIiBoZXJlLiAqLwogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGVEZWNsLT5ub2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQkFTRV9UWVBFLAoJCQkJICAiU2NoZW1hczogZXh0ZW5zaW9uIHR5cGUgJXMgaXMgcmVjdXJzaXZlXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CgkJICAgIH0KCQkgICAgdHlwZURlY2wtPnJlY3Vyc2UgPSAxOwogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlLCBjdHh0LCBOVUxMKTsKCQkgICAgdHlwZURlY2wtPnJlY3Vyc2UgPSAwOwogICAgICAgICAgICAgICAgICAgIGlmIChleHBsaWNpdENvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiAyLjEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0gYmFzZS0+Y29udGVudFR5cGU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChiYXNlLT5jb250ZW50VHlwZSA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIDIuMiBpbWJpdGFibGUgISAqLwogICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIDIuMyBpbWJpdGFibGUgcGFyZWlsICEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6ewogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+c3VidHlwZXMgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVGaXh1cCh0eXBlRGVjbC0+c3VidHlwZXMsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPnN1YnR5cGVzLT5jb250ZW50VHlwZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoJCQkvKiBFdmFsdWF0ZSB0aGUgZGVyaXZhdGlvbiBtZXRob2QuICovCgkJCWlmICgodHlwZURlY2wtPnN1YnR5cGVzICE9IE5VTEwpICYmCgkJCSAgICAoKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PSAKCQkJCVhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHx8CgkJCSAgICAodHlwZURlY2wtPnN1YnR5cGVzLT50eXBlID09IAoJCQkJWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSkgJiYKCQkJICAgICh0eXBlRGVjbC0+c3VidHlwZXMtPnN1YnR5cGVzICE9IE5VTEwpKSB7CQkJICAgIAkJCSAgICAKCQkJICAgIGlmICh0eXBlRGVjbC0+c3VidHlwZXMtPnN1YnR5cGVzLT50eXBlID09IAoJCQkJICAgIFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT04pIHsKCQkJCXR5cGVEZWNsLT5mbGFncyB8PSAKCQkJCSAgICBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTjsKCQkJICAgIH0gZWxzZSBpZiAodHlwZURlY2wtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+dHlwZSA9PSAKCQkJCSAgICBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT04pIHsKCQkJCXR5cGVEZWNsLT5mbGFncyB8PSAKCQkJCSAgICBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OOwogICAgICAgICAgICAgICAgICAgIH0KCQkJfQogICAgICAgICAgICAgICAgICAgIH0KCQkgICAgeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uKGN0eHQsIHR5cGVEZWNsKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UOnsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPnN1YnR5cGVzID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVGaXh1cCh0eXBlRGVjbC0+c3VidHlwZXMsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPnN1YnR5cGVzLT5jb250ZW50VHlwZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoJCQkvKiAKCQkJICogUmVtb3ZlZCBkdWUgdG8gaW1wbGVtZW50YXRpb24gb2YgdGhlIGJ1aWxkIG9mIGF0dHJpYnV0ZSB1c2VzLiAKCQkJICovCgkJCS8qCgkJCWlmICh0eXBlRGVjbC0+YXR0cmlidXRlcyA9PSBOVUxMKQoJCQkgICAgdHlwZURlY2wtPmF0dHJpYnV0ZXMgPQoJCQkgICAgICAgIHR5cGVEZWNsLT5zdWJ0eXBlcy0+YXR0cmlidXRlczsKCQkJKi8KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CiAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfTElTVDoKCQl4bWxTY2hlbWFQYXJzZUxpc3RSZWZGaXh1cCh0eXBlRGVjbCwgY3R4dCk7CgkJLyogbm8gYnJlYWsgb24gcHVycG9zZSAqLwogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9VTklPTjoKCQlpZiAodHlwZURlY2wtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1VOSU9OKQoJCSAgICB4bWxTY2hlbWFQYXJzZVVuaW9uUmVmQ2hlY2sodHlwZURlY2wsIGN0eHQpOwoJCS8qIG5vIGJyZWFrIG9uIHB1cnBvc2UgKi8KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQkFTSUM6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRkFDRVQ6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVVI6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX05PVEFUSU9OOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CiAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwoJCWlmICh0eXBlRGVjbC0+c3VidHlwZXMgIT0gTlVMTCkKCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGVEZWNsLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiNpZmRlZiBERUJVR19UWVBFCiAgICBpZiAodHlwZURlY2wtPm5vZGUgIT0gTlVMTCkgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiVHlwZSBvZiAlcyA6ICVzOiVkIDoiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+bm9kZS0+ZG9jLT5VUkwsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEdldExpbmVObyh0eXBlRGVjbC0+bm9kZSkpOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIlR5cGUgb2YgJXMgOiIsIG5hbWUpOwogICAgfQogICAgc3dpdGNoICh0eXBlRGVjbC0+Y29udGVudFR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAic2ltcGxlXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiZWxlbWVudHNcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgInVua25vd24gISEhXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiZW1wdHlcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJtaXhlZFxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEX09SX0VMRU1FTlRTOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIm1peGVkIG9yIGVsZW1zXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiYmFzaWNcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub3QgcmVnaXN0ZXJlZCAhISFcbiIpOwogICAgICAgICAgICBicmVhazsKICAgIH0KI2VuZGlmCn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0ZhY2V0OgogKiBAZmFjZXQ6ICB0aGUgZmFjZXQKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0IG9yIE5VTEwKICogQG5hbWU6IG5hbWUgb2YgdGhlIHR5cGUKICoKICogQ2hlY2tzIHRoZSBkZWZhdWx0IHZhbHVlcyB0eXBlcywgZXNwZWNpYWxseSBmb3IgZmFjZXRzIAogKgogKiBSZXR1cm5zIDAgaWYgb2theSBvciAtMSBpbiBjYWUgb2YgZXJyb3IKICovCmludAp4bWxTY2hlbWFDaGVja0ZhY2V0KHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LAogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgbm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSA9IE5VTEw7CiAgICBpbnQgcmV0ID0gMDsKCiAgICBpZiAobm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSA9PSBOVUxMKSB7CiAgICAgICAgbm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSA9CiAgICAgICAgICAgIHhtbFNjaGVtYUdldFByZWRlZmluZWRUeXBlKEJBRF9DQVNUICJub25OZWdhdGl2ZUludGVnZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFOcyk7CiAgICB9CiAgICBzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRTp7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogT2theSB3ZSBuZWVkIHRvIHZhbGlkYXRlIHRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICogYXQgdGhhdCBwb2ludC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0OwoKICAgICAgICAgICAgICAgIHZjdHh0ID0geG1sU2NoZW1hTmV3VmFsaWRDdHh0KE5VTEwpOwogICAgICAgICAgICAgICAgaWYgKHZjdHh0ID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlKHZjdHh0LCB0eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgICAgIGZhY2V0LT52YWwgPSB2Y3R4dC0+dmFsdWU7CiAgICAgICAgICAgICAgICB2Y3R4dC0+dmFsdWUgPSBOVUxMOwogICAgICAgICAgICAgICAgaWYgKGZhY2V0LT52YWwgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIC8qIGVycm9yIGNvZGUgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgZmFjZXQtPm5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2NoZW1hczogdHlwZSAlcyBmYWNldCB2YWx1ZSAlcyBpbnZhbGlkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dCh2Y3R4dCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjp7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogT2theSB3ZSBuZWVkIHRvIHZhbGlkYXRlIHRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICogYXQgdGhhdCBwb2ludC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0OwogICAgICAgICAgICAgICAgaW50IHRtcDsKCiAgICAgICAgICAgICAgICB2Y3R4dCA9IHhtbFNjaGVtYU5ld1ZhbGlkQ3R4dChOVUxMKTsKICAgICAgICAgICAgICAgIGlmICh2Y3R4dCA9PSBOVUxMKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgdG1wID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZSh2Y3R4dCwgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICBpZiAodG1wICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgZmFjZXQtPm5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9FTlVNLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTY2hlbWFzOiB0eXBlICVzIGVudW1lcmF0aW9uIHZhbHVlICVzIGludmFsaWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KHZjdHh0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CiAgICAgICAgICAgIGZhY2V0LT5yZWdleHAgPSB4bWxSZWdleHBDb21waWxlKGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgIGlmIChmYWNldC0+cmVnZXhwID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGVEZWNsLT5ub2RlLAoJCQkgICAgICBYTUxfU0NIRU1BUF9SRUdFWFBfSU5WQUxJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IHR5cGUgJXMgZmFjZXQgcmVnZXhwICVzIGludmFsaWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICByZXQgPSAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOnsKICAgICAgICAgICAgICAgIGludCB0bXA7CgogICAgICAgICAgICAgICAgdG1wID0KICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZVByZWRlZmluZWRUeXBlKG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldC0+dmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZmFjZXQtPnZhbCk7CiAgICAgICAgICAgICAgICBpZiAodG1wICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAvKiBlcnJvciBjb2RlICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGZhY2V0LT5ub2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IHR5cGUgJXMgZmFjZXQgdmFsdWUgJXMgaW52YWxpZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBmYWNldC0+dmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXQgPSAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6ewogICAgICAgICAgICAgICAgaWYgKHhtbFN0ckVxdWFsKGZhY2V0LT52YWx1ZSwgQkFEX0NBU1QgInByZXNlcnZlIikpIHsKICAgICAgICAgICAgICAgICAgICBmYWNldC0+d2hpdGVzcGFjZSA9IFhNTF9TQ0hFTUFTX0ZBQ0VUX1BSRVNFUlZFOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJyZXBsYWNlIikpIHsKICAgICAgICAgICAgICAgICAgICBmYWNldC0+d2hpdGVzcGFjZSA9IFhNTF9TQ0hFTUFTX0ZBQ0VUX1JFUExBQ0U7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGZhY2V0LT52YWx1ZSwgQkFEX0NBU1QgImNvbGxhcHNlIikpIHsKICAgICAgICAgICAgICAgICAgICBmYWNldC0+d2hpdGVzcGFjZSA9IFhNTF9TQ0hFTUFTX0ZBQ0VUX0NPTExBUFNFOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgZmFjZXQtPm5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9XSElURV9TUEFDRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2NoZW1hczogdHlwZSAlcyB3aGl0ZVNwYWNlIHZhbHVlICVzIGludmFsaWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrRGVmYXVsdHM6CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBDaGVja3MgdGhlIGRlZmF1bHQgdmFsdWVzIHR5cGVzLCBlc3BlY2lhbGx5IGZvciBmYWNldHMgCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0RlZmF1bHRzKHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gdHlwZURlY2wtPm5hbWU7CiAgICBpZiAodHlwZURlY2wtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OKSB7CiAgICAgICAgaWYgKHR5cGVEZWNsLT5mYWNldHMgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldCA9IHR5cGVEZWNsLT5mYWNldHM7CgogICAgICAgICAgICB3aGlsZSAoZmFjZXQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgeG1sU2NoZW1hQ2hlY2tGYWNldChmYWNldCwgdHlwZURlY2wsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICAgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJHcnBGaXh1cDoKICogQGF0dHJncnBEZWNsOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGF0dHJpYnV0ZXMgZGVmaW5pdGlvbnMKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUF0dHJHcnBGaXh1cCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBhdHRyZ3JwLAogICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gYXR0cmdycC0+bmFtZTsKICAgIGlmIChhdHRyZ3JwLT5hdHRyaWJ1dGVzICE9IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHJncnAtPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgcmVmOwoKICAgICAgICByZWYgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cChjdHh0LT5zY2hlbWEsIGF0dHJncnAtPnJlZiwgYXR0cmdycC0+cmVmTnMpOwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGF0dHJncnAtPm5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9BVFRSSUJVVEVfR1JPVVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IGF0dHJpYnV0ZSBncm91cCAlcyByZWZlcmVuY2UgJXMgbm90IGZvdW5kXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIGF0dHJncnAtPnJlZik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgeG1sU2NoZW1hQXR0ckdycEZpeHVwKHJlZiwgY3R4dCwgTlVMTCk7CiAgICAgICAgYXR0cmdycC0+YXR0cmlidXRlcyA9IHJlZi0+YXR0cmlidXRlczsKCWF0dHJncnAtPmF0dHJpYnV0ZVdpbGRjYXJkID0gcmVmLT5hdHRyaWJ1dGVXaWxkY2FyZDsKICAgIH0KICAgIC8qIAogICAgKiBSZW1vdmVkLCBzaW5jZSBhIGdsb2JhbCBhdHRyaWJ1dGUgZ3JvdXAgZG9lcyBub3QgbmVlZCB0byBob2xkIGFueQogICAgKiBhdHRyaWJ1dGVzIG9yIHdpbGRjYXJkIAogICAgKi8KICAgIC8qCiAgICBlbHNlIHsKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGF0dHJncnAtPm5vZGUsIFhNTF9TQ0hFTUFQX05PQVRUUl9OT1JFRiwKICAgICAgICAgICAgICAgICAgICAgICJTY2hlbWFzOiBhdHRyaWJ1dGUgZ3JvdXAgJXMgaGFzIG5vIGF0dHJpYnV0ZXMgbm9yIHJlZmVyZW5jZVxuIiwKICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIE5VTEwpOwogICAgfQogICAgKi8KfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJGaXh1cDoKICogQGF0dHJEZWNsOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGF0dHJpYnV0ZXMgZGVmaW5pdGlvbnMKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUF0dHJGaXh1cCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0ckRlY2wsCiAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIG5hbWUgPSBhdHRyRGVjbC0+bmFtZTsKICAgIGlmIChhdHRyRGVjbC0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoYXR0ckRlY2wtPnR5cGVOYW1lICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CgogICAgICAgIHR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgYXR0ckRlY2wtPnR5cGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJEZWNsLT50eXBlTnMpOwogICAgICAgIGlmICh0eXBlID09IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBhdHRyRGVjbC0+bm9kZSwgWE1MX1NDSEVNQVBfVU5LTk9XTl9UWVBFLAogICAgICAgICAgICAgICAgICAgICAgICAgICJTY2hlbWFzOiBhdHRyaWJ1dGUgJXMgdHlwZSAlcyBub3QgZm91bmRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgYXR0ckRlY2wtPnR5cGVOYW1lKTsKICAgICAgICB9CiAgICAgICAgYXR0ckRlY2wtPnN1YnR5cGVzID0gdHlwZTsKICAgIH0gZWxzZSBpZiAoYXR0ckRlY2wtPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHJlZjsKCglyZWYgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoY3R4dC0+c2NoZW1hLCBhdHRyRGVjbC0+cmVmLCBhdHRyRGVjbC0+cmVmTnMpOwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGF0dHJEZWNsLT5ub2RlLCBYTUxfU0NIRU1BUF9VTktOT1dOX1JFRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiU2NoZW1hczogYXR0cmlidXRlICVzIHJlZmVyZW5jZSAlcyBub3QgZm91bmRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgYXR0ckRlY2wtPnJlZik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgeG1sU2NoZW1hQXR0ckZpeHVwKHJlZiwgY3R4dCwgTlVMTCk7CiAgICAgICAgYXR0ckRlY2wtPnN1YnR5cGVzID0gcmVmLT5zdWJ0eXBlczsKICAgIH0gZWxzZSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBhdHRyRGVjbC0+bm9kZSwgWE1MX1NDSEVNQVBfTk9UWVBFX05PUkVGLAogICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IGF0dHJpYnV0ZSAlcyBoYXMgbm8gdHlwZSBub3IgcmVmZXJlbmNlXG4iLAogICAgICAgICAgICAgICAgICAgICAgbmFtZSwgTlVMTCk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogcGFyc2UgYSBzY2hlbWEgZGVmaW5pdGlvbiByZXNvdXJjZSBhbmQgYnVpbGQgYW4gaW50ZXJuYWwKICogWE1MIFNoZW1hIHN0cnV0dXJlIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHZhbGlkYXRlIGluc3RhbmNlcy4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBpbnRlcm5hbCBYTUwgU2NoZW1hIHN0cnVjdHVyZSBidWlsdCBmcm9tIHRoZSByZXNvdXJjZSBvcgogKiAgICAgICAgIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUHRyCnhtbFNjaGVtYVBhcnNlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hUHRyIHJldCA9IE5VTEw7CiAgICB4bWxEb2NQdHIgZG9jOwogICAgeG1sTm9kZVB0ciByb290OwogICAgaW50IG5iZXJyb3JzOwogICAgaW50IHByZXNlcnZlID0gMDsKCiAgICB4bWxTY2hlbWFJbml0VHlwZXMoKTsKCiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgbmJlcnJvcnMgPSBjdHh0LT5uYmVycm9yczsKICAgIGN0eHQtPm5iZXJyb3JzID0gMDsKICAgIGN0eHQtPmNvdW50ZXIgPSAwOwogICAgY3R4dC0+Y29udGFpbmVyID0gTlVMTDsKCiAgICAvKgogICAgICogRmlyc3Qgc3RlcCBpcyB0byBwYXJzZSB0aGUgaW5wdXQgZG9jdW1lbnQgaW50byBhbiBET00vSW5mb3NldAogICAgICovCiAgICBpZiAoY3R4dC0+VVJMICE9IE5VTEwpIHsKICAgICAgICBkb2MgPSB4bWxSZWFkRmlsZSgoY29uc3QgY2hhciAqKSBjdHh0LT5VUkwsIE5VTEwsIAoJICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgICAgICBpZiAoZG9jID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJCSAgWE1MX1NDSEVNQVBfRkFJTEVEX0xPQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVBhcnNlOiBjb3VsZCBub3QgbG9hZCAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5VUkwsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoY3R4dC0+YnVmZmVyICE9IE5VTEwpIHsKICAgICAgICBkb2MgPSB4bWxSZWFkTWVtb3J5KGN0eHQtPmJ1ZmZlciwgY3R4dC0+c2l6ZSwgTlVMTCwgTlVMTCwKCSAgICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgICAgICBpZiAoZG9jID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJCSAgWE1MX1NDSEVNQVBfRkFJTEVEX1BBUlNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IHBhcnNlXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgICAgICBkb2MtPlVSTCA9IHhtbFN0cmR1cChCQURfQ0FTVCAiaW5fbWVtb3J5X2J1ZmZlciIpOwogICAgICAgIGN0eHQtPlVSTCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgQkFEX0NBU1QgImluX21lbW9yeV9idWZmZXIiLCAtMSk7CiAgICB9IGVsc2UgaWYgKGN0eHQtPmRvYyAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0gY3R4dC0+ZG9jOwoJcHJlc2VydmUgPSAxOwogICAgfSBlbHNlIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwKCQkgICAgICBYTUxfU0NIRU1BUF9OT1RISU5HX1RPX1BBUlNFLAoJCSAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IHBhcnNlXG4iLAoJCSAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CgogICAgLyoKICAgICAqIFRoZW4gZXh0cmFjdCB0aGUgcm9vdCBhbmQgU2NoZW1hIHBhcnNlIGl0CiAgICAgKi8KICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwogICAgaWYgKHJvb3QgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PUk9PVCwKCQkgICAgICAic2NoZW1hcyBoYXMgbm8gcm9vdCIsIE5VTEwsIE5VTEwpOwoJaWYgKCFwcmVzZXJ2ZSkgewoJICAgIHhtbEZyZWVEb2MoZG9jKTsKCX0KICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQoKICAgIC8qCiAgICAgKiBSZW1vdmUgYWxsIHRoZSBibGFuayB0ZXh0IG5vZGVzCiAgICAgKi8KICAgIHhtbFNjaGVtYUNsZWFudXBEb2MoY3R4dCwgcm9vdCk7CgogICAgLyoKICAgICAqIFRoZW4gZG8gdGhlIHBhcnNpbmcgZm9yIGdvb2QKICAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hUGFyc2VTY2hlbWEoY3R4dCwgcm9vdCk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAoIXByZXNlcnZlKSB7CgkgICAgeG1sRnJlZURvYyhkb2MpOwoJfQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPmRvYyA9IGRvYzsKICAgIHJldC0+cHJlc2VydmUgPSBwcmVzZXJ2ZTsKCiAgICAvKgogICAgICogVGhlbiBmaXggYWxsIHRoZSByZWZlcmVuY2VzLgogICAgICovCiAgICBjdHh0LT5zY2hlbWEgPSByZXQ7CiAgICB4bWxIYXNoU2NhbkZ1bGwocmV0LT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXJGdWxsKSB4bWxTY2hlbWFSZWZGaXh1cENhbGxiYWNrLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBmaXh1cCBhbGwgYXR0cmlidXRlcyBkZWNsYXJhdGlvbnMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5hdHRyRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFBdHRyRml4dXAsIGN0eHQpOwoKICAgIC8qCiAgICAgKiBUaGVuIGZpeHVwIGFsbCBhdHRyaWJ1dGVzIGdyb3VwIGRlY2xhcmF0aW9ucwogICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJncnBEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUF0dHJHcnBGaXh1cCwKICAgICAgICAgICAgICAgIGN0eHQpOwoKICAgIC8qCiAgICAgKiBUaGVuIGZpeHVwIGFsbCB0eXBlcyBwcm9wZXJ0aWVzCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hVHlwZUZpeHVwLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBidWlsZCB0aGUgY29udGVudCBtb2RlbCBmb3IgYWxsIGVsZW1lbnRzCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBjaGVjayB0aGUgZGVmYXVsdHMgcGFydCBvZiB0aGUgdHlwZSBsaWtlIGZhY2V0cyB2YWx1ZXMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT50eXBlRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFDaGVja0RlZmF1bHRzLAogICAgICAgICAgICAgICAgY3R4dCk7CgogICAgaWYgKGN0eHQtPm5iZXJyb3JzICE9IDApIHsKICAgICAgICB4bWxTY2hlbWFGcmVlKHJldCk7CiAgICAgICAgcmV0ID0gTlVMTDsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFBhcnNlckVycm9yczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycjogIHRoZSBlcnJvciBjYWxsYmFjawogKiBAd2FybjogIHRoZSB3YXJuaW5nIGNhbGxiYWNrCiAqIEBjdHg6ICBjb250ZXh0dWFsIGRhdGEgZm9yIHRoZSBjYWxsYmFja3MKICoKICogU2V0IHRoZSBjYWxsYmFjayBmdW5jdGlvbnMgdXNlZCB0byBoYW5kbGUgZXJyb3JzIGZvciBhIHZhbGlkYXRpb24gY29udGV4dAogKi8Kdm9pZAp4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyLAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuLCB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgY3R4dC0+ZXJyb3IgPSBlcnI7CiAgICBjdHh0LT53YXJuaW5nID0gd2FybjsKICAgIGN0eHQtPnVzZXJEYXRhID0gY3R4Owp9CgovKioKICogeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmc6CiAqIEB0eXBlOiAgdGhlIGZhY2V0IHR5cGUKICoKICogQ29udmVydCB0aGUgeG1sU2NoZW1hVHlwZVR5cGUgdG8gYSBjaGFyIHN0cmluZy4KICoKICogUmV0dXJucyB0aGUgY2hhciBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGZhY2V0IHR5cGUgaWYgdGhlCiAqICAgICB0eXBlIGlzIGEgZmFjZXQgYW5kIGFuICJJbnRlcm5hbCBFcnJvciIgc3RyaW5nIG90aGVyd2lzZS4KICovCnN0YXRpYyBjb25zdCBjaGFyICoKeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSkKewogICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CiAgICAgICAgICAgIHJldHVybiAoInBhdHRlcm4iKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKCJtYXhFeGNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKCJtYXhJbmNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKCJtaW5FeGNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKCJtaW5JbmNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKICAgICAgICAgICAgcmV0dXJuICgid2hpdGVTcGFjZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKICAgICAgICAgICAgcmV0dXJuICgiZW51bWVyYXRpb24iKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgogICAgICAgICAgICByZXR1cm4gKCJsZW5ndGgiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgogICAgICAgICAgICByZXR1cm4gKCJtYXhMZW5ndGgiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgogICAgICAgICAgICByZXR1cm4gKCJtaW5MZW5ndGgiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgICAgIHJldHVybiAoInRvdGFsRGlnaXRzIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgICAgICByZXR1cm4gKCJmcmFjdGlvbkRpZ2l0cyIpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuICgiSW50ZXJuYWwgRXJyb3IiKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWw6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBiYXNlOiAgdGhlIGJhc2UgdHlwZQogKiBAZmFjZXRzOiAgdGhlIGxpc3Qgb2YgZmFjZXRzIHRvIGNoZWNrCiAqIEB2YWx1ZTogIHRoZSBsZXhpY2FsIHJlcHIgb2YgdGhlIHZhbHVlIHRvIHZhbGlkYXRlCiAqIEB2YWw6ICB0aGUgcHJlY29tcHV0ZWQgdmFsdWUKICogQGZpcmVFcnJvcnM6ICBpZiAwLCBvbmx5IGludGVybmFsIGVycm9ycyB3aWxsIGJlIGZpcmVkOwogKgkJIG90aGVyd2lzZSBhbGwgZXJyb3JzIHdpbGwgYmUgZmlyZWQuCiAqCiAqIENoZWNrIGEgdmFsdWUgYWdhaW5zdCBhbGwgZmFjZXQgY29uZGl0aW9ucwogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldHMsCgkJCWNvbnN0IHhtbENoYXIgKiB2YWx1ZSwgaW50IGZpcmVFcnJvcnMpCnsKICAgIGludCByZXQgPSAwOwogICAgaW50IHRtcCA9IDA7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQgPSBmYWNldHM7CgogICAgd2hpbGUgKGZhY2V0ICE9IE5VTEwpIHsKICAgICAgICB0eXBlID0gZmFjZXQtPnR5cGU7CiAgICAgICAgaWYgKHR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikgewogICAgICAgICAgICB0bXAgPSAxOwoKICAgICAgICAgICAgd2hpbGUgKGZhY2V0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIHRtcCA9CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVGYWNldChiYXNlLCBmYWNldCwgdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICBpZiAodG1wID09IDApIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UKICAgICAgICAgICAgdG1wID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldChiYXNlLCBmYWNldCwgdmFsdWUsIGN0eHQtPnZhbHVlKTsKCiAgICAgICAgaWYgKHRtcCAhPSAwKSB7CiAgICAgICAgICAgIHJldCA9IHRtcDsKICAgICAgICAgICAgaWYgKGZpcmVFcnJvcnMpCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgWE1MX1NDSEVNQVNfRVJSX0ZBQ0VULAoJCQkgICAgICAiRmFpbGVkIHRvIHZhbGlkYXRlIHR5cGUgd2l0aCBmYWNldCAlc1xuIiwKCQkJICAgICAgKGNvbnN0IHhtbENoYXIgKikgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcodHlwZSksCgkJCSAgICAgIE5VTEwpOwogICAgICAgIH0KICAgICAgICBpZiAoZmFjZXQgIT0gTlVMTCkKICAgICAgICAgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAYmFzZTogIHRoZSBiYXNlIHR5cGUKICogQGZhY2V0czogIHRoZSBsaXN0IG9mIGZhY2V0cyB0byBjaGVjawogKiBAdmFsdWU6ICB0aGUgbGV4aWNhbCByZXByIG9mIHRoZSB2YWx1ZSB0byB2YWxpZGF0ZQogKiBAdmFsOiAgdGhlIHByZWNvbXB1dGVkIHZhbHVlCiAqCiAqIENoZWNrIGEgdmFsdWUgYWdhaW5zdCBhbGwgZmFjZXQgY29uZGl0aW9ucwogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVGYWNldHMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXRzLCBjb25zdCB4bWxDaGFyICogdmFsdWUpCnsKICAgIHJldHVybih4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIGJhc2UsIGZhY2V0cywgdmFsdWUsIDEpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVNpbXBsZSB0eXBlIHZhbGlkYXRpb24JCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZVVuaW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGRlY2xhcmF0aW9uCiAqIEB2YWx1ZTogIHRoZSB2YWx1ZSB0byB2YWxpZGF0ZQogKgogKiBWYWxpZGF0ZXMgYSB2YWx1ZSBhZ2FpbnN0IGEgdW5pb24uCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWVVbmlvbih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGNvbnN0IHhtbENoYXIgKiB2YWx1ZSkKewogICAgaW50IHJldCA9IDA7CiAgICBjb25zdCB4bWxDaGFyICpjdXIsICplbmQsICpwcmVmaXgsICpuY05hbWU7CiAgICB4bWxDaGFyICp0bXA7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHN1YnR5cGU7CiAgICB4bWxOc1B0ciBuczsKICAgIGludCBsZW47CiAgIAoKICAgIC8qIFByb2Nlc3MgcmVmZXJlbmNlZCBtZW1iZXJUeXBlcy4gKi8KICAgIGN1ciA9IHR5cGUtPnJlZjsKICAgIGRvIHsKICAgICAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgICAgIGN1cisrOwogICAgICAgIGVuZCA9IGN1cjsKICAgICAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKICAgICAgICAgICAgZW5kKys7CiAgICAgICAgaWYgKGVuZCA9PSBjdXIpCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIHRtcCA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOwogICAgICAgICBuY05hbWUgPSB4bWxTcGxpdFFOYW1lMyh0bXAsICZsZW4pOwogICAgICAgIGlmIChuY05hbWUgIT0gTlVMTCkgewogICAgICAgICAgICBwcmVmaXggPSB4bWxTdHJuZHVwKHRtcCwgbGVuKTsKICAgICAgICAgICAgLyogcHJlZml4ID0geG1sRGljdExvb2t1cChjdHh0LT5kb2MtPmRpY3QsIHRtcCwgbGVuKTsgKi8KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcmVmaXggPSBOVUxMOwogICAgICAgICAgICBuY05hbWUgPSB0bXA7CiAgICAgICAgfQogICAgICAgIC8qIFdlIHdvbid0IGRvIGFkZGl0aW9uYWwgY2hlY2tzIGhlcmUsCgkgKiBzaW5jZSB0aGV5IGhhdmUgYmVlbiBwZXJmb3JtZWQgZHVyaW5nIHBhcnNpbmcuICovCiAgICAgICAgbnMgPSB4bWxTZWFyY2hOcyh0eXBlLT5ub2RlLT5kb2MsIHR5cGUtPm5vZGUsIHByZWZpeCk7CiAgICAgICAgLyogbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kb2MtPmRpY3QsIG5zLT5ocmVmLCAtMSk7ICovCiAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCBuY05hbWUsIG5zLT5ocmVmKTsKCWlmICh0bXAgIT0gTlVMTCkKCSAgICB4bWxGcmVlKHRtcCk7CglpZiAocHJlZml4ICE9IE5VTEwpCgkgICAgeG1sRnJlZSgodm9pZCAqKXByZWZpeCk7CiAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZUludGVybmFsKGN0eHQsIHN1YnR5cGUsIHZhbHVlLCAwKTsKICAgICAgICBpZiAoKHJldCA9PSAwKSB8fCAocmV0ID09IC0xKSkgewogICAgICAgICAgICByZXR1cm4gKHJldCk7CiAgICAgICAgfQogICAgICAgIGN1ciA9IGVuZDsKICAgIH0gd2hpbGUgKCpjdXIgIT0gMCk7CgogICAgaWYgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICBzdWJ0eXBlID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgZG8gewogICAgICAgICAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlSW50ZXJuYWwoY3R4dCwgc3VidHlwZSwgdmFsdWUsIDApOwogICAgICAgICAgICBpZiAoKHJldCA9PSAwKSB8fCAocmV0ID09IC0xKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIChyZXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN1YnR5cGUgPSBzdWJ0eXBlLT5uZXh0OwogICAgICAgIH0gd2hpbGUgKHN1YnR5cGUgIT0gTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGRlY2xhcmF0aW9uCiAqIEB2YWx1ZTogIHRoZSB2YWx1ZSB0byB2YWxpZGF0ZQogKgogKiBWYWxpZGF0ZSBhIHZhbHVlIGFnYWluc3QgYSBzaW1wbGUgdHlwZQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgY29uc3QgeG1sQ2hhciAqIHZhbHVlKQp7CiAgcmV0dXJuICh4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlSW50ZXJuYWwoY3R4dCwgdHlwZSwgdmFsdWUsIDEpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHR5cGUgZGVjbGFyYXRpb24KICogQHZhbHVlOiAgdGhlIHZhbHVlIHRvIHZhbGlkYXRlCiAqIEBmaXJlRXJyb3JzOiAgaWYgMCwgb25seSBpbnRlcm5hbCBlcnJvcnMgd2lsbCBiZSBmaXJlZDsKICoJCSBvdGhlcndpc2UgYWxsIGVycm9ycyB3aWxsIGJlIGZpcmVkLgogKgogKiBWYWxpZGF0ZSBhIHZhbHVlIGFnYWluc3QgYSBzaW1wbGUgdHlwZQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlSW50ZXJuYWwoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICAgIGNvbnN0IHhtbENoYXIgKiB2YWx1ZSwKCQkJICAgICBpbnQgZmlyZUVycm9ycykKewogICAgaW50IHJldCA9IDA7CgogICAgLyoKICAgICAqIEZpcnN0IG5vcm1hbGl6ZSB0aGUgdmFsdWUgYWNjb3JkaW5nbHkgdG8gU2NoZW1hIERhdGF0eXBlCiAgICAgKiA0LjMuNiB3aGl0ZVNwYWNlIGRlZmluaXRpb24gb2YgdGhlIHdoaXRlU3BhY2UgZmFjZXQgb2YgdHlwZQogICAgICoKICAgICAqIFRoZW4gY2hlY2sgdGhlIG5vcm1hbGl6ZWQgdmFsdWUgYWdhaW5zdCB0aGUgbGV4aWNhbCBzcGFjZSBvZiB0aGUKICAgICAqIHR5cGUuCiAgICAgKi8KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewogICAgICAgIGlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShjdHh0LT52YWx1ZSk7CiAgICAgICAgICAgIGN0eHQtPnZhbHVlID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsUHJlZGVmVHlwZU5vZGUodHlwZSwgdmFsdWUsICYoY3R4dC0+dmFsdWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPmN1cik7CiAgICAgICAgaWYgKChmaXJlRXJyb3JzKSAmJiAocmV0ICE9IDApKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgY3R4dC0+Y3VyLCBYTUxfU0NIRU1BU19FUlJfVkFMVUUsCgkgICAgCQkgICJGYWlsZWQgdG8gdmFsaWRhdGUgYmFzaWMgdHlwZSAlc1xuIiwKCQkJICB0eXBlLT5uYW1lLCBOVUxMKTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OKSB7CiAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwogICAgICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoKICAgICAgICBiYXNlID0gdHlwZS0+YmFzZVR5cGU7CiAgICAgICAgaWYgKGJhc2UgIT0gTlVMTCkgewogICAgICAgICAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlSW50ZXJuYWwoY3R4dCwgYmFzZSwKCSAgICAJCQl2YWx1ZSwgZmlyZUVycm9ycyk7CiAgICAgICAgfSBlbHNlIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CgkgICAgVE9ETwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBEbyBub3QgdmFsaWRhdGUgZmFjZXRzIG9yIGF0dHJpYnV0ZXMgd2hlbiB3b3JraW5nIG9uCgkgKiBidWlsZGluZyB0aGUgU2NoZW1hcwogICAgICAgICAqLwogICAgICAgIGlmIChjdHh0LT5zY2hlbWEgIT0gTlVMTCkgewogICAgICAgICAgICBpZiAocmV0ID09IDApIHsKICAgICAgICAgICAgICAgIGZhY2V0ID0gdHlwZS0+ZmFjZXRzOwogICAgICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbChjdHh0LCBiYXNlLCBmYWNldCwKCQkJCXZhbHVlLCBmaXJlRXJyb3JzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB7CiAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwoKICAgICAgICBiYXNlID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgaWYgKGJhc2UgIT0gTlVMTCkgewogICAgICAgICAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlSW50ZXJuYWwoY3R4dCwgYmFzZSwKCSAgICAJCQl2YWx1ZSwgZmlyZUVycm9ycyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICBUT0RPfQogICAgfSBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9MSVNUKSB7CiAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwogICAgICAgIGNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKCXhtbENoYXIgKnRtcDsKICAgICAgICBpbnQgcmV0MjsKCiAgICAgICAgYmFzZSA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgIGlmIChiYXNlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkJIkludGVybmFsOiBMaXN0IHR5cGUgJXMgaGFzIG5vIGJhc2UgdHlwZVxuIiwKCQkJdHlwZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoLTEpOwogICAgICAgIH0KICAgICAgICBjdXIgPSB2YWx1ZTsKICAgICAgICBkbyB7CiAgICAgICAgICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKICAgICAgICAgICAgICAgIGN1cisrOwogICAgICAgICAgICBlbmQgPSBjdXI7CiAgICAgICAgICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQogICAgICAgICAgICAgICAgZW5kKys7CiAgICAgICAgICAgIGlmIChlbmQgPT0gY3VyKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIHRtcCA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOwogICAgICAgICAgICByZXQyID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZUludGVybmFsKGN0eHQsIGJhc2UsCgkgICAgCQkJdG1wLCBmaXJlRXJyb3JzKTsKCSAgICB4bWxGcmVlKHRtcCk7CiAgICAgICAgICAgIGlmIChyZXQyICE9IDApCiAgICAgICAgICAgICAgICByZXQgPSAxOwogICAgICAgICAgICBjdXIgPSBlbmQ7CiAgICAgICAgfSB3aGlsZSAoKmN1ciAhPSAwKTsKICAgIH0gIGVsc2UgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1VOSU9OKSB7CiAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZVVuaW9uKGN0eHQsIHR5cGUsIHZhbHVlKTsKICAgICAgICBpZiAoKGZpcmVFcnJvcnMpICYmIChyZXQgIT0gMCkpIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBjdHh0LT5jdXIsIFhNTF9TQ0hFTUFTX0VSUl9WQUxVRSwKCSAgICAJCSAgIkZhaWxlZCB0byB2YWxpZGF0ZSB0eXBlICVzXG4iLCB0eXBlLT5uYW1lLCBOVUxMKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIFRPRE8KICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCURPTSBWYWxpZGF0aW9uIGNvZGUJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgaW50IHhtbFNjaGVtYVZhbGlkYXRlQ29udGVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIGludCB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgZWxlbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKTsKc3RhdGljIGludCB4bWxTY2hlbWFWYWxpZGF0ZVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgZWxlbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKTsKCgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJTdGF0ZXM6CiAqIEBzdGF0ZTogIGEgbGlzdCBvZiBhdHRyaWJ1dGUgc3RhdGVzCiAqCiAqIEZyZWUgdGhlIGdpdmVuIGxpc3Qgb2YgYXR0cmlidXRlIHN0YXRlcwogKgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVN0YXRlcyh4bWxTY2hlbWFBdHRyU3RhdGVQdHIgc3RhdGUpCnsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CiAgICB3aGlsZSAoc3RhdGUgIT0gTlVMTCkgewoJdG1wID0gc3RhdGU7CglzdGF0ZSA9IHN0YXRlLT5uZXh0OwkKCXhtbEZyZWUodG1wKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYVJlZ2lzdGVyQXR0cmlidXRlczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGF0dHJzOiAgYSBsaXN0IG9mIGF0dHJpYnV0ZXMKICoKICogUmVnaXN0ZXIgdGhlIGxpc3Qgb2YgYXR0cmlidXRlcyBhcyB0aGUgc2V0IHRvIGJlIHZhbGlkYXRlZCBvbiB0aGF0IGVsZW1lbnQKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIG90aGVyd2lzZQogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFSZWdpc3RlckF0dHJpYnV0ZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbEF0dHJQdHIgYXR0cnMpCnsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CgogICAgY3R4dC0+YXR0ciA9IE5VTEw7CiAgICBjdHh0LT5hdHRyVG9wID0gTlVMTDsKICAgIHdoaWxlIChhdHRycyAhPSBOVUxMKSB7CiAgICAgICAgaWYgKChhdHRycy0+bnMgIT0gTlVMTCkgJiYKICAgICAgICAgICAgKHhtbFN0ckVxdWFsKGF0dHJzLT5ucy0+aHJlZiwgeG1sU2NoZW1hSW5zdGFuY2VOcykpKSB7CiAgICAgICAgICAgIGF0dHJzID0gYXR0cnMtPm5leHQ7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICAgICAgdG1wID0gKHhtbFNjaGVtYUF0dHJTdGF0ZVB0cikKCSAgICAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJTdGF0ZSkpOwogICAgICAgICAgICBpZiAodG1wID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoY3R4dCwgInJlZ2lzdGVyaW5nIGF0dHJpYnV0ZXMiLCBOVUxMKTsKICAgICAgICAgICAgICAgIHJldHVybiAoLTEpOwogICAgICAgICAgICB9Cgl0bXAtPmF0dHIgPSBhdHRyczsKCXRtcC0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV047Cgl0bXAtPm5leHQgPSBOVUxMOwoJaWYgKGN0eHQtPmF0dHIgPT0gTlVMTCkgCiAgICAgICAgICAgIGN0eHQtPmF0dHIgPSB0bXA7CgllbHNlCgkgICAgY3R4dC0+YXR0clRvcC0+bmV4dCA9IHRtcDsKCWN0eHQtPmF0dHJUb3AgPSB0bXA7CiAgICAgICAgYXR0cnMgPSBhdHRycy0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZXM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIG5vZGUgY2FycnlpbmcgaXQuCiAqCiAqIENoZWNrIHRoYXQgdGhlIHJlZ2lzdGVyZWQgc2V0IG9mIGF0dHJpYnV0ZXMgb24gdGhlIGN1cnJlbnQgbm9kZQogKiBoYXMgYmVlbiBwcm9wZXJseSB2YWxpZGF0ZWQuCiAqCiAqIFJldHVybnMgMCBpZiB2YWxpZGl0eSBjb25zdHJhaW50cyBhcmUgbWV0LCAxIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGludCByZXQgPSAwOwogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGN1cjsgICAgCgogICAgY3VyID0gY3R4dC0+YXR0cjsKICAgIHdoaWxlICgoY3VyICE9IE5VTEwpICYmIChjdXIgIT0gY3R4dC0+YXR0clRvcC0+bmV4dCkpIHsKCWlmIChjdXItPnN0YXRlICE9IFhNTF9TQ0hFTUFTX0FUVFJfQ0hFQ0tFRCkgewkgICAgCSAgICAKICAgICAgICAgICAgcmV0ID0gMTsKCSAgICBpZiAoY3VyLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV04pCiAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0FUVFJVTktOT1dOLAoJICAgIAkJICAiQXR0cmlidXRlICVzIG9uICVzIGlzIHVua25vd25cbiIsCgkJICAgIGN1ci0+YXR0ci0+bmFtZSwgbm9kZS0+bmFtZSk7CgkgICAgZWxzZSBpZiAoY3VyLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQpCgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfQVRUUlVOS05PV04sCgkJICAgICJBdHRyaWJ1dGUgJXMgb24gJXMgaXMgcHJvaGliaXRlZFxuIiwKCQkgICAgY3VyLT5hdHRyLT5uYW1lLCBub2RlLT5uYW1lKTsKCSAgICBlbHNlIGlmIChjdXItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9WQUxVRSkKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9BVFRSSU5WQUxJRCwKCQkgICAgIkF0dHJpYnV0ZSAlcyBvbiAlcyBkb2VzIG5vdCBtYXRjaCB0eXBlXG4iLAoJCSAgICBjdXItPmF0dHItPm5hbWUsIG5vZGUtPm5hbWUpOwoJICAgIGVsc2UgaWYgKGN1ci0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9NSVNTSU5HKSB7CgkJaWYgKGN1ci0+ZGVjbC0+cmVmICE9IE5VTEwpCgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX01JU1NJTkcsCgkJCSJBdHRyaWJ1dGUgJXMgb24gJXMgaXMgcmVxdWlyZWQgYnV0IG1pc3NpbmdcbiIsIAoJCQljdXItPmRlY2wtPnJlZiwgbm9kZS0+bmFtZSk7CgkJZWxzZQoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9NSVNTSU5HLAoJCQkiQXR0cmlidXRlICVzIG9uICVzIGlzIHJlcXVpcmVkIGJ1dCBtaXNzaW5nXG4iLCAKCQkJY3VyLT5kZWNsLT5uYW1lLCBub2RlLT5uYW1lKTsKICAgICAgICB9CiAgICB9CgljdXIgPSBjdXItPm5leHQ7CiAgICB9CgogICAgcmV0dXJuIChyZXQpOwp9CgojaWYgMAkJLyogTm90IGN1cnJlbnRseSB1c2VkIC0gcmVtb3ZlIGlmIGV2ZXIgbmVlZGVkICovCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZUNvbnRlbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAdHlwZTogIHRoZSB0eXBlIGRlY2xhcmF0aW9uCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgZXhwZWN0ZWQgdG8gYmUgYSBzaW1wbGUgdHlwZQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVDb250ZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIHhtbE5vZGVQdHIgY2hpbGQ7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGJhc2U7CiAgICB4bWxDaGFyICp2YWx1ZTsKICAgIGludCByZXQgPSAwOwoKICAgIGNoaWxkID0gY3R4dC0+bm9kZTsKICAgIHR5cGUgPSBjdHh0LT50eXBlOwoKICAgIC8qCiAgICAgKiBWYWxpZGF0aW9uIFJ1bGU6IEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoVHlwZSk6IDMuMS4zCiAgICAgKi8KICAgIHZhbHVlID0geG1sTm9kZUdldENvbnRlbnQoY2hpbGQpOwogICAgLyogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZShjdHh0LCB0eXBlLCB2YWx1ZSk7ICovCiAgICBzd2l0Y2ggKHR5cGUtPnR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTjp7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCiAgICAgICAgICAgICAgICBiYXNlID0gdHlwZS0+YmFzZVR5cGU7CiAgICAgICAgICAgICAgICBpZiAoYmFzZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZShjdHh0LCBiYXNlLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVE9ET30KICAgICAgICAgICAgICAgIGlmIChyZXQgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIGZhY2V0ID0gdHlwZS0+ZmFjZXRzOwogICAgICAgICAgICAgICAgICAgIHJldCA9CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzKGN0eHQsIGJhc2UsIGZhY2V0LCB2YWx1ZSk7CiAgICAgICAgICAgICAgICB9CgkJLyogCgkJICogVGhpcyBzaG91bGQgYXR0ZW1wdCB0byB2YWxpZGF0ZSB0aGUgYXR0cmlidXRlcyBldmVuCgkJICogd2hlbiB2YWxpZGF0aW9uIG9mIHRoZSB2YWx1ZSBmYWlsZWQuCgkJICovCgkJLyoKCQlpZiAodHlwZS0+YXR0cmlidXRlcyAhPSBOVUxMKSB7CgkJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBub2RlLAoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+YXR0cmlidXRlcyk7CgkJfQoJCSovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTjp7CgkgICAgICAgIFRPRE8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgZGVmYXVsdDoKCSAgICBUT0RPCiAgICB9CiAgICBpZiAodmFsdWUgIT0gTlVMTCkKICAgICAgICB4bWxGcmVlKHZhbHVlKTsKCiAgICByZXR1cm4gKHJldCk7Cn0KI2VuZGlmCgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVDaGVja05vZGVMaXN0CiAqIEBub2RlbGlzdDogdGhlIGxpc3Qgb2Ygbm9kZXMKICoKICogQ2hlY2sgdGhlIG5vZGUgbGlzdCBpcyBvbmx5IG1hZGUgb2YgdGV4dCBub2RlcyBhbmQgZW50aXRpZXMgcG9pbnRpbmcKICogdG8gdGV4dCBub2RlcwogKgogKiBSZXR1cm5zIDEgaWYgdHJ1ZSwgMCBpZiBmYWxzZSBhbmQgLTEgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUNoZWNrTm9kZUxpc3QoeG1sTm9kZVB0ciBub2RlbGlzdCkKewogICAgd2hpbGUgKG5vZGVsaXN0ICE9IE5VTEwpIHsKICAgICAgICBpZiAobm9kZWxpc3QtPnR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgewogICAgICAgICAgICBUT0RPICAgICAgICAgICAgICAgIC8qIGltcGxlbWVudCByZWN1cnNpb24gaW4gdGhlIGVudGl0eSBjb250ZW50ICovCiAgICAgICAgfQogICAgICAgIGlmICgobm9kZWxpc3QtPnR5cGUgIT0gWE1MX1RFWFRfTk9ERSkgJiYKICAgICAgICAgICAgKG5vZGVsaXN0LT50eXBlICE9IFhNTF9DT01NRU5UX05PREUpICYmCiAgICAgICAgICAgIChub2RlbGlzdC0+dHlwZSAhPSBYTUxfUElfTk9ERSkgJiYKICAgICAgICAgICAgKG5vZGVsaXN0LT50eXBlICE9IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSB7CiAgICAgICAgICAgIHJldHVybiAoMCk7CiAgICAgICAgfQogICAgICAgIG5vZGVsaXN0ID0gbm9kZWxpc3QtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDEpOwp9CgovKioKICogeG1sU2NoZW1hU2tpcElnbm9yZWQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGN1cnJlbnQgdHlwZSBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBTa2lwIGlnbm9yYWJsZSBub2RlcyBpbiB0aGF0IGNvbnRleHQKICoKICogUmV0dXJucyB0aGUgbmV3IHNpYmxpbmcKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIHhtbE5vZGVQdHIKeG1sU2NoZW1hU2tpcElnbm9yZWQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQgQVRUUklCVVRFX1VOVVNFRCwKICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGludCBtaXhlZCA9IDA7CgogICAgLyoKICAgICAqIFRPRE8gY29tcGxldGUgYW5kIGhhbmRsZSBlbnRpdGllcwogICAgICovCiAgICBtaXhlZCA9ICgodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSB8fAogICAgICAgICAgICAgKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRF9PUl9FTEVNRU5UUykpOwogICAgd2hpbGUgKChub2RlICE9IE5VTEwpICYmCiAgICAgICAgICAgKChub2RlLT50eXBlID09IFhNTF9DT01NRU5UX05PREUpIHx8CiAgICAgICAgICAgICgobWl4ZWQgPT0gMSkgJiYgKG5vZGUtPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkpIHx8CiAgICAgICAgICAgICgoKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykgJiYKICAgICAgICAgICAgICAobm9kZS0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSAmJiAoSVNfQkxBTktfTk9ERShub2RlKSkpKSkpIHsKICAgICAgICBub2RlID0gbm9kZS0+bmV4dDsKICAgIH0KICAgIHJldHVybiAobm9kZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IGRldGVjdGVkIChtaWdodCBiZSBOVUxMKQogKiBAdHlwZTogIHRoZSB0eXBlCiAqCiAqIEEgdHJhbnNpdGlvbiBoYXMgYmVlbiBtYWRlIGluIHRoZSBhdXRvbWF0YSBhc3NvY2lhdGVkIHRvIGFuIGVsZW1lbnQKICogY29udGVudCBtb2RlbAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjayh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VELAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG9sZHR5cGUgPSBjdHh0LT50eXBlOwogICAgeG1sTm9kZVB0ciBvbGRub2RlID0gY3R4dC0+bm9kZTsKCiNpZmRlZiBERUJVR19DT05URU5UCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjazogJXMsICVzLCAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBuYW1lLCB0eXBlLT5uYW1lLCBub2RlLT5uYW1lKTsKI2VuZGlmCiAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgIGN0eHQtPm5vZGUgPSBub2RlOwogICAgeG1sU2NoZW1hVmFsaWRhdGVDb250ZW50KGN0eHQsIG5vZGUpOwogICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CiAgICBjdHh0LT5ub2RlID0gb2xkbm9kZTsKfQoKCiNpZiAwCgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVSZXN0cmljdGlvblR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhIHJlc3RyaWN0aW9uIHR5cGUuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVJlc3RyaWN0aW9uVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgaW50IHJldDsKCiAgICBjaGlsZCA9IGN0eHQtPm5vZGU7CiAgICB0eXBlID0gY3R4dC0+dHlwZTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlUmVzdHJpY3Rpb25UeXBlICVzXG4iLAoJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgLyoKICAgICAqIE9ubHkgdGV4dCBhbmQgdGV4dCBiYXNlZCBlbnRpdGllcyByZWZlcmVuY2VzIHNoYWxsIGJlIGZvdW5kIHRoZXJlCiAgICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlQ2hlY2tOb2RlTGlzdChjaGlsZCk7CiAgICBpZiAocmV0IDwgMCkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlICVzIGNvbnRlbnRcbiIsCgkJICAgICAgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9IGVsc2UgaWYgKHJldCA9PSAwKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfTk9UU0lNUExFLAoJCSAgICAgICJFbGVtZW50ICVzIGNvbnRlbnQgaXMgbm90IGEgc2ltcGxlIHR5cGVcbiIsCgkJICAgICAgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICBjdHh0LT50eXBlID0gdHlwZS0+c3VidHlwZXM7CiAgICB4bWxTY2hlbWFWYWxpZGF0ZUNvbnRlbnQoY3R4dCwgbm9kZSk7CiAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgIHJldHVybiAocmV0KTsKfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBzaW1wbGUgdHlwZS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBiYXNlLCB2YXJpZXR5OwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgaW50IHJldDsKICAgIHhtbENoYXIgKnZhbHVlOwogICAgCgogICAgY2hpbGQgPSBjdHh0LT5ub2RlOwogICAgdHlwZSA9IGN0eHQtPnR5cGU7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJICAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGUgJXNcbiIsCgkJICAgICAgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKgogICAgICogT25seSB0ZXh0IGFuZCB0ZXh0IGJhc2VkIGVudGl0aWVzIHJlZmVyZW5jZXMgc2hhbGwgYmUgZm91bmQgdGhlcmUKICAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVDaGVja05vZGVMaXN0KGNoaWxkKTsKICAgIGlmIChyZXQgPCAwKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJICAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGUgJXMgY29udGVudFxuIiwKCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0gZWxzZSBpZiAocmV0ID09IDApIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9OT1RTSU1QTEUsCgkJICAgICAgIkVsZW1lbnQgJXMgY29udGVudCBpcyBub3QgYSBzaW1wbGUgdHlwZVxuIiwKCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qCiAgICAgKiBWYWxpZGF0aW9uIFJ1bGU6IEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoVHlwZSk6IDMuMS4xCiAgICAgKi8gICAgCiAgICAKICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewogICAgICAgIGlmICgoYXR0ci0+bnMgPT0gTlVMTCkgfHwKICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHx8CiAgICAgICAgICAgICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJ0eXBlIikpICYmCiAgICAgICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuaWwiKSkgJiYKICAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNjaGVtYXNMb2NhdGlvbiIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbAogICAgICAgICAgICAgIChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiIpKSkpIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5WQUxJREFUVFIsCgkgICAgCQkgICJFbGVtZW50ICVzOiBhdHRyaWJ1dGUgJXMgc2hvdWxkIG5vdCBiZSBwcmVzZW50XG4iLAoJCQkgIG5vZGUtPm5hbWUsIGF0dHItPm5hbWUpOwogICAgICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICAgICAgfQogICAgfQogICAgLyogVE9ETzoKICAgICAqIElmIHt2YXJpZXR5fSBpcyC3YXRvbWljtyB0aGVuIHRoZSB7dmFyaWV0eX0gb2Yge2Jhc2UgdHlwZSBkZWZpbml0aW9ufQogICAgICogbXVzdCBiZSC3YXRvbWljty4gCiAgICAgKiBJZiB7dmFyaWV0eX0gaXMgt2xpc3S3IHRoZW4gdGhlIHt2YXJpZXR5fSBvZiB7aXRlbSB0eXBlIGRlZmluaXRpb259CiAgICAgKiBtdXN0IGJlIGVpdGhlciC3YXRvbWljtyBvciC3dW5pb263LiAKICAgICAqIElmIHt2YXJpZXR5fSBpcyC3dW5pb263IHRoZW4ge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBtdXN0IGJlIGEgbGlzdAogICAgICogb2YgZGF0YXR5cGUgZGVmaW5pdGlvbnMuIAogICAgICovCiAgICBpZiAodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJICAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGU7ICIKCQkgICAgICAic2ltcGxlIHR5cGUgJXMgZG9lcyBub3QgZGVmaW5lIGEgdmFyaWV0eVxuIiwKCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKCXJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KICAgIC8qIFZhcmlldGllczogUmVzdHJpY3Rpb24gb3IgTGlzdCBvciBVbmlvbi4gKi8KICAgIHZhcmlldHkgPSB0eXBlLT5zdWJ0eXBlczsKICAgIGN0eHQtPnR5cGUgPSB2YXJpZXR5OyAgICAgICAgCiAgICB2YWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KGNoaWxkKTsKICAgIHN3aXRjaCAodmFyaWV0eS0+dHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOnsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoKICAgICAgICAgICAgICAgIGJhc2UgPSB2YXJpZXR5LT5iYXNlVHlwZTsKICAgICAgICAgICAgICAgIGlmIChiYXNlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlKGN0eHQsIGJhc2UsIHZhbHVlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBUT0RPfQogICAgICAgICAgICAgICAgaWYgKHJldCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQgPSB2YXJpZXR5LT5mYWNldHM7CiAgICAgICAgICAgICAgICAgICAgcmV0ID0KICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVGYWNldHMoY3R4dCwgYmFzZSwgZmFjZXQsIHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KCQkvKiBSZW1vdmVkIGR1ZSB0byBjaGFuZ2VzIG9mIGF0dHJpYnV0ZSB2YWxpZGF0aW9uOgoJCWlmICgocmV0ID09IDApICYmICh2YXJpZXR5LT5hdHRyaWJ1dGVzICE9IE5VTEwpKSB7CgkJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBub2RlLAoJCSAgICAJCXZhcmlldHktPmF0dHJpYnV0ZXMpOwoJCX0KCQkqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9MSVNUOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfVU5JT046IHsKCSAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZShjdHh0LCB2YXJpZXR5LCB2YWx1ZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6ewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZTsgIgoJCQkgICAgICAic2ltcGxlIHR5cGUgJXMgZGVmaW5lcyB1bmtub3duIGNvbnRlbnQ6ICVzXG4iLAoJCQkgICAgICB2YXJpZXR5LT5uYW1lLCBOVUxMKTsKCQlyZXQgPSBjdHh0LT5lcnI7CgkgICAgfQogICAgfQogICAgaWYgKHZhbHVlICE9IE5VTEwpCiAgICAgICAgeG1sRnJlZSh2YWx1ZSk7CgogICAgLyogVGhpcyB3YXMgcmVtb3ZlZCwgc2luY2UgYSBzaW1wbGUgY29udGVudCBpcyBub3QgYSBjb250ZW50IG9mIGEKICAgICAqIHNpbXBsZSB0eXBlLCBidXQgb2YgYSBjb21wbGV4IHR5cGUuCiAgICAgKiByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZUNvbnRlbnQoY3R4dCwgbm9kZSk7CiAgICAgKi8KICAgIGN0eHQtPnR5cGUgPSB0eXBlOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50VHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgdHlwZS4KICogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKENvbXBsZXggVHlwZSkKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudFR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbFJlZ0V4ZWNDdHh0UHRyIG9sZHJlZ2V4cDsgICAgICAgIC8qIGNvbnQgbW9kZWwgb2YgdGhlIHBhcmVudCAqLwogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsOwogICAgaW50IHJldDsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBhdHRycyA9IE5VTEwsIGF0dHJUb3AgPSBOVUxMOwoKICAgIC8qIAogICAgICogVE9ETzogTG9vayBpbnRvICJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQiIGZvciBtaXNzaW5nIHBhcnRzLCB3aGljaCBzaG91bGQKICAgICAqIGdvIGluIGhlcmUgYXMgd2VsbC4KICAgICAqLwoKICAgIC8qIFRPRE86IElzIHRoaXMgb25lIGNhbGxlZCBhbHdheXMgd2l0aCBhbiBlbGVtZW50IGRlY2xhcmF0aW9uIGFzIHRoZSAKICAgICAqIGNvbnRleHQncyB0eXBlPwogICAgICovCgogICAgb2xkcmVnZXhwID0gY3R4dC0+cmVnZXhwOwoKICAgIGNoaWxkID0gY3R4dC0+bm9kZTsKICAgIHR5cGUgPSBjdHh0LT50eXBlOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50VHlwZVxuIiwKCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGlmIChjaGlsZCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKHR5cGUtPm1pbk9jY3VycyA+IDApIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfTUlTU0lORywKCSAgICAJCSAgIkVsZW1lbnQgJXM6IG1pc3NpbmcgY2hpbGQgJXNcbiIsCgkJCSAgbm9kZS0+bmFtZSwgdHlwZS0+bmFtZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KCiAgICAvKgogICAgICogVmVyaWZ5IHRoZSBlbGVtZW50IG1hdGNoZXMKICAgICAqLwogICAgaWYgKCF4bWxTdHJFcXVhbChjaGlsZC0+bmFtZSwgdHlwZS0+bmFtZSkpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyMyhjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfV1JPTkdFTEVNLAoJCSAgICAgICAiRWxlbWVudCAlczogbWlzc2luZyBjaGlsZCAlcyBmb3VuZCAlc1xuIiwKCQkgICAgICAgbm9kZS0+bmFtZSwgdHlwZS0+bmFtZSwgY2hpbGQtPm5hbWUpOwogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KICAgIC8qCiAgICAgKiBWZXJpZnkgdGhlIGF0dHJpYnV0ZXMKICAgICAqLwogICAgCiAgICBhdHRycyA9IGN0eHQtPmF0dHI7ICAgIAogICAgYXR0clRvcCA9IGN0eHQtPmF0dHJUb3A7CiAgICAKICAgIHhtbFNjaGVtYVJlZ2lzdGVyQXR0cmlidXRlcyhjdHh0LCBjaGlsZC0+cHJvcGVydGllcyk7CiAgICAgICAgCiAgICAvKiAKICAgICAqIEFuIGVsZW1lbnQgZGVjbGFyYXRpb24gZG9lcyBub3QgaG9sZCBhbnkgaW5mb3JtYXRpb24gYWJvdXQKICAgICAqIGF0dHJpYnV0ZXM7IHRodXMsIHRoZSBmb2xsb3dpbmcgd2FzIHJlbW92ZWQuCiAgICAgKi8KICAgIC8qIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBjaGlsZCwgdHlwZS0+YXR0cmlidXRlcyk7ICovCgogICAgLyoKICAgICAqIFZlcmlmeSB0aGUgZWxlbWVudCBjb250ZW50IHJlY3Vyc2l2ZWx5CiAgICAgKi8KICAgIGRlY2wgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgdHlwZTsKICAgIG9sZHJlZ2V4cCA9IGN0eHQtPnJlZ2V4cDsKICAgIGlmIChkZWNsLT5jb250TW9kZWwgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPnJlZ2V4cCA9IHhtbFJlZ05ld0V4ZWNDdHh0KGRlY2wtPmNvbnRNb2RlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoeG1sUmVnRXhlY0NhbGxiYWNrcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrLCBjdHh0KTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICI9PT09PiAlc1xuIiwgbm9kZS0+bmFtZSk7CiNlbmRpZgogICAgfQogICAgeG1sU2NoZW1hVmFsaWRhdGVUeXBlKGN0eHQsIGNoaWxkLCAoeG1sU2NoZW1hRWxlbWVudFB0cikgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyk7CgogICAgaWYgKGRlY2wtPmNvbnRNb2RlbCAhPSBOVUxMKSB7CiAgICAgICAgcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcoY3R4dC0+cmVnZXhwLCBOVUxMLCBOVUxMKTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICI9PT09PiAlcyA6ICVkXG4iLCBub2RlLT5uYW1lLCByZXQpOwojZW5kaWYKICAgICAgICBpZiAocmV0ID09IDApIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfRUxFTUNPTlQsCgkgICAgCQkgICJFbGVtZW50ICVzIGNvbnRlbnQgY2hlY2sgZmFpbGVkXG4iLAoJCQkgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIH0gZWxzZSBpZiAocmV0IDwgMCkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9FTEVNQ09OVCwKCSAgICAJCSAgIkVsZW1lbnQgJXMgY29udGVudCBjaGVjayBmYWlsdXJlXG4iLAoJCQkgIG5vZGUtPm5hbWUsIE5VTEwpOwojaWZkZWYgREVCVUdfQ09OVEVOVAogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVsZW1lbnQgJXMgY29udGVudCBjaGVjayBzdWNjZWVkZWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLT5uYW1lKTsKCiNlbmRpZgogICAgICAgIH0KICAgICAgICB4bWxSZWdGcmVlRXhlY0N0eHQoY3R4dC0+cmVnZXhwKTsKICAgIH0KICAgIC8qCiAgICAgKiBWZXJpZnkgdGhhdCBhbGwgYXR0cmlidXRlcyB3ZXJlIFNjaGVtYXMtdmFsaWRhdGVkCiAgICAgKi8KICAgIHhtbFNjaGVtYUNoZWNrQXR0cmlidXRlcyhjdHh0LCBub2RlKTsKICAgIGlmIChjdHh0LT5hdHRyICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlQXR0cmlidXRlU3RhdGVzKGN0eHQtPmF0dHIpOwogICAgY3R4dC0+YXR0ciA9IGF0dHJzOyAgICAKICAgIGN0eHQtPmF0dHJUb3AgPSBhdHRyVG9wOwogICAgY3R4dC0+cmVnZXhwID0gb2xkcmVnZXhwOwogICAgY3R4dC0+bm9kZSA9IGNoaWxkOwogICAgY3R4dC0+dHlwZSA9IHR5cGU7CiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUJhc2ljVHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgZXhwZWN0ZWQgdG8gYmUgYSBiYXNpYyB0eXBlIHR5cGUKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlQmFzaWNUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGludCByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkLCBjdXI7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxDaGFyICp2YWx1ZTsgICAgICAgICAgICAgLyogbGV4aWNhbCByZXByZXNlbnRhdGlvbiAqLwoKICAgIGNoaWxkID0gY3R4dC0+bm9kZTsKICAgIHR5cGUgPSBjdHh0LT50eXBlOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVCYXNpY1R5cGVcbiIsCgkJICAgICAgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKgogICAgICogRmlyc3QgY2hlY2sgdGhlIGNvbnRlbnQgbW9kZWwgb2YgdGhlIG5vZGUuCiAgICAgKi8KICAgIGN1ciA9IGNoaWxkOwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CiAgICAgICAgc3dpdGNoIChjdXItPnR5cGUpIHsKICAgICAgICAgICAgY2FzZSBYTUxfVEVYVF9OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9DREFUQV9TRUNUSU9OX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX1BJX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX0NPTU1FTlRfTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfWElOQ0xVREVfU1RBUlQ6CiAgICAgICAgICAgIGNhc2UgWE1MX1hJTkNMVURFX0VORDoKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFhNTF9FTlRJVFlfUkVGX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX0VOVElUWV9OT0RFOgogICAgICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICAgICAgY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgogICAgICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5WQUxJREVMRU0sCgkJCSAgICAgICJFbGVtZW50ICVzOiBjaGlsZCAlcyBzaG91bGQgbm90IGJlIHByZXNlbnRcbiIsCgkJCSAgICAgIG5vZGUtPm5hbWUsIGN1ci0+bmFtZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICAgICAgICAgIGNhc2UgWE1MX0FUVFJJQlVURV9OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9ET0NVTUVOVF9OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9ET0NVTUVOVF9UWVBFX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX0RPQ1VNRU5UX0ZSQUdfTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfTk9UQVRJT05fTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfSFRNTF9ET0NVTUVOVF9OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9EVERfTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfRUxFTUVOVF9ERUNMOgogICAgICAgICAgICBjYXNlIFhNTF9BVFRSSUJVVEVfREVDTDoKICAgICAgICAgICAgY2FzZSBYTUxfRU5USVRZX0RFQ0w6CiAgICAgICAgICAgIGNhc2UgWE1MX05BTUVTUEFDRV9ERUNMOgojaWZkZWYgTElCWE1MX0RPQ0JfRU5BQkxFRAogICAgICAgICAgICBjYXNlIFhNTF9ET0NCX0RPQ1VNRU5UX05PREU6CiNlbmRpZgogICAgICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5WQUxJREVMRU0sCgkJCSAgICAgICJFbGVtZW50ICVzOiBub2RlIHR5cGUgb2Ygbm9kZSB1bmV4cGVjdGVkIGhlcmVcbiIsCgkJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgICAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgICAgIH0KICAgICAgICBjdXIgPSBjdXItPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgPT0gTlVMTCkKICAgICAgICB2YWx1ZSA9IE5VTEw7CiAgICBlbHNlCiAgICAgICAgdmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudChjaGlsZC0+cGFyZW50KTsKCiAgICBpZiAoY3R4dC0+dmFsdWUgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShjdHh0LT52YWx1ZSk7CiAgICAgICAgY3R4dC0+dmFsdWUgPSBOVUxMOwogICAgfQogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVQcmVkZWZpbmVkVHlwZSh0eXBlLCB2YWx1ZSwgJihjdHh0LT52YWx1ZSkpOwogICAgaWYgKHZhbHVlICE9IE5VTEwpCiAgICAgICAgeG1sRnJlZSh2YWx1ZSk7CiAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9WQUxVRSwKCQkgICAgICAiRWxlbWVudCAlczogZmFpbGVkIHRvIHZhbGlkYXRlIGJhc2ljIHR5cGUgJXNcbiIsCgkJICAgICAgbm9kZS0+bmFtZSwgdHlwZS0+bmFtZSk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUNvbXBsZXhUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSB0b3Agbm9kZS4KICoKICogVmFsaWRhdGUgdGhlIGNvbnRlbnQgb2YgYW4gZWxlbWVudCBleHBlY3RlZCB0byBiZSBhIGNvbXBsZXggdHlwZSB0eXBlCiAqIHhtbHNjaGVtYS0xLmh0bWwjY3ZjLWNvbXBsZXgtdHlwZQogKiBWYWxpZGF0aW9uIFJ1bGU6IEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoQ29tcGxleCBUeXBlKQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOwogICAgaW50IHJldDsKCiAgICAvKiBUT0RPOiBIYW5kbGUgeHNkOnJlc3RyaWN0aW9uICYgeHNkOmV4dGVuc2lvbiAqLwoKICAgIGNoaWxkID0gY3R4dC0+bm9kZTsKICAgIHR5cGUgPSBjdHh0LT50eXBlOwogICAgY3R4dC0+Y3VyID0gbm9kZTsKCiAgICBzd2l0Y2ggKHR5cGUtPmNvbnRlbnRUeXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk6CgkgICAgaWYgKHR5cGUtPmJhc2VUeXBlICE9IE5VTEwpIHsKCSAgICB9IGVsc2UgaWYgKGNoaWxkICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9OT1RFTVBUWSwKCQkJICAgICAgIkVsZW1lbnQgJXMgaXMgc3VwcG9zZWQgdG8gYmUgZW1wdHlcbiIsCgkJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgICAgICB9CgkgICAgLyogUmVtb3ZlZCBkdWUgdG8gY2hhbmdlcyBvZiBhdHRyaWJ1dGUgdmFsaWRhdGlvbjoKICAgICAgICAgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKGN0eHQsIG5vZGUsIHR5cGUtPmF0dHJpYnV0ZXMpOwogICAgICAgICAgICB9CgkgICAgKi8KICAgICAgICAgICAgc3VidHlwZSA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICB3aGlsZSAoc3VidHlwZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBjdHh0LT50eXBlID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUoY3R4dCwgbm9kZSk7CiAgICAgICAgICAgICAgICBzdWJ0eXBlID0gc3VidHlwZS0+bmV4dDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRF9PUl9FTEVNRU5UUzoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogU2tpcCBpZ25vcmFibGUgbm9kZXMgaW4gdGhhdCBjb250ZXh0CiAgICAgICAgICAgICAqLwoJICAgIC8qIENvbXBsZXhUeXBlLCBDb21wbGV4Q29udGVudCAqLwoJICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgICAgIGNoaWxkID0geG1sU2NoZW1hU2tpcElnbm9yZWQoY3R4dCwgdHlwZSwgY2hpbGQpOwogICAgICAgICAgICB3aGlsZSAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgaWYgKGNoaWxkLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKICAgICAgICAgICAgICAgICAgICByZXQgPSB4bWxSZWdFeGVjUHVzaFN0cmluZyhjdHh0LT5yZWdleHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQtPm5hbWUsIGNoaWxkKTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCiAgICAgICAgICAgICAgICAgICAgaWYgKHJldCA8IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgLS0+ICVzIEVycm9yXG4iLCBjaGlsZC0+bmFtZSk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIC0tPiAlc1xuIiwgY2hpbGQtPm5hbWUpOwojZW5kaWYKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogU2tpcCBpZ25vcmFibGUgbm9kZXMgaW4gdGhhdCBjb250ZXh0CiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGNoaWxkID0geG1sU2NoZW1hU2tpcElnbm9yZWQoY3R4dCwgdHlwZSwgY2hpbGQpOwogICAgICAgICAgICB9CgkgICAgfQoJICAgIAoJICAgIGlmICgoKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgfHwKCQkodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEX09SX0VMRU1FTlRTKSkgJiYKCQkodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkpIHsKCQlUT0RPCgkgICAgfQoKCSAgICAvKiBSZW1vdmVkIGR1ZSB0byBjaGFuZ2VzIG9mIGF0dHJpYnV0ZSB2YWxpZGF0aW9uOgogICAgICAgICAgICBpZiAodHlwZS0+YXR0cmlidXRlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoY3R4dCwgbm9kZSwgdHlwZS0+YXR0cmlidXRlcyk7CiAgICAgICAgICAgIH0KCSAgICAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQzp7CiAgICAgICAgICAgICAgICBpZiAodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGN0eHQtPnR5cGUgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZUNvbXBsZXhUeXBlKGN0eHQsIG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHR5cGUtPmJhc2VUeXBlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBjdHh0LT50eXBlID0gdHlwZS0+YmFzZVR5cGU7CgkJICAgIGlmICh0eXBlLT5iYXNlVHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpCgkJCXhtbFNjaGVtYVZhbGlkYXRlQmFzaWNUeXBlKGN0eHQsIG5vZGUpOwoJCSAgICBlbHNlIGlmICh0eXBlLT5iYXNlVHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkKCQkJeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZShjdHh0LCBub2RlKTsKCQkgICAgLyogVE9ETzogVGhpcyBtaWdodCBiZSBpbmNvcnJlY3QuICovCgkJICAgIGVsc2UgaWYgKHR5cGUtPmJhc2VUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIAoJCQl4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGUoY3R4dCwgbm9kZSk7CgkJICAgIGVsc2UKCQkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmV4cGVjdGVkIGNvbnRlbnQgdHlwZSBvZiBiYXNlOiAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+Y29udGVudFR5cGUpOwogICAgICAgICAgICAgICAgfQoJCS8qIFJlbW92ZWQgZHVlIHRvIGNoYW5nZXMgb2YgYXR0cmlidXRlIHZhbGlkYXRpb246CiAgICAgICAgICAgICAgICBpZiAodHlwZS0+YXR0cmlidXRlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKGN0eHQsIG5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmF0dHJpYnV0ZXMpOwogICAgICAgICAgICAgICAgfQoJCSovCiAgICAgICAgICAgICAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOnsKICAgICAgICAgICAgICAgIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgY3R4dC0+dHlwZSA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUoY3R4dCwgbm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodHlwZS0+YmFzZVR5cGUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGN0eHQtPnR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZUNvbXBsZXhUeXBlKGN0eHQsIG5vZGUpOwogICAgICAgICAgICAgICAgfQoJCS8qIFJlbW92ZWQgZHVlIHRvIGNoYW5nZXMgb2YgYXR0cmlidXRlIHZhbGlkYXRpb246CiAgICAgICAgICAgICAgICBpZiAodHlwZS0+YXR0cmlidXRlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKGN0eHQsIG5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmF0dHJpYnV0ZXMpOwogICAgICAgICAgICAgICAgfQoJCSovCiAgICAgICAgICAgICAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgICAgICAgICAgICAgIGJyZWFrOwoJfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFRPRE8geG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmltcGxlbWVudGVkIGNvbnRlbnQgdHlwZSAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+Y29udGVudFR5cGUpOwogICAgfQogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpCgl4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoY3R4dCwgbm9kZSwgdHlwZSk7CiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUNvbnRlbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAdHlwZTogIHRoZSB0eXBlIGRlY2xhcmF0aW9uCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgYWdhaW5zdCB0aGUgdHlwZS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlQ29udGVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKICAgIGNoaWxkID0gY3R4dC0+bm9kZTsKICAgIHR5cGUgPSBjdHh0LT50eXBlOwogICAgY3R4dC0+Y3VyID0gbm9kZTsKCiAgICAvKiAKICAgICAqIFJlbW92ZWQsIHNpbmNlIHJlZHVuZGFudC4gCiAgICAgKi8KICAgIC8qIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBub2RlLCB0eXBlLT5hdHRyaWJ1dGVzKTsgKi8KICAgIGN0eHQtPmN1ciA9IG5vZGU7CgogICAgc3dpdGNoICh0eXBlLT50eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgogICAgICAgICAgICAvKiBBbnkgdHlwZSB3aWxsIGRvIGl0LCBmaW5lICovCiAgICAgICAgICAgIFRPRE8gICAgICAgICAgICAgICAgLyogaGFuZGxlIHJlY3Vyc2l2aXR5ICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgogICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZUNvbXBsZXhUeXBlKGN0eHQsIG5vZGUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOnsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZGVjbCA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSB0eXBlOwoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBIYW5kbGUgZWxlbWVudCByZWZlcmVuY2UgaGVyZQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoZGVjbC0+cmVmICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZGVjbC0+cmVmRGVjbCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkJICAgICAgIkludGVybmFsIGVycm9yOiBlbGVtZW50IHJlZmVyZW5jZSAlcyAiCgkJCQkgICAgICAibm90IHJlc29sdmVkXG4iLCBkZWNsLT5yZWYsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC0xKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY3R4dC0+dHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKSBkZWNsLT5yZWZEZWNsOwogICAgICAgICAgICAgICAgICAgIGRlY2wgPSBkZWNsLT5yZWZEZWNsOwogICAgICAgICAgICAgICAgfQoJCS8qIFRPRE86IFNob3VsZCAieG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50IiBiZSBjYWxsZWQgaW5zdGVhZD8gKi8KICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudFR5cGUoY3R4dCwgbm9kZSk7CiAgICAgICAgICAgICAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQkFTSUM6CiAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlQmFzaWNUeXBlKGN0eHQsIG5vZGUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9GQUNFVDoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CiAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZShjdHh0LCBub2RlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVDoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQ6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVVI6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046CiAgICAgICAgICAgIC8qeG1sU2NoZW1hVmFsaWRhdGVSZXN0cmljdGlvblR5cGUoY3R4dCwgbm9kZSk7ICovCiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9OT1RBVElPTjoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9MSVNUOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1VOSU9OOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURToKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgIH0KICAgIC8qIAogICAgICogUmVtb3ZlZCwgc2luY2UgcmVkdW5kYW50LiAKICAgICAqLwogICAgLyogeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKGN0eHQsIG5vZGUsIHR5cGUtPmF0dHJpYnV0ZXMpOyAqLwoKICAgIGlmIChjdHh0LT5ub2RlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgY3R4dC0+bm9kZSA9IGN0eHQtPm5vZGUtPm5leHQ7CiAgICBjdHh0LT50eXBlID0gdHlwZS0+bmV4dDsKICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlVHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW06ICBhbiBlbGVtZW50CiAqIEB0eXBlOiAgdGhlIGxpc3Qgb2YgdHlwZSBkZWNsYXJhdGlvbnMKICoKICogVmFsaWRhdGUgdGhlIGNvbnRlbnQgb2YgYW4gZWxlbWVudCBhZ2FpbnN0IHRoZSB0eXBlcy4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBlbGVtLAogICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxDaGFyICpuaWw7CgogICAgaWYgKChlbGVtID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpIHx8IChlbGVtRGVjbCA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKDApOwoKICAgIC8qIFRoaXMgb25lIGlzIGNhbGxlZCBieSAieG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50VHlwZSIgYW5kCiAgICAgKiAieG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50Ii4KICAgICAqLwoKICAgIC8qCiAgICAgKiAzLjMuNCA6IDIKICAgICAqLwogICAgaWYgKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1QpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9JU0FCU1RSQUNULAoJCSAgICAgICJFbGVtZW50IGRlY2xhcmF0aW9uICVzIGlzIGFic3RyYWN0XG4iLAoJCSAgICAgIGVsZW1EZWNsLT5uYW1lLCBOVUxMKTsKCS8qIENoYW5nZWQsIHNpbmNlIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIGlzIGFic3RyYWN0IGFuZCBub3QKCSAqIHRoZSBlbGVtZW50IGl0c2VsZi4gKi8KCS8qIHhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgWE1MX1NDSEVNQVNfRVJSX0lTQUJTVFJBQ1QsCgkJCSAiRWxlbWVudCAlcyBpcyBhYnN0cmFjdFxuIiwgZWxlbS0+bmFtZSwgTlVMTCk7ICovCiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfQogICAgLyoKICAgICAqIDMuMy40OiAzCiAgICAgKi8KICAgIG5pbCA9IHhtbEdldE5zUHJvcChlbGVtLCBCQURfQ0FTVCAibmlsIiwgeG1sU2NoZW1hSW5zdGFuY2VOcyk7CiAgICBpZiAoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRSkgewogICAgICAgIC8qIDMuMy40OiAzLjIgKi8KICAgICAgICBpZiAoeG1sU3RyRXF1YWwobmlsLCBCQURfQ0FTVCAidHJ1ZSIpKSB7CiAgICAgICAgICAgIGlmIChlbGVtLT5jaGlsZHJlbiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9OT1RFTVBUWSwKCQkJICAgICAgIkVsZW1lbnQgJXMgaXMgbm90IGVtcHR5XG4iLCBlbGVtLT5uYW1lLCBOVUxMKTsKICAgICAgICAgICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpICYmCiAgICAgICAgICAgICAgICAoZWxlbURlY2wtPnZhbHVlICE9IE5VTEwpKSB7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9IQVZFREVGQVVMVCwKCQkJICAgICAgIkVtcHR5IGVsZW1lbnQgJXMgY2Fubm90IGdldCBhIGZpeGVkIHZhbHVlXG4iLAoJCQkgICAgICBlbGVtLT5uYW1lLCBOVUxMKTsKICAgICAgICAgICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgLyogMy4zLjQ6IDMuMSAqLwogICAgICAgIGlmIChuaWwgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9OT1ROSUxMQUJMRSwKCSAgICAJCSAgIkVsZW1lbnQgJXMgd2l0aCB4czpuaWwgYnV0IG5vdCBuaWxsYWJsZVxuIiwKCQkJICBlbGVtLT5uYW1lLCBOVUxMKTsKICAgICAgICAgICAgeG1sRnJlZShuaWwpOwogICAgICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFRPRE8gMy4zLjQ6IDQgaWYgdGhlIGVsZW1lbnQgY2FycmllcyB4czp0eXBlICovCgogICAgY3R4dC0+dHlwZSA9IGVsZW1EZWNsLT5zdWJ0eXBlczsKICAgIGN0eHQtPm5vZGUgPSBlbGVtLT5jaGlsZHJlbjsKICAgIHhtbFNjaGVtYVZhbGlkYXRlQ29udGVudChjdHh0LCBlbGVtKTsKICAgIC8qIFJlbW92ZWQsIHNpbmNlIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24gZG9lcyBub3QgaG9sZCBhbnkgYXR0cmlidXRlCiAgICAgKiBkZWNsYXJhdGlvbnMgKi8KICAgIC8qIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBlbGVtLCBlbGVtRGVjbC0+YXR0cmlidXRlcyk7ICovCgogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW06ICBhbiBlbGVtZW50CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXhUeXBlIGhvbGRpbmcgdGhlIGF0dHJpYnV0ZSB1c2VzCiAqCiAqIFZhbGlkYXRlIHRoZSBhdHRyaWJ1dGVzIG9mIGFuIGVsZW1lbnQuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgZWxlbSwgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICBpbnQgcmV0OwogICAgeG1sQXR0clB0ciBhdHRyOyAvKiBBbiBhdHRyaWJ1dGUgb24gdGhlIGVsZW1lbnQuICovCiAgICB4bWxDaGFyICp2YWx1ZTsKICAgIGNvbnN0IHhtbENoYXIgKm5zVVJJOwogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBhdHRyVXNlOwogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHJEZWNsOwogICAgaW50IGZvdW5kOwogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGN1clN0YXRlLCByZXFBdHRyU3RhdGVzID0gTlVMTCwgcmVxQXR0clN0YXRlc1RvcCA9IE5VTEw7CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KICAgIGludCByZWR1bmRhbnQgPSAwOwojZW5kaWYKICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB7Cgl4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkJICAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXM6ICIKCQkJICAgICAgImdpdmVuIHR5cGUgXCIlc1wiaXMgbm90IGEgY29tcGxleFR5cGVcbiIsCgkJCSAgICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJcmV0dXJuKC0xKTsKICAgIH0gICAgCgogICAgaWYgKCh0eXBlLT5hdHRyaWJ1dGVVc2VzID09IE5VTEwpICYmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKDApOwoKICAgIGF0dHJVc2UgPSB0eXBlLT5hdHRyaWJ1dGVVc2VzOwoKICAgIHdoaWxlIChhdHRyVXNlICE9IE5VTEwpIHsKICAgICAgICBmb3VuZCA9IDA7ICAgIAoJYXR0ckRlY2wgPSBhdHRyVXNlLT5hdHRyOwojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCglwcmludGYoImF0dHIgdXNlIC0gbmFtZTogJXNcbiIsIHhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShhdHRyRGVjbCkpOwoJcHJpbnRmKCJhdHRyIHVzZSAtIHVzZTogJWRcbiIsIGF0dHJEZWNsLT5vY2N1cnMpOwojZW5kaWYKICAgICAgICBmb3IgKGN1clN0YXRlID0gY3R4dC0+YXR0cjsgY3VyU3RhdGUgIT0gTlVMTDsgY3VyU3RhdGUgPSBjdXJTdGF0ZS0+bmV4dCkgewkJICAgIAoKCSAgICBpZiAoY3VyU3RhdGUtPmRlY2wgPT0gYXR0clVzZS0+YXR0cikgewojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgkJcmVkdW5kYW50ID0gMTsKI2VuZGlmCiAgICAgICAgfQoJICAgIGF0dHIgPSBjdXJTdGF0ZS0+YXR0cjsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJICAgIHByaW50ZigiYXR0ciAtIG5hbWU6ICVzXG4iLCBhdHRyLT5uYW1lKTsKCSAgICBpZiAoYXR0ci0+bnMgIT0gTlVMTCkKCQlwcmludGYoImF0dHIgLSBuczogJXNcbiIsIGF0dHItPm5zLT5ocmVmKTsKCSAgICBlbHNlCgkJcHJpbnRmKCJhdHRyIC0gbnM6IG5vbmVcbiIpOwojZW5kaWYKCSAgICAvKiBUT0RPOiBDYW4gdGhpcyBldmVyIGhhcHBlbj8gKi8KICAgICAgICAgICAgaWYgKGF0dHIgPT0gTlVMTCkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAoYXR0ckRlY2wtPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIGF0dHJEZWNsLT5yZWYpKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaWYgKGF0dHItPm5zICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKGF0dHJEZWNsLT5yZWZOcyA9PSBOVUxMKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCBhdHRyRGVjbC0+cmVmTnMpKSkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGF0dHJEZWNsLT5yZWZOcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIGF0dHJEZWNsLT5uYW1lKSkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBoYW5kbGUgdGhlIG5hbWVzcGFjZXMgY2hlY2tzIGhlcmUKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgICogYWNjZXB0IGFuIHVucXVhbGlmaWVkIGF0dHJpYnV0ZSBvbmx5IGlmIHRoZSB0YXJnZXQKCQkgICAgICogbmFtZXNwYWNlIG9mIHRoZSBkZWNsYXJhdGlvbiBpcyBhYnNlbnQuCgkJICAgICAqLwoJCSAgICBpZiAoYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKQoJCQkvKiAKCQkJICogVGhpcyBjaGVjayB3YXMgcmVtb3ZlZCwgc2luY2UgdGhlIHRhcmdldCBuYW1lc3BhY2UKCQkJICogd2FzIGV2YWx1YXRlZCBkdXJpbmcgcGFyc2luZyBhbmQgYWxyZWFkeSB0b29rCgkJCSAqICJhdHRyaWJ1dGVGb3JtRGVmYXVsdCIgaW50byBhY2NvdW50LgoJCQkgKi8KCQkgICAgICAgIC8qICgoYXR0cmlidXRlcy0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX05TREVGQVVMVCkgPT0gMCkpICovCgkJICAgICAgICBjb250aW51ZTsKCQl9IGVsc2UgewoJCSAgICBpZiAoYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZSA9PSBOVUxMKQoJCSAgICAgICAgY29udGludWU7CgkJICAgIGlmICgheG1sU3RyRXF1YWwoYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkgICAgICAgICAgICAgICAgICAgICBhdHRyLT5ucy0+aHJlZikpCgkJCWNvbnRpbnVlOwoJCX0KICAgICAgICAgICAgfQojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgkgICAgcHJpbnRmKCJmb3VuZFxuIik7CiNlbmRpZgogICAgICAgICAgICBmb3VuZCA9IDE7CiAgICAgICAgICAgIGN0eHQtPmN1ciA9ICh4bWxOb2RlUHRyKSBhdHRyOwoKICAgICAgICAgICAgaWYgKGF0dHJEZWNsLT5zdWJ0eXBlcyA9PSBOVUxMKSB7CgkJY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9UWVBFX05PVF9SRVNPTFZFRDsKCQljdXJTdGF0ZS0+ZGVjbCA9IGF0dHJEZWNsOwoJCS8qIAoJCSAqIFRoaXMgY291bGQgYmUgcHV0IGludG8gInhtbFNjaGVtYUNoZWNrQXR0cmlidXRlcyIgYXMgd2VsbCwgYnV0CgkJICogc2luY2UgaXQgcmVwb3J0cyBhbiBpbnRlcm5hbCBlcnJvciwgaXQgYmV0dGVyIHN0YXlzIGhlcmUgdG8gZWFzZQoJCSAqIGRlYnVnZ2luZy4KCQkgKi8KICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkJICAgICAgIkludGVybmFsIGVycm9yOiBhdHRyaWJ1dGUgJXMgdHlwZSBub3QgcmVzb2x2ZWRcbiIsCgkJCSAgICAgIGF0dHItPm5hbWUsIE5VTEwpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFsdWUgPSB4bWxOb2RlTGlzdEdldFN0cmluZyhlbGVtLT5kb2MsIGF0dHItPmNoaWxkcmVuLCAxKTsKICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZShjdHh0LCBhdHRyRGVjbC0+c3VidHlwZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUpOwogICAgICAgICAgICBpZiAocmV0ICE9IDApIAoJCWN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9WQUxVRTsgICAJCQkJCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfQ0hFQ0tFRDsKCSAgICBjdXJTdGF0ZS0+ZGVjbCA9IGF0dHJEZWNsOwogICAgICAgICAgICBpZiAodmFsdWUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgeG1sRnJlZSh2YWx1ZSk7CiAgICAgICAgICAgIH0JICAgIAogICAgICAgIH0KICAgICAgICBpZiAoKCFmb3VuZCkgJiYgKGF0dHJEZWNsLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQpKSB7CgkgICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIHRtcDsKCiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCSAgICBwcmludGYoInJlcXVpcmVkIGF0dHIgbm90IGZvdW5kXG4iKTsKI2VuZGlmCgkgICAgLyoKCSAgICAgKiBBZGQgYSBuZXcgZHVtbXkgYXR0cmlidXRlIHN0YXRlLgoJICAgICAqLwkKCSAgICB0bXAgPSAoeG1sU2NoZW1hQXR0clN0YXRlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJTdGF0ZSkpOwoJICAgIGlmICh0bXAgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVZFcnJNZW1vcnkoY3R4dCwgInJlZ2lzdGVyaW5nIHJlcXVpcmVkIGF0dHJpYnV0ZXMiLCBOVUxMKTsKCQlyZXR1cm4gKC0xKTsKICAgICAgICAgICAgfSAgICAgICAgICAgIAoJICAgIHRtcC0+YXR0ciA9IE5VTEw7CgkgICAgdG1wLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfTUlTU0lORzsKCSAgICB0bXAtPmRlY2wgPSBhdHRyRGVjbDsKCSAgICB0bXAtPm5leHQgPSBOVUxMOwogICAgICAgICAKCSAgICBpZiAocmVxQXR0clN0YXRlcyA9PSBOVUxMKSB7CgkJcmVxQXR0clN0YXRlcyA9IHRtcDsKCQlyZXFBdHRyU3RhdGVzVG9wID0gdG1wOwogICAgICAgICAgICB9IGVsc2UgewoJCXJlcUF0dHJTdGF0ZXNUb3AtPm5leHQgPSB0bXA7CgkJcmVxQXR0clN0YXRlc1RvcCA9IHRtcDsKICAgICAgICAgICAgfQoJCgl9CiAgICAgICAgYXR0clVzZSA9IGF0dHJVc2UtPm5leHQ7CiAgICB9CiAgICAvKgogICAgICogQWRkIHJlcXVpcmVkIGF0dHJpYnV0ZXMgdG8gdGhlIGF0dHJpYnV0ZSBzdGF0ZXMgb2YgdGhlIGNvbnRleHQuCiAgICAgKi8KICAgIGlmIChyZXFBdHRyU3RhdGVzICE9IE5VTEwpIHsKCWlmIChjdHh0LT5hdHRyID09IE5VTEwpIHsKCSAgICBjdHh0LT5hdHRyID0gcmVxQXR0clN0YXRlczsKCX0gZWxzZSB7CQkKCSAgICBjdHh0LT5hdHRyVG9wLT5uZXh0ID0gcmVxQXR0clN0YXRlczsKCX0KCWN0eHQtPmF0dHJUb3AgPSByZXFBdHRyU3RhdGVzVG9wOwogICAgICAgICAgICB9CiAgICAvKgogICAgKiBQcm9jZXNzIHdpbGRjYXJkcy4KICAgICovCiAgICBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewkKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBuczsJCglwcmludGYoIm1hdGNoaW5nIHdpbGRjYXJkOiBbJWRdIG9mIGNvbXBsZXhUeXBlOiAlc1xuIiwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIHR5cGUtPm5hbWUpOwoJaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkgICAgWE1MX1NDSEVNQVNfQU5ZX0xBWCkKCSAgICBwcmludGYoInByb2Nlc3NDb250ZW50czogbGF4XG4iKTsKCWVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkgICAgWE1MX1NDSEVNQVNfQU5ZX1NUUklDVCkKCSAgICBwcmludGYoInByb2Nlc3NDb250ZW50czogc3RyaWN0XG4iKTsKCWVsc2UKCSAgICBwcmludGYoInByb2Nlc3NDb250ZW50czogc2tpcFxuIik7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPmFueSkKCSAgICBwcmludGYoInR5cGU6IGFueVxuIik7CgllbHNlIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJICAgIHByaW50ZigidHlwZTogbmVnYXRlZFxuIik7CgkgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkKCQlwcmludGYoIm5zOiAoYWJzZW50KVxuIik7CgkgICAgZWxzZQoJCXByaW50ZigibnM6ICVzXG4iLCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bmVnTnNTZXQtPnZhbHVlKTsKCX0gZWxzZSBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBwcmludGYoInR5cGU6IHNldFxuIik7CgkgICAgbnMgPSB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bnNTZXQ7CgkgICAgd2hpbGUgKG5zICE9IE5VTEwpIHsKCQlpZiAobnMtPnZhbHVlID09IE5VTEwpCgkJICAgIHByaW50ZigibnM6IChhYnNlbnQpXG4iKTsKCQllbHNlCgkJICAgIHByaW50ZigibnM6ICVzXG4iLCBucy0+dmFsdWUpOwoJCW5zID0gbnMtPm5leHQ7CgkgICAgfQkgICAgCgl9IGVsc2UKCSAgICBwcmludGYoImVtcHR5XG4iKTsKCgojZW5kaWYJCgljdXJTdGF0ZSA9IGN0eHQtPmF0dHI7Cgl3aGlsZSAoY3VyU3RhdGUgIT0gTlVMTCkgewoJICAgIGlmIChjdXJTdGF0ZS0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOKSB7CQkKCQlpZiAoY3VyU3RhdGUtPmF0dHItPm5zICE9IE5VTEwpIAoJCSAgICBuc1VSSSA9IGN1clN0YXRlLT5hdHRyLT5ucy0+aHJlZjsKCQllbHNlCgkJICAgIG5zVVJJID0gTlVMTDsJCQoJCWlmICh4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgCgkJICAgIG5zVVJJKSkgewoJCSAgICAvKgoJCSAgICAqIEhhbmRsZSBwcm9jZXNzQ29udGVudHMuCgkJICAgICovCgkJICAgIGlmICgodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCQkJWE1MX1NDSEVNQVNfQU5ZX0xBWCkgfHwKCQkJKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkJCVhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1QpKSB7CgkJCQoJCQlhdHRyID0gY3VyU3RhdGUtPmF0dHI7CQkJCQkJCgkJCWF0dHJEZWNsID0geG1sU2NoZW1hR2V0QXR0cmlidXRlKGN0eHQtPnNjaGVtYSwgCgkJCSAgICBhdHRyLT5uYW1lLCBuc1VSSSk7CQkKCQkJaWYgKGF0dHJEZWNsICE9IE5VTEwpIHsKCQkJICAgIHZhbHVlID0geG1sTm9kZUxpc3RHZXRTdHJpbmcoZWxlbS0+ZG9jLCBhdHRyLT5jaGlsZHJlbiwgMSk7CgkJCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlKGN0eHQsIGF0dHJEZWNsLT5zdWJ0eXBlcywgCgkJCQl2YWx1ZSk7CgkJCSAgICBpZiAocmV0ICE9IDApIAoJCQkJY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX1ZBTFVFOyAgIAkJCQkKCQkJICAgIGVsc2UKCQkJCWN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfQ0hFQ0tFRDsKCQkJICAgIGN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CgkJCSAgICBpZiAodmFsdWUgIT0gTlVMTCkgewoJCQkJeG1sRnJlZSh2YWx1ZSk7CgkJCSAgICB9CSAgICAKCQkJICAgIAoJCQl9IGVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkJCSAgICBYTUxfU0NIRU1BU19BTllfTEFYKSB7CgkJCSAgICBjdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQ7CgkJCX0JCQkJCQkJCQkJCQoJCSAgICB9IGVsc2UKCQkJY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEOwoJCX0JCQoJICAgIH0KCSAgICBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0OwogICAgICAgIH0KICAgIH0KI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgogICAgaWYgKHJlZHVuZGFudCkKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXM6IHJlZHVuZGFudCBjYWxsIGJ5IHR5cGU6ICVzXG4iLAoJICAgICAgICAgICAgICAgIHR5cGUtPm5hbWUpOwojZW5kaWYKICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW06ICBhbiBlbGVtZW50CiAqCiAqIFZhbGlkYXRlIGFuIGVsZW1lbnQgaW4gYSB0cmVlCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgZWxlbSkKewogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbDsKICAgIGludCByZXQ7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgYXR0cnMsIGF0dHJUb3A7CgogICAgaWYgKGVsZW0tPm5zICE9IE5VTEwpIHsKICAgICAgICBlbGVtRGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5uYW1lLCBlbGVtLT5ucy0+aHJlZiwgTlVMTCk7CiAgICB9IGVsc2UgewogICAgICAgIGVsZW1EZWNsID0geG1sSGFzaExvb2t1cDMoY3R4dC0+c2NoZW1hLT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPm5hbWUsIE5VTEwsIE5VTEwpOwogICAgfQogICAgLyoKICAgICAqIHNwZWNpYWwgY2FzZSB3aGUgZWxlbWVudEZvcm1EZWZhdWx0IGlzIHVucXVhbGlmaWVkIGZvciB0b3AtbGV2ZWwgZWxlbS4KICAgICAqLwogICAgLyoKICAgICAqIFRoaXMgd2FzIHJlbW92ZWQsIHNpbmNlIGVsZW1lbnRGb3JtRGVmYXVsdCBkb2VzIG5vdCBhcHBseSB0byB0b3AtbGV2ZWwKICAgICAqIGVsZW1lbnQgZGVjbGFyYXRpb25zLgogICAgICovCiAgICAvKgogICAgaWYgKChlbGVtRGVjbCA9PSBOVUxMKSAmJiAoZWxlbS0+bnMgIT0gTlVMTCkgJiYKICAgICAgICAoZWxlbS0+cGFyZW50ICE9IE5VTEwpICYmIChlbGVtLT5wYXJlbnQtPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYKICAgICAgICAoeG1sU3RyRXF1YWwoY3R4dC0+c2NoZW1hLT50YXJnZXROYW1lc3BhY2UsIGVsZW0tPm5zLT5ocmVmKSkgJiYKCSgoY3R4dC0+c2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNKSA9PSAwKSkgewogICAgICAgIGVsZW1EZWNsID0geG1sSGFzaExvb2t1cDMoY3R4dC0+c2NoZW1hLT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPm5hbWUsIE5VTEwsIE5VTEwpOwogICAgfQogICAgKi8KCiAgICAvKgogICAgICogMy4zLjQgOiAxCiAgICAgKi8KICAgIGlmIChlbGVtRGVjbCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBlbGVtLCBYTUxfU0NIRU1BU19FUlJfVU5ERUNMQVJFREVMRU0sCgkJICAgICAgIkVsZW1lbnQgJXMgbm90IGRlY2xhcmVkXG4iLCBlbGVtLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICBpZiAoZWxlbURlY2wtPnN1YnR5cGVzID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9OT1RZUEUsCgkJICAgICAgIkVsZW1lbnQgJXMgaGFzIG5vIHR5cGVcbiIsIGVsZW0tPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KICAgIC8qCiAgICAgKiBWZXJpZnkgdGhlIGF0dHJpYnV0ZXMKICAgICAqLwogICAgYXR0cnMgPSBjdHh0LT5hdHRyOwogICAgYXR0clRvcCA9IGN0eHQtPmF0dHJUb3A7CiAgICB4bWxTY2hlbWFSZWdpc3RlckF0dHJpYnV0ZXMoY3R4dCwgZWxlbS0+cHJvcGVydGllcyk7CiAgICAvKgogICAgICogVmVyaWZ5IHRoZSBlbGVtZW50IGNvbnRlbnQgcmVjdXJzaXZlbHkKICAgICAqLwogICAgaWYgKGVsZW1EZWNsLT5jb250TW9kZWwgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPnJlZ2V4cCA9IHhtbFJlZ05ld0V4ZWNDdHh0KGVsZW1EZWNsLT5jb250TW9kZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHhtbFJlZ0V4ZWNDYWxsYmFja3MpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjaywgY3R4dCk7CiNpZmRlZiBERUJVR19BVVRPTUFUQQogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiPT09PT4gJXNcbiIsIGVsZW0tPm5hbWUpOwojZW5kaWYKICAgIH0KICAgIHhtbFNjaGVtYVZhbGlkYXRlVHlwZShjdHh0LCBlbGVtLCBlbGVtRGVjbCwgZWxlbURlY2wtPnN1YnR5cGVzKTsKICAgIGlmIChlbGVtRGVjbC0+Y29udE1vZGVsICE9IE5VTEwpIHsKICAgICAgICByZXQgPSB4bWxSZWdFeGVjUHVzaFN0cmluZyhjdHh0LT5yZWdleHAsIE5VTEwsIE5VTEwpOwojaWZkZWYgREVCVUdfQVVUT01BVEEKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIj09PT0+ICVzIDogJWRcbiIsIGVsZW0tPm5hbWUsIHJldCk7CiNlbmRpZgogICAgICAgIGlmIChyZXQgPT0gMCkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9FTEVNQ09OVCwKCSAgICAJCSAgIkVsZW1lbnQgJXMgY29udGVudCBjaGVjayBmYWlsZWRcbiIsCgkJCSAgZWxlbS0+bmFtZSwgTlVMTCk7CiAgICAgICAgfSBlbHNlIGlmIChyZXQgPCAwKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgWE1MX1NDSEVNQVNfRVJSX0VMRU1DT05ULAoJICAgIAkJICAiRWxlbWVudCAlcyBjb250ZW50IGNoZWNrIGZhaWxlZFxuIiwKCQkJICBlbGVtLT5uYW1lLCBOVUxMKTsKI2lmZGVmIERFQlVHX0NPTlRFTlQKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbGVtZW50ICVzIGNvbnRlbnQgY2hlY2sgc3VjY2VlZGVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bmFtZSk7CgojZW5kaWYKICAgICAgICB9CiAgICAgICAgeG1sUmVnRnJlZUV4ZWNDdHh0KGN0eHQtPnJlZ2V4cCk7CiAgICB9CiAgICAvKgogICAgICogVmVyaWZ5IHRoYXQgYWxsIGF0dHJpYnV0ZXMgd2VyZSBTY2hlbWFzLXZhbGlkYXRlZAogICAgICovCiAgICB4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZXMoY3R4dCwgZWxlbSk7CiAgICBpZiAoY3R4dC0+YXR0ciAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVN0YXRlcyhjdHh0LT5hdHRyKTsKICAgIGN0eHQtPmF0dHIgPSBhdHRyczsKICAgIGN0eHQtPmF0dHJUb3AgPSBhdHRyVG9wOwoKICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRG9jdW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBkb2M6ICBhIHBhcnNlZCBkb2N1bWVudCB0cmVlCiAqCiAqIFZhbGlkYXRlIGEgZG9jdW1lbnQgdHJlZSBpbiBtZW1vcnkuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZG9jdW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVEb2N1bWVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sRG9jUHRyIGRvYykKewogICAgeG1sTm9kZVB0ciByb290OwogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbDsKCiAgICByb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKICAgIGlmIChyb290ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsIFhNTF9TQ0hFTUFTX0VSUl9OT1JPT1QsCgkJICAgICAgImRvY3VtZW50IGhhcyBubyByb290XG4iLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAKICAgIGlmIChyb290LT5ucyAhPSBOVUxMKQogICAgICAgIGVsZW1EZWNsID0geG1sSGFzaExvb2t1cDMoY3R4dC0+c2NoZW1hLT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvb3QtPm5hbWUsIHJvb3QtPm5zLT5ocmVmLCBOVUxMKTsKICAgIGVsc2UKICAgICAgICBlbGVtRGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290LT5uYW1lLCBOVUxMLCBOVUxMKTsKCiAgICAvKgogICAgICogc3BlY2lhbCBjYXNlIHdoZSBlbGVtZW50Rm9ybURlZmF1bHQgaXMgdW5xdWFsaWZpZWQgZm9yIHRvcC1sZXZlbCBlbGVtLgogICAgICovCiAgICAvKiBSZW1vdmVkLCBzaW5jZSBlbGVtZW50Rm9ybURlZmF1bHQgZG9lcyBub3QgYXBwbHkgdG8gdG9wIGxldmVsIAogICAgKiBlbGVtZW50cyAqLwogICAgLyoKICAgIGlmICgoZWxlbURlY2wgPT0gTlVMTCkgJiYgKHJvb3QtPm5zICE9IE5VTEwpICYmCiAgICAgICAgKHhtbFN0ckVxdWFsKGN0eHQtPnNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCByb290LT5ucy0+aHJlZikpICYmCgkoKGN0eHQtPnNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkgPT0gMCkpIHsKICAgICAgICBlbGVtRGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290LT5uYW1lLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgICovCgogICAgaWYgKGVsZW1EZWNsID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIHJvb3QsIFhNTF9TQ0hFTUFTX0VSUl9VTkRFQ0xBUkVERUxFTSwKCQkgICAgICAiRWxlbWVudCAlcyBub3QgZGVjbGFyZWRcbiIsIHJvb3QtPm5hbWUsIE5VTEwpOwogICAgfSBlbHNlIGlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpID09IDApIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIHJvb3QsIFhNTF9TQ0hFTUFTX0VSUl9OT1RUT1BMRVZFTCwKCQkgICAgICAiUm9vdCBlbGVtZW50ICVzIG5vdCBnbG9iYWxcbiIsIHJvb3QtPm5hbWUsIE5VTEwpOwogICAgfQogICAgLyoKICAgICAqIE9rYXksIHN0YXJ0IHRoZSByZWN1cnNpdmUgdmFsaWRhdGlvbgogICAgICovCiAgICB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQoY3R4dCwgcm9vdCk7CgogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU0FYIFZhbGlkYXRpb24gY29kZQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW9uIGludGVyZmFjZXMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3VmFsaWRDdHh0OgogKiBAc2NoZW1hOiAgYSBwcmVjb21waWxlZCBYTUwgU2NoZW1hcwogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgdmFsaWRhdGlvbiBjb250ZXh0IGJhc2VkIG9uIHRoZSBnaXZlbiBzY2hlbWEKICoKICogUmV0dXJucyB0aGUgdmFsaWRhdGlvbiBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hVmFsaWRDdHh0UHRyCnhtbFNjaGVtYU5ld1ZhbGlkQ3R4dCh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHZhbGlkYXRpb24gY29udGV4dCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICByZXQtPnNjaGVtYSA9IHNjaGVtYTsKICAgIC8qIAogICAgICogUmVtb3ZlZCBkdWUgdG8gY2hhbmdlcyBvZiB0aGUgYXR0cmlidXRlIHN0YXRlIGxpc3QuCiAgICAqLwogICAgLyogcmV0LT5hdHRyTnIgPSAwOyAqLwogICAgLyogcmV0LT5hdHRyTWF4ID0gMTA7ICovCiAgICAvKiByZXQtPmF0dHJCYXNlID0gTlVMTDsgKi8KICAgIHJldC0+YXR0clRvcCA9IE5VTEw7CiAgICByZXQtPmF0dHIgPSBOVUxMOwogICAgLyogCiAgICAgKiBSZW1vdmVkIGR1ZSB0byBjaGFuZ2VzIG9mIHRoZSBhdHRyaWJ1dGUgc3RhdGUgbGlzdC4KICAgICAqCiAgICByZXQtPmF0dHIgPSAoeG1sU2NoZW1hQXR0clN0YXRlUHRyKSB4bWxNYWxsb2MocmV0LT5hdHRyTWF4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoeG1sU2NoZW1hQXR0clN0YXRlKSk7CiAgICBpZiAocmV0LT5hdHRyID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHZhbGlkYXRpb24gY29udGV4dCIsIE5VTEwpOwogICAgICAgIGZyZWUocmV0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldC0+YXR0ciwgMCwgcmV0LT5hdHRyTWF4ICogc2l6ZW9mKHhtbFNjaGVtYUF0dHJTdGF0ZSkpOwogICAgKi8KCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlVmFsaWRDdHh0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIEZyZWUgdGhlIHJlc291cmNlcyBhc3NvY2lhdGVkIHRvIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVWYWxpZEN0eHQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGN0eHQtPmF0dHIgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQXR0cmlidXRlU3RhdGVzKGN0eHQtPmF0dHIpOwogICAgaWYgKGN0eHQtPnZhbHVlICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGN0eHQtPnZhbHVlKTsKICAgIHhtbEZyZWUoY3R4dCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTZXRWYWxpZEVycm9yczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycjogIHRoZSBlcnJvciBmdW5jdGlvbgogKiBAd2FybjogdGhlIHdhcm5pbmcgZnVuY3Rpb24KICogQGN0eDogdGhlIGZ1bmN0aW9ucyBjb250ZXh0CiAqCiAqIFNldCB0aGUgZXJyb3IgYW5kIHdhcm5pbmcgY2FsbGJhY2sgaW5mb3JtYXRpb25zCiAqLwp2b2lkCnhtbFNjaGVtYVNldFZhbGlkRXJyb3JzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2Fybiwgdm9pZCAqY3R4KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGN0eHQtPmVycm9yID0gZXJyOwogICAgY3R4dC0+d2FybmluZyA9IHdhcm47CiAgICBjdHh0LT51c2VyRGF0YSA9IGN0eDsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRG9jOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZG9jOiAgYSBwYXJzZWQgZG9jdW1lbnQgdHJlZQogKgogKiBWYWxpZGF0ZSBhIGRvY3VtZW50IHRyZWUgaW4gbWVtb3J5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRhdGVEb2MoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbERvY1B0ciBkb2MpCnsKICAgIGludCByZXQ7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChkb2MgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CgogICAgY3R4dC0+ZG9jID0gZG9jOwogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVEb2N1bWVudChjdHh0LCBkb2MpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTdHJlYW06CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBpbnB1dDogIHRoZSBpbnB1dCB0byB1c2UgZm9yIHJlYWRpbmcgdGhlIGRhdGEKICogQGVuYzogIGFuIG9wdGlvbmFsIGVuY29kaW5nIGluZm9ybWF0aW9uCiAqIEBzYXg6ICBhIFNBWCBoYW5kbGVyIGZvciB0aGUgcmVzdWx0aW5nIGV2ZW50cwogKiBAdXNlcl9kYXRhOiAgdGhlIGNvbnRleHQgdG8gcHJvdmlkZSB0byB0aGUgU0FYIGhhbmRsZXIuCiAqCiAqIFZhbGlkYXRlIGEgZG9jdW1lbnQgdHJlZSBpbiBtZW1vcnkuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZG9jdW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFWYWxpZGF0ZVN0cmVhbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sUGFyc2VySW5wdXRCdWZmZXJQdHIgaW5wdXQsIHhtbENoYXJFbmNvZGluZyBlbmMsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNBWEhhbmRsZXJQdHIgc2F4LCB2b2lkICp1c2VyX2RhdGEpCnsKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoaW5wdXQgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICBjdHh0LT5pbnB1dCA9IGlucHV0OwogICAgY3R4dC0+ZW5jID0gZW5jOwogICAgY3R4dC0+c2F4ID0gc2F4OwogICAgY3R4dC0+dXNlcl9kYXRhID0gdXNlcl9kYXRhOwogICAgVE9ETyByZXR1cm4gKDApOwp9CgojZW5kaWYgLyogTElCWE1MX1NDSEVNQVNfRU5BQkxFRCAqLwo=