LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfY3BwdWhlbHBlci5oeHgiCgojaW5jbHVkZSA8Y3BwdWhlbHBlci9pbnRlcmZhY2Vjb250YWluZXIuaHh4PgojaW5jbHVkZSA8Y3BwdWhlbHBlci9xdWVyeWludGVyZmFjZS5oeHg+CiNpbmNsdWRlIDxjcHB1aGVscGVyL3Byb3BzaGxwLmh4eD4KCiNpbmNsdWRlIDxvc2wvZGlhZ25vc2UuaD4KI2luY2x1ZGUgPG9zbC9tdXRleC5oeHg+CgojaW5jbHVkZSA8aGFzaF9tYXA+CgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2xhbmcvWEV2ZW50TGlzdGVuZXIuaHBwPgoKCnVzaW5nIG5hbWVzcGFjZSBvc2w7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6dW5vOwp1c2luZyBuYW1lc3BhY2UgY29tOjpzdW46OnN0YXI6Omxhbmc7CgpuYW1lc3BhY2UgY3BwdQp7CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovKioKICogUmVhbGxvY2F0ZSB0aGUgc2VxdWVuY2UuCiAqLwpzdGF0aWMgdm9pZCByZWFsbG9jKCBTZXF1ZW5jZTwgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gPiAmIHJTZXEsIHNhbF9JbnQzMiBuTmV3TGVuICkKCVNBTF9USFJPVyggKCkgKQp7CglyU2VxLnJlYWxsb2MoIG5OZXdMZW4gKTsKfQoKLyoqCiAqIFJlbW92ZSBhbiBlbGVtZW50IGZyb20gYW4gaW50ZXJmYWNlIHNlcXVlbmNlLgogKi8Kc3RhdGljIHZvaWQgc2VxdWVuY2VSZW1vdmVFbGVtZW50QXQoIFNlcXVlbmNlPCBSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiA+ICYgclNlcSwgc2FsX0ludDMyIGluZGV4ICkKCVNBTF9USFJPVyggKCkgKQp7CglzYWxfSW50MzIgbk5ld0xlbiA9IHJTZXEuZ2V0TGVuZ3RoKCkgLSAxOwoKCVNlcXVlbmNlPCBSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiA+IGFEZXN0U2VxKCByU2VxLmdldExlbmd0aCgpIC0gMSApOwoJLy8gZ2V0QXJyYXkgb24gYSBjb25zdCBzZXF1ZW5jZSBpcyBmYXN0ZXIKCWNvbnN0IFJlZmVyZW5jZTwgWEludGVyZmFjZSA+ICogcFNvdXJjZSA9ICgoY29uc3QgU2VxdWVuY2U8IFJlZmVyZW5jZTwgWEludGVyZmFjZSA+ID4gJilyU2VxKS5nZXRDb25zdEFycmF5KCk7CglSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiAqIHBEZXN0ID0gYURlc3RTZXEuZ2V0QXJyYXkoKTsKCXNhbF9JbnQzMiBpID0gMDsKCWZvciggOyBpIDwgaW5kZXg7IGkrKyApCgkJcERlc3RbaV0gPSBwU291cmNlW2ldOwoJZm9yKCBzYWxfSW50MzIgaiA9IGkgOyBqIDwgbk5ld0xlbjsgaisrICkKCQlwRGVzdFtqXSA9IHBTb3VyY2VbaisxXTsKCXJTZXEgPSBhRGVzdFNlcTsKfQoKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKI2lmZGVmIF9NU0NfVkVSCiNwcmFnbWEgd2FybmluZyggZGlzYWJsZTogNDc4NiApCiNlbmRpZgoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KT0ludGVyZmFjZUl0ZXJhdG9ySGVscGVyOjpPSW50ZXJmYWNlSXRlcmF0b3JIZWxwZXIoIE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIgJiByQ29udF8gKQoJU0FMX1RIUk9XKCAoKSApCgk6IHJDb250KCByQ29udF8gKQp7CglNdXRleEd1YXJkIGFHdWFyZCggckNvbnQuck11dGV4ICk7CglpZiggckNvbnQuYkluVXNlICkKCQkvLyB3b3JzdCBjYXNlLCB0d28gaXRlcmF0b3JzIGF0IHRoZSBzYW1lIHRpbWUKCQlyQ29udC5jb3B5QW5kUmVzZXRJblVzZSgpOwoJYklzTGlzdCA9IHJDb250Xy5iSXNMaXN0OwoJYURhdGEgPSByQ29udF8uYURhdGE7CglpZiggYklzTGlzdCApCgl7CgkJckNvbnQuYkluVXNlID0gc2FsX1RydWU7CgkJblJlbWFpbiA9IGFEYXRhLnBBc1NlcXVlbmNlLT5nZXRMZW5ndGgoKTsKCX0KCWVsc2UgaWYoIGFEYXRhLnBBc0ludGVyZmFjZSApCgl7CgkJYURhdGEucEFzSW50ZXJmYWNlLT5hY3F1aXJlKCk7CgkJblJlbWFpbiA9IDE7Cgl9CgllbHNlCgkJblJlbWFpbiA9IDA7Cn0KCk9JbnRlcmZhY2VJdGVyYXRvckhlbHBlcjo6fk9JbnRlcmZhY2VJdGVyYXRvckhlbHBlcigpIFNBTF9USFJPVyggKCkgKQp7CglzYWxfQm9vbCBiU2hhcmVkOwoJewoJTXV0ZXhHdWFyZCBhR3VhcmQoIHJDb250LnJNdXRleCApOwoJLy8gYlJlc2V0SW5Vc2UgcHJvdGVjdCB0aGUgaXRlcmF0b3IgYWdhaW5zdCByZWN1cnNpb24KCWJTaGFyZWQgPSBhRGF0YS5wQXNTZXF1ZW5jZSA9PSByQ29udC5hRGF0YS5wQXNTZXF1ZW5jZSAmJiByQ29udC5iSXNMaXN0OwoJaWYoIGJTaGFyZWQgKQoJewoJCU9TTF9FTlNVUkUoIHJDb250LmJJblVzZSwgIk9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIgbXVzdCBiZSBpbiB1c2UiICk7CgkJckNvbnQuYkluVXNlID0gc2FsX0ZhbHNlOwoJfQoJfQoKCWlmKCAhYlNoYXJlZCApCgl7CgkJaWYoIGJJc0xpc3QgKQoJCQkvLyBTZXF1ZW5jZSBvd25lZCBieSB0aGUgaXRlcmF0b3IKCQkJZGVsZXRlIGFEYXRhLnBBc1NlcXVlbmNlOwoJCWVsc2UgaWYoIGFEYXRhLnBBc0ludGVyZmFjZSApCgkJCS8vIEludGVyZmFjZSBpcyBhY3F1aXJlZCBieSB0aGUgaXRlcmF0b3IKCQkJYURhdGEucEFzSW50ZXJmYWNlLT5yZWxlYXNlKCk7Cgl9Cn0KClhJbnRlcmZhY2UgKiBPSW50ZXJmYWNlSXRlcmF0b3JIZWxwZXI6Om5leHQoKSBTQUxfVEhST1coICgpICkKewoJaWYoIG5SZW1haW4gKQoJewoJCW5SZW1haW4tLTsKCQlpZiggYklzTGlzdCApCgkJCS8vIHR5cGVjYXNlIHRvIGNvbnN0LHNvIHRoZSBnZXRBcnJheSBtZXRob2QgaXMgZmFzdGVyCgkJCXJldHVybiBhRGF0YS5wQXNTZXF1ZW5jZS0+Z2V0Q29uc3RBcnJheSgpW25SZW1haW5dLmdldCgpOwoJCWVsc2UgaWYoIGFEYXRhLnBBc0ludGVyZmFjZSApCgkJCXJldHVybiBhRGF0YS5wQXNJbnRlcmZhY2U7Cgl9CgkvLyBleGNlcHRpb24KCXJldHVybiAwOwp9Cgp2b2lkIE9JbnRlcmZhY2VJdGVyYXRvckhlbHBlcjo6cmVtb3ZlKCkgU0FMX1RIUk9XKCAoKSApCnsKCWlmKCBiSXNMaXN0ICkKCXsKCQlPU0xfQVNTRVJUKCBuUmVtYWluID49IDAgJiYKCQkJCQluUmVtYWluIDwgYURhdGEucEFzU2VxdWVuY2UtPmdldExlbmd0aCgpICk7CiAgICAgICAgWEludGVyZmFjZSAqIHAgPSBhRGF0YS5wQXNTZXF1ZW5jZS0+Z2V0Q29uc3RBcnJheSgpW25SZW1haW5dLmdldCgpOwoJCXJDb250LnJlbW92ZUludGVyZmFjZSggKiByZWludGVycHJldF9jYXN0PCBjb25zdCBSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiAqID4oICZwICkgKTsKCX0KCWVsc2UKCXsKCQlPU0xfQVNTRVJUKCAwID09IG5SZW1haW4gKTsKCQlyQ29udC5yZW1vdmVJbnRlcmZhY2UoICogcmVpbnRlcnByZXRfY2FzdDwgY29uc3QgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gKiA+KCZhRGF0YS5wQXNJbnRlcmZhY2UpKTsKCX0KfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCgpPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyOjpPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyKCBNdXRleCAmIHJNdXRleF8gKSBTQUxfVEhST1coICgpICkKCTogck11dGV4KCByTXV0ZXhfICkKCSwgYkluVXNlKCBzYWxfRmFsc2UgKQoJLCBiSXNMaXN0KCBzYWxfRmFsc2UgKQp7Cn0KCk9JbnRlcmZhY2VDb250YWluZXJIZWxwZXI6On5PSW50ZXJmYWNlQ29udGFpbmVySGVscGVyKCkgU0FMX1RIUk9XKCAoKSApCnsKCU9TTF9FTlNVUkUoICFiSW5Vc2UsICJ+T0ludGVyZmFjZUNvbnRhaW5lckhlbHBlciBidXQgaXMgaW4gdXNlIiApOwoJaWYoIGJJc0xpc3QgKQoJCWRlbGV0ZSBhRGF0YS5wQXNTZXF1ZW5jZTsKCWVsc2UgaWYoIGFEYXRhLnBBc0ludGVyZmFjZSApCgkJYURhdGEucEFzSW50ZXJmYWNlLT5yZWxlYXNlKCk7Cn0KCnNhbF9JbnQzMiBPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyOjpnZXRMZW5ndGgoKSBjb25zdCBTQUxfVEhST1coICgpICkKewoJTXV0ZXhHdWFyZCBhR3VhcmQoIHJNdXRleCApOwoJaWYoIGJJc0xpc3QgKQoJCXJldHVybiBhRGF0YS5wQXNTZXF1ZW5jZS0+Z2V0TGVuZ3RoKCk7CgllbHNlIGlmKCBhRGF0YS5wQXNJbnRlcmZhY2UgKQoJCXJldHVybiAxOwoJcmV0dXJuIDA7Cn0KClNlcXVlbmNlPCBSZWZlcmVuY2U8WEludGVyZmFjZT4gPiBPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyOjpnZXRFbGVtZW50cygpIGNvbnN0IFNBTF9USFJPVyggKCkgKQp7CglNdXRleEd1YXJkIGFHdWFyZCggck11dGV4ICk7CglpZiggYklzTGlzdCApCgkJcmV0dXJuICphRGF0YS5wQXNTZXF1ZW5jZTsKCWVsc2UgaWYoIGFEYXRhLnBBc0ludGVyZmFjZSApCgl7CgkJUmVmZXJlbmNlPFhJbnRlcmZhY2U+IHgoIGFEYXRhLnBBc0ludGVyZmFjZSApOwoJCXJldHVybiBTZXF1ZW5jZTwgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gPiggJngsIDEgKTsKCX0KCXJldHVybiBTZXF1ZW5jZTwgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gPigpOwp9Cgp2b2lkIE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXI6OmNvcHlBbmRSZXNldEluVXNlKCkgU0FMX1RIUk9XKCAoKSApCnsKCU9TTF9FTlNVUkUoIGJJblVzZSwgIk9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIgbm90IGluIHVzZSIgKTsKCWlmKCBiSW5Vc2UgKQoJewoJCS8vIHRoaXMgc2hvdWxkIGJlIHRoZSB3b3JzdCBjYXNlLiBJZiBhIGl0ZXJhdG9yIGlzIGFjdGl2ZQoJCS8vIGFuZCBhIG5ldyBMaXN0ZW5lciBpcyBhZGRlZC4KCQlpZiggYklzTGlzdCApCgkJCWFEYXRhLnBBc1NlcXVlbmNlID0gbmV3IFNlcXVlbmNlPCBSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiA+KCAqYURhdGEucEFzU2VxdWVuY2UgKTsKCQllbHNlIGlmKCBhRGF0YS5wQXNJbnRlcmZhY2UgKQoJCQlhRGF0YS5wQXNJbnRlcmZhY2UtPmFjcXVpcmUoKTsKCgkJYkluVXNlID0gc2FsX0ZhbHNlOwoJfQp9CgpzYWxfSW50MzIgT0ludGVyZmFjZUNvbnRhaW5lckhlbHBlcjo6YWRkSW50ZXJmYWNlKCBjb25zdCBSZWZlcmVuY2U8WEludGVyZmFjZT4gJiByTGlzdGVuZXIgKSBTQUxfVEhST1coICgpICkKewoJT1NMX0FTU0VSVCggckxpc3RlbmVyLmlzKCkgKTsKCU11dGV4R3VhcmQgYUd1YXJkKCByTXV0ZXggKTsKCWlmKCBiSW5Vc2UgKQoJCWNvcHlBbmRSZXNldEluVXNlKCk7CgoJaWYoIGJJc0xpc3QgKQoJewoJCXNhbF9JbnQzMiBuTGVuID0gYURhdGEucEFzU2VxdWVuY2UtPmdldExlbmd0aCgpOwoJCXJlYWxsb2MoICphRGF0YS5wQXNTZXF1ZW5jZSwgbkxlbiArMSApOwoJCWFEYXRhLnBBc1NlcXVlbmNlLT5nZXRBcnJheSgpWyBuTGVuIF0gPSByTGlzdGVuZXI7CgkJcmV0dXJuIG5MZW4gKzE7Cgl9CgllbHNlIGlmKCBhRGF0YS5wQXNJbnRlcmZhY2UgKQoJewoJCVNlcXVlbmNlPCBSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiA+ICogcFNlcSA9IG5ldyBTZXF1ZW5jZTwgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gPiggMiApOwoJCVJlZmVyZW5jZTxYSW50ZXJmYWNlPiAqIHBBcnJheSA9IHBTZXEtPmdldEFycmF5KCk7CgkJcEFycmF5WzBdID0gYURhdGEucEFzSW50ZXJmYWNlOwoJCXBBcnJheVsxXSA9IHJMaXN0ZW5lcjsKCQlhRGF0YS5wQXNJbnRlcmZhY2UtPnJlbGVhc2UoKTsKCQlhRGF0YS5wQXNTZXF1ZW5jZSA9IHBTZXE7CgkJYklzTGlzdCA9IHNhbF9UcnVlOwoJCXJldHVybiAyOwoJfQoJZWxzZQoJewoJCWFEYXRhLnBBc0ludGVyZmFjZSA9IHJMaXN0ZW5lci5nZXQoKTsKCQlpZiggckxpc3RlbmVyLmlzKCkgKQoJCQlyTGlzdGVuZXItPmFjcXVpcmUoKTsKCQlyZXR1cm4gMTsKCX0KfQoKc2FsX0ludDMyIE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXI6OnJlbW92ZUludGVyZmFjZSggY29uc3QgUmVmZXJlbmNlPFhJbnRlcmZhY2U+ICYgckxpc3RlbmVyICkgU0FMX1RIUk9XKCAoKSApCnsKCU9TTF9BU1NFUlQoIHJMaXN0ZW5lci5pcygpICk7CglNdXRleEd1YXJkIGFHdWFyZCggck11dGV4ICk7CglpZiggYkluVXNlICkKCQljb3B5QW5kUmVzZXRJblVzZSgpOwoKCWlmKCBiSXNMaXN0ICkKCXsKCQljb25zdCBSZWZlcmVuY2U8WEludGVyZmFjZT4gKiBwTCA9IGFEYXRhLnBBc1NlcXVlbmNlLT5nZXRDb25zdEFycmF5KCk7CgkJc2FsX0ludDMyIG5MZW4gPSBhRGF0YS5wQXNTZXF1ZW5jZS0+Z2V0TGVuZ3RoKCk7CgkJc2FsX0ludDMyIGk7CgkJZm9yKCBpID0gMDsgaSA8IG5MZW47IGkrKyApCgkJewoJCQkvLyBJdCBpcyBub3QgdmFsaWQgdG8gY29tcGFyZSB0aGUgUG9pbnRlciBkaXJla3QsIGJ1dCBpcyBpcyBpcyBtdWNoCgkJCS8vIG1vcmUgZmFzdGVyLgoJCQlpZiggcExbaV0uZ2V0KCkgPT0gckxpc3RlbmVyLmdldCgpICkKCQkJewoJCQkJc2VxdWVuY2VSZW1vdmVFbGVtZW50QXQoICphRGF0YS5wQXNTZXF1ZW5jZSwgaSApOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCWlmKCBpID09IG5MZW4gKQoJCXsKCQkJLy8gaW50ZXJmYWNlIG5vdCBmb3VuZCwgdXNlIHRoZSBjb3JyZWN0IGNvbXBhcmUgbWV0aG9kCgkJCWZvciggaSA9IDA7IGkgPCBuTGVuOyBpKysgKQoJCQl7CgkJCQlpZiggcExbaV0gPT0gckxpc3RlbmVyICkKCQkJCXsKCQkJCQlzZXF1ZW5jZVJlbW92ZUVsZW1lbnRBdCgqYURhdGEucEFzU2VxdWVuY2UsIGkgKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCgkJaWYoIGFEYXRhLnBBc1NlcXVlbmNlLT5nZXRMZW5ndGgoKSA9PSAxICkKCQl7CgkJCVhJbnRlcmZhY2UgKiBwID0gYURhdGEucEFzU2VxdWVuY2UtPmdldENvbnN0QXJyYXkoKVswXS5nZXQoKTsKCQkJcC0+YWNxdWlyZSgpOwoJCQlkZWxldGUgYURhdGEucEFzU2VxdWVuY2U7CgkJCWFEYXRhLnBBc0ludGVyZmFjZSA9IHA7CgkJCWJJc0xpc3QgPSBzYWxfRmFsc2U7CgkJCXJldHVybiAxOwoJCX0KCQllbHNlCgkJCXJldHVybiBhRGF0YS5wQXNTZXF1ZW5jZS0+Z2V0TGVuZ3RoKCk7Cgl9CgllbHNlIGlmKCBhRGF0YS5wQXNJbnRlcmZhY2UgJiYgUmVmZXJlbmNlPFhJbnRlcmZhY2U+KCBhRGF0YS5wQXNJbnRlcmZhY2UgKSA9PSByTGlzdGVuZXIgKQoJewoJCWFEYXRhLnBBc0ludGVyZmFjZS0+cmVsZWFzZSgpOwoJCWFEYXRhLnBBc0ludGVyZmFjZSA9IDA7Cgl9CglyZXR1cm4gYURhdGEucEFzSW50ZXJmYWNlID8gMSA6IDA7Cn0KCnZvaWQgT0ludGVyZmFjZUNvbnRhaW5lckhlbHBlcjo6ZGlzcG9zZUFuZENsZWFyKCBjb25zdCBFdmVudE9iamVjdCAmIHJFdnQgKSBTQUxfVEhST1coICgpICkKewoJQ2xlYXJhYmxlTXV0ZXhHdWFyZCBhR3VhcmQoIHJNdXRleCApOwoJT0ludGVyZmFjZUl0ZXJhdG9ySGVscGVyIGFJdCggKnRoaXMgKTsKCS8vIENvbnRhaW5lciBmcmVpZ2ViZW4sIGZhbGxzIGltIGRpc3Bvc2luZyBuZXVlIEVpbnRy5GdlIGtvbW1lbgoJT1NMX0VOU1VSRSggIWJJc0xpc3QgfHwgYkluVXNlLCAiT0ludGVyZmFjZUNvbnRhaW5lckhlbHBlciBub3QgaW4gdXNlIiApOwoJaWYoICFiSXNMaXN0ICYmIGFEYXRhLnBBc0ludGVyZmFjZSApCgkJYURhdGEucEFzSW50ZXJmYWNlLT5yZWxlYXNlKCk7CgkvLyBzZXQgdGhlIG1lbWJlciB0byBudWxsLCB0aGUgaXRlcmF0b3IgZGVsZXRlIHRoZSB2YWx1ZXMKCWFEYXRhLnBBc0ludGVyZmFjZSA9IE5VTEw7CgliSXNMaXN0ID0gc2FsX0ZhbHNlOwoJYkluVXNlID0gc2FsX0ZhbHNlOwoJYUd1YXJkLmNsZWFyKCk7Cgl3aGlsZSggYUl0Lmhhc01vcmVFbGVtZW50cygpICkKCXsKCQl0cnkKCQl7CgkJCVJlZmVyZW5jZTxYRXZlbnRMaXN0ZW5lciA+IHhMc3QoIGFJdC5uZXh0KCksIFVOT19RVUVSWSApOwoJCQlpZiggeExzdC5pcygpICkKCQkJCXhMc3QtPmRpc3Bvc2luZyggckV2dCApOwoJCX0KCQljYXRjaCAoIFJ1bnRpbWVFeGNlcHRpb24gJiApCgkJewoJCQkvLyBiZSByb2J1c3QsIGlmIGUuZy4gYSByZW1vdGUgYnJpZGdlIGhhcyBkaXNwb3NlZCBhbHJlYWR5LgoJCQkvLyB0aGVyZSBpcyBubyB3YXksIHRvIGRlbGVnYXRlIHRoZSBlcnJvciB0byB0aGUgY2FsbGVyIDpvKC4KCQl9Cgl9Cn0KCgp2b2lkIE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXI6OmNsZWFyKCkgU0FMX1RIUk9XKCAoKSApCnsKCUNsZWFyYWJsZU11dGV4R3VhcmQgYUd1YXJkKCByTXV0ZXggKTsKCU9JbnRlcmZhY2VJdGVyYXRvckhlbHBlciBhSXQoICp0aGlzICk7CgkvLyBDb250YWluZXIgZnJlaWdlYmVuLCBmYWxscyBpbSBkaXNwb3NpbmcgbmV1ZSBFaW50cuRnZSBrb21tZW4KCU9TTF9FTlNVUkUoICFiSXNMaXN0IHx8IGJJblVzZSwgIk9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIgbm90IGluIHVzZSIgKTsKCWlmKCAhYklzTGlzdCAmJiBhRGF0YS5wQXNJbnRlcmZhY2UgKQoJCWFEYXRhLnBBc0ludGVyZmFjZS0+cmVsZWFzZSgpOwoJLy8gc2V0IHRoZSBtZW1iZXIgdG8gbnVsbCwgdGhlIGl0ZXJhdG9yIGRlbGV0ZSB0aGUgdmFsdWVzCglhRGF0YS5wQXNJbnRlcmZhY2UgPSAwOwoJYklzTGlzdCA9IHNhbF9GYWxzZTsKCWJJblVzZSA9IHNhbF9GYWxzZTsKCS8vIHJlbGVhc2UgbXV0ZXggYmVmb3JlIGFJdCBkZXN0cnVjdG9yIGNhbGwKCWFHdWFyZC5jbGVhcigpOwp9CgovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKLy8gc3BlY2lhbGl6ZWQgY2xhc3MgZm9yIHR5cGUKCnR5cGVkZWYgOjpzdGQ6OnZlY3Rvcjwgc3RkOjpwYWlyIDwgVHlwZSAsIHZvaWQqID4gPiB0X3R5cGUycHRyOwoKT011bHRpVHlwZUludGVyZmFjZUNvbnRhaW5lckhlbHBlcjo6T011bHRpVHlwZUludGVyZmFjZUNvbnRhaW5lckhlbHBlciggTXV0ZXggJiByTXV0ZXhfICkKICAgIFNBTF9USFJPVyggKCkgKQogICAgOiByTXV0ZXgoIHJNdXRleF8gKQp7CgltX3BNYXAgPSBuZXcgdF90eXBlMnB0cigpOwp9Ck9NdWx0aVR5cGVJbnRlcmZhY2VDb250YWluZXJIZWxwZXI6On5PTXVsdGlUeXBlSW50ZXJmYWNlQ29udGFpbmVySGVscGVyKCkKICAgIFNBTF9USFJPVyggKCkgKQp7CiAgICB0X3R5cGUycHRyICogcE1hcCA9ICh0X3R5cGUycHRyICopbV9wTWFwOwoJdF90eXBlMnB0cjo6aXRlcmF0b3IgaXRlciA9IHBNYXAtPmJlZ2luKCk7Cgl0X3R5cGUycHRyOjppdGVyYXRvciBlbmQgPSBwTWFwLT5lbmQoKTsKCgl3aGlsZSggaXRlciAhPSBlbmQgKQoJewoJCWRlbGV0ZSAoT0ludGVyZmFjZUNvbnRhaW5lckhlbHBlciopKCppdGVyKS5zZWNvbmQ7CgkJKCppdGVyKS5zZWNvbmQgPSAwOwoJCSsraXRlcjsKCX0KCWRlbGV0ZSBwTWFwOwp9ClNlcXVlbmNlPCBUeXBlID4gT011bHRpVHlwZUludGVyZmFjZUNvbnRhaW5lckhlbHBlcjo6Z2V0Q29udGFpbmVkVHlwZXMoKSBjb25zdAogICAgU0FMX1RIUk9XKCAoKSApCnsKICAgIHRfdHlwZTJwdHIgKiBwTWFwID0gKHRfdHlwZTJwdHIgKiltX3BNYXA7Cgl0X3R5cGUycHRyOjpzaXplX3R5cGUgblNpemU7CgoJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCByTXV0ZXggKTsKCW5TaXplID0gcE1hcC0+c2l6ZSgpOwoJaWYoIG5TaXplICkKCXsKCQk6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlNlcXVlbmNlPCBUeXBlID4gYUludGVyZmFjZVR5cGVzKCBuU2l6ZSApOwoJCVR5cGUgKiBwQXJyYXkgPSBhSW50ZXJmYWNlVHlwZXMuZ2V0QXJyYXkoKTsKCgkJdF90eXBlMnB0cjo6aXRlcmF0b3IgaXRlciA9IHBNYXAtPmJlZ2luKCk7CgkJdF90eXBlMnB0cjo6aXRlcmF0b3IgZW5kID0gcE1hcC0+ZW5kKCk7CgoJCXNhbF9JbnQzMiBpID0gMDsKCQl3aGlsZSggaXRlciAhPSBlbmQgKQoJCXsKCQkJLy8gYXJlIGludGVyZmFjZXMgYWRkZWQgdG8gdGhpcyBjb250YWluZXI/CgkJCWlmKCAoKE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIqKSgqaXRlcikuc2Vjb25kKS0+Z2V0TGVuZ3RoKCkgKQoJCQkJLy8geWVzLCBwdXQgdGhlIHR5cGUgaW4gdGhlIGFycmF5CgkJCQlwQXJyYXlbaSsrXSA9ICgqaXRlcikuZmlyc3Q7CgkJCSsraXRlcjsKCQl9CgkJaWYoICh0X3R5cGUycHRyOjpzaXplX3R5cGUpaSAhPSBuU2l6ZSApIHsKCQkJLy8gbWF5IGJlIGVtcHR5IGNvbnRhaW5lciwgcmVkdWNlIHRoZSBzZXF1ZW5jZSB0byB0aGUgcmlnaHQgc2l6ZQoJCQlhSW50ZXJmYWNlVHlwZXMgPSA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlNlcXVlbmNlPCBUeXBlID4oIHBBcnJheSwgaSApOwoJCX0KCQlyZXR1cm4gYUludGVyZmFjZVR5cGVzOwoJfQoJcmV0dXJuIDo6Y29tOjpzdW46OnN0YXI6OnVubzo6U2VxdWVuY2U8IFR5cGUgPigpOwp9CgpzdGF0aWMgdF90eXBlMnB0cjo6aXRlcmF0b3IgZmluZFR5cGUodF90eXBlMnB0ciAqcE1hcCwgY29uc3QgVHlwZSAmIHJLZXkgKQp7Cgl0X3R5cGUycHRyOjppdGVyYXRvciBpdGVyID0gcE1hcC0+YmVnaW4oKTsKCXRfdHlwZTJwdHI6Oml0ZXJhdG9yIGVuZCA9IHBNYXAtPmVuZCgpOwoKCXdoaWxlKCBpdGVyICE9IGVuZCApCiAgICB7CiAgICAgICAgaWYgKGl0ZXItPmZpcnN0ID09IHJLZXkpCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGl0ZXIrKzsKICAgIH0KICAgIHJldHVybiBpdGVyOwp9CgpPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyICogT011bHRpVHlwZUludGVyZmFjZUNvbnRhaW5lckhlbHBlcjo6Z2V0Q29udGFpbmVyKCBjb25zdCBUeXBlICYgcktleSApIGNvbnN0CiAgICBTQUxfVEhST1coICgpICkKewoJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCByTXV0ZXggKTsKCiAgICB0X3R5cGUycHRyICogcE1hcCA9ICh0X3R5cGUycHRyICopbV9wTWFwOwogCXRfdHlwZTJwdHI6Oml0ZXJhdG9yIGl0ZXIgPSBmaW5kVHlwZSggcE1hcCwgcktleSApOwoJaWYoIGl0ZXIgIT0gcE1hcC0+ZW5kKCkgKQoJCQlyZXR1cm4gKE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIqKSAoKml0ZXIpLnNlY29uZDsKCXJldHVybiAwOwp9CnNhbF9JbnQzMiBPTXVsdGlUeXBlSW50ZXJmYWNlQ29udGFpbmVySGVscGVyOjphZGRJbnRlcmZhY2UoCiAgICBjb25zdCBUeXBlICYgcktleSwgY29uc3QgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gJiByTGlzdGVuZXIgKQogICAgU0FMX1RIUk9XKCAoKSApCnsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggck11dGV4ICk7CiAgICB0X3R5cGUycHRyICogcE1hcCA9ICh0X3R5cGUycHRyICopbV9wTWFwOwoJdF90eXBlMnB0cjo6aXRlcmF0b3IgaXRlciA9IGZpbmRUeXBlKCBwTWFwLCByS2V5ICk7CglpZiggaXRlciA9PSBwTWFwLT5lbmQoKSApCgl7CgkJT0ludGVyZmFjZUNvbnRhaW5lckhlbHBlciAqIHBMQyA9IG5ldyBPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyKCByTXV0ZXggKTsKICAgICAgICBwTWFwLT5wdXNoX2JhY2soc3RkOjpwYWlyPFR5cGUsIHZvaWQqPihyS2V5LCBwTEMpKTsKCQlyZXR1cm4gcExDLT5hZGRJbnRlcmZhY2UoIHJMaXN0ZW5lciApOwoJfQoJZWxzZQoJCXJldHVybiAoKE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIqKSgqaXRlcikuc2Vjb25kKS0+YWRkSW50ZXJmYWNlKCByTGlzdGVuZXIgKTsKfQpzYWxfSW50MzIgT011bHRpVHlwZUludGVyZmFjZUNvbnRhaW5lckhlbHBlcjo6cmVtb3ZlSW50ZXJmYWNlKAogICAgY29uc3QgVHlwZSAmIHJLZXksIGNvbnN0IFJlZmVyZW5jZTwgWEludGVyZmFjZSA+ICYgckxpc3RlbmVyICkKICAgIFNBTF9USFJPVyggKCkgKQp7Cgk6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIHJNdXRleCApOwoKCS8vIHNlYXJjaCBjb250YWluZXIgd2l0aCBpZCBuVWlrCiAgICB0X3R5cGUycHRyICogcE1hcCA9ICh0X3R5cGUycHRyICopbV9wTWFwOwoJdF90eXBlMnB0cjo6aXRlcmF0b3IgaXRlciA9IGZpbmRUeXBlKCBwTWFwLCByS2V5ICk7CgkJLy8gY29udGFpbmVyIGZvdW5kPwoJaWYoIGl0ZXIgIT0gcE1hcC0+ZW5kKCkgKQogICAgICAgIHJldHVybiAoKE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIqKSgqaXRlcikuc2Vjb25kKS0+cmVtb3ZlSW50ZXJmYWNlKCByTGlzdGVuZXIgKTsKCgkvLyBubyBjb250YWluZXIgd2l0aCB0aGlzIGlkLiBBbHdheXMgcmV0dXJuIDAKCXJldHVybiAwOwp9CnZvaWQgT011bHRpVHlwZUludGVyZmFjZUNvbnRhaW5lckhlbHBlcjo6ZGlzcG9zZUFuZENsZWFyKCBjb25zdCBFdmVudE9iamVjdCAmIHJFdnQgKQogICAgU0FMX1RIUk9XKCAoKSApCnsKCXRfdHlwZTJwdHI6OnNpemVfdHlwZSBuU2l6ZSA9IDA7CglPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyICoqIHBwTGlzdGVuZXJDb250YWluZXJzID0gTlVMTDsKCXsKCQk6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIHJNdXRleCApOwogICAgICAgIHRfdHlwZTJwdHIgKiBwTWFwID0gKHRfdHlwZTJwdHIgKiltX3BNYXA7CgkJblNpemUgPSBwTWFwLT5zaXplKCk7CgkJaWYoIG5TaXplICkKCQl7CgkJCXR5cGVkZWYgT0ludGVyZmFjZUNvbnRhaW5lckhlbHBlciogcHBwOwoJCQlwcExpc3RlbmVyQ29udGFpbmVycyA9IG5ldyBwcHBbblNpemVdOwoJCQkvL3BwTGlzdGVuZXJDb250YWluZXJzID0gbmV3IChMaXN0ZW5lckNvbnRhaW5lciopW25TaXplXTsKCgkJCXRfdHlwZTJwdHI6Oml0ZXJhdG9yIGl0ZXIgPSBwTWFwLT5iZWdpbigpOwoJCQl0X3R5cGUycHRyOjppdGVyYXRvciBlbmQgPSBwTWFwLT5lbmQoKTsKCgkJCXRfdHlwZTJwdHI6OnNpemVfdHlwZSBpID0gMDsKCQkJd2hpbGUoIGl0ZXIgIT0gZW5kICkKCQkJewoJCQkJcHBMaXN0ZW5lckNvbnRhaW5lcnNbaSsrXSA9IChPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyKikoKml0ZXIpLnNlY29uZDsKCQkJCSsraXRlcjsKCQkJfQoJCX0KCX0KCgkvLyBjcmVhdGUgYSBjb3B5LCBiZWNhdXNlIGRvIG5vdCBmaXJlIGV2ZW50IGluIGEgZ3VhcmRlZCBzZWN0aW9uCglmb3IoIHRfdHlwZTJwdHI6OnNpemVfdHlwZSBpID0gMDsKCQkJaSA8IG5TaXplOyBpKysgKQoJewoJCWlmKCBwcExpc3RlbmVyQ29udGFpbmVyc1tpXSApCgkJCXBwTGlzdGVuZXJDb250YWluZXJzW2ldLT5kaXNwb3NlQW5kQ2xlYXIoIHJFdnQgKTsKCX0KCglkZWxldGUgW10gcHBMaXN0ZW5lckNvbnRhaW5lcnM7Cn0Kdm9pZCBPTXVsdGlUeXBlSW50ZXJmYWNlQ29udGFpbmVySGVscGVyOjpjbGVhcigpCiAgICBTQUxfVEhST1coICgpICkKewoJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCByTXV0ZXggKTsKICAgIHRfdHlwZTJwdHIgKiBwTWFwID0gKHRfdHlwZTJwdHIgKiltX3BNYXA7Cgl0X3R5cGUycHRyOjppdGVyYXRvciBpdGVyID0gcE1hcC0+YmVnaW4oKTsKCXRfdHlwZTJwdHI6Oml0ZXJhdG9yIGVuZCA9IHBNYXAtPmVuZCgpOwoKCXdoaWxlKCBpdGVyICE9IGVuZCApCgl7CgkJKChPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyKikoKml0ZXIpLnNlY29uZCktPmNsZWFyKCk7CgkJKytpdGVyOwoJfQp9CgoKLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwovLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCi8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCi8vIHNwZWNpYWxpemVkIGNsYXNzIGZvciBsb25nCgp0eXBlZGVmIDo6c3RkOjp2ZWN0b3I8IHN0ZDo6cGFpciA8IHNhbF9JbnQzMiAsIHZvaWQqID4gPiB0X2xvbmcycHRyOwoKc3RhdGljIHRfbG9uZzJwdHI6Oml0ZXJhdG9yIGZpbmRMb25nKHRfbG9uZzJwdHIgKnBNYXAsIHNhbF9JbnQzMiBuS2V5ICkKewoJdF9sb25nMnB0cjo6aXRlcmF0b3IgaXRlciA9IHBNYXAtPmJlZ2luKCk7Cgl0X2xvbmcycHRyOjppdGVyYXRvciBlbmQgPSBwTWFwLT5lbmQoKTsKCgl3aGlsZSggaXRlciAhPSBlbmQgKQogICAgewogICAgICAgIGlmIChpdGVyLT5maXJzdCA9PSBuS2V5KQogICAgICAgICAgICBicmVhazsKICAgICAgICBpdGVyKys7CiAgICB9CiAgICByZXR1cm4gaXRlcjsKfQoKT011bHRpVHlwZUludGVyZmFjZUNvbnRhaW5lckhlbHBlckludDMyOjpPTXVsdGlUeXBlSW50ZXJmYWNlQ29udGFpbmVySGVscGVySW50MzIoIE11dGV4ICYgck11dGV4XyApCiAgICBTQUxfVEhST1coICgpICkKICAgIDogbV9wTWFwKCBOVUxMICkKICAgICwgck11dGV4KCByTXV0ZXhfICkKewogICAgLy8gZGVsYXkgcE1hcCBhbGxvY2F0aW9uIHVudGlsIG5lY2Vzc2FyeS4KfQpPTXVsdGlUeXBlSW50ZXJmYWNlQ29udGFpbmVySGVscGVySW50MzI6On5PTXVsdGlUeXBlSW50ZXJmYWNlQ29udGFpbmVySGVscGVySW50MzIoKQogICAgU0FMX1RIUk9XKCAoKSApCnsKICAgIGlmICghbV9wTWFwKQogICAgICAgIHJldHVybjsKCiAgICB0X2xvbmcycHRyICogcE1hcCA9ICh0X2xvbmcycHRyICopbV9wTWFwOwoJdF9sb25nMnB0cjo6aXRlcmF0b3IgaXRlciA9IHBNYXAtPmJlZ2luKCk7Cgl0X2xvbmcycHRyOjppdGVyYXRvciBlbmQgPSBwTWFwLT5lbmQoKTsKCgl3aGlsZSggaXRlciAhPSBlbmQgKQoJewoJCWRlbGV0ZSAoT0ludGVyZmFjZUNvbnRhaW5lckhlbHBlciopKCppdGVyKS5zZWNvbmQ7CgkJKCppdGVyKS5zZWNvbmQgPSAwOwoJCSsraXRlcjsKCX0KCWRlbGV0ZSBwTWFwOwp9ClNlcXVlbmNlPCBzYWxfSW50MzIgPiBPTXVsdGlUeXBlSW50ZXJmYWNlQ29udGFpbmVySGVscGVySW50MzI6OmdldENvbnRhaW5lZFR5cGVzKCkgY29uc3QKICAgIFNBTF9USFJPVyggKCkgKQp7CiAgICB0X2xvbmcycHRyICogcE1hcCA9ICh0X2xvbmcycHRyICopbV9wTWFwOwoJdF9sb25nMnB0cjo6c2l6ZV90eXBlIG5TaXplOwoKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggck11dGV4ICk7CgluU2l6ZSA9IHBNYXAgPyBwTWFwLT5zaXplKCkgOiAwOwoJaWYoIG5TaXplICkKCXsKCQk6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlNlcXVlbmNlPCBzYWxfSW50MzIgPiBhSW50ZXJmYWNlVHlwZXMoIG5TaXplICk7CgkJc2FsX0ludDMyICogcEFycmF5ID0gYUludGVyZmFjZVR5cGVzLmdldEFycmF5KCk7CgoJCXRfbG9uZzJwdHI6Oml0ZXJhdG9yIGl0ZXIgPSBwTWFwLT5iZWdpbigpOwoJCXRfbG9uZzJwdHI6Oml0ZXJhdG9yIGVuZCA9IHBNYXAtPmVuZCgpOwogICAgICAgIAoJCXNhbF9JbnQzMiBpID0gMDsKCQl3aGlsZSggaXRlciAhPSBlbmQgKQoJCXsKCQkJLy8gYXJlIGludGVyZmFjZXMgYWRkZWQgdG8gdGhpcyBjb250YWluZXI/CgkJCWlmKCAoKE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIqKSgqaXRlcikuc2Vjb25kKS0+Z2V0TGVuZ3RoKCkgKQoJCQkJLy8geWVzLCBwdXQgdGhlIHR5cGUgaW4gdGhlIGFycmF5CgkJCQlwQXJyYXlbaSsrXSA9ICgqaXRlcikuZmlyc3Q7CgkJCSsraXRlcjsKCQl9CgkJaWYoICh0X2xvbmcycHRyOjpzaXplX3R5cGUpaSAhPSBuU2l6ZSApIHsKCQkJLy8gbWF5IGJlIGVtcHR5IGNvbnRhaW5lciwgcmVkdWNlIHRoZSBzZXF1ZW5jZSB0byB0aGUgcmlnaHQgc2l6ZQoJCQlhSW50ZXJmYWNlVHlwZXMgPSA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlNlcXVlbmNlPCBzYWxfSW50MzIgPiggcEFycmF5LCBpICk7CgkJfQoJCXJldHVybiBhSW50ZXJmYWNlVHlwZXM7Cgl9CglyZXR1cm4gOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpTZXF1ZW5jZTwgc2FsX0ludDMyID4oKTsKfQpPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyICogT011bHRpVHlwZUludGVyZmFjZUNvbnRhaW5lckhlbHBlckludDMyOjpnZXRDb250YWluZXIoIGNvbnN0IHNhbF9JbnQzMiAmIHJLZXkgKSBjb25zdAogICAgU0FMX1RIUk9XKCAoKSApCnsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggck11dGV4ICk7CgogICAgaWYgKCFtX3BNYXApCiAgICAgICAgcmV0dXJuIDA7CiAgICB0X2xvbmcycHRyICogcE1hcCA9ICh0X2xvbmcycHRyICopbV9wTWFwOwogCXRfbG9uZzJwdHI6Oml0ZXJhdG9yIGl0ZXIgPSBmaW5kTG9uZyggcE1hcCwgcktleSApOwoJaWYoIGl0ZXIgIT0gcE1hcC0+ZW5kKCkgKQoJCQlyZXR1cm4gKE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIqKSAoKml0ZXIpLnNlY29uZDsKCXJldHVybiAwOwp9CnNhbF9JbnQzMiBPTXVsdGlUeXBlSW50ZXJmYWNlQ29udGFpbmVySGVscGVySW50MzI6OmFkZEludGVyZmFjZSgKICAgIGNvbnN0IHNhbF9JbnQzMiAmIHJLZXksIGNvbnN0IFJlZmVyZW5jZTwgWEludGVyZmFjZSA+ICYgckxpc3RlbmVyICkKICAgIFNBTF9USFJPVyggKCkgKQp7Cgk6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIHJNdXRleCApOwogICAgaWYgKCFtX3BNYXApCiAgICAJbV9wTWFwID0gbmV3IHRfbG9uZzJwdHIoKTsKICAgIHRfbG9uZzJwdHIgKiBwTWFwID0gKHRfbG9uZzJwdHIgKiltX3BNYXA7Cgl0X2xvbmcycHRyOjppdGVyYXRvciBpdGVyID0gZmluZExvbmcoIHBNYXAsIHJLZXkgKTsKIAlpZiggaXRlciA9PSBwTWFwLT5lbmQoKSApCgl7CgkJT0ludGVyZmFjZUNvbnRhaW5lckhlbHBlciAqIHBMQyA9IG5ldyBPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyKCByTXV0ZXggKTsKICAgICAgICBwTWFwLT5wdXNoX2JhY2soc3RkOjpwYWlyPCBzYWxfSW50MzIsIHZvaWQqID4ocktleSwgcExDKSk7CgkJcmV0dXJuIHBMQy0+YWRkSW50ZXJmYWNlKCByTGlzdGVuZXIgKTsKCX0KCWVsc2UKCQlyZXR1cm4gKChPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyKikoKml0ZXIpLnNlY29uZCktPmFkZEludGVyZmFjZSggckxpc3RlbmVyICk7Cn0Kc2FsX0ludDMyIE9NdWx0aVR5cGVJbnRlcmZhY2VDb250YWluZXJIZWxwZXJJbnQzMjo6cmVtb3ZlSW50ZXJmYWNlKAogICAgY29uc3Qgc2FsX0ludDMyICYgcktleSwgY29uc3QgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gJiByTGlzdGVuZXIgKQogICAgU0FMX1RIUk9XKCAoKSApCnsKCTo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggck11dGV4ICk7CgogICAgaWYgKCFtX3BNYXApCiAgICAgICAgcmV0dXJuIDA7CgkvLyBzZWFyY2ggY29udGFpbmVyIHdpdGggaWQgblVpawogICAgdF9sb25nMnB0ciAqIHBNYXAgPSAodF9sb25nMnB0ciAqKW1fcE1hcDsKCXRfbG9uZzJwdHI6Oml0ZXJhdG9yIGl0ZXIgPSBmaW5kTG9uZyggcE1hcCwgcktleSApOwoJCS8vIGNvbnRhaW5lciBmb3VuZD8KCWlmKCBpdGVyICE9IHBNYXAtPmVuZCgpICkKICAgICAgICByZXR1cm4gKChPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyKikoKml0ZXIpLnNlY29uZCktPnJlbW92ZUludGVyZmFjZSggckxpc3RlbmVyICk7CgoJLy8gbm8gY29udGFpbmVyIHdpdGggdGhpcyBpZC4gQWx3YXlzIHJldHVybiAwCglyZXR1cm4gMDsKfQp2b2lkIE9NdWx0aVR5cGVJbnRlcmZhY2VDb250YWluZXJIZWxwZXJJbnQzMjo6ZGlzcG9zZUFuZENsZWFyKCBjb25zdCBFdmVudE9iamVjdCAmIHJFdnQgKQogICAgU0FMX1RIUk9XKCAoKSApCnsKCXRfbG9uZzJwdHI6OnNpemVfdHlwZSBuU2l6ZSA9IDA7CglPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyICoqIHBwTGlzdGVuZXJDb250YWluZXJzID0gTlVMTDsKCXsKCQk6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIHJNdXRleCApOwogICAgICAgIGlmICghbV9wTWFwKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIHRfbG9uZzJwdHIgKiBwTWFwID0gKHRfbG9uZzJwdHIgKiltX3BNYXA7CgkJblNpemUgPSBwTWFwLT5zaXplKCk7CgkJaWYoIG5TaXplICkKCQl7CgkJCXR5cGVkZWYgT0ludGVyZmFjZUNvbnRhaW5lckhlbHBlciogcHBwOwoJCQlwcExpc3RlbmVyQ29udGFpbmVycyA9IG5ldyBwcHBbblNpemVdOwoJCQkvL3BwTGlzdGVuZXJDb250YWluZXJzID0gbmV3IChMaXN0ZW5lckNvbnRhaW5lciopW25TaXplXTsKCgkJCXRfbG9uZzJwdHI6Oml0ZXJhdG9yIGl0ZXIgPSBwTWFwLT5iZWdpbigpOwoJCQl0X2xvbmcycHRyOjppdGVyYXRvciBlbmQgPSBwTWFwLT5lbmQoKTsKCgkJCXRfbG9uZzJwdHI6OnNpemVfdHlwZSBpID0gMDsKCQkJd2hpbGUoIGl0ZXIgIT0gZW5kICkKCQkJewoJCQkJcHBMaXN0ZW5lckNvbnRhaW5lcnNbaSsrXSA9IChPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyKikoKml0ZXIpLnNlY29uZDsKCQkJCSsraXRlcjsKCQkJfQoJCX0KCX0KCgkvLyBjcmVhdGUgYSBjb3B5LCBiZWNhdXNlIGRvIG5vdCBmaXJlIGV2ZW50IGluIGEgZ3VhcmRlZCBzZWN0aW9uCglmb3IoIHRfbG9uZzJwdHI6OnNpemVfdHlwZSBpID0gMDsKCQkJaSA8IG5TaXplOyBpKysgKQoJewoJCWlmKCBwcExpc3RlbmVyQ29udGFpbmVyc1tpXSApCgkJCXBwTGlzdGVuZXJDb250YWluZXJzW2ldLT5kaXNwb3NlQW5kQ2xlYXIoIHJFdnQgKTsKCX0KCglkZWxldGUgW10gcHBMaXN0ZW5lckNvbnRhaW5lcnM7Cn0Kdm9pZCBPTXVsdGlUeXBlSW50ZXJmYWNlQ29udGFpbmVySGVscGVySW50MzI6OmNsZWFyKCkKICAgIFNBTF9USFJPVyggKCkgKQp7Cgk6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIHJNdXRleCApOwogICAgaWYgKCFtX3BNYXApCiAgICAgICAgcmV0dXJuOwogICAgdF9sb25nMnB0ciAqIHBNYXAgPSAodF9sb25nMnB0ciAqKW1fcE1hcDsKCXRfbG9uZzJwdHI6Oml0ZXJhdG9yIGl0ZXIgPSBwTWFwLT5iZWdpbigpOwoJdF9sb25nMnB0cjo6aXRlcmF0b3IgZW5kID0gcE1hcC0+ZW5kKCk7CgoJd2hpbGUoIGl0ZXIgIT0gZW5kICkKCXsKCQkoKE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIqKSgqaXRlcikuc2Vjb25kKS0+Y2xlYXIoKTsKCQkrK2l0ZXI7Cgl9Cn0KCn0KCg==