ZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0Ly5jbGFzc3BhdGhfY2FyYm9uIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvLmNsYXNzcGF0aF9jYXJib24KaW5kZXggYzQ5Y2M4Mi4uNmMzNGRlZCAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvLmNsYXNzcGF0aF9jYXJib24KKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvLmNsYXNzcGF0aF9jYXJib24KQEAgLTEsMjIgKzEsMjIgQEAKIDw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+CiA8Y2xhc3NwYXRoPgogICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJ2YXIiIHBhdGg9IkpSRV9MSUIiLz4KLSAgICA8Y2xhc3NwYXRoZW50cnkga2luZD0ic3JjIiBwYXRoPSJFY2xpcHNlIFNXVC9jYXJib24iLz4KLSAgICA8Y2xhc3NwYXRoZW50cnkga2luZD0ic3JjIiBwYXRoPSJFY2xpcHNlIFNXVC9lbXVsYXRlZC9iaWRpIi8+Ci0gICAgPGNsYXNzcGF0aGVudHJ5IGtpbmQ9InNyYyIgcGF0aD0iRWNsaXBzZSBTV1QvZW11bGF0ZWQvY29vbGJhciIvPgotICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJzcmMiIHBhdGg9IkVjbGlwc2UgU1dUL2VtdWxhdGVkL3RyZWV0YWJsZSIvPgorICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJzcmMiIHBhdGg9IkVjbGlwc2UgU1dUL2NhcmJvbiIgZXhjbHVkaW5nPSJUcmVlKi4qfFRhYmxlKi4qIi8+CiAgICAgPGNsYXNzcGF0aGVudHJ5IGtpbmQ9InNyYyIgcGF0aD0iRWNsaXBzZSBTV1QvY29tbW9uIi8+CiAgICAgPGNsYXNzcGF0aGVudHJ5IGtpbmQ9InNyYyIgcGF0aD0iRWNsaXBzZSBTV1QvY29tbW9uX2oyc2UiLz4KKyAgICA8Y2xhc3NwYXRoZW50cnkga2luZD0ic3JjIiBwYXRoPSJFY2xpcHNlIFNXVC9lbXVsYXRlZC9iaWRpIi8+CisgICAgPGNsYXNzcGF0aGVudHJ5IGtpbmQ9InNyYyIgcGF0aD0iRWNsaXBzZSBTV1QvZW11bGF0ZWQvY29vbGJhciIvPgogICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJzcmMiIHBhdGg9IkVjbGlwc2UgU1dUIFBJL2NhcmJvbiIvPgogICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJzcmMiIHBhdGg9IkVjbGlwc2UgU1dUIFBJL2NvbW1vbl9qMnNlIi8+Ci0gICAgPGNsYXNzcGF0aGVudHJ5IGtpbmQ9InNyYyIgcGF0aD0iRWNsaXBzZSBTV1QgQWNjZXNzaWJpbGl0eS9lbXVsYXRlZCIvPgogICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJzcmMiIHBhdGg9IkVjbGlwc2UgU1dUIEFjY2Vzc2liaWxpdHkvY29tbW9uIi8+Ci0gICAgPGNsYXNzcGF0aGVudHJ5IGtpbmQ9InNyYyIgcGF0aD0iRWNsaXBzZSBTV1QgRHJhZyBhbmQgRHJvcC9jYXJib24iLz4KLSAgICA8Y2xhc3NwYXRoZW50cnkga2luZD0ic3JjIiBwYXRoPSJFY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NvbW1vbiIvPgotICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJzcmMiIHBhdGg9IkVjbGlwc2UgU1dUIFByaW50aW5nL2NhcmJvbiIvPgotICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJzcmMiIHBhdGg9IkVjbGlwc2UgU1dUIFByaW50aW5nL2NvbW1vbiIvPgotICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJzcmMiIHBhdGg9IkVjbGlwc2UgU1dUIFByb2dyYW0vY2FyYm9uIi8+Ci0gICAgPGNsYXNzcGF0aGVudHJ5IGtpbmQ9InNyYyIgcGF0aD0iRWNsaXBzZSBTV1QgUHJvZ3JhbS9jb21tb24iLz4KKyAgICA8Y2xhc3NwYXRoZW50cnkga2luZD0ic3JjIiBwYXRoPSJFY2xpcHNlIFNXVCBBY2Nlc3NpYmlsaXR5L2VtdWxhdGVkIi8+CiAgICAgPGNsYXNzcGF0aGVudHJ5IGtpbmQ9InNyYyIgcGF0aD0iRWNsaXBzZSBTV1QgQ3VzdG9tIFdpZGdldHMvY29tbW9uIi8+CisgICAgPGNsYXNzcGF0aGVudHJ5IGtpbmQ9InNyYyIgcGF0aD0iRWNsaXBzZSBTV1QgRHJhZyBhbmQgRHJvcC9jb21tb24iLz4KKyAgICA8Y2xhc3NwYXRoZW50cnkga2luZD0ic3JjIiBwYXRoPSJFY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbiIvPgorICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJzcmMiIHBhdGg9IkVjbGlwc2UgU1dUIFByaW50aW5nL2NvbW1vbiIvPgorICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJzcmMiIHBhdGg9IkVjbGlwc2UgU1dUIFByaW50aW5nL2NhcmJvbiIvPgorICAgIDxjbGFzc3BhdGhlbnRyeSBraW5kPSJzcmMiIHBhdGg9IkVjbGlwc2UgU1dUIFByb2dyYW0vY29tbW9uIi8+CisgICAgPGNsYXNzcGF0aGVudHJ5IGtpbmQ9InNyYyIgcGF0aD0iRWNsaXBzZSBTV1QgUHJvZ3JhbS9jYXJib24iLz4KKyAgICA8Y2xhc3NwYXRoZW50cnkga2luZD0ic3JjIiBwYXRoPSJFY2xpcHNlIFNXVC9lbXVsYXRlZC90cmVldGFibGUiLz4KICAgICA8Y2xhc3NwYXRoZW50cnkga2luZD0ib3V0cHV0IiBwYXRoPSJiaW4iLz4KIDwvY2xhc3NwYXRoPgpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgRHJhZyBhbmQgRHJvcC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2RuZC9CeXRlQXJyYXlUcmFuc2Zlci5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgRHJhZyBhbmQgRHJvcC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2RuZC9CeXRlQXJyYXlUcmFuc2Zlci5qYXZhCmluZGV4IDRkZWJhZjQuLmE4N2Y2Y2UgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIERyYWcgYW5kIERyb3AvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9kbmQvQnl0ZUFycmF5VHJhbnNmZXIuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZG5kL0J5dGVBcnJheVRyYW5zZmVyLmphdmEKQEAgLTcsMTA5ICs3LDYgQEAKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAgKi8KIAotLyoqCi0gKiBUaGUgY2xhc3MgPGNvZGU+Qnl0ZUFycmF5VHJhbnNmZXI8L2NvZGU+IHByb3ZpZGVzIGEgcGxhdGZvcm0gc3BlY2lmaWMgCi0gKiBtZWNoYW5pc20gZm9yIGNvbnZlcnRpbmcgYSBqYXZhIDxjb2RlPmJ5dGVbXTwvY29kZT4gdG8gYSBwbGF0Zm9ybSAKLSAqIHNwZWNpZmljIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBieXRlIGFycmF5IGFuZCB2aWNlIHZlcnNhLiAgU2VlIAotICogPGNvZGU+VHJhbnNmZXI8L2NvZGU+IGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLgotICoKLSAqIDxwPjxjb2RlPkJ5dGVBcnJheVRyYW5zZmVyPC9jb2RlPiBpcyBuZXZlciB1c2VkIGRpcmVjdGx5IGJ1dCBpcyBzdWItY2xhc3NlZCAKLSAqIGJ5IHRyYW5zZmVyIGFnZW50cyB0aGF0IGNvbnZlcnQgYmV0d2VlbiBkYXRhIGluIGEgamF2YSBmb3JtYXQgc3VjaCBhcyBhCi0gKiA8Y29kZT5TdHJpbmc8L2NvZGU+IGFuZCBhIHBsYXRmb3JtIHNwZWNpZmljIGJ5dGUgYXJyYXkuCi0gKiAKLSAqIDxwPklmIHRoZSBkYXRhIHlvdSBhcmUgY29udmVydGluZyA8Yj5kb2VzIG5vdDwvYj4gbWFwIHRvIGEgCi0gKiA8Y29kZT5ieXRlW108L2NvZGU+LCB5b3Ugc2hvdWxkIHN1Yi1jbGFzcyA8Y29kZT5UcmFuc2ZlcjwvY29kZT4gZGlyZWN0bHkgCi0gKiBhbmQgZG8geW91ciBvd24gbWFwcGluZyB0byBhIHBsYXRmb3JtIGRhdGEgdHlwZS48L3A+Ci0gKiAKLSAqIDxwPlRoZSBmb2xsb3dpbmcgc25pcHBldCBzaG93cyBhIHN1YmxjYXNzIG9mIEJ5dGVBcnJheVRyYW5zZmVyIHRoYXQgdHJhbnNmZXJzCi0gKiBkYXRhIGRlZmluZWQgYnkgdGhlIGNsYXNzIDxjb2RlPk15VHlwZTwvY29kZT4uPC9wPgotICogCi0gKiA8cHJlPjxjb2RlPgotICogcHVibGljIGNsYXNzIE15VHlwZSB7Ci0gKglwdWJsaWMgU3RyaW5nIGZpbGVOYW1lOwotICoJcHVibGljIGxvbmcgZmlsZUxlbmd0aDsKLSAqCXB1YmxpYyBsb25nIGxhc3RNb2RpZmllZDsKLSAqIH0KLSAqIDwvY29kZT48L3ByZT4KLSAqIAotICogPGNvZGU+PHByZT4KLSAqIHB1YmxpYyBjbGFzcyBNeVR5cGVUcmFuc2ZlciBleHRlbmRzIEJ5dGVBcnJheVRyYW5zZmVyIHsKLSAqCQotICoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE1ZVFlQRU5BTUUgPSAibXlfdHlwZV9uYW1lIjsKLSAqCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNWVRZUEVJRCA9IHJlZ2lzdGVyVHlwZShNWVRZUEVOQU1FKTsKLSAqCXByaXZhdGUgc3RhdGljIE15VHlwZVRyYW5zZmVyIF9pbnN0YW5jZSA9IG5ldyBNeVR5cGVUcmFuc2ZlcigpOwotICogCi0gKiBwcml2YXRlIE15VHlwZVRyYW5zZmVyKCkge30KLSAqIAotICogcHVibGljIHN0YXRpYyBNeVR5cGVUcmFuc2ZlciBnZXRJbnN0YW5jZSAoKSB7Ci0gKiAJcmV0dXJuIF9pbnN0YW5jZTsKLSAqIH0KLSAqIHB1YmxpYyB2b2lkIGphdmFUb05hdGl2ZSAoT2JqZWN0IG9iamVjdCwgVHJhbnNmZXJEYXRhIHRyYW5zZmVyRGF0YSkgewotICogCWlmIChvYmplY3QgPT0gbnVsbCB8fCAhKG9iamVjdCBpbnN0YW5jZW9mIE15VHlwZVtdKSkgcmV0dXJuOwotICogCQotICogCWlmIChpc1N1cHBvcnRlZFR5cGUodHJhbnNmZXJEYXRhKSkgewotICogCQlNeVR5cGVbXSBteVR5cGVzID0gKE15VHlwZVtdKSBvYmplY3Q7CQotICogCQl0cnkgewotICogCQkJLy8gd3JpdGUgZGF0YSB0byBhIGJ5dGUgYXJyYXkgYW5kIHRoZW4gYXNrIHN1cGVyIHRvIGNvbnZlcnQgdG8gcE1lZGl1bQotICogCQkJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKLSAqIAkJCURhdGFPdXRwdXRTdHJlYW0gd3JpdGVPdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShvdXQpOwotICogCQkJZm9yIChpbnQgaSA9IDAsIGxlbmd0aCA9IG15VHlwZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyAgaSsrKXsKLSAqIAkJCQlieXRlW10gYnVmZmVyID0gbXlUeXBlc1tpXS5maWxlTmFtZS5nZXRCeXRlcygpOwotICogCQkJCXdyaXRlT3V0LndyaXRlSW50KGJ1ZmZlci5sZW5ndGgpOwotICogCQkJCXdyaXRlT3V0LndyaXRlKGJ1ZmZlcik7Ci0gKiAJCQkJd3JpdGVPdXQud3JpdGVMb25nKG15VHlwZXNbaV0uZmlsZUxlbmd0aCk7Ci0gKiAJCQkJd3JpdGVPdXQud3JpdGVMb25nKG15VHlwZXNbaV0ubGFzdE1vZGlmaWVkKTsKLSAqIAkJCX0KLSAqIAkJCWJ5dGVbXSBidWZmZXIgPSBvdXQudG9CeXRlQXJyYXkoKTsKLSAqIAkJCXdyaXRlT3V0LmNsb3NlKCk7Ci0gKiAKLSAqIAkJCXN1cGVyLmphdmFUb05hdGl2ZShidWZmZXIsIHRyYW5zZmVyRGF0YSk7Ci0gKiAJCQkKLSAqIAkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotICogCQl9Ci0gKiAJfQotICogfQotICogcHVibGljIE9iamVjdCBuYXRpdmVUb0phdmEoVHJhbnNmZXJEYXRhIHRyYW5zZmVyRGF0YSl7CQotICogCi0gKiAJaWYgKGlzU3VwcG9ydGVkVHlwZSh0cmFuc2ZlckRhdGEpKSB7Ci0gKiAJCQotICogCQlieXRlW10gYnVmZmVyID0gKGJ5dGVbXSlzdXBlci5uYXRpdmVUb0phdmEodHJhbnNmZXJEYXRhKTsKLSAqIAkJaWYgKGJ1ZmZlciA9PSBudWxsKSByZXR1cm4gbnVsbDsKLSAqIAkJCi0gKiAJCU15VHlwZVtdIG15RGF0YSA9IG5ldyBNeVR5cGVbMF07Ci0gKiAJCXRyeSB7Ci0gKiAJCQlCeXRlQXJyYXlJbnB1dFN0cmVhbSBpbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShidWZmZXIpOwotICogCQkJRGF0YUlucHV0U3RyZWFtIHJlYWRJbiA9IG5ldyBEYXRhSW5wdXRTdHJlYW0oaW4pOwotICogCQkJd2hpbGUocmVhZEluLmF2YWlsYWJsZSgpID4gMjApIHsKLSAqIAkJCQlNeVR5cGUgZGF0dW0gPSBuZXcgTXlUeXBlKCk7Ci0gKiAJCQkJaW50IHNpemUgPSByZWFkSW4ucmVhZEludCgpOwotICogCQkJCWJ5dGVbXSBuYW1lID0gbmV3IGJ5dGVbc2l6ZV07Ci0gKiAJCQkJcmVhZEluLnJlYWQobmFtZSk7Ci0gKiAJCQkJZGF0dW0uZmlsZU5hbWUgPSBuZXcgU3RyaW5nKG5hbWUpOwotICogCQkJCWRhdHVtLmZpbGVMZW5ndGggPSByZWFkSW4ucmVhZExvbmcoKTsKLSAqIAkJCQlkYXR1bS5sYXN0TW9kaWZpZWQgPSByZWFkSW4ucmVhZExvbmcoKTsKLSAqIAkJCQlNeVR5cGVbXSBuZXdNeURhdGEgPSBuZXcgTXlUeXBlW215RGF0YS5sZW5ndGggKyAxXTsKLSAqIAkJCQlTeXN0ZW0uYXJyYXljb3B5KG15RGF0YSwgMCwgbmV3TXlEYXRhLCAwLCBteURhdGEubGVuZ3RoKTsKLSAqIAkJCQluZXdNeURhdGFbbXlEYXRhLmxlbmd0aF0gPSBkYXR1bTsKLSAqIAkJCQlteURhdGEgPSBuZXdNeURhdGE7Ci0gKiAJCQl9Ci0gKiAJCQlyZWFkSW4uY2xvc2UoKTsKLSAqIAkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKLSAqIAkJCXJldHVybiBudWxsOwotICogCQl9Ci0gKiAJCXJldHVybiBteURhdGE7Ci0gKiAJfQotICogCi0gKiAJcmV0dXJuIG51bGw7Ci0gKiB9Ci0gKiBwcm90ZWN0ZWQgU3RyaW5nW10gZ2V0VHlwZU5hbWVzKCl7Ci0gKiAJcmV0dXJuIG5ldyBTdHJpbmdbXXtNWVRZUEVOQU1FfTsKLSAqIH0KLSAqIHByb3RlY3RlZCBpbnRbXSBnZXRUeXBlSWRzKCl7Ci0gKiAJcmV0dXJuIG5ldyBpbnRbXSB7TVlUWVBFSUR9OwotICogfQotICogfQotICovCiBwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQnl0ZUFycmF5VHJhbnNmZXIgZXh0ZW5kcyBUcmFuc2ZlciB7CiAJCiBwdWJsaWMgVHJhbnNmZXJEYXRhW10gZ2V0U3VwcG9ydGVkVHlwZXMoKSB7CkBAIC0xMjMsNjEgKzIwLDMwIEBACiB9CiAKIHB1YmxpYyBib29sZWFuIGlzU3VwcG9ydGVkVHlwZShUcmFuc2ZlckRhdGEgdHJhbnNmZXJEYXRhKXsKLQlpZiAodHJhbnNmZXJEYXRhICE9IG51bGwpIHsKLQkJaW50W10gdHlwZXM9IGdldFR5cGVJZHMoKTsKLQkJZm9yIChpbnQgaT0gMDsgaSA8IHR5cGVzLmxlbmd0aDsgaSsrKSB7Ci0JCQlpZiAodHJhbnNmZXJEYXRhLnR5cGUgPT0gdHlwZXNbaV0pCi0JCQkJcmV0dXJuIHRydWU7Ci0JCX0KKwlpZiAodHJhbnNmZXJEYXRhID09IG51bGwpIHJldHVybiBmYWxzZTsKKwlpbnRbXSB0eXBlcz0gZ2V0VHlwZUlkcygpOworCWZvciAoaW50IGk9IDA7IGkgPCB0eXBlcy5sZW5ndGg7IGkrKykgeworCQlpZiAodHJhbnNmZXJEYXRhLnR5cGUgPT0gdHlwZXNbaV0pCisJCQlyZXR1cm4gdHJ1ZTsKIAl9CiAJcmV0dXJuIGZhbHNlOwogfQogCi0vKioKLSAqIFRoaXMgaW1wbGVtZW50YXRpb24gb2YgPGNvZGU+amF2YVRvTmF0aXZlPC9jb2RlPiBjb252ZXJ0cyBhIGphdmEgCi0gKiA8Y29kZT5ieXRlW108L2NvZGU+IHRvIGEgcGxhdGZvcm0gc3BlY2lmaWMgcmVwcmVzZW50YXRpb24uICBGb3IgYWRkaXRpb25hbAotICogaW5mb3JtYXRpb24gc2VlIDxjb2RlPlRyYW5zZmVyI2phdmFUb05hdGl2ZTwvY29kZT4uCi0gKiAKLSAqIEBzZWUgVHJhbnNmZXIjamF2YVRvTmF0aXZlCi0gKiAKLSAqIEBwYXJhbSBvYmplY3QgYSBqYXZhIDxjb2RlPmJ5dGVbXTwvY29kZT4gY29udGFpbmluZyB0aGUgZGF0YSB0byBiZSBjb252ZXJ0ZWQKLSAqIEBwYXJhbSB0cmFuc2ZlckRhdGEgYW4gZW1wdHkgPGNvZGU+VHJhbnNmZXJEYXRhPC9jb2RlPiBvYmplY3Q7IHRoaXMKLSAqICBvYmplY3Qgd2lsbCBiZSBmaWxsZWQgaW4gb24gcmV0dXJuIHdpdGggdGhlIHBsYXRmb3JtIHNwZWNpZmljIGZvcm1hdCBvZiB0aGUgZGF0YQotICovCiBwcm90ZWN0ZWQgdm9pZCBqYXZhVG9OYXRpdmUgKE9iamVjdCBvYmplY3QsIFRyYW5zZmVyRGF0YSB0cmFuc2ZlckRhdGEpIHsKIAlpZiAoKG9iamVjdCA9PSBudWxsKSB8fCAhKG9iamVjdCBpbnN0YW5jZW9mIGJ5dGVbXSkgfHwgIShpc1N1cHBvcnRlZFR5cGUodHJhbnNmZXJEYXRhKSkpIHsKLQkJdHJhbnNmZXJEYXRhLnJlc3VsdCA9IDA7CisJCXRyYW5zZmVyRGF0YS5yZXN1bHQgPSAtMTsKIAkJcmV0dXJuOwogCX0KLQlieXRlW10gYnVmZmVyPSAoYnl0ZVtdKW9iamVjdDsKLQkvKgotCXRyYW5zZmVyRGF0YS5wVmFsdWUgPSBPUy5nX21hbGxvYyhidWZmZXIubGVuZ3RoKTsKLQlPUy5tZW1tb3ZlKHRyYW5zZmVyRGF0YS5wVmFsdWUsIGJ1ZmZlciwgYnVmZmVyLmxlbmd0aCk7Ci0JKi8KLQl0cmFuc2ZlckRhdGEuZGF0YT0gYnVmZmVyOwotCXRyYW5zZmVyRGF0YS5sZW5ndGggPSBidWZmZXIubGVuZ3RoOwotCS8vdHJhbnNmZXJEYXRhLmZvcm1hdCA9IDg7Ci0JdHJhbnNmZXJEYXRhLnJlc3VsdCA9IDE7CisJYnl0ZVtdIG9yaWcgPSAoYnl0ZVtdKW9iamVjdDsKKwlieXRlW10gYnVmZmVyPSBuZXcgYnl0ZVtvcmlnLmxlbmd0aF07CisJU3lzdGVtLmFycmF5Y29weShvcmlnLCAwLCBidWZmZXIsIDAsIG9yaWcubGVuZ3RoKTsKKwl0cmFuc2ZlckRhdGEuZGF0YSA9IGJ1ZmZlcjsKKwl0cmFuc2ZlckRhdGEucmVzdWx0ID0gMDsKIH0KIAotLyoqCi0gKiBUaGlzIGltcGxlbWVudGF0aW9uIG9mIDxjb2RlPm5hdGl2ZVRvSmF2YTwvY29kZT4gY29udmVydHMgYSBwbGF0Zm9ybSBzcGVjaWZpYyAKLSAqIHJlcHJlc2VudGF0aW9uIG9mIGEgYnl0ZSBhcnJheSB0byBhIGphdmEgPGNvZGU+Ynl0ZVtdPC9jb2RlPi4gICAKLSAqIEZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHNlZSA8Y29kZT5UcmFuc2ZlciNuYXRpdmVUb0phdmE8L2NvZGU+LgotICogCi0gKiBAc2VlIFRyYW5zZmVyI25hdGl2ZVRvSmF2YQotICogCi0gKiBAcGFyYW0gdHJhbnNmZXJEYXRhIHRoZSBwbGF0Zm9ybSBzcGVjaWZpYyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGF0YSB0byBiZSAKLSAqIGJlZW4gY29udmVydGVkCi0gKiBAcmV0dXJuIGEgamF2YSA8Y29kZT5ieXRlW108L2NvZGU+IGNvbnRhaW5pbmcgdGhlIGNvbnZlcnRlZCBkYXRhIGlmIHRoZSAKLSAqIGNvbnZlcnNpb24gd2FzIHN1Y2Nlc3NmdWw7IG90aGVyd2lzZSBudWxsCi0gKi8KIHByb3RlY3RlZCBPYmplY3QgbmF0aXZlVG9KYXZhKFRyYW5zZmVyRGF0YSB0cmFuc2ZlckRhdGEpIHsKLQlpZiAoICFpc1N1cHBvcnRlZFR5cGUodHJhbnNmZXJEYXRhKSB8fCAgdHJhbnNmZXJEYXRhLmRhdGEgPT0gbnVsbCApIHJldHVybiBudWxsOwotCWludCBuPSB0cmFuc2ZlckRhdGEubGVuZ3RoOwotCWJ5dGVbXSBidWZmZXI9IG5ldyBieXRlW25dOwotCVN5c3RlbS5hcnJheWNvcHkodHJhbnNmZXJEYXRhLmRhdGEsIDAsIGJ1ZmZlciwgMCwgbik7Ci0JcmV0dXJuIGJ1ZmZlcjsKKwlpZiAoIWlzU3VwcG9ydGVkVHlwZSh0cmFuc2ZlckRhdGEpKSByZXR1cm4gbnVsbDsKKwlyZXR1cm4gdHJhbnNmZXJEYXRhLmRhdGE7CiB9CiAKLX0KK30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZG5kL0NsaXBib2FyZC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgRHJhZyBhbmQgRHJvcC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2RuZC9DbGlwYm9hcmQuamF2YQppbmRleCA3MWRlYzk1Li44YjU1NGQ1IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZG5kL0NsaXBib2FyZC5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIERyYWcgYW5kIERyb3AvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9kbmQvQ2xpcGJvYXJkLmphdmEKQEAgLTksMzUgKzksMTMgQEAKIAogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5NYWNVdGlsOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uT1M7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5DRlJhbmdlOwogCi0KLS8qKgotICogVGhlIDxjb2RlPkNsaXBib2FyZDwvY29kZT4gcHJvdmlkZXMgYSBtZWNoYW5pc20gZm9yIHRyYW5zZmVycmluZyBkYXRhIGZyb20gb25lCi0gKiBhcHBsaWNhdGlvbiB0byBhbm90aGVyIG9yIHdpdGhpbiBhbiBhcHBsaWNhdGlvbi4KLSAqIAotICogPHA+SU1QT1JUQU5UOiBUaGlzIGNsYXNzIGlzIDxlbT5ub3Q8L2VtPiBpbnRlbmRlZCB0byBiZSBzdWJjbGFzc2VkLjwvcD4KLSAqLwogcHVibGljIGNsYXNzIENsaXBib2FyZCB7CiAJCiAJcHJpdmF0ZSBEaXNwbGF5IGRpc3BsYXk7CiAKLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLiAgQ3JlYXRpbmcgYW4gaW5zdGFuY2Ugb2YgYSBDbGlwYm9hcmQKLSAqIG1heSBjYXVzZSBzeXN0ZW0gcmVzb3VyY2VzIHRvIGJlIGFsbG9jYXRlZCBkZXBlbmRpbmcgb24gdGhlIHBsYXRmb3JtLiAgSXQgaXMgdGhlcmVmb3JlCi0gKiBtYW5kYXRvcnkgdGhhdCB0aGUgQ2xpcGJvYXJkIGluc3RhbmNlIGJlIGRpc3Bvc2VkIHdoZW4gbm8gbG9uZ2VyIHJlcXVpcmVkLgotICoKLSAqIEBwYXJhbSBkaXNwbGF5IHRoZSBkaXNwbGF5IG9uIHdoaWNoIHRvIGFsbG9jYXRlIHRoZSBjbGlwYm9hcmQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBDbGlwYm9hcmQjZGlzcG9zZQotICogQHNlZSBDbGlwYm9hcmQjY2hlY2tTdWJjbGFzcwotICovCiBwdWJsaWMgQ2xpcGJvYXJkKERpc3BsYXkgZGlzcGxheSkgewkKIAljaGVja1N1YmNsYXNzICgpOwogCWlmIChkaXNwbGF5ID09IG51bGwpIHsKQEAgLTUyLDMzICszMCw2IEBACiAJdGhpcy5kaXNwbGF5ID0gZGlzcGxheTsKIH0KIAotLyoqCi0gKiBDaGVja3MgdGhhdCB0aGlzIGNsYXNzIGNhbiBiZSBzdWJjbGFzc2VkLgotICogPHA+Ci0gKiBUaGUgU1dUIGNsYXNzIGxpYnJhcnkgaXMgaW50ZW5kZWQgdG8gYmUgc3ViY2xhc3NlZCAKLSAqIG9ubHkgYXQgc3BlY2lmaWMsIGNvbnRyb2xsZWQgcG9pbnRzLiBUaGlzIG1ldGhvZCBlbmZvcmNlcyB0aGlzCi0gKiBydWxlIHVubGVzcyBpdCBpcyBvdmVycmlkZGVuLgotICogPC9wPjxwPgotICogPGVtPklNUE9SVEFOVDo8L2VtPiBCeSBwcm92aWRpbmcgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhpcwotICogbWV0aG9kIHRoYXQgYWxsb3dzIGEgc3ViY2xhc3Mgb2YgYSBjbGFzcyB3aGljaCBkb2VzIG5vdCAKLSAqIG5vcm1hbGx5IGFsbG93IHN1YmNsYXNzaW5nIHRvIGJlIGNyZWF0ZWQsIHRoZSBpbXBsZW1lbnRlcgotICogYWdyZWVzIHRvIGJlIGZ1bGx5IHJlc3BvbnNpYmxlIGZvciB0aGUgZmFjdCB0aGF0IGFueSBzdWNoCi0gKiBzdWJjbGFzcyB3aWxsIGxpa2VseSBmYWlsIGJldHdlZW4gU1dUIHJlbGVhc2VzIGFuZCB3aWxsIGJlCi0gKiBzdHJvbmdseSBwbGF0Zm9ybSBzcGVjaWZpYy4gTm8gc3VwcG9ydCBpcyBwcm92aWRlZCBmb3IKLSAqIHVzZXItd3JpdHRlbiBjbGFzc2VzIHdoaWNoIGFyZSBpbXBsZW1lbnRlZCBpbiB0aGlzIGZhc2hpb24uCi0gKiA8L3A+PHA+Ci0gKiBUaGUgYWJpbGl0eSB0byBzdWJjbGFzcyBvdXRzaWRlIG9mIHRoZSBhbGxvd2VkIFNXVCBjbGFzc2VzCi0gKiBpcyBpbnRlbmRlZCBwdXJlbHkgdG8gZW5hYmxlIHRob3NlIG5vdCBvbiB0aGUgU1dUIGRldmVsb3BtZW50Ci0gKiB0ZWFtIHRvIGltcGxlbWVudCBwYXRjaGVzIGluIG9yZGVyIHRvIGdldCBhcm91bmQgc3BlY2lmaWMKLSAqIGxpbWl0YXRpb25zIGluIGFkdmFuY2Ugb2Ygd2hlbiB0aG9zZSBsaW1pdGF0aW9ucyBjYW4gYmUKLSAqIGFkZHJlc3NlZCBieSB0aGUgdGVhbS4gU3ViY2xhc3Npbmcgc2hvdWxkIG5vdCBiZSBhdHRlbXB0ZWQKLSAqIHdpdGhvdXQgYW4gaW50aW1hdGUgYW5kIGRldGFpbGVkIHVuZGVyc3RhbmRpbmcgb2YgdGhlIGhpZXJhcmNoeS4KLSAqIDwvcD4KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqLwogcHJvdGVjdGVkIHZvaWQgY2hlY2tTdWJjbGFzcyAoKSB7CiAJU3RyaW5nIG5hbWUgPSBnZXRDbGFzcygpLmdldE5hbWUgKCk7CiAJU3RyaW5nIHZhbGlkTmFtZSA9IENsaXBib2FyZC5jbGFzcy5nZXROYW1lKCk7CkBAIC04NiwxOTQgKzM3LDg3IEBACiAJCURORC5lcnJvciAoU1dULkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MpOwogCX0KIH0KLS8qKgotICogRGlzcG9zZXMgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0gcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY2xpcGJvYXJkLiAKLSAqIFRoZSBkYXRhIHdpbGwgc3RpbGwgYmUgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0gY2xpcGJvYXJkIGFmdGVyIHRoZSBkaXNwb3NlIAotICogbWV0aG9kIGlzIGNhbGxlZC4gIAotICogCi0gKiA8cD5OT1RFOiBPbiBzb21lIHBsYXRmb3JtcyB0aGUgZGF0YSB3aWxsIG5vdCBiZSBhdmFpbGFibGUgb25jZSB0aGUgYXBwbGljYXRpb24KLSAqIGhhcyBleGl0ZWQgb3IgdGhlIGRpc3BsYXkgaGFzIGJlZW4gZGlzcG9zZWQuPC9wPgotICovCisKIHB1YmxpYyB2b2lkIGRpc3Bvc2UgKCkgewogCWRpc3BsYXkgPSBudWxsOwogfQotLyoqCi0gKiBSZXRyaWV2ZSB0aGUgZGF0YSBvZiB0aGUgc3BlY2lmaWVkIHR5cGUgY3VycmVudGx5IGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtIGNsaXBib2FyZC4gIFJlZmVyIHRvIHRoZSAKLSAqIHNwZWNpZmljIHN1YmNsYXNzIG9mIDxjb2RlPlRyYW1zZmVyPC9jb2RlPiB0byBkZXRlcm1pbmUgdGhlIHR5cGUgb2Ygb2JqZWN0IHJldHVybmVkLgotICogCi0gKiA8cD5UaGUgZm9sbG93aW5nIHNuaXBwZXQgc2hvd3MgdGV4dCBhbmQgUlRGIHRleHQgYmVpbmcgcmV0cmlldmVkIGZyb20gdGhlIGNsaXBib2FyZDo8L3A+Ci0gKiAKLSAqICAgIDxjb2RlPjxwcmU+Ci0gKiAgICBDbGlwYm9hcmQgY2xpcGJvYXJkID0gbmV3IENsaXBib2FyZChkaXNwbGF5KTsKLSAqICAgIFRleHRUcmFuc2ZlciB0ZXh0VHJhbnNmZXIgPSBUZXh0VHJhbnNmZXIuZ2V0SW5zdGFuY2UoKTsKLSAqICAgIFN0cmluZyB0ZXh0RGF0YSA9IChTdHJpbmcpY2xpcGJvYXJkLmdldENvbnRlbnRzKHRleHRUcmFuc2Zlcik7Ci0gKiAgICBpZiAodGV4dERhdGEgIT0gbnVsbCkgU3lzdGVtLm91dC5wcmludGxuKCJUZXh0IGlzICIrdGV4dERhdGEpOwotICogICAgUlRGVHJhbnNmZXIgcnRmVHJhbnNmZXIgPSBSVEZUcmFuc2Zlci5nZXRJbnN0YW5jZSgpOwotICogICAgU3RyaW5nIHJ0ZkRhdGEgPSAoU3RyaW5nKWNsaXBib2FyZC5nZXRDb250ZW50cyhydGZUcmFuc2Zlcik7Ci0gKiAgICBpZiAocnRmRGF0YSAhPSBudWxsKSBTeXN0ZW0ub3V0LnByaW50bG4oIlJURiBUZXh0IGlzICIrcnRmRGF0YSk7Ci0gKiAgICBjbGlwYm9hcmQuZGlzcG9zZSgpOwotICogICAgPC9jb2RlPjwvcHJlPgotICogCi0gKiBAc2VlIFRyYW5zZmVyCi0gKiAKLSAqIEBwYXJhbSB0cmFuc2ZlciB0aGUgdHJhbnNmZXIgYWdlbnQgZm9yIHRoZSB0eXBlIG9mIGRhdGEgYmVpbmcgcmVxdWVzdGVkCi0gKiAKLSAqIEByZXR1cm4gdGhlIGRhdGEgb2J0YWluZWQgZnJvbSB0aGUgY2xpcGJvYXJkIG9yIG51bGwgaWYgbm8gZGF0YSBvZiB0aGlzIHR5cGUgaXMgYXZhaWxhYmxlCi0gKi8KKwogcHVibGljIE9iamVjdCBnZXRDb250ZW50cyhUcmFuc2ZlciB0cmFuc2ZlcikgewotCQotCWlmIChkaXNwbGF5LmlzRGlzcG9zZWQoKSkKLQkJcmV0dXJuIG51bGw7CisJaWYgKGRpc3BsYXkgPT0gbnVsbCkgRE5ELmVycm9yKFNXVC5FUlJPUl9XSURHRVRfRElTUE9TRUQpOworCWlmIChkaXNwbGF5LmlzRGlzcG9zZWQoKSkgRE5ELmVycm9yKFNXVC5FUlJPUl9ERVZJQ0VfRElTUE9TRUQpOworCWlmICh0cmFuc2ZlciA9PSBudWxsKSBETkQuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCQkKLQlpZiAodHJhbnNmZXIgPT0gbnVsbCkKLQkJcmV0dXJuIG51bGw7Ci0JCQotCWludFtdIHNjcmFwSGFuZGxlPSBuZXcgaW50WzFdOworCWludFtdIHNjcmFwSGFuZGxlID0gbmV3IGludFsxXTsKIAlPUy5HZXRDdXJyZW50U2NyYXAoc2NyYXBIYW5kbGUpOwogCWludCBzY3JhcD0gc2NyYXBIYW5kbGVbMF07CiAJCQogCS8vIERvZXMgQ2xpcGJvYXJkIGhhdmUgZGF0YSBpbiByZXF1aXJlZCBmb3JtYXQ/Ci0JaW50W10gdHlwZUlkcz0gdHJhbnNmZXIuZ2V0VHlwZUlkcygpOworCWludFtdIHR5cGVJZHMgPSB0cmFuc2Zlci5nZXRUeXBlSWRzKCk7CiAJZm9yIChpbnQgaT0gMDsgaSA8IHR5cGVJZHMubGVuZ3RoOyBpKyspIHsKLQkJaW50IGZsYXZvclR5cGU9IHR5cGVJZHNbaV07Ci0JCWludFtdIHNpemU9IG5ldyBpbnRbMV07Ci0JCWlmIChPUy5HZXRTY3JhcEZsYXZvclNpemUoc2NyYXAsIGZsYXZvclR5cGUsIHNpemUpID09IE9TLmtOb0VycikgeworCQlpbnQgdHlwZSA9IHR5cGVJZHNbaV07CisJCWludFtdIHNpemUgPSBuZXcgaW50WzFdOworCQlpZiAoT1MuR2V0U2NyYXBGbGF2b3JTaXplKHNjcmFwLCB0eXBlLCBzaXplKSA9PSBPUy5ub0VycikgewogCQkJaWYgKHNpemVbMF0gPiAwKSB7Ci0JCQkJCi0JCQkJVHJhbnNmZXJEYXRhIHRkYXRhPSBuZXcgVHJhbnNmZXJEYXRhKCk7Ci0JCi0JCQkJdGRhdGEudHlwZT0gZmxhdm9yVHlwZTsJCQotCQkJCXRkYXRhLmRhdGE9IG5ldyBieXRlW3NpemVbMF1dOwotCQkJCU9TLkdldFNjcmFwRmxhdm9yRGF0YShzY3JhcCwgZmxhdm9yVHlwZSwgc2l6ZSwgdGRhdGEuZGF0YSk7Ci0JCQkJdGRhdGEubGVuZ3RoPSBzaXplWzBdOwotCQkJCQotCQkJCU9iamVjdCByZXN1bHQ9IHRyYW5zZmVyLm5hdGl2ZVRvSmF2YSh0ZGF0YSk7Ci0JCQkJaWYgKHJlc3VsdCAhPSBudWxsKQotCQkJCQlyZXR1cm4gcmVzdWx0OworCQkJCVRyYW5zZmVyRGF0YSB0ZGF0YSA9IG5ldyBUcmFuc2ZlckRhdGEoKTsKKwkJCQl0ZGF0YS50eXBlID0gdHlwZTsJCQorCQkJCXRkYXRhLmRhdGEgPSBuZXcgYnl0ZVtzaXplWzBdXTsKKwkJCQlPUy5HZXRTY3JhcEZsYXZvckRhdGEoc2NyYXAsIHR5cGUsIHNpemUsIHRkYXRhLmRhdGEpOworCQkJCXJldHVybiB0cmFuc2Zlci5uYXRpdmVUb0phdmEodGRhdGEpOwogCQkJfQogCQl9CiAJfQkJCi0JCiAJcmV0dXJuIG51bGw7CS8vIE5vIGRhdGEgYXZhaWxhYmxlIGZvciB0aGlzIHRyYW5zZmVyCiB9Ci0vKioKLSAqIFBsYWNlIGRhdGEgb2YgdGhlIHNwZWNpZmllZCB0eXBlIG9uIHRoZSBzeXN0ZW0gY2xpcGJvYXJkLiAgTW9yZSB0aGFuIG9uZSB0eXBlIG9mCi0gKiBkYXRhIGNhbiBiZSBwbGFjZWQgb24gdGhlIHN5c3RlbSBjbGlwYm9hcmQgYXQgdGhlIHNhbWUgdGltZS4gIFNldHRpbmcgdGhlIGRhdGEgCi0gKiBjbGVhcnMgYW55IHByZXZpb3VzIGRhdGEgb2YgdGhlIHNhbWUgdHlwZSBmcm9tIHRoZSBzeXN0ZW0gY2xpcGJvYXJkIGFuZCBhbHNvCi0gKiBjbGVhcnMgZGF0YSBvZiBhbnkgb3RoZXIgdHlwZSBjdXJyZW50bHkgb24gdGhlIHN5c3RlbSBjbGlwYm9hcmQuCi0gKiAKLSAqIDxwPk5PVEU6IE9uIHNvbWUgcGxhdGZvcm1zLCB0aGUgZGF0YSBpcyBpbW1lZGlhdGVseSBjb3BpZWQgdG8gdGhlIHN5c3RlbQotICogY2xpcGJvYXJkIGJ1dCBvbiBvdGhlciBwbGF0Zm9ybXMgaXQgaXMgcHJvdmlkZWQgdXBvbiByZXF1ZXN0LiAgQXMgYSByZXN1bHQsIGlmIHRoZSAKLSAqIGFwcGxpY2F0aW9uIG1vZGlmZXMgdGhlIGRhdGEgb2JqZWN0IGl0IGhhcyBzZXQgb24gdGhlIGNsaXBib2FyZCwgdGhhdCBtb2RpZmljYXRpb24gCi0gKiBtYXkgb3IgbWF5IG5vdCBiZSBhdmFpbGFibGUgd2hlbiB0aGUgZGF0YSBpcyBzdWJzZXF1ZW50bHkgcmVxdWVzdGVkLjwvcD4KLSAqCi0gKiA8cD5UaGUgZm9sbG93aW5nIHNuaXBwZXQgc2hvd3MgdGV4dCBhbmQgUlRGIHRleHQgYmVpbmcgc2V0IG9uIHRoZSBjbGlwYm9hcmQ6PC9wPgotICogCi0gKiA8Y29kZT48cHJlPgotICogCUNsaXBib2FyZCBjbGlwYm9hcmQgPSBuZXcgQ2xpcGJvYXJkKGRpc3BsYXkpOwotICoJCVN0cmluZyB0ZXh0RGF0YSA9ICJIZWxsbyBXb3JsZCI7Ci0gKgkJU3RyaW5nIHJ0ZkRhdGEgPSAie1xccnRmMVxcYlxcaSBIZWxsbyBXb3JsZH0iOwotICoJCVRleHRUcmFuc2ZlciB0ZXh0VHJhbnNmZXIgPSBUZXh0VHJhbnNmZXIuZ2V0SW5zdGFuY2UoKTsKLSAqCQlSVEZUcmFuc2ZlciBydGZUcmFuc2ZlciA9IFJURlRyYW5zZmVyLmdldEluc3RhbmNlKCk7Ci0gKgkJY2xpcGJvYXJkLnNldENvbnRlbnRzKG5ldyBPYmplY3RbXXt0ZXh0RGF0YSwgcnRmRGF0YX0sIG5ldyBUcmFuc2Zlcltde3RleHRUcmFuc2ZlciwgcnRmVHJhbnNmZXJ9KTsKLSAqCQljbGlwYm9hcmQuZGlzcG9zZSgpOwotICogPC9jb2RlPjwvcHJlPgotICoKLSAqIEBwYXJhbSBkYXRhIHRoZSBkYXRhIHRvIGJlIHNldCBpbiB0aGUgY2xpcGJvYXJkCi0gKiBAcGFyYW0gZGF0YVR5cGVzIHRoZSB0cmFuc2ZlciBhZ2VudHMgdGhhdCB3aWxsIGNvbnZlcnQgdGhlIGRhdGEgdG8gaXRzIHBsYXRmb3JtIAotICogc3BlY2lmaWMgZm9ybWF0OyBlYWNoIGVudHJ5IGluIHRoZSBkYXRhIGFycmF5IG11c3QgaGF2ZSBhIGNvcnJlc3BvbmRpbmcgZGF0YVR5cGUKLSAqIAotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiBkYXRhIGlzIG51bGwgb3IgZGF0YXR5cGVzIGlzIG51bGwgCi0gKiAgICAgICAgICBvciB0aGUgbGVuZ3RoIG9mIGRhdGEgaXMgbm90IHRoZSBzYW1lIGFzIHRoZSBsZW5ndGggb2YgZGF0YVR5cGVzPC9saT4KLSAqIDwvdWw+Ci0gKiAgQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfQ0FOTk9UX1NFVF9DTElQQk9BUkQgLSBpZiB0aGUgY2xpcGJvYXJkIGlzIGxvY2tlZCBvciAKLSAqICAgICAgICAgb3RoZXJ3aXNlIHVuYXZhaWxhYmxlPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0Q29udGVudHMoT2JqZWN0W10gZGF0YSwgVHJhbnNmZXJbXSBkYXRhVHlwZXMpIHsKLQkKLQlpZiAoZGF0YSA9PSBudWxsKSB7CisJaWYgKGRpc3BsYXkgPT0gbnVsbCkgRE5ELmVycm9yKFNXVC5FUlJPUl9XSURHRVRfRElTUE9TRUQpOworCWlmIChkaXNwbGF5LmlzRGlzcG9zZWQoKSkgRE5ELmVycm9yKFNXVC5FUlJPUl9ERVZJQ0VfRElTUE9TRUQpOworCWlmIChkYXRhID09IG51bGwgfHwgZGF0YVR5cGVzID09IG51bGwgfHwgZGF0YS5sZW5ndGggIT0gZGF0YVR5cGVzLmxlbmd0aCkgewogCQlETkQuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwogCX0KLQlpZiAoZGF0YVR5cGVzID09IG51bGwgfHwgZGF0YS5sZW5ndGggIT0gZGF0YVR5cGVzLmxlbmd0aCkgewotCQlETkQuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwotCX0KLQkKLQlpZiAoZGlzcGxheS5pc0Rpc3Bvc2VkKCkpCi0JCURORC5lcnJvcihETkQuRVJST1JfQ0FOTk9UX1NFVF9DTElQQk9BUkQpOwogCQogCU9TLkNsZWFyQ3VycmVudFNjcmFwKCk7Ci0JaW50W10gc2NyYXBIYW5kbGU9IG5ldyBpbnRbMV07CisJaW50W10gc2NyYXBIYW5kbGUgPSBuZXcgaW50WzFdOwogCU9TLkdldEN1cnJlbnRTY3JhcChzY3JhcEhhbmRsZSk7Ci0JaW50IHNjcmFwPSBzY3JhcEhhbmRsZVswXTsKLQkJCi0JaW50IHN0YXR1cz0gMTsKLQkKKwlpbnQgc2NyYXAgPSBzY3JhcEhhbmRsZVswXTsKIAkvLyBjb3B5IGRhdGEgZGlyZWN0bHkgb3ZlciB0byBTeXN0ZW0gY2xpcGJvYXJkIChub3QgZGVmZXJyZWQpCiAJZm9yIChpbnQgaT0gMDsgaSA8IGRhdGFUeXBlcy5sZW5ndGg7IGkrKykgewotCQlpbnRbXSBpZHM9IGRhdGFUeXBlc1tpXS5nZXRUeXBlSWRzKCk7CisJCWludFtdIGlkcyA9IGRhdGFUeXBlc1tpXS5nZXRUeXBlSWRzKCk7CiAJCWZvciAoaW50IGo9IDA7IGogPCBpZHMubGVuZ3RoOyBqKyspIHsKLQkJCVRyYW5zZmVyRGF0YSB0cmFuc2ZlckRhdGE9IG5ldyBUcmFuc2ZlckRhdGEoKTsKLQkJCS8qIFVzZSB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIGZvciB0aGUgZGVmYXVsdCBsb2NhbGUgKi8KLQkJCXRyYW5zZmVyRGF0YS50eXBlPSBpZHNbal07CisJCQlUcmFuc2ZlckRhdGEgdHJhbnNmZXJEYXRhID0gbmV3IFRyYW5zZmVyRGF0YSgpOworCQkJdHJhbnNmZXJEYXRhLnR5cGUgPSBpZHNbal07CiAJCQlkYXRhVHlwZXNbaV0uamF2YVRvTmF0aXZlKGRhdGFbaV0sIHRyYW5zZmVyRGF0YSk7Ci0JCQlpZiAodHJhbnNmZXJEYXRhLnJlc3VsdCA9PSAxKSB7Ci0JCQkJLyoKLQkJCQlpZiAodHJhbnNmZXJEYXRhLmZvcm1hdCA9PSA4KSB7Ci0JCQkJCWJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVt0cmFuc2ZlckRhdGEubGVuZ3RoXTsKLQkJCQkJT1MubWVtbW92ZShidWZmZXIsIHRyYW5zZmVyRGF0YS5wVmFsdWUsIHRyYW5zZmVyRGF0YS5sZW5ndGgpOwotCQkJCQlieXRlW10gYk5hbWUgPSBDb252ZXJ0ZXIud2NzVG9NYmNzKG51bGwsIG5hbWVzW2pdLCB0cnVlKTsKLQkJCQkJc3RhdHVzID0gT1MuWG1DbGlwYm9hcmRDb3B5KHhEaXNwbGF5LCB4V2luZG93LCBpdGVtX2lkWzBdLCBiTmFtZSwgYnVmZmVyLCB0cmFuc2ZlckRhdGEubGVuZ3RoLCAwLCBudWxsKTsKLQkJCQl9Ci0JCQkJKi8KLQkJCQlzdGF0dXM9IE9TLlB1dFNjcmFwRmxhdm9yKHNjcmFwLCB0cmFuc2ZlckRhdGEudHlwZSwgMCwgdHJhbnNmZXJEYXRhLmRhdGEpOworCQkJaWYgKHRyYW5zZmVyRGF0YS5yZXN1bHQgIT0gT1Mubm9FcnIpCisJCQkJRE5ELmVycm9yKERORC5FUlJPUl9DQU5OT1RfU0VUX0NMSVBCT0FSRCk7CisJCQlpZiAoT1MuUHV0U2NyYXBGbGF2b3Ioc2NyYXAsIHRyYW5zZmVyRGF0YS50eXBlLCAwLCB0cmFuc2ZlckRhdGEuZGF0YS5sZW5ndGgsIHRyYW5zZmVyRGF0YS5kYXRhKSAhPSBPUy5ub0Vycil7CisJCQkJRE5ELmVycm9yKERORC5FUlJPUl9DQU5OT1RfU0VUX0NMSVBCT0FSRCk7CiAJCQl9CiAJCX0KIAl9Ci0JCi0JaWYgKHN0YXR1cyAhPSBPUy5rTm9FcnIpCi0JCURORC5lcnJvcihETkQuRVJST1JfQ0FOTk9UX1NFVF9DTElQQk9BUkQpOwogfQotLyoqCi0gKiBSZXR1cm5zIGEgcGxhdGZvcm0gc3BlY2lmaWMgbGlzdCBvZiB0aGUgZGF0YSB0eXBlcyBjdXJyZW50bHkgYXZhaWxhYmxlIG9uIHRoZSAKLSAqIHN5c3RlbSBjbGlwYm9hcmQuCi0gKiAKLSAqIDxwPk5vdGU6IDxjb2RlPmdldEF2YWlsYWJsZVR5cGVOYW1lczwvY29kZT4gaXMgYSB1dGlsaXR5IGZvciB3cml0aW5nIGEgVHJhbnNmZXIgCi0gKiBzdWItY2xhc3MuICBJdCBzaG91bGQgTk9UIGJlIHVzZWQgd2l0aGluIGFuIGFwcGxpY2F0aW9uIGJlY2F1c2UgaXQgcHJvdmlkZXMgCi0gKiBwbGF0Zm9ybSBzcGVjaWZpYyBpbmZvcm1hdGlvbi48L3A+Ci0gKiAKLSAqIEByZXR1cm5zIGEgcGxhdGZvcm0gc3BlY2lmaWMgbGlzdCBvZiB0aGUgZGF0YSB0eXBlcyBjdXJyZW50bHkgYXZhaWxhYmxlIG9uIHRoZSAKLSAqIHN5c3RlbSBjbGlwYm9hcmQKLSAqLworCiBwdWJsaWMgU3RyaW5nW10gZ2V0QXZhaWxhYmxlVHlwZU5hbWVzKCkgewotCi0JaWYgKGRpc3BsYXkuaXNEaXNwb3NlZCgpKQotCQlyZXR1cm4gbnVsbDsKKwlpZiAoZGlzcGxheSA9PSBudWxsKSBETkQuZXJyb3IoU1dULkVSUk9SX1dJREdFVF9ESVNQT1NFRCk7CisJaWYgKGRpc3BsYXkuaXNEaXNwb3NlZCgpKSBETkQuZXJyb3IoU1dULkVSUk9SX0RFVklDRV9ESVNQT1NFRCk7CiAJCi0JaW50W10gc2NyYXBIYW5kbGU9IG5ldyBpbnRbMV07CisJaW50W10gc2NyYXBIYW5kbGUgPSBuZXcgaW50WzFdOwogCU9TLkdldEN1cnJlbnRTY3JhcChzY3JhcEhhbmRsZSk7Ci0JaW50IHNjcmFwPSBzY3JhcEhhbmRsZVswXTsKLQkKLQlpbnRbXSBmbGF2b3JDb3VudD0gbmV3IGludFsxXTsKLQlPUy5HZXRTY3JhcEZsYXZvckNvdW50KHNjcmFwLCBmbGF2b3JDb3VudCk7Ci0JCi0JLy9TeXN0ZW0ub3V0LnByaW50bG4oIkNsaXBib2FyZC5nZXRBdmFpbGFibGVUeXBlTmFtZXM6Iik7Ci0JaWYgKGZsYXZvckNvdW50WzBdID4gMCkgewotCQlpbnRbXSBpbmZvPSBuZXcgaW50W2ZsYXZvckNvdW50WzBdICogMl07Ci0JCU9TLkdldFNjcmFwRmxhdm9ySW5mb0xpc3Qoc2NyYXAsIGZsYXZvckNvdW50LCBpbmZvKTsKLQkJaW50IG49IGZsYXZvckNvdW50WzBdOwotCQlTdHJpbmdbXSByZXN1bHQ9IG5ldyBTdHJpbmdbbl07Ci0JCWZvciAoaW50IGk9IDA7IGkgPCBuOyBpKyspIHsKLQkJCWludCBmbGF2b3JUeXBlPSBpbmZvW2kqMl07Ci0JCQlTdHJpbmcgdHlwZT0gTWFjVXRpbC50b1N0cmluZyhmbGF2b3JUeXBlKTsKLQkJCS8vU3lzdGVtLm91dC5wcmludGxuKCIgICIgKyBpICsgIjogIiArIHR5cGUpOwotCQkJcmVzdWx0W2ldPSB0eXBlOwotCQl9Ci0JCXJldHVybiByZXN1bHQ7CisJaW50IHNjcmFwID0gc2NyYXBIYW5kbGVbMF07CQorCWludFtdIGNvdW50ID0gbmV3IGludFsxXTsKKwlPUy5HZXRTY3JhcEZsYXZvckNvdW50KHNjcmFwLCBjb3VudCk7CisJaWYgKGNvdW50IFswXSA9PSAwKSByZXR1cm4gbmV3IFN0cmluZyBbMF07CisJaW50W10gaW5mbyA9IG5ldyBpbnRbY291bnRbMF0gKiAyXTsKKwlPUy5HZXRTY3JhcEZsYXZvckluZm9MaXN0KHNjcmFwLCBjb3VudCwgaW5mbyk7CisJU3RyaW5nW10gcmVzdWx0ID0gbmV3IFN0cmluZ1tjb3VudFswXV07CisJZm9yIChpbnQgaT0gMDsgaSA8IGNvdW50IFswXTsgaSsrKSB7CisJCWludCB0eXBlID0gaW5mb1tpKjJdOworCQlTdHJpbmdCdWZmZXIgc2IgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CisJCXNiLmFwcGVuZCgoY2hhcikoKHR5cGUgJiAweGZmMDAwMDAwKSA+PiAyNCkpOworCQlzYi5hcHBlbmQoKGNoYXIpKCh0eXBlICYgMHgwMGZmMDAwMCkgPj4gMTYpKTsKKwkJc2IuYXBwZW5kKChjaGFyKSgodHlwZSAmIDB4MDAwMGZmMDApID4+IDgpKTsKKwkJc2IuYXBwZW5kKChjaGFyKSgodHlwZSAmIDB4MDAwMDAwZmYpID4+IDApKTsKKwkJcmVzdWx0W2ldID0gc2IudG9TdHJpbmcoKTsKIAl9Ci0KLQlyZXR1cm4gbnVsbDsKKwlyZXR1cm4gcmVzdWx0OwogfQogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgRHJhZyBhbmQgRHJvcC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2RuZC9EcmFnU291cmNlLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZG5kL0RyYWdTb3VyY2UuamF2YQppbmRleCAyNTI3Y2NmLi5kODQ1NzljIDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZG5kL0RyYWdTb3VyY2UuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZG5kL0RyYWdTb3VyY2UuamF2YQpAQCAtODgsNiArODgsMTMgQEAKICAqIDwvZGw+CiAgKi8KIHB1YmxpYyBmaW5hbCBjbGFzcyBEcmFnU291cmNlIGV4dGVuZHMgV2lkZ2V0IHsKKwkKKwkvLyBpbmZvIGZvciByZWdpc3RlcmluZyBhcyBhIGRyYWcgc291cmNlCisJcHJpdmF0ZSBDb250cm9sIGNvbnRyb2w7CisJcHJpdmF0ZSBMaXN0ZW5lciBjb250cm9sTGlzdGVuZXI7CisJcHJpdmF0ZSBUcmFuc2ZlcltdIHRyYW5zZmVyQWdlbnRzID0gbmV3IFRyYW5zZmVyWzBdOworCQorCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBEUkFHU09VUkNFSUQgPSAiRHJhZ1NvdXJjZSI7CiAKIC8qKgogICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5EcmFnU291cmNlPC9jb2RlPiB0byBoYW5kbGUgZHJhZ2dpbmcgZnJvbSB0aGUgc3BlY2lmaWVkIDxjb2RlPkNvbnRyb2w8L2NvZGU+LgpAQCAtMTEyLDYgKzExOSwyNCBAQAogICovCiBwdWJsaWMgRHJhZ1NvdXJjZShDb250cm9sIGNvbnRyb2wsIGludCBzdHlsZSkgewogCXN1cGVyIChjb250cm9sLCBzdHlsZSk7CisJdGhpcy5jb250cm9sID0gY29udHJvbDsKKwlpZiAoY29udHJvbC5nZXREYXRhKERSQUdTT1VSQ0VJRCkgIT0gbnVsbCkKKwkJRE5ELmVycm9yKERORC5FUlJPUl9DQU5OT1RfSU5JVF9EUkFHKTsKKwkJCisJY29udHJvbExpc3RlbmVyID0gbmV3IExpc3RlbmVyICgpIHsKKwkJcHVibGljIHZvaWQgaGFuZGxlRXZlbnQgKEV2ZW50IGV2ZW50KSB7CisJCQlpZiAoZXZlbnQudHlwZSA9PSBTV1QuRGlzcG9zZSl7CisJCQkJRHJhZ1NvdXJjZS50aGlzLmRpc3Bvc2UoKTsKKwkJCX0KKwkJfQorCX07CisJY29udHJvbC5hZGRMaXN0ZW5lciAoU1dULkRpc3Bvc2UsIGNvbnRyb2xMaXN0ZW5lcik7CisJCisJdGhpcy5hZGRMaXN0ZW5lcihTV1QuRGlzcG9zZSwgbmV3IExpc3RlbmVyKCkgeworCQlwdWJsaWMgdm9pZCBoYW5kbGVFdmVudChFdmVudCBlKSB7CisJCQlvbkRpc3Bvc2UoKTsKKwkJfQorCX0pOwogfQogCiAvKioKQEAgLTE0NCw5ICsxNjksMjEgQEAKICAqIEBzZWUgRHJhZ1NvdXJjZUV2ZW50CiAgKi8KIHB1YmxpYyB2b2lkIGFkZERyYWdMaXN0ZW5lcihEcmFnU291cmNlTGlzdGVuZXIgbGlzdGVuZXIpIHsKLQorCWlmIChsaXN0ZW5lciA9PSBudWxsKSBETkQuZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlETkRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IERORExpc3RlbmVyIChsaXN0ZW5lcik7CisJYWRkTGlzdGVuZXIgKERORC5EcmFnU3RhcnQsIHR5cGVkTGlzdGVuZXIpOworCWFkZExpc3RlbmVyIChETkQuRHJhZ0VuZCwgdHlwZWRMaXN0ZW5lcik7CisJYWRkTGlzdGVuZXIgKERORC5EcmFnU2V0RGF0YSwgdHlwZWRMaXN0ZW5lcik7CiB9CiAKK3Byb3RlY3RlZCB2b2lkIGNoZWNrU3ViY2xhc3MgKCkgeworCVN0cmluZyBuYW1lID0gZ2V0Q2xhc3MoKS5nZXROYW1lICgpOworCVN0cmluZyB2YWxpZE5hbWUgPSBEcmFnU291cmNlLmNsYXNzLmdldE5hbWUoKTsKKwlpZiAoIXZhbGlkTmFtZS5lcXVhbHMobmFtZSkpIHsKKwkJRE5ELmVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9TVUJDTEFTUyk7CisJfQorfQorCQogLyoqCiAgKiBSZXR1cm5zIHRoZSBDb250cm9sIHdoaWNoIGlzIHJlZ2lzdGVyZWQgZm9yIHRoaXMgRHJhZ1NvdXJjZS4gIFRoaXMgaXMgdGhlIGNvbnRyb2wgdGhhdCB0aGUgCiAgKiB1c2VyIGNsaWNrcyBpbiB0byBpbml0aWF0ZSBkcmFnZ2luZy4KQEAgLTE1NCwxMSArMTkxLDEyIEBACiAgKiBAcmV0dXJuIHRoZSBDb250cm9sIHdoaWNoIGlzIHJlZ2lzdGVyZWQgZm9yIHRoaXMgRHJhZ1NvdXJjZQogICovCiBwdWJsaWMgQ29udHJvbCBnZXRDb250cm9sICgpIHsKLQlyZXR1cm4gbnVsbDsKKwlyZXR1cm4gY29udHJvbDsKIH0KIAogcHVibGljIERpc3BsYXkgZ2V0RGlzcGxheSAoKSB7Ci0JcmV0dXJuIG51bGw7CisJaWYgKGNvbnRyb2wgPT0gbnVsbCkgRE5ELmVycm9yKFNXVC5FUlJPUl9XSURHRVRfRElTUE9TRUQpOworCXJldHVybiBjb250cm9sLmdldERpc3BsYXkgKCk7CiB9CiAvKioKICAqIFJldHVybnMgdGhlIGxpc3Qgb2YgZGF0YSB0eXBlcyB0aGF0IGNhbiBiZSB0cmFuc2ZlcnJlZCBieSB0aGlzIERyYWdTb3VyY2UuCkBAIC0xNjYsNyArMjA0LDE5IEBACiAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIGRhdGEgdHlwZXMgdGhhdCBjYW4gYmUgdHJhbnNmZXJyZWQgYnkgdGhpcyBEcmFnU291cmNlCiAgKi8KIHB1YmxpYyBUcmFuc2ZlcltdIGdldFRyYW5zZmVyKCl7Ci0JcmV0dXJuIG51bGw7CisJcmV0dXJuIHRyYW5zZmVyQWdlbnRzOworfQorCitwcml2YXRlIHZvaWQgb25EaXNwb3NlICgpIHsKKwlpZiAoY29udHJvbCAhPSBudWxsICYmIGNvbnRyb2xMaXN0ZW5lciAhPSBudWxsKXsKKwkJY29udHJvbC5yZW1vdmVMaXN0ZW5lcihTV1QuRGlzcG9zZSwgY29udHJvbExpc3RlbmVyKTsKKwkJY29udHJvbC5yZW1vdmVMaXN0ZW5lcihTV1QuRHJhZ0RldGVjdCwgY29udHJvbExpc3RlbmVyKTsKKwl9CisJY29udHJvbExpc3RlbmVyID0gbnVsbDsKKwljb250cm9sLnNldERhdGEoRFJBR1NPVVJDRUlELCBudWxsKTsJCisJY29udHJvbCA9IG51bGw7CisJCisJdHJhbnNmZXJBZ2VudHMgPSBudWxsOwogfQogCiAvKioKQEAgLTE4Nyw2ICsyMzcsMTAgQEAKICAqIEBzZWUgI2FkZERyYWdMaXN0ZW5lcgogICovCiBwdWJsaWMgdm9pZCByZW1vdmVEcmFnTGlzdGVuZXIoRHJhZ1NvdXJjZUxpc3RlbmVyIGxpc3RlbmVyKSB7CisJaWYgKGxpc3RlbmVyID09IG51bGwpIERORC5lcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCXJlbW92ZUxpc3RlbmVyIChETkQuRHJhZ1N0YXJ0LCBsaXN0ZW5lcik7CisJcmVtb3ZlTGlzdGVuZXIgKERORC5EcmFnRW5kLCBsaXN0ZW5lcik7CisJcmVtb3ZlTGlzdGVuZXIgKERORC5EcmFnU2V0RGF0YSwgbGlzdGVuZXIpOwogfQogCiAvKioKQEAgLTE5OCw2ICsyNTIsNyBAQAogICogZHJhZ2dlZCBmcm9tIHRoaXMgc291cmNlCiAgKi8KIHB1YmxpYyB2b2lkIHNldFRyYW5zZmVyKFRyYW5zZmVyW10gdHJhbnNmZXJBZ2VudHMpeworCXRoaXMudHJhbnNmZXJBZ2VudHMgPSB0cmFuc2ZlckFnZW50czsKIH0KIAogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgRHJhZyBhbmQgRHJvcC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2RuZC9Ecm9wVGFyZ2V0LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZG5kL0Ryb3BUYXJnZXQuamF2YQppbmRleCA0OWRiZTdiLi5kNGQxZjA2IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZG5kL0Ryb3BUYXJnZXQuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZG5kL0Ryb3BUYXJnZXQuamF2YQpAQCAtNjUsNiArNjUsMTMgQEAKICAqLwogcHVibGljIGZpbmFsIGNsYXNzIERyb3BUYXJnZXQgZXh0ZW5kcyBXaWRnZXQgewogCQorCS8vIGluZm8gZm9yIHJlZ2lzdGVyaW5nIGFzIGEgZHJvcHRhcmdldAkKKwlwcml2YXRlIENvbnRyb2wgY29udHJvbDsKKwlwcml2YXRlIExpc3RlbmVyIGNvbnRyb2xMaXN0ZW5lcjsKKwlwcml2YXRlIFRyYW5zZmVyW10gdHJhbnNmZXJBZ2VudHMgPSBuZXcgVHJhbnNmZXJbMF07CisJCisJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERST1BUQVJHRVRJRCA9ICJEcm9wVGFyZ2V0IjsKKwkKIC8qKgogICogQ3JlYXRlcyBhIG5ldyA8Y29kZT5Ecm9wVGFyZ2V0PC9jb2RlPiB0byBhbGxvdyBkYXRhIHRvIGJlIGRyb3BwZWQgb24gdGhlIHNwZWNpZmllZCAKICAqIDxjb2RlPkNvbnRyb2w8L2NvZGU+LgpAQCAtODUsNiArOTIsMjQgQEAKICAqLwogcHVibGljIERyb3BUYXJnZXQoQ29udHJvbCBjb250cm9sLCBpbnQgc3R5bGUpIHsKIAlzdXBlcihjb250cm9sLCBzdHlsZSk7CisJdGhpcy5jb250cm9sID0gY29udHJvbDsKKwlpZiAoY29udHJvbC5nZXREYXRhKERST1BUQVJHRVRJRCkgIT0gbnVsbCkKKwkJRE5ELmVycm9yKERORC5FUlJPUl9DQU5OT1RfSU5JVF9EUk9QKTsKKwljb250cm9sLnNldERhdGEoRFJPUFRBUkdFVElELCB0aGlzKTsKKworCWNvbnRyb2xMaXN0ZW5lciA9IG5ldyBMaXN0ZW5lciAoKSB7CisJCXB1YmxpYyB2b2lkIGhhbmRsZUV2ZW50IChFdmVudCBldmVudCkgeworCQkJRHJvcFRhcmdldC50aGlzLmRpc3Bvc2UoKTsKKwkJfQorCX07CisJCisJY29udHJvbC5hZGRMaXN0ZW5lciAoU1dULkRpc3Bvc2UsIGNvbnRyb2xMaXN0ZW5lcik7CisJCisJdGhpcy5hZGRMaXN0ZW5lciAoU1dULkRpc3Bvc2UsIG5ldyBMaXN0ZW5lciAoKSB7CisJCXB1YmxpYyB2b2lkIGhhbmRsZUV2ZW50IChFdmVudCBldmVudCkgeworCQkJb25EaXNwb3NlKCk7CisJCX0KKwl9KTsKIH0KIAogLyoqCkBAIC0xMjAsOCArMTQ1LDI0IEBACiAgKiBAc2VlIERyb3BUYXJnZXRFdmVudAogICovCiBwdWJsaWMgdm9pZCBhZGREcm9wTGlzdGVuZXIoRHJvcFRhcmdldExpc3RlbmVyIGxpc3RlbmVyKSB7CQorCWlmIChsaXN0ZW5lciA9PSBudWxsKSBETkQuZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlETkRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IERORExpc3RlbmVyIChsaXN0ZW5lcik7CisJYWRkTGlzdGVuZXIgKERORC5EcmFnRW50ZXIsIHR5cGVkTGlzdGVuZXIpOworCWFkZExpc3RlbmVyIChETkQuRHJhZ0xlYXZlLCB0eXBlZExpc3RlbmVyKTsKKwlhZGRMaXN0ZW5lciAoRE5ELkRyYWdPdmVyLCB0eXBlZExpc3RlbmVyKTsKKwlhZGRMaXN0ZW5lciAoRE5ELkRyYWdPcGVyYXRpb25DaGFuZ2VkLCB0eXBlZExpc3RlbmVyKTsKKwlhZGRMaXN0ZW5lciAoRE5ELkRyb3AsIHR5cGVkTGlzdGVuZXIpOworCWFkZExpc3RlbmVyIChETkQuRHJvcEFjY2VwdCwgdHlwZWRMaXN0ZW5lcik7CiB9CiAKK3Byb3RlY3RlZCB2b2lkIGNoZWNrU3ViY2xhc3MgKCkgeworCVN0cmluZyBuYW1lID0gZ2V0Q2xhc3MoKS5nZXROYW1lICgpOworCVN0cmluZyB2YWxpZE5hbWUgPSBEcm9wVGFyZ2V0LmNsYXNzLmdldE5hbWUoKTsKKwlpZiAoIXZhbGlkTmFtZS5lcXVhbHMobmFtZSkpIHsKKwkJRE5ELmVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9TVUJDTEFTUyk7CisJfQorfQorCQogLyoqCiAgKiBSZXR1cm5zIHRoZSBDb250cm9sIHdoaWNoIGlzIHJlZ2lzdGVyZWQgZm9yIHRoaXMgRHJvcFRhcmdldC4gIFRoaXMgaXMgdGhlIGNvbnRyb2wgb3ZlciB3aGljaCB0aGUgCiAgKiB1c2VyIHBvc2l0aW9ucyB0aGUgY3Vyc29yIHRvIGRyb3AgdGhlIGRhdGEuCkBAIC0xMjksMTkgKzE3MCwzMyBAQAogICogQHJldHVybiB0aGUgQ29udHJvbCB3aGljaCBpcyByZWdpc3RlcmVkIGZvciB0aGlzIERyb3BUYXJnZXQKICAqLwogcHVibGljIENvbnRyb2wgZ2V0Q29udHJvbCAoKSB7Ci0JcmV0dXJuIG51bGw7CisJcmV0dXJuIGNvbnRyb2w7CiB9CisKIHB1YmxpYyBEaXNwbGF5IGdldERpc3BsYXkgKCkgewotCXJldHVybiBudWxsOworCWlmIChjb250cm9sID09IG51bGwpIERORC5lcnJvcihTV1QuRVJST1JfV0lER0VUX0RJU1BPU0VEKTsKKwlyZXR1cm4gY29udHJvbC5nZXREaXNwbGF5ICgpOwogfQorCiAvKioKICAqIFJldHVybnMgYSBsaXN0IG9mIHRoZSBkYXRhIHR5cGVzIHRoYXQgY2FuIGJlIHRyYW5zZmVycmVkIHRvIHRoaXMgRHJvcFRhcmdldC4KICAqCiAgKiBAcmV0dXJuIGEgbGlzdCBvZiB0aGUgZGF0YSB0eXBlcyB0aGF0IGNhbiBiZSB0cmFuc2ZlcnJlZCB0byB0aGlzIERyb3BUYXJnZXQKICAqLwotcHVibGljIFRyYW5zZmVyW10gZ2V0VHJhbnNmZXIoKSB7IHJldHVybiBudWxsOyB9CitwdWJsaWMgVHJhbnNmZXJbXSBnZXRUcmFuc2ZlcigpeworCXJldHVybiB0cmFuc2ZlckFnZW50czsKK30KIAotcHVibGljIHZvaWQgbm90aWZ5TGlzdGVuZXIgKGludCBldmVudFR5cGUsIEV2ZW50IGV2ZW50KSB7fQorcHJpdmF0ZSB2b2lkIG9uRGlzcG9zZSAoKSB7CQorCWlmIChjb250cm9sID09IG51bGwpIHJldHVybjsKKwkKKwlpZiAoY29udHJvbExpc3RlbmVyICE9IG51bGwpCisJCWNvbnRyb2wucmVtb3ZlTGlzdGVuZXIoU1dULkRpc3Bvc2UsIGNvbnRyb2xMaXN0ZW5lcik7CisJY29udHJvbExpc3RlbmVyID0gbnVsbDsKKwljb250cm9sLnNldERhdGEoRFJPUFRBUkdFVElELCBudWxsKTsKKwl0cmFuc2ZlckFnZW50cyA9IG51bGw7CisJY29udHJvbCA9IG51bGw7Cit9CiAKIC8qKgogICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKQEAgLTE2MCw3ICsyMTUsMTUgQEAKICAqIEBzZWUgRHJvcFRhcmdldExpc3RlbmVyCiAgKiBAc2VlICNhZGREcm9wTGlzdGVuZXIKICAqLwotcHVibGljIHZvaWQgcmVtb3ZlRHJvcExpc3RlbmVyKERyb3BUYXJnZXRMaXN0ZW5lciBsaXN0ZW5lcikge30KK3B1YmxpYyB2b2lkIHJlbW92ZURyb3BMaXN0ZW5lcihEcm9wVGFyZ2V0TGlzdGVuZXIgbGlzdGVuZXIpIHsJCisJaWYgKGxpc3RlbmVyID09IG51bGwpIERORC5lcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCXJlbW92ZUxpc3RlbmVyIChETkQuRHJhZ0VudGVyLCBsaXN0ZW5lcik7CisJcmVtb3ZlTGlzdGVuZXIgKERORC5EcmFnTGVhdmUsIGxpc3RlbmVyKTsKKwlyZW1vdmVMaXN0ZW5lciAoRE5ELkRyYWdPdmVyLCBsaXN0ZW5lcik7CisJcmVtb3ZlTGlzdGVuZXIgKERORC5EcmFnT3BlcmF0aW9uQ2hhbmdlZCwgbGlzdGVuZXIpOworCXJlbW92ZUxpc3RlbmVyIChETkQuRHJvcCwgbGlzdGVuZXIpOworCXJlbW92ZUxpc3RlbmVyIChETkQuRHJvcEFjY2VwdCwgbGlzdGVuZXIpOworfQogCiAvKioKICAqIFNwZWNpZmllcyB0aGUgZGF0YSB0eXBlcyB0aGF0IGNhbiBiZSB0cmFuc2ZlcnJlZCB0byB0aGlzIERyb3BUYXJnZXQuICBJZiBkYXRhIGlzIApAQCAtMTc2LDYgKzIzOSw3IEBACiAgKi8KIHB1YmxpYyB2b2lkIHNldFRyYW5zZmVyKFRyYW5zZmVyW10gdHJhbnNmZXJBZ2VudHMpewogCWlmICh0cmFuc2ZlckFnZW50cyA9PSBudWxsKSBETkQuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCXRoaXMudHJhbnNmZXJBZ2VudHMgPSB0cmFuc2ZlckFnZW50czsKIH0KIAotfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIERyYWcgYW5kIERyb3AvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9kbmQvVGV4dFRyYW5zZmVyLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZG5kL1RleHRUcmFuc2Zlci5qYXZhCmluZGV4IDIyYWZjZGMuLjIyNDllYjIgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIERyYWcgYW5kIERyb3AvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9kbmQvVGV4dFRyYW5zZmVyLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgRHJhZyBhbmQgRHJvcC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2RuZC9UZXh0VHJhbnNmZXIuamF2YQpAQCAtNiw4ICs2LDkgQEAKICAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCi0gCi0gaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5Db252ZXJ0ZXI7CisKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuQ29udmVydGVyOyAKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLk9TOwogIAogLyoqCiAgKiBUaGUgY2xhc3MgPGNvZGU+VGV4dFRyYW5zZmVyPC9jb2RlPiBwcm92aWRlcyBhIHBsYXRmb3JtIHNwZWNpZmljIG1lY2hhbmlzbSAKQEAgLTI2LDcgKzI3LDcgQEAKIAogCXByaXZhdGUgc3RhdGljIFRleHRUcmFuc2ZlciBfaW5zdGFuY2UgPSBuZXcgVGV4dFRyYW5zZmVyKCk7CiAJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRZUEVOQU1FMSA9ICJURVhUIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVFlQRUlEMSA9ICgnVCc8PDI0KSArICgnRSc8PDE2KSArICgnWCc8PDgpICsgJ1QnOworCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUWVBFSUQxID0gT1Mua1NjcmFwRmxhdm9yVHlwZVRleHQ7CiAKIHByaXZhdGUgVGV4dFRyYW5zZmVyKCkgewogfQpAQCAtMzgsNiArMzksNyBAQAogcHVibGljIHN0YXRpYyBUZXh0VHJhbnNmZXIgZ2V0SW5zdGFuY2UgKCkgewogCXJldHVybiBfaW5zdGFuY2U7CiB9CisKIC8qKgogICogVGhpcyBpbXBsZW1lbnRhdGlvbiBvZiA8Y29kZT5qYXZhVG9OYXRpdmU8L2NvZGU+IGNvbnZlcnRzIHBsYWluIHRleHQKICAqIHJlcHJlc2VudGVkIGJ5IGEgamF2YSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGEgcGxhdGZvcm0gc3BlY2lmaWMgcmVwcmVzZW50YXRpb24uCkBAIC00OCwxMCArNTAsMTQgQEAKICAqICBvYmplY3Qgd2lsbCBiZSBmaWxsZWQgaW4gb24gcmV0dXJuIHdpdGggdGhlIHBsYXRmb3JtIHNwZWNpZmljIGZvcm1hdCBvZiB0aGUgZGF0YQogICovCiBwdWJsaWMgdm9pZCBqYXZhVG9OYXRpdmUgKE9iamVjdCBvYmplY3QsIFRyYW5zZmVyRGF0YSB0cmFuc2ZlckRhdGEpewotCWlmIChvYmplY3QgPT0gbnVsbCB8fCAhKG9iamVjdCBpbnN0YW5jZW9mIFN0cmluZykpIHJldHVybjsKKwlpZiAob2JqZWN0ID09IG51bGwgfHwgIShvYmplY3QgaW5zdGFuY2VvZiBTdHJpbmcpKSB7CisJCXRyYW5zZmVyRGF0YS5yZXN1bHQgPSAtMTsKKwkJcmV0dXJuOworCX0gCiAJYnl0ZSBbXSBidWZmZXIgPSBDb252ZXJ0ZXIud2NzVG9NYmNzIChudWxsLCAoU3RyaW5nKW9iamVjdCwgdHJ1ZSk7CiAJc3VwZXIuamF2YVRvTmF0aXZlKGJ1ZmZlciwgdHJhbnNmZXJEYXRhKTsKIH0KKwogLyoqCiAgKiBUaGlzIGltcGxlbWVudGF0aW9uIG9mIDxjb2RlPm5hdGl2ZVRvSmF2YTwvY29kZT4gY29udmVydHMgYSBwbGF0Zm9ybSBzcGVjaWZpYyAKICAqIHJlcHJlc2VudGF0aW9uIG9mIHBsYWluIHRleHQgdG8gYSBqYXZhIDxjb2RlPlN0cmluZzwvY29kZT4uCkBAIC03Miw5ICs3OCwxMSBAQAogCWludCBlbmQgPSBzdHJpbmcuaW5kZXhPZignXDAnKTsKIAlyZXR1cm4gKGVuZCA9PSAtMSkgPyBzdHJpbmcgOiBzdHJpbmcuc3Vic3RyaW5nKDAsIGVuZCk7CiB9CisKIHByb3RlY3RlZCBTdHJpbmdbXSBnZXRUeXBlTmFtZXMoKSB7CiAJcmV0dXJuIG5ldyBTdHJpbmdbXSB7IFRZUEVOQU1FMSB9OwogfQorCiBwcm90ZWN0ZWQgaW50W10gZ2V0VHlwZUlkcygpIHsKIAlyZXR1cm4gbmV3IGludFtdIHsgVFlQRUlEMSB9OwogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgRHJhZyBhbmQgRHJvcC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2RuZC9UcmFuc2ZlckRhdGEuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIERyYWcgYW5kIERyb3AvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9kbmQvVHJhbnNmZXJEYXRhLmphdmEKaW5kZXggZGU1OGU4OC4uZDNlZDc3OSAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgRHJhZyBhbmQgRHJvcC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2RuZC9UcmFuc2ZlckRhdGEuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBEcmFnIGFuZCBEcm9wL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZG5kL1RyYW5zZmVyRGF0YS5qYXZhCkBAIC0yOSwyNCArMjksMTggQEAKIAlwdWJsaWMgaW50IHR5cGU7CiAJCiAJLyoqCi0JICogVGhlIGJ5dGUgY291bnQgZm9yIHRoZSBkYXRhLgotCSAqIChXYXJuaW5nOiBUaGlzIGZpZWxkIGlzIHBsYXRmb3JtIGRlcGVuZGVudCkKLQkgKi8KLQlwdWJsaWMgaW50IGxlbmd0aDsKLQkKLQkvKioKIAkgKiBUaGUgZGF0YSBiZWluZyB0cmFuc2ZlcnJlZC4KIAkgKiAoV2FybmluZzogVGhpcyBmaWVsZCBpcyBwbGF0Zm9ybSBkZXBlbmRlbnQpCiAJICovCiAJcHVibGljIGJ5dGVbXSBkYXRhOwotCisJCiAJLyoqCiAJICogVGhlIHJlc3VsdCBmaWVsZCBjb250YWlucyB0aGUgcmVzdWx0IG9mIGNvbnZlcnRpbmcgYSBqYXZhIGRhdGEgdHlwZQogCSAqIGludG8gYSBwbGF0Zm9ybSBzcGVjaWZpYyB2YWx1ZS4KIAkgKiAoV2FybmluZzogVGhpcyBmaWVsZCBpcyBwbGF0Zm9ybSBkZXBlbmRlbnQpCiAJICogCi0gCSAqIDxwPlRoZSB2YWx1ZSBvZiByZXN1bHQgaXMgMSBpZiB0aGUgY29udmVyc2lvbiB3YXMgc3VjY2Vzc2Z1bGx5LiAgVGhlIHZhbHVlIG9mIAotCSAqIHJlc3VsdCBpcyAwIGlmIHRoZSBjb252ZXJzaW9uIGZhaWxlZC48L3A+CisgCSAqIDxwPlRoZSB2YWx1ZSBvZiByZXN1bHQgaXMgIGlmIHRoZSBjb252ZXJzaW9uIHdhcyBzdWNjZXNzZnVsbHkuICBUaGUgdmFsdWUgb2YgCisJICogcmVzdWx0IGlzIGFuIGVycm9yIGNvZGUgaWYgdGhlIGNvbnZlcnNpb24gZmFpbGVkLjwvcD4KIAkgKi8KIAlwdWJsaWMgaW50IHJlc3VsdDsKIAkKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9saWJyYXJ5Ly5jdnNpZ25vcmUgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vbGlicmFyeS8uY3ZzaWdub3JlCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYTk0ODFjLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9saWJyYXJ5Ly5jdnNpZ25vcmUKKysrIC9kZXYvbnVsbApAQCAtMSArMCwwIEBACi1vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TLmgKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9saWJyYXJ5L2J1aWxkLmNzaCBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9saWJyYXJ5L2J1aWxkLmNzaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NTcyYTYwCi0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL2xpYnJhcnkvYnVpbGQuY3NoCkBAIC0wLDAgKzEsMTAgQEAKKyMhL2Jpbi9jc2gKKworIyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyMgQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyMgVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKKyMgd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyMgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyMqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisKK21ha2UgLWYgbWFrZV9jYXJib24ubWFrICQxICQyICQzICQ0ICQ1ICQ2ICQ3ICQ4ICQ5CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vbGlicmFyeS9tYWtlX2NhcmJvbi5tYWsgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vbGlicmFyeS9tYWtlX2NhcmJvbi5tYWsKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGE2YTNmNgotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9saWJyYXJ5L21ha2VfY2FyYm9uLm1hawpAQCAtMCwwICsxLDMyIEBACisjKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorIyBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorIyBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorIyB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorIyBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAorIyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyMKKyMgTWFrZWZpbGUgZm9yIFNXVCBsaWJyYXJpZXMgb24gQ2FyYm9uL01hYworCitpbmNsdWRlIG1ha2VfY29tbW9uLm1haworCitTV1RfUFJFRklYPXN3dAorV1NfUFJFRklYPWNhcmJvbgorU1dUX1ZFUlNJT049JChtYWpfdmVyKSQobWluX3ZlcikKK1NXVF9MSUI9bGliJChTV1RfUFJFRklYKS0kKFdTX1BSRUZJWCktJChTV1RfVkVSU0lPTikuam5pbGliCisKK0RFQlVHID0gIAorQ0ZMQUdTID0gLWMgLURTV1RfVkVSU0lPTj0kKFNXVF9WRVJTSU9OKSAkKERFQlVHKSAtRENBUkJPTiAtSSAvU3lzdGVtL0xpYnJhcnkvRnJhbWV3b3Jrcy9KYXZhVk0uZnJhbWV3b3JrL0hlYWRlcnMKK0xGTEFHUyA9IC1idW5kbGUgLWZyYW1ld29yayBKYXZhVk0gLWZyYW1ld29yayBDYXJib24gCisKK1NXVF9PQkpTID0gc3d0Lm8gc3RydWN0cy5vIGNhbGxiYWNrLm8KKworYWxsOiAkKFNXVF9MSUIpCisKKy5jLm86CisJY2MgJChDRkxBR1MpICQqLmMKKworJChTV1RfTElCKTogJChTV1RfT0JKUykKKwljYyAtbyAkKFNXVF9MSUIpICAkKExGTEFHUykgJChTV1RfT0JKUykKKworY2xlYW46CisJcm0gLWYgKi5qbmlsaWIgKi5vClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL2xpYnJhcnkvbWFrZV9jYXJib24ueG1sIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL2xpYnJhcnkvbWFrZV9jYXJib24ueG1sCmluZGV4IGU4ZjIzZjkuLmVjM2E3OTAgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9saWJyYXJ5L21ha2VfY2FyYm9uLnhtbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vbGlicmFyeS9tYWtlX2NhcmJvbi54bWwKQEAgLTMsNTcgKzMsMzMgQEAKIDwhLS0gVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAgLS0+CiA8IS0tIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0ICAgICAgICAgICAgICAgICAgICAgIC0tPgogPCEtLSBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLT4KLTwhLS0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0+Ci08IS0tIEFuZHJlIFdlaW5hbmQsIE9USSAtIEluaXRpYWwgdmVyc2lvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tPgogPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAtLT4gCiAKLTxwcm9qZWN0IGRlZmF1bHQ9ImJ1aWxkX2RsbCIgYmFzZWRpcj0iLiI+Cis8cHJvamVjdCBkZWZhdWx0PSJidWlsZF9saWIiIGJhc2VkaXI9Ii4iPgogCiAJPHRhcmdldCBuYW1lPSJpbml0Ij4KIAkJPHRzdGFtcC8+CiAgICAgICAgCTxwcm9wZXJ0eSBuYW1lPSJmcmFnbWVudF9kaXIiIHZhbHVlPSIuLi8uLi8uLi8uLi9vcmcuZWNsaXBzZS5zd3QuY2FyYm9uIiAvPgogICAgICAgICA8cHJvcGVydHkgbmFtZT0iamFyX2Rlc3RkaXIiIHZhbHVlPSIke2ZyYWdtZW50X2Rpcn0vd3MvY2FyYm9uIiAvPgotICAgICAgICA8cHJvcGVydHkgbmFtZT0iZGxsX2Rlc3RkaXIiIHZhbHVlPSIke2ZyYWdtZW50X2Rpcn0vb3MvbWFjb3N4L3BwYyIgLz4KKyAgICAgICAgPHByb3BlcnR5IG5hbWU9ImxpYl9kZXN0ZGlyIiB2YWx1ZT0iJHtmcmFnbWVudF9kaXJ9L29zL21hY29zeC9wcGMiIC8+CiAJCTxwcm9wZXJ0eSBuYW1lPSJwbHVnaW4iIHZhbHVlPSJvcmcuZWNsaXBzZS5zd3QiIC8+CiAJCTxwcm9wZXJ0eSBuYW1lPSJiaW5fZGlyIiB2YWx1ZT0iLi4vLi4vLi4vYmluIiAvPgotICAgICAgICA8cHJvcGVydHkgbmFtZT0iY29tbW9uX2xpYnJhcnkiIHZhbHVlPSIuLi8uLi8uLi9FY2xpcHNlIFNXVC9jb21tb24vbGlicmFyeSIgLz4KICAgICAgICAgPG1rZGlyIGRpcj0iJHtqYXJfZGVzdGRpcn0iIC8+Ci0gICAgICAgIDxta2RpciBkaXI9IiR7ZGxsX2Rlc3RkaXJ9IiAvPgorICAgICAgICA8bWtkaXIgZGlyPSIke2xpYl9kZXN0ZGlyfSIgLz4KIAk8L3RhcmdldD4KIAogCTx0YXJnZXQgbmFtZT0iYnVpbGQiIGRlcGVuZHM9ImluaXQiPgogICAgIAk8ZWNsaXBzZS5pbmNyZW1lbnRhbEJ1aWxkIHByb2plY3Q9IiR7cGx1Z2lufSIga2luZD0iaW5jciIgLz4KIAk8L3RhcmdldD4KIAkKLQk8dGFyZ2V0IG5hbWU9ImJ1aWxkX2hlYWRlciIgZGVwZW5kcz0iYnVpbGQiPgotIAkJPGphdmFoCi0gCQkJZGVzdGRpcj0iLiIKLSAJCQlmb3JjZT0ieWVzIgotIAkJCWNsYXNzcGF0aD0iJHtiaW5fZGlyfSIKLSAgCQkJY2xhc3M9ICJvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLk9TIgotCQkvPgotCTwvdGFyZ2V0PgotCi0JPHRhcmdldCBuYW1lPSJidWlsZF9kbGwiIGRlcGVuZHM9ImJ1aWxkX2hlYWRlciI+CisJPHRhcmdldCBuYW1lPSJidWlsZF9saWIiIGRlcGVuZHM9ImJ1aWxkIj4KIAkKLQkJPHByb3BlcnR5IGZpbGU9IiR7Y29tbW9uX2xpYnJhcnl9L21ha2VfY29tbW9uLm1hayIgLz4JCQotCQk8cHJvcGVydHkgbmFtZT0iU1dUX1ZFUlNJT04iIHZhbHVlPSIke21hal92ZXJ9JHttaW5fdmVyfSIgLz4KLQkJPHByb3BlcnR5IG5hbWU9IlNXVF9QUkVGSVgiIHZhbHVlPSJzd3QiIC8+Ci0JCTxwcm9wZXJ0eSBuYW1lPSJXU19QUkVGSVgiIHZhbHVlPSJjYXJib24iIC8+Ci0JCTxwcm9wZXJ0eSBuYW1lPSJTV1RfRExMIiB2YWx1ZT0ibGliJHtTV1RfUFJFRklYfS0ke1dTX1BSRUZJWH0tJHtTV1RfVkVSU0lPTn0uam5pbGliIiAvPgotCQkKLQkJPGV4ZWMgZXhlY3V0YWJsZT0iY2MiPgotICAJCQk8YXJnIGxpbmU9Ii1idW5kbGUiIC8+Ci0gIAkJCTxhcmcgdmFsdWU9Jy1EUExBVEZPUk09ImNhcmJvbiInIC8+Ci0gIAkJCTxhcmcgdmFsdWU9Ii1EUkVEVUNFRF9DQUxMQkFDS1M9MSIgLz4KLSAgCQkJPGFyZyBsaW5lPSItSSAvU3lzdGVtL0xpYnJhcnkvRnJhbWV3b3Jrcy9KYXZhVk0uZnJhbWV3b3JrL0hlYWRlcnMiIC8+Ci0gIAkJCTxhcmcgbGluZT0iLW8gJHtkbGxfZGVzdGRpcn0vJHtTV1RfRExMfSIgLz4KLSAgCQkJPGFyZyBsaW5lPSItZnJhbWV3b3JrIEphdmFWTSIgLz4KLSAgCQkJPGFyZyBsaW5lPSItZnJhbWV3b3JrIENhcmJvbiIgLz4KLSAgCQkJPGFyZyBsaW5lPSJzd3QuYyIgLz4KLSAJCQk8YXJnIHZhbHVlPSIke2NvbW1vbl9saWJyYXJ5fS9jYWxsYmFjay5jIiAvPgorCQk8ZXhlYyBkaXI9IiR7YmluX2Rpcn0vbGlicmFyeS8iIGV4ZWN1dGFibGU9ImNzaCI+CisgIAkJCTxhcmcgbGluZT0nYnVpbGQuY3NoJyAvPgogCQk8L2V4ZWM+Ci0JCQorCQk8Y29weSB0b2Rpcj0iJHtsaWJfZGVzdGRpcn0iPgorCQkgICAgPGZpbGVzZXQgZGlyPSIke2Jpbl9kaXJ9L2xpYnJhcnkiIGluY2x1ZGVzPSIqKi8qLmpuaWxpYiIvPgorCQk8L2NvcHk+CiAJPC90YXJnZXQ+CiAJCQogICAgIDx0YXJnZXQgbmFtZT0iYnVpbGRfamFyIiBkZXBlbmRzPSJidWlsZCI+CkBAIC02Miw4ICszOCwxNiBAQAogICAgICAgICAgICAgYmFzZWRpcj0iJHtiaW5fZGlyfSIKICAgICAgICAgLz4KICAgICA8L3RhcmdldD4KKyAgICAKKwk8dGFyZ2V0IG5hbWU9ImNsZWFuIiBkZXBlbmRzPSJpbml0Ij4KKwkKKwkJPGV4ZWMgZGlyPSIke2Jpbl9kaXJ9L2xpYnJhcnkvIiBleGVjdXRhYmxlPSJjc2giPgorICAJCQk8YXJnIGxpbmU9J2J1aWxkLmNzaCcgLz4KKyAgCQkJPGFyZyBsaW5lPSdjbGVhbicgLz4KKwkJPC9leGVjPgorCTwvdGFyZ2V0PgogCi0gICAgPHRhcmdldCBuYW1lPSJleHBvcnQiIGRlcGVuZHM9ImJ1aWxkX2phcixidWlsZF9kbGwiPgorICAgIDx0YXJnZXQgbmFtZT0iZXhwb3J0IiBkZXBlbmRzPSJidWlsZF9qYXIsYnVpbGRfbGliIj4KICAgICA8L3RhcmdldD4KIAkKIDwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9saWJyYXJ5L3N0cnVjdHMuYyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9saWJyYXJ5L3N0cnVjdHMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZGZkNmFkCi0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL2xpYnJhcnkvc3RydWN0cy5jCkBAIC0wLDAgKzEsMTcxNiBAQAorLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKworLyoqCisgKiBKTkkgU1dUIG9iamVjdCBmaWVsZCBnZXR0ZXJzIGFuZCBzZXR0ZXJzIGRlY2xhcmF0aW9ucyBmb3IgTWFjL0NhcmJvbiBzdHJ1Y3RzLgorICovCisKKyNpbmNsdWRlICJzd3QuaCIKKyNpbmNsdWRlICJzdHJ1Y3RzLmgiCisKKyNpZm5kZWYgTk9fQUVEZXNjCit0eXBlZGVmIHN0cnVjdCBBRURlc2NfRklEX0NBQ0hFIHsKKwlpbnQgY2FjaGVkOworCWpjbGFzcyBjbGF6ejsKKwlqZmllbGRJRCBkZXNjcmlwdG9yVHlwZSwgZGF0YUhhbmRsZTsKK30gQUVEZXNjX0ZJRF9DQUNIRTsKKworQUVEZXNjX0ZJRF9DQUNIRSBBRURlc2NGYzsKKwordm9pZCBjYWNoZUFFRGVzY0ZpZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QpCit7CisJaWYgKEFFRGVzY0ZjLmNhY2hlZCkgcmV0dXJuOworCUFFRGVzY0ZjLmNsYXp6ID0gKCplbnYpLT5HZXRPYmplY3RDbGFzcyhlbnYsIGxwT2JqZWN0KTsKKwlBRURlc2NGYy5kZXNjcmlwdG9yVHlwZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEFFRGVzY0ZjLmNsYXp6LCAiZGVzY3JpcHRvclR5cGUiLCAiSSIpOworCUFFRGVzY0ZjLmRhdGFIYW5kbGUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBBRURlc2NGYy5jbGF6eiwgImRhdGFIYW5kbGUiLCAiSSIpOworCUFFRGVzY0ZjLmNhY2hlZCA9IDE7Cit9CisKK0FFRGVzYyAqZ2V0QUVEZXNjRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBBRURlc2MgKmxwU3RydWN0KQoreworCWlmICghQUVEZXNjRmMuY2FjaGVkKSBjYWNoZUFFRGVzY0ZpZHMoZW52LCBscE9iamVjdCk7CisJbHBTdHJ1Y3QtPmRlc2NyaXB0b3JUeXBlID0gKERlc2NUeXBlKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQUVEZXNjRmMuZGVzY3JpcHRvclR5cGUpOworCWxwU3RydWN0LT5kYXRhSGFuZGxlID0gKEFFRGF0YVN0b3JhZ2UpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBBRURlc2NGYy5kYXRhSGFuZGxlKTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0QUVEZXNjRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBBRURlc2MgKmxwU3RydWN0KQoreworCWlmICghQUVEZXNjRmMuY2FjaGVkKSBjYWNoZUFFRGVzY0ZpZHMoZW52LCBscE9iamVjdCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBBRURlc2NGYy5kZXNjcmlwdG9yVHlwZSwgKGppbnQpbHBTdHJ1Y3QtPmRlc2NyaXB0b3JUeXBlKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFFRGVzY0ZjLmRhdGFIYW5kbGUsIChqaW50KWxwU3RydWN0LT5kYXRhSGFuZGxlKTsKK30KKyNlbmRpZiAvKiBOT19BRURlc2MgKi8KKworI2lmbmRlZiBOT19BVFNUcmFwZXpvaWQKK3R5cGVkZWYgc3RydWN0IEFUU1RyYXBlem9pZF9GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIHVwcGVyTGVmdF94LCB1cHBlckxlZnRfeSwgdXBwZXJSaWdodF94LCB1cHBlclJpZ2h0X3ksIGxvd2VyUmlnaHRfeCwgbG93ZXJSaWdodF95LCBsb3dlckxlZnRfeCwgbG93ZXJMZWZ0X3k7Cit9IEFUU1RyYXBlem9pZF9GSURfQ0FDSEU7CisKK0FUU1RyYXBlem9pZF9GSURfQ0FDSEUgQVRTVHJhcGV6b2lkRmM7CisKK3ZvaWQgY2FjaGVBVFNUcmFwZXpvaWRGaWRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0KQoreworCWlmIChBVFNUcmFwZXpvaWRGYy5jYWNoZWQpIHJldHVybjsKKwlBVFNUcmFwZXpvaWRGYy5jbGF6eiA9ICgqZW52KS0+R2V0T2JqZWN0Q2xhc3MoZW52LCBscE9iamVjdCk7CisJQVRTVHJhcGV6b2lkRmMudXBwZXJMZWZ0X3ggPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBBVFNUcmFwZXpvaWRGYy5jbGF6eiwgInVwcGVyTGVmdF94IiwgIkkiKTsKKwlBVFNUcmFwZXpvaWRGYy51cHBlckxlZnRfeSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEFUU1RyYXBlem9pZEZjLmNsYXp6LCAidXBwZXJMZWZ0X3kiLCAiSSIpOworCUFUU1RyYXBlem9pZEZjLnVwcGVyUmlnaHRfeCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEFUU1RyYXBlem9pZEZjLmNsYXp6LCAidXBwZXJSaWdodF94IiwgIkkiKTsKKwlBVFNUcmFwZXpvaWRGYy51cHBlclJpZ2h0X3kgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBBVFNUcmFwZXpvaWRGYy5jbGF6eiwgInVwcGVyUmlnaHRfeSIsICJJIik7CisJQVRTVHJhcGV6b2lkRmMubG93ZXJSaWdodF94ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQVRTVHJhcGV6b2lkRmMuY2xhenosICJsb3dlclJpZ2h0X3giLCAiSSIpOworCUFUU1RyYXBlem9pZEZjLmxvd2VyUmlnaHRfeSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEFUU1RyYXBlem9pZEZjLmNsYXp6LCAibG93ZXJSaWdodF95IiwgIkkiKTsKKwlBVFNUcmFwZXpvaWRGYy5sb3dlckxlZnRfeCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEFUU1RyYXBlem9pZEZjLmNsYXp6LCAibG93ZXJMZWZ0X3giLCAiSSIpOworCUFUU1RyYXBlem9pZEZjLmxvd2VyTGVmdF95ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQVRTVHJhcGV6b2lkRmMuY2xhenosICJsb3dlckxlZnRfeSIsICJJIik7CisJQVRTVHJhcGV6b2lkRmMuY2FjaGVkID0gMTsKK30KKworQVRTVHJhcGV6b2lkICpnZXRBVFNUcmFwZXpvaWRGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIEFUU1RyYXBlem9pZCAqbHBTdHJ1Y3QpCit7CisJaWYgKCFBVFNUcmFwZXpvaWRGYy5jYWNoZWQpIGNhY2hlQVRTVHJhcGV6b2lkRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+dXBwZXJMZWZ0LnggPSAoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFUU1RyYXBlem9pZEZjLnVwcGVyTGVmdF94KTsKKwlscFN0cnVjdC0+dXBwZXJMZWZ0LnkgPSAoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFUU1RyYXBlem9pZEZjLnVwcGVyTGVmdF95KTsKKwlscFN0cnVjdC0+dXBwZXJSaWdodC54ID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBBVFNUcmFwZXpvaWRGYy51cHBlclJpZ2h0X3gpOworCWxwU3RydWN0LT51cHBlclJpZ2h0LnkgPSAoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFUU1RyYXBlem9pZEZjLnVwcGVyUmlnaHRfeSk7CisJbHBTdHJ1Y3QtPmxvd2VyUmlnaHQueCA9ICgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQVRTVHJhcGV6b2lkRmMubG93ZXJSaWdodF94KTsKKwlscFN0cnVjdC0+bG93ZXJSaWdodC55ID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBBVFNUcmFwZXpvaWRGYy5sb3dlclJpZ2h0X3kpOworCWxwU3RydWN0LT5sb3dlckxlZnQueCA9ICgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQVRTVHJhcGV6b2lkRmMubG93ZXJMZWZ0X3gpOworCWxwU3RydWN0LT5sb3dlckxlZnQueSA9ICgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQVRTVHJhcGV6b2lkRmMubG93ZXJMZWZ0X3kpOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXRBVFNUcmFwZXpvaWRGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIEFUU1RyYXBlem9pZCAqbHBTdHJ1Y3QpCit7CisJaWYgKCFBVFNUcmFwZXpvaWRGYy5jYWNoZWQpIGNhY2hlQVRTVHJhcGV6b2lkRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFUU1RyYXBlem9pZEZjLnVwcGVyTGVmdF94LCAoamludClscFN0cnVjdC0+dXBwZXJMZWZ0LngpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQVRTVHJhcGV6b2lkRmMudXBwZXJMZWZ0X3ksIChqaW50KWxwU3RydWN0LT51cHBlckxlZnQueSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBBVFNUcmFwZXpvaWRGYy51cHBlclJpZ2h0X3gsIChqaW50KWxwU3RydWN0LT51cHBlclJpZ2h0LngpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQVRTVHJhcGV6b2lkRmMudXBwZXJSaWdodF95LCAoamludClscFN0cnVjdC0+dXBwZXJSaWdodC55KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFUU1RyYXBlem9pZEZjLmxvd2VyUmlnaHRfeCwgKGppbnQpbHBTdHJ1Y3QtPmxvd2VyUmlnaHQueCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBBVFNUcmFwZXpvaWRGYy5sb3dlclJpZ2h0X3ksIChqaW50KWxwU3RydWN0LT5sb3dlclJpZ2h0LnkpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQVRTVHJhcGV6b2lkRmMubG93ZXJMZWZ0X3gsIChqaW50KWxwU3RydWN0LT5sb3dlckxlZnQueCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBBVFNUcmFwZXpvaWRGYy5sb3dlckxlZnRfeSwgKGppbnQpbHBTdHJ1Y3QtPmxvd2VyTGVmdC55KTsKK30KKyNlbmRpZiAvKiBOT19BVFNUcmFwZXpvaWQgKi8KKworI2lmbmRlZiBOT19BbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlYwordHlwZWRlZiBzdHJ1Y3QgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNfRklEX0NBQ0hFIHsKKwlpbnQgY2FjaGVkOworCWpjbGFzcyBjbGF6ejsKKwlqZmllbGRJRCB2ZXJzaW9uLCBtb3ZhYmxlLCBoZWxwQnV0dG9uLCBkZWZhdWx0VGV4dCwgY2FuY2VsVGV4dCwgb3RoZXJUZXh0LCBkZWZhdWx0QnV0dG9uLCBjYW5jZWxCdXR0b24sIHBvc2l0aW9uLCBmbGFnczsKK30gQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNfRklEX0NBQ0hFOworCitBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY19GSURfQ0FDSEUgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYzsKKwordm9pZCBjYWNoZUFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmlkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCkKK3sKKwlpZiAoQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5jYWNoZWQpIHJldHVybjsKKwlBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmNsYXp6ID0gKCplbnYpLT5HZXRPYmplY3RDbGFzcyhlbnYsIGxwT2JqZWN0KTsKKwlBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLnZlcnNpb24gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmNsYXp6LCAidmVyc2lvbiIsICJJIik7CisJQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5tb3ZhYmxlID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5jbGF6eiwgIm1vdmFibGUiLCAiWiIpOworCUFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMuaGVscEJ1dHRvbiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMuY2xhenosICJoZWxwQnV0dG9uIiwgIloiKTsKKwlBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmRlZmF1bHRUZXh0ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5jbGF6eiwgImRlZmF1bHRUZXh0IiwgIkkiKTsKKwlBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmNhbmNlbFRleHQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmNsYXp6LCAiY2FuY2VsVGV4dCIsICJJIik7CisJQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5vdGhlclRleHQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmNsYXp6LCAib3RoZXJUZXh0IiwgIkkiKTsKKwlBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmRlZmF1bHRCdXR0b24gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmNsYXp6LCAiZGVmYXVsdEJ1dHRvbiIsICJTIik7CisJQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5jYW5jZWxCdXR0b24gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmNsYXp6LCAiY2FuY2VsQnV0dG9uIiwgIlMiKTsKKwlBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLnBvc2l0aW9uID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5jbGF6eiwgInBvc2l0aW9uIiwgIlMiKTsKKwlBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmZsYWdzID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5jbGF6eiwgImZsYWdzIiwgIkkiKTsKKwlBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmNhY2hlZCA9IDE7Cit9CisKK0FsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjICpnZXRBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWMgKmxwU3RydWN0KQoreworCWlmICghQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5jYWNoZWQpIGNhY2hlQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT52ZXJzaW9uID0gKFVJbnQzMikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMudmVyc2lvbik7CisJbHBTdHJ1Y3QtPm1vdmFibGUgPSAoQm9vbGVhbikoKmVudiktPkdldEJvb2xlYW5GaWVsZChlbnYsIGxwT2JqZWN0LCBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLm1vdmFibGUpOworCWxwU3RydWN0LT5oZWxwQnV0dG9uID0gKEJvb2xlYW4pKCplbnYpLT5HZXRCb29sZWFuRmllbGQoZW52LCBscE9iamVjdCwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5oZWxwQnV0dG9uKTsKKwlscFN0cnVjdC0+ZGVmYXVsdFRleHQgPSAoQ0ZTdHJpbmdSZWYpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmRlZmF1bHRUZXh0KTsKKwlscFN0cnVjdC0+Y2FuY2VsVGV4dCA9IChDRlN0cmluZ1JlZikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMuY2FuY2VsVGV4dCk7CisJbHBTdHJ1Y3QtPm90aGVyVGV4dCA9IChDRlN0cmluZ1JlZikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMub3RoZXJUZXh0KTsKKwlscFN0cnVjdC0+ZGVmYXVsdEJ1dHRvbiA9IChTSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMuZGVmYXVsdEJ1dHRvbik7CisJbHBTdHJ1Y3QtPmNhbmNlbEJ1dHRvbiA9IChTSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMuY2FuY2VsQnV0dG9uKTsKKwlscFN0cnVjdC0+cG9zaXRpb24gPSAoVUludDE2KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLnBvc2l0aW9uKTsKKwlscFN0cnVjdC0+ZmxhZ3MgPSAoT3B0aW9uQml0cykoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMuZmxhZ3MpOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXRBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWMgKmxwU3RydWN0KQoreworCWlmICghQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5jYWNoZWQpIGNhY2hlQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGaWRzKGVudiwgbHBPYmplY3QpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy52ZXJzaW9uLCAoamludClscFN0cnVjdC0+dmVyc2lvbik7CisJKCplbnYpLT5TZXRCb29sZWFuRmllbGQoZW52LCBscE9iamVjdCwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5tb3ZhYmxlLCAoamJvb2xlYW4pbHBTdHJ1Y3QtPm1vdmFibGUpOworCSgqZW52KS0+U2V0Qm9vbGVhbkZpZWxkKGVudiwgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMuaGVscEJ1dHRvbiwgKGpib29sZWFuKWxwU3RydWN0LT5oZWxwQnV0dG9uKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMuZGVmYXVsdFRleHQsIChqaW50KWxwU3RydWN0LT5kZWZhdWx0VGV4dCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZjLmNhbmNlbFRleHQsIChqaW50KWxwU3RydWN0LT5jYW5jZWxUZXh0KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMub3RoZXJUZXh0LCAoamludClscFN0cnVjdC0+b3RoZXJUZXh0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5kZWZhdWx0QnV0dG9uLCAoanNob3J0KWxwU3RydWN0LT5kZWZhdWx0QnV0dG9uKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGYy5jYW5jZWxCdXR0b24sIChqc2hvcnQpbHBTdHJ1Y3QtPmNhbmNlbEJ1dHRvbik7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMucG9zaXRpb24sIChqc2hvcnQpbHBTdHJ1Y3QtPnBvc2l0aW9uKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmMuZmxhZ3MsIChqaW50KWxwU3RydWN0LT5mbGFncyk7Cit9CisjZW5kaWYgLyogTk9fQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWMgKi8KKworI2lmbmRlZiBOT19CaXRNYXAKK3R5cGVkZWYgc3RydWN0IEJpdE1hcF9GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIGJhc2VBZGRyLCByb3dCeXRlcywgdG9wLCBsZWZ0LCBib3R0b20sIHJpZ2h0OworfSBCaXRNYXBfRklEX0NBQ0hFOworCitCaXRNYXBfRklEX0NBQ0hFIEJpdE1hcEZjOworCit2b2lkIGNhY2hlQml0TWFwRmlkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCkKK3sKKwlpZiAoQml0TWFwRmMuY2FjaGVkKSByZXR1cm47CisJQml0TWFwRmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCUJpdE1hcEZjLmJhc2VBZGRyID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQml0TWFwRmMuY2xhenosICJiYXNlQWRkciIsICJJIik7CisJQml0TWFwRmMucm93Qnl0ZXMgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBCaXRNYXBGYy5jbGF6eiwgInJvd0J5dGVzIiwgIlMiKTsKKwlCaXRNYXBGYy50b3AgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBCaXRNYXBGYy5jbGF6eiwgInRvcCIsICJTIik7CisJQml0TWFwRmMubGVmdCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEJpdE1hcEZjLmNsYXp6LCAibGVmdCIsICJTIik7CisJQml0TWFwRmMuYm90dG9tID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQml0TWFwRmMuY2xhenosICJib3R0b20iLCAiUyIpOworCUJpdE1hcEZjLnJpZ2h0ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQml0TWFwRmMuY2xhenosICJyaWdodCIsICJTIik7CisJQml0TWFwRmMuY2FjaGVkID0gMTsKK30KKworQml0TWFwICpnZXRCaXRNYXBGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIEJpdE1hcCAqbHBTdHJ1Y3QpCit7CisJaWYgKCFCaXRNYXBGYy5jYWNoZWQpIGNhY2hlQml0TWFwRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+YmFzZUFkZHIgPSAodm9pZCAqKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQml0TWFwRmMuYmFzZUFkZHIpOworCWxwU3RydWN0LT5yb3dCeXRlcyA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBCaXRNYXBGYy5yb3dCeXRlcyk7CisJbHBTdHJ1Y3QtPmJvdW5kcy50b3AgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQml0TWFwRmMudG9wKTsKKwlscFN0cnVjdC0+Ym91bmRzLmxlZnQgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQml0TWFwRmMubGVmdCk7CisJbHBTdHJ1Y3QtPmJvdW5kcy5ib3R0b20gPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQml0TWFwRmMuYm90dG9tKTsKKwlscFN0cnVjdC0+Ym91bmRzLnJpZ2h0ID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEJpdE1hcEZjLnJpZ2h0KTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0Qml0TWFwRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBCaXRNYXAgKmxwU3RydWN0KQoreworCWlmICghQml0TWFwRmMuY2FjaGVkKSBjYWNoZUJpdE1hcEZpZHMoZW52LCBscE9iamVjdCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBCaXRNYXBGYy5iYXNlQWRkciwgKGppbnQpbHBTdHJ1Y3QtPmJhc2VBZGRyKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQml0TWFwRmMucm93Qnl0ZXMsIChqc2hvcnQpbHBTdHJ1Y3QtPnJvd0J5dGVzKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQml0TWFwRmMudG9wLCAoanNob3J0KWxwU3RydWN0LT5ib3VuZHMudG9wKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQml0TWFwRmMubGVmdCwgKGpzaG9ydClscFN0cnVjdC0+Ym91bmRzLmxlZnQpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBCaXRNYXBGYy5ib3R0b20sIChqc2hvcnQpbHBTdHJ1Y3QtPmJvdW5kcy5ib3R0b20pOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBCaXRNYXBGYy5yaWdodCwgKGpzaG9ydClscFN0cnVjdC0+Ym91bmRzLnJpZ2h0KTsKK30KKyNlbmRpZiAvKiBOT19CaXRNYXAgKi8KKworI2lmbmRlZiBOT19DRlJhbmdlCit0eXBlZGVmIHN0cnVjdCBDRlJhbmdlX0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgbG9jYXRpb24sIGxlbmd0aDsKK30gQ0ZSYW5nZV9GSURfQ0FDSEU7CisKK0NGUmFuZ2VfRklEX0NBQ0hFIENGUmFuZ2VGYzsKKwordm9pZCBjYWNoZUNGUmFuZ2VGaWRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0KQoreworCWlmIChDRlJhbmdlRmMuY2FjaGVkKSByZXR1cm47CisJQ0ZSYW5nZUZjLmNsYXp6ID0gKCplbnYpLT5HZXRPYmplY3RDbGFzcyhlbnYsIGxwT2JqZWN0KTsKKwlDRlJhbmdlRmMubG9jYXRpb24gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDRlJhbmdlRmMuY2xhenosICJsb2NhdGlvbiIsICJJIik7CisJQ0ZSYW5nZUZjLmxlbmd0aCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENGUmFuZ2VGYy5jbGF6eiwgImxlbmd0aCIsICJJIik7CisJQ0ZSYW5nZUZjLmNhY2hlZCA9IDE7Cit9CisKK0NGUmFuZ2UgKmdldENGUmFuZ2VGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENGUmFuZ2UgKmxwU3RydWN0KQoreworCWlmICghQ0ZSYW5nZUZjLmNhY2hlZCkgY2FjaGVDRlJhbmdlRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+bG9jYXRpb24gPSAoQ0ZJbmRleCkoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIENGUmFuZ2VGYy5sb2NhdGlvbik7CisJbHBTdHJ1Y3QtPmxlbmd0aCA9IChDRkluZGV4KSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQ0ZSYW5nZUZjLmxlbmd0aCk7CisJcmV0dXJuIGxwU3RydWN0OworfQorCit2b2lkIHNldENGUmFuZ2VGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENGUmFuZ2UgKmxwU3RydWN0KQoreworCWlmICghQ0ZSYW5nZUZjLmNhY2hlZCkgY2FjaGVDRlJhbmdlRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIENGUmFuZ2VGYy5sb2NhdGlvbiwgKGppbnQpbHBTdHJ1Y3QtPmxvY2F0aW9uKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIENGUmFuZ2VGYy5sZW5ndGgsIChqaW50KWxwU3RydWN0LT5sZW5ndGgpOworfQorI2VuZGlmIC8qIE5PX0NGUmFuZ2UgKi8KKworI2lmbmRlZiBOT19DR1BvaW50Cit0eXBlZGVmIHN0cnVjdCBDR1BvaW50X0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgeCwgeTsKK30gQ0dQb2ludF9GSURfQ0FDSEU7CisKK0NHUG9pbnRfRklEX0NBQ0hFIENHUG9pbnRGYzsKKwordm9pZCBjYWNoZUNHUG9pbnRGaWRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0KQoreworCWlmIChDR1BvaW50RmMuY2FjaGVkKSByZXR1cm47CisJQ0dQb2ludEZjLmNsYXp6ID0gKCplbnYpLT5HZXRPYmplY3RDbGFzcyhlbnYsIGxwT2JqZWN0KTsKKwlDR1BvaW50RmMueCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENHUG9pbnRGYy5jbGF6eiwgIngiLCAiRiIpOworCUNHUG9pbnRGYy55ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ0dQb2ludEZjLmNsYXp6LCAieSIsICJGIik7CisJQ0dQb2ludEZjLmNhY2hlZCA9IDE7Cit9CisKK0NHUG9pbnQgKmdldENHUG9pbnRGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENHUG9pbnQgKmxwU3RydWN0KQoreworCWlmICghQ0dQb2ludEZjLmNhY2hlZCkgY2FjaGVDR1BvaW50RmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+eCA9IChmbG9hdCkoKmVudiktPkdldEZsb2F0RmllbGQoZW52LCBscE9iamVjdCwgQ0dQb2ludEZjLngpOworCWxwU3RydWN0LT55ID0gKGZsb2F0KSgqZW52KS0+R2V0RmxvYXRGaWVsZChlbnYsIGxwT2JqZWN0LCBDR1BvaW50RmMueSk7CisJcmV0dXJuIGxwU3RydWN0OworfQorCit2b2lkIHNldENHUG9pbnRGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENHUG9pbnQgKmxwU3RydWN0KQoreworCWlmICghQ0dQb2ludEZjLmNhY2hlZCkgY2FjaGVDR1BvaW50RmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldEZsb2F0RmllbGQoZW52LCBscE9iamVjdCwgQ0dQb2ludEZjLngsIChqZmxvYXQpbHBTdHJ1Y3QtPngpOworCSgqZW52KS0+U2V0RmxvYXRGaWVsZChlbnYsIGxwT2JqZWN0LCBDR1BvaW50RmMueSwgKGpmbG9hdClscFN0cnVjdC0+eSk7Cit9CisjZW5kaWYgLyogTk9fQ0dQb2ludCAqLworCisjaWZuZGVmIE5PX0NHUmVjdAordHlwZWRlZiBzdHJ1Y3QgQ0dSZWN0X0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgeCwgeSwgd2lkdGgsIGhlaWdodDsKK30gQ0dSZWN0X0ZJRF9DQUNIRTsKKworQ0dSZWN0X0ZJRF9DQUNIRSBDR1JlY3RGYzsKKwordm9pZCBjYWNoZUNHUmVjdEZpZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QpCit7CisJaWYgKENHUmVjdEZjLmNhY2hlZCkgcmV0dXJuOworCUNHUmVjdEZjLmNsYXp6ID0gKCplbnYpLT5HZXRPYmplY3RDbGFzcyhlbnYsIGxwT2JqZWN0KTsKKwlDR1JlY3RGYy54ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ0dSZWN0RmMuY2xhenosICJ4IiwgIkYiKTsKKwlDR1JlY3RGYy55ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ0dSZWN0RmMuY2xhenosICJ5IiwgIkYiKTsKKwlDR1JlY3RGYy53aWR0aCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENHUmVjdEZjLmNsYXp6LCAid2lkdGgiLCAiRiIpOworCUNHUmVjdEZjLmhlaWdodCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENHUmVjdEZjLmNsYXp6LCAiaGVpZ2h0IiwgIkYiKTsKKwlDR1JlY3RGYy5jYWNoZWQgPSAxOworfQorCitDR1JlY3QgKmdldENHUmVjdEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ0dSZWN0ICpscFN0cnVjdCkKK3sKKwlpZiAoIUNHUmVjdEZjLmNhY2hlZCkgY2FjaGVDR1JlY3RGaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT5vcmlnaW4ueCA9IChmbG9hdCkoKmVudiktPkdldEZsb2F0RmllbGQoZW52LCBscE9iamVjdCwgQ0dSZWN0RmMueCk7CisJbHBTdHJ1Y3QtPm9yaWdpbi55ID0gKGZsb2F0KSgqZW52KS0+R2V0RmxvYXRGaWVsZChlbnYsIGxwT2JqZWN0LCBDR1JlY3RGYy55KTsKKwlscFN0cnVjdC0+c2l6ZS53aWR0aCA9IChmbG9hdCkoKmVudiktPkdldEZsb2F0RmllbGQoZW52LCBscE9iamVjdCwgQ0dSZWN0RmMud2lkdGgpOworCWxwU3RydWN0LT5zaXplLmhlaWdodCA9IChmbG9hdCkoKmVudiktPkdldEZsb2F0RmllbGQoZW52LCBscE9iamVjdCwgQ0dSZWN0RmMuaGVpZ2h0KTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0Q0dSZWN0RmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBDR1JlY3QgKmxwU3RydWN0KQoreworCWlmICghQ0dSZWN0RmMuY2FjaGVkKSBjYWNoZUNHUmVjdEZpZHMoZW52LCBscE9iamVjdCk7CisJKCplbnYpLT5TZXRGbG9hdEZpZWxkKGVudiwgbHBPYmplY3QsIENHUmVjdEZjLngsIChqZmxvYXQpbHBTdHJ1Y3QtPm9yaWdpbi54KTsKKwkoKmVudiktPlNldEZsb2F0RmllbGQoZW52LCBscE9iamVjdCwgQ0dSZWN0RmMueSwgKGpmbG9hdClscFN0cnVjdC0+b3JpZ2luLnkpOworCSgqZW52KS0+U2V0RmxvYXRGaWVsZChlbnYsIGxwT2JqZWN0LCBDR1JlY3RGYy53aWR0aCwgKGpmbG9hdClscFN0cnVjdC0+c2l6ZS53aWR0aCk7CisJKCplbnYpLT5TZXRGbG9hdEZpZWxkKGVudiwgbHBPYmplY3QsIENHUmVjdEZjLmhlaWdodCwgKGpmbG9hdClscFN0cnVjdC0+c2l6ZS5oZWlnaHQpOworfQorI2VuZGlmIC8qIE5PX0NHUmVjdCAqLworCisjaWZuZGVmIE5PX0NvbG9yUGlja2VySW5mbwordHlwZWRlZiBzdHJ1Y3QgQ29sb3JQaWNrZXJJbmZvX0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgcHJvZmlsZSwgcmVkLCBncmVlbiwgYmx1ZSwgZHN0UHJvZmlsZSwgZmxhZ3MsIHBsYWNlV2hlcmUsIGgsIHYsIHBpY2tlclR5cGUsIGV2ZW50UHJvYywgY29sb3JQcm9jLCBjb2xvclByb2NEYXRhLCBwcm9tcHQsIGVkaXRNZW51SUQsIGN1dEl0ZW0sIGNvcHlJdGVtLCBwYXN0ZUl0ZW0sIGNsZWFySXRlbSwgdW5kb0l0ZW0sIG5ld0NvbG9yQ2hvc2VuOworfSBDb2xvclBpY2tlckluZm9fRklEX0NBQ0hFOworCitDb2xvclBpY2tlckluZm9fRklEX0NBQ0hFIENvbG9yUGlja2VySW5mb0ZjOworCit2b2lkIGNhY2hlQ29sb3JQaWNrZXJJbmZvRmlkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCkKK3sKKwlpZiAoQ29sb3JQaWNrZXJJbmZvRmMuY2FjaGVkKSByZXR1cm47CisJQ29sb3JQaWNrZXJJbmZvRmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCUNvbG9yUGlja2VySW5mb0ZjLnByb2ZpbGUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb2xvclBpY2tlckluZm9GYy5jbGF6eiwgInByb2ZpbGUiLCAiSSIpOworCUNvbG9yUGlja2VySW5mb0ZjLnJlZCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbG9yUGlja2VySW5mb0ZjLmNsYXp6LCAicmVkIiwgIlMiKTsKKwlDb2xvclBpY2tlckluZm9GYy5ncmVlbiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbG9yUGlja2VySW5mb0ZjLmNsYXp6LCAiZ3JlZW4iLCAiUyIpOworCUNvbG9yUGlja2VySW5mb0ZjLmJsdWUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb2xvclBpY2tlckluZm9GYy5jbGF6eiwgImJsdWUiLCAiUyIpOworCUNvbG9yUGlja2VySW5mb0ZjLmRzdFByb2ZpbGUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb2xvclBpY2tlckluZm9GYy5jbGF6eiwgImRzdFByb2ZpbGUiLCAiSSIpOworCUNvbG9yUGlja2VySW5mb0ZjLmZsYWdzID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29sb3JQaWNrZXJJbmZvRmMuY2xhenosICJmbGFncyIsICJJIik7CisJQ29sb3JQaWNrZXJJbmZvRmMucGxhY2VXaGVyZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbG9yUGlja2VySW5mb0ZjLmNsYXp6LCAicGxhY2VXaGVyZSIsICJTIik7CisJQ29sb3JQaWNrZXJJbmZvRmMuaCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbG9yUGlja2VySW5mb0ZjLmNsYXp6LCAiaCIsICJTIik7CisJQ29sb3JQaWNrZXJJbmZvRmMudiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbG9yUGlja2VySW5mb0ZjLmNsYXp6LCAidiIsICJTIik7CisJQ29sb3JQaWNrZXJJbmZvRmMucGlja2VyVHlwZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbG9yUGlja2VySW5mb0ZjLmNsYXp6LCAicGlja2VyVHlwZSIsICJJIik7CisJQ29sb3JQaWNrZXJJbmZvRmMuZXZlbnRQcm9jID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29sb3JQaWNrZXJJbmZvRmMuY2xhenosICJldmVudFByb2MiLCAiSSIpOworCUNvbG9yUGlja2VySW5mb0ZjLmNvbG9yUHJvYyA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbG9yUGlja2VySW5mb0ZjLmNsYXp6LCAiY29sb3JQcm9jIiwgIkkiKTsKKwlDb2xvclBpY2tlckluZm9GYy5jb2xvclByb2NEYXRhID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29sb3JQaWNrZXJJbmZvRmMuY2xhenosICJjb2xvclByb2NEYXRhIiwgIkkiKTsKKwlDb2xvclBpY2tlckluZm9GYy5wcm9tcHQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb2xvclBpY2tlckluZm9GYy5jbGF6eiwgInByb21wdCIsICJbQiIpOworCUNvbG9yUGlja2VySW5mb0ZjLmVkaXRNZW51SUQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb2xvclBpY2tlckluZm9GYy5jbGF6eiwgImVkaXRNZW51SUQiLCAiUyIpOworCUNvbG9yUGlja2VySW5mb0ZjLmN1dEl0ZW0gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb2xvclBpY2tlckluZm9GYy5jbGF6eiwgImN1dEl0ZW0iLCAiUyIpOworCUNvbG9yUGlja2VySW5mb0ZjLmNvcHlJdGVtID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29sb3JQaWNrZXJJbmZvRmMuY2xhenosICJjb3B5SXRlbSIsICJTIik7CisJQ29sb3JQaWNrZXJJbmZvRmMucGFzdGVJdGVtID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29sb3JQaWNrZXJJbmZvRmMuY2xhenosICJwYXN0ZUl0ZW0iLCAiUyIpOworCUNvbG9yUGlja2VySW5mb0ZjLmNsZWFySXRlbSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbG9yUGlja2VySW5mb0ZjLmNsYXp6LCAiY2xlYXJJdGVtIiwgIlMiKTsKKwlDb2xvclBpY2tlckluZm9GYy51bmRvSXRlbSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbG9yUGlja2VySW5mb0ZjLmNsYXp6LCAidW5kb0l0ZW0iLCAiUyIpOworCUNvbG9yUGlja2VySW5mb0ZjLm5ld0NvbG9yQ2hvc2VuID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29sb3JQaWNrZXJJbmZvRmMuY2xhenosICJuZXdDb2xvckNob3NlbiIsICJaIik7CisJQ29sb3JQaWNrZXJJbmZvRmMuY2FjaGVkID0gMTsKK30KKworQ29sb3JQaWNrZXJJbmZvICpnZXRDb2xvclBpY2tlckluZm9GaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENvbG9yUGlja2VySW5mbyAqbHBTdHJ1Y3QpCit7CisJaWYgKCFDb2xvclBpY2tlckluZm9GYy5jYWNoZWQpIGNhY2hlQ29sb3JQaWNrZXJJbmZvRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+dGhlQ29sb3IucHJvZmlsZSA9IChDTVByb2ZpbGVIYW5kbGUpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy5wcm9maWxlKTsKKwlscFN0cnVjdC0+dGhlQ29sb3IuY29sb3IucmdiLnJlZCA9IChVSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLnJlZCk7CisJbHBTdHJ1Y3QtPnRoZUNvbG9yLmNvbG9yLnJnYi5ncmVlbiA9IChVSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLmdyZWVuKTsKKwlscFN0cnVjdC0+dGhlQ29sb3IuY29sb3IucmdiLmJsdWUgPSAoVUludDE2KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy5ibHVlKTsKKwlscFN0cnVjdC0+ZHN0UHJvZmlsZSA9IChDTVByb2ZpbGVIYW5kbGUpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy5kc3RQcm9maWxlKTsKKwlscFN0cnVjdC0+ZmxhZ3MgPSAoVUludDMyKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMuZmxhZ3MpOworCWxwU3RydWN0LT5wbGFjZVdoZXJlID0gKERpYWxvZ1BsYWNlbWVudFNwZWMpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLnBsYWNlV2hlcmUpOworCWxwU3RydWN0LT5kaWFsb2dPcmlnaW4uaCA9IChzaG9ydCkoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMuaCk7CisJbHBTdHJ1Y3QtPmRpYWxvZ09yaWdpbi52ID0gKHNob3J0KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy52KTsKKwlscFN0cnVjdC0+cGlja2VyVHlwZSA9IChPU1R5cGUpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy5waWNrZXJUeXBlKTsKKwlscFN0cnVjdC0+ZXZlbnRQcm9jID0gKFVzZXJFdmVudFVQUCkoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLmV2ZW50UHJvYyk7CisJbHBTdHJ1Y3QtPmNvbG9yUHJvYyA9IChDb2xvckNoYW5nZWRVUFApKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy5jb2xvclByb2MpOworCWxwU3RydWN0LT5jb2xvclByb2NEYXRhID0gKFVJbnQzMikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLmNvbG9yUHJvY0RhdGEpOworCXsKKwlqYnl0ZUFycmF5IGxwT2JqZWN0MSA9ICgqZW52KS0+R2V0T2JqZWN0RmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMucHJvbXB0KTsKKwkoKmVudiktPkdldEJ5dGVBcnJheVJlZ2lvbihlbnYsIGxwT2JqZWN0MSwgMCwgc2l6ZW9mKGxwU3RydWN0LT5wcm9tcHQpLCBscFN0cnVjdC0+cHJvbXB0KTsKKwl9CisJbHBTdHJ1Y3QtPm1JbmZvLmVkaXRNZW51SUQgPSAoU0ludDE2KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy5lZGl0TWVudUlEKTsKKwlscFN0cnVjdC0+bUluZm8uY3V0SXRlbSA9IChTSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLmN1dEl0ZW0pOworCWxwU3RydWN0LT5tSW5mby5jb3B5SXRlbSA9IChTSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLmNvcHlJdGVtKTsKKwlscFN0cnVjdC0+bUluZm8ucGFzdGVJdGVtID0gKFNJbnQxNikoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMucGFzdGVJdGVtKTsKKwlscFN0cnVjdC0+bUluZm8uY2xlYXJJdGVtID0gKFNJbnQxNikoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMuY2xlYXJJdGVtKTsKKwlscFN0cnVjdC0+bUluZm8udW5kb0l0ZW0gPSAoU0ludDE2KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy51bmRvSXRlbSk7CisJbHBTdHJ1Y3QtPm5ld0NvbG9yQ2hvc2VuID0gKEJvb2xlYW4pKCplbnYpLT5HZXRCb29sZWFuRmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMubmV3Q29sb3JDaG9zZW4pOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXRDb2xvclBpY2tlckluZm9GaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENvbG9yUGlja2VySW5mbyAqbHBTdHJ1Y3QpCit7CisJaWYgKCFDb2xvclBpY2tlckluZm9GYy5jYWNoZWQpIGNhY2hlQ29sb3JQaWNrZXJJbmZvRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLnByb2ZpbGUsIChqaW50KWxwU3RydWN0LT50aGVDb2xvci5wcm9maWxlKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMucmVkLCAoanNob3J0KWxwU3RydWN0LT50aGVDb2xvci5jb2xvci5yZ2IucmVkKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMuZ3JlZW4sIChqc2hvcnQpbHBTdHJ1Y3QtPnRoZUNvbG9yLmNvbG9yLnJnYi5ncmVlbik7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLmJsdWUsIChqc2hvcnQpbHBTdHJ1Y3QtPnRoZUNvbG9yLmNvbG9yLnJnYi5ibHVlKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLmRzdFByb2ZpbGUsIChqaW50KWxwU3RydWN0LT5kc3RQcm9maWxlKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLmZsYWdzLCAoamludClscFN0cnVjdC0+ZmxhZ3MpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy5wbGFjZVdoZXJlLCAoanNob3J0KWxwU3RydWN0LT5wbGFjZVdoZXJlKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMuaCwgKGpzaG9ydClscFN0cnVjdC0+ZGlhbG9nT3JpZ2luLmgpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy52LCAoanNob3J0KWxwU3RydWN0LT5kaWFsb2dPcmlnaW4udik7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy5waWNrZXJUeXBlLCAoamludClscFN0cnVjdC0+cGlja2VyVHlwZSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy5ldmVudFByb2MsIChqaW50KWxwU3RydWN0LT5ldmVudFByb2MpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMuY29sb3JQcm9jLCAoamludClscFN0cnVjdC0+Y29sb3JQcm9jKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLmNvbG9yUHJvY0RhdGEsIChqaW50KWxwU3RydWN0LT5jb2xvclByb2NEYXRhKTsKKwl7CisJamJ5dGVBcnJheSBscE9iamVjdDEgPSAoKmVudiktPkdldE9iamVjdEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLnByb21wdCk7CisJKCplbnYpLT5TZXRCeXRlQXJyYXlSZWdpb24oZW52LCBscE9iamVjdDEsIDAsIHNpemVvZihscFN0cnVjdC0+cHJvbXB0KSwgbHBTdHJ1Y3QtPnByb21wdCk7CisJfQorCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy5lZGl0TWVudUlELCAoanNob3J0KWxwU3RydWN0LT5tSW5mby5lZGl0TWVudUlEKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMuY3V0SXRlbSwgKGpzaG9ydClscFN0cnVjdC0+bUluZm8uY3V0SXRlbSk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLmNvcHlJdGVtLCAoanNob3J0KWxwU3RydWN0LT5tSW5mby5jb3B5SXRlbSk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLnBhc3RlSXRlbSwgKGpzaG9ydClscFN0cnVjdC0+bUluZm8ucGFzdGVJdGVtKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvRmMuY2xlYXJJdGVtLCAoanNob3J0KWxwU3RydWN0LT5tSW5mby5jbGVhckl0ZW0pOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb2xvclBpY2tlckluZm9GYy51bmRvSXRlbSwgKGpzaG9ydClscFN0cnVjdC0+bUluZm8udW5kb0l0ZW0pOworCSgqZW52KS0+U2V0Qm9vbGVhbkZpZWxkKGVudiwgbHBPYmplY3QsIENvbG9yUGlja2VySW5mb0ZjLm5ld0NvbG9yQ2hvc2VuLCAoamJvb2xlYW4pbHBTdHJ1Y3QtPm5ld0NvbG9yQ2hvc2VuKTsKK30KKyNlbmRpZiAvKiBOT19Db2xvclBpY2tlckluZm8gKi8KKworI2lmbmRlZiBOT19Db250cm9sQnV0dG9uQ29udGVudEluZm8KK3R5cGVkZWYgc3RydWN0IENvbnRyb2xCdXR0b25Db250ZW50SW5mb19GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIGNvbnRlbnRUeXBlLCBpY29uUmVmOworfSBDb250cm9sQnV0dG9uQ29udGVudEluZm9fRklEX0NBQ0hFOworCitDb250cm9sQnV0dG9uQ29udGVudEluZm9fRklEX0NBQ0hFIENvbnRyb2xCdXR0b25Db250ZW50SW5mb0ZjOworCit2b2lkIGNhY2hlQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmlkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCkKK3sKKwlpZiAoQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmMuY2FjaGVkKSByZXR1cm47CisJQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCUNvbnRyb2xCdXR0b25Db250ZW50SW5mb0ZjLmNvbnRlbnRUeXBlID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmMuY2xhenosICJjb250ZW50VHlwZSIsICJTIik7CisJQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmMuaWNvblJlZiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbnRyb2xCdXR0b25Db250ZW50SW5mb0ZjLmNsYXp6LCAiaWNvblJlZiIsICJJIik7CisJQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmMuY2FjaGVkID0gMTsKK30KKworQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvICpnZXRDb250cm9sQnV0dG9uQ29udGVudEluZm9GaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENvbnRyb2xCdXR0b25Db250ZW50SW5mbyAqbHBTdHJ1Y3QpCit7CisJaWYgKCFDb250cm9sQnV0dG9uQ29udGVudEluZm9GYy5jYWNoZWQpIGNhY2hlQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+Y29udGVudFR5cGUgPSAoQ29udHJvbENvbnRlbnRUeXBlKSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sQnV0dG9uQ29udGVudEluZm9GYy5jb250ZW50VHlwZSk7CisJbHBTdHJ1Y3QtPnUuaWNvblJlZiA9ICh2b2lkICopKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sQnV0dG9uQ29udGVudEluZm9GYy5pY29uUmVmKTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0Q29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBDb250cm9sQnV0dG9uQ29udGVudEluZm8gKmxwU3RydWN0KQoreworCWlmICghQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmMuY2FjaGVkKSBjYWNoZUNvbnRyb2xCdXR0b25Db250ZW50SW5mb0ZpZHMoZW52LCBscE9iamVjdCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbnRyb2xCdXR0b25Db250ZW50SW5mb0ZjLmNvbnRlbnRUeXBlLCAoanNob3J0KWxwU3RydWN0LT5jb250ZW50VHlwZSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sQnV0dG9uQ29udGVudEluZm9GYy5pY29uUmVmLCAoamludClscFN0cnVjdC0+dS5pY29uUmVmKTsKK30KKyNlbmRpZiAvKiBOT19Db250cm9sQnV0dG9uQ29udGVudEluZm8gKi8KKworI2lmbmRlZiBOT19Db250cm9sRm9udFN0eWxlUmVjCit0eXBlZGVmIHN0cnVjdCBDb250cm9sRm9udFN0eWxlUmVjX0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgZmxhZ3MsIGZvbnQsIHNpemUsIHN0eWxlLCBtb2RlLCBqdXN0LCBmb3JlQ29sb3JfcmVkLCBmb3JlQ29sb3JfZ3JlZW4sIGZvcmVDb2xvcl9ibHVlLCBiYWNrQ29sb3JfcmVkLCBiYWNrQ29sb3JfZ3JlZW4sIGJhY2tDb2xvcl9ibHVlOworfSBDb250cm9sRm9udFN0eWxlUmVjX0ZJRF9DQUNIRTsKKworQ29udHJvbEZvbnRTdHlsZVJlY19GSURfQ0FDSEUgQ29udHJvbEZvbnRTdHlsZVJlY0ZjOworCit2b2lkIGNhY2hlQ29udHJvbEZvbnRTdHlsZVJlY0ZpZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QpCit7CisJaWYgKENvbnRyb2xGb250U3R5bGVSZWNGYy5jYWNoZWQpIHJldHVybjsKKwlDb250cm9sRm9udFN0eWxlUmVjRmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCUNvbnRyb2xGb250U3R5bGVSZWNGYy5mbGFncyA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbnRyb2xGb250U3R5bGVSZWNGYy5jbGF6eiwgImZsYWdzIiwgIlMiKTsKKwlDb250cm9sRm9udFN0eWxlUmVjRmMuZm9udCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbnRyb2xGb250U3R5bGVSZWNGYy5jbGF6eiwgImZvbnQiLCAiUyIpOworCUNvbnRyb2xGb250U3R5bGVSZWNGYy5zaXplID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29udHJvbEZvbnRTdHlsZVJlY0ZjLmNsYXp6LCAic2l6ZSIsICJTIik7CisJQ29udHJvbEZvbnRTdHlsZVJlY0ZjLnN0eWxlID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29udHJvbEZvbnRTdHlsZVJlY0ZjLmNsYXp6LCAic3R5bGUiLCAiUyIpOworCUNvbnRyb2xGb250U3R5bGVSZWNGYy5tb2RlID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29udHJvbEZvbnRTdHlsZVJlY0ZjLmNsYXp6LCAibW9kZSIsICJTIik7CisJQ29udHJvbEZvbnRTdHlsZVJlY0ZjLmp1c3QgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb250cm9sRm9udFN0eWxlUmVjRmMuY2xhenosICJqdXN0IiwgIlMiKTsKKwlDb250cm9sRm9udFN0eWxlUmVjRmMuZm9yZUNvbG9yX3JlZCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbnRyb2xGb250U3R5bGVSZWNGYy5jbGF6eiwgImZvcmVDb2xvcl9yZWQiLCAiUyIpOworCUNvbnRyb2xGb250U3R5bGVSZWNGYy5mb3JlQ29sb3JfZ3JlZW4gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb250cm9sRm9udFN0eWxlUmVjRmMuY2xhenosICJmb3JlQ29sb3JfZ3JlZW4iLCAiUyIpOworCUNvbnRyb2xGb250U3R5bGVSZWNGYy5mb3JlQ29sb3JfYmx1ZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbnRyb2xGb250U3R5bGVSZWNGYy5jbGF6eiwgImZvcmVDb2xvcl9ibHVlIiwgIlMiKTsKKwlDb250cm9sRm9udFN0eWxlUmVjRmMuYmFja0NvbG9yX3JlZCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbnRyb2xGb250U3R5bGVSZWNGYy5jbGF6eiwgImJhY2tDb2xvcl9yZWQiLCAiUyIpOworCUNvbnRyb2xGb250U3R5bGVSZWNGYy5iYWNrQ29sb3JfZ3JlZW4gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb250cm9sRm9udFN0eWxlUmVjRmMuY2xhenosICJiYWNrQ29sb3JfZ3JlZW4iLCAiUyIpOworCUNvbnRyb2xGb250U3R5bGVSZWNGYy5iYWNrQ29sb3JfYmx1ZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIENvbnRyb2xGb250U3R5bGVSZWNGYy5jbGF6eiwgImJhY2tDb2xvcl9ibHVlIiwgIlMiKTsKKwlDb250cm9sRm9udFN0eWxlUmVjRmMuY2FjaGVkID0gMTsKK30KKworQ29udHJvbEZvbnRTdHlsZVJlYyAqZ2V0Q29udHJvbEZvbnRTdHlsZVJlY0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ29udHJvbEZvbnRTdHlsZVJlYyAqbHBTdHJ1Y3QpCit7CisJaWYgKCFDb250cm9sRm9udFN0eWxlUmVjRmMuY2FjaGVkKSBjYWNoZUNvbnRyb2xGb250U3R5bGVSZWNGaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT5mbGFncyA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuZmxhZ3MpOworCWxwU3RydWN0LT5mb250ID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbnRyb2xGb250U3R5bGVSZWNGYy5mb250KTsKKwlscFN0cnVjdC0+c2l6ZSA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuc2l6ZSk7CisJbHBTdHJ1Y3QtPnN0eWxlID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbnRyb2xGb250U3R5bGVSZWNGYy5zdHlsZSk7CisJbHBTdHJ1Y3QtPm1vZGUgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29udHJvbEZvbnRTdHlsZVJlY0ZjLm1vZGUpOworCWxwU3RydWN0LT5qdXN0ID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbnRyb2xGb250U3R5bGVSZWNGYy5qdXN0KTsKKwlscFN0cnVjdC0+Zm9yZUNvbG9yLnJlZCA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuZm9yZUNvbG9yX3JlZCk7CisJbHBTdHJ1Y3QtPmZvcmVDb2xvci5ncmVlbiA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuZm9yZUNvbG9yX2dyZWVuKTsKKwlscFN0cnVjdC0+Zm9yZUNvbG9yLmJsdWUgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29udHJvbEZvbnRTdHlsZVJlY0ZjLmZvcmVDb2xvcl9ibHVlKTsKKwlscFN0cnVjdC0+YmFja0NvbG9yLnJlZCA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuYmFja0NvbG9yX3JlZCk7CisJbHBTdHJ1Y3QtPmJhY2tDb2xvci5ncmVlbiA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuYmFja0NvbG9yX2dyZWVuKTsKKwlscFN0cnVjdC0+YmFja0NvbG9yLmJsdWUgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29udHJvbEZvbnRTdHlsZVJlY0ZjLmJhY2tDb2xvcl9ibHVlKTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0Q29udHJvbEZvbnRTdHlsZVJlY0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ29udHJvbEZvbnRTdHlsZVJlYyAqbHBTdHJ1Y3QpCit7CisJaWYgKCFDb250cm9sRm9udFN0eWxlUmVjRmMuY2FjaGVkKSBjYWNoZUNvbnRyb2xGb250U3R5bGVSZWNGaWRzKGVudiwgbHBPYmplY3QpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuZmxhZ3MsIChqc2hvcnQpbHBTdHJ1Y3QtPmZsYWdzKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29udHJvbEZvbnRTdHlsZVJlY0ZjLmZvbnQsIChqc2hvcnQpbHBTdHJ1Y3QtPmZvbnQpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuc2l6ZSwgKGpzaG9ydClscFN0cnVjdC0+c2l6ZSk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbnRyb2xGb250U3R5bGVSZWNGYy5zdHlsZSwgKGpzaG9ydClscFN0cnVjdC0+c3R5bGUpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMubW9kZSwgKGpzaG9ydClscFN0cnVjdC0+bW9kZSk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbnRyb2xGb250U3R5bGVSZWNGYy5qdXN0LCAoanNob3J0KWxwU3RydWN0LT5qdXN0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29udHJvbEZvbnRTdHlsZVJlY0ZjLmZvcmVDb2xvcl9yZWQsIChqc2hvcnQpbHBTdHJ1Y3QtPmZvcmVDb2xvci5yZWQpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuZm9yZUNvbG9yX2dyZWVuLCAoanNob3J0KWxwU3RydWN0LT5mb3JlQ29sb3IuZ3JlZW4pOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuZm9yZUNvbG9yX2JsdWUsIChqc2hvcnQpbHBTdHJ1Y3QtPmZvcmVDb2xvci5ibHVlKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29udHJvbEZvbnRTdHlsZVJlY0ZjLmJhY2tDb2xvcl9yZWQsIChqc2hvcnQpbHBTdHJ1Y3QtPmJhY2tDb2xvci5yZWQpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuYmFja0NvbG9yX2dyZWVuLCAoanNob3J0KWxwU3RydWN0LT5iYWNrQ29sb3IuZ3JlZW4pOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjRmMuYmFja0NvbG9yX2JsdWUsIChqc2hvcnQpbHBTdHJ1Y3QtPmJhY2tDb2xvci5ibHVlKTsKK30KKyNlbmRpZiAvKiBOT19Db250cm9sRm9udFN0eWxlUmVjICovCisKKyNpZm5kZWYgTk9fQ29udHJvbFRhYkVudHJ5Cit0eXBlZGVmIHN0cnVjdCBDb250cm9sVGFiRW50cnlfRklEX0NBQ0hFIHsKKwlpbnQgY2FjaGVkOworCWpjbGFzcyBjbGF6ejsKKwlqZmllbGRJRCBpY29uLCBuYW1lLCBlbmFibGVkOworfSBDb250cm9sVGFiRW50cnlfRklEX0NBQ0hFOworCitDb250cm9sVGFiRW50cnlfRklEX0NBQ0hFIENvbnRyb2xUYWJFbnRyeUZjOworCit2b2lkIGNhY2hlQ29udHJvbFRhYkVudHJ5RmlkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCkKK3sKKwlpZiAoQ29udHJvbFRhYkVudHJ5RmMuY2FjaGVkKSByZXR1cm47CisJQ29udHJvbFRhYkVudHJ5RmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCUNvbnRyb2xUYWJFbnRyeUZjLmljb24gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb250cm9sVGFiRW50cnlGYy5jbGF6eiwgImljb24iLCAiSSIpOworCUNvbnRyb2xUYWJFbnRyeUZjLm5hbWUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb250cm9sVGFiRW50cnlGYy5jbGF6eiwgIm5hbWUiLCAiSSIpOworCUNvbnRyb2xUYWJFbnRyeUZjLmVuYWJsZWQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDb250cm9sVGFiRW50cnlGYy5jbGF6eiwgImVuYWJsZWQiLCAiWiIpOworCUNvbnRyb2xUYWJFbnRyeUZjLmNhY2hlZCA9IDE7Cit9CisKK0NvbnRyb2xUYWJFbnRyeSAqZ2V0Q29udHJvbFRhYkVudHJ5RmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBDb250cm9sVGFiRW50cnkgKmxwU3RydWN0KQoreworCWlmICghQ29udHJvbFRhYkVudHJ5RmMuY2FjaGVkKSBjYWNoZUNvbnRyb2xUYWJFbnRyeUZpZHMoZW52LCBscE9iamVjdCk7CisJbHBTdHJ1Y3QtPmljb24gPSAoQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvICopKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sVGFiRW50cnlGYy5pY29uKTsKKwlscFN0cnVjdC0+bmFtZSA9IChDRlN0cmluZ1JlZikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIENvbnRyb2xUYWJFbnRyeUZjLm5hbWUpOworCWxwU3RydWN0LT5lbmFibGVkID0gKEJvb2xlYW4pKCplbnYpLT5HZXRCb29sZWFuRmllbGQoZW52LCBscE9iamVjdCwgQ29udHJvbFRhYkVudHJ5RmMuZW5hYmxlZCk7CisJcmV0dXJuIGxwU3RydWN0OworfQorCit2b2lkIHNldENvbnRyb2xUYWJFbnRyeUZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ29udHJvbFRhYkVudHJ5ICpscFN0cnVjdCkKK3sKKwlpZiAoIUNvbnRyb2xUYWJFbnRyeUZjLmNhY2hlZCkgY2FjaGVDb250cm9sVGFiRW50cnlGaWRzKGVudiwgbHBPYmplY3QpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQ29udHJvbFRhYkVudHJ5RmMuaWNvbiwgKGppbnQpbHBTdHJ1Y3QtPmljb24pOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQ29udHJvbFRhYkVudHJ5RmMubmFtZSwgKGppbnQpbHBTdHJ1Y3QtPm5hbWUpOworCSgqZW52KS0+U2V0Qm9vbGVhbkZpZWxkKGVudiwgbHBPYmplY3QsIENvbnRyb2xUYWJFbnRyeUZjLmVuYWJsZWQsIChqYm9vbGVhbilscFN0cnVjdC0+ZW5hYmxlZCk7Cit9CisjZW5kaWYgLyogTk9fQ29udHJvbFRhYkVudHJ5ICovCisKKyNpZm5kZWYgTk9fQ29udHJvbFRhYkluZm9SZWNWMQordHlwZWRlZiBzdHJ1Y3QgQ29udHJvbFRhYkluZm9SZWNWMV9GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIHZlcnNpb24sIGljb25TdWl0ZUlELCBuYW1lOworfSBDb250cm9sVGFiSW5mb1JlY1YxX0ZJRF9DQUNIRTsKKworQ29udHJvbFRhYkluZm9SZWNWMV9GSURfQ0FDSEUgQ29udHJvbFRhYkluZm9SZWNWMUZjOworCit2b2lkIGNhY2hlQ29udHJvbFRhYkluZm9SZWNWMUZpZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QpCit7CisJaWYgKENvbnRyb2xUYWJJbmZvUmVjVjFGYy5jYWNoZWQpIHJldHVybjsKKwlDb250cm9sVGFiSW5mb1JlY1YxRmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCUNvbnRyb2xUYWJJbmZvUmVjVjFGYy52ZXJzaW9uID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29udHJvbFRhYkluZm9SZWNWMUZjLmNsYXp6LCAidmVyc2lvbiIsICJTIik7CisJQ29udHJvbFRhYkluZm9SZWNWMUZjLmljb25TdWl0ZUlEID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29udHJvbFRhYkluZm9SZWNWMUZjLmNsYXp6LCAiaWNvblN1aXRlSUQiLCAiUyIpOworCUNvbnRyb2xUYWJJbmZvUmVjVjFGYy5uYW1lID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ29udHJvbFRhYkluZm9SZWNWMUZjLmNsYXp6LCAibmFtZSIsICJJIik7CisJQ29udHJvbFRhYkluZm9SZWNWMUZjLmNhY2hlZCA9IDE7Cit9CisKK0NvbnRyb2xUYWJJbmZvUmVjVjEgKmdldENvbnRyb2xUYWJJbmZvUmVjVjFGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENvbnRyb2xUYWJJbmZvUmVjVjEgKmxwU3RydWN0KQoreworCWlmICghQ29udHJvbFRhYkluZm9SZWNWMUZjLmNhY2hlZCkgY2FjaGVDb250cm9sVGFiSW5mb1JlY1YxRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+dmVyc2lvbiA9IChTSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbnRyb2xUYWJJbmZvUmVjVjFGYy52ZXJzaW9uKTsKKwlscFN0cnVjdC0+aWNvblN1aXRlSUQgPSAoU0ludDE2KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sVGFiSW5mb1JlY1YxRmMuaWNvblN1aXRlSUQpOworCWxwU3RydWN0LT5uYW1lID0gKENGU3RyaW5nUmVmKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgQ29udHJvbFRhYkluZm9SZWNWMUZjLm5hbWUpOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXRDb250cm9sVGFiSW5mb1JlY1YxRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBDb250cm9sVGFiSW5mb1JlY1YxICpscFN0cnVjdCkKK3sKKwlpZiAoIUNvbnRyb2xUYWJJbmZvUmVjVjFGYy5jYWNoZWQpIGNhY2hlQ29udHJvbFRhYkluZm9SZWNWMUZpZHMoZW52LCBscE9iamVjdCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIENvbnRyb2xUYWJJbmZvUmVjVjFGYy52ZXJzaW9uLCAoanNob3J0KWxwU3RydWN0LT52ZXJzaW9uKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ29udHJvbFRhYkluZm9SZWNWMUZjLmljb25TdWl0ZUlELCAoanNob3J0KWxwU3RydWN0LT5pY29uU3VpdGVJRCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDb250cm9sVGFiSW5mb1JlY1YxRmMubmFtZSwgKGppbnQpbHBTdHJ1Y3QtPm5hbWUpOworfQorI2VuZGlmIC8qIE5PX0NvbnRyb2xUYWJJbmZvUmVjVjEgKi8KKworI2lmbmRlZiBOT19DdXJzb3IKK3R5cGVkZWYgc3RydWN0IEN1cnNvcl9GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIGRhdGEsIG1hc2ssIGhvdFNwb3RfdiwgaG90U3BvdF9oOworfSBDdXJzb3JfRklEX0NBQ0hFOworCitDdXJzb3JfRklEX0NBQ0hFIEN1cnNvckZjOworCit2b2lkIGNhY2hlQ3Vyc29yRmlkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCkKK3sKKwlpZiAoQ3Vyc29yRmMuY2FjaGVkKSByZXR1cm47CisJQ3Vyc29yRmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCUN1cnNvckZjLmRhdGEgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBDdXJzb3JGYy5jbGF6eiwgImRhdGEiLCAiW1MiKTsKKwlDdXJzb3JGYy5tYXNrID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ3Vyc29yRmMuY2xhenosICJtYXNrIiwgIltTIik7CisJQ3Vyc29yRmMuaG90U3BvdF92ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgQ3Vyc29yRmMuY2xhenosICJob3RTcG90X3YiLCAiUyIpOworCUN1cnNvckZjLmhvdFNwb3RfaCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEN1cnNvckZjLmNsYXp6LCAiaG90U3BvdF9oIiwgIlMiKTsKKwlDdXJzb3JGYy5jYWNoZWQgPSAxOworfQorCitDdXJzb3IgKmdldEN1cnNvckZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ3Vyc29yICpscFN0cnVjdCkKK3sKKwlpZiAoIUN1cnNvckZjLmNhY2hlZCkgY2FjaGVDdXJzb3JGaWRzKGVudiwgbHBPYmplY3QpOworCXsKKwlqc2hvcnRBcnJheSBscE9iamVjdDEgPSAoKmVudiktPkdldE9iamVjdEZpZWxkKGVudiwgbHBPYmplY3QsIEN1cnNvckZjLmRhdGEpOworCSgqZW52KS0+R2V0U2hvcnRBcnJheVJlZ2lvbihlbnYsIGxwT2JqZWN0MSwgMCwgc2l6ZW9mKGxwU3RydWN0LT5kYXRhKSAvIDIsIGxwU3RydWN0LT5kYXRhKTsKKwl9CisJeworCWpzaG9ydEFycmF5IGxwT2JqZWN0MSA9ICgqZW52KS0+R2V0T2JqZWN0RmllbGQoZW52LCBscE9iamVjdCwgQ3Vyc29yRmMubWFzayk7CisJKCplbnYpLT5HZXRTaG9ydEFycmF5UmVnaW9uKGVudiwgbHBPYmplY3QxLCAwLCBzaXplb2YobHBTdHJ1Y3QtPm1hc2spIC8gMiwgbHBTdHJ1Y3QtPm1hc2spOworCX0KKwlscFN0cnVjdC0+aG90U3BvdC52ID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEN1cnNvckZjLmhvdFNwb3Rfdik7CisJbHBTdHJ1Y3QtPmhvdFNwb3QuaCA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBDdXJzb3JGYy5ob3RTcG90X2gpOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXRDdXJzb3JGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIEN1cnNvciAqbHBTdHJ1Y3QpCit7CisJaWYgKCFDdXJzb3JGYy5jYWNoZWQpIGNhY2hlQ3Vyc29yRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwl7CisJanNob3J0QXJyYXkgbHBPYmplY3QxID0gKCplbnYpLT5HZXRPYmplY3RGaWVsZChlbnYsIGxwT2JqZWN0LCBDdXJzb3JGYy5kYXRhKTsKKwkoKmVudiktPlNldFNob3J0QXJyYXlSZWdpb24oZW52LCBscE9iamVjdDEsIDAsIHNpemVvZihscFN0cnVjdC0+ZGF0YSkgLyAyLCBscFN0cnVjdC0+ZGF0YSk7CisJfQorCXsKKwlqc2hvcnRBcnJheSBscE9iamVjdDEgPSAoKmVudiktPkdldE9iamVjdEZpZWxkKGVudiwgbHBPYmplY3QsIEN1cnNvckZjLm1hc2spOworCSgqZW52KS0+U2V0U2hvcnRBcnJheVJlZ2lvbihlbnYsIGxwT2JqZWN0MSwgMCwgc2l6ZW9mKGxwU3RydWN0LT5tYXNrKSAvIDIsIGxwU3RydWN0LT5tYXNrKTsKKwl9CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEN1cnNvckZjLmhvdFNwb3RfdiwgKGpzaG9ydClscFN0cnVjdC0+aG90U3BvdC52KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgQ3Vyc29yRmMuaG90U3BvdF9oLCAoanNob3J0KWxwU3RydWN0LT5ob3RTcG90LmgpOworfQorI2VuZGlmIC8qIE5PX0N1cnNvciAqLworCisjaWZuZGVmIE5PX0RhdGFCcm93c2VyQ2FsbGJhY2tzCit0eXBlZGVmIHN0cnVjdCBEYXRhQnJvd3NlckNhbGxiYWNrc19GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIHZlcnNpb24sIHYxX2l0ZW1EYXRhQ2FsbGJhY2ssIHYxX2l0ZW1Db21wYXJlQ2FsbGJhY2ssIHYxX2l0ZW1Ob3RpZmljYXRpb25DYWxsYmFjaywgdjFfYWRkRHJhZ0l0ZW1DYWxsYmFjaywgdjFfYWNjZXB0RHJhZ0NhbGxiYWNrLCB2MV9yZWNlaXZlRHJhZ0NhbGxiYWNrLCB2MV9wb3N0UHJvY2Vzc0RyYWdDYWxsYmFjaywgdjFfaXRlbUhlbHBDb250ZW50Q2FsbGJhY2ssIHYxX2dldENvbnRleHR1YWxNZW51Q2FsbGJhY2ssIHYxX3NlbGVjdENvbnRleHR1YWxNZW51Q2FsbGJhY2s7Cit9IERhdGFCcm93c2VyQ2FsbGJhY2tzX0ZJRF9DQUNIRTsKKworRGF0YUJyb3dzZXJDYWxsYmFja3NfRklEX0NBQ0hFIERhdGFCcm93c2VyQ2FsbGJhY2tzRmM7CisKK3ZvaWQgY2FjaGVEYXRhQnJvd3NlckNhbGxiYWNrc0ZpZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QpCit7CisJaWYgKERhdGFCcm93c2VyQ2FsbGJhY2tzRmMuY2FjaGVkKSByZXR1cm47CisJRGF0YUJyb3dzZXJDYWxsYmFja3NGYy5jbGF6eiA9ICgqZW52KS0+R2V0T2JqZWN0Q2xhc3MoZW52LCBscE9iamVjdCk7CisJRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52ZXJzaW9uID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJDYWxsYmFja3NGYy5jbGF6eiwgInZlcnNpb24iLCAiSSIpOworCURhdGFCcm93c2VyQ2FsbGJhY2tzRmMudjFfaXRlbURhdGFDYWxsYmFjayA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMuY2xhenosICJ2MV9pdGVtRGF0YUNhbGxiYWNrIiwgIkkiKTsKKwlEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLnYxX2l0ZW1Db21wYXJlQ2FsbGJhY2sgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLmNsYXp6LCAidjFfaXRlbUNvbXBhcmVDYWxsYmFjayIsICJJIik7CisJRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52MV9pdGVtTm90aWZpY2F0aW9uQ2FsbGJhY2sgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLmNsYXp6LCAidjFfaXRlbU5vdGlmaWNhdGlvbkNhbGxiYWNrIiwgIkkiKTsKKwlEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLnYxX2FkZERyYWdJdGVtQ2FsbGJhY2sgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLmNsYXp6LCAidjFfYWRkRHJhZ0l0ZW1DYWxsYmFjayIsICJJIik7CisJRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52MV9hY2NlcHREcmFnQ2FsbGJhY2sgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLmNsYXp6LCAidjFfYWNjZXB0RHJhZ0NhbGxiYWNrIiwgIkkiKTsKKwlEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLnYxX3JlY2VpdmVEcmFnQ2FsbGJhY2sgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLmNsYXp6LCAidjFfcmVjZWl2ZURyYWdDYWxsYmFjayIsICJJIik7CisJRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52MV9wb3N0UHJvY2Vzc0RyYWdDYWxsYmFjayA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMuY2xhenosICJ2MV9wb3N0UHJvY2Vzc0RyYWdDYWxsYmFjayIsICJJIik7CisJRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52MV9pdGVtSGVscENvbnRlbnRDYWxsYmFjayA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMuY2xhenosICJ2MV9pdGVtSGVscENvbnRlbnRDYWxsYmFjayIsICJJIik7CisJRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52MV9nZXRDb250ZXh0dWFsTWVudUNhbGxiYWNrID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJDYWxsYmFja3NGYy5jbGF6eiwgInYxX2dldENvbnRleHR1YWxNZW51Q2FsbGJhY2siLCAiSSIpOworCURhdGFCcm93c2VyQ2FsbGJhY2tzRmMudjFfc2VsZWN0Q29udGV4dHVhbE1lbnVDYWxsYmFjayA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMuY2xhenosICJ2MV9zZWxlY3RDb250ZXh0dWFsTWVudUNhbGxiYWNrIiwgIkkiKTsKKwlEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLmNhY2hlZCA9IDE7Cit9CisKK0RhdGFCcm93c2VyQ2FsbGJhY2tzICpnZXREYXRhQnJvd3NlckNhbGxiYWNrc0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRGF0YUJyb3dzZXJDYWxsYmFja3MgKmxwU3RydWN0KQoreworCWlmICghRGF0YUJyb3dzZXJDYWxsYmFja3NGYy5jYWNoZWQpIGNhY2hlRGF0YUJyb3dzZXJDYWxsYmFja3NGaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT52ZXJzaW9uID0gKFVJbnQzMikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMudmVyc2lvbik7CisJbHBTdHJ1Y3QtPnUudjEuaXRlbURhdGFDYWxsYmFjayA9IChEYXRhQnJvd3Nlckl0ZW1EYXRhVVBQKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52MV9pdGVtRGF0YUNhbGxiYWNrKTsKKwlscFN0cnVjdC0+dS52MS5pdGVtQ29tcGFyZUNhbGxiYWNrID0gKERhdGFCcm93c2VySXRlbUNvbXBhcmVVUFApKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLnYxX2l0ZW1Db21wYXJlQ2FsbGJhY2spOworCWxwU3RydWN0LT51LnYxLml0ZW1Ob3RpZmljYXRpb25DYWxsYmFjayA9IChEYXRhQnJvd3Nlckl0ZW1Ob3RpZmljYXRpb25VUFApKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLnYxX2l0ZW1Ob3RpZmljYXRpb25DYWxsYmFjayk7CisJbHBTdHJ1Y3QtPnUudjEuYWRkRHJhZ0l0ZW1DYWxsYmFjayA9IChEYXRhQnJvd3NlckFkZERyYWdJdGVtVVBQKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52MV9hZGREcmFnSXRlbUNhbGxiYWNrKTsKKwlscFN0cnVjdC0+dS52MS5hY2NlcHREcmFnQ2FsbGJhY2sgPSAoRGF0YUJyb3dzZXJBY2NlcHREcmFnVVBQKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52MV9hY2NlcHREcmFnQ2FsbGJhY2spOworCWxwU3RydWN0LT51LnYxLnJlY2VpdmVEcmFnQ2FsbGJhY2sgPSAoRGF0YUJyb3dzZXJSZWNlaXZlRHJhZ1VQUCkoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMudjFfcmVjZWl2ZURyYWdDYWxsYmFjayk7CisJbHBTdHJ1Y3QtPnUudjEucG9zdFByb2Nlc3NEcmFnQ2FsbGJhY2sgPSAoRGF0YUJyb3dzZXJQb3N0UHJvY2Vzc0RyYWdVUFApKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLnYxX3Bvc3RQcm9jZXNzRHJhZ0NhbGxiYWNrKTsKKwlscFN0cnVjdC0+dS52MS5pdGVtSGVscENvbnRlbnRDYWxsYmFjayA9IChEYXRhQnJvd3Nlckl0ZW1IZWxwQ29udGVudFVQUCkoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMudjFfaXRlbUhlbHBDb250ZW50Q2FsbGJhY2spOworCWxwU3RydWN0LT51LnYxLmdldENvbnRleHR1YWxNZW51Q2FsbGJhY2sgPSAoRGF0YUJyb3dzZXJHZXRDb250ZXh0dWFsTWVudVVQUCkoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMudjFfZ2V0Q29udGV4dHVhbE1lbnVDYWxsYmFjayk7CisJbHBTdHJ1Y3QtPnUudjEuc2VsZWN0Q29udGV4dHVhbE1lbnVDYWxsYmFjayA9IChEYXRhQnJvd3NlclNlbGVjdENvbnRleHR1YWxNZW51VVBQKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52MV9zZWxlY3RDb250ZXh0dWFsTWVudUNhbGxiYWNrKTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0RGF0YUJyb3dzZXJDYWxsYmFja3NGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIERhdGFCcm93c2VyQ2FsbGJhY2tzICpscFN0cnVjdCkKK3sKKwlpZiAoIURhdGFCcm93c2VyQ2FsbGJhY2tzRmMuY2FjaGVkKSBjYWNoZURhdGFCcm93c2VyQ2FsbGJhY2tzRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMudmVyc2lvbiwgKGppbnQpbHBTdHJ1Y3QtPnZlcnNpb24pOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52MV9pdGVtRGF0YUNhbGxiYWNrLCAoamludClscFN0cnVjdC0+dS52MS5pdGVtRGF0YUNhbGxiYWNrKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMudjFfaXRlbUNvbXBhcmVDYWxsYmFjaywgKGppbnQpbHBTdHJ1Y3QtPnUudjEuaXRlbUNvbXBhcmVDYWxsYmFjayk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLnYxX2l0ZW1Ob3RpZmljYXRpb25DYWxsYmFjaywgKGppbnQpbHBTdHJ1Y3QtPnUudjEuaXRlbU5vdGlmaWNhdGlvbkNhbGxiYWNrKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMudjFfYWRkRHJhZ0l0ZW1DYWxsYmFjaywgKGppbnQpbHBTdHJ1Y3QtPnUudjEuYWRkRHJhZ0l0ZW1DYWxsYmFjayk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLnYxX2FjY2VwdERyYWdDYWxsYmFjaywgKGppbnQpbHBTdHJ1Y3QtPnUudjEuYWNjZXB0RHJhZ0NhbGxiYWNrKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ2FsbGJhY2tzRmMudjFfcmVjZWl2ZURyYWdDYWxsYmFjaywgKGppbnQpbHBTdHJ1Y3QtPnUudjEucmVjZWl2ZURyYWdDYWxsYmFjayk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLnYxX3Bvc3RQcm9jZXNzRHJhZ0NhbGxiYWNrLCAoamludClscFN0cnVjdC0+dS52MS5wb3N0UHJvY2Vzc0RyYWdDYWxsYmFjayk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLnYxX2l0ZW1IZWxwQ29udGVudENhbGxiYWNrLCAoamludClscFN0cnVjdC0+dS52MS5pdGVtSGVscENvbnRlbnRDYWxsYmFjayk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckNhbGxiYWNrc0ZjLnYxX2dldENvbnRleHR1YWxNZW51Q2FsbGJhY2ssIChqaW50KWxwU3RydWN0LT51LnYxLmdldENvbnRleHR1YWxNZW51Q2FsbGJhY2spOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDYWxsYmFja3NGYy52MV9zZWxlY3RDb250ZXh0dWFsTWVudUNhbGxiYWNrLCAoamludClscFN0cnVjdC0+dS52MS5zZWxlY3RDb250ZXh0dWFsTWVudUNhbGxiYWNrKTsKK30KKyNlbmRpZiAvKiBOT19EYXRhQnJvd3NlckNhbGxiYWNrcyAqLworCisjaWZuZGVmIE5PX0RhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzCit0eXBlZGVmIHN0cnVjdCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc19GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIHZlcnNpb24sIHYxX2RyYXdJdGVtQ2FsbGJhY2ssIHYxX2VkaXRUZXh0Q2FsbGJhY2ssIHYxX2hpdFRlc3RDYWxsYmFjaywgdjFfdHJhY2tpbmdDYWxsYmFjaywgdjFfZHJhZ1JlZ2lvbkNhbGxiYWNrLCB2MV9hY2NlcHREcmFnQ2FsbGJhY2ssIHYxX3JlY2VpdmVEcmFnQ2FsbGJhY2s7Cit9IERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzX0ZJRF9DQUNIRTsKKworRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NfRklEX0NBQ0hFIERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmM7CisKK3ZvaWQgY2FjaGVEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZpZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QpCit7CisJaWYgKERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmMuY2FjaGVkKSByZXR1cm47CisJRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy5jbGF6eiA9ICgqZW52KS0+R2V0T2JqZWN0Q2xhc3MoZW52LCBscE9iamVjdCk7CisJRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy52ZXJzaW9uID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy5jbGF6eiwgInZlcnNpb24iLCAiSSIpOworCURhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmMudjFfZHJhd0l0ZW1DYWxsYmFjayA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmMuY2xhenosICJ2MV9kcmF3SXRlbUNhbGxiYWNrIiwgIkkiKTsKKwlEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLnYxX2VkaXRUZXh0Q2FsbGJhY2sgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLmNsYXp6LCAidjFfZWRpdFRleHRDYWxsYmFjayIsICJJIik7CisJRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy52MV9oaXRUZXN0Q2FsbGJhY2sgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLmNsYXp6LCAidjFfaGl0VGVzdENhbGxiYWNrIiwgIkkiKTsKKwlEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLnYxX3RyYWNraW5nQ2FsbGJhY2sgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLmNsYXp6LCAidjFfdHJhY2tpbmdDYWxsYmFjayIsICJJIik7CisJRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy52MV9kcmFnUmVnaW9uQ2FsbGJhY2sgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLmNsYXp6LCAidjFfZHJhZ1JlZ2lvbkNhbGxiYWNrIiwgIkkiKTsKKwlEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLnYxX2FjY2VwdERyYWdDYWxsYmFjayA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmMuY2xhenosICJ2MV9hY2NlcHREcmFnQ2FsbGJhY2siLCAiSSIpOworCURhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmMudjFfcmVjZWl2ZURyYWdDYWxsYmFjayA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmMuY2xhenosICJ2MV9yZWNlaXZlRHJhZ0NhbGxiYWNrIiwgIkkiKTsKKwlEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLmNhY2hlZCA9IDE7Cit9CisKK0RhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzICpnZXREYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3MgKmxwU3RydWN0KQoreworCWlmICghRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy5jYWNoZWQpIGNhY2hlRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT52ZXJzaW9uID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLnZlcnNpb24pOworCWxwU3RydWN0LT51LnYxLmRyYXdJdGVtQ2FsbGJhY2sgPSAoRGF0YUJyb3dzZXJEcmF3SXRlbVVQUCkgKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLnYxX2RyYXdJdGVtQ2FsbGJhY2spOworCWxwU3RydWN0LT51LnYxLmVkaXRUZXh0Q2FsbGJhY2sgPSAoRGF0YUJyb3dzZXJFZGl0SXRlbVVQUCkoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmMudjFfZWRpdFRleHRDYWxsYmFjayk7CisJbHBTdHJ1Y3QtPnUudjEuaGl0VGVzdENhbGxiYWNrID0gKERhdGFCcm93c2VySGl0VGVzdFVQUCkoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmMudjFfaGl0VGVzdENhbGxiYWNrKTsKKwlscFN0cnVjdC0+dS52MS50cmFja2luZ0NhbGxiYWNrID0gKERhdGFCcm93c2VyVHJhY2tpbmdVUFApKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLnYxX3RyYWNraW5nQ2FsbGJhY2spOworCWxwU3RydWN0LT51LnYxLmRyYWdSZWdpb25DYWxsYmFjayA9IChEYXRhQnJvd3Nlckl0ZW1EcmFnUmduVVBQKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy52MV9kcmFnUmVnaW9uQ2FsbGJhY2spOworCWxwU3RydWN0LT51LnYxLmFjY2VwdERyYWdDYWxsYmFjayA9IChEYXRhQnJvd3Nlckl0ZW1BY2NlcHREcmFnVVBQKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy52MV9hY2NlcHREcmFnQ2FsbGJhY2spOworCWxwU3RydWN0LT51LnYxLnJlY2VpdmVEcmFnQ2FsbGJhY2sgPSAoRGF0YUJyb3dzZXJJdGVtUmVjZWl2ZURyYWdVUFApKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLnYxX3JlY2VpdmVEcmFnQ2FsbGJhY2spOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXREYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3MgKmxwU3RydWN0KQoreworCWlmICghRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy5jYWNoZWQpIGNhY2hlRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGaWRzKGVudiwgbHBPYmplY3QpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy52ZXJzaW9uLCAoamludClscFN0cnVjdC0+dmVyc2lvbik7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLnYxX2RyYXdJdGVtQ2FsbGJhY2ssIChqaW50KWxwU3RydWN0LT51LnYxLmRyYXdJdGVtQ2FsbGJhY2spOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy52MV9lZGl0VGV4dENhbGxiYWNrLCAoamludClscFN0cnVjdC0+dS52MS5lZGl0VGV4dENhbGxiYWNrKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmMudjFfaGl0VGVzdENhbGxiYWNrLCAoamludClscFN0cnVjdC0+dS52MS5oaXRUZXN0Q2FsbGJhY2spOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy52MV90cmFja2luZ0NhbGxiYWNrLCAoamludClscFN0cnVjdC0+dS52MS50cmFja2luZ0NhbGxiYWNrKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmMudjFfZHJhZ1JlZ2lvbkNhbGxiYWNrLCAoamludClscFN0cnVjdC0+dS52MS5kcmFnUmVnaW9uQ2FsbGJhY2spOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGYy52MV9hY2NlcHREcmFnQ2FsbGJhY2ssIChqaW50KWxwU3RydWN0LT51LnYxLmFjY2VwdERyYWdDYWxsYmFjayk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZjLnYxX3JlY2VpdmVEcmFnQ2FsbGJhY2ssIChqaW50KWxwU3RydWN0LT51LnYxLnJlY2VpdmVEcmFnQ2FsbGJhY2spOworfQorI2VuZGlmIC8qIE5PX0RhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzICovCisKKyNpZm5kZWYgTk9fRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2MKK3R5cGVkZWYgc3RydWN0IERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjX0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgcHJvcGVydHlEZXNjX3Byb3BlcnR5SUQsIHByb3BlcnR5RGVzY19wcm9wZXJ0eVR5cGUsIHByb3BlcnR5RGVzY19wcm9wZXJ0eUZsYWdzLCBoZWFkZXJCdG5EZXNjX3ZlcnNpb24sIGhlYWRlckJ0bkRlc2NfbWluaW11bVdpZHRoLCBoZWFkZXJCdG5EZXNjX21heGltdW1XaWR0aCwgaGVhZGVyQnRuRGVzY190aXRsZU9mZnNldCwgaGVhZGVyQnRuRGVzY190aXRsZVN0cmluZywgaGVhZGVyQnRuRGVzY19pbml0aWFsT3JkZXIsIGhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX2ZsYWdzLCBoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mb250LCBoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9zaXplLCBoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9zdHlsZSwgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfbW9kZSwgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfanVzdCwgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9yZUNvbG9yX3JlZCwgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9yZUNvbG9yX2dyZWVuLCBoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mb3JlQ29sb3JfYmx1ZSwgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfYmFja0NvbG9yX3JlZCwgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfYmFja0NvbG9yX2dyZWVuLCBoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9iYWNrQ29sb3JfYmx1ZSwgaGVhZGVyQnRuRGVzY19idG5Db250ZW50SW5mb19jb250ZW50VHlwZSwgaGVhZGVyQnRuRGVzY19idG5Db250ZW50SW5mb19pY29uUmVmOworfSBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY19GSURfQ0FDSEU7CisKK0RhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjX0ZJRF9DQUNIRSBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjOworCit2b2lkIGNhY2hlRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGaWRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0KQoreworCWlmIChEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmNhY2hlZCkgcmV0dXJuOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMucHJvcGVydHlEZXNjX3Byb3BlcnR5SUQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmNsYXp6LCAicHJvcGVydHlEZXNjX3Byb3BlcnR5SUQiLCAiSSIpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMucHJvcGVydHlEZXNjX3Byb3BlcnR5VHlwZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJwcm9wZXJ0eURlc2NfcHJvcGVydHlUeXBlIiwgIkkiKTsKKwlEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLnByb3BlcnR5RGVzY19wcm9wZXJ0eUZsYWdzID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5jbGF6eiwgInByb3BlcnR5RGVzY19wcm9wZXJ0eUZsYWdzIiwgIkkiKTsKKwlEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfdmVyc2lvbiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJoZWFkZXJCdG5EZXNjX3ZlcnNpb24iLCAiSSIpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19taW5pbXVtV2lkdGggPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmNsYXp6LCAiaGVhZGVyQnRuRGVzY19taW5pbXVtV2lkdGgiLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19tYXhpbXVtV2lkdGggPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmNsYXp6LCAiaGVhZGVyQnRuRGVzY19tYXhpbXVtV2lkdGgiLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY190aXRsZU9mZnNldCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJoZWFkZXJCdG5EZXNjX3RpdGxlT2Zmc2V0IiwgIlMiKTsKKwlEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfdGl0bGVTdHJpbmcgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmNsYXp6LCAiaGVhZGVyQnRuRGVzY190aXRsZVN0cmluZyIsICJJIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2luaXRpYWxPcmRlciA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJoZWFkZXJCdG5EZXNjX2luaXRpYWxPcmRlciIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mbGFncyA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mbGFncyIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mb250ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5jbGF6eiwgImhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX2ZvbnQiLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfc2l6ZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9zaXplIiwgIlMiKTsKKwlEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX3N0eWxlID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5jbGF6eiwgImhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX3N0eWxlIiwgIlMiKTsKKwlEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX21vZGUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmNsYXp6LCAiaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfbW9kZSIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9qdXN0ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5jbGF6eiwgImhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX2p1c3QiLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9yZUNvbG9yX3JlZCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mb3JlQ29sb3JfcmVkIiwgIlMiKTsKKwlEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX2ZvcmVDb2xvcl9ncmVlbiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mb3JlQ29sb3JfZ3JlZW4iLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9yZUNvbG9yX2JsdWUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmNsYXp6LCAiaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9yZUNvbG9yX2JsdWUiLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfYmFja0NvbG9yX3JlZCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9iYWNrQ29sb3JfcmVkIiwgIlMiKTsKKwlEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX2JhY2tDb2xvcl9ncmVlbiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9iYWNrQ29sb3JfZ3JlZW4iLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfYmFja0NvbG9yX2JsdWUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmNsYXp6LCAiaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfYmFja0NvbG9yX2JsdWUiLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Db250ZW50SW5mb19jb250ZW50VHlwZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJoZWFkZXJCdG5EZXNjX2J0bkNvbnRlbnRJbmZvX2NvbnRlbnRUeXBlIiwgIlMiKTsKKwlEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfYnRuQ29udGVudEluZm9faWNvblJlZiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2xhenosICJoZWFkZXJCdG5EZXNjX2J0bkNvbnRlbnRJbmZvX2ljb25SZWYiLCAiSSIpOworCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuY2FjaGVkID0gMTsKK30KKworRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2MgKmdldERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYyAqbHBTdHJ1Y3QpCit7CisJaWYgKCFEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmNhY2hlZCkgY2FjaGVEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZpZHMoZW52LCBscE9iamVjdCk7CisJbHBTdHJ1Y3QtPnByb3BlcnR5RGVzYy5wcm9wZXJ0eUlEID0gKERhdGFCcm93c2VyUHJvcGVydHlJRCkoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMucHJvcGVydHlEZXNjX3Byb3BlcnR5SUQpOworCWxwU3RydWN0LT5wcm9wZXJ0eURlc2MucHJvcGVydHlUeXBlID0gKE9TVHlwZSkoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMucHJvcGVydHlEZXNjX3Byb3BlcnR5VHlwZSk7CisJbHBTdHJ1Y3QtPnByb3BlcnR5RGVzYy5wcm9wZXJ0eUZsYWdzID0gKERhdGFCcm93c2VyUHJvcGVydHlGbGFncykoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMucHJvcGVydHlEZXNjX3Byb3BlcnR5RmxhZ3MpOworCWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLnZlcnNpb24gPSAoVUludDMyKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX3ZlcnNpb24pOworCWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLm1pbmltdW1XaWR0aCA9IChVSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19taW5pbXVtV2lkdGgpOworCWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLm1heGltdW1XaWR0aCA9IChVSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19tYXhpbXVtV2lkdGgpOworCWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLnRpdGxlT2Zmc2V0ID0gKFNJbnQxNikoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX3RpdGxlT2Zmc2V0KTsKKwlscFN0cnVjdC0+aGVhZGVyQnRuRGVzYy50aXRsZVN0cmluZyA9IChDRlN0cmluZ1JlZikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY190aXRsZVN0cmluZyk7CisJbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuaW5pdGlhbE9yZGVyID0gKERhdGFCcm93c2VyU29ydE9yZGVyKSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfaW5pdGlhbE9yZGVyKTsKKwlscFN0cnVjdC0+aGVhZGVyQnRuRGVzYy5idG5Gb250U3R5bGUuZmxhZ3MgPSAoU0ludDE2KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX2ZsYWdzKTsKKwlscFN0cnVjdC0+aGVhZGVyQnRuRGVzYy5idG5Gb250U3R5bGUuZm9udCA9IChTSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9udCk7CisJbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuYnRuRm9udFN0eWxlLnNpemUgPSAoU0ludDE2KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX3NpemUpOworCWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLmJ0bkZvbnRTdHlsZS5zdHlsZSA9IChTSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfc3R5bGUpOworCWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLmJ0bkZvbnRTdHlsZS5tb2RlID0gKFNJbnQxNikoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9tb2RlKTsKKwlscFN0cnVjdC0+aGVhZGVyQnRuRGVzYy5idG5Gb250U3R5bGUuanVzdCA9IChTSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfanVzdCk7CisJbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuYnRuRm9udFN0eWxlLmZvcmVDb2xvci5yZWQgPSAodW5zaWduZWQgc2hvcnQpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9yZUNvbG9yX3JlZCk7CisJbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuYnRuRm9udFN0eWxlLmZvcmVDb2xvci5ncmVlbiA9ICh1bnNpZ25lZCBzaG9ydCkoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mb3JlQ29sb3JfZ3JlZW4pOworCWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLmJ0bkZvbnRTdHlsZS5mb3JlQ29sb3IuYmx1ZSA9ICh1bnNpZ25lZCBzaG9ydCkoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mb3JlQ29sb3JfYmx1ZSk7CisJbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuYnRuRm9udFN0eWxlLmJhY2tDb2xvci5yZWQgPSAodW5zaWduZWQgc2hvcnQpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfYmFja0NvbG9yX3JlZCk7CisJbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuYnRuRm9udFN0eWxlLmJhY2tDb2xvci5ncmVlbiA9ICh1bnNpZ25lZCBzaG9ydCkoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9iYWNrQ29sb3JfZ3JlZW4pOworCWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLmJ0bkZvbnRTdHlsZS5iYWNrQ29sb3IuYmx1ZSA9ICh1bnNpZ25lZCBzaG9ydCkoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9iYWNrQ29sb3JfYmx1ZSk7CisJbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuYnRuQ29udGVudEluZm8uY29udGVudFR5cGUgPSAoQ29udHJvbENvbnRlbnRUeXBlKSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfYnRuQ29udGVudEluZm9fY29udGVudFR5cGUpOworCWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLmJ0bkNvbnRlbnRJbmZvLnUuaWNvblJlZiA9IChJY29uUmVmKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkNvbnRlbnRJbmZvX2ljb25SZWYpOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXREYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2MgKmxwU3RydWN0KQoreworCWlmICghRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5jYWNoZWQpIGNhY2hlRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGaWRzKGVudiwgbHBPYmplY3QpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5wcm9wZXJ0eURlc2NfcHJvcGVydHlJRCwgKGppbnQpbHBTdHJ1Y3QtPnByb3BlcnR5RGVzYy5wcm9wZXJ0eUlEKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMucHJvcGVydHlEZXNjX3Byb3BlcnR5VHlwZSwgKGppbnQpbHBTdHJ1Y3QtPnByb3BlcnR5RGVzYy5wcm9wZXJ0eVR5cGUpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5wcm9wZXJ0eURlc2NfcHJvcGVydHlGbGFncywgKGppbnQpbHBTdHJ1Y3QtPnByb3BlcnR5RGVzYy5wcm9wZXJ0eUZsYWdzKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY192ZXJzaW9uLCAoamludClscFN0cnVjdC0+aGVhZGVyQnRuRGVzYy52ZXJzaW9uKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX21pbmltdW1XaWR0aCwgKGpzaG9ydClscFN0cnVjdC0+aGVhZGVyQnRuRGVzYy5taW5pbXVtV2lkdGgpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfbWF4aW11bVdpZHRoLCAoanNob3J0KWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLm1heGltdW1XaWR0aCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY190aXRsZU9mZnNldCwgKGpzaG9ydClscFN0cnVjdC0+aGVhZGVyQnRuRGVzYy50aXRsZU9mZnNldCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfdGl0bGVTdHJpbmcsIChqaW50KWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLnRpdGxlU3RyaW5nKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2luaXRpYWxPcmRlciwgKGpzaG9ydClscFN0cnVjdC0+aGVhZGVyQnRuRGVzYy5pbml0aWFsT3JkZXIpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZjLmhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX2ZsYWdzLCAoanNob3J0KWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLmJ0bkZvbnRTdHlsZS5mbGFncyk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9udCwgKGpzaG9ydClscFN0cnVjdC0+aGVhZGVyQnRuRGVzYy5idG5Gb250U3R5bGUuZm9udCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfc2l6ZSwgKGpzaG9ydClscFN0cnVjdC0+aGVhZGVyQnRuRGVzYy5idG5Gb250U3R5bGUuc2l6ZSk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfc3R5bGUsIChqc2hvcnQpbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuYnRuRm9udFN0eWxlLnN0eWxlKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9tb2RlLCAoanNob3J0KWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLmJ0bkZvbnRTdHlsZS5tb2RlKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9qdXN0LCAoanNob3J0KWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLmJ0bkZvbnRTdHlsZS5qdXN0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mb3JlQ29sb3JfcmVkLCAoanNob3J0KWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLmJ0bkZvbnRTdHlsZS5mb3JlQ29sb3IucmVkKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mb3JlQ29sb3JfZ3JlZW4sIChqc2hvcnQpbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuYnRuRm9udFN0eWxlLmZvcmVDb2xvci5ncmVlbik7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9yZUNvbG9yX2JsdWUsIChqc2hvcnQpbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuYnRuRm9udFN0eWxlLmZvcmVDb2xvci5ibHVlKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9iYWNrQ29sb3JfcmVkLCAoanNob3J0KWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLmJ0bkZvbnRTdHlsZS5iYWNrQ29sb3IucmVkKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9iYWNrQ29sb3JfZ3JlZW4sIChqc2hvcnQpbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuYnRuRm9udFN0eWxlLmJhY2tDb2xvci5ncmVlbik7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfYmFja0NvbG9yX2JsdWUsIChqc2hvcnQpbHBTdHJ1Y3QtPmhlYWRlckJ0bkRlc2MuYnRuRm9udFN0eWxlLmJhY2tDb2xvci5ibHVlKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2NGYy5oZWFkZXJCdG5EZXNjX2J0bkNvbnRlbnRJbmZvX2NvbnRlbnRUeXBlLCAoanNob3J0KWxwU3RydWN0LT5oZWFkZXJCdG5EZXNjLmJ0bkNvbnRlbnRJbmZvLmNvbnRlbnRUeXBlKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmMuaGVhZGVyQnRuRGVzY19idG5Db250ZW50SW5mb19pY29uUmVmLCAoamludClscFN0cnVjdC0+aGVhZGVyQnRuRGVzYy5idG5Db250ZW50SW5mby51Lmljb25SZWYpOworfQorI2VuZGlmIC8qIE5PX0RhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjICovCisKKyNpZm5kZWYgTk9fRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MKK3R5cGVkZWYgc3RydWN0IERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjX0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgdmVyc2lvbiwgbWluaW11bVdpZHRoLCBtYXhpbXVtV2lkdGgsIHRpdGxlT2Zmc2V0LCB0aXRsZVN0cmluZywgaW5pdGlhbE9yZGVyLCBidG5Gb250U3R5bGVfZmxhZ3MsIGJ0bkZvbnRTdHlsZV9mb250LCBidG5Gb250U3R5bGVfc2l6ZSwgYnRuRm9udFN0eWxlX3N0eWxlLCBidG5Gb250U3R5bGVfbW9kZSwgYnRuRm9udFN0eWxlX2p1c3QsIGJ0bkZvbnRTdHlsZV9mb3JlQ29sb3JfcmVkLCBidG5Gb250U3R5bGVfZm9yZUNvbG9yX2dyZWVuLCBidG5Gb250U3R5bGVfZm9yZUNvbG9yX2JsdWUsIGJ0bkZvbnRTdHlsZV9iYWNrQ29sb3JfcmVkLCBidG5Gb250U3R5bGVfYmFja0NvbG9yX2dyZWVuLCBidG5Gb250U3R5bGVfYmFja0NvbG9yX2JsdWUsIGJ0bkNvbnRlbnRJbmZvX2NvbnRlbnRUeXBlLCBidG5Db250ZW50SW5mb19pY29uUmVmOworfSBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY19GSURfQ0FDSEU7CisKK0RhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjX0ZJRF9DQUNIRSBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjOworCit2b2lkIGNhY2hlRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGaWRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0KQoreworCWlmIChEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmNhY2hlZCkgcmV0dXJuOworCURhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCURhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMudmVyc2lvbiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2xhenosICJ2ZXJzaW9uIiwgIkkiKTsKKwlEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLm1pbmltdW1XaWR0aCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2xhenosICJtaW5pbXVtV2lkdGgiLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMubWF4aW11bVdpZHRoID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5jbGF6eiwgIm1heGltdW1XaWR0aCIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy50aXRsZU9mZnNldCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2xhenosICJ0aXRsZU9mZnNldCIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy50aXRsZVN0cmluZyA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2xhenosICJ0aXRsZVN0cmluZyIsICJJIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5pbml0aWFsT3JkZXIgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmNsYXp6LCAiaW5pdGlhbE9yZGVyIiwgIlMiKTsKKwlEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkZvbnRTdHlsZV9mbGFncyA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2xhenosICJidG5Gb250U3R5bGVfZmxhZ3MiLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2ZvbnQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmNsYXp6LCAiYnRuRm9udFN0eWxlX2ZvbnQiLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX3NpemUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmNsYXp6LCAiYnRuRm9udFN0eWxlX3NpemUiLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX3N0eWxlID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5jbGF6eiwgImJ0bkZvbnRTdHlsZV9zdHlsZSIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Gb250U3R5bGVfbW9kZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2xhenosICJidG5Gb250U3R5bGVfbW9kZSIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Gb250U3R5bGVfanVzdCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2xhenosICJidG5Gb250U3R5bGVfanVzdCIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Gb250U3R5bGVfZm9yZUNvbG9yX3JlZCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2xhenosICJidG5Gb250U3R5bGVfZm9yZUNvbG9yX3JlZCIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Gb250U3R5bGVfZm9yZUNvbG9yX2dyZWVuID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5jbGF6eiwgImJ0bkZvbnRTdHlsZV9mb3JlQ29sb3JfZ3JlZW4iLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2ZvcmVDb2xvcl9ibHVlID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5jbGF6eiwgImJ0bkZvbnRTdHlsZV9mb3JlQ29sb3JfYmx1ZSIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Gb250U3R5bGVfYmFja0NvbG9yX3JlZCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2xhenosICJidG5Gb250U3R5bGVfYmFja0NvbG9yX3JlZCIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Gb250U3R5bGVfYmFja0NvbG9yX2dyZWVuID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5jbGF6eiwgImJ0bkZvbnRTdHlsZV9iYWNrQ29sb3JfZ3JlZW4iLCAiUyIpOworCURhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2JhY2tDb2xvcl9ibHVlID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5jbGF6eiwgImJ0bkZvbnRTdHlsZV9iYWNrQ29sb3JfYmx1ZSIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Db250ZW50SW5mb19jb250ZW50VHlwZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2xhenosICJidG5Db250ZW50SW5mb19jb250ZW50VHlwZSIsICJTIik7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Db250ZW50SW5mb19pY29uUmVmID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5jbGF6eiwgImJ0bkNvbnRlbnRJbmZvX2ljb25SZWYiLCAiSSIpOworCURhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuY2FjaGVkID0gMTsKK30KKworRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MgKmdldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzYyAqbHBTdHJ1Y3QpCit7CisJaWYgKCFEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmNhY2hlZCkgY2FjaGVEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZpZHMoZW52LCBscE9iamVjdCk7CisJbHBTdHJ1Y3QtPnZlcnNpb24gPSAoVUludDMyKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy52ZXJzaW9uKTsKKwlscFN0cnVjdC0+bWluaW11bVdpZHRoID0gKFVJbnQxNikoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5taW5pbXVtV2lkdGgpOworCWxwU3RydWN0LT5tYXhpbXVtV2lkdGggPSAoVUludDE2KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLm1heGltdW1XaWR0aCk7CisJbHBTdHJ1Y3QtPnRpdGxlT2Zmc2V0ID0gKFNJbnQxNikoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy50aXRsZU9mZnNldCk7CisJbHBTdHJ1Y3QtPnRpdGxlU3RyaW5nID0gKENGU3RyaW5nUmVmKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy50aXRsZVN0cmluZyk7CisJbHBTdHJ1Y3QtPmluaXRpYWxPcmRlciA9IChEYXRhQnJvd3NlclNvcnRPcmRlcikoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5pbml0aWFsT3JkZXIpOworCWxwU3RydWN0LT5idG5Gb250U3R5bGUuZmxhZ3MgPSAoU0ludDE2KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkZvbnRTdHlsZV9mbGFncyk7CisJbHBTdHJ1Y3QtPmJ0bkZvbnRTdHlsZS5mb250ID0gKFNJbnQxNikoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Gb250U3R5bGVfZm9udCk7CisJbHBTdHJ1Y3QtPmJ0bkZvbnRTdHlsZS5zaXplID0gKFNJbnQxNikoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Gb250U3R5bGVfc2l6ZSk7CisJbHBTdHJ1Y3QtPmJ0bkZvbnRTdHlsZS5zdHlsZSA9IChTSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX3N0eWxlKTsKKwlscFN0cnVjdC0+YnRuRm9udFN0eWxlLm1vZGUgPSAoU0ludDE2KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkZvbnRTdHlsZV9tb2RlKTsKKwlscFN0cnVjdC0+YnRuRm9udFN0eWxlLmp1c3QgPSAoU0ludDE2KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkZvbnRTdHlsZV9qdXN0KTsKKwlscFN0cnVjdC0+YnRuRm9udFN0eWxlLmZvcmVDb2xvci5yZWQgPSAodW5zaWduZWQgc2hvcnQpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2ZvcmVDb2xvcl9yZWQpOworCWxwU3RydWN0LT5idG5Gb250U3R5bGUuZm9yZUNvbG9yLmdyZWVuID0gKHVuc2lnbmVkIHNob3J0KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkZvbnRTdHlsZV9mb3JlQ29sb3JfZ3JlZW4pOworCWxwU3RydWN0LT5idG5Gb250U3R5bGUuZm9yZUNvbG9yLmJsdWUgPSAodW5zaWduZWQgc2hvcnQpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2ZvcmVDb2xvcl9ibHVlKTsKKwlscFN0cnVjdC0+YnRuRm9udFN0eWxlLmJhY2tDb2xvci5yZWQgPSAodW5zaWduZWQgc2hvcnQpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2JhY2tDb2xvcl9yZWQpOworCWxwU3RydWN0LT5idG5Gb250U3R5bGUuYmFja0NvbG9yLmdyZWVuID0gKHVuc2lnbmVkIHNob3J0KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkZvbnRTdHlsZV9iYWNrQ29sb3JfZ3JlZW4pOworCWxwU3RydWN0LT5idG5Gb250U3R5bGUuYmFja0NvbG9yLmJsdWUgPSAodW5zaWduZWQgc2hvcnQpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2JhY2tDb2xvcl9ibHVlKTsKKwlscFN0cnVjdC0+YnRuQ29udGVudEluZm8uY29udGVudFR5cGUgPSAoQ29udHJvbENvbnRlbnRUeXBlKSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkNvbnRlbnRJbmZvX2NvbnRlbnRUeXBlKTsKKwlscFN0cnVjdC0+YnRuQ29udGVudEluZm8udS5pY29uUmVmID0gKEljb25SZWYpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkNvbnRlbnRJbmZvX2ljb25SZWYpOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MgKmxwU3RydWN0KQoreworCWlmICghRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5jYWNoZWQpIGNhY2hlRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGaWRzKGVudiwgbHBPYmplY3QpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy52ZXJzaW9uLCAoamludClscFN0cnVjdC0+dmVyc2lvbik7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMubWluaW11bVdpZHRoLCAoanNob3J0KWxwU3RydWN0LT5taW5pbXVtV2lkdGgpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLm1heGltdW1XaWR0aCwgKGpzaG9ydClscFN0cnVjdC0+bWF4aW11bVdpZHRoKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy50aXRsZU9mZnNldCwgKGpzaG9ydClscFN0cnVjdC0+dGl0bGVPZmZzZXQpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy50aXRsZVN0cmluZywgKGppbnQpbHBTdHJ1Y3QtPnRpdGxlU3RyaW5nKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5pbml0aWFsT3JkZXIsIChqc2hvcnQpbHBTdHJ1Y3QtPmluaXRpYWxPcmRlcik7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2ZsYWdzLCAoanNob3J0KWxwU3RydWN0LT5idG5Gb250U3R5bGUuZmxhZ3MpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkZvbnRTdHlsZV9mb250LCAoanNob3J0KWxwU3RydWN0LT5idG5Gb250U3R5bGUuZm9udCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX3NpemUsIChqc2hvcnQpbHBTdHJ1Y3QtPmJ0bkZvbnRTdHlsZS5zaXplKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Gb250U3R5bGVfc3R5bGUsIChqc2hvcnQpbHBTdHJ1Y3QtPmJ0bkZvbnRTdHlsZS5zdHlsZSk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX21vZGUsIChqc2hvcnQpbHBTdHJ1Y3QtPmJ0bkZvbnRTdHlsZS5tb2RlKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGYy5idG5Gb250U3R5bGVfanVzdCwgKGpzaG9ydClscFN0cnVjdC0+YnRuRm9udFN0eWxlLmp1c3QpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkZvbnRTdHlsZV9mb3JlQ29sb3JfcmVkLCAoanNob3J0KWxwU3RydWN0LT5idG5Gb250U3R5bGUuZm9yZUNvbG9yLnJlZCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2ZvcmVDb2xvcl9ncmVlbiwgKGpzaG9ydClscFN0cnVjdC0+YnRuRm9udFN0eWxlLmZvcmVDb2xvci5ncmVlbik7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2ZvcmVDb2xvcl9ibHVlLCAoanNob3J0KWxwU3RydWN0LT5idG5Gb250U3R5bGUuZm9yZUNvbG9yLmJsdWUpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkZvbnRTdHlsZV9iYWNrQ29sb3JfcmVkLCAoanNob3J0KWxwU3RydWN0LT5idG5Gb250U3R5bGUuYmFja0NvbG9yLnJlZCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2JhY2tDb2xvcl9ncmVlbiwgKGpzaG9ydClscFN0cnVjdC0+YnRuRm9udFN0eWxlLmJhY2tDb2xvci5ncmVlbik7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmMuYnRuRm9udFN0eWxlX2JhY2tDb2xvcl9ibHVlLCAoanNob3J0KWxwU3RydWN0LT5idG5Gb250U3R5bGUuYmFja0NvbG9yLmJsdWUpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkNvbnRlbnRJbmZvX2NvbnRlbnRUeXBlLCAoanNob3J0KWxwU3RydWN0LT5idG5Db250ZW50SW5mby5jb250ZW50VHlwZSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZjLmJ0bkNvbnRlbnRJbmZvX2ljb25SZWYsIChqaW50KWxwU3RydWN0LT5idG5Db250ZW50SW5mby51Lmljb25SZWYpOworfQorI2VuZGlmIC8qIE5PX0RhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjICovCisKKyNpZm5kZWYgTk9fRXZlbnRSZWNvcmQKK3R5cGVkZWYgc3RydWN0IEV2ZW50UmVjb3JkX0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgd2hhdCwgbWVzc2FnZSwgd2hlbiwgd2hlcmVfdiwgd2hlcmVfaCwgbW9kaWZpZXJzOworfSBFdmVudFJlY29yZF9GSURfQ0FDSEU7CisKK0V2ZW50UmVjb3JkX0ZJRF9DQUNIRSBFdmVudFJlY29yZEZjOworCit2b2lkIGNhY2hlRXZlbnRSZWNvcmRGaWRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0KQoreworCWlmIChFdmVudFJlY29yZEZjLmNhY2hlZCkgcmV0dXJuOworCUV2ZW50UmVjb3JkRmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCUV2ZW50UmVjb3JkRmMud2hhdCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEV2ZW50UmVjb3JkRmMuY2xhenosICJ3aGF0IiwgIlMiKTsKKwlFdmVudFJlY29yZEZjLm1lc3NhZ2UgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBFdmVudFJlY29yZEZjLmNsYXp6LCAibWVzc2FnZSIsICJJIik7CisJRXZlbnRSZWNvcmRGYy53aGVuID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRXZlbnRSZWNvcmRGYy5jbGF6eiwgIndoZW4iLCAiSSIpOworCUV2ZW50UmVjb3JkRmMud2hlcmVfdiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEV2ZW50UmVjb3JkRmMuY2xhenosICJ3aGVyZV92IiwgIlMiKTsKKwlFdmVudFJlY29yZEZjLndoZXJlX2ggPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBFdmVudFJlY29yZEZjLmNsYXp6LCAid2hlcmVfaCIsICJTIik7CisJRXZlbnRSZWNvcmRGYy5tb2RpZmllcnMgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBFdmVudFJlY29yZEZjLmNsYXp6LCAibW9kaWZpZXJzIiwgIlMiKTsKKwlFdmVudFJlY29yZEZjLmNhY2hlZCA9IDE7Cit9CisKK0V2ZW50UmVjb3JkICpnZXRFdmVudFJlY29yZEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRXZlbnRSZWNvcmQgKmxwU3RydWN0KQoreworCWlmICghRXZlbnRSZWNvcmRGYy5jYWNoZWQpIGNhY2hlRXZlbnRSZWNvcmRGaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT53aGF0ID0gKEV2ZW50S2luZCkoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRXZlbnRSZWNvcmRGYy53aGF0KTsKKwlscFN0cnVjdC0+bWVzc2FnZSA9ICgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRXZlbnRSZWNvcmRGYy5tZXNzYWdlKTsKKwlscFN0cnVjdC0+d2hlbiA9ICgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRXZlbnRSZWNvcmRGYy53aGVuKTsKKwlscFN0cnVjdC0+d2hlcmUudiA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBFdmVudFJlY29yZEZjLndoZXJlX3YpOworCWxwU3RydWN0LT53aGVyZS5oID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEV2ZW50UmVjb3JkRmMud2hlcmVfaCk7CisJbHBTdHJ1Y3QtPm1vZGlmaWVycyA9IChFdmVudE1vZGlmaWVycykoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRXZlbnRSZWNvcmRGYy5tb2RpZmllcnMpOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXRFdmVudFJlY29yZEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRXZlbnRSZWNvcmQgKmxwU3RydWN0KQoreworCWlmICghRXZlbnRSZWNvcmRGYy5jYWNoZWQpIGNhY2hlRXZlbnRSZWNvcmRGaWRzKGVudiwgbHBPYmplY3QpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBFdmVudFJlY29yZEZjLndoYXQsIChqc2hvcnQpbHBTdHJ1Y3QtPndoYXQpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgRXZlbnRSZWNvcmRGYy5tZXNzYWdlLCAoamludClscFN0cnVjdC0+bWVzc2FnZSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBFdmVudFJlY29yZEZjLndoZW4sIChqaW50KWxwU3RydWN0LT53aGVuKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRXZlbnRSZWNvcmRGYy53aGVyZV92LCAoanNob3J0KWxwU3RydWN0LT53aGVyZS52KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRXZlbnRSZWNvcmRGYy53aGVyZV9oLCAoanNob3J0KWxwU3RydWN0LT53aGVyZS5oKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRXZlbnRSZWNvcmRGYy5tb2RpZmllcnMsIChqc2hvcnQpbHBTdHJ1Y3QtPm1vZGlmaWVycyk7Cit9CisjZW5kaWYgLyogTk9fRXZlbnRSZWNvcmQgKi8KKworI2lmbmRlZiBOT19Gb250SW5mbwordHlwZWRlZiBzdHJ1Y3QgRm9udEluZm9fRklEX0NBQ0hFIHsKKwlpbnQgY2FjaGVkOworCWpjbGFzcyBjbGF6ejsKKwlqZmllbGRJRCBhc2NlbnQsIGRlc2NlbnQsIHdpZE1heCwgbGVhZGluZzsKK30gRm9udEluZm9fRklEX0NBQ0hFOworCitGb250SW5mb19GSURfQ0FDSEUgRm9udEluZm9GYzsKKwordm9pZCBjYWNoZUZvbnRJbmZvRmlkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCkKK3sKKwlpZiAoRm9udEluZm9GYy5jYWNoZWQpIHJldHVybjsKKwlGb250SW5mb0ZjLmNsYXp6ID0gKCplbnYpLT5HZXRPYmplY3RDbGFzcyhlbnYsIGxwT2JqZWN0KTsKKwlGb250SW5mb0ZjLmFzY2VudCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEZvbnRJbmZvRmMuY2xhenosICJhc2NlbnQiLCAiUyIpOworCUZvbnRJbmZvRmMuZGVzY2VudCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEZvbnRJbmZvRmMuY2xhenosICJkZXNjZW50IiwgIlMiKTsKKwlGb250SW5mb0ZjLndpZE1heCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEZvbnRJbmZvRmMuY2xhenosICJ3aWRNYXgiLCAiUyIpOworCUZvbnRJbmZvRmMubGVhZGluZyA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEZvbnRJbmZvRmMuY2xhenosICJsZWFkaW5nIiwgIlMiKTsKKwlGb250SW5mb0ZjLmNhY2hlZCA9IDE7Cit9CisKK0ZvbnRJbmZvICpnZXRGb250SW5mb0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRm9udEluZm8gKmxwU3RydWN0KQoreworCWlmICghRm9udEluZm9GYy5jYWNoZWQpIGNhY2hlRm9udEluZm9GaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT5hc2NlbnQgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRm9udEluZm9GYy5hc2NlbnQpOworCWxwU3RydWN0LT5kZXNjZW50ID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEZvbnRJbmZvRmMuZGVzY2VudCk7CisJbHBTdHJ1Y3QtPndpZE1heCA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBGb250SW5mb0ZjLndpZE1heCk7CisJbHBTdHJ1Y3QtPmxlYWRpbmcgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRm9udEluZm9GYy5sZWFkaW5nKTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0Rm9udEluZm9GaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIEZvbnRJbmZvICpscFN0cnVjdCkKK3sKKwlpZiAoIUZvbnRJbmZvRmMuY2FjaGVkKSBjYWNoZUZvbnRJbmZvRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRm9udEluZm9GYy5hc2NlbnQsIChqc2hvcnQpbHBTdHJ1Y3QtPmFzY2VudCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEZvbnRJbmZvRmMuZGVzY2VudCwgKGpzaG9ydClscFN0cnVjdC0+ZGVzY2VudCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEZvbnRJbmZvRmMud2lkTWF4LCAoanNob3J0KWxwU3RydWN0LT53aWRNYXgpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBGb250SW5mb0ZjLmxlYWRpbmcsIChqc2hvcnQpbHBTdHJ1Y3QtPmxlYWRpbmcpOworfQorI2VuZGlmIC8qIE5PX0ZvbnRJbmZvICovCisKKyNpZm5kZWYgTk9fRm9udFNlbGVjdGlvblFEU3R5bGUKK3R5cGVkZWYgc3RydWN0IEZvbnRTZWxlY3Rpb25RRFN0eWxlX0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgdmVyc2lvbiwgaW5zdGFuY2VfZm9udEZhbWlseSwgaW5zdGFuY2VfZm9udFN0eWxlLCBzaXplLCBoYXNDb2xvciwgcmVzZXJ2ZWQsIGNvbG9yX3JlZCwgY29sb3JfZ3JlZW4sIGNvbG9yX2JsdWU7Cit9IEZvbnRTZWxlY3Rpb25RRFN0eWxlX0ZJRF9DQUNIRTsKKworRm9udFNlbGVjdGlvblFEU3R5bGVfRklEX0NBQ0hFIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmM7CisKK3ZvaWQgY2FjaGVGb250U2VsZWN0aW9uUURTdHlsZUZpZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QpCit7CisJaWYgKEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuY2FjaGVkKSByZXR1cm47CisJRm9udFNlbGVjdGlvblFEU3R5bGVGYy5jbGF6eiA9ICgqZW52KS0+R2V0T2JqZWN0Q2xhc3MoZW52LCBscE9iamVjdCk7CisJRm9udFNlbGVjdGlvblFEU3R5bGVGYy52ZXJzaW9uID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRm9udFNlbGVjdGlvblFEU3R5bGVGYy5jbGF6eiwgInZlcnNpb24iLCAiSSIpOworCUZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuaW5zdGFuY2VfZm9udEZhbWlseSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuY2xhenosICJpbnN0YW5jZV9mb250RmFtaWx5IiwgIlMiKTsKKwlGb250U2VsZWN0aW9uUURTdHlsZUZjLmluc3RhbmNlX2ZvbnRTdHlsZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuY2xhenosICJpbnN0YW5jZV9mb250U3R5bGUiLCAiUyIpOworCUZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuc2l6ZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuY2xhenosICJzaXplIiwgIlMiKTsKKwlGb250U2VsZWN0aW9uUURTdHlsZUZjLmhhc0NvbG9yID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRm9udFNlbGVjdGlvblFEU3R5bGVGYy5jbGF6eiwgImhhc0NvbG9yIiwgIloiKTsKKwlGb250U2VsZWN0aW9uUURTdHlsZUZjLnJlc2VydmVkID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgRm9udFNlbGVjdGlvblFEU3R5bGVGYy5jbGF6eiwgInJlc2VydmVkIiwgIkIiKTsKKwlGb250U2VsZWN0aW9uUURTdHlsZUZjLmNvbG9yX3JlZCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuY2xhenosICJjb2xvcl9yZWQiLCAiUyIpOworCUZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuY29sb3JfZ3JlZW4gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBGb250U2VsZWN0aW9uUURTdHlsZUZjLmNsYXp6LCAiY29sb3JfZ3JlZW4iLCAiUyIpOworCUZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuY29sb3JfYmx1ZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuY2xhenosICJjb2xvcl9ibHVlIiwgIlMiKTsKKwlGb250U2VsZWN0aW9uUURTdHlsZUZjLmNhY2hlZCA9IDE7Cit9CisKK0ZvbnRTZWxlY3Rpb25RRFN0eWxlICpnZXRGb250U2VsZWN0aW9uUURTdHlsZUZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRm9udFNlbGVjdGlvblFEU3R5bGUgKmxwU3RydWN0KQoreworCWlmICghRm9udFNlbGVjdGlvblFEU3R5bGVGYy5jYWNoZWQpIGNhY2hlRm9udFNlbGVjdGlvblFEU3R5bGVGaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT52ZXJzaW9uID0gKFVJbnQzMikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMudmVyc2lvbik7CisJbHBTdHJ1Y3QtPmluc3RhbmNlLmZvbnRGYW1pbHkgPSAoRk1Gb250RmFtaWx5KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBGb250U2VsZWN0aW9uUURTdHlsZUZjLmluc3RhbmNlX2ZvbnRGYW1pbHkpOworCWxwU3RydWN0LT5pbnN0YW5jZS5mb250U3R5bGUgPSAoRk1Gb250U3R5bGUpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuaW5zdGFuY2VfZm9udFN0eWxlKTsKKwlscFN0cnVjdC0+c2l6ZSA9IChGTUZvbnRTaXplKSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBGb250U2VsZWN0aW9uUURTdHlsZUZjLnNpemUpOworCWxwU3RydWN0LT5oYXNDb2xvciA9IChCb29sZWFuKSgqZW52KS0+R2V0Qm9vbGVhbkZpZWxkKGVudiwgbHBPYmplY3QsIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuaGFzQ29sb3IpOworCWxwU3RydWN0LT5yZXNlcnZlZCA9IChVSW50OCkoKmVudiktPkdldEJ5dGVGaWVsZChlbnYsIGxwT2JqZWN0LCBGb250U2VsZWN0aW9uUURTdHlsZUZjLnJlc2VydmVkKTsKKwlscFN0cnVjdC0+Y29sb3IucmVkID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuY29sb3JfcmVkKTsKKwlscFN0cnVjdC0+Y29sb3IuZ3JlZW4gPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRm9udFNlbGVjdGlvblFEU3R5bGVGYy5jb2xvcl9ncmVlbik7CisJbHBTdHJ1Y3QtPmNvbG9yLmJsdWUgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRm9udFNlbGVjdGlvblFEU3R5bGVGYy5jb2xvcl9ibHVlKTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0Rm9udFNlbGVjdGlvblFEU3R5bGVGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIEZvbnRTZWxlY3Rpb25RRFN0eWxlICpscFN0cnVjdCkKK3sKKwlpZiAoIUZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuY2FjaGVkKSBjYWNoZUZvbnRTZWxlY3Rpb25RRFN0eWxlRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMudmVyc2lvbiwgKGppbnQpbHBTdHJ1Y3QtPnZlcnNpb24pOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBGb250U2VsZWN0aW9uUURTdHlsZUZjLmluc3RhbmNlX2ZvbnRGYW1pbHksIChqc2hvcnQpbHBTdHJ1Y3QtPmluc3RhbmNlLmZvbnRGYW1pbHkpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBGb250U2VsZWN0aW9uUURTdHlsZUZjLmluc3RhbmNlX2ZvbnRTdHlsZSwgKGpzaG9ydClscFN0cnVjdC0+aW5zdGFuY2UuZm9udFN0eWxlKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRm9udFNlbGVjdGlvblFEU3R5bGVGYy5zaXplLCAoanNob3J0KWxwU3RydWN0LT5zaXplKTsKKwkoKmVudiktPlNldEJvb2xlYW5GaWVsZChlbnYsIGxwT2JqZWN0LCBGb250U2VsZWN0aW9uUURTdHlsZUZjLmhhc0NvbG9yLCAoamJvb2xlYW4pbHBTdHJ1Y3QtPmhhc0NvbG9yKTsKKwkoKmVudiktPlNldEJ5dGVGaWVsZChlbnYsIGxwT2JqZWN0LCBGb250U2VsZWN0aW9uUURTdHlsZUZjLnJlc2VydmVkLCAoamJ5dGUpbHBTdHJ1Y3QtPnJlc2VydmVkKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRm9udFNlbGVjdGlvblFEU3R5bGVGYy5jb2xvcl9yZWQsIChqc2hvcnQpbHBTdHJ1Y3QtPmNvbG9yLnJlZCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEZvbnRTZWxlY3Rpb25RRFN0eWxlRmMuY29sb3JfZ3JlZW4sIChqc2hvcnQpbHBTdHJ1Y3QtPmNvbG9yLmdyZWVuKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgRm9udFNlbGVjdGlvblFEU3R5bGVGYy5jb2xvcl9ibHVlLCAoanNob3J0KWxwU3RydWN0LT5jb2xvci5ibHVlKTsKK30KKyNlbmRpZiAvKiBOT19Gb250U2VsZWN0aW9uUURTdHlsZSAqLworCisjaWZuZGVmIE5PX0dEZXZpY2UKK3R5cGVkZWYgc3RydWN0IEdEZXZpY2VfRklEX0NBQ0hFIHsKKwlpbnQgY2FjaGVkOworCWpjbGFzcyBjbGF6ejsKKwlqZmllbGRJRCBnZFJlZk51bSwgZ2RJRCwgZ2RUeXBlLCBnZElUYWJsZSwgZ2RSZXNQcmVmLCBnZFNlYXJjaFByb2MsIGdkQ29tcFByb2MsIGdkRmxhZ3MsIGdkUE1hcCwgZ2RSZWZDb24sIGdkTmV4dEdELCBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b20sIGdkTW9kZSwgZ2RDQ0J5dGVzLCBnZENDRGVwdGgsIGdkQ0NYRGF0YSwgZ2RDQ1hNYXNrLCBnZEV4dDsKK30gR0RldmljZV9GSURfQ0FDSEU7CisKK0dEZXZpY2VfRklEX0NBQ0hFIEdEZXZpY2VGYzsKKwordm9pZCBjYWNoZUdEZXZpY2VGaWRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0KQoreworCWlmIChHRGV2aWNlRmMuY2FjaGVkKSByZXR1cm47CisJR0RldmljZUZjLmNsYXp6ID0gKCplbnYpLT5HZXRPYmplY3RDbGFzcyhlbnYsIGxwT2JqZWN0KTsKKwlHRGV2aWNlRmMuZ2RSZWZOdW0gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBHRGV2aWNlRmMuY2xhenosICJnZFJlZk51bSIsICJTIik7CisJR0RldmljZUZjLmdkSUQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBHRGV2aWNlRmMuY2xhenosICJnZElEIiwgIlMiKTsKKwlHRGV2aWNlRmMuZ2RUeXBlID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgR0RldmljZUZjLmNsYXp6LCAiZ2RUeXBlIiwgIlMiKTsKKwlHRGV2aWNlRmMuZ2RJVGFibGUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBHRGV2aWNlRmMuY2xhenosICJnZElUYWJsZSIsICJJIik7CisJR0RldmljZUZjLmdkUmVzUHJlZiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEdEZXZpY2VGYy5jbGF6eiwgImdkUmVzUHJlZiIsICJTIik7CisJR0RldmljZUZjLmdkU2VhcmNoUHJvYyA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEdEZXZpY2VGYy5jbGF6eiwgImdkU2VhcmNoUHJvYyIsICJJIik7CisJR0RldmljZUZjLmdkQ29tcFByb2MgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBHRGV2aWNlRmMuY2xhenosICJnZENvbXBQcm9jIiwgIkkiKTsKKwlHRGV2aWNlRmMuZ2RGbGFncyA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEdEZXZpY2VGYy5jbGF6eiwgImdkRmxhZ3MiLCAiUyIpOworCUdEZXZpY2VGYy5nZFBNYXAgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBHRGV2aWNlRmMuY2xhenosICJnZFBNYXAiLCAiSSIpOworCUdEZXZpY2VGYy5nZFJlZkNvbiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEdEZXZpY2VGYy5jbGF6eiwgImdkUmVmQ29uIiwgIkkiKTsKKwlHRGV2aWNlRmMuZ2ROZXh0R0QgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBHRGV2aWNlRmMuY2xhenosICJnZE5leHRHRCIsICJJIik7CisJR0RldmljZUZjLmxlZnQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBHRGV2aWNlRmMuY2xhenosICJsZWZ0IiwgIlMiKTsKKwlHRGV2aWNlRmMudG9wID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgR0RldmljZUZjLmNsYXp6LCAidG9wIiwgIlMiKTsKKwlHRGV2aWNlRmMucmlnaHQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBHRGV2aWNlRmMuY2xhenosICJyaWdodCIsICJTIik7CisJR0RldmljZUZjLmJvdHRvbSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEdEZXZpY2VGYy5jbGF6eiwgImJvdHRvbSIsICJTIik7CisJR0RldmljZUZjLmdkTW9kZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEdEZXZpY2VGYy5jbGF6eiwgImdkTW9kZSIsICJJIik7CisJR0RldmljZUZjLmdkQ0NCeXRlcyA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEdEZXZpY2VGYy5jbGF6eiwgImdkQ0NCeXRlcyIsICJTIik7CisJR0RldmljZUZjLmdkQ0NEZXB0aCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEdEZXZpY2VGYy5jbGF6eiwgImdkQ0NEZXB0aCIsICJTIik7CisJR0RldmljZUZjLmdkQ0NYRGF0YSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEdEZXZpY2VGYy5jbGF6eiwgImdkQ0NYRGF0YSIsICJJIik7CisJR0RldmljZUZjLmdkQ0NYTWFzayA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEdEZXZpY2VGYy5jbGF6eiwgImdkQ0NYTWFzayIsICJJIik7CisJR0RldmljZUZjLmdkRXh0ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgR0RldmljZUZjLmNsYXp6LCAiZ2RFeHQiLCAiSSIpOworCUdEZXZpY2VGYy5jYWNoZWQgPSAxOworfQorCitHRGV2aWNlICpnZXRHRGV2aWNlRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBHRGV2aWNlICpscFN0cnVjdCkKK3sKKwlpZiAoIUdEZXZpY2VGYy5jYWNoZWQpIGNhY2hlR0RldmljZUZpZHMoZW52LCBscE9iamVjdCk7CisJbHBTdHJ1Y3QtPmdkUmVmTnVtID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEdEZXZpY2VGYy5nZFJlZk51bSk7CisJbHBTdHJ1Y3QtPmdkSUQgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkSUQpOworCWxwU3RydWN0LT5nZFR5cGUgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkVHlwZSk7CisJbHBTdHJ1Y3QtPmdkSVRhYmxlID0gKElUYWJIYW5kbGUpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RJVGFibGUpOworCWxwU3RydWN0LT5nZFJlc1ByZWYgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkUmVzUHJlZik7CisJbHBTdHJ1Y3QtPmdkU2VhcmNoUHJvYyA9IChTUHJvY0huZGwpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RTZWFyY2hQcm9jKTsKKwlscFN0cnVjdC0+Z2RDb21wUHJvYyA9IChDUHJvY0huZGwpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RDb21wUHJvYyk7CisJbHBTdHJ1Y3QtPmdkRmxhZ3MgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkRmxhZ3MpOworCWxwU3RydWN0LT5nZFBNYXAgPSAoUGl4TWFwSGFuZGxlKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkUE1hcCk7CisJbHBTdHJ1Y3QtPmdkUmVmQ29uID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RSZWZDb24pOworCWxwU3RydWN0LT5nZE5leHRHRCA9IChHREhhbmRsZSkoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEdEZXZpY2VGYy5nZE5leHRHRCk7CisJbHBTdHJ1Y3QtPmdkUmVjdC5sZWZ0ID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEdEZXZpY2VGYy5sZWZ0KTsKKwlscFN0cnVjdC0+Z2RSZWN0LnRvcCA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMudG9wKTsKKwlscFN0cnVjdC0+Z2RSZWN0LnJpZ2h0ID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEdEZXZpY2VGYy5yaWdodCk7CisJbHBTdHJ1Y3QtPmdkUmVjdC5ib3R0b20gPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmJvdHRvbSk7CisJbHBTdHJ1Y3QtPmdkTW9kZSA9ICgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkTW9kZSk7CisJbHBTdHJ1Y3QtPmdkQ0NCeXRlcyA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RDQ0J5dGVzKTsKKwlscFN0cnVjdC0+Z2RDQ0RlcHRoID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEdEZXZpY2VGYy5nZENDRGVwdGgpOworCWxwU3RydWN0LT5nZENDWERhdGEgPSAoSGFuZGxlKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkQ0NYRGF0YSk7CisJbHBTdHJ1Y3QtPmdkQ0NYTWFzayA9IChIYW5kbGUpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RDQ1hNYXNrKTsKKwlscFN0cnVjdC0+Z2RFeHQgPSAoSGFuZGxlKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkRXh0KTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0R0RldmljZUZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgR0RldmljZSAqbHBTdHJ1Y3QpCit7CisJaWYgKCFHRGV2aWNlRmMuY2FjaGVkKSBjYWNoZUdEZXZpY2VGaWRzKGVudiwgbHBPYmplY3QpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RSZWZOdW0sIChqc2hvcnQpbHBTdHJ1Y3QtPmdkUmVmTnVtKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkSUQsIChqc2hvcnQpbHBTdHJ1Y3QtPmdkSUQpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RUeXBlLCAoanNob3J0KWxwU3RydWN0LT5nZFR5cGUpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkSVRhYmxlLCAoamludClscFN0cnVjdC0+Z2RJVGFibGUpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RSZXNQcmVmLCAoanNob3J0KWxwU3RydWN0LT5nZFJlc1ByZWYpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkU2VhcmNoUHJvYywgKGppbnQpbHBTdHJ1Y3QtPmdkU2VhcmNoUHJvYyk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RDb21wUHJvYywgKGppbnQpbHBTdHJ1Y3QtPmdkQ29tcFByb2MpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RGbGFncywgKGpzaG9ydClscFN0cnVjdC0+Z2RGbGFncyk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RQTWFwLCAoamludClscFN0cnVjdC0+Z2RQTWFwKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEdEZXZpY2VGYy5nZFJlZkNvbiwgKGppbnQpbHBTdHJ1Y3QtPmdkUmVmQ29uKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEdEZXZpY2VGYy5nZE5leHRHRCwgKGppbnQpbHBTdHJ1Y3QtPmdkTmV4dEdEKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmxlZnQsIChqc2hvcnQpbHBTdHJ1Y3QtPmdkUmVjdC5sZWZ0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLnRvcCwgKGpzaG9ydClscFN0cnVjdC0+Z2RSZWN0LnRvcCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEdEZXZpY2VGYy5yaWdodCwgKGpzaG9ydClscFN0cnVjdC0+Z2RSZWN0LnJpZ2h0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmJvdHRvbSwgKGpzaG9ydClscFN0cnVjdC0+Z2RSZWN0LmJvdHRvbSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RNb2RlLCAoamludClscFN0cnVjdC0+Z2RNb2RlKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkQ0NCeXRlcywgKGpzaG9ydClscFN0cnVjdC0+Z2RDQ0J5dGVzKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkQ0NEZXB0aCwgKGpzaG9ydClscFN0cnVjdC0+Z2RDQ0RlcHRoKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEdEZXZpY2VGYy5nZENDWERhdGEsIChqaW50KWxwU3RydWN0LT5nZENDWERhdGEpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgR0RldmljZUZjLmdkQ0NYTWFzaywgKGppbnQpbHBTdHJ1Y3QtPmdkQ0NYTWFzayk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBHRGV2aWNlRmMuZ2RFeHQsIChqaW50KWxwU3RydWN0LT5nZEV4dCk7Cit9CisjZW5kaWYgLyogTk9fR0RldmljZSAqLworCisjaWZuZGVmIE5PX0hJQ29tbWFuZAordHlwZWRlZiBzdHJ1Y3QgSElDb21tYW5kX0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgYXR0cmlidXRlcywgY29tbWFuZElELCBtZW51X21lbnVSZWYsIG1lbnVfbWVudUl0ZW1JbmRleDsKK30gSElDb21tYW5kX0ZJRF9DQUNIRTsKKworSElDb21tYW5kX0ZJRF9DQUNIRSBISUNvbW1hbmRGYzsKKwordm9pZCBjYWNoZUhJQ29tbWFuZEZpZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QpCit7CisJaWYgKEhJQ29tbWFuZEZjLmNhY2hlZCkgcmV0dXJuOworCUhJQ29tbWFuZEZjLmNsYXp6ID0gKCplbnYpLT5HZXRPYmplY3RDbGFzcyhlbnYsIGxwT2JqZWN0KTsKKwlISUNvbW1hbmRGYy5hdHRyaWJ1dGVzID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgSElDb21tYW5kRmMuY2xhenosICJhdHRyaWJ1dGVzIiwgIkkiKTsKKwlISUNvbW1hbmRGYy5jb21tYW5kSUQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBISUNvbW1hbmRGYy5jbGF6eiwgImNvbW1hbmRJRCIsICJJIik7CisJSElDb21tYW5kRmMubWVudV9tZW51UmVmID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgSElDb21tYW5kRmMuY2xhenosICJtZW51X21lbnVSZWYiLCAiSSIpOworCUhJQ29tbWFuZEZjLm1lbnVfbWVudUl0ZW1JbmRleCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEhJQ29tbWFuZEZjLmNsYXp6LCAibWVudV9tZW51SXRlbUluZGV4IiwgIlMiKTsKKwlISUNvbW1hbmRGYy5jYWNoZWQgPSAxOworfQorCitISUNvbW1hbmQgKmdldEhJQ29tbWFuZEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgSElDb21tYW5kICpscFN0cnVjdCkKK3sKKwlpZiAoIUhJQ29tbWFuZEZjLmNhY2hlZCkgY2FjaGVISUNvbW1hbmRGaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT5hdHRyaWJ1dGVzID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBISUNvbW1hbmRGYy5hdHRyaWJ1dGVzKTsKKwlscFN0cnVjdC0+Y29tbWFuZElEID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBISUNvbW1hbmRGYy5jb21tYW5kSUQpOworCWxwU3RydWN0LT5tZW51Lm1lbnVSZWYgPSAoTWVudVJlZikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEhJQ29tbWFuZEZjLm1lbnVfbWVudVJlZik7CisJbHBTdHJ1Y3QtPm1lbnUubWVudUl0ZW1JbmRleCA9IChNZW51SXRlbUluZGV4KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBISUNvbW1hbmRGYy5tZW51X21lbnVJdGVtSW5kZXgpOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXRISUNvbW1hbmRGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIEhJQ29tbWFuZCAqbHBTdHJ1Y3QpCit7CisJaWYgKCFISUNvbW1hbmRGYy5jYWNoZWQpIGNhY2hlSElDb21tYW5kRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEhJQ29tbWFuZEZjLmF0dHJpYnV0ZXMsIChqaW50KWxwU3RydWN0LT5hdHRyaWJ1dGVzKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIEhJQ29tbWFuZEZjLmNvbW1hbmRJRCwgKGppbnQpbHBTdHJ1Y3QtPmNvbW1hbmRJRCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBISUNvbW1hbmRGYy5tZW51X21lbnVSZWYsIChqaW50KWxwU3RydWN0LT5tZW51Lm1lbnVSZWYpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBISUNvbW1hbmRGYy5tZW51X21lbnVJdGVtSW5kZXgsIChqc2hvcnQpbHBTdHJ1Y3QtPm1lbnUubWVudUl0ZW1JbmRleCk7Cit9CisjZW5kaWYgLyogTk9fSElDb21tYW5kICovCisKKyNpZm5kZWYgTk9fSE1IZWxwQ29udGVudFJlYwordHlwZWRlZiBzdHJ1Y3QgSE1IZWxwQ29udGVudFJlY19GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIHZlcnNpb24sIGFic0hvdFJlY3RfdG9wLCBhYnNIb3RSZWN0X2xlZnQsIGFic0hvdFJlY3RfYm90dG9tLCBhYnNIb3RSZWN0X3JpZ2h0LCB0YWdTaWRlLCBjb250ZW50MF9jb250ZW50VHlwZSwgY29udGVudDBfdGFnQ0ZTdHJpbmcsIGNvbnRlbnQxX2NvbnRlbnRUeXBlLCBjb250ZW50MV90YWdDRlN0cmluZzsKK30gSE1IZWxwQ29udGVudFJlY19GSURfQ0FDSEU7CisKK0hNSGVscENvbnRlbnRSZWNfRklEX0NBQ0hFIEhNSGVscENvbnRlbnRSZWNGYzsKKwordm9pZCBjYWNoZUhNSGVscENvbnRlbnRSZWNGaWRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0KQoreworCWlmIChITUhlbHBDb250ZW50UmVjRmMuY2FjaGVkKSByZXR1cm47CisJSE1IZWxwQ29udGVudFJlY0ZjLmNsYXp6ID0gKCplbnYpLT5HZXRPYmplY3RDbGFzcyhlbnYsIGxwT2JqZWN0KTsKKwlITUhlbHBDb250ZW50UmVjRmMudmVyc2lvbiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEhNSGVscENvbnRlbnRSZWNGYy5jbGF6eiwgInZlcnNpb24iLCAiSSIpOworCUhNSGVscENvbnRlbnRSZWNGYy5hYnNIb3RSZWN0X3RvcCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEhNSGVscENvbnRlbnRSZWNGYy5jbGF6eiwgImFic0hvdFJlY3RfdG9wIiwgIlMiKTsKKwlITUhlbHBDb250ZW50UmVjRmMuYWJzSG90UmVjdF9sZWZ0ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgSE1IZWxwQ29udGVudFJlY0ZjLmNsYXp6LCAiYWJzSG90UmVjdF9sZWZ0IiwgIlMiKTsKKwlITUhlbHBDb250ZW50UmVjRmMuYWJzSG90UmVjdF9ib3R0b20gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBITUhlbHBDb250ZW50UmVjRmMuY2xhenosICJhYnNIb3RSZWN0X2JvdHRvbSIsICJTIik7CisJSE1IZWxwQ29udGVudFJlY0ZjLmFic0hvdFJlY3RfcmlnaHQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBITUhlbHBDb250ZW50UmVjRmMuY2xhenosICJhYnNIb3RSZWN0X3JpZ2h0IiwgIlMiKTsKKwlITUhlbHBDb250ZW50UmVjRmMudGFnU2lkZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEhNSGVscENvbnRlbnRSZWNGYy5jbGF6eiwgInRhZ1NpZGUiLCAiUyIpOworCUhNSGVscENvbnRlbnRSZWNGYy5jb250ZW50MF9jb250ZW50VHlwZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEhNSGVscENvbnRlbnRSZWNGYy5jbGF6eiwgImNvbnRlbnQwX2NvbnRlbnRUeXBlIiwgIkkiKTsKKwlITUhlbHBDb250ZW50UmVjRmMuY29udGVudDBfdGFnQ0ZTdHJpbmcgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBITUhlbHBDb250ZW50UmVjRmMuY2xhenosICJjb250ZW50MF90YWdDRlN0cmluZyIsICJJIik7CisJSE1IZWxwQ29udGVudFJlY0ZjLmNvbnRlbnQxX2NvbnRlbnRUeXBlID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgSE1IZWxwQ29udGVudFJlY0ZjLmNsYXp6LCAiY29udGVudDFfY29udGVudFR5cGUiLCAiSSIpOworCUhNSGVscENvbnRlbnRSZWNGYy5jb250ZW50MV90YWdDRlN0cmluZyA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIEhNSGVscENvbnRlbnRSZWNGYy5jbGF6eiwgImNvbnRlbnQxX3RhZ0NGU3RyaW5nIiwgIkkiKTsKKwlITUhlbHBDb250ZW50UmVjRmMuY2FjaGVkID0gMTsKK30KKworSE1IZWxwQ29udGVudFJlYyAqZ2V0SE1IZWxwQ29udGVudFJlY0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgSE1IZWxwQ29udGVudFJlYyAqbHBTdHJ1Y3QpCit7CisJaWYgKCFITUhlbHBDb250ZW50UmVjRmMuY2FjaGVkKSBjYWNoZUhNSGVscENvbnRlbnRSZWNGaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT52ZXJzaW9uID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjRmMudmVyc2lvbik7CisJbHBTdHJ1Y3QtPmFic0hvdFJlY3QudG9wID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEhNSGVscENvbnRlbnRSZWNGYy5hYnNIb3RSZWN0X3RvcCk7CisJbHBTdHJ1Y3QtPmFic0hvdFJlY3QubGVmdCA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjRmMuYWJzSG90UmVjdF9sZWZ0KTsKKwlscFN0cnVjdC0+YWJzSG90UmVjdC5ib3R0b20gPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgSE1IZWxwQ29udGVudFJlY0ZjLmFic0hvdFJlY3RfYm90dG9tKTsKKwlscFN0cnVjdC0+YWJzSG90UmVjdC5yaWdodCA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjRmMuYWJzSG90UmVjdF9yaWdodCk7CisJbHBTdHJ1Y3QtPnRhZ1NpZGUgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgSE1IZWxwQ29udGVudFJlY0ZjLnRhZ1NpZGUpOworCWxwU3RydWN0LT5jb250ZW50WzBdLmNvbnRlbnRUeXBlID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjRmMuY29udGVudDBfY29udGVudFR5cGUpOworCWxwU3RydWN0LT5jb250ZW50WzBdLnUudGFnQ0ZTdHJpbmcgPSAoQ0ZTdHJpbmdSZWYpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjRmMuY29udGVudDBfdGFnQ0ZTdHJpbmcpOworCWxwU3RydWN0LT5jb250ZW50WzFdLmNvbnRlbnRUeXBlID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjRmMuY29udGVudDFfY29udGVudFR5cGUpOworCWxwU3RydWN0LT5jb250ZW50WzFdLnUudGFnQ0ZTdHJpbmcgPSAoQ0ZTdHJpbmdSZWYpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjRmMuY29udGVudDFfdGFnQ0ZTdHJpbmcpOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXRITUhlbHBDb250ZW50UmVjRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjICpscFN0cnVjdCkKK3sKKwlpZiAoIUhNSGVscENvbnRlbnRSZWNGYy5jYWNoZWQpIGNhY2hlSE1IZWxwQ29udGVudFJlY0ZpZHMoZW52LCBscE9iamVjdCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjRmMudmVyc2lvbiwgKGppbnQpbHBTdHJ1Y3QtPnZlcnNpb24pOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjRmMuYWJzSG90UmVjdF90b3AsIChqc2hvcnQpbHBTdHJ1Y3QtPmFic0hvdFJlY3QudG9wKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgSE1IZWxwQ29udGVudFJlY0ZjLmFic0hvdFJlY3RfbGVmdCwgKGpzaG9ydClscFN0cnVjdC0+YWJzSG90UmVjdC5sZWZ0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgSE1IZWxwQ29udGVudFJlY0ZjLmFic0hvdFJlY3RfYm90dG9tLCAoanNob3J0KWxwU3RydWN0LT5hYnNIb3RSZWN0LmJvdHRvbSk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIEhNSGVscENvbnRlbnRSZWNGYy5hYnNIb3RSZWN0X3JpZ2h0LCAoanNob3J0KWxwU3RydWN0LT5hYnNIb3RSZWN0LnJpZ2h0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgSE1IZWxwQ29udGVudFJlY0ZjLnRhZ1NpZGUsIChqc2hvcnQpbHBTdHJ1Y3QtPnRhZ1NpZGUpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgSE1IZWxwQ29udGVudFJlY0ZjLmNvbnRlbnQwX2NvbnRlbnRUeXBlLCAoamludClscFN0cnVjdC0+Y29udGVudFswXS5jb250ZW50VHlwZSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjRmMuY29udGVudDBfdGFnQ0ZTdHJpbmcsIChqaW50KWxwU3RydWN0LT5jb250ZW50WzBdLnUudGFnQ0ZTdHJpbmcpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgSE1IZWxwQ29udGVudFJlY0ZjLmNvbnRlbnQxX2NvbnRlbnRUeXBlLCAoamludClscFN0cnVjdC0+Y29udGVudFsxXS5jb250ZW50VHlwZSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjRmMuY29udGVudDFfdGFnQ0ZTdHJpbmcsIChqaW50KWxwU3RydWN0LT5jb250ZW50WzFdLnUudGFnQ0ZTdHJpbmcpOworfQorI2VuZGlmIC8qIE5PX0hNSGVscENvbnRlbnRSZWMgKi8KKworI2lmbmRlZiBOT19NZW51VHJhY2tpbmdEYXRhCit0eXBlZGVmIHN0cnVjdCBNZW51VHJhY2tpbmdEYXRhX0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgbWVudSwgaXRlbVNlbGVjdGVkLCBpdGVtVW5kZXJNb3VzZSwgdG9wLCBsZWZ0LCBib3R0b20sIHJpZ2h0LCB2aXJ0dWFsTWVudVRvcCwgdmlydHVhbE1lbnVCb3R0b207Cit9IE1lbnVUcmFja2luZ0RhdGFfRklEX0NBQ0hFOworCitNZW51VHJhY2tpbmdEYXRhX0ZJRF9DQUNIRSBNZW51VHJhY2tpbmdEYXRhRmM7CisKK3ZvaWQgY2FjaGVNZW51VHJhY2tpbmdEYXRhRmlkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCkKK3sKKwlpZiAoTWVudVRyYWNraW5nRGF0YUZjLmNhY2hlZCkgcmV0dXJuOworCU1lbnVUcmFja2luZ0RhdGFGYy5jbGF6eiA9ICgqZW52KS0+R2V0T2JqZWN0Q2xhc3MoZW52LCBscE9iamVjdCk7CisJTWVudVRyYWNraW5nRGF0YUZjLm1lbnUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBNZW51VHJhY2tpbmdEYXRhRmMuY2xhenosICJtZW51IiwgIkkiKTsKKwlNZW51VHJhY2tpbmdEYXRhRmMuaXRlbVNlbGVjdGVkID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTWVudVRyYWNraW5nRGF0YUZjLmNsYXp6LCAiaXRlbVNlbGVjdGVkIiwgIlMiKTsKKwlNZW51VHJhY2tpbmdEYXRhRmMuaXRlbVVuZGVyTW91c2UgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBNZW51VHJhY2tpbmdEYXRhRmMuY2xhenosICJpdGVtVW5kZXJNb3VzZSIsICJTIik7CisJTWVudVRyYWNraW5nRGF0YUZjLnRvcCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIE1lbnVUcmFja2luZ0RhdGFGYy5jbGF6eiwgInRvcCIsICJTIik7CisJTWVudVRyYWNraW5nRGF0YUZjLmxlZnQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBNZW51VHJhY2tpbmdEYXRhRmMuY2xhenosICJsZWZ0IiwgIlMiKTsKKwlNZW51VHJhY2tpbmdEYXRhRmMuYm90dG9tID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTWVudVRyYWNraW5nRGF0YUZjLmNsYXp6LCAiYm90dG9tIiwgIlMiKTsKKwlNZW51VHJhY2tpbmdEYXRhRmMucmlnaHQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBNZW51VHJhY2tpbmdEYXRhRmMuY2xhenosICJyaWdodCIsICJTIik7CisJTWVudVRyYWNraW5nRGF0YUZjLnZpcnR1YWxNZW51VG9wID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTWVudVRyYWNraW5nRGF0YUZjLmNsYXp6LCAidmlydHVhbE1lbnVUb3AiLCAiSSIpOworCU1lbnVUcmFja2luZ0RhdGFGYy52aXJ0dWFsTWVudUJvdHRvbSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIE1lbnVUcmFja2luZ0RhdGFGYy5jbGF6eiwgInZpcnR1YWxNZW51Qm90dG9tIiwgIkkiKTsKKwlNZW51VHJhY2tpbmdEYXRhRmMuY2FjaGVkID0gMTsKK30KKworTWVudVRyYWNraW5nRGF0YSAqZ2V0TWVudVRyYWNraW5nRGF0YUZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgTWVudVRyYWNraW5nRGF0YSAqbHBTdHJ1Y3QpCit7CisJaWYgKCFNZW51VHJhY2tpbmdEYXRhRmMuY2FjaGVkKSBjYWNoZU1lbnVUcmFja2luZ0RhdGFGaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT5tZW51ID0gKE1lbnVSZWYpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBNZW51VHJhY2tpbmdEYXRhRmMubWVudSk7CisJbHBTdHJ1Y3QtPml0ZW1TZWxlY3RlZCA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBNZW51VHJhY2tpbmdEYXRhRmMuaXRlbVNlbGVjdGVkKTsKKwlscFN0cnVjdC0+aXRlbVVuZGVyTW91c2UgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgTWVudVRyYWNraW5nRGF0YUZjLml0ZW1VbmRlck1vdXNlKTsKKwlscFN0cnVjdC0+aXRlbVJlY3QudG9wID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIE1lbnVUcmFja2luZ0RhdGFGYy50b3ApOworCWxwU3RydWN0LT5pdGVtUmVjdC5sZWZ0ID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIE1lbnVUcmFja2luZ0RhdGFGYy5sZWZ0KTsKKwlscFN0cnVjdC0+aXRlbVJlY3QuYm90dG9tID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIE1lbnVUcmFja2luZ0RhdGFGYy5ib3R0b20pOworCWxwU3RydWN0LT5pdGVtUmVjdC5yaWdodCA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBNZW51VHJhY2tpbmdEYXRhRmMucmlnaHQpOworCWxwU3RydWN0LT52aXJ0dWFsTWVudVRvcCA9ICgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgTWVudVRyYWNraW5nRGF0YUZjLnZpcnR1YWxNZW51VG9wKTsKKwlscFN0cnVjdC0+dmlydHVhbE1lbnVCb3R0b20gPSAoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE1lbnVUcmFja2luZ0RhdGFGYy52aXJ0dWFsTWVudUJvdHRvbSk7CisJcmV0dXJuIGxwU3RydWN0OworfQorCit2b2lkIHNldE1lbnVUcmFja2luZ0RhdGFGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIE1lbnVUcmFja2luZ0RhdGEgKmxwU3RydWN0KQoreworCWlmICghTWVudVRyYWNraW5nRGF0YUZjLmNhY2hlZCkgY2FjaGVNZW51VHJhY2tpbmdEYXRhRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE1lbnVUcmFja2luZ0RhdGFGYy5tZW51LCAoamludClscFN0cnVjdC0+bWVudSk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIE1lbnVUcmFja2luZ0RhdGFGYy5pdGVtU2VsZWN0ZWQsIChqc2hvcnQpbHBTdHJ1Y3QtPml0ZW1TZWxlY3RlZCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIE1lbnVUcmFja2luZ0RhdGFGYy5pdGVtVW5kZXJNb3VzZSwgKGpzaG9ydClscFN0cnVjdC0+aXRlbVVuZGVyTW91c2UpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBNZW51VHJhY2tpbmdEYXRhRmMudG9wLCAoanNob3J0KWxwU3RydWN0LT5pdGVtUmVjdC50b3ApOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBNZW51VHJhY2tpbmdEYXRhRmMubGVmdCwgKGpzaG9ydClscFN0cnVjdC0+aXRlbVJlY3QubGVmdCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIE1lbnVUcmFja2luZ0RhdGFGYy5ib3R0b20sIChqc2hvcnQpbHBTdHJ1Y3QtPml0ZW1SZWN0LmJvdHRvbSk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIE1lbnVUcmFja2luZ0RhdGFGYy5yaWdodCwgKGpzaG9ydClscFN0cnVjdC0+aXRlbVJlY3QucmlnaHQpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgTWVudVRyYWNraW5nRGF0YUZjLnZpcnR1YWxNZW51VG9wLCAoamludClscFN0cnVjdC0+dmlydHVhbE1lbnVUb3ApOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgTWVudVRyYWNraW5nRGF0YUZjLnZpcnR1YWxNZW51Qm90dG9tLCAoamludClscFN0cnVjdC0+dmlydHVhbE1lbnVCb3R0b20pOworfQorI2VuZGlmIC8qIE5PX01lbnVUcmFja2luZ0RhdGEgKi8KKworI2lmbmRlZiBOT19OYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnMKK3R5cGVkZWYgc3RydWN0IE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc19GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIHZlcnNpb24sIG9wdGlvbkZsYWdzLCBsb2NhdGlvbl9oLCBsb2NhdGlvbl92LCBjbGllbnROYW1lLCB3aW5kb3dUaXRsZSwgYWN0aW9uQnV0dG9uTGFiZWwsIGNhbmNlbEJ1dHRvbkxhYmVsLCBzYXZlRmlsZU5hbWUsIG1lc3NhZ2UsIHByZWZlcmVuY2VLZXksIHBvcHVwRXh0ZW5zaW9uLCBtb2RhbGl0eSwgcGFyZW50V2luZG93OworfSBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNfRklEX0NBQ0hFOworCitOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNfRklEX0NBQ0hFIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjOworCit2b2lkIGNhY2hlTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmlkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCkKK3sKKwlpZiAoTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuY2FjaGVkKSByZXR1cm47CisJTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCU5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLnZlcnNpb24gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5jbGF6eiwgInZlcnNpb24iLCAiUyIpOworCU5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLm9wdGlvbkZsYWdzID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuY2xhenosICJvcHRpb25GbGFncyIsICJJIik7CisJTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMubG9jYXRpb25faCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLmNsYXp6LCAibG9jYXRpb25faCIsICJTIik7CisJTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMubG9jYXRpb25fdiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLmNsYXp6LCAibG9jYXRpb25fdiIsICJTIik7CisJTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuY2xpZW50TmFtZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLmNsYXp6LCAiY2xpZW50TmFtZSIsICJJIik7CisJTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMud2luZG93VGl0bGUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5jbGF6eiwgIndpbmRvd1RpdGxlIiwgIkkiKTsKKwlOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5hY3Rpb25CdXR0b25MYWJlbCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLmNsYXp6LCAiYWN0aW9uQnV0dG9uTGFiZWwiLCAiSSIpOworCU5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLmNhbmNlbEJ1dHRvbkxhYmVsID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuY2xhenosICJjYW5jZWxCdXR0b25MYWJlbCIsICJJIik7CisJTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuc2F2ZUZpbGVOYW1lID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuY2xhenosICJzYXZlRmlsZU5hbWUiLCAiSSIpOworCU5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLm1lc3NhZ2UgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5jbGF6eiwgIm1lc3NhZ2UiLCAiSSIpOworCU5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLnByZWZlcmVuY2VLZXkgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5jbGF6eiwgInByZWZlcmVuY2VLZXkiLCAiSSIpOworCU5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLnBvcHVwRXh0ZW5zaW9uID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuY2xhenosICJwb3B1cEV4dGVuc2lvbiIsICJJIik7CisJTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMubW9kYWxpdHkgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5jbGF6eiwgIm1vZGFsaXR5IiwgIkkiKTsKKwlOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5wYXJlbnRXaW5kb3cgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5jbGF6eiwgInBhcmVudFdpbmRvdyIsICJJIik7CisJTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuY2FjaGVkID0gMTsKK30KKworTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zICpnZXROYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucyAqbHBTdHJ1Y3QpCit7CisJaWYgKCFOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5jYWNoZWQpIGNhY2hlTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+dmVyc2lvbiA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy52ZXJzaW9uKTsKKwlscFN0cnVjdC0+b3B0aW9uRmxhZ3MgPSAoTmF2RGlhbG9nT3B0aW9uRmxhZ3MpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5vcHRpb25GbGFncyk7CisJbHBTdHJ1Y3QtPmxvY2F0aW9uLmggPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMubG9jYXRpb25faCk7CisJbHBTdHJ1Y3QtPmxvY2F0aW9uLnYgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMubG9jYXRpb25fdik7CisJbHBTdHJ1Y3QtPmNsaWVudE5hbWUgPSAoQ0ZTdHJpbmdSZWYpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5jbGllbnROYW1lKTsKKwlscFN0cnVjdC0+d2luZG93VGl0bGUgPSAoQ0ZTdHJpbmdSZWYpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy53aW5kb3dUaXRsZSk7CisJbHBTdHJ1Y3QtPmFjdGlvbkJ1dHRvbkxhYmVsID0gKENGU3RyaW5nUmVmKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuYWN0aW9uQnV0dG9uTGFiZWwpOworCWxwU3RydWN0LT5jYW5jZWxCdXR0b25MYWJlbCA9IChDRlN0cmluZ1JlZikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLmNhbmNlbEJ1dHRvbkxhYmVsKTsKKwlscFN0cnVjdC0+c2F2ZUZpbGVOYW1lID0gKENGU3RyaW5nUmVmKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuc2F2ZUZpbGVOYW1lKTsKKwlscFN0cnVjdC0+bWVzc2FnZSA9IChDRlN0cmluZ1JlZikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLm1lc3NhZ2UpOworCWxwU3RydWN0LT5wcmVmZXJlbmNlS2V5ID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5wcmVmZXJlbmNlS2V5KTsKKwlscFN0cnVjdC0+cG9wdXBFeHRlbnNpb24gPSAoQ0ZBcnJheVJlZikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLnBvcHVwRXh0ZW5zaW9uKTsKKwlscFN0cnVjdC0+bW9kYWxpdHkgPSAoV2luZG93TW9kYWxpdHkpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5tb2RhbGl0eSk7CisJbHBTdHJ1Y3QtPnBhcmVudFdpbmRvdyA9IChXaW5kb3dSZWYpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5wYXJlbnRXaW5kb3cpOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXROYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucyAqbHBTdHJ1Y3QpCit7CisJaWYgKCFOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5jYWNoZWQpIGNhY2hlTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMudmVyc2lvbiwgKGpzaG9ydClscFN0cnVjdC0+dmVyc2lvbik7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5vcHRpb25GbGFncywgKGppbnQpbHBTdHJ1Y3QtPm9wdGlvbkZsYWdzKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMubG9jYXRpb25faCwgKGpzaG9ydClscFN0cnVjdC0+bG9jYXRpb24uaCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLmxvY2F0aW9uX3YsIChqc2hvcnQpbHBTdHJ1Y3QtPmxvY2F0aW9uLnYpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuY2xpZW50TmFtZSwgKGppbnQpbHBTdHJ1Y3QtPmNsaWVudE5hbWUpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMud2luZG93VGl0bGUsIChqaW50KWxwU3RydWN0LT53aW5kb3dUaXRsZSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5hY3Rpb25CdXR0b25MYWJlbCwgKGppbnQpbHBTdHJ1Y3QtPmFjdGlvbkJ1dHRvbkxhYmVsKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLmNhbmNlbEJ1dHRvbkxhYmVsLCAoamludClscFN0cnVjdC0+Y2FuY2VsQnV0dG9uTGFiZWwpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMuc2F2ZUZpbGVOYW1lLCAoamludClscFN0cnVjdC0+c2F2ZUZpbGVOYW1lKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLm1lc3NhZ2UsIChqaW50KWxwU3RydWN0LT5tZXNzYWdlKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLnByZWZlcmVuY2VLZXksIChqaW50KWxwU3RydWN0LT5wcmVmZXJlbmNlS2V5KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZjLnBvcHVwRXh0ZW5zaW9uLCAoamludClscFN0cnVjdC0+cG9wdXBFeHRlbnNpb24pOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmMubW9kYWxpdHksIChqaW50KWxwU3RydWN0LT5tb2RhbGl0eSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGYy5wYXJlbnRXaW5kb3csIChqaW50KWxwU3RydWN0LT5wYXJlbnRXaW5kb3cpOworfQorI2VuZGlmIC8qIE5PX05hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucyAqLworCisjaWZuZGVmIE5PX05hdlJlcGx5UmVjb3JkCit0eXBlZGVmIHN0cnVjdCBOYXZSZXBseVJlY29yZF9GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIHZlcnNpb24sIHZhbGlkUmVjb3JkLCByZXBsYWNpbmcsIGlzU3RhdGlvbmVyeSwgdHJhbnNsYXRpb25OZWVkZWQsIHNlbGVjdGlvbl9kZXNjcmlwdG9yVHlwZSwgc2VsZWN0aW9uX2RhdGFIYW5kbGUsIGtleVNjcmlwdCwgZmlsZVRyYW5zbGF0aW9uLCByZXNlcnZlZDEsIHNhdmVGaWxlTmFtZSwgc2F2ZUZpbGVFeHRlbnNpb25IaWRkZW4sIHJlc2VydmVkMiwgcmVzZXJ2ZWQ7Cit9IE5hdlJlcGx5UmVjb3JkX0ZJRF9DQUNIRTsKKworTmF2UmVwbHlSZWNvcmRfRklEX0NBQ0hFIE5hdlJlcGx5UmVjb3JkRmM7CisKK3ZvaWQgY2FjaGVOYXZSZXBseVJlY29yZEZpZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QpCit7CisJaWYgKE5hdlJlcGx5UmVjb3JkRmMuY2FjaGVkKSByZXR1cm47CisJTmF2UmVwbHlSZWNvcmRGYy5jbGF6eiA9ICgqZW52KS0+R2V0T2JqZWN0Q2xhc3MoZW52LCBscE9iamVjdCk7CisJTmF2UmVwbHlSZWNvcmRGYy52ZXJzaW9uID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTmF2UmVwbHlSZWNvcmRGYy5jbGF6eiwgInZlcnNpb24iLCAiUyIpOworCU5hdlJlcGx5UmVjb3JkRmMudmFsaWRSZWNvcmQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBOYXZSZXBseVJlY29yZEZjLmNsYXp6LCAidmFsaWRSZWNvcmQiLCAiWiIpOworCU5hdlJlcGx5UmVjb3JkRmMucmVwbGFjaW5nID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTmF2UmVwbHlSZWNvcmRGYy5jbGF6eiwgInJlcGxhY2luZyIsICJaIik7CisJTmF2UmVwbHlSZWNvcmRGYy5pc1N0YXRpb25lcnkgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBOYXZSZXBseVJlY29yZEZjLmNsYXp6LCAiaXNTdGF0aW9uZXJ5IiwgIloiKTsKKwlOYXZSZXBseVJlY29yZEZjLnRyYW5zbGF0aW9uTmVlZGVkID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTmF2UmVwbHlSZWNvcmRGYy5jbGF6eiwgInRyYW5zbGF0aW9uTmVlZGVkIiwgIloiKTsKKwlOYXZSZXBseVJlY29yZEZjLnNlbGVjdGlvbl9kZXNjcmlwdG9yVHlwZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIE5hdlJlcGx5UmVjb3JkRmMuY2xhenosICJzZWxlY3Rpb25fZGVzY3JpcHRvclR5cGUiLCAiSSIpOworCU5hdlJlcGx5UmVjb3JkRmMuc2VsZWN0aW9uX2RhdGFIYW5kbGUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBOYXZSZXBseVJlY29yZEZjLmNsYXp6LCAic2VsZWN0aW9uX2RhdGFIYW5kbGUiLCAiSSIpOworCU5hdlJlcGx5UmVjb3JkRmMua2V5U2NyaXB0ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTmF2UmVwbHlSZWNvcmRGYy5jbGF6eiwgImtleVNjcmlwdCIsICJTIik7CisJTmF2UmVwbHlSZWNvcmRGYy5maWxlVHJhbnNsYXRpb24gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBOYXZSZXBseVJlY29yZEZjLmNsYXp6LCAiZmlsZVRyYW5zbGF0aW9uIiwgIkkiKTsKKwlOYXZSZXBseVJlY29yZEZjLnJlc2VydmVkMSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIE5hdlJlcGx5UmVjb3JkRmMuY2xhenosICJyZXNlcnZlZDEiLCAiSSIpOworCU5hdlJlcGx5UmVjb3JkRmMuc2F2ZUZpbGVOYW1lID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTmF2UmVwbHlSZWNvcmRGYy5jbGF6eiwgInNhdmVGaWxlTmFtZSIsICJJIik7CisJTmF2UmVwbHlSZWNvcmRGYy5zYXZlRmlsZUV4dGVuc2lvbkhpZGRlbiA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIE5hdlJlcGx5UmVjb3JkRmMuY2xhenosICJzYXZlRmlsZUV4dGVuc2lvbkhpZGRlbiIsICJaIik7CisJTmF2UmVwbHlSZWNvcmRGYy5yZXNlcnZlZDIgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBOYXZSZXBseVJlY29yZEZjLmNsYXp6LCAicmVzZXJ2ZWQyIiwgIkIiKTsKKwlOYXZSZXBseVJlY29yZEZjLnJlc2VydmVkID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgTmF2UmVwbHlSZWNvcmRGYy5jbGF6eiwgInJlc2VydmVkIiwgIltCIik7CisJTmF2UmVwbHlSZWNvcmRGYy5jYWNoZWQgPSAxOworfQorCitOYXZSZXBseVJlY29yZCAqZ2V0TmF2UmVwbHlSZWNvcmRGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkICpscFN0cnVjdCkKK3sKKwlpZiAoIU5hdlJlcGx5UmVjb3JkRmMuY2FjaGVkKSBjYWNoZU5hdlJlcGx5UmVjb3JkRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+dmVyc2lvbiA9IChVSW50MTYpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkRmMudmVyc2lvbik7CisJbHBTdHJ1Y3QtPnZhbGlkUmVjb3JkID0gKEJvb2xlYW4pKCplbnYpLT5HZXRCb29sZWFuRmllbGQoZW52LCBscE9iamVjdCwgTmF2UmVwbHlSZWNvcmRGYy52YWxpZFJlY29yZCk7CisJbHBTdHJ1Y3QtPnJlcGxhY2luZyA9IChCb29sZWFuKSgqZW52KS0+R2V0Qm9vbGVhbkZpZWxkKGVudiwgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkRmMucmVwbGFjaW5nKTsKKwlscFN0cnVjdC0+aXNTdGF0aW9uZXJ5ID0gKEJvb2xlYW4pKCplbnYpLT5HZXRCb29sZWFuRmllbGQoZW52LCBscE9iamVjdCwgTmF2UmVwbHlSZWNvcmRGYy5pc1N0YXRpb25lcnkpOworCWxwU3RydWN0LT50cmFuc2xhdGlvbk5lZWRlZCA9IChCb29sZWFuKSgqZW52KS0+R2V0Qm9vbGVhbkZpZWxkKGVudiwgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkRmMudHJhbnNsYXRpb25OZWVkZWQpOworCWxwU3RydWN0LT5zZWxlY3Rpb24uZGVzY3JpcHRvclR5cGUgPSAoRGVzY1R5cGUpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZSZXBseVJlY29yZEZjLnNlbGVjdGlvbl9kZXNjcmlwdG9yVHlwZSk7CisJbHBTdHJ1Y3QtPnNlbGVjdGlvbi5kYXRhSGFuZGxlID0gKEFFRGF0YVN0b3JhZ2UpKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZSZXBseVJlY29yZEZjLnNlbGVjdGlvbl9kYXRhSGFuZGxlKTsKKwlscFN0cnVjdC0+a2V5U2NyaXB0ID0gKFNjcmlwdENvZGUpKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkRmMua2V5U2NyaXB0KTsKKwlscFN0cnVjdC0+ZmlsZVRyYW5zbGF0aW9uID0gKEZpbGVUcmFuc2xhdGlvblNwZWNBcnJheUhhbmRsZSkoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkRmMuZmlsZVRyYW5zbGF0aW9uKTsKKwlscFN0cnVjdC0+cmVzZXJ2ZWQxID0gKFVJbnQzMikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkRmMucmVzZXJ2ZWQxKTsKKwlscFN0cnVjdC0+c2F2ZUZpbGVOYW1lID0gKENGU3RyaW5nUmVmKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgTmF2UmVwbHlSZWNvcmRGYy5zYXZlRmlsZU5hbWUpOworCWxwU3RydWN0LT5zYXZlRmlsZUV4dGVuc2lvbkhpZGRlbiA9IChCb29sZWFuKSgqZW52KS0+R2V0Qm9vbGVhbkZpZWxkKGVudiwgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkRmMuc2F2ZUZpbGVFeHRlbnNpb25IaWRkZW4pOworCWxwU3RydWN0LT5yZXNlcnZlZDIgPSAoVUludDgpKCplbnYpLT5HZXRCeXRlRmllbGQoZW52LCBscE9iamVjdCwgTmF2UmVwbHlSZWNvcmRGYy5yZXNlcnZlZDIpOworCXsKKwlqYnl0ZUFycmF5IGxwT2JqZWN0MSA9ICgqZW52KS0+R2V0T2JqZWN0RmllbGQoZW52LCBscE9iamVjdCwgTmF2UmVwbHlSZWNvcmRGYy5yZXNlcnZlZCk7CisJKCplbnYpLT5HZXRCeXRlQXJyYXlSZWdpb24oZW52LCBscE9iamVjdDEsIDAsIHNpemVvZihscFN0cnVjdC0+cmVzZXJ2ZWQpLCBscFN0cnVjdC0+cmVzZXJ2ZWQpOworCX0KKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0TmF2UmVwbHlSZWNvcmRGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkICpscFN0cnVjdCkKK3sKKwlpZiAoIU5hdlJlcGx5UmVjb3JkRmMuY2FjaGVkKSBjYWNoZU5hdlJlcGx5UmVjb3JkRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgTmF2UmVwbHlSZWNvcmRGYy52ZXJzaW9uLCAoanNob3J0KWxwU3RydWN0LT52ZXJzaW9uKTsKKwkoKmVudiktPlNldEJvb2xlYW5GaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZSZXBseVJlY29yZEZjLnZhbGlkUmVjb3JkLCAoamJvb2xlYW4pbHBTdHJ1Y3QtPnZhbGlkUmVjb3JkKTsKKwkoKmVudiktPlNldEJvb2xlYW5GaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZSZXBseVJlY29yZEZjLnJlcGxhY2luZywgKGpib29sZWFuKWxwU3RydWN0LT5yZXBsYWNpbmcpOworCSgqZW52KS0+U2V0Qm9vbGVhbkZpZWxkKGVudiwgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkRmMuaXNTdGF0aW9uZXJ5LCAoamJvb2xlYW4pbHBTdHJ1Y3QtPmlzU3RhdGlvbmVyeSk7CisJKCplbnYpLT5TZXRCb29sZWFuRmllbGQoZW52LCBscE9iamVjdCwgTmF2UmVwbHlSZWNvcmRGYy50cmFuc2xhdGlvbk5lZWRlZCwgKGpib29sZWFuKWxwU3RydWN0LT50cmFuc2xhdGlvbk5lZWRlZCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZSZXBseVJlY29yZEZjLnNlbGVjdGlvbl9kZXNjcmlwdG9yVHlwZSwgKGppbnQpbHBTdHJ1Y3QtPnNlbGVjdGlvbi5kZXNjcmlwdG9yVHlwZSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZSZXBseVJlY29yZEZjLnNlbGVjdGlvbl9kYXRhSGFuZGxlLCAoamludClscFN0cnVjdC0+c2VsZWN0aW9uLmRhdGFIYW5kbGUpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZSZXBseVJlY29yZEZjLmtleVNjcmlwdCwgKGpzaG9ydClscFN0cnVjdC0+a2V5U2NyaXB0KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkRmMuZmlsZVRyYW5zbGF0aW9uLCAoamludClscFN0cnVjdC0+ZmlsZVRyYW5zbGF0aW9uKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkRmMucmVzZXJ2ZWQxLCAoamludClscFN0cnVjdC0+cmVzZXJ2ZWQxKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkRmMuc2F2ZUZpbGVOYW1lLCAoamludClscFN0cnVjdC0+c2F2ZUZpbGVOYW1lKTsKKwkoKmVudiktPlNldEJvb2xlYW5GaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZSZXBseVJlY29yZEZjLnNhdmVGaWxlRXh0ZW5zaW9uSGlkZGVuLCAoamJvb2xlYW4pbHBTdHJ1Y3QtPnNhdmVGaWxlRXh0ZW5zaW9uSGlkZGVuKTsKKwkoKmVudiktPlNldEJ5dGVGaWVsZChlbnYsIGxwT2JqZWN0LCBOYXZSZXBseVJlY29yZEZjLnJlc2VydmVkMiwgKGpieXRlKWxwU3RydWN0LT5yZXNlcnZlZDIpOworCXsKKwlqYnl0ZUFycmF5IGxwT2JqZWN0MSA9ICgqZW52KS0+R2V0T2JqZWN0RmllbGQoZW52LCBscE9iamVjdCwgTmF2UmVwbHlSZWNvcmRGYy5yZXNlcnZlZCk7CisJKCplbnYpLT5TZXRCeXRlQXJyYXlSZWdpb24oZW52LCBscE9iamVjdDEsIDAsIHNpemVvZihscFN0cnVjdC0+cmVzZXJ2ZWQpLCBscFN0cnVjdC0+cmVzZXJ2ZWQpOworCX0KK30KKyNlbmRpZiAvKiBOT19OYXZSZXBseVJlY29yZCAqLworCisjaWZuZGVmIE5PX1BpeE1hcAordHlwZWRlZiBzdHJ1Y3QgUGl4TWFwX0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgcG1WZXJzaW9uLCBwYWNrVHlwZSwgcGFja1NpemUsIGhSZXMsIHZSZXMsIHBpeGVsVHlwZSwgcGl4ZWxTaXplLCBjbXBDb3VudCwgY21wU2l6ZSwgcGl4ZWxGb3JtYXQsIHBtVGFibGUsIHBtRXh0OworfSBQaXhNYXBfRklEX0NBQ0hFOworCitQaXhNYXBfRklEX0NBQ0hFIFBpeE1hcEZjOworCit2b2lkIGNhY2hlUGl4TWFwRmlkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCkKK3sKKwlpZiAoUGl4TWFwRmMuY2FjaGVkKSByZXR1cm47CisJY2FjaGVCaXRNYXBGaWRzKGVudiwgbHBPYmplY3QpOworCVBpeE1hcEZjLmNsYXp6ID0gKCplbnYpLT5HZXRPYmplY3RDbGFzcyhlbnYsIGxwT2JqZWN0KTsKKwlQaXhNYXBGYy5wbVZlcnNpb24gPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBQaXhNYXBGYy5jbGF6eiwgInBtVmVyc2lvbiIsICJTIik7CisJUGl4TWFwRmMucGFja1R5cGUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBQaXhNYXBGYy5jbGF6eiwgInBhY2tUeXBlIiwgIlMiKTsKKwlQaXhNYXBGYy5wYWNrU2l6ZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIFBpeE1hcEZjLmNsYXp6LCAicGFja1NpemUiLCAiSSIpOworCVBpeE1hcEZjLmhSZXMgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBQaXhNYXBGYy5jbGF6eiwgImhSZXMiLCAiSSIpOworCVBpeE1hcEZjLnZSZXMgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBQaXhNYXBGYy5jbGF6eiwgInZSZXMiLCAiSSIpOworCVBpeE1hcEZjLnBpeGVsVHlwZSA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIFBpeE1hcEZjLmNsYXp6LCAicGl4ZWxUeXBlIiwgIlMiKTsKKwlQaXhNYXBGYy5waXhlbFNpemUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBQaXhNYXBGYy5jbGF6eiwgInBpeGVsU2l6ZSIsICJTIik7CisJUGl4TWFwRmMuY21wQ291bnQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBQaXhNYXBGYy5jbGF6eiwgImNtcENvdW50IiwgIlMiKTsKKwlQaXhNYXBGYy5jbXBTaXplID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgUGl4TWFwRmMuY2xhenosICJjbXBTaXplIiwgIlMiKTsKKwlQaXhNYXBGYy5waXhlbEZvcm1hdCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIFBpeE1hcEZjLmNsYXp6LCAicGl4ZWxGb3JtYXQiLCAiSSIpOworCVBpeE1hcEZjLnBtVGFibGUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBQaXhNYXBGYy5jbGF6eiwgInBtVGFibGUiLCAiSSIpOworCVBpeE1hcEZjLnBtRXh0ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgUGl4TWFwRmMuY2xhenosICJwbUV4dCIsICJJIik7CisJUGl4TWFwRmMuY2FjaGVkID0gMTsKK30KKworUGl4TWFwICpnZXRQaXhNYXBGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIFBpeE1hcCAqbHBTdHJ1Y3QpCit7CisJaWYgKCFQaXhNYXBGYy5jYWNoZWQpIGNhY2hlUGl4TWFwRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlnZXRCaXRNYXBGaWVsZHMoZW52LCBscE9iamVjdCwgKEJpdE1hcCAqKWxwU3RydWN0KTsKKwlscFN0cnVjdC0+cG1WZXJzaW9uID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnBtVmVyc2lvbik7CisJbHBTdHJ1Y3QtPnBhY2tUeXBlID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnBhY2tUeXBlKTsKKwlscFN0cnVjdC0+cGFja1NpemUgPSAoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnBhY2tTaXplKTsKKwlscFN0cnVjdC0+aFJlcyA9ICgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgUGl4TWFwRmMuaFJlcyk7CisJbHBTdHJ1Y3QtPnZSZXMgPSAoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnZSZXMpOworCWxwU3RydWN0LT5waXhlbFR5cGUgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUGl4TWFwRmMucGl4ZWxUeXBlKTsKKwlscFN0cnVjdC0+cGl4ZWxTaXplID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnBpeGVsU2l6ZSk7CisJbHBTdHJ1Y3QtPmNtcENvdW50ID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLmNtcENvdW50KTsKKwlscFN0cnVjdC0+Y21wU2l6ZSA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBQaXhNYXBGYy5jbXBTaXplKTsKKwlscFN0cnVjdC0+cGl4ZWxGb3JtYXQgPSAoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnBpeGVsRm9ybWF0KTsKKwlscFN0cnVjdC0+cG1UYWJsZSA9IChDVGFiSGFuZGxlKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgUGl4TWFwRmMucG1UYWJsZSk7CisJbHBTdHJ1Y3QtPnBtRXh0ID0gKHZvaWQgKikoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnBtRXh0KTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0UGl4TWFwRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBQaXhNYXAgKmxwU3RydWN0KQoreworCWlmICghUGl4TWFwRmMuY2FjaGVkKSBjYWNoZVBpeE1hcEZpZHMoZW52LCBscE9iamVjdCk7CisJc2V0Qml0TWFwRmllbGRzKGVudiwgbHBPYmplY3QsIChCaXRNYXAgKilscFN0cnVjdCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnBtVmVyc2lvbiwgKGpzaG9ydClscFN0cnVjdC0+cG1WZXJzaW9uKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUGl4TWFwRmMucGFja1R5cGUsIChqc2hvcnQpbHBTdHJ1Y3QtPnBhY2tUeXBlKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnBhY2tTaXplLCAoamludClscFN0cnVjdC0+cGFja1NpemUpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgUGl4TWFwRmMuaFJlcywgKGppbnQpbHBTdHJ1Y3QtPmhSZXMpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgUGl4TWFwRmMudlJlcywgKGppbnQpbHBTdHJ1Y3QtPnZSZXMpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBQaXhNYXBGYy5waXhlbFR5cGUsIChqc2hvcnQpbHBTdHJ1Y3QtPnBpeGVsVHlwZSk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnBpeGVsU2l6ZSwgKGpzaG9ydClscFN0cnVjdC0+cGl4ZWxTaXplKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUGl4TWFwRmMuY21wQ291bnQsIChqc2hvcnQpbHBTdHJ1Y3QtPmNtcENvdW50KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUGl4TWFwRmMuY21wU2l6ZSwgKGpzaG9ydClscFN0cnVjdC0+Y21wU2l6ZSk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBQaXhNYXBGYy5waXhlbEZvcm1hdCwgKGppbnQpbHBTdHJ1Y3QtPnBpeGVsRm9ybWF0KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnBtVGFibGUsIChqaW50KWxwU3RydWN0LT5wbVRhYmxlKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIFBpeE1hcEZjLnBtRXh0LCAoamludClscFN0cnVjdC0+cG1FeHQpOworfQorI2VuZGlmIC8qIE5PX1BpeE1hcCAqLworCisjaWZuZGVmIE5PX1BvaW50Cit0eXBlZGVmIHN0cnVjdCBQb2ludF9GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIHYsIGg7Cit9IFBvaW50X0ZJRF9DQUNIRTsKKworUG9pbnRfRklEX0NBQ0hFIFBvaW50RmM7CisKK3ZvaWQgY2FjaGVQb2ludEZpZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QpCit7CisJaWYgKFBvaW50RmMuY2FjaGVkKSByZXR1cm47CisJUG9pbnRGYy5jbGF6eiA9ICgqZW52KS0+R2V0T2JqZWN0Q2xhc3MoZW52LCBscE9iamVjdCk7CisJUG9pbnRGYy52ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgUG9pbnRGYy5jbGF6eiwgInYiLCAiUyIpOworCVBvaW50RmMuaCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIFBvaW50RmMuY2xhenosICJoIiwgIlMiKTsKKwlQb2ludEZjLmNhY2hlZCA9IDE7Cit9CisKK1BvaW50ICpnZXRQb2ludEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgUG9pbnQgKmxwU3RydWN0KQoreworCWlmICghUG9pbnRGYy5jYWNoZWQpIGNhY2hlUG9pbnRGaWRzKGVudiwgbHBPYmplY3QpOworCWxwU3RydWN0LT52ID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFBvaW50RmMudik7CisJbHBTdHJ1Y3QtPmggPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUG9pbnRGYy5oKTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0UG9pbnRGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIFBvaW50ICpscFN0cnVjdCkKK3sKKwlpZiAoIVBvaW50RmMuY2FjaGVkKSBjYWNoZVBvaW50RmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUG9pbnRGYy52LCAoanNob3J0KWxwU3RydWN0LT52KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUG9pbnRGYy5oLCAoanNob3J0KWxwU3RydWN0LT5oKTsKK30KKyNlbmRpZiAvKiBOT19Qb2ludCAqLworCisjaWZuZGVmIE5PX1JHQkNvbG9yCit0eXBlZGVmIHN0cnVjdCBSR0JDb2xvcl9GSURfQ0FDSEUgeworCWludCBjYWNoZWQ7CisJamNsYXNzIGNsYXp6OworCWpmaWVsZElEIHJlZCwgZ3JlZW4sIGJsdWU7Cit9IFJHQkNvbG9yX0ZJRF9DQUNIRTsKKworUkdCQ29sb3JfRklEX0NBQ0hFIFJHQkNvbG9yRmM7CisKK3ZvaWQgY2FjaGVSR0JDb2xvckZpZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QpCit7CisJaWYgKFJHQkNvbG9yRmMuY2FjaGVkKSByZXR1cm47CisJUkdCQ29sb3JGYy5jbGF6eiA9ICgqZW52KS0+R2V0T2JqZWN0Q2xhc3MoZW52LCBscE9iamVjdCk7CisJUkdCQ29sb3JGYy5yZWQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBSR0JDb2xvckZjLmNsYXp6LCAicmVkIiwgIlMiKTsKKwlSR0JDb2xvckZjLmdyZWVuID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgUkdCQ29sb3JGYy5jbGF6eiwgImdyZWVuIiwgIlMiKTsKKwlSR0JDb2xvckZjLmJsdWUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBSR0JDb2xvckZjLmNsYXp6LCAiYmx1ZSIsICJTIik7CisJUkdCQ29sb3JGYy5jYWNoZWQgPSAxOworfQorCitSR0JDb2xvciAqZ2V0UkdCQ29sb3JGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIFJHQkNvbG9yICpscFN0cnVjdCkKK3sKKwlpZiAoIVJHQkNvbG9yRmMuY2FjaGVkKSBjYWNoZVJHQkNvbG9yRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+cmVkID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFJHQkNvbG9yRmMucmVkKTsKKwlscFN0cnVjdC0+Z3JlZW4gPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUkdCQ29sb3JGYy5ncmVlbik7CisJbHBTdHJ1Y3QtPmJsdWUgPSAoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUkdCQ29sb3JGYy5ibHVlKTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0UkdCQ29sb3JGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIFJHQkNvbG9yICpscFN0cnVjdCkKK3sKKwlpZiAoIVJHQkNvbG9yRmMuY2FjaGVkKSBjYWNoZVJHQkNvbG9yRmlkcyhlbnYsIGxwT2JqZWN0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUkdCQ29sb3JGYy5yZWQsIChqc2hvcnQpbHBTdHJ1Y3QtPnJlZCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFJHQkNvbG9yRmMuZ3JlZW4sIChqc2hvcnQpbHBTdHJ1Y3QtPmdyZWVuKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUkdCQ29sb3JGYy5ibHVlLCAoanNob3J0KWxwU3RydWN0LT5ibHVlKTsKK30KKyNlbmRpZiAvKiBOT19SR0JDb2xvciAqLworCisjaWZuZGVmIE5PX1JlY3QKK3R5cGVkZWYgc3RydWN0IFJlY3RfRklEX0NBQ0hFIHsKKwlpbnQgY2FjaGVkOworCWpjbGFzcyBjbGF6ejsKKwlqZmllbGRJRCB0b3AsIGxlZnQsIGJvdHRvbSwgcmlnaHQ7Cit9IFJlY3RfRklEX0NBQ0hFOworCitSZWN0X0ZJRF9DQUNIRSBSZWN0RmM7CisKK3ZvaWQgY2FjaGVSZWN0RmlkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCkKK3sKKwlpZiAoUmVjdEZjLmNhY2hlZCkgcmV0dXJuOworCVJlY3RGYy5jbGF6eiA9ICgqZW52KS0+R2V0T2JqZWN0Q2xhc3MoZW52LCBscE9iamVjdCk7CisJUmVjdEZjLnRvcCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIFJlY3RGYy5jbGF6eiwgInRvcCIsICJTIik7CisJUmVjdEZjLmxlZnQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBSZWN0RmMuY2xhenosICJsZWZ0IiwgIlMiKTsKKwlSZWN0RmMuYm90dG9tID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgUmVjdEZjLmNsYXp6LCAiYm90dG9tIiwgIlMiKTsKKwlSZWN0RmMucmlnaHQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBSZWN0RmMuY2xhenosICJyaWdodCIsICJTIik7CisJUmVjdEZjLmNhY2hlZCA9IDE7Cit9CisKK1JlY3QgKmdldFJlY3RGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIFJlY3QgKmxwU3RydWN0KQoreworCWlmICghUmVjdEZjLmNhY2hlZCkgY2FjaGVSZWN0RmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+dG9wID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFJlY3RGYy50b3ApOworCWxwU3RydWN0LT5sZWZ0ID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFJlY3RGYy5sZWZ0KTsKKwlscFN0cnVjdC0+Ym90dG9tID0gKCplbnYpLT5HZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFJlY3RGYy5ib3R0b20pOworCWxwU3RydWN0LT5yaWdodCA9ICgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBSZWN0RmMucmlnaHQpOworCXJldHVybiBscFN0cnVjdDsKK30KKwordm9pZCBzZXRSZWN0RmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBSZWN0ICpscFN0cnVjdCkKK3sKKwlpZiAoIVJlY3RGYy5jYWNoZWQpIGNhY2hlUmVjdEZpZHMoZW52LCBscE9iamVjdCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFJlY3RGYy50b3AsIChqc2hvcnQpbHBTdHJ1Y3QtPnRvcCk7CisJKCplbnYpLT5TZXRTaG9ydEZpZWxkKGVudiwgbHBPYmplY3QsIFJlY3RGYy5sZWZ0LCAoanNob3J0KWxwU3RydWN0LT5sZWZ0KTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUmVjdEZjLmJvdHRvbSwgKGpzaG9ydClscFN0cnVjdC0+Ym90dG9tKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgUmVjdEZjLnJpZ2h0LCAoanNob3J0KWxwU3RydWN0LT5yaWdodCk7Cit9CisjZW5kaWYgLyogTk9fUmVjdCAqLworCisjaWZuZGVmIE5PX1RoZW1lQnV0dG9uRHJhd0luZm8KK3R5cGVkZWYgc3RydWN0IFRoZW1lQnV0dG9uRHJhd0luZm9fRklEX0NBQ0hFIHsKKwlpbnQgY2FjaGVkOworCWpjbGFzcyBjbGF6ejsKKwlqZmllbGRJRCBzdGF0ZSwgdmFsdWUsIGFkb3JubWVudDsKK30gVGhlbWVCdXR0b25EcmF3SW5mb19GSURfQ0FDSEU7CisKK1RoZW1lQnV0dG9uRHJhd0luZm9fRklEX0NBQ0hFIFRoZW1lQnV0dG9uRHJhd0luZm9GYzsKKwordm9pZCBjYWNoZVRoZW1lQnV0dG9uRHJhd0luZm9GaWRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0KQoreworCWlmIChUaGVtZUJ1dHRvbkRyYXdJbmZvRmMuY2FjaGVkKSByZXR1cm47CisJVGhlbWVCdXR0b25EcmF3SW5mb0ZjLmNsYXp6ID0gKCplbnYpLT5HZXRPYmplY3RDbGFzcyhlbnYsIGxwT2JqZWN0KTsKKwlUaGVtZUJ1dHRvbkRyYXdJbmZvRmMuc3RhdGUgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBUaGVtZUJ1dHRvbkRyYXdJbmZvRmMuY2xhenosICJzdGF0ZSIsICJJIik7CisJVGhlbWVCdXR0b25EcmF3SW5mb0ZjLnZhbHVlID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgVGhlbWVCdXR0b25EcmF3SW5mb0ZjLmNsYXp6LCAidmFsdWUiLCAiUyIpOworCVRoZW1lQnV0dG9uRHJhd0luZm9GYy5hZG9ybm1lbnQgPSAoKmVudiktPkdldEZpZWxkSUQoZW52LCBUaGVtZUJ1dHRvbkRyYXdJbmZvRmMuY2xhenosICJhZG9ybm1lbnQiLCAiUyIpOworCVRoZW1lQnV0dG9uRHJhd0luZm9GYy5jYWNoZWQgPSAxOworfQorCitUaGVtZUJ1dHRvbkRyYXdJbmZvICpnZXRUaGVtZUJ1dHRvbkRyYXdJbmZvRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBUaGVtZUJ1dHRvbkRyYXdJbmZvICpscFN0cnVjdCkKK3sKKwlpZiAoIVRoZW1lQnV0dG9uRHJhd0luZm9GYy5jYWNoZWQpIGNhY2hlVGhlbWVCdXR0b25EcmF3SW5mb0ZpZHMoZW52LCBscE9iamVjdCk7CisJbHBTdHJ1Y3QtPnN0YXRlID0gKFRoZW1lRHJhd1N0YXRlKSgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgVGhlbWVCdXR0b25EcmF3SW5mb0ZjLnN0YXRlKTsKKwlscFN0cnVjdC0+dmFsdWUgPSAoVGhlbWVCdXR0b25WYWx1ZSkoKmVudiktPkdldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgVGhlbWVCdXR0b25EcmF3SW5mb0ZjLnZhbHVlKTsKKwlscFN0cnVjdC0+YWRvcm5tZW50ID0gKFRoZW1lQnV0dG9uQWRvcm5tZW50KSgqZW52KS0+R2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBUaGVtZUJ1dHRvbkRyYXdJbmZvRmMuYWRvcm5tZW50KTsKKwlyZXR1cm4gbHBTdHJ1Y3Q7Cit9CisKK3ZvaWQgc2V0VGhlbWVCdXR0b25EcmF3SW5mb0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgVGhlbWVCdXR0b25EcmF3SW5mbyAqbHBTdHJ1Y3QpCit7CisJaWYgKCFUaGVtZUJ1dHRvbkRyYXdJbmZvRmMuY2FjaGVkKSBjYWNoZVRoZW1lQnV0dG9uRHJhd0luZm9GaWRzKGVudiwgbHBPYmplY3QpOworCSgqZW52KS0+U2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgVGhlbWVCdXR0b25EcmF3SW5mb0ZjLnN0YXRlLCAoamludClscFN0cnVjdC0+c3RhdGUpOworCSgqZW52KS0+U2V0U2hvcnRGaWVsZChlbnYsIGxwT2JqZWN0LCBUaGVtZUJ1dHRvbkRyYXdJbmZvRmMudmFsdWUsIChqc2hvcnQpbHBTdHJ1Y3QtPnZhbHVlKTsKKwkoKmVudiktPlNldFNob3J0RmllbGQoZW52LCBscE9iamVjdCwgVGhlbWVCdXR0b25EcmF3SW5mb0ZjLmFkb3JubWVudCwgKGpzaG9ydClscFN0cnVjdC0+YWRvcm5tZW50KTsKK30KKyNlbmRpZiAvKiBOT19UaGVtZUJ1dHRvbkRyYXdJbmZvICovCisKKyNpZm5kZWYgTk9fVFhOTG9uZ1JlY3QKK3R5cGVkZWYgc3RydWN0IFRYTkxvbmdSZWN0X0ZJRF9DQUNIRSB7CisJaW50IGNhY2hlZDsKKwlqY2xhc3MgY2xheno7CisJamZpZWxkSUQgdG9wLCBsZWZ0LCBib3R0b20sIHJpZ2h0OworfSBUWE5Mb25nUmVjdF9GSURfQ0FDSEU7CisKK1RYTkxvbmdSZWN0X0ZJRF9DQUNIRSBUWE5Mb25nUmVjdEZjOworCit2b2lkIGNhY2hlVFhOTG9uZ1JlY3RGaWRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0KQoreworCWlmIChUWE5Mb25nUmVjdEZjLmNhY2hlZCkgcmV0dXJuOworCVRYTkxvbmdSZWN0RmMuY2xhenogPSAoKmVudiktPkdldE9iamVjdENsYXNzKGVudiwgbHBPYmplY3QpOworCVRYTkxvbmdSZWN0RmMudG9wID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgVFhOTG9uZ1JlY3RGYy5jbGF6eiwgInRvcCIsICJJIik7CisJVFhOTG9uZ1JlY3RGYy5sZWZ0ID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgVFhOTG9uZ1JlY3RGYy5jbGF6eiwgImxlZnQiLCAiSSIpOworCVRYTkxvbmdSZWN0RmMuYm90dG9tID0gKCplbnYpLT5HZXRGaWVsZElEKGVudiwgVFhOTG9uZ1JlY3RGYy5jbGF6eiwgImJvdHRvbSIsICJJIik7CisJVFhOTG9uZ1JlY3RGYy5yaWdodCA9ICgqZW52KS0+R2V0RmllbGRJRChlbnYsIFRYTkxvbmdSZWN0RmMuY2xhenosICJyaWdodCIsICJJIik7CisJVFhOTG9uZ1JlY3RGYy5jYWNoZWQgPSAxOworfQorCitUWE5Mb25nUmVjdCAqZ2V0VFhOTG9uZ1JlY3RGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIFRYTkxvbmdSZWN0ICpscFN0cnVjdCkKK3sKKwlpZiAoIVRYTkxvbmdSZWN0RmMuY2FjaGVkKSBjYWNoZVRYTkxvbmdSZWN0RmlkcyhlbnYsIGxwT2JqZWN0KTsKKwlscFN0cnVjdC0+dG9wID0gKCplbnYpLT5HZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBUWE5Mb25nUmVjdEZjLnRvcCk7CisJbHBTdHJ1Y3QtPmxlZnQgPSAoKmVudiktPkdldEludEZpZWxkKGVudiwgbHBPYmplY3QsIFRYTkxvbmdSZWN0RmMubGVmdCk7CisJbHBTdHJ1Y3QtPmJvdHRvbSA9ICgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgVFhOTG9uZ1JlY3RGYy5ib3R0b20pOworCWxwU3RydWN0LT5yaWdodCA9ICgqZW52KS0+R2V0SW50RmllbGQoZW52LCBscE9iamVjdCwgVFhOTG9uZ1JlY3RGYy5yaWdodCk7CisJcmV0dXJuIGxwU3RydWN0OworfQorCit2b2lkIHNldFRYTkxvbmdSZWN0RmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBUWE5Mb25nUmVjdCAqbHBTdHJ1Y3QpCit7CisJaWYgKCFUWE5Mb25nUmVjdEZjLmNhY2hlZCkgY2FjaGVUWE5Mb25nUmVjdEZpZHMoZW52LCBscE9iamVjdCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBUWE5Mb25nUmVjdEZjLnRvcCwgKGppbnQpbHBTdHJ1Y3QtPnRvcCk7CisJKCplbnYpLT5TZXRJbnRGaWVsZChlbnYsIGxwT2JqZWN0LCBUWE5Mb25nUmVjdEZjLmxlZnQsIChqaW50KWxwU3RydWN0LT5sZWZ0KTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIFRYTkxvbmdSZWN0RmMuYm90dG9tLCAoamludClscFN0cnVjdC0+Ym90dG9tKTsKKwkoKmVudiktPlNldEludEZpZWxkKGVudiwgbHBPYmplY3QsIFRYTkxvbmdSZWN0RmMucmlnaHQsIChqaW50KWxwU3RydWN0LT5yaWdodCk7Cit9CisjZW5kaWYgLyogTk9fVFhOTG9uZ1JlY3QgKi8KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9saWJyYXJ5L3N0cnVjdHMuaCBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9saWJyYXJ5L3N0cnVjdHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hM2E1OGI3Ci0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL2xpYnJhcnkvc3RydWN0cy5oCkBAIC0wLDAgKzEsMjY4IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworCisvKioKKyAqIEpOSSBTV1Qgb2JqZWN0IGZpZWxkIGdldHRlcnMgYW5kIHNldHRlcnMgZGVjbGFyYXRpb25zIGZvciBNYWMvQ2FyYm9uIHN0cnVjdHMuCisgKi8KKworI2luY2x1ZGUgPENhcmJvbi9DYXJib24uaD4KKworI2lmbmRlZiBOT19BRURlc2MKK0FFRGVzYyAqZ2V0QUVEZXNjRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBBRURlc2MgKmxwU3RydWN0KTsKK3ZvaWQgc2V0QUVEZXNjRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBBRURlc2MgKmxwU3RydWN0KTsKKyNlbHNlCisjZGVmaW5lIGdldEFFRGVzY0ZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRBRURlc2NGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fQUVEZXNjICovCisKKyNpZm5kZWYgTk9fQVRTVHJhcGV6b2lkCitBVFNUcmFwZXpvaWQgKmdldEFUU1RyYXBlem9pZEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQVRTVHJhcGV6b2lkICpscFN0cnVjdCk7Cit2b2lkIHNldEFUU1RyYXBlem9pZEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQVRTVHJhcGV6b2lkICpscFN0cnVjdCk7CisjZWxzZQorI2RlZmluZSBnZXRBVFNUcmFwZXpvaWRGaWVsZHMoYSxiLGMpIE5VTEwKKyNkZWZpbmUgc2V0QVRTVHJhcGV6b2lkRmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX0FUU1RyYXBlem9pZCAqLworCisjaWZuZGVmIE5PX0FsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjCitBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlYyAqZ2V0QWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjICpscFN0cnVjdCk7Cit2b2lkIHNldEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlYyAqbHBTdHJ1Y3QpOworI2Vsc2UKKyNkZWZpbmUgZ2V0QWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGaWVsZHMoYSxiLGMpIE5VTEwKKyNkZWZpbmUgc2V0QWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWMgKi8KKworI2lmbmRlZiBOT19CaXRNYXAKK0JpdE1hcCAqZ2V0Qml0TWFwRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBCaXRNYXAgKmxwU3RydWN0KTsKK3ZvaWQgc2V0Qml0TWFwRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBCaXRNYXAgKmxwU3RydWN0KTsKKyNlbHNlCisjZGVmaW5lIGdldEJpdE1hcEZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRCaXRNYXBGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fQml0TWFwICovCisKKyNpZm5kZWYgTk9fQ0ZSYW5nZQorQ0ZSYW5nZSAqZ2V0Q0ZSYW5nZUZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ0ZSYW5nZSAqbHBTdHJ1Y3QpOwordm9pZCBzZXRDRlJhbmdlRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBDRlJhbmdlICpscFN0cnVjdCk7CisjZWxzZQorI2RlZmluZSBnZXRDRlJhbmdlRmllbGRzKGEsYixjKSBOVUxMCisjZGVmaW5lIHNldENGUmFuZ2VGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fQ0ZSYW5nZSAqLworCisjaWZuZGVmIE5PX0NHUG9pbnQKK0NHUG9pbnQgKmdldENHUG9pbnRGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENHUG9pbnQgKmxwU3RydWN0KTsKK3ZvaWQgc2V0Q0dQb2ludEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ0dQb2ludCAqbHBTdHJ1Y3QpOworI2Vsc2UKKyNkZWZpbmUgZ2V0Q0dQb2ludEZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRDR1BvaW50RmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX0NHUG9pbnQgKi8KKworI2lmbmRlZiBOT19DR1JlY3QKK0NHUmVjdCAqZ2V0Q0dSZWN0RmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBDR1JlY3QgKmxwU3RydWN0KTsKK3ZvaWQgc2V0Q0dSZWN0RmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBDR1JlY3QgKmxwU3RydWN0KTsKKyNlbHNlCisjZGVmaW5lIGdldENHUmVjdEZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRDR1JlY3RGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fQ0dSZWN0ICovCisKKyNpZm5kZWYgTk9fQ29sb3JQaWNrZXJJbmZvCitDb2xvclBpY2tlckluZm8gKmdldENvbG9yUGlja2VySW5mb0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvICpscFN0cnVjdCk7Cit2b2lkIHNldENvbG9yUGlja2VySW5mb0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ29sb3JQaWNrZXJJbmZvICpscFN0cnVjdCk7CisjZWxzZQorI2RlZmluZSBnZXRDb2xvclBpY2tlckluZm9GaWVsZHMoYSxiLGMpIE5VTEwKKyNkZWZpbmUgc2V0Q29sb3JQaWNrZXJJbmZvRmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX0NvbG9yUGlja2VySW5mbyAqLworCisjaWZuZGVmIE5PX0NvbnRyb2xCdXR0b25Db250ZW50SW5mbworQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvICpnZXRDb250cm9sQnV0dG9uQ29udGVudEluZm9GaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENvbnRyb2xCdXR0b25Db250ZW50SW5mbyAqbHBTdHJ1Y3QpOwordm9pZCBzZXRDb250cm9sQnV0dG9uQ29udGVudEluZm9GaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENvbnRyb2xCdXR0b25Db250ZW50SW5mbyAqbHBTdHJ1Y3QpOworI2Vsc2UKKyNkZWZpbmUgZ2V0Q29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmllbGRzKGEsYixjKSBOVUxMCisjZGVmaW5lIHNldENvbnRyb2xCdXR0b25Db250ZW50SW5mb0ZpZWxkcyhhLGIsYykKKyNlbmRpZiAvKiBOT19Db250cm9sQnV0dG9uQ29udGVudEluZm8gKi8KKworI2lmbmRlZiBOT19Db250cm9sRm9udFN0eWxlUmVjCitDb250cm9sRm9udFN0eWxlUmVjICpnZXRDb250cm9sRm9udFN0eWxlUmVjRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBDb250cm9sRm9udFN0eWxlUmVjICpscFN0cnVjdCk7Cit2b2lkIHNldENvbnRyb2xGb250U3R5bGVSZWNGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENvbnRyb2xGb250U3R5bGVSZWMgKmxwU3RydWN0KTsKKyNlbHNlCisjZGVmaW5lIGdldENvbnRyb2xGb250U3R5bGVSZWNGaWVsZHMoYSxiLGMpIE5VTEwKKyNkZWZpbmUgc2V0Q29udHJvbEZvbnRTdHlsZVJlY0ZpZWxkcyhhLGIsYykKKyNlbmRpZiAvKiBOT19Db250cm9sRm9udFN0eWxlUmVjICovCisKKyNpZm5kZWYgTk9fQ29udHJvbFRhYkVudHJ5CitDb250cm9sVGFiRW50cnkgKmdldENvbnRyb2xUYWJFbnRyeUZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ29udHJvbFRhYkVudHJ5ICpscFN0cnVjdCk7Cit2b2lkIHNldENvbnRyb2xUYWJFbnRyeUZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ29udHJvbFRhYkVudHJ5ICpscFN0cnVjdCk7CisjZWxzZQorI2RlZmluZSBnZXRDb250cm9sVGFiRW50cnlGaWVsZHMoYSxiLGMpIE5VTEwKKyNkZWZpbmUgc2V0Q29udHJvbFRhYkVudHJ5RmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX0NvbnRyb2xUYWJFbnRyeSAqLworCisjaWZuZGVmIE5PX0NvbnRyb2xUYWJJbmZvUmVjVjEKK0NvbnRyb2xUYWJJbmZvUmVjVjEgKmdldENvbnRyb2xUYWJJbmZvUmVjVjFGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIENvbnRyb2xUYWJJbmZvUmVjVjEgKmxwU3RydWN0KTsKK3ZvaWQgc2V0Q29udHJvbFRhYkluZm9SZWNWMUZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgQ29udHJvbFRhYkluZm9SZWNWMSAqbHBTdHJ1Y3QpOworI2Vsc2UKKyNkZWZpbmUgZ2V0Q29udHJvbFRhYkluZm9SZWNWMUZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRDb250cm9sVGFiSW5mb1JlY1YxRmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX0NvbnRyb2xUYWJJbmZvUmVjVjEgKi8KKworI2lmbmRlZiBOT19DdXJzb3IKK0N1cnNvciAqZ2V0Q3Vyc29yRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBDdXJzb3IgKmxwU3RydWN0KTsKK3ZvaWQgc2V0Q3Vyc29yRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBDdXJzb3IgKmxwU3RydWN0KTsKKyNlbHNlCisjZGVmaW5lIGdldEN1cnNvckZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRDdXJzb3JGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fQ3Vyc29yICovCisKKyNpZm5kZWYgTk9fRGF0YUJyb3dzZXJDYWxsYmFja3MKK0RhdGFCcm93c2VyQ2FsbGJhY2tzICpnZXREYXRhQnJvd3NlckNhbGxiYWNrc0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRGF0YUJyb3dzZXJDYWxsYmFja3MgKmxwU3RydWN0KTsKK3ZvaWQgc2V0RGF0YUJyb3dzZXJDYWxsYmFja3NGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIERhdGFCcm93c2VyQ2FsbGJhY2tzICpscFN0cnVjdCk7CisjZWxzZQorI2RlZmluZSBnZXREYXRhQnJvd3NlckNhbGxiYWNrc0ZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXREYXRhQnJvd3NlckNhbGxiYWNrc0ZpZWxkcyhhLGIsYykKKyNlbmRpZiAvKiBOT19EYXRhQnJvd3NlckNhbGxiYWNrcyAqLworCisjaWZuZGVmIE5PX0RhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzCitEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrcyAqZ2V0RGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzICpscFN0cnVjdCk7Cit2b2lkIHNldERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrcyAqbHBTdHJ1Y3QpOworI2Vsc2UKKyNkZWZpbmUgZ2V0RGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGaWVsZHMoYSxiLGMpIE5VTEwKKyNkZWZpbmUgc2V0RGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3MgKi8KKworI2lmbmRlZiBOT19EYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYworRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2MgKmdldERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYyAqbHBTdHJ1Y3QpOwordm9pZCBzZXREYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2MgKmxwU3RydWN0KTsKKyNlbHNlCisjZGVmaW5lIGdldERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmllbGRzKGEsYixjKSBOVUxMCisjZGVmaW5lIHNldERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX0RhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjICovCisKKyNpZm5kZWYgTk9fRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MKK0RhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjICpnZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MgKmxwU3RydWN0KTsKK3ZvaWQgc2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjICpscFN0cnVjdCk7CisjZWxzZQorI2RlZmluZSBnZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzY0ZpZWxkcyhhLGIsYykKKyNlbmRpZiAvKiBOT19EYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzYyAqLworCisjaWZuZGVmIE5PX0V2ZW50UmVjb3JkCitFdmVudFJlY29yZCAqZ2V0RXZlbnRSZWNvcmRGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIEV2ZW50UmVjb3JkICpscFN0cnVjdCk7Cit2b2lkIHNldEV2ZW50UmVjb3JkRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBFdmVudFJlY29yZCAqbHBTdHJ1Y3QpOworI2Vsc2UKKyNkZWZpbmUgZ2V0RXZlbnRSZWNvcmRGaWVsZHMoYSxiLGMpIE5VTEwKKyNkZWZpbmUgc2V0RXZlbnRSZWNvcmRGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fRXZlbnRSZWNvcmQgKi8KKworI2lmbmRlZiBOT19Gb250SW5mbworRm9udEluZm8gKmdldEZvbnRJbmZvRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBGb250SW5mbyAqbHBTdHJ1Y3QpOwordm9pZCBzZXRGb250SW5mb0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRm9udEluZm8gKmxwU3RydWN0KTsKKyNlbHNlCisjZGVmaW5lIGdldEZvbnRJbmZvRmllbGRzKGEsYixjKSBOVUxMCisjZGVmaW5lIHNldEZvbnRJbmZvRmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX0ZvbnRJbmZvICovCisKKyNpZm5kZWYgTk9fRm9udFNlbGVjdGlvblFEU3R5bGUKK0ZvbnRTZWxlY3Rpb25RRFN0eWxlICpnZXRGb250U2VsZWN0aW9uUURTdHlsZUZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgRm9udFNlbGVjdGlvblFEU3R5bGUgKmxwU3RydWN0KTsKK3ZvaWQgc2V0Rm9udFNlbGVjdGlvblFEU3R5bGVGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIEZvbnRTZWxlY3Rpb25RRFN0eWxlICpscFN0cnVjdCk7CisjZWxzZQorI2RlZmluZSBnZXRGb250U2VsZWN0aW9uUURTdHlsZUZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRGb250U2VsZWN0aW9uUURTdHlsZUZpZWxkcyhhLGIsYykKKyNlbmRpZiAvKiBOT19Gb250U2VsZWN0aW9uUURTdHlsZSAqLworCisjaWZuZGVmIE5PX0dEZXZpY2UKK0dEZXZpY2UgKmdldEdEZXZpY2VGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIEdEZXZpY2UgKmxwU3RydWN0KTsKK3ZvaWQgc2V0R0RldmljZUZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgR0RldmljZSAqbHBTdHJ1Y3QpOworI2Vsc2UKKyNkZWZpbmUgZ2V0R0RldmljZUZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRHRGV2aWNlRmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX0dEZXZpY2UgKi8KKworI2lmbmRlZiBOT19ISUNvbW1hbmQKK0hJQ29tbWFuZCAqZ2V0SElDb21tYW5kRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBISUNvbW1hbmQgKmxwU3RydWN0KTsKK3ZvaWQgc2V0SElDb21tYW5kRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBISUNvbW1hbmQgKmxwU3RydWN0KTsKKyNlbHNlCisjZGVmaW5lIGdldEhJQ29tbWFuZEZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRISUNvbW1hbmRGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fSElDb21tYW5kICovCisKKyNpZm5kZWYgTk9fSE1IZWxwQ29udGVudFJlYworSE1IZWxwQ29udGVudFJlYyAqZ2V0SE1IZWxwQ29udGVudFJlY0ZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgSE1IZWxwQ29udGVudFJlYyAqbHBTdHJ1Y3QpOwordm9pZCBzZXRITUhlbHBDb250ZW50UmVjRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBITUhlbHBDb250ZW50UmVjICpscFN0cnVjdCk7CisjZWxzZQorI2RlZmluZSBnZXRITUhlbHBDb250ZW50UmVjRmllbGRzKGEsYixjKSBOVUxMCisjZGVmaW5lIHNldEhNSGVscENvbnRlbnRSZWNGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fSE1IZWxwQ29udGVudFJlYyAqLworCisjaWZuZGVmIE5PX01lbnVUcmFja2luZ0RhdGEKK01lbnVUcmFja2luZ0RhdGEgKmdldE1lbnVUcmFja2luZ0RhdGFGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIE1lbnVUcmFja2luZ0RhdGEgKmxwU3RydWN0KTsKK3ZvaWQgc2V0TWVudVRyYWNraW5nRGF0YUZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgTWVudVRyYWNraW5nRGF0YSAqbHBTdHJ1Y3QpOworI2Vsc2UKKyNkZWZpbmUgZ2V0TWVudVRyYWNraW5nRGF0YUZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRNZW51VHJhY2tpbmdEYXRhRmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX01lbnVUcmFja2luZ0RhdGEgKi8KKworI2lmbmRlZiBOT19OYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnMKK05hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucyAqZ2V0TmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnMgKmxwU3RydWN0KTsKK3ZvaWQgc2V0TmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnMgKmxwU3RydWN0KTsKKyNlbHNlCisjZGVmaW5lIGdldE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXROYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zICovCisKKyNpZm5kZWYgTk9fUGl4TWFwCitQaXhNYXAgKmdldFBpeE1hcEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgUGl4TWFwICpscFN0cnVjdCk7Cit2b2lkIHNldFBpeE1hcEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgUGl4TWFwICpscFN0cnVjdCk7CisjZWxzZQorI2RlZmluZSBnZXRQaXhNYXBGaWVsZHMoYSxiLGMpIE5VTEwKKyNkZWZpbmUgc2V0UGl4TWFwRmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX1BpeE1hcCAqLworCisjaWZuZGVmIE5PX05hdlJlcGx5UmVjb3JkCitOYXZSZXBseVJlY29yZCAqZ2V0TmF2UmVwbHlSZWNvcmRGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIE5hdlJlcGx5UmVjb3JkICpscFN0cnVjdCk7Cit2b2lkIHNldE5hdlJlcGx5UmVjb3JkRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBOYXZSZXBseVJlY29yZCAqbHBTdHJ1Y3QpOworI2Vsc2UKKyNkZWZpbmUgZ2V0TmF2UmVwbHlSZWNvcmRGaWVsZHMoYSxiLGMpIE5VTEwKKyNkZWZpbmUgc2V0TmF2UmVwbHlSZWNvcmRGaWVsZHMoYSxiLGMpCisjZW5kaWYgLyogTk9fTmF2UmVwbHlSZWNvcmQgKi8KKworI2lmbmRlZiBOT19Qb2ludAorUG9pbnQgKmdldFBvaW50RmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBQb2ludCAqbHBTdHJ1Y3QpOwordm9pZCBzZXRQb2ludEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgUG9pbnQgKmxwU3RydWN0KTsKKyNlbHNlCisjZGVmaW5lIGdldFBvaW50RmllbGRzKGEsYixjKSBOVUxMCisjZGVmaW5lIHNldFBvaW50RmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX1BvaW50ICovCisKKyNpZm5kZWYgTk9fUkdCQ29sb3IKK1JHQkNvbG9yICpnZXRSR0JDb2xvckZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgUkdCQ29sb3IgKmxwU3RydWN0KTsKK3ZvaWQgc2V0UkdCQ29sb3JGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIFJHQkNvbG9yICpscFN0cnVjdCk7CisjZWxzZQorI2RlZmluZSBnZXRSR0JDb2xvckZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRSR0JDb2xvckZpZWxkcyhhLGIsYykKKyNlbmRpZiAvKiBOT19SR0JDb2xvciAqLworCisjaWZuZGVmIE5PX1JlY3QKK1JlY3QgKmdldFJlY3RGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIFJlY3QgKmxwU3RydWN0KTsKK3ZvaWQgc2V0UmVjdEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgUmVjdCAqbHBTdHJ1Y3QpOworI2Vsc2UKKyNkZWZpbmUgZ2V0UmVjdEZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRSZWN0RmllbGRzKGEsYixjKQorI2VuZGlmIC8qIE5PX1JlY3QgKi8KKworI2lmbmRlZiBOT19UaGVtZUJ1dHRvbkRyYXdJbmZvCitUaGVtZUJ1dHRvbkRyYXdJbmZvICpnZXRUaGVtZUJ1dHRvbkRyYXdJbmZvRmllbGRzKEpOSUVudiAqZW52LCBqb2JqZWN0IGxwT2JqZWN0LCBUaGVtZUJ1dHRvbkRyYXdJbmZvICpscFN0cnVjdCk7Cit2b2lkIHNldFRoZW1lQnV0dG9uRHJhd0luZm9GaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIFRoZW1lQnV0dG9uRHJhd0luZm8gKmxwU3RydWN0KTsKKyNlbHNlCisjZGVmaW5lIGdldFRoZW1lQnV0dG9uRHJhd0luZm9GaWVsZHMoYSxiLGMpIE5VTEwKKyNkZWZpbmUgc2V0VGhlbWVCdXR0b25EcmF3SW5mb0ZpZWxkcyhhLGIsYykKKyNlbmRpZiAvKiBOT19UaGVtZUJ1dHRvbkRyYXdJbmZvICovCisKKyNpZm5kZWYgTk9fVFhOTG9uZ1JlY3QKK1RYTkxvbmdSZWN0ICpnZXRUWE5Mb25nUmVjdEZpZWxkcyhKTklFbnYgKmVudiwgam9iamVjdCBscE9iamVjdCwgVFhOTG9uZ1JlY3QgKmxwU3RydWN0KTsKK3ZvaWQgc2V0VFhOTG9uZ1JlY3RGaWVsZHMoSk5JRW52ICplbnYsIGpvYmplY3QgbHBPYmplY3QsIFRYTkxvbmdSZWN0ICpscFN0cnVjdCk7CisjZWxzZQorI2RlZmluZSBnZXRUWE5Mb25nUmVjdEZpZWxkcyhhLGIsYykgTlVMTAorI2RlZmluZSBzZXRUWE5Mb25nUmVjdEZpZWxkcyhhLGIsYykKKyNlbmRpZiAvKiBOT19UWE5Mb25nUmVjdCAqLwpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL2xpYnJhcnkvc3d0LmMgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vbGlicmFyeS9zd3QuYwppbmRleCA3NzAxNmYwLi42NTYyODU4IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vbGlicmFyeS9zd3QuYworKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vbGlicmFyeS9zd3QuYwpAQCAtMywzNjQ0ICszLDc0NzAgQEAKICAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKLSAqCi0gKiBBbmRyZSBXZWluYW5kLCBPVEkgLSBJbml0aWFsIHZlcnNpb24KICAqLwogCi0jaWZuZGVmIF9JbmNsdWRlZF9KTklPdXQKLSNpbmNsdWRlICJvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TLmgiCi0jZW5kaWYKKy8qKgorICogU1dUIE9TIG5hdGl2ZXMgaW1wbGVtZW50YXRpb24uCisgKi8gCiAKLSNpbmNsdWRlIDxDYXJib24vQ2FyYm9uLmg+Ci0JCi0vLyNkZWZpbmUgVVNFX0FUU1VJIDEKKyNpbmNsdWRlICJzd3QuaCIKKyNpbmNsdWRlICJzdHJ1Y3RzLmgiCiAKLXN0YXRpYyBjb25zdCBSZWN0IE5VTExfUkVDVDsKKyNkZWZpbmUgT1NfTkFUSVZFKGZ1bmMpIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU18jI2Z1bmMKIAotLy8gZm9yd2FyZCBkZWNsYXJhdGlvbnMKLXN0YXRpYyBQb2ludCBwb2ludChKTklFbnYgKmVudiwganNob3J0QXJyYXkgYSk7Ci1zdGF0aWMgdm9pZCBjb3B5RXZlbnQoSk5JRW52ICplbnYsIGppbnRBcnJheSBlRGF0YSwgRXZlbnRSZWNvcmQgKmV2ZW50KTsKLXN0YXRpYyB2b2lkIGNvcHlFdmVudERhdGEoSk5JRW52ICplbnYsIEV2ZW50UmVjb3JkICpldmVudCwgamludEFycmF5IGVEYXRhKTsKKyNpZm5kZWYgTk9fQWN0aXZlTm9uRmxvYXRpbmdXaW5kb3cKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0FjdGl2ZU5vbkZsb2F0aW5nV2luZG93CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCkKK3sKKwlERUJVR19DQUxMKCJBY3RpdmVOb25GbG9hdGluZ1dpbmRvd1xuIikKIAotI2lmZGVmIERFQlVHCi0jZGVmaW5lIFJDKGYpIGNoZWNrU3RhdHVzKF9fTElORV9fLCAoZikpCi0KLXN0YXRpYyBpbnQgY2hlY2tTdGF0dXMoaW50IGxpbmUsIGludCByYykgewotICAgIHN3aXRjaCAocmMpIHsKLQljYXNlIDA6Ci0JY2FzZSBldmVudE5vdEhhbmRsZWRFcnI6Ci0JY2FzZSBldmVudExvb3BUaW1lZE91dEVycjoKLQljYXNlIGVyckNvbnRyb2xJc05vdEVtYmVkZGVyOgotCQlicmVhazsKLQlkZWZhdWx0OgotICAgICAgICAvL2ZwcmludGYoc3RkZXJyLCAiT1M6IGxpbmU6ICVkICVkXG4iLCBsaW5lLCByYyk7Ci0JCWJyZWFrOwotCX0KLSAgICByZXR1cm4gcmM7Ci19Ci0jZWxzZQotI2RlZmluZSBSQyhmKSBmCi0jZW5kaWYKLQotLy8tLS0tIGZvbnRzCi0KLUpOSUVYUE9SVCBqc2hvcnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRk1HZXRGb250RmFtaWx5RnJvbU5hbWUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWpieXRlQXJyYXkgbmFtZSkgewotCWpieXRlICpzYT0gKCplbnYpLT5HZXRCeXRlQXJyYXlFbGVtZW50cyhlbnYsIG5hbWUsIDApOwotCWpzaG9ydCBpZD0gKGpzaG9ydCkgRk1HZXRGb250RmFtaWx5RnJvbU5hbWUoKENvbnN0U3RyMjU1UGFyYW0pIHNhKTsKLQkoKmVudiktPlJlbGVhc2VCeXRlQXJyYXlFbGVtZW50cyhlbnYsIG5hbWUsIHNhLCAwKTsKLQlyZXR1cm4gaWQ7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0ZNR2V0Rm9udEZhbWlseU5hbWUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWpzaG9ydCBpZCwgamJ5dGVBcnJheSBuYW1lKSB7Ci0JU3RyMjU1IHM7Ci0JamludCBzdGF0dXM9IChqc2hvcnQpIFJDKEZNR2V0Rm9udEZhbWlseU5hbWUoKEZNRm9udEZhbWlseSkgaWQsIHMpKTsKLQlqYnl0ZSAqc2E9ICgqZW52KS0+R2V0Qnl0ZUFycmF5RWxlbWVudHMoZW52LCBuYW1lLCAwKTsKLQltZW1jcHkoc2EsIHMsIDI1NSk7Ci0JKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBuYW1lLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotLyoKLXZvaWQgbGlzQWxsRm9udHMoKSB7Ci0JRk1Gb250RmFtaWx5SXRlcmF0b3IgaXRlcjsKLQlGTUZvbnRGYW1pbHkgZmFtaWx5OwotCUZNQ3JlYXRlRm9udEZhbWlseUl0ZXJhdG9yKE5VTEwsIE5VTEwsIGtGTVVzZUdsb2JhbFNjb3BlT3B0aW9uLCAmaXRlcik7Ci0KLQl3aGlsZSAoRk1HZXROZXh0Rm9udEZhbWlseSgmaXRlciwgJmZhbWlseSkgIT0ga0ZNSXRlcmF0aW9uQ29tcGxldGVkKSB7Ci0JCVN0cjI1NSBuYW1lOwotCQlGTUdldEZvbnRGYW1pbHlOYW1lKGZhbWlseSwgbmFtZSk7Ci0JCW5hbWVbbmFtZVswXSsxXT0gMDsKLQkJZnByaW50ZihzdGRlcnIsICJmb250ZmFtaWx5OiAlc1xuIiwgJm5hbWVbMV0pOwotCX0KLQlGTURpc3Bvc2VGb250RmFtaWx5SXRlcmF0b3IoJml0ZXIpOwotfQotKi8KLQotLy8tLS0tIEFwcGVhcmFuY2UgTWFuYWdlcgotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SZWdpc3RlckFwcGVhcmFuY2VDbGllbnQoSk5JRW52ICplbnYsIGpjbGFzcyB6eikgewotCXJldHVybiAoamludCkgUkMoUmVnaXN0ZXJBcHBlYXJhbmNlQ2xpZW50KCkpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRUaGVtZVdpbmRvd0JhY2tncm91bmQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IHdIYW5kbGUsIGpzaG9ydCBicnVzaCwgamJvb2xlYW4gdXBkYXRlKSB7Ci0JcmV0dXJuIChqaW50KSBSQyhTZXRUaGVtZVdpbmRvd0JhY2tncm91bmQoKFdpbmRvd1JlZikgd0hhbmRsZSwgKFRoZW1lQnJ1c2gpIGJydXNoLCAoQm9vbGVhbikgdXBkYXRlKSk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0RyYXdUaGVtZVRleHRCb3goSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IHNIYW5kbGUsIGpzaG9ydCBmb250SUQsIGppbnQgc3RhdGUsIGpib29sZWFuIHdyYXBUb1dpZHRoLCBqc2hvcnRBcnJheSBib3VuZHMsIGpzaG9ydCBqdXN0LCBqaW50IGNvbnRleHQpIHsKLQotICAgIGpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCAwKTsKLQlqaW50IHN0YXR1cz0gUkMoRHJhd1RoZW1lVGV4dEJveCgoQ0ZTdHJpbmdSZWYpc0hhbmRsZSwgKFRoZW1lRm9udElEKWZvbnRJRCwgKFRoZW1lRHJhd1N0YXRlKXN0YXRlLAotCQkoQm9vbGVhbil3cmFwVG9XaWR0aCwgKGNvbnN0IFJlY3QqKXNhLCAoU0ludDE2KWp1c3QsICh2b2lkKiljb250ZXh0KSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0VGhlbWVUZXh0RGltZW5zaW9ucyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgc0hhbmRsZSwganNob3J0IGZvbnRJRCwgamludCBzdGF0ZSwgamJvb2xlYW4gd3JhcFRvV2lkdGgsIGpzaG9ydEFycmF5IHNpemUsIGpzaG9ydEFycmF5IGJhc2VMaW5lKSB7Ci0KLSAgICBqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHNpemUsIDApOwotCWppbnQgc3RhdHVzPSBSQyhHZXRUaGVtZVRleHREaW1lbnNpb25zKChDRlN0cmluZ1JlZilzSGFuZGxlLCAoVGhlbWVGb250SUQpZm9udElELCAoVGhlbWVEcmF3U3RhdGUpc3RhdGUsCi0JCShCb29sZWFuKXdyYXBUb1dpZHRoLCAoUG9pbnQqKXNhLCAoU0ludDE2KiliYXNlTGluZSkpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHNpemUsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EcmF3VGhlbWVFZGl0VGV4dEZyYW1lKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJanNob3J0QXJyYXkgYm91bmRzLCBqaW50IHN0YXRlKSB7Ci0JamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgMCk7Ci0JT1NTdGF0dXMgc3RhdHVzPSBSQyhEcmF3VGhlbWVFZGl0VGV4dEZyYW1lKChSZWN0KilzYSwgc3RhdGUpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRHJhd1RoZW1lRm9jdXNSZWN0KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJanNob3J0QXJyYXkgYm91bmRzLCBqYm9vbGVhbiBoYXNGb2N1cykgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCU9TU3RhdHVzIHN0YXR1cz0gUkMoRHJhd1RoZW1lRm9jdXNSZWN0KChSZWN0KilzYSwgaGFzRm9jdXMpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRHJhd1RoZW1lR2VuZXJpY1dlbGwoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqc2hvcnRBcnJheSBib3VuZHMsIGppbnQgc3RhdGUsIGpib29sZWFuIGZpbGxDZW50ZXIpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCAwKTsKLQlPU1N0YXR1cyBzdGF0dXM9IFJDKERyYXdUaGVtZUdlbmVyaWNXZWxsKChSZWN0KilzYSwgc3RhdGUsIGZpbGxDZW50ZXIpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRHJhd1RoZW1lU2VwYXJhdG9yKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJanNob3J0QXJyYXkgYm91bmRzLCBqaW50IHN0YXRlKSB7Ci0JamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgMCk7Ci0JT1NTdGF0dXMgc3RhdHVzPSBSQyhEcmF3VGhlbWVTZXBhcmF0b3IoKFJlY3QqKXNhLCBzdGF0ZSkpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRUaGVtZUZvbnQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqc2hvcnQgdGhlbWVGb250SWQsIGpzaG9ydCBzY3JpcHRDb2RlLCBqYnl0ZUFycmF5IGZvbnROYW1lLCBqc2hvcnRBcnJheSBmb250U2l6ZSwgamJ5dGVBcnJheSBzdHlsZSkgewotCWpieXRlICpzYT0gTlVMTDsKLQlqc2hvcnQgKiBzYj0gTlVMTDsKLQlqYnl0ZSAqc2M9IE5VTEw7Ci0JamludCBzdGF0dXM9IDA7Ci0JaWYgKGZvbnROYW1lICE9IE5VTEwpCi0JCXNhPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgZm9udE5hbWUsIDApOwotCXNiPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGZvbnRTaXplLCAwKTsKLQlzYz0gKCplbnYpLT5HZXRCeXRlQXJyYXlFbGVtZW50cyhlbnYsIHN0eWxlLCAwKTsKLQlzdGF0dXM9IChqaW50KSBSQyhHZXRUaGVtZUZvbnQoKFRoZW1lRm9udElEKXRoZW1lRm9udElkLCAoU2NyaXB0Q29kZSlzY3JpcHRDb2RlLCAodW5zaWduZWQgY2hhciopc2EsIChTSW50MTYqKXNiLCAoU3R5bGUqKXNjKSk7Ci0JaWYgKHNhICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZUJ5dGVBcnJheUVsZW1lbnRzKGVudiwgZm9udE5hbWUsIHNhLCAwKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBmb250U2l6ZSwgc2IsIDApOwotCSgqZW52KS0+UmVsZWFzZUJ5dGVBcnJheUVsZW1lbnRzKGVudiwgc3R5bGUsIHNjLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EcmF3VGhlbWVCdXR0b24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqc2hvcnRBcnJheSBib3VuZHMsIGpzaG9ydCBraW5kLCBqc2hvcnRBcnJheSBuZXdJbmZvQXJyYXksIGpzaG9ydEFycmF5IHByZXZJbmZvQXJyYXksIGppbnQgZXJhc2VQcm9jLAotCQkJCQlqaW50IGxhYmVsUHJvYywgamludCB1c2VyRGF0YSkgewotCVRoZW1lQnV0dG9uRHJhd0luZm8gaW5mbzsKLQlUaGVtZUJ1dHRvbkRyYXdJbmZvIG5ld0luZm8sICpwcmV2SW5mbz0gTlVMTDsJCi0JamludCBzdGF0dXM9IDA7Ci0JanNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCWpzaG9ydCAqc2I9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgbmV3SW5mb0FycmF5LCAwKTsKLQlqc2hvcnQgKnNjPSBOVUxMOwotCQotCQotCW5ld0luZm8uc3RhdGU9IHNiWzBdOwotCW5ld0luZm8udmFsdWU9IHNiWzFdOwotCW5ld0luZm8uYWRvcm5tZW50PSBzYlsyXTsKLQkKLQlpZiAocHJldkluZm9BcnJheSAhPSBOVUxMKSB7Ci0JCXNjPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHByZXZJbmZvQXJyYXksIDApOwotCQlpbmZvLnN0YXRlPSBzY1swXTsKLQkJaW5mby52YWx1ZT0gc2NbMV07Ci0JCWluZm8uYWRvcm5tZW50PSBzY1syXTsKLQkJcHJldkluZm89ICZpbmZvOwotCX0KLQotCXN0YXR1cz0gKGppbnQpIFJDKERyYXdUaGVtZUJ1dHRvbigoY29uc3QgUmVjdCAqKXNhLCAoVGhlbWVCdXR0b25LaW5kKWtpbmQsICZuZXdJbmZvLCBwcmV2SW5mbywgKFRoZW1lRXJhc2VVUFApZXJhc2VQcm9jLAotCQkJCQkJKFRoZW1lQnV0dG9uRHJhd1VQUCkgbGFiZWxQcm9jLCAoVUludDMyKXVzZXJEYXRhKSk7Ci0JCQkJCQkKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIHNhLCAwKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBuZXdJbmZvQXJyYXksIHNiLCAwKTsKLQlpZiAoc2MgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgcHJldkluZm9BcnJheSwgc2MsIDApOwotCQotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldFRoZW1lQmFja2dyb3VuZChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWpzaG9ydCBicnVzaCwganNob3J0IGRlcHRoLCBqYm9vbGVhbiBpc0NvbG9yRGV2aWNlKSB7Ci0JcmV0dXJuIFJDKFNldFRoZW1lQmFja2dyb3VuZChicnVzaCwgZGVwdGgsIGlzQ29sb3JEZXZpY2UpKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0VGhlbWVEcmF3aW5nU3RhdGUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50QXJyYXkgc3RhdGUpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgc3RhdGUsIDApOwotCWppbnQgc3RhdHVzPSAoamludCkgUkMoR2V0VGhlbWVEcmF3aW5nU3RhdGUoKFRoZW1lRHJhd2luZ1N0YXRlKikgc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgc3RhdGUsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRUaGVtZURyYXdpbmdTdGF0ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgc3RhdGUsIGpib29sZWFuIGRpc3Bvc2VOb3cpIHsKLQlyZXR1cm4gUkMoU2V0VGhlbWVEcmF3aW5nU3RhdGUoKFRoZW1lRHJhd2luZ1N0YXRlKXN0YXRlLCBkaXNwb3NlTm93KSk7Ci19Ci0KLS8vLS0tLSB0YWJzCi0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX3NldFRhYlRleHQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IGNIYW5kbGUsIGppbnQgaW5kZXgsIGppbnQgc0hhbmRsZSkgewotCUNvbnRyb2xUYWJJbmZvUmVjVjEgdGFiOwotCQkJCi0JdGFiLnZlcnNpb249IGtDb250cm9sVGFiSW5mb1ZlcnNpb25PbmU7Ci0JdGFiLmljb25TdWl0ZUlEPSAwOwotCXRhYi5uYW1lPSAoQ0ZTdHJpbmdSZWYpIHNIYW5kbGU7Ci0JcmV0dXJuIFJDKFNldENvbnRyb2xEYXRhKChDb250cm9sUmVmKWNIYW5kbGUsIGluZGV4LCBrQ29udHJvbFRhYkluZm9UYWcsIHNpemVvZihDb250cm9sVGFiSW5mb1JlY1YxKSwgJnRhYikpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19zZXRUYWJJY29uKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBjSGFuZGxlLCBqaW50IGluZGV4LCBqaW50IGljb25IYW5kbGUpIHsKLQlDb250cm9sQnV0dG9uQ29udGVudEluZm8gdGFiOwotCUNJY29uSGFuZGxlIGloPSAoQ0ljb25IYW5kbGUpIGljb25IYW5kbGU7Ci0JCQkKLQl0YWIuY29udGVudFR5cGU9IGtDb250cm9sQ29udGVudENJY29uSGFuZGxlOwotCXRhYi51LmNJY29uSGFuZGxlPSBpaDsKLQkKLQlyZXR1cm4gUkMoU2V0Q29udHJvbERhdGEoKENvbnRyb2xSZWYpY0hhbmRsZSwgaW5kZXgsIGtDb250cm9sVGFiSW1hZ2VDb250ZW50VGFnLCBzaXplb2YoQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvKSwgJnRhYikpOwotfQotCi0vLy0tLS0gQ29tYm8KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0Q29udHJvbFBvcHVwTWVudUhhbmRsZShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludCBtSGFuZGxlKSB7Ci0JU2V0Q29udHJvbFBvcHVwTWVudUhhbmRsZSgoQ29udHJvbFJlZiljSGFuZGxlLCAoTWVudVJlZikgbUhhbmRsZSk7Ci19Ci0KLS8vLS0tLSBEYXRhQnJvd3NlcgotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19jcmVhdGVEYXRhQnJvd3NlckNvbnRyb2woSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlKSB7Ci0JQ29udHJvbFJlZiBjb250cm9sUmVmOwotCURhdGFCcm93c2VyQ2FsbGJhY2tzIGNhbGxiYWNrczsKLQkKLQlDcmVhdGVEYXRhQnJvd3NlckNvbnRyb2woKFdpbmRvd1JlZil3SGFuZGxlLCAmTlVMTF9SRUNULCBrRGF0YUJyb3dzZXJMaXN0VmlldywgJmNvbnRyb2xSZWYpOwotCQotCWNhbGxiYWNrcy52ZXJzaW9uPSBrRGF0YUJyb3dzZXJMYXRlc3RDYWxsYmFja3M7Ci0JSW5pdERhdGFCcm93c2VyQ2FsbGJhY2tzKCZjYWxsYmFja3MpOwotCVNldERhdGFCcm93c2VyQ2FsbGJhY2tzKGNvbnRyb2xSZWYsICZjYWxsYmFja3MpOwotCQkKLQlyZXR1cm4gKGppbnQpIGNvbnRyb2xSZWY7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX3NldERhdGFCcm93c2VyQ2FsbGJhY2tzKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJCWppbnQgY0hhbmRsZSwgamludCBkYXRhVVBQLCBqaW50IGNvbXBhcmVVUFAsIGppbnQgbm90aWZpY2F0aW9uVVBQKSB7Ci0JRGF0YUJyb3dzZXJDYWxsYmFja3MgY2FsbGJhY2tzOwotCUdldERhdGFCcm93c2VyQ2FsbGJhY2tzKChDb250cm9sUmVmKSBjSGFuZGxlLCAmY2FsbGJhY2tzKTsKLQljYWxsYmFja3MudS52MS5pdGVtRGF0YUNhbGxiYWNrPSAoRGF0YUJyb3dzZXJJdGVtRGF0YVVQUCkgZGF0YVVQUDsKLQljYWxsYmFja3MudS52MS5pdGVtQ29tcGFyZUNhbGxiYWNrPSAoRGF0YUJyb3dzZXJJdGVtQ29tcGFyZVVQUCkgY29tcGFyZVVQUDsKLQljYWxsYmFja3MudS52MS5pdGVtTm90aWZpY2F0aW9uQ2FsbGJhY2s9IChEYXRhQnJvd3Nlckl0ZW1Ob3RpZmljYXRpb25VUFApIG5vdGlmaWNhdGlvblVQUDsKLQlTZXREYXRhQnJvd3NlckNhbGxiYWNrcygoQ29udHJvbFJlZikgY0hhbmRsZSwgJmNhbGxiYWNrcyk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX25ld0NvbHVtbkRlc2MoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgcHJvcGVydHlJRCwgamludCBwcm9wZXJ0eVR5cGUsIGppbnQgcHJvcGVydHlGbGFncywganNob3J0IG1pbmltdW1XaWR0aCwganNob3J0IG1heGltdW1XaWR0aCkgewotCi0JRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2MgKmNvbHVtbkRlc2M9IChEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYyopIGNhbGxvYyhzaXplb2YoRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2MpLCAxKTsKLQkJCQotCWNvbHVtbkRlc2MtPnByb3BlcnR5RGVzYy5wcm9wZXJ0eUlEPSBwcm9wZXJ0eUlEOwotCWNvbHVtbkRlc2MtPnByb3BlcnR5RGVzYy5wcm9wZXJ0eVR5cGU9IHByb3BlcnR5VHlwZTsKLQljb2x1bW5EZXNjLT5wcm9wZXJ0eURlc2MucHJvcGVydHlGbGFncz0gcHJvcGVydHlGbGFnczsKLQkKLQljb2x1bW5EZXNjLT5oZWFkZXJCdG5EZXNjLnZlcnNpb249IGtEYXRhQnJvd3Nlckxpc3RWaWV3TGF0ZXN0SGVhZGVyRGVzYzsKLQljb2x1bW5EZXNjLT5oZWFkZXJCdG5EZXNjLm1pbmltdW1XaWR0aD0gbWluaW11bVdpZHRoOwotCWNvbHVtbkRlc2MtPmhlYWRlckJ0bkRlc2MubWF4aW11bVdpZHRoPSBtYXhpbXVtV2lkdGg7Ci0KLQljb2x1bW5EZXNjLT5oZWFkZXJCdG5EZXNjLnRpdGxlT2Zmc2V0PSAwOwotCWNvbHVtbkRlc2MtPmhlYWRlckJ0bkRlc2MudGl0bGVTdHJpbmc9IE5VTEw7Ci0JY29sdW1uRGVzYy0+aGVhZGVyQnRuRGVzYy5pbml0aWFsT3JkZXI9IGtEYXRhQnJvd3Nlck9yZGVySW5jcmVhc2luZzsKLQkKLQkvKgotCWNvbHVtbkRlc2MuaGVhZGVyQnRuRGVzYy50aXRsZUFsaWdubWVudD0gdGVDZW50ZXI7Ci0JY29sdW1uRGVzYy5oZWFkZXJCdG5EZXNjLnRpdGxlRm9udFR5cGVJRD0ga0NvbnRyb2xGb250Vmlld1N5c3RlbUZvbnQ7Ci0JY29sdW1uRGVzYy5oZWFkZXJCdG5EZXNjLmJ0bkZvbnRTdHlsZT0gbm9ybWFsOwotCSovCi0KLQlyZXR1cm4gKGppbnQpY29sdW1uRGVzYzsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQXV0b1NpemVEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1ucyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQlqaW50IGNIYW5kbGUpIHsKLQlyZXR1cm4gUkMoQXV0b1NpemVEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1ucygoQ29udHJvbFJlZikgY0hhbmRsZSkpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3NlckFjdGl2ZUl0ZW1zKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCWppbnQgY0hhbmRsZSwgamJvb2xlYW4gYWN0aXZlKSB7Ci0JcmV0dXJuIFJDKFNldERhdGFCcm93c2VyQWN0aXZlSXRlbXMoKENvbnRyb2xSZWYpIGNIYW5kbGUsIChCb29sZWFuKWFjdGl2ZSkpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19BZGREYXRhQnJvd3Nlckl0ZW1zKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJCQlqaW50IGNIYW5kbGUsIGppbnQgY29udGFpbmVySUQsIGppbnQgbnVtSXRlbXMsIGppbnRBcnJheSBpdGVtcywgamludCBzb3J0UHJvcGVydHkpIHsKLSAgICBqaW50ICpzYT0gTlVMTDsKLQlPU1N0YXR1cyBzdGF0dXM7Ci0JaWYgKGl0ZW1zICE9IDApCi0JCXNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBpdGVtcywgMCk7Ci0Jc3RhdHVzPSBSQyhBZGREYXRhQnJvd3Nlckl0ZW1zKChDb250cm9sUmVmKSBjSGFuZGxlLCBjb250YWluZXJJRCwgbnVtSXRlbXMsIChjb25zdCBEYXRhQnJvd3Nlckl0ZW1JRCopIHNhLCBzb3J0UHJvcGVydHkpKTsKLQlpZiAoc2EgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGl0ZW1zLCBzYSwgMCk7Ci0JcmV0dXJuIChqaW50KSBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1JlbW92ZURhdGFCcm93c2VySXRlbXMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQkJCWppbnQgY0hhbmRsZSwgamludCBjb250YWluZXJJRCwgamludCBudW1JdGVtcywgamludEFycmF5IGl0ZW1zLCBqaW50IHNvcnRQcm9wZXJ0eSkgewotICAgIGppbnQgKnNhPSBOVUxMOwotCU9TU3RhdHVzIHN0YXR1czsKLQlpZiAoaXRlbXMgIT0gMCkKLQkJc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGl0ZW1zLCAwKTsKLQlzdGF0dXM9IFJDKFJlbW92ZURhdGFCcm93c2VySXRlbXMoKENvbnRyb2xSZWYpIGNIYW5kbGUsIGNvbnRhaW5lcklELCBudW1JdGVtcywgKGNvbnN0IERhdGFCcm93c2VySXRlbUlEKikgc2EsIHNvcnRQcm9wZXJ0eSkpOwotCWlmIChzYSAhPSBOVUxMKQotCQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgaXRlbXMsIHNhLCAwKTsKLQlyZXR1cm4gKGppbnQpIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RGF0YUJyb3dzZXJJdGVtRGF0YVRleHQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaXRlbUlkLCBqaW50IHNIYW5kbGUpIHsKLQlyZXR1cm4gKGppbnQpIFJDKFNldERhdGFCcm93c2VySXRlbURhdGFUZXh0KChEYXRhQnJvd3Nlckl0ZW1EYXRhUmVmKSBpdGVtSWQsIChDRlN0cmluZ1JlZilzSGFuZGxlKSk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldERhdGFCcm93c2VySXRlbURhdGFCb29sZWFuVmFsdWUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaXRlbUlkLCBqYm9vbGVhbiB2YWx1ZSkgewotCXJldHVybiAoamludCkgUkMoU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUJvb2xlYW5WYWx1ZSgoRGF0YUJyb3dzZXJJdGVtRGF0YVJlZikgaXRlbUlkLCAoQm9vbGVhbil2YWx1ZSkpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3Nlckl0ZW1EYXRhSXRlbUlEKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGl0ZW1JZCwgamludCBpdGVtSUQpIHsKLQlyZXR1cm4gKGppbnQpIFJDKFNldERhdGFCcm93c2VySXRlbURhdGFJdGVtSUQoKERhdGFCcm93c2VySXRlbURhdGFSZWYpIGl0ZW1JZCwgKERhdGFCcm93c2VySXRlbUlEKWl0ZW1JRCkpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3Nlckl0ZW1EYXRhSWNvbihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpdGVtSWQsIGppbnQgaWNvblJlZikgewotCXJldHVybiAoamludCkgUkMoU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUljb24oKERhdGFCcm93c2VySXRlbURhdGFSZWYpIGl0ZW1JZCwgKEljb25SZWYpaWNvblJlZikpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3Nlckl0ZW1EYXRhQnV0dG9uVmFsdWUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaXRlbUlkLCBqc2hvcnQgdGhlbWVCdXR0b25WYWx1ZSkgewotCXJldHVybiAoamludCkgUkMoU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUJ1dHRvblZhbHVlKChEYXRhQnJvd3Nlckl0ZW1EYXRhUmVmKSBpdGVtSWQsIChUaGVtZUJ1dHRvblZhbHVlKXRoZW1lQnV0dG9uVmFsdWUpKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RGF0YUJyb3dzZXJIYXNTY3JvbGxCYXJzKEpOSUVudiAqZW52LCBqY2xhc3MgenosCQotCQkJCWppbnQgY0hhbmRsZSwgamJvb2xlYW4gaFNjcm9sbCwgamJvb2xlYW4gdlNjcm9sbCkgewotCXJldHVybiBSQyhTZXREYXRhQnJvd3Nlckhhc1Njcm9sbEJhcnMoKENvbnRyb2xSZWYpIGNIYW5kbGUsIGhTY3JvbGwsIHZTY3JvbGwpKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckJ0bkhlaWdodChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwganNob3J0IGhlaWdodCkgewotCXJldHVybiBSQyhTZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyQnRuSGVpZ2h0KChDb250cm9sUmVmKSBjSGFuZGxlLCBoZWlnaHQpKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQWRkRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludCBoYW5kbGUsIGppbnQgaW5kZXgpIHsKLQlyZXR1cm4gUkMoQWRkRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbigoQ29udHJvbFJlZiljSGFuZGxlLCAoRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2MqKWhhbmRsZSwgKERhdGFCcm93c2VyVGFibGVWaWV3Q29sdW1uSW5kZXgpaW5kZXgpKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVXBkYXRlRGF0YUJyb3dzZXJJdGVtcyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludCBjb250YWluZXIsIGppbnQgbnVtSXRlbXMsIGppbnRBcnJheSBpdGVtcywgamludCBwcmVTb3J0UHJvcGVydHksIGppbnQgcHJvcGVydHlJRCkgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBpdGVtcywgMCk7Ci0JamludCBzdGF0dXM9IFJDKFVwZGF0ZURhdGFCcm93c2VySXRlbXMoKENvbnRyb2xSZWYpY0hhbmRsZSwgKERhdGFCcm93c2VySXRlbUlEKWNvbnRhaW5lciwgbnVtSXRlbXMsIHNhLAotCQkJCShEYXRhQnJvd3NlclByb3BlcnR5SUQpcHJlU29ydFByb3BlcnR5LCAoRGF0YUJyb3dzZXJQcm9wZXJ0eUlEKSBwcm9wZXJ0eUlEKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGl0ZW1zLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RGF0YUJyb3dzZXJTZWxlY3Rpb25GbGFncyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludCBzZWxlY3Rpb25GbGFncykgewotCXJldHVybiBSQyhTZXREYXRhQnJvd3NlclNlbGVjdGlvbkZsYWdzKChDb250cm9sUmVmKWNIYW5kbGUsIChEYXRhQnJvd3NlclNlbGVjdGlvbkZsYWdzKSBzZWxlY3Rpb25GbGFncykpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXREYXRhQnJvd3Nlckl0ZW1Db3VudChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludCBjb250YWluZXIsIGpib29sZWFuIHJlY3Vyc2UsIGppbnQgc3RhdGUsIGppbnRBcnJheSBudW1JdGVtcykgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBudW1JdGVtcywgMCk7Ci0JT1NTdGF0dXMgc3RhdHVzPSBSQyhHZXREYXRhQnJvd3Nlckl0ZW1Db3VudCgoQ29udHJvbFJlZiljSGFuZGxlLCAoRGF0YUJyb3dzZXJJdGVtSUQpY29udGFpbmVyLCByZWN1cnNlLCBzdGF0ZSwgc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgbnVtSXRlbXMsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXREYXRhQnJvd3Nlckl0ZW1zKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBjSGFuZGxlLCBqaW50IGNvbnRhaW5lciwgamJvb2xlYW4gcmVjdXJzZSwgamludCBzdGF0ZSwgamludCBpdGVtcykgewotCXJldHVybiBSQyhHZXREYXRhQnJvd3Nlckl0ZW1zKChDb250cm9sUmVmKWNIYW5kbGUsIChEYXRhQnJvd3Nlckl0ZW1JRCljb250YWluZXIsIHJlY3Vyc2UsIAotCQkJCQkJKERhdGFCcm93c2VySXRlbVN0YXRlKXN0YXRlLCAoSGFuZGxlKWl0ZW1zKSk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludCBudW1JdGVtcywgamludEFycmF5IGl0ZW1zLCBqaW50IG9wZXJhdGlvbikgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBpdGVtcywgMCk7Ci0JT1NTdGF0dXMgc3RhdHVzPSBSQyhTZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMoKENvbnRyb2xSZWYpY0hhbmRsZSwgbnVtSXRlbXMsIChEYXRhQnJvd3Nlckl0ZW1JRCopc2EsIG9wZXJhdGlvbikpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBpdGVtcywgc2EsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1JldmVhbERhdGFCcm93c2VySXRlbShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludCBpdGVtLCBqaW50IHByb3BlcnR5SUQsIGpib29sZWFuIGNlbnRlckluVmlldykgewotCXJldHVybiBSQyhSZXZlYWxEYXRhQnJvd3Nlckl0ZW0oKENvbnRyb2xSZWYpY0hhbmRsZSwgaXRlbSwgcHJvcGVydHlJRCwgY2VudGVySW5WaWV3KSk7Ci19Ci0KLUpOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Jc0RhdGFCcm93c2VySXRlbVNlbGVjdGVkKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBjSGFuZGxlLCBqaW50IGl0ZW0pIHsKLQlyZXR1cm4gSXNEYXRhQnJvd3Nlckl0ZW1TZWxlY3RlZCgoQ29udHJvbFJlZiljSGFuZGxlLCBpdGVtKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RGF0YUJyb3dzZXJTY3JvbGxQb3NpdGlvbihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludEFycmF5IHRvcCwgamludEFycmF5IGxlZnQpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgdG9wLCAwKTsKLQlqaW50ICpzYj0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgbGVmdCwgMCk7Ci0JamludCBzdGF0dXM9IFJDKEdldERhdGFCcm93c2VyU2Nyb2xsUG9zaXRpb24oKENvbnRyb2xSZWYpY0hhbmRsZSwgKFVJbnQzMiopc2EsIChVSW50MzIqKXNiKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIHRvcCwgc2EsIDApOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBsZWZ0LCBzYiwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RGF0YUJyb3dzZXJTY3JvbGxQb3NpdGlvbihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludCB0b3AsIGppbnQgbGVmdCkgewotCXJldHVybiBSQyhTZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uKChDb250cm9sUmVmKWNIYW5kbGUsIChVSW50MzIpdG9wLCAoVUludDMyKWxlZnQpKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RGF0YUJyb3dzZXJUYXJnZXQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IGNIYW5kbGUsIGppbnQgcm9vdElEKSB7Ci0JcmV0dXJuIFJDKFNldERhdGFCcm93c2VyVGFyZ2V0KChDb250cm9sUmVmKWNIYW5kbGUsIChEYXRhQnJvd3Nlckl0ZW1JRClyb290SUQpKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0Rpc2Nsb3N1cmVDb2x1bW4oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IGNIYW5kbGUsIGppbnQgY29sSUQsIGpib29sZWFuIGIpIHsKLQlyZXR1cm4gUkMoU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0Rpc2Nsb3N1cmVDb2x1bW4oKENvbnRyb2xSZWYpY0hhbmRsZSwgKERhdGFCcm93c2VyVGFibGVWaWV3Q29sdW1uSUQpY29sSUQsIChCb29sZWFuKWIpKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RGF0YUJyb3dzZXJJdGVtUGFydEJvdW5kcyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludCBpdGVtLCBqaW50IHByb3BlcnR5LCBqaW50IHBhcnQsIGpzaG9ydEFycmF5IGJvdW5kcykgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCWludCByYz0gUkMoR2V0RGF0YUJyb3dzZXJJdGVtUGFydEJvdW5kcygoQ29udHJvbFJlZiljSGFuZGxlLCBpdGVtLCBwcm9wZXJ0eSwgcGFydCwgKFJlY3QqKSBzYSkpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIHNhLCAwKTsKLQlyZXR1cm4gcmM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX09wZW5EYXRhQnJvd3NlckNvbnRhaW5lcihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludCBjb250YWluZXIpIHsKLQlyZXR1cm4gUkMoT3BlbkRhdGFCcm93c2VyQ29udGFpbmVyKChDb250cm9sUmVmKWNIYW5kbGUsIGNvbnRhaW5lcikpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DbG9zZURhdGFCcm93c2VyQ29udGFpbmVyKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBjSGFuZGxlLCBqaW50IGNvbnRhaW5lcikgewotCXJldHVybiBSQyhDbG9zZURhdGFCcm93c2VyQ29udGFpbmVyKChDb250cm9sUmVmKWNIYW5kbGUsIGNvbnRhaW5lcikpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXREYXRhQnJvd3Nlckl0ZW1TdGF0ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwgamludCBpdGVtLCBqc2hvcnRBcnJheSBzdGF0ZSkgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBzdGF0ZSwgMCk7Ci0JaW50IHJjPSBSQyhHZXREYXRhQnJvd3Nlckl0ZW1TdGF0ZSgoQ29udHJvbFJlZiljSGFuZGxlLCBpdGVtLCAoRGF0YUJyb3dzZXJJdGVtU3RhdGUqKSBzYSkpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBzdGF0ZSwgc2EsIDApOwotCXJldHVybiByYzsKLX0KLQotLy8tLS0tIGV2ZW50cwotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DYWxsTmV4dEV2ZW50SGFuZGxlcihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgbmV4dEhhbmRsZXIsIGppbnQgZXZlbnRSZWZIYW5kbGUpIHsKLQlyZXR1cm4gKGppbnQpIENhbGxOZXh0RXZlbnRIYW5kbGVyKChFdmVudEhhbmRsZXJDYWxsUmVmKSBuZXh0SGFuZGxlciwgKEV2ZW50UmVmKSBldmVudFJlZkhhbmRsZSk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEV2ZW50SElDb21tYW5kKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGVSZWZIYW5kbGUsIGppbnRBcnJheSBvdXRQYXJhbVR5cGUpIHsKLQlqaW50IHN0YXR1czsKLSAJSElDb21tYW5kIGNvbW1hbmQ7Ci0JCi0Jc3RhdHVzPSAoamludCkgUkMoR2V0RXZlbnRQYXJhbWV0ZXIoKEV2ZW50UmVmKWVSZWZIYW5kbGUsIGtFdmVudFBhcmFtRGlyZWN0T2JqZWN0LCB0eXBlSElDb21tYW5kLCAKLQkJCU5VTEwsIHNpemVvZihISUNvbW1hbmQpLCBOVUxMLCAmY29tbWFuZCkpOwotCQotCWlmIChvdXRQYXJhbVR5cGUgIT0gTlVMTCkgewotCQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0UGFyYW1UeXBlLCAwKTsKLQkJc2FbMF09IChqaW50KSBjb21tYW5kLmF0dHJpYnV0ZXM7Ci0JCXNhWzFdPSAoamludCkgY29tbWFuZC5jb21tYW5kSUQ7Ci0JCXNhWzJdPSAoamludCkgY29tbWFuZC5tZW51Lm1lbnVSZWY7Ci0JCXNhWzNdPSAoamludCkgY29tbWFuZC5tZW51Lm1lbnVJdGVtSW5kZXg7Ci0JCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBvdXRQYXJhbVR5cGUsIHNhLCAwKTsKLQl9Ci0KLQlyZXR1cm4gc3RhdHVzOwotfQotCi0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lfM0lfM0IoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgZVJlZkhhbmRsZSwgamludCBwYXJhbU5hbWUsIGppbnQgcGFyYW1UeXBlLCBqaW50QXJyYXkgb3V0UGFyYW1UeXBlLCBqaW50QXJyYXkgb3V0QWN0dWFsU2l6ZSwgamJ5dGVBcnJheSBkYXRhKSB7Ci0JamludCBzdGF0dXM7Ci0gICAgamludCAqc2E9IE5VTEw7Ci0gICAgamludCAqc2I9IE5VTEw7Ci0gICAgamJ5dGUgKnNjPSBOVUxMOwotCWludCBzaXplPSAwOwotCQotCWlmIChvdXRQYXJhbVR5cGUgIT0gTlVMTCkKLQkJc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIG91dFBhcmFtVHlwZSwgMCk7Ci0JaWYgKG91dEFjdHVhbFNpemUgIT0gTlVMTCkKLQkJc2I9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIG91dEFjdHVhbFNpemUsIDApOwotCWlmIChkYXRhICE9IE5VTEwpIHsKLQkJc2M9ICgqZW52KS0+R2V0Qnl0ZUFycmF5RWxlbWVudHMoZW52LCBkYXRhLCAwKTsKLQkJc2l6ZT0gKCplbnYpLT5HZXRBcnJheUxlbmd0aChlbnYsIGRhdGEpOwotCX0KLQkKLQlzdGF0dXM9IChqaW50KSBSQyhHZXRFdmVudFBhcmFtZXRlcigoRXZlbnRSZWYpZVJlZkhhbmRsZSwgKEV2ZW50UGFyYW1OYW1lKXBhcmFtTmFtZSwgKEV2ZW50UGFyYW1UeXBlKXBhcmFtVHlwZSwgCi0JCQkoRXZlbnRQYXJhbVR5cGUqKXNhLCBzaXplICogc2l6ZW9mKGpieXRlKSwgKFVJbnQzMiopc2IsICh2b2lkKilzYykpOwotCQotCWlmIChzYSAhPSBOVUxMKQotCQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0UGFyYW1UeXBlLCBzYSwgMCk7Ci0JaWYgKHNiICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBvdXRBY3R1YWxTaXplLCBzYiwgMCk7Ci0JaWYgKHNjICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZUJ5dGVBcnJheUVsZW1lbnRzKGVudiwgZGF0YSwgc2MsIDApOwotCi0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RXZlbnRQYXJhbWV0ZXJfX0lJSV8zSV8zSV8zQyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBlUmVmSGFuZGxlLCBqaW50IHBhcmFtTmFtZSwgamludCBwYXJhbVR5cGUsIGppbnRBcnJheSBvdXRQYXJhbVR5cGUsIGppbnRBcnJheSBvdXRBY3R1YWxTaXplLCBqY2hhckFycmF5IGRhdGEpIHsKLQlqaW50IHN0YXR1czsKLSAgICBqaW50ICpzYT0gTlVMTDsKLSAgICBqaW50ICpzYj0gTlVMTDsKLSAgICBqY2hhciAqc2M9IE5VTEw7Ci0JaW50IHNpemU9IDA7Ci0JCi0JaWYgKG91dFBhcmFtVHlwZSAhPSBOVUxMKQotCQlzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0UGFyYW1UeXBlLCAwKTsKLQlpZiAob3V0QWN0dWFsU2l6ZSAhPSBOVUxMKQotCQlzYj0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0QWN0dWFsU2l6ZSwgMCk7Ci0JaWYgKGRhdGEgIT0gTlVMTCkgewotCQlzYz0gKCplbnYpLT5HZXRDaGFyQXJyYXlFbGVtZW50cyhlbnYsIGRhdGEsIDApOwotCQlzaXplPSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgZGF0YSk7Ci0JfQotCQotCXN0YXR1cz0gKGppbnQpIFJDKEdldEV2ZW50UGFyYW1ldGVyKChFdmVudFJlZillUmVmSGFuZGxlLCAoRXZlbnRQYXJhbU5hbWUpcGFyYW1OYW1lLCAoRXZlbnRQYXJhbVR5cGUpcGFyYW1UeXBlLCAKLQkJCShFdmVudFBhcmFtVHlwZSopc2EsIHNpemUgKiBzaXplb2YoamNoYXIpLCAoVUludDMyKilzYiwgKHZvaWQqKXNjKSk7Ci0JCi0JaWYgKHNhICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBvdXRQYXJhbVR5cGUsIHNhLCAwKTsKLQlpZiAoc2IgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIG91dEFjdHVhbFNpemUsIHNiLCAwKTsKLQlpZiAoc2MgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlQ2hhckFycmF5RWxlbWVudHMoZW52LCBkYXRhLCBzYywgMCk7Ci0KLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJXzNJXzNTKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGVSZWZIYW5kbGUsIGppbnQgcGFyYW1OYW1lLCBqaW50IHBhcmFtVHlwZSwgamludEFycmF5IG91dFBhcmFtVHlwZSwgamludEFycmF5IG91dEFjdHVhbFNpemUsIGpzaG9ydEFycmF5IGRhdGEpIHsKLQlqaW50IHN0YXR1czsKLSAgICBqaW50ICpzYT0gTlVMTDsKLSAgICBqaW50ICpzYj0gTlVMTDsKLSAgICBqc2hvcnQgKnNjPSBOVUxMOwotCWludCBzaXplPSAwOwotCQotCWlmIChvdXRQYXJhbVR5cGUgIT0gTlVMTCkKLQkJc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIG91dFBhcmFtVHlwZSwgMCk7Ci0JaWYgKG91dEFjdHVhbFNpemUgIT0gTlVMTCkKLQkJc2I9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIG91dEFjdHVhbFNpemUsIDApOwotCWlmIChkYXRhICE9IE5VTEwpIHsKLQkJc2M9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgZGF0YSwgMCk7Ci0JCXNpemU9ICgqZW52KS0+R2V0QXJyYXlMZW5ndGgoZW52LCBkYXRhKTsKLQl9Ci0JCi0Jc3RhdHVzPSAoamludCkgUkMoR2V0RXZlbnRQYXJhbWV0ZXIoKEV2ZW50UmVmKWVSZWZIYW5kbGUsIChFdmVudFBhcmFtTmFtZSlwYXJhbU5hbWUsIChFdmVudFBhcmFtVHlwZSlwYXJhbVR5cGUsIAotCQkJKEV2ZW50UGFyYW1UeXBlKilzYSwgc2l6ZSAqIHNpemVvZihqc2hvcnQpLCAoVUludDMyKilzYiwgKHZvaWQqKXNjKSk7Ci0JCi0JaWYgKHNhICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBvdXRQYXJhbVR5cGUsIHNhLCAwKTsKLQlpZiAoc2IgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIG91dEFjdHVhbFNpemUsIHNiLCAwKTsKLQlpZiAoc2MgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgZGF0YSwgc2MsIDApOwotCi0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RXZlbnRQYXJhbWV0ZXJfX0lJSV8zSV8zSV8zSShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBlUmVmSGFuZGxlLCBqaW50IHBhcmFtTmFtZSwgamludCBwYXJhbVR5cGUsIGppbnRBcnJheSBvdXRQYXJhbVR5cGUsIGppbnRBcnJheSBvdXRBY3R1YWxTaXplLCBqaW50QXJyYXkgZGF0YSkgewotCWppbnQgc3RhdHVzOwotICAgIGppbnQgKnNhPSBOVUxMOwotICAgIGppbnQgKnNiPSBOVUxMOwotICAgIGppbnQgKnNjPSBOVUxMOwotCWludCBzaXplPSAwOwotCQotCWlmIChvdXRQYXJhbVR5cGUgIT0gTlVMTCkKLQkJc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIG91dFBhcmFtVHlwZSwgMCk7Ci0JaWYgKG91dEFjdHVhbFNpemUgIT0gTlVMTCkKLQkJc2I9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIG91dEFjdHVhbFNpemUsIDApOwotCWlmIChkYXRhICE9IE5VTEwpIHsKLQkJc2M9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGRhdGEsIDApOwotCQlzaXplPSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgZGF0YSk7Ci0JfQotCQotCXN0YXR1cz0gKGppbnQpIFJDKEdldEV2ZW50UGFyYW1ldGVyKChFdmVudFJlZillUmVmSGFuZGxlLCAoRXZlbnRQYXJhbU5hbWUpcGFyYW1OYW1lLCAoRXZlbnRQYXJhbVR5cGUpcGFyYW1UeXBlLCAKLQkJCShFdmVudFBhcmFtVHlwZSopc2EsIHNpemUgKiBzaXplb2YoamludCksIChVSW50MzIqKXNiLCAodm9pZCopc2MpKTsKLQkKLQlpZiAoc2EgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIG91dFBhcmFtVHlwZSwgc2EsIDApOwotCWlmIChzYiAhPSBOVUxMKQotCQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0QWN0dWFsU2l6ZSwgc2IsIDApOwotCWlmIChzYyAhPSBOVUxMKQotCQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgZGF0YSwgc2MsIDApOwotCi0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RXZlbnRQYXJhbWV0ZXIoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgZVJlZkhhbmRsZSwgamludCBwYXJhbU5hbWUsIGppbnQgcGFyYW1UeXBlLCBqY2hhckFycmF5IGRhdGEpIHsKLQlqaW50IHN0YXR1czsKLSAgICBqY2hhciAqc2M9IE5VTEw7Ci0JaW50IHNpemU9IDA7Ci0JCi0JaWYgKGRhdGEgIT0gTlVMTCkgewotCQlzYz0gKCplbnYpLT5HZXRDaGFyQXJyYXlFbGVtZW50cyhlbnYsIGRhdGEsIDApOwotCQlzaXplPSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgZGF0YSk7Ci0JfQotCQotCXN0YXR1cz0gKGppbnQpIFJDKFNldEV2ZW50UGFyYW1ldGVyKChFdmVudFJlZillUmVmSGFuZGxlLCAoRXZlbnRQYXJhbU5hbWUpcGFyYW1OYW1lLCAoRXZlbnRQYXJhbVR5cGUpcGFyYW1UeXBlLCAKLQkJCXNpemUgKiBzaXplb2YoamNoYXIpLCAodm9pZCopc2MpKTsKLQkKLQlpZiAoc2MgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlQ2hhckFycmF5RWxlbWVudHMoZW52LCBkYXRhLCBzYywgMCk7Ci0KLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19JbnN0YWxsRXZlbnRIYW5kbGVyKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJCQlqaW50IGV2ZW50VGFyZ2V0UmVmLCBqaW50IGV2ZW50SGFuZGxlclVQUCwgamludEFycmF5IGV2ZW50VHlwZXMsIGppbnQgY2xpZW50RGF0YSkgewotICAgIGppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBldmVudFR5cGVzLCAwKTsKLSAgICBqc2l6ZSBsZW5ndGg9ICgqZW52KS0+R2V0QXJyYXlMZW5ndGgoZW52LCBldmVudFR5cGVzKTsKLQlqaW50IHN0YXR1czsKLQkKLQlzdGF0dXM9IChqaW50KSBSQyhJbnN0YWxsRXZlbnRIYW5kbGVyKAotCQkJKEV2ZW50VGFyZ2V0UmVmKSBldmVudFRhcmdldFJlZiwgCi0JCQkoRXZlbnRIYW5kbGVyVVBQKSBldmVudEhhbmRsZXJVUFAsIAotCQkJbGVuZ3RoLzIsIChFdmVudFR5cGVTcGVjKikgc2EsCi0JCQkodm9pZCopIGNsaWVudERhdGEsCi0JCQlOVUxMCi0JCSkpOwotCQkKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgZXZlbnRUeXBlcywgc2EsIDApOwotCQkKLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDb250cm9sRXZlbnRUYXJnZXQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBjSGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBHZXRDb250cm9sRXZlbnRUYXJnZXQoKENvbnRyb2xSZWYpIGNIYW5kbGUpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRNZW51RXZlbnRUYXJnZXQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBHZXRNZW51RXZlbnRUYXJnZXQoKE1lbnVSZWYpIG1IYW5kbGUpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRVc2VyRm9jdXNFdmVudFRhcmdldChKTklFbnYgKmVudiwgamNsYXNzIHp6KSB7Ci0JcmV0dXJuIChqaW50KSBHZXRVc2VyRm9jdXNFdmVudFRhcmdldCgpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRBcHBsaWNhdGlvbkV2ZW50VGFyZ2V0KEpOSUVudiAqZW52LCBqY2xhc3MgenopIHsKLQlyZXR1cm4gKGppbnQpIEdldEFwcGxpY2F0aW9uRXZlbnRUYXJnZXQoKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0VXNlckZvY3VzV2luZG93KEpOSUVudiAqZW52LCBqY2xhc3MgenopIHsKLQlyZXR1cm4gKGppbnQpIEdldFVzZXJGb2N1c1dpbmRvdygpOwotfQotCi1KTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRXZlbnRBdmFpbChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqc2hvcnQgbWFzaywgamludCBlSGFuZGxlKSB7Ci0JcmV0dXJuIChqYm9vbGVhbikgRXZlbnRBdmFpbChtYXNrLCAoRXZlbnRSZWNvcmQqKSBlSGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldE5leHRFdmVudChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqc2hvcnQgbWFzaywgamludEFycmF5IGVEYXRhKSB7Ci0JRXZlbnRSZWNvcmQgZXZlbnQ7Ci0JamJvb2xlYW4gcmM9IEdldE5leHRFdmVudChtYXNrLCAmZXZlbnQpOwotCWNvcHlFdmVudChlbnYsIGVEYXRhLCAmZXZlbnQpOwotCXJldHVybiByYzsKLX0KLQotSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1dhaXROZXh0RXZlbnQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0IG1hc2ssIGppbnRBcnJheSBlRGF0YSwgamludCBzbGVlcHRpbWUpIHsKLQlFdmVudFJlY29yZCBldmVudDsKLQlqYm9vbGVhbiByYz0gV2FpdE5leHRFdmVudChtYXNrLCAmZXZlbnQsIHNsZWVwdGltZSwgbmlsKTsJCi0JY29weUV2ZW50KGVudiwgZURhdGEsICZldmVudCk7Ci0JcmV0dXJuIHJjOwotfQotCi1KTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU3RpbGxEb3duKEpOSUVudiAqZW52LCBqY2xhc3MgenopIHsKLQlyZXR1cm4gKGpib29sZWFuKSBTdGlsbERvd24oKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0TW91c2UoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0QXJyYXkgd2hlcmUpIHsKLQlqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHdoZXJlLCAwKTsKLQlHZXRNb3VzZSgoc3RydWN0IFBvaW50KilzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgd2hlcmUsIHNhLCAwKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQUVQcm9jZXNzQXBwbGVFdmVudChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnRBcnJheSBldmVudERhdGEpIHsKLQlFdmVudFJlY29yZCBldmVudDsKLQljb3B5RXZlbnREYXRhKGVudiwgJmV2ZW50LCBldmVudERhdGEpOwotCUFFUHJvY2Vzc0FwcGxlRXZlbnQoJmV2ZW50KTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTWVudUV2ZW50KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludEFycmF5IGV2ZW50RGF0YSkgewotCUV2ZW50UmVjb3JkIGV2ZW50OwotCWNvcHlFdmVudERhdGEoZW52LCAmZXZlbnQsIGV2ZW50RGF0YSk7Ci0JcmV0dXJuIChqaW50KSBNZW51RXZlbnQoJmV2ZW50KTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUG9zdEV2ZW50KEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzaG9ydCBraW5kLCBqaW50IG1lc3NhZ2UpIHsKLQlyZXR1cm4gUkMoUG9zdEV2ZW50KGtpbmQsIG1lc3NhZ2UpKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0S2V5Ym9hcmRGb2N1cyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHdIYW5kbGUsIGppbnRBcnJheSBjSGFuZGxlKSB7Ci0gICAgamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGNIYW5kbGUsIDApOwotCWludCByYz0gUkMoR2V0S2V5Ym9hcmRGb2N1cygoV2luZG93UmVmKSB3SGFuZGxlLCAoQ29udHJvbFJlZiopIHNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGNIYW5kbGUsIHNhLCAwKTsKLQlyZXR1cm4gcmM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0FkdmFuY2VLZXlib2FyZEZvY3VzKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSkgewotCXJldHVybiBSQyhBZHZhbmNlS2V5Ym9hcmRGb2N1cygoV2luZG93UmVmKSB3SGFuZGxlKSk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldEtleWJvYXJkRm9jdXMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgd0hhbmRsZSwgamludCBjSGFuZGxlLCBqc2hvcnQgcGFydCkgewotCXJldHVybiAoamludCkgUkMoU2V0S2V5Ym9hcmRGb2N1cygoV2luZG93UmVmKSB3SGFuZGxlLCAoQ29udHJvbFJlZikgY0hhbmRsZSwgcGFydCkpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDdXJyZW50RXZlbnRMb29wKEpOSUVudiAqZW52LCBqY2xhc3MgenopIHsKLQlyZXR1cm4gKGppbnQpIEdldEN1cnJlbnRFdmVudExvb3AoKTsKLX0KLQotSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0lzU2hvd0NvbnRleHR1YWxNZW51Q2xpY2soSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludEFycmF5IGV2ZW50RGF0YSkgewotCUV2ZW50UmVjb3JkIGV2ZW50OwotCWNvcHlFdmVudERhdGEoZW52LCAmZXZlbnQsIGV2ZW50RGF0YSk7Ci0JcmV0dXJuIChqYm9vbGVhbikgSXNTaG93Q29udGV4dHVhbE1lbnVDbGljaygmZXZlbnQpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Db250ZXh0dWFsTWVudVNlbGVjdChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBtSGFuZGxlLCBqc2hvcnRBcnJheSBsb2NhdGlvbiwganNob3J0QXJyYXkgbWVudUlkLCBqc2hvcnRBcnJheSBpbmRleCkgewotCVVJbnQzMiBvdXRVc2VyU2VsZWN0aW9uVHlwZTsJCi0gICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBtZW51SWQsIDApOwotICAgIGpzaG9ydCAqc2I9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgaW5kZXgsIDApOwotCWppbnQgc3RhdHVzPSBSQyhDb250ZXh0dWFsTWVudVNlbGVjdCgKLQkJCQkoTWVudVJlZikgbUhhbmRsZSwKLQkJCQlwb2ludChlbnYsIGxvY2F0aW9uKSwgCi0JCQkJZmFsc2UsIAotCQkJCTAsIC8vIGtDTUhlbHBJdGVtT3RoZXJIZWxwLCAKLQkJCQkwLCAvLyAiXHBpbkhlbHBJdGVtU3RyaW5nIiwgCi0JCQkJTlVMTCwgCi0JCQkJJm91dFVzZXJTZWxlY3Rpb25UeXBlLCAKLQkJCQkoU0ludDE2Kikgc2EsIAotCQkJCShNZW51SXRlbUluZGV4Kikgc2IpKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBtZW51SWQsIHNhLCAwKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBpbmRleCwgc2IsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0luc3RhbGxFdmVudExvb3BUaW1lcihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQlqaW50IGluRXZlbnRMb29wLCBqZG91YmxlIGluRmlyZURlbGF5LCBqZG91YmxlIGluSW50ZXJ2YWwsIGppbnQgaW5UaW1lclByb2MsIGppbnQgaW5UaW1lckRhdGEsIGppbnRBcnJheSBvdXRUaW1lcikgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBvdXRUaW1lciwgMCk7Ci0JaW50IHJjPSBSQyhJbnN0YWxsRXZlbnRMb29wVGltZXIoKEV2ZW50TG9vcFJlZikgaW5FdmVudExvb3AsIChFdmVudFRpbWVySW50ZXJ2YWwpIGluRmlyZURlbGF5LCAoRXZlbnRUaW1lckludGVydmFsKSBpbkludGVydmFsLAotICAgICAgICAgICAgICAgIChFdmVudExvb3BUaW1lclVQUCkgaW5UaW1lclByb2MsICh2b2lkKikgaW5UaW1lckRhdGEsIChFdmVudExvb3BUaW1lclJlZiopIHNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIG91dFRpbWVyLCBzYSwgMCk7Ci0JcmV0dXJuIHJjOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SZW1vdmVFdmVudExvb3BUaW1lcihKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHRpbWVyKSB7Ci0JcmV0dXJuIFJDKFJlbW92ZUV2ZW50TG9vcFRpbWVyKChFdmVudExvb3BUaW1lclJlZikgdGltZXIpKTsKLX0KLQotSk5JRVhQT1JUIGpkb3VibGUgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0TGFzdFVzZXJFdmVudFRpbWUoSk5JRW52ICplbnYsIGpjbGFzcyB6eikgewotCXJldHVybiBHZXRMYXN0VXNlckV2ZW50VGltZSgpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SZWNlaXZlTmV4dEV2ZW50KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCWppbnRBcnJheSBldmVudFR5cGVTcGVjTGlzdCwgamRvdWJsZSBpblRpbWVvdXQsIGpib29sZWFuIGluUHVsbEV2ZW50LCBqaW50QXJyYXkgb3V0RXZlbnQpIHsKLQlqaW50IHN0YXR1czsKLQlqaW50ICpzYT0gTlVMTCwgKnNiPSBOVUxMOwotCVVJbnQzMiBpbk51bVR5cGVzPSAwOwotCWlmIChldmVudFR5cGVTcGVjTGlzdCAhPSBOVUxMKSB7Ci0JCXNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBldmVudFR5cGVTcGVjTGlzdCwgMCk7Ci0JCWluTnVtVHlwZXM9ICgqZW52KS0+R2V0QXJyYXlMZW5ndGgoZW52LCBldmVudFR5cGVTcGVjTGlzdCkvMjsKLQl9Ci0JaWYgKG91dEV2ZW50ICE9IE5VTEwpCi0JCXNiPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBvdXRFdmVudCwgMCk7Ci0Jc3RhdHVzPSAoamludCkgUkMoUmVjZWl2ZU5leHRFdmVudChpbk51bVR5cGVzLCAoY29uc3QgRXZlbnRUeXBlU3BlYyopIHNhLCBpblRpbWVvdXQsIGluUHVsbEV2ZW50LCAoRXZlbnRSZWYqKSBzYikpOwotCWlmIChzYSAhPSBOVUxMKQotCQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgZXZlbnRUeXBlU3BlY0xpc3QsIHNhLCAwKTsJCi0JaWYgKHNiICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBvdXRFdmVudCwgc2IsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEV2ZW50RGlzcGF0Y2hlclRhcmdldChKTklFbnYgKmVudiwgamNsYXNzIHp6KSB7Ci0JcmV0dXJuIChqaW50KSBHZXRFdmVudERpc3BhdGNoZXJUYXJnZXQoKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2VuZEV2ZW50VG9FdmVudFRhcmdldChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGVIYW5kbGUsIGppbnQgdGFyZ2V0KSB7Ci0JcmV0dXJuIChqaW50KSBSQyhTZW5kRXZlbnRUb0V2ZW50VGFyZ2V0KChFdmVudFJlZillSGFuZGxlLCAoRXZlbnRUYXJnZXRSZWYpIHRhcmdldCkpOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SZWxlYXNlRXZlbnQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBlSGFuZGxlKSB7Ci0JUmVsZWFzZUV2ZW50KChFdmVudFJlZillSGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NvbnZlcnRFdmVudFJlZlRvRXZlbnRSZWNvcmQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBlSGFuZGxlLCBqaW50QXJyYXkgZGF0YSkgewotCUV2ZW50UmVjb3JkIGV2ZW50OwotCWpib29sZWFuIHJjPSBDb252ZXJ0RXZlbnRSZWZUb0V2ZW50UmVjb3JkKChFdmVudFJlZikgZUhhbmRsZSwgJmV2ZW50KTsKLQljb3B5RXZlbnQoZW52LCBkYXRhLCAmZXZlbnQpOwotCXJldHVybiByYzsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW5zdGFsbFN0YW5kYXJkRXZlbnRIYW5kbGVyKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgdGFyZ2V0KSB7Ci0JcmV0dXJuIChqaW50KSBSQyhJbnN0YWxsU3RhbmRhcmRFdmVudEhhbmRsZXIoKEV2ZW50VGFyZ2V0UmVmKSB0YXJnZXQpKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0V2luZG93RXZlbnRUYXJnZXQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBHZXRXaW5kb3dFdmVudFRhcmdldCgoV2luZG93UmVmKSB3SGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RXZlbnRDbGFzcyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGVIYW5kbGUpIHsKLQlyZXR1cm4gKGppbnQpIEdldEV2ZW50Q2xhc3MoKEV2ZW50UmVmKSBlSGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RXZlbnRLaW5kKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgZUhhbmRsZSkgewotCXJldHVybiAoamludCkgR2V0RXZlbnRLaW5kKChFdmVudFJlZikgZUhhbmRsZSk7Ci19Ci0KLUpOSUVYUE9SVCBqZG91YmxlIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEV2ZW50VGltZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGVIYW5kbGUpIHsKLQlyZXR1cm4gKGpkb3VibGUpIEdldEV2ZW50VGltZSgoRXZlbnRSZWYpIGVIYW5kbGUpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRNb3VzZUxvY2F0aW9uKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgZUhhbmRsZSwganNob3J0QXJyYXkgbG9jKSB7Ci0JanNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBsb2MsIDApOwotCWppbnQgc3RhdHVzPSBSQyhHZXRFdmVudFBhcmFtZXRlcigoRXZlbnRSZWYpIGVIYW5kbGUsIGtFdmVudFBhcmFtTW91c2VMb2NhdGlvbiwgdHlwZVFEUG9pbnQsIE5VTEwsIHNpemVvZihQb2ludCksIE5VTEwsIChQb2ludCopc2EpKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBsb2MsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UcmFja01vdXNlTG9jYXRpb24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgcG9ydEhhbmRsZSwganNob3J0QXJyYXkgbG9jLCBqc2hvcnRBcnJheSBwYXJ0KSB7Ci0JanNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBsb2MsIDApOwotCWpzaG9ydCAqc2I9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgcGFydCwgMCk7Ci0JamludCBzdGF0dXM9IFJDKFRyYWNrTW91c2VMb2NhdGlvbigoR3JhZlB0cikgcG9ydEhhbmRsZSwgKFBvaW50Kikgc2EsIHNiKSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgbG9jLCBzYSwgMCk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgcGFydCwgc2IsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEdsb2JhbE1vdXNlKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzaG9ydEFycmF5IHdoZXJlKSB7Ci0JanNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCB3aGVyZSwgMCk7Ci0JR2V0R2xvYmFsTW91c2UoKFBvaW50KilzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgd2hlcmUsIHNhLCAwKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ3JlYXRlRXZlbnQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgYWxsb2NhdG9yLCBqaW50IGNsYXNzSUQsIGppbnQga2luZCwgamRvdWJsZSB3aGVuLCBqaW50IGZsYWdzLCBqaW50QXJyYXkgZXZlbnRSZWYpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgZXZlbnRSZWYsIDApOwotCWppbnQgc3RhdHVzPSBSQyhDcmVhdGVFdmVudCgoQ0ZBbGxvY2F0b3JSZWYpYWxsb2NhdG9yLCBjbGFzc0lELCBraW5kLCAoRXZlbnRUaW1lKXdoZW4sIChFdmVudEF0dHJpYnV0ZXMpZmxhZ3MsIChFdmVudFJlZiopIHNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGV2ZW50UmVmLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUG9zdEV2ZW50VG9RdWV1ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBxdWV1ZSwgamludCBldmVudCwganNob3J0IHByaW9yaXR5KSB7Ci0JcmV0dXJuIFJDKFBvc3RFdmVudFRvUXVldWUoKEV2ZW50UXVldWVSZWYpcXVldWUsIChFdmVudFJlZilldmVudCwgKEV2ZW50UHJpb3JpdHkpIHByaW9yaXR5KSk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldE1haW5FdmVudFF1ZXVlKEpOSUVudiAqZW52LCBqY2xhc3MgenopIHsKLQlyZXR1cm4gKGppbnQpIEdldE1haW5FdmVudFF1ZXVlKCk7Ci19Ci0KLS8vLS0tLSBDdXJzb3JzCi0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEN1cnNvcihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQlqc2hvcnQgaWQpIHsKLQlyZXR1cm4gKGppbnQpIEdldEN1cnNvcihpZCk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05ld0N1cnNvcihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQlqc2hvcnQgaG90WCwganNob3J0IGhvdFksIGpzaG9ydEFycmF5IGRhdGEsIGpzaG9ydEFycmF5IG1hc2spIHsKLQkKLQlqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGRhdGEsIDApOwotCWpzaG9ydCAqc2I9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgbWFzaywgMCk7Ci0KLQlDdXJzb3IgKmM9IChDdXJzb3IqKSBOZXdQdHJDbGVhcihzaXplb2YoQ3Vyc29yKSk7Ci0JbWVtY3B5KCZjLT5kYXRhLCBzYSwgc2l6ZW9mIChCaXRzMTYpKTsKLQltZW1jcHkoJmMtPm1hc2ssIHNiLCBzaXplb2YgKEJpdHMxNikpOwotCWMtPmhvdFNwb3QuaD0gaG90WDsKLQljLT5ob3RTcG90LnY9IGhvdFk7Ci0KLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBkYXRhLCBzYSwgMCk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgbWFzaywgc2IsIDApOwotCQotCXJldHVybiAoamludCkgYzsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0Q3Vyc29yKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY3Vyc29yKSB7Ci0JU2V0Q3Vyc29yKChjb25zdCBDdXJzb3IqKWN1cnNvcik7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldFRoZW1lQ3Vyc29yKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY3Vyc29yKSB7Ci0JcmV0dXJuIChqaW50KSBTZXRUaGVtZUN1cnNvcigoVGhlbWVDdXJzb3IpY3Vyc29yKTsKLX0KLQotLy8tLS0tIEdyYWZQb3J0Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFFER2xvYmFsc1NjcmVlbkJpdHMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgYml0bWFwKSB7Ci0JcmV0dXJuIChqaW50KSBHZXRRREdsb2JhbHNTY3JlZW5CaXRzKChCaXRNYXAqKWJpdG1hcCk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1FEU3dhcFRleHRGbGFncyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGZsYWdzKSB7Ci0JcmV0dXJuIChqaW50KSBTd2FwUURUZXh0RmxhZ3MoZmxhZ3MpOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19RRFNldFBhdHRlcm5PcmlnaW4oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJanNob3J0QXJyYXkgbykgewotCVFEU2V0UGF0dGVybk9yaWdpbihwb2ludChlbnYsIG8pKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0UG9ydChKTklFbnYgKmVudiwgamNsYXNzIHp6KSB7Ci0JR3JhZlB0ciBwOwotCUdldFBvcnQoJnApOwotCXJldHVybiAoamludCkgcDsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0UG9ydChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQlqaW50IHBvcnRIYW5kbGUpIHsKLQlTZXRQb3J0KChHcmFmUHRyKSBwb3J0SGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0lzVmFsaWRQb3J0KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCWppbnQgcG9ydEhhbmRsZSkgewotCXJldHVybiAoamJvb2xlYW4pIElzVmFsaWRQb3J0KChDR3JhZlB0cilwb3J0SGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0UG9ydFdpbmRvd1BvcnQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlKSB7Ci0JU2V0UG9ydFdpbmRvd1BvcnQoKFdpbmRvd1JlZikgd0hhbmRsZSk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFBvcnRCb3VuZHMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJamludCBwb3J0LCBqc2hvcnRBcnJheSBib3VuZHMpIHsKLQlqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgMCk7Ci0JR2V0UG9ydEJvdW5kcygoQ0dyYWZQdHIpIHBvcnQsIChSZWN0Kikgc2EpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgc2EsIDApOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19FcmFzZVJlY3QoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0QXJyYXkgYm91bmRzKSB7Ci0JanNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCUVyYXNlUmVjdCgoUmVjdCopIHNhKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIHNhLCAwKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRnJhbWVSZWN0KEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzaG9ydEFycmF5IGJvdW5kcykgewotCWpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCAwKTsKLQlGcmFtZVJlY3QoKFJlY3QqKSBzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCBzYSwgMCk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1BhaW50UmVjdChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqc2hvcnRBcnJheSBib3VuZHMpIHsKLQlqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgMCk7Ci0JUGFpbnRSZWN0KChSZWN0Kikgc2EpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgc2EsIDApOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19GcmFtZU92YWwoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0QXJyYXkgYm91bmRzKSB7Ci0gICAgICAgIGpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCAwKTsKLQlGcmFtZU92YWwoKFJlY3QqKSBzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCBzYSwgMCk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1BhaW50T3ZhbChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqc2hvcnRBcnJheSBib3VuZHMpIHsKLSAgICAgICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCVBhaW50T3ZhbCgoUmVjdCopIHNhKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIHNhLCAwKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRnJhbWVSb3VuZFJlY3QoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWpzaG9ydEFycmF5IGJvdW5kcywganNob3J0IG92YWxXaWR0aCwganNob3J0IG92YWxIZWlnaHQpIHsKLSAgICAgICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCUZyYW1lUm91bmRSZWN0KChSZWN0Kikgc2EsIG92YWxXaWR0aCwgb3ZhbEhlaWdodCk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCBzYSwgMCk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1BhaW50Um91bmRSZWN0KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqc2hvcnRBcnJheSBib3VuZHMsIGpzaG9ydCBvdmFsV2lkdGgsIGpzaG9ydCBvdmFsSGVpZ2h0KSB7Ci0gICAgICAgIGpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCAwKTsKLQlQYWludFJvdW5kUmVjdCgoUmVjdCopIHNhLCBvdmFsV2lkdGgsIG92YWxIZWlnaHQpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgc2EsIDApOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Ob3JtYWxpemVUaGVtZURyYXdpbmdTdGF0ZShKTklFbnYgKmVudiwgamNsYXNzIHp6KSB7Ci0JTm9ybWFsaXplVGhlbWVEcmF3aW5nU3RhdGUoKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVGV4dEZvbnQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0IGZvbnRJRCkgewotCVRleHRGb250KGZvbnRJRCk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RleHRTaXplKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzaG9ydCBzaXplKSB7Ci0JVGV4dFNpemUoc2l6ZSk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RleHRGYWNlKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzaG9ydCBmYWNlKSB7Ci0JVGV4dEZhY2UoZmFjZSk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RleHRNb2RlKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzaG9ydCBtb2RlKSB7Ci0JVGV4dE1vZGUobW9kZSk7Ci19Ci0KLSNpZmRlZiBVU0VfQVRTVUkKLQotc3RhdGljIEFUU1VUZXh0TGF5b3V0IGZnVGV4dExheW91dDsKLXN0YXRpYyBBVFNVU3R5bGUgZmdTdHlsZTsKLXN0YXRpYyBpbnQgZmdUZXh0TGF5b3V0SW5pdGlhbGl6ZWQ7Ci1zdGF0aWMgQVRTVUF0dHJpYnV0ZVRhZyBmZ0FUU1VBdHRyaWJ1dGVUYWdbNF07Ci1zdGF0aWMgQnl0ZUNvdW50IGZnQnl0ZUNvdW50WzRdOwotc3RhdGljIEFUU1VBdHRyaWJ1dGVWYWx1ZVB0ciBmZ0FUU1VBdHRyaWJ1dGVWYWx1ZVB0cls0XTsKLQotc3RhdGljIHZvaWQgaW5pdEFUU1VJKEFUU1VGb250SUQgZm9udCwgc2hvcnQgc2l6ZSwgc2hvcnQgZmFjZSkgewotCUFUU1VGb250SUQgZj0gMDsgCi0JRml4ZWQgcz0gc2l6ZSA8PCAxNjsKLQlCb29sZWFuIGlzQm9sZD0gZmFsc2U7Ci0JQm9vbGVhbiBpc0l0YWxpYz0gZmFsc2U7Ci0JaW50IG49IDM7Ci0JCi0JaWYgKChmYWNlICYgYm9sZCkgIT0gMCkKLQkJaXNCb2xkPSB0cnVlOwotCWlmICgoZmFjZSAmIGl0YWxpYykgIT0gMCkKLQkJaXNJdGFsaWM9IHRydWU7Ci0JCi0JaWYgKEFUU1VGT05EdG9Gb250SUQoZm9udCwgKFN0eWxlKSBub3JtYWwsICZmKSAhPSAwKQotCQlmcHJpbnRmKHN0ZGVyciwgIkFUU1VGT05EdG9Gb250SUQ6IGVycm9yXG4iKTsKLQllbHNlIGlmIChmICE9IDApCi0JCW4rKzsKLQkKLQlpZiAoZmdUZXh0TGF5b3V0SW5pdGlhbGl6ZWQgPT0gMCkgewotCQlpZiAoQVRTVUNyZWF0ZVRleHRMYXlvdXQoJmZnVGV4dExheW91dCkgIT0gMCkKLQkJCi0JCWlmIChBVFNVU2V0VHJhbnNpZW50Rm9udE1hdGNoaW5nKGZnVGV4dExheW91dCwgdHJ1ZSkgIT0gMCkKLQkJCWZwcmludGYoc3RkZXJyLCAiQVRTVVNldFRyYW5zaWVudEZvbnRNYXRjaGluZzE6IGVycm9yXG4iKTsKLQotCQlpZiAoQVRTVUNyZWF0ZVN0eWxlKCZmZ1N0eWxlKSAhPSAwKQotCQkJZnByaW50ZihzdGRlcnIsICJBVFNVQ3JlYXRlU3R5bGU6IGVycm9yXG4iKTsKLQkJCQkJCQotCQlmZ0FUU1VBdHRyaWJ1dGVUYWdbMF09IGtBVFNVU2l6ZVRhZzsKLQkJZmdBVFNVQXR0cmlidXRlVGFnWzFdPSBrQVRTVVFEQm9sZGZhY2VUYWc7Ci0JCWZnQVRTVUF0dHJpYnV0ZVRhZ1syXT0ga0FUU1VRREl0YWxpY1RhZzsKLQkJZmdBVFNVQXR0cmlidXRlVGFnWzNdPSBrQVRTVUZvbnRUYWc7Ci0KLQkJZmdCeXRlQ291bnRbMF09IHNpemVvZihGaXhlZCk7Ci0JCWZnQnl0ZUNvdW50WzFdPSBzaXplb2YoQm9vbGVhbik7Ci0JCWZnQnl0ZUNvdW50WzJdPSBzaXplb2YoQm9vbGVhbik7Ci0JCWZnQnl0ZUNvdW50WzNdPSBzaXplb2YoQVRTVUZvbnRJRCk7Ci0JCi0JCWZnVGV4dExheW91dEluaXRpYWxpemVkPSAxOwotCX0gZWxzZSB7Ci0JCWlmIChBVFNVU2V0VHJhbnNpZW50Rm9udE1hdGNoaW5nKGZnVGV4dExheW91dCwgdHJ1ZSkgIT0gMCkKLQkJCWZwcmludGYoc3RkZXJyLCAiQVRTVVNldFRyYW5zaWVudEZvbnRNYXRjaGluZzI6IGVycm9yXG4iKTsKLQl9Ci0JCi0JZmdBVFNVQXR0cmlidXRlVmFsdWVQdHJbMF09ICZzOwotCWZnQVRTVUF0dHJpYnV0ZVZhbHVlUHRyWzFdPSAmaXNCb2xkOwotCWZnQVRTVUF0dHJpYnV0ZVZhbHVlUHRyWzJdPSAmaXNJdGFsaWM7Ci0JZmdBVFNVQXR0cmlidXRlVmFsdWVQdHJbM109ICZmOwotCQotCWlmIChBVFNVU2V0QXR0cmlidXRlcyhmZ1N0eWxlLCBuLCBmZ0FUU1VBdHRyaWJ1dGVUYWcsIGZnQnl0ZUNvdW50LCBmZ0FUU1VBdHRyaWJ1dGVWYWx1ZVB0cikgIT0gMCkKLQkJZnByaW50ZihzdGRlcnIsICJBVFNVU2V0QXR0cmlidXRlczogZXJyb3JcbiIpOworCXJldHVybiAoamludClBY3RpdmVOb25GbG9hdGluZ1dpbmRvdygpOwogfQogI2VuZGlmCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0RyYXdUZXh0KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqc3RyaW5nIHMsIGpzaG9ydCBmb250LCBqc2hvcnQgc2l6ZSwganNob3J0IGZhY2UpIHsKLSNpZmRlZiBVU0VfQVRTVUkKLQkKLQlpZiAocyAhPSAgTlVMTCkgewotCQljb25zdCBqY2hhciAqc3M9ICgqZW52KS0+R2V0U3RyaW5nQ2hhcnMoZW52LCBzLCBOVUxMKTsKLQkJaW50IGw9ICgqZW52KS0+R2V0U3RyaW5nTGVuZ3RoKGVudiwgcyk7Ci0JCQotCQlpbml0QVRTVUkoZm9udCwgc2l6ZSwgZmFjZSk7Ci0JCi0JCWlmIChBVFNVU2V0VGV4dFBvaW50ZXJMb2NhdGlvbihmZ1RleHRMYXlvdXQsIChDb25zdFVuaUNoYXJBcnJheVB0cilzcywga0FUU1VGcm9tVGV4dEJlZ2lubmluZywga0FUU1VUb1RleHRFbmQsIGwpICE9IDApCi0JCQlmcHJpbnRmKHN0ZGVyciwgIkFUU1VTZXRUZXh0UG9pbnRlckxvY2F0aW9uOiBlcnJvclxuIik7Ci0JCQotCQlpZiAoQVRTVVNldFJ1blN0eWxlKGZnVGV4dExheW91dCwgZmdTdHlsZSwgKFVuaUNoYXJBcnJheU9mZnNldCkgMCwgKFVuaUNoYXJDb3VudCkgbCkgIT0gMCkKLQkJCWZwcmludGYoc3RkZXJyLCAiQVRTVVNldFJ1blN0eWxlOiBlcnJvclxuIik7CQkKKyNpZm5kZWYgTk9fQWRkRGF0YUJyb3dzZXJJdGVtcworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQWRkRGF0YUJyb3dzZXJJdGVtcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnRBcnJheSBhcmczLCBqaW50IGFyZzQpCit7CisJamludCAqbHBhcmczPU5VTEw7CisJamludCByYzsKIAotCQlpZiAoQVRTVURyYXdUZXh0KGZnVGV4dExheW91dCwga0FUU1VGcm9tVGV4dEJlZ2lubmluZywgIGtBVFNVVG9UZXh0RW5kICwga0FUU1VVc2VHcmFmUG9ydFBlbkxvYywga0FUU1VVc2VHcmFmUG9ydFBlbkxvYykgIT0gMCkKLQkJCWZwcmludGYoc3RkZXJyLCAiQVRTVURyYXdUZXh0OiBlcnJvclxuIik7CisJREVCVUdfQ0FMTCgiQWRkRGF0YUJyb3dzZXJJdGVtc1xuIikKIAotCQkoKmVudiktPlJlbGVhc2VTdHJpbmdDaGFycyhlbnYsIHMsIHNzKTsKLQl9Ci0jZWxzZQorCWlmIChhcmczKSBscGFyZzMgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBOVUxMKTsKKwlyYyA9IChqaW50KUFkZERhdGFCcm93c2VySXRlbXMoKENvbnRyb2xSZWYpYXJnMCwgKERhdGFCcm93c2VySXRlbUlEKWFyZzEsIChVSW50MzIpYXJnMiwgKGNvbnN0IERhdGFCcm93c2VySXRlbUlEICopbHBhcmczLCAoRGF0YUJyb3dzZXJQcm9wZXJ0eUlEKWFyZzQpOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fQWRkRGF0YUJyb3dzZXJJdGVtcyAqLwogCi0JY29uc3QgY2hhciAqc3M9ICgqZW52KS0+R2V0U3RyaW5nVVRGQ2hhcnMoZW52LCBzLCBOVUxMKTsKLQlEcmF3VGV4dChzcywgMCwgKHNob3J0KXN0cmxlbihzcykpOwotCSgqZW52KS0+UmVsZWFzZVN0cmluZ1VURkNoYXJzKGVudiwgcywgc3MpOworI2lmbmRlZiBOT19BZGREYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19BZGREYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEsIGppbnQgYXJnMikKK3sKKwlEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYyBfYXJnMT17MH0sICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQWRkRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtblxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXREYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzY0ZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJcmMgPSAoamludClBZGREYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uKChDb250cm9sUmVmKWFyZzAsIChEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYyAqKWxwYXJnMSwgKERhdGFCcm93c2VyVGFibGVWaWV3Q29sdW1uSW5kZXgpYXJnMik7CisJaWYgKGFyZzEpIHNldERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjRmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fQWRkRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbiAqLworCisjaWZuZGVmIE5PX0FFQ291bnRJdGVtcworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQUVDb3VudEl0ZW1zCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwLCBqaW50QXJyYXkgYXJnMSkKK3sKKwlBRURlc2MgX2FyZzAsICpscGFyZzA9TlVMTDsKKwlqaW50ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQUVDb3VudEl0ZW1zXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldEFFRGVzY0ZpZWxkcyhlbnYsIGFyZzAsICZfYXJnMCk7CisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCXJjID0gKGppbnQpQUVDb3VudEl0ZW1zKChjb25zdCBBRURlc2NMaXN0ICopbHBhcmcwLCAobG9uZyAqKWxwYXJnMSk7CisJaWYgKGFyZzApIHNldEFFRGVzY0ZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7CisJaWYgKGFyZzEpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19BRUNvdW50SXRlbXMgKi8KKworI2lmbmRlZiBOT19BRUdldE50aFB0cgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQUVHZXROdGhQdHIKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50QXJyYXkgYXJnMywgamludEFycmF5IGFyZzQsIGppbnQgYXJnNSwgamludCBhcmc2LCBqaW50QXJyYXkgYXJnNykKK3sKKwlBRURlc2MgX2FyZzAsICpscGFyZzA9TlVMTDsKKwlqaW50ICpscGFyZzM9TlVMTDsKKwlqaW50ICpscGFyZzQ9TlVMTDsKKwlqaW50ICpscGFyZzc9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQUVHZXROdGhQdHJcbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gZ2V0QUVEZXNjRmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJaWYgKGFyZzQpIGxwYXJnNCA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIE5VTEwpOworCWlmIChhcmc3KSBscGFyZzcgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc3LCBOVUxMKTsKKwlyYyA9IChqaW50KUFFR2V0TnRoUHRyKChjb25zdCBBRURlc2NMaXN0ICopbHBhcmcwLCBhcmcxLCAoRGVzY1R5cGUpYXJnMiwgKEFFS2V5d29yZCAqKWxwYXJnMywgKERlc2NUeXBlICopbHBhcmc0LCAodm9pZCAqKWFyZzUsIChTaXplKWFyZzYsIChTaXplICopbHBhcmc3KTsKKwlpZiAoYXJnMCkgc2V0QUVEZXNjRmllbGRzKGVudiwgYXJnMCwgbHBhcmcwKTsKKwlpZiAoYXJnMykgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CisJaWYgKGFyZzQpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBscGFyZzQsIDApOworCWlmIChhcmc3KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNywgbHBhcmc3LCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fQUVHZXROdGhQdHIgKi8KKworI2lmbmRlZiBOT19BRVByb2Nlc3NBcHBsZUV2ZW50CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19BRVByb2Nlc3NBcHBsZUV2ZW50CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwKQoreworCUV2ZW50UmVjb3JkIF9hcmcwLCAqbHBhcmcwPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkFFUHJvY2Vzc0FwcGxlRXZlbnRcbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gZ2V0RXZlbnRSZWNvcmRGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCXJjID0gKGppbnQpQUVQcm9jZXNzQXBwbGVFdmVudCgoY29uc3QgRXZlbnRSZWNvcmQgKilscGFyZzApOworCWlmIChhcmcwKSBzZXRFdmVudFJlY29yZEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0FFUHJvY2Vzc0FwcGxlRXZlbnQgKi8KKworI2lmbmRlZiBOT19BcHBlbmRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0FwcGVuZE1lbnVJdGVtVGV4dFdpdGhDRlN0cmluZworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMywganNob3J0QXJyYXkgYXJnNCkKK3sKKwlqc2hvcnQgKmxwYXJnND1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJBcHBlbmRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmdcbiIpCisKKwlpZiAoYXJnNCkgbHBhcmc0ID0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlyYyA9IChqaW50KUFwcGVuZE1lbnVJdGVtVGV4dFdpdGhDRlN0cmluZygoTWVudVJlZilhcmcwLCAoQ0ZTdHJpbmdSZWYpYXJnMSwgKE1lbnVJdGVtQXR0cmlidXRlcylhcmcyLCAoTWVudUNvbW1hbmQpYXJnMywgKE1lbnVJdGVtSW5kZXggKilscGFyZzQpOworCWlmIChhcmc0KSAoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBscGFyZzQsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19BcHBlbmRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcgKi8KKworI2lmbmRlZiBOT19BVFNVQ3JlYXRlU3R5bGUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgT1NfTkFUSVZFKEFUU1VDcmVhdGVTdHlsZSkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50QXJyYXkgYXJnMCkKK3sKKwlqaW50ICpscGFyZzA9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQVRTVUNyZWF0ZVN0eWxlXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIE5VTEwpOworCXJjID0gKGppbnQpQVRTVUNyZWF0ZVN0eWxlKChBVFNVU3R5bGUgKilscGFyZzApOworCWlmIChhcmcwKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMCwgbHBhcmcwLCAwKTsKKwlyZXR1cm4gcmM7Cit9CiAjZW5kaWYKKworI2lmbmRlZiBOT19BVFNVQ3JlYXRlVGV4dExheW91dAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBPU19OQVRJVkUoQVRTVUNyZWF0ZVRleHRMYXlvdXQpCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludEFycmF5IGFyZzApCit7CisJamludCAqbHBhcmcwPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkFUU1VDcmVhdGVUZXh0TGF5b3V0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIE5VTEwpOworCXJjID0gKGppbnQpQVRTVUNyZWF0ZVRleHRMYXlvdXQoKEFUU1VUZXh0TGF5b3V0ICopbHBhcmcwKTsKKwlpZiAoYXJnMCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIGxwYXJnMCwgMCk7CisJcmV0dXJuIHJjOwogfQotCi1KTklFWFBPUlQganNob3J0IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RleHRXaWR0aChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJanN0cmluZyBzLCBqc2hvcnQgZm9udCwganNob3J0IHNpemUsIGpzaG9ydCBmYWNlKSB7Ci0JanNob3J0IHdpZHRoPSAwOwotCQotI2lmZGVmIFVTRV9BVFNVSQotCWlmIChzICE9ICBOVUxMKSB7Ci0JCUFUU1RyYXBlem9pZCB0cmFwOwotCQlJdGVtQ291bnQgbjsKLQkJY29uc3QgamNoYXIgKnNzPSAoKmVudiktPkdldFN0cmluZ0NoYXJzKGVudiwgcywgTlVMTCk7Ci0JCWludCBsPSAoKmVudiktPkdldFN0cmluZ0xlbmd0aChlbnYsIHMpOwotCQkKLQkJaW5pdEFUU1VJKGZvbnQsIHNpemUsIGZhY2UpOwotCi0JCWlmIChBVFNVU2V0VGV4dFBvaW50ZXJMb2NhdGlvbihmZ1RleHRMYXlvdXQsIChDb25zdFVuaUNoYXJBcnJheVB0cilzcywga0FUU1VGcm9tVGV4dEJlZ2lubmluZywga0FUU1VUb1RleHRFbmQsIGwpICE9IDApCi0JCQlmcHJpbnRmKHN0ZGVyciwgIkFUU1VTZXRUZXh0UG9pbnRlckxvY2F0aW9uOiBlcnJvclxuIik7Ci0JCQotCQlpZiAoQVRTVVNldFJ1blN0eWxlKGZnVGV4dExheW91dCwgZmdTdHlsZSwgKFVuaUNoYXJBcnJheU9mZnNldCkgMCwgKFVuaUNoYXJDb3VudCkgbCkgIT0gMCkKLQkJCWZwcmludGYoc3RkZXJyLCAiQVRTVVNldFJ1blN0eWxlOiBlcnJvclxuIik7CQkKLQkJCi0JCWlmIChBVFNVR2V0R2x5cGhCb3VuZHMoZmdUZXh0TGF5b3V0LCAoQVRTVVRleHRNZWFzdXJlbWVudCkwLCAoQVRTVVRleHRNZWFzdXJlbWVudCkwLAotCQkJCQlrQVRTVUZyb21UZXh0QmVnaW5uaW5nLCBrQVRTVVRvVGV4dEVuZCwga0FUU1VzZURldmljZU9yaWdpbnMsIDEsICZ0cmFwLCAmbikgICE9IDApCi0JCQlmcHJpbnRmKHN0ZGVyciwgIkFUU1VHZXRHbHlwaEJvdW5kczogZXJyb3JcbiIpOwotCQkJCi0JCSgqZW52KS0+UmVsZWFzZVN0cmluZ0NoYXJzKGVudiwgcywgc3MpOwotCi0JCXdpZHRoPSBIaVdvcmQodHJhcC5sb3dlclJpZ2h0LngpOwotCX0KLSNlbHNlCi0JY29uc3QgY2hhciAqc3M9ICgqZW52KS0+R2V0U3RyaW5nVVRGQ2hhcnMoZW52LCBzLCBOVUxMKTsKLQl3aWR0aD0gVGV4dFdpZHRoKHNzLCAwLCAoc2hvcnQpc3RybGVuKHNzKSk7Ci0JKCplbnYpLT5SZWxlYXNlU3RyaW5nVVRGQ2hhcnMoZW52LCBzLCBzcyk7CiAjZW5kaWYKLQlyZXR1cm4gd2lkdGg7CisKKyNpZm5kZWYgTk9fQVRTVURpc3Bvc2VTdHlsZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBPU19OQVRJVkUoQVRTVURpc3Bvc2VTdHlsZSkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiQVRTVURpc3Bvc2VTdHlsZVxuIikKKworCXJldHVybiAoamludClBVFNVRGlzcG9zZVN0eWxlKChBVFNVU3R5bGUpYXJnMCk7CiB9CisjZW5kaWYKKworI2lmbmRlZiBOT19BVFNVRGlzcG9zZVRleHRMYXlvdXQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgT1NfTkFUSVZFKEFUU1VEaXNwb3NlVGV4dExheW91dCkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiQVRTVURpc3Bvc2VUZXh0TGF5b3V0XG4iKQogCi1KTklFWFBPUlQganNob3J0IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NoYXJXaWR0aChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqYnl0ZSBjKSB7Ci0JcmV0dXJuIChqc2hvcnQpIENoYXJXaWR0aChjKTsKKwlyZXR1cm4gKGppbnQpQVRTVURpc3Bvc2VUZXh0TGF5b3V0KChBVFNVVGV4dExheW91dClhcmcwKTsKIH0KKyNlbmRpZgorCisjaWZuZGVmIE5PX0FUU1VEcmF3VGV4dAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBPU19OQVRJVkUoQVRTVURyYXdUZXh0KQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMywgamludCBhcmc0KQoreworCURFQlVHX0NBTEwoIkFUU1VEcmF3VGV4dFxuIikKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Rm9udEluZm8oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0QXJyYXkgaW5mbykgewotICAgIGpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgaW5mbywgMCk7Ci0JR2V0Rm9udEluZm8oKEZvbnRJbmZvKikgc2EpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGluZm8sIHNhLCAwKTsKKwlyZXR1cm4gKGppbnQpQVRTVURyYXdUZXh0KChBVFNVVGV4dExheW91dClhcmcwLCAoVW5pQ2hhckFycmF5T2Zmc2V0KWFyZzEsIChVbmlDaGFyQ291bnQpYXJnMiwgKEFUU1VUZXh0TWVhc3VyZW1lbnQpYXJnMywgKEFUU1VUZXh0TWVhc3VyZW1lbnQpYXJnNCk7CiB9CisjZW5kaWYKKworI2lmbmRlZiBOT19BVFNVR2V0R2x5cGhCb3VuZHMKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgT1NfTkFUSVZFKEFUU1VHZXRHbHlwaEJvdW5kcykKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMsIGppbnQgYXJnNCwganNob3J0IGFyZzUsIGppbnQgYXJnNiwgamludCBhcmc3LCBqaW50QXJyYXkgYXJnOCkKK3sKKwlqaW50ICpscGFyZzg9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQVRTVUdldEdseXBoQm91bmRzXG4iKQogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRGcmFjdEVuYWJsZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqYm9vbGVhbiBlbmFibGUpIHsKLQlTZXRGcmFjdEVuYWJsZShlbmFibGUpOworCWlmIChhcmc4KSBscGFyZzggPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc4LCBOVUxMKTsKKwlyYyA9IChqaW50KUFUU1VHZXRHbHlwaEJvdW5kcygoQVRTVVRleHRMYXlvdXQpYXJnMCwgKEFUU1VUZXh0TWVhc3VyZW1lbnQpYXJnMSwgKEFUU1VUZXh0TWVhc3VyZW1lbnQpYXJnMiwgKFVuaUNoYXJBcnJheU9mZnNldClhcmczLCAoVW5pQ2hhckNvdW50KWFyZzQsIChVSW50MTYpYXJnNSwgKEl0ZW1Db3VudClhcmc2LCAoQVRTVHJhcGV6b2lkICopYXJnNywgKEl0ZW1Db3VudCAqKWxwYXJnOCk7CisJaWYgKGFyZzgpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc4LCBscGFyZzgsIDApOworCXJldHVybiByYzsKIH0KKyNlbmRpZgorCisjaWZuZGVmIE5PX0FUU1VTZXRBdHRyaWJ1dGVzCitKTklFWFBPUlQgamludCBKTklDQUxMIE9TX05BVElWRShBVFNVU2V0QXR0cmlidXRlcykKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludEFycmF5IGFyZzIsIGppbnRBcnJheSBhcmczLCBqaW50QXJyYXkgYXJnNCkKK3sKKwlqaW50ICpscGFyZzI9TlVMTDsKKwlqaW50ICpscGFyZzM9TlVMTDsKKwlqaW50ICpscGFyZzQ9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQVRTVVNldEF0dHJpYnV0ZXNcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1BlblNpemUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0IGgsIGpzaG9ydCB2KSB7Ci0JUGVuU2l6ZShoLCB2KTsKKwlpZiAoYXJnMikgbHBhcmcyID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJaWYgKGFyZzMpIGxwYXJnMyA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIE5VTEwpOworCWlmIChhcmc0KSBscGFyZzQgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlyYyA9IChqaW50KUFUU1VTZXRBdHRyaWJ1dGVzKChBVFNVU3R5bGUpYXJnMCwgKEl0ZW1Db3VudClhcmcxLCAoQVRTVUF0dHJpYnV0ZVRhZyAqKWxwYXJnMiwgKEJ5dGVDb3VudCAqKWxwYXJnMywgKEFUU1VBdHRyaWJ1dGVWYWx1ZVB0ciAqKWxwYXJnNCk7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX01vdmVUbyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqc2hvcnQgaCwganNob3J0IHYpIHsKLQlNb3ZlVG8oaCwgdik7CisjaWZuZGVmIE5PX0FUU1VTZXRMYXlvdXRDb250cm9scworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBPU19OQVRJVkUoQVRTVVNldExheW91dENvbnRyb2xzKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50QXJyYXkgYXJnMiwgamludEFycmF5IGFyZzMsIGppbnRBcnJheSBhcmc0KQoreworCWppbnQgKmxwYXJnMj1OVUxMOworCWppbnQgKmxwYXJnMz1OVUxMOworCWppbnQgKmxwYXJnND1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJBVFNVU2V0TGF5b3V0Q29udHJvbHNcbiIpCisKKwlpZiAoYXJnMikgbHBhcmcyID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJaWYgKGFyZzMpIGxwYXJnMyA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIE5VTEwpOworCWlmIChhcmc0KSBscGFyZzQgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlyYyA9IChqaW50KUFUU1VTZXRMYXlvdXRDb250cm9scygoQVRTVVRleHRMYXlvdXQpYXJnMCwgKEl0ZW1Db3VudClhcmcxLCAoQVRTVUF0dHJpYnV0ZVRhZyAqKWxwYXJnMiwgKEJ5dGVDb3VudCAqKWxwYXJnMywgKEFUU1VBdHRyaWJ1dGVWYWx1ZVB0ciAqKWxwYXJnNCk7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fQVRTVVNldFJ1blN0eWxlCitKTklFWFBPUlQgamludCBKTklDQUxMIE9TX05BVElWRShBVFNVU2V0UnVuU3R5bGUpCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczKQoreworCURFQlVHX0NBTEwoIkFUU1VTZXRSdW5TdHlsZVxuIikKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTGluZVRvKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzaG9ydCBoLCBqc2hvcnQgdikgewotCUxpbmVUbyhoLCB2KTsKKwlyZXR1cm4gKGppbnQpQVRTVVNldFJ1blN0eWxlKChBVFNVVGV4dExheW91dClhcmcwLCAoQVRTVVN0eWxlKWFyZzEsIChVbmlDaGFyQXJyYXlPZmZzZXQpYXJnMiwgKFVuaUNoYXJDb3VudClhcmczKTsKIH0KKyNlbmRpZgogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DbGlwUmVjdChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqc2hvcnRBcnJheSBjbGlwKSB7Ci0gICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBjbGlwLCAwKTsKLQlDbGlwUmVjdCgoUmVjdCopIHNhKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBjbGlwLCBzYSwgMCk7CisjaWZuZGVmIE5PX0FUU1VTZXRUZXh0UG9pbnRlckxvY2F0aW9uCitKTklFWFBPUlQgamludCBKTklDQUxMIE9TX05BVElWRShBVFNVU2V0VGV4dFBvaW50ZXJMb2NhdGlvbikKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMsIGppbnQgYXJnNCkKK3sKKwlERUJVR19DQUxMKCJBVFNVU2V0VGV4dFBvaW50ZXJMb2NhdGlvblxuIikKKworCXJldHVybiAoamludClBVFNVU2V0VGV4dFBvaW50ZXJMb2NhdGlvbigoQVRTVVRleHRMYXlvdXQpYXJnMCwgKENvbnN0VW5pQ2hhckFycmF5UHRyKWFyZzEsIChVbmlDaGFyQXJyYXlPZmZzZXQpYXJnMiwgKFVuaUNoYXJDb3VudClhcmczLCAoVW5pQ2hhckNvdW50KWFyZzQpOwogfQorI2VuZGlmCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1Njcm9sbFJlY3QoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0QXJyYXkgciwganNob3J0IGRoLCBqc2hvcnQgZHYsIGppbnQgcmduKSB7Ci0gICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCByLCAwKTsKLQlTY3JvbGxSZWN0KChSZWN0Kikgc2EsIGRoLCBkdiwgKFJnbkhhbmRsZSkgcmduKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCByLCBzYSwgMCk7CisjaWZuZGVmIE5PX0F1dG9TaXplRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbnMKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0F1dG9TaXplRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbnMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiQXV0b1NpemVEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uc1xuIikKKworCXJldHVybiAoamludClBdXRvU2l6ZURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5zKChDb250cm9sUmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0F1dG9TaXplRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbnMgKi8KKworI2lmbmRlZiBOT19CZWdpblVwZGF0ZQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQmVnaW5VcGRhdGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiQmVnaW5VcGRhdGVcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1FERmx1c2hQb3J0QnVmZmVyKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcG9ydCwgamludCByZ25IYW5kbGUpIHsKLQlRREZsdXNoUG9ydEJ1ZmZlcigoR3JhZlB0cikgcG9ydCwgKFJnbkhhbmRsZSkgcmduSGFuZGxlKTsKKwlCZWdpblVwZGF0ZSgoV2luZG93UmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0JlZ2luVXBkYXRlICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFBvcnRWaXNpYmxlUmVnaW9uKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcEhhbmRsZSwKLQkJCQlqaW50IHJnbkhhbmRsZSkgewotCXJldHVybiAoamludCkgR2V0UG9ydFZpc2libGVSZWdpb24oKENHcmFmUHRyKSBwSGFuZGxlLCAoUmduSGFuZGxlKSByZ25IYW5kbGUpOworI2lmbmRlZiBOT19CcmluZ1RvRnJvbnQKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0JyaW5nVG9Gcm9udAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJCcmluZ1RvRnJvbnRcbiIpCisKKwlCcmluZ1RvRnJvbnQoKFdpbmRvd1JlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19CcmluZ1RvRnJvbnQgKi8KKworI2lmbmRlZiBOT19DRlJlbGVhc2UKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NGUmVsZWFzZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJDRlJlbGVhc2VcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldFBvcnRWaXNpYmxlUmVnaW9uKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcEhhbmRsZSwKLQkJCQlqaW50IHJnbkhhbmRsZSkgewotCVNldFBvcnRWaXNpYmxlUmVnaW9uKChDR3JhZlB0cikgcEhhbmRsZSwgKFJnbkhhbmRsZSkgcmduSGFuZGxlKTsKKwlDRlJlbGVhc2UoKENGVHlwZVJlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19DRlJlbGVhc2UgKi8KKworI2lmbmRlZiBOT19DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqY2hhckFycmF5IGFyZzEsIGppbnQgYXJnMikKK3sKKwlqY2hhciAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnNcbiIpCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1FER2V0RGlydHlSZWdpb24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBwSGFuZGxlLAotCQkJCWppbnQgcmduSGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBSQyhRREdldERpcnR5UmVnaW9uKChDR3JhZlB0cikgcEhhbmRsZSwgKFJnbkhhbmRsZSkgcmduSGFuZGxlKSk7CisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0Q2hhckFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBOVUxMKTsKKwlyYyA9IChqaW50KUNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMoKENGQWxsb2NhdG9yUmVmKWFyZzAsIChjb25zdCBVbmlDaGFyICopbHBhcmcxLCAoQ0ZJbmRleClhcmcyKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlQ2hhckFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOworCXJldHVybiByYzsKIH0KKyNlbmRpZiAvKiBOT19DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1FEU2V0RGlydHlSZWdpb24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBwSGFuZGxlLAotCQkJCWppbnQgcmduSGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBSQyhRRFNldERpcnR5UmVnaW9uKChDR3JhZlB0cikgcEhhbmRsZSwgKFJnbkhhbmRsZSkgcmduSGFuZGxlKSk7CisjaWZuZGVmIE5PX0NGU3RyaW5nR2V0Qnl0ZXMKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NGU3RyaW5nR2V0Qnl0ZXMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyLCBqYnl0ZSBhcmczLCBqYm9vbGVhbiBhcmc0LCBqYnl0ZUFycmF5IGFyZzUsIGppbnQgYXJnNiwgamludEFycmF5IGFyZzcpCit7CisJQ0ZSYW5nZSBfYXJnMSwgKmxwYXJnMT1OVUxMOworCWpieXRlICpscGFyZzU9TlVMTDsKKwlqaW50ICpscGFyZzc9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQ0ZTdHJpbmdHZXRCeXRlc1xuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRDRlJhbmdlRmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlpZiAoYXJnNSkgbHBhcmc1ID0gKCplbnYpLT5HZXRCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIE5VTEwpOworCWlmIChhcmc3KSBscGFyZzcgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc3LCBOVUxMKTsKKwlyYyA9IChqaW50KUNGU3RyaW5nR2V0Qnl0ZXMoKENGU3RyaW5nUmVmKWFyZzAsIChDRlJhbmdlKSpscGFyZzEsIChDRlN0cmluZ0VuY29kaW5nKWFyZzIsIChVSW50OClhcmczLCAoQm9vbGVhbilhcmc0LCAoVUludDggKilscGFyZzUsIChDRkluZGV4KWFyZzYsIChDRkluZGV4ICopbHBhcmc3KTsKKwlpZiAoYXJnMSkgc2V0Q0ZSYW5nZUZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJaWYgKGFyZzUpICgqZW52KS0+UmVsZWFzZUJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlpZiAoYXJnNykgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzcsIGxwYXJnNywgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fQ0ZTdHJpbmdDcmVhdGVXaXRoQnl0ZXMKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NGU3RyaW5nQ3JlYXRlV2l0aEJ5dGVzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqYnl0ZUFycmF5IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqYm9vbGVhbiBhcmc0KQoreworCWpieXRlICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQ0ZTdHJpbmdDcmVhdGVXaXRoQnl0ZXNcbiIpCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0xvY2tQb3J0Qml0cyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHBIYW5kbGUpIHsKLQlyZXR1cm4gKGppbnQpIFJDKExvY2tQb3J0Qml0cygoR3JhZlB0cikgcEhhbmRsZSkpOworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJcmMgPSAoamludClDRlN0cmluZ0NyZWF0ZVdpdGhCeXRlcygoQ0ZBbGxvY2F0b3JSZWYpYXJnMCwgKGNvbnN0IFVJbnQ4ICopbHBhcmcxLCAoQ0ZJbmRleClhcmcyLCAoQ0ZTdHJpbmdFbmNvZGluZylhcmczLCAoQm9vbGVhbilhcmc0KTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOworCXJldHVybiByYzsKIH0KKyNlbmRpZgorCisjaWZuZGVmIE5PX0NGU3RyaW5nR2V0Q2hhcmFjdGVycworSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0ZTdHJpbmdHZXRDaGFyYWN0ZXJzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEsIGpjaGFyQXJyYXkgYXJnMikKK3sKKwlDRlJhbmdlIF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamNoYXIgKmxwYXJnMj1OVUxMOworCisJREVCVUdfQ0FMTCgiQ0ZTdHJpbmdHZXRDaGFyYWN0ZXJzXG4iKQogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19VbmxvY2tQb3J0Qml0cyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHBIYW5kbGUpIHsKLQlyZXR1cm4gKGppbnQpIFJDKFVubG9ja1BvcnRCaXRzKChHcmFmUHRyKSBwSGFuZGxlKSk7CisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldENGUmFuZ2VGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldENoYXJBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJQ0ZTdHJpbmdHZXRDaGFyYWN0ZXJzKChDRlN0cmluZ1JlZilhcmcwLCAoQ0ZSYW5nZSkqbHBhcmcxLCAoVW5pQ2hhciAqKWxwYXJnMik7CisJaWYgKGFyZzEpIHNldENGUmFuZ2VGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmcyKSAoKmVudiktPlJlbGVhc2VDaGFyQXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CiB9CisjZW5kaWYgLyogTk9fQ0ZTdHJpbmdHZXRDaGFyYWN0ZXJzICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1JHQkZvcmVDb2xvcihKTklFbnYgKmVuYywgamNsYXNzIHp6LCBqc2hvcnQgcmVkLCBqc2hvcnQgZ3JlZW4sIGpzaG9ydCBibHVlKSB7Ci0Jc3RydWN0IFJHQkNvbG9yIGM7Ci0JYy5yZWQ9IHJlZDsKLQljLmdyZWVuPSBncmVlbjsKLQljLmJsdWU9IGJsdWU7Ci0JUkdCRm9yZUNvbG9yKCZjKTsKKyNpZm5kZWYgTk9fQ0ZTdHJpbmdHZXRMZW5ndGgKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NGU3RyaW5nR2V0TGVuZ3RoCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkNGU3RyaW5nR2V0TGVuZ3RoXG4iKQorCisJcmV0dXJuIChqaW50KUNGU3RyaW5nR2V0TGVuZ3RoKChDRlN0cmluZ1JlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19DRlN0cmluZ0dldExlbmd0aCAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SR0JCYWNrQ29sb3IoSk5JRW52ICplbmMsIGpjbGFzcyB6eiwganNob3J0IHJlZCwganNob3J0IGdyZWVuLCBqc2hvcnQgYmx1ZSkgewotCXN0cnVjdCBSR0JDb2xvciBjOwotCWMucmVkPSByZWQ7Ci0JYy5ncmVlbj0gZ3JlZW47Ci0JYy5ibHVlPSBibHVlOwotCVJHQkJhY2tDb2xvcigmYyk7CisjaWZuZGVmIE5PX0NGU3RyaW5nR2V0U3lzdGVtRW5jb2RpbmcKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NGU3RyaW5nR2V0U3lzdGVtRW5jb2RpbmcKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0KQoreworCURFQlVHX0NBTEwoIkNGU3RyaW5nR2V0U3lzdGVtRW5jb2RpbmdcbiIpCisKKwlyZXR1cm4gKGppbnQpQ0ZTdHJpbmdHZXRTeXN0ZW1FbmNvZGluZygpOwogfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fQ0ZVUkxDb3B5RmlsZVN5c3RlbVBhdGgKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NGVVJMQ29weUZpbGVTeXN0ZW1QYXRoCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiQ0ZVUkxDb3B5RmlsZVN5c3RlbVBhdGhcbiIpCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFdpbmRvd0Zyb21Qb3J0KEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcEhhbmRsZSkgewotCXJldHVybiAoamludCkgR2V0V2luZG93RnJvbVBvcnQoKEdyYWZQdHIpcEhhbmRsZSk7CisJcmV0dXJuIChqaW50KUNGVVJMQ29weUZpbGVTeXN0ZW1QYXRoKChDRlVSTFJlZilhcmcwLCAoQ0ZVUkxQYXRoU3R5bGUpYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fQ0ZVUkxDb3B5RmlsZVN5c3RlbVBhdGggKi8KKworI2lmbmRlZiBOT19DRlVSTENvcHlMYXN0UGF0aENvbXBvbmVudAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0ZVUkxDb3B5TGFzdFBhdGhDb21wb25lbnQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiQ0ZVUkxDb3B5TGFzdFBhdGhDb21wb25lbnRcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0ludmVydFJlY3QoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0IHgsIGpzaG9ydCB5LCBqc2hvcnQgdywganNob3J0IGgpIHsKLQlSZWN0IHI7Ci0JU2V0UmVjdCgmciwgeCwgeSwgeCt3LCB5K2gpOwotCUludmVydFJlY3QoJnIpOworCXJldHVybiAoamludClDRlVSTENvcHlMYXN0UGF0aENvbXBvbmVudCgoQ0ZVUkxSZWYpYXJnMCk7CiB9CisjZW5kaWYKIAotLy8tLS0tIFJlZ2lvbnMKKyNpZm5kZWYgTk9fQ0ZVUkxDcmVhdGVDb3B5QXBwZW5kaW5nUGF0aENvbXBvbmVudAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0ZVUkxDcmVhdGVDb3B5QXBwZW5kaW5nUGF0aENvbXBvbmVudAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGpib29sZWFuIGFyZzMpCit7CisJREVCVUdfQ0FMTCgiQ0ZVUkxDcmVhdGVDb3B5QXBwZW5kaW5nUGF0aENvbXBvbmVudFxuIikKIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmV3UmduKEpOSUVudiAqZW52LCBqY2xhc3MgenopIHsKLQlyZXR1cm4gKGppbnQpIE5ld1JnbigpOworCXJldHVybiAoamludClDRlVSTENyZWF0ZUNvcHlBcHBlbmRpbmdQYXRoQ29tcG9uZW50KChDRkFsbG9jYXRvclJlZilhcmcwLCAoQ0ZVUkxSZWYpYXJnMSwgKENGU3RyaW5nUmVmKWFyZzIsIChCb29sZWFuKWFyZzMpOwogfQorI2VuZGlmCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldEVtcHR5UmduKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcmduSGFuZGxlKSB7Ci0JU2V0RW1wdHlSZ24oKFJnbkhhbmRsZSlyZ25IYW5kbGUpOworI2lmbmRlZiBOT19DRlVSTENyZWF0ZUNvcHlEZWxldGluZ0xhc3RQYXRoQ29tcG9uZW50CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DRlVSTENyZWF0ZUNvcHlEZWxldGluZ0xhc3RQYXRoQ29tcG9uZW50CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiQ0ZVUkxDcmVhdGVDb3B5RGVsZXRpbmdMYXN0UGF0aENvbXBvbmVudFxuIikKKworCXJldHVybiAoamludClDRlVSTENyZWF0ZUNvcHlEZWxldGluZ0xhc3RQYXRoQ29tcG9uZW50KChDRkFsbG9jYXRvclJlZilhcmcwLCAoQ0ZVUkxSZWYpYXJnMSk7CiB9CisjZW5kaWYKKworI2lmbmRlZiBOT19DRlVSTENyZWF0ZUZyb21GU1JlZgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0ZVUkxDcmVhdGVGcm9tRlNSZWYKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpieXRlQXJyYXkgYXJnMSkKK3sKKwlqYnl0ZSAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNGVVJMQ3JlYXRlRnJvbUZTUmVmXG4iKQogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SZWN0UmduKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcmduSGFuZGxlLCBqc2hvcnRBcnJheSByZWN0KSB7Ci0gICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCByZWN0LCAwKTsKLQlSZWN0UmduKChSZ25IYW5kbGUpIHJnbkhhbmRsZSwgKFJlY3QqKSBzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgcmVjdCwgc2EsIDApOworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJcmMgPSAoamludClDRlVSTENyZWF0ZUZyb21GU1JlZigoQ0ZBbGxvY2F0b3JSZWYpYXJnMCwgKGNvbnN0IHN0cnVjdCBGU1JlZiAqKWxwYXJnMSk7CisJaWYgKGFyZzEpICgqZW52KS0+UmVsZWFzZUJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fQ0ZVUkxDcmVhdGVGcm9tRlNSZWYgKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0UmVnaW9uQm91bmRzKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcmduSGFuZGxlLAotCQkJCWpzaG9ydEFycmF5IGJvdW5kcykgewotICAgIGpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCAwKTsKLQlHZXRSZWdpb25Cb3VuZHMoKFJnbkhhbmRsZSkgcmduSGFuZGxlLCAoUmVjdCopIHNhKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIHNhLCAwKTsKKyNpZm5kZWYgTk9fQ0dCaXRtYXBDb250ZXh0Q3JlYXRlCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0JpdG1hcENvbnRleHRDcmVhdGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMsIGppbnQgYXJnNCwgamludCBhcmc1LCBqaW50IGFyZzYpCit7CisJREVCVUdfQ0FMTCgiQ0dCaXRtYXBDb250ZXh0Q3JlYXRlXG4iKQorCisJcmV0dXJuIChqaW50KUNHQml0bWFwQ29udGV4dENyZWF0ZSgodm9pZCAqKWFyZzAsIChzaXplX3QpYXJnMSwgKHNpemVfdClhcmcyLCAoc2l6ZV90KWFyZzMsIChzaXplX3QpYXJnNCwgKENHQ29sb3JTcGFjZVJlZilhcmc1LCAoQ0dJbWFnZUFscGhhSW5mbylhcmc2KTsKIH0KKyNlbmRpZiAvKiBOT19DR0JpdG1hcENvbnRleHRDcmVhdGUgKi8KKworI2lmbmRlZiBOT19DR0NvbG9yU3BhY2VDcmVhdGVEZXZpY2VSR0IKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29sb3JTcGFjZUNyZWF0ZURldmljZVJHQgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiQ0dDb2xvclNwYWNlQ3JlYXRlRGV2aWNlUkdCXG4iKQogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRSZWN0UmduKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcmduSGFuZGxlLAotCQlqc2hvcnQgbGVmdCwganNob3J0IHRvcCwganNob3J0IHJpZ2h0LCBqc2hvcnQgYm90dG9tKSB7Ci0JU2V0UmVjdFJnbigoUmduSGFuZGxlKXJnbkhhbmRsZSwgbGVmdCwgdG9wLCByaWdodCwgYm90dG9tKTsKKwlyZXR1cm4gKGppbnQpQ0dDb2xvclNwYWNlQ3JlYXRlRGV2aWNlUkdCKCk7CiB9CisjZW5kaWYgLyogTk9fQ0dDb2xvclNwYWNlQ3JlYXRlRGV2aWNlUkdCICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NlY3RSZ24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCByYSwgamludCByYiwgamludCBkZXN0KSB7Ci0JU2VjdFJnbigoUmduSGFuZGxlKSByYSwgKFJnbkhhbmRsZSkgcmIsIChSZ25IYW5kbGUpIGRlc3QpOworI2lmbmRlZiBOT19DR0NvbG9yU3BhY2VSZWxlYXNlCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbG9yU3BhY2VSZWxlYXNlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkNHQ29sb3JTcGFjZVJlbGVhc2VcbiIpCisKKwlDR0NvbG9yU3BhY2VSZWxlYXNlKChDR0NvbG9yU3BhY2VSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fQ0dDb2xvclNwYWNlUmVsZWFzZSAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19VbmlvblJnbihKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHJhLCBqaW50IHJiLCBqaW50IGRlc3QpIHsKLQlVbmlvblJnbigoUmduSGFuZGxlKSByYSwgKFJnbkhhbmRsZSkgcmIsIChSZ25IYW5kbGUpIGRlc3QpOworI2lmbmRlZiBOT19DR0NvbnRleHRBZGRBcmMKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dEFkZEFyYworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamZsb2F0IGFyZzEsIGpmbG9hdCBhcmcyLCBqZmxvYXQgYXJnMywgamZsb2F0IGFyZzQsIGpmbG9hdCBhcmc1LCBqYm9vbGVhbiBhcmc2KQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dEFkZEFyY1xuIikKKworCUNHQ29udGV4dEFkZEFyYygoQ0dDb250ZXh0UmVmKWFyZzAsIChmbG9hdClhcmcxLCAoZmxvYXQpYXJnMiwgKGZsb2F0KWFyZzMsIChmbG9hdClhcmc0LCAoZmxvYXQpYXJnNSwgKEJvb2xlYW4pYXJnNik7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0QWRkQXJjICovCisKKyNpZm5kZWYgTk9fQ0dDb250ZXh0QWRkQXJjVG9Qb2ludAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0QWRkQXJjVG9Qb2ludAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamZsb2F0IGFyZzEsIGpmbG9hdCBhcmcyLCBqZmxvYXQgYXJnMywgamZsb2F0IGFyZzQsIGpmbG9hdCBhcmc1KQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dEFkZEFyY1RvUG9pbnRcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0RpZmZSZ24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCByYSwgamludCByYiwgamludCBkZXN0KSB7Ci0JRGlmZlJnbigoUmduSGFuZGxlKSByYSwgKFJnbkhhbmRsZSkgcmIsIChSZ25IYW5kbGUpIGRlc3QpOworCUNHQ29udGV4dEFkZEFyY1RvUG9pbnQoKENHQ29udGV4dFJlZilhcmcwLCAoZmxvYXQpYXJnMSwgKGZsb2F0KWFyZzIsIChmbG9hdClhcmczLCAoZmxvYXQpYXJnNCwgKGZsb2F0KWFyZzUpOwogfQorI2VuZGlmIC8qIE5PX0NHQ29udGV4dEFkZEFyYyAqLwogCi1KTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUHRJblJnbihKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqc2hvcnRBcnJheSBwdCwgamludCByZ25IYW5kbGUpIHsKLQlyZXR1cm4gKGpib29sZWFuKSBQdEluUmduKHBvaW50KGVudiwgcHQpLCAoUmduSGFuZGxlKSByZ25IYW5kbGUpOworI2lmbmRlZiBOT19DR0NvbnRleHRBZGRMaW5lVG9Qb2ludAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0QWRkTGluZVRvUG9pbnQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpmbG9hdCBhcmcxLCBqZmxvYXQgYXJnMikKK3sKKwlERUJVR19DQUxMKCJDR0NvbnRleHRBZGRMaW5lVG9Qb2ludFxuIikKKworCUNHQ29udGV4dEFkZExpbmVUb1BvaW50KChDR0NvbnRleHRSZWYpYXJnMCwgYXJnMSwgYXJnMik7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0QWRkTGluZVRvUG9pbnQgKi8KKworI2lmbmRlZiBOT19DR0NvbnRleHRBZGRMaW5lcworSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0QWRkTGluZXMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyKQoreworCWpmbG9hdCAqbHBhcmcxPU5VTEw7CiAKLUpOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SZWN0SW5SZ24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0QXJyYXkgcmVjdCwgamludCByZ25IYW5kbGUpIHsKLSAgICBqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHJlY3QsIDApOwotCWpib29sZWFuIHN0YXR1cz0gKGpib29sZWFuKSBSZWN0SW5SZ24oKHN0cnVjdCBSZWN0KilzYSwgKFJnbkhhbmRsZSkgcmduSGFuZGxlKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCByZWN0LCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0JCisJREVCVUdfQ0FMTCgiQ0dDb250ZXh0QWRkTGluZXNcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NvcHlSZ24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBzcmMsIGppbnQgZGVzdCkgewotCUNvcHlSZ24oKFJnbkhhbmRsZSkgc3JjLCAoUmduSGFuZGxlKSBkZXN0KTsKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRGbG9hdEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBOVUxMKTsKKwlDR0NvbnRleHRBZGRMaW5lcygoQ0dDb250ZXh0UmVmKWFyZzAsIChjb25zdCBDR1BvaW50ICopbHBhcmcxLCAoc2l6ZV90KWFyZzIpOworCWlmIChhcmcxKSAoKmVudiktPlJlbGVhc2VGbG9hdEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOwogfQotCQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q2xpcChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHJnbkhhbmRsZSkgewotCUdldENsaXAoKFJnbkhhbmRsZSlyZ25IYW5kbGUpOwotfQorI2VuZGlmIC8qIE5PX0NHQ29udGV4dEFkZExpbmVzICovCisKKyNpZm5kZWYgTk9fQ0dDb250ZXh0QmVnaW5QYXRoCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRCZWdpblBhdGgKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiQ0dDb250ZXh0QmVnaW5QYXRoXG4iKQogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDbGlwKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcmduSGFuZGxlKSB7Ci0JU2V0Q2xpcCgoUmduSGFuZGxlKXJnbkhhbmRsZSk7CisJQ0dDb250ZXh0QmVnaW5QYXRoKChDR0NvbnRleHRSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0QmVnaW5QYXRoICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFBvcnRDbGlwUmVnaW9uKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCWppbnQgcG9ydCwgamludCByZ25IYW5kbGUpIHsKLQlHZXRQb3J0Q2xpcFJlZ2lvbigoQ0dyYWZQdHIpcG9ydCwgKFJnbkhhbmRsZSlyZ25IYW5kbGUpOwotfQorI2lmbmRlZiBOT19DR0NvbnRleHRDbGlwCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRDbGlwCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dENsaXBcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldE9yaWdpbihKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqc2hvcnQgaCwganNob3J0IHYpIHsKLQlTZXRPcmlnaW4oaCwgdik7CisJQ0dDb250ZXh0Q2xpcCgoQ0dDb250ZXh0UmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0NHQ29udGV4dENsaXAgKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGlzcG9zZVJnbihKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHJnbkhhbmRsZSkgewotCURpc3Bvc2VSZ24oKFJnbkhhbmRsZSlyZ25IYW5kbGUpOwotfQorI2lmbmRlZiBOT19DR0NvbnRleHRDbG9zZVBhdGgKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dENsb3NlUGF0aAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJDR0NvbnRleHRDbG9zZVBhdGhcbiIpCiAKLUpOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19FbXB0eVJnbihKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHJnbkhhbmRsZSkgewotCXJldHVybiAoamJvb2xlYW4pIEVtcHR5UmduKChSZ25IYW5kbGUpcmduSGFuZGxlKTsKKwlDR0NvbnRleHRDbG9zZVBhdGgoKENHQ29udGV4dFJlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRDbG9zZVBhdGggKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfT2Zmc2V0UmduKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCByZ25IYW5kbGUsIGpzaG9ydCBkaCwganNob3J0IGR2KSB7Ci0JT2Zmc2V0UmduKChSZ25IYW5kbGUpcmduSGFuZGxlLCBkaCwgZHYpOwotfQorI2lmbmRlZiBOT19DR0NvbnRleHREcmF3SW1hZ2UKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dERyYXdJbWFnZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxLCBqaW50IGFyZzIpCit7CisJQ0dSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0VyYXNlUmduKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcmduSGFuZGxlKSB7Ci0JRXJhc2VSZ24oKFJnbkhhbmRsZSkgcmduSGFuZGxlKTsKLX0KKwlERUJVR19DQUxMKCJDR0NvbnRleHREcmF3SW1hZ2VcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0ludmVydFJnbihKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHJnbkhhbmRsZSkgewotCUludmVydFJnbigoUmduSGFuZGxlKSByZ25IYW5kbGUpOworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRDR1JlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCUNHQ29udGV4dERyYXdJbWFnZSgoQ0dDb250ZXh0UmVmKWFyZzAsIChDR1JlY3QpKmxwYXJnMSwgKENHSW1hZ2VSZWYpYXJnMik7CisJaWYgKGFyZzEpIHNldENHUmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0RHJhd0ltYWdlICovCiAKLS8vLS0tLSBQb2x5Z29ucworI2lmbmRlZiBOT19DR0NvbnRleHRGaWxsUGF0aAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0RmlsbFBhdGgKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiQ0dDb250ZXh0RmlsbFBhdGhcbiIpCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX09wZW5Qb2x5KEpOSUVudiAqZW52LCBqY2xhc3MgenopIHsKLQlyZXR1cm4gKGppbnQpIE9wZW5Qb2x5KCk7CisJQ0dDb250ZXh0RmlsbFBhdGgoKENHQ29udGV4dFJlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRGaWxsUGF0aCAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DbG9zZVBvbHkoSk5JRW52ICplbnYsIGpjbGFzcyB6eikgewotCUNsb3NlUG9seSgpOwotfQorI2lmbmRlZiBOT19DR0NvbnRleHRGaWxsUmVjdAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0RmlsbFJlY3QKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlDR1JlY3QgX2FyZzEsICpscGFyZzE9TlVMTDsKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfT2Zmc2V0UG9seShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHBvbHlIYW5kbGUsIGpzaG9ydCBkeCwganNob3J0IGR5KSB7Ci0JT2Zmc2V0UG9seSgoUG9seVB0ciAqKXBvbHlIYW5kbGUsIGR4LCBkeSk7Ci19CisJREVCVUdfQ0FMTCgiQ0dDb250ZXh0RmlsbFJlY3RcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0ZyYW1lUG9seShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHBvbHlIYW5kbGUpIHsKLQlGcmFtZVBvbHkoKFBvbHlQdHIgKilwb2x5SGFuZGxlKTsKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0Q0dSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlDR0NvbnRleHRGaWxsUmVjdCgoQ0dDb250ZXh0UmVmKWFyZzAsIChDR1JlY3QpKmxwYXJnMSk7CisJaWYgKGFyZzEpIHNldENHUmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0RmlsbFJlY3QgKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUGFpbnRQb2x5KEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcG9seUhhbmRsZSkgewotCVBhaW50UG9seSgoUG9seVB0ciAqKXBvbHlIYW5kbGUpOwotfQorI2lmbmRlZiBOT19DR0NvbnRleHRGbHVzaAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0Rmx1c2gKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpmbG9hdCBhcmcxLCBqZmxvYXQgYXJnMikKK3sKKwlERUJVR19DQUxMKCJDR0NvbnRleHRGbHVzaFxuIikKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfS2lsbFBvbHkoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBwb2x5SGFuZGxlKSB7Ci0JS2lsbFBvbHkoKFBvbHlQdHIgKilwb2x5SGFuZGxlKTsKKwlDR0NvbnRleHRGbHVzaCgoQ0dDb250ZXh0UmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0NHQ29udGV4dEZsdXNoICovCiAKLS8vLS0tLSBCaXRNYXAgJiBQaXhNYXAKKyNpZm5kZWYgTk9fQ0dDb250ZXh0R2V0VGV4dFBvc2l0aW9uCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRHZXRUZXh0UG9zaXRpb24KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlDR1BvaW50IF9hcmcxLCAqbHBhcmcxPU5VTEw7CiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05ld1BpeE1hcChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJanNob3J0IHdpZHRoLCBqc2hvcnQgaGVpZ2h0LCBqc2hvcnQgcm93Ynl0ZXMsCi0JCQlqc2hvcnQgcGl4ZWxUeXBlLCBqc2hvcnQgcGl4ZWxTaXplLCBqc2hvcnQgY21wU2l6ZSwganNob3J0IGNtcENvdW50LCBqc2hvcnQgcGl4ZWxGb3JtYXQpIHsKLQkJCQotCVBpeE1hcEhhbmRsZSBwbWg9IE5ld1BpeE1hcCgpOwotCVBpeE1hcCAqcG09ICpwbWg7Ci0JCi0JcG0tPmJhc2VBZGRyPSBOVUxMOwotCXBtLT5yb3dCeXRlcz0gcm93Ynl0ZXMgfCAweDgwMDA7CS8vIG1hcmsgYXMgUGl4TWFwCi0JcG0tPmJvdW5kcy50b3A9IDA7Ci0JcG0tPmJvdW5kcy5sZWZ0PSAwOwotCXBtLT5ib3VuZHMuYm90dG9tPSBoZWlnaHQ7Ci0JcG0tPmJvdW5kcy5yaWdodD0gd2lkdGg7Ci0JcG0tPnBtVmVyc2lvbj0gYmFzZUFkZHIzMjsJLy8gMzIgQml0IGNsZWFuCi0JcG0tPnBhY2tUeXBlPSAwOwotCXBtLT5wYWNrU2l6ZT0gMDsKLQlwbS0+aFJlcz0gMHgwMDQ4MDAwMDsKLQlwbS0+dlJlcz0gMHgwMDQ4MDAwMDsKLQlwbS0+cGl4ZWxUeXBlPSBwaXhlbFR5cGU7Ci0JcG0tPnBpeGVsU2l6ZT0gcGl4ZWxTaXplOwotCXBtLT5jbXBDb3VudD0gY21wQ291bnQ7Ci0JcG0tPmNtcFNpemU9IGNtcFNpemU7Ci0JcG0tPnBpeGVsRm9ybWF0PSBwaXhlbEZvcm1hdDsKLQlwbS0+cG1UYWJsZT0gTlVMTDsKLQlwbS0+cG1FeHQ9IE5VTEw7CisJREVCVUdfQ0FMTCgiQ0dDb250ZXh0R2V0VGV4dFBvc2l0aW9uXG4iKQogCi0JcmV0dXJuIChqaW50KSBwbWg7CisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldENHUG9pbnRGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCSpscGFyZzEgPSBDR0NvbnRleHRHZXRUZXh0UG9zaXRpb24oKENHQ29udGV4dFJlZilhcmcwKTsKKwlpZiAoYXJnMSkgc2V0Q0dQb2ludEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0R2V0VGV4dFBvc2l0aW9uICovCisKKyNpZm5kZWYgTk9fQ0dDb250ZXh0TW92ZVRvUG9pbnQKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dE1vdmVUb1BvaW50CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqZmxvYXQgYXJnMSwgamZsb2F0IGFyZzIpCit7CisJREVCVUdfQ0FMTCgiQ0dDb250ZXh0TW92ZVRvUG9pbnRcbiIpCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX2dldFJvd0J5dGVzKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcEhhbmRsZSkgewotCUJpdE1hcCAqKmJtaD0gKEJpdE1hcCoqKSBwSGFuZGxlOwotCXJldHVybiAoamludCkgKCpibWgpLT5yb3dCeXRlczsKKwlDR0NvbnRleHRNb3ZlVG9Qb2ludCgoQ0dDb250ZXh0UmVmKWFyZzAsIChmbG9hdClhcmcxLCAoZmxvYXQpYXJnMik7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0TW92ZVRvUG9pbnQgKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1Nfc2V0Um93Qnl0ZXMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IHBIYW5kbGUsIGpzaG9ydCByb3dCeXRlcykgewotCUJpdE1hcCAqKmJtaD0gKEJpdE1hcCoqKSBwSGFuZGxlOwotCSgqYm1oKS0+cm93Qnl0ZXM9IHJvd0J5dGVzOwotfQorI2lmbmRlZiBOT19DR0NvbnRleHRSZWxlYXNlCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRSZWxlYXNlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dFJlbGVhc2VcbiIpCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX2dldEJhc2VBZGRyKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcEhhbmRsZSkgewotCS8qCi0JQml0TWFwICoqYm1oPSAoQml0TWFwKiopIHBIYW5kbGU7Ci0JcmV0dXJuIChqaW50KSAoKmJtaCktPmJhc2VBZGRyOwotCSovCi0JcmV0dXJuIChqaW50KSBHZXRQaXhCYXNlQWRkcigoUGl4TWFwSGFuZGxlKXBIYW5kbGUpOworCUNHQ29udGV4dFJlbGVhc2UoKENHQ29udGV4dFJlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRSZWxlYXNlICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX2dldENvbG9yVGFibGVTaXplKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCWppbnQgcGl4TWFwSGFuZGxlKSB7Ci0JUGl4TWFwSGFuZGxlIHNyY2g9IChQaXhNYXBIYW5kbGUpIHBpeE1hcEhhbmRsZTsKLQlQaXhNYXAgKnNyYz0gKnNyY2g7Ci0JaWYgKHNyYy0+cG1UYWJsZSAhPSBOVUxMKSB7Ci0JCUNvbG9yVGFibGUgKmN0PSAqc3JjLT5wbVRhYmxlOwotCQlyZXR1cm4gY3QtPmN0U2l6ZSArIDE7Ci0JfQotCXJldHVybiAtMTsKKyNpZm5kZWYgTk9fQ0dDb250ZXh0UmVzdG9yZUdTdGF0ZQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0UmVzdG9yZUdTdGF0ZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJDR0NvbnRleHRSZXN0b3JlR1N0YXRlXG4iKQorCisJQ0dDb250ZXh0UmVzdG9yZUdTdGF0ZSgoQ0dDb250ZXh0UmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0NHQ29udGV4dFJlc3RvcmVHU3RhdGUgKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfZ2V0Q29sb3JUYWJsZShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBwaXhNYXBIYW5kbGUsIGpzaG9ydEFycmF5IGNvbG9yc3BlYykgewotCVBpeE1hcEhhbmRsZSBzcmNoPSAoUGl4TWFwSGFuZGxlKSBwaXhNYXBIYW5kbGU7Ci0JUGl4TWFwICpzcmM9ICpzcmNoOwotCWludCBuPSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgY29sb3JzcGVjKSAvIDQ7Ci0JaWYgKHNyYy0+cG1UYWJsZSAhPSBOVUxMKSB7Ci0JCUNvbG9yVGFibGUgKmN0PSAqc3JjLT5wbVRhYmxlOwotCQlqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGNvbG9yc3BlYywgMCk7Ci0JCW1lbWNweShzYSwgY3QtPmN0VGFibGUsIG4gKiBzaXplb2YoQ29sb3JTcGVjKSk7Ci0JCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGNvbG9yc3BlYywgc2EsIDApOwotCX0KLX0KLQkJCQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1Nfc2V0Q29sb3JUYWJsZShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBwaXhNYXBIYW5kbGUsIGpzaG9ydEFycmF5IGNvbG9yc3BlYykgewotCQkJCQotCVBpeE1hcEhhbmRsZSBwaD0gKFBpeE1hcEhhbmRsZSkgcGl4TWFwSGFuZGxlOwotCVBpeE1hcCAqcG09ICpwaDsKLQlDb2xvclRhYmxlICpjdDsKLQlqc2hvcnQgKnNhOwotCWludCBuPSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgY29sb3JzcGVjKSAvIDQ7Ci0JCi0JaWYgKHBtLT5wbVRhYmxlICE9IE5VTEwpCi0JCURpc3Bvc2VIYW5kbGUoKEhhbmRsZSlwbS0+cG1UYWJsZSk7Ci0JcG0tPnBtVGFibGU9IChDb2xvclRhYmxlKiopIE5ld0hhbmRsZShzaXplb2YoQ29sb3JUYWJsZSkrc2l6ZW9mKENvbG9yU3BlYykqKG4tMSkpOwotCWN0PSAqcG0tPnBtVGFibGU7Ci0JY3QtPmN0U2l6ZT0gKG4tMSk7Ci0JY3QtPmN0RmxhZ3M9IDA7Ci0JY3QtPmN0U2VlZD0gR2V0Q1RTZWVkKCk7Ci0JCi0Jc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgY29sb3JzcGVjLCAwKTsKLQltZW1jcHkoY3QtPmN0VGFibGUsIHNhLCBuICogc2l6ZW9mKENvbG9yU3BlYykpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGNvbG9yc3BlYywgc2EsIDApOwotfQotCQkKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX3NldEJhc2VBZGRyKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBiaXRNYXBIYW5kbGUsIGppbnQgcHRyKSB7Ci0JQml0TWFwICoqYm1oPSAoQml0TWFwKiopIGJpdE1hcEhhbmRsZTsKLQkoKmJtaCktPmJhc2VBZGRyPSAodm9pZCopIHB0cjsKLX0KKyNpZm5kZWYgTk9fQ0dDb250ZXh0U2F2ZUdTdGF0ZQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0U2F2ZUdTdGF0ZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJDR0NvbnRleHRTYXZlR1N0YXRlXG4iKQogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EaXNwb3NlUGl4TWFwKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcGl4TWFwSGFuZGxlKSB7Ci0JUGl4TWFwSGFuZGxlIHBoPSAoUGl4TWFwSGFuZGxlKSBwaXhNYXBIYW5kbGU7Ci0JUGl4TWFwICpwbT0gKnBoOwotCQotCWlmIChwbS0+YmFzZUFkZHIgIT0gTlVMTCkgewotCQlEaXNwb3NlUHRyKHBtLT5iYXNlQWRkcik7Ci0JCXBtLT5iYXNlQWRkcj0gTlVMTDsKLQl9Ci0JCi0JaWYgKChwbS0+cm93Qnl0ZXMgJiAweDgwMDApICE9IDApIHsJLy8gUGl4bWFwCi0JCURpc3Bvc2VQaXhNYXAocGgpOwotCX0gZWxzZSB7CS8vIEJpdG1hcAotCQlmcHJpbnRmKHN0ZGVyciwgIk9TLkRpc3Bvc2VQaXhNYXA6IHdhcm5pbmc6IHBpeG1hcCBpcyBiaXRtYXBcbiIpOwotCX0KKwlDR0NvbnRleHRTYXZlR1N0YXRlKChDR0NvbnRleHRSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0U2F2ZUdTdGF0ZSAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19kdXBsaWNhdGVQaXhNYXAoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBzcmNQaXhtYXApIHsKKyNpZm5kZWYgTk9fQ0dDb250ZXh0U2NhbGVDVE0KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dFNjYWxlQ1RNCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqZmxvYXQgYXJnMSwgamZsb2F0IGFyZzIpCit7CisJREVCVUdfQ0FMTCgiQ0dDb250ZXh0U2NhbGVDVE1cbiIpCiAKLQlQaXhNYXBIYW5kbGUgc3JjaD0gKFBpeE1hcEhhbmRsZSkgc3JjUGl4bWFwOwotCVBpeE1hcEhhbmRsZSBkc3RoPSBOZXdQaXhNYXAoKTsKLQkJCi0JUGl4TWFwICpzcmM9ICpzcmNoOwotCVBpeE1hcCAqZHN0PSAqZHN0aDsKLQkKLQkqZHN0PSAqc3JjOwotCWRzdC0+cG1FeHQ9IE5VTEw7Ci0JCi0JaWYgKHNyYy0+YmFzZUFkZHIgIT0gTlVMTCkgewotCQlTaXplIGRhdGFTaXplPSBHZXRQdHJTaXplKHNyYy0+YmFzZUFkZHIpOwotCQkvL2ZwcmludGYoc3RkZXJyLCAiZHVwbGljYXRlUGl4TWFwOiBkYXRhICVsZFxuIiwgZGF0YVNpemUpOwotCQlkc3QtPmJhc2VBZGRyPSBOZXdQdHIoZGF0YVNpemUpOwotCQltZW1jcHkoZHN0LT5iYXNlQWRkciwgc3JjLT5iYXNlQWRkciwgZGF0YVNpemUpOwotCX0KLQkKLQlpZiAoKGRzdC0+cm93Qnl0ZXMgJiAweDgwMDApICE9IDApIHsJLy8gcGl4bWFwCi0JCWlmIChzcmMtPnBtVGFibGUgIT0gTlVMTCkgewotCQkJQ29sb3JUYWJsZSAqY3Q7Ci0JCQlTaXplIGRhdGFTaXplPSBHZXRIYW5kbGVTaXplKChIYW5kbGUpc3JjLT5wbVRhYmxlKTsKLQkJCS8vZnByaW50ZihzdGRlcnIsICJkdXBsaWNhdGVQaXhNYXA6IGN0YWIgJWxkXG4iLCBkYXRhU2l6ZSk7Ci0JCQlkc3QtPnBtVGFibGU9IChDb2xvclRhYmxlKiopIE5ld0hhbmRsZShkYXRhU2l6ZSk7Ci0JCQljdD0gKmRzdC0+cG1UYWJsZTsKLQkJCW1lbWNweShjdCwgKnNyYy0+cG1UYWJsZSwgZGF0YVNpemUpOwotCQkJLy9mcHJpbnRmKHN0ZGVyciwgImR1cGxpY2F0ZVBpeE1hcDogY3RhYiBzaXplICVkXG4iLCBjdC0+Y3RTaXplKTsKLQkJfQotCX0KLQkJCQotCXJldHVybiAoamludCkgZHN0aDsKKwlDR0NvbnRleHRTY2FsZUNUTSgoQ0dDb250ZXh0UmVmKWFyZzAsIChmbG9hdClhcmcxLCAoZmxvYXQpYXJnMik7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0U2NhbGVDVE0gKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0UGl4Qm91bmRzKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcEhhbmRsZSwganNob3J0QXJyYXkgYm91bmRzKSB7Ci0gICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCUdldFBpeEJvdW5kcygoUGl4TWFwSGFuZGxlKSBwSGFuZGxlLCAoUmVjdCopIHNhKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIHNhLCAwKTsKLX0KKyNpZm5kZWYgTk9fQ0dDb250ZXh0U2VsZWN0Rm9udAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0U2VsZWN0Rm9udAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamJ5dGVBcnJheSBhcmcxLCBqZmxvYXQgYXJnMiwgamludCBhcmczKQoreworCWpieXRlICpscGFyZzE9TlVMTDsKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1Nfc2V0UGl4Qm91bmRzKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCWppbnQgcEhhbmRsZSwganNob3J0IHRvcCwganNob3J0IGxlZnQsIGpzaG9ydCBib3R0b20sIGpzaG9ydCByaWdodCkgewotCUJpdE1hcCAqKmJtaD0gKEJpdE1hcCoqKSBwSGFuZGxlOwotCUJpdE1hcCAqYm09ICpibWg7Ci0JYm0tPmJvdW5kcy50b3A9IHRvcDsKLQlibS0+Ym91bmRzLmxlZnQ9IGxlZnQ7Ci0JYm0tPmJvdW5kcy5ib3R0b209IGJvdHRvbTsKLQlibS0+Ym91bmRzLnJpZ2h0PSByaWdodDsKLX0KKwlERUJVR19DQUxMKCJDR0NvbnRleHRTZWxlY3RGb250XG4iKQogCi1KTklFWFBPUlQganNob3J0IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFBpeERlcHRoKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcEhhbmRsZSkgewotCXJldHVybiBHZXRQaXhEZXB0aCgoUGl4TWFwSGFuZGxlKSBwSGFuZGxlKTsKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCUNHQ29udGV4dFNlbGVjdEZvbnQoKENHQ29udGV4dFJlZilhcmcwLCAoY29uc3QgY2hhciAqKWxwYXJnMSwgKGZsb2F0KWFyZzIsIChDR1RleHRFbmNvZGluZylhcmczKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOwogfQorI2VuZGlmIC8qIE5PX0NHQ29udGV4dFNlbGVjdEZvbnQgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfZ2V0UGl4SFJlcyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHBIYW5kbGUpIHsKLQlQaXhNYXBIYW5kbGUgcG1oPSAoUGl4TWFwSGFuZGxlKSBwSGFuZGxlOwotCXJldHVybiAoamludCkgKCpwbWgpLT5oUmVzOwotfQorI2lmbmRlZiBOT19DR0NvbnRleHRTZXRGaWxsQ29sb3IKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dFNldEZpbGxDb2xvcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamZsb2F0QXJyYXkgYXJnMSkKK3sKKwlqZmxvYXQgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgiQ0dDb250ZXh0U2V0RmlsbENvbG9yXG4iKQogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19nZXRQaXhWUmVzKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgcEhhbmRsZSkgewotCVBpeE1hcEhhbmRsZSBwbWg9IChQaXhNYXBIYW5kbGUpIHBIYW5kbGU7Ci0JcmV0dXJuIChqaW50KSAoKnBtaCktPnZSZXM7CisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0RmxvYXRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJQ0dDb250ZXh0U2V0RmlsbENvbG9yKChDR0NvbnRleHRSZWYpYXJnMCwgKGNvbnN0IGZsb2F0ICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlRmxvYXRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRTZXRGaWxsQ29sb3IgKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ29weUJpdHMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJamludCBzcmNCaXRzLCBqaW50IGRzdEJpdHMsIGpzaG9ydEFycmF5IHNyY1JlY3QsIGpzaG9ydEFycmF5IGRzdFJlY3QsIGpzaG9ydCBtb2RlLCBqaW50IG1hc2tSZ24pIHsKLSAgICBqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHNyY1JlY3QsIDApOwotICAgIGpzaG9ydCAqc2I9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgZHN0UmVjdCwgMCk7Ci0gICAJQ29weUJpdHMoKEJpdE1hcCopc3JjQml0cywgKEJpdE1hcCopZHN0Qml0cywgKFJlY3QqKXNhLCAoUmVjdCopc2IsIG1vZGUsIChSZ25IYW5kbGUpIG1hc2tSZ24pOwotIAkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBzcmNSZWN0LCBzYSwgMCk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgZHN0UmVjdCwgc2IsIDApOwotfQorI2lmbmRlZiBOT19DR0NvbnRleHRTZXRGaWxsQ29sb3JTcGFjZQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0U2V0RmlsbENvbG9yU3BhY2UKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJDR0NvbnRleHRTZXRGaWxsQ29sb3JTcGFjZVxuIikKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ29weU1hc2soSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJamludCBzcmNCaXRzLCBqaW50IG1hc2tCaXRzLCBqaW50IGRzdEJpdHMsIGpzaG9ydEFycmF5IHNyY1JlY3QsIGpzaG9ydEFycmF5IG1hc2tSZWN0LCBqc2hvcnRBcnJheSBkc3RSZWN0KSB7Ci0gICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBzcmNSZWN0LCAwKTsKLSAgICBqc2hvcnQgKnNiPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIG1hc2tSZWN0LCAwKTsKLSAgICBqc2hvcnQgKnNjPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGRzdFJlY3QsIDApOwotCUNvcHlNYXNrKChCaXRNYXAqKXNyY0JpdHMsIChCaXRNYXAqKW1hc2tCaXRzLCAoQml0TWFwKilkc3RCaXRzLCAoUmVjdCopc2EsIChSZWN0KilzYiwgKFJlY3QqKXNjKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBzcmNSZWN0LCBzYSwgMCk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgbWFza1JlY3QsIHNiLCAwKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBkc3RSZWN0LCBzYywgMCk7IAorCUNHQ29udGV4dFNldEZpbGxDb2xvclNwYWNlKChDR0NvbnRleHRSZWYpYXJnMCwgKENHQ29sb3JTcGFjZVJlZilhcmcxKTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRTZXRGaWxsQ29sb3JTcGFjZSAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Db3B5RGVlcE1hc2soSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBzcmNCaXRzLAotCQlqaW50IG1hc2tCaXRzLCBqaW50IGRzdEJpdHMsIGpzaG9ydEFycmF5IHNyY1JlY3QsIGpzaG9ydEFycmF5IG1hc2tSZWN0LCBqc2hvcnRBcnJheSBkc3RSZWN0LCBqc2hvcnQgbW9kZSwgamludCBtYXNrUmduKSB7Ci0gICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBzcmNSZWN0LCAwKTsKLSAgICBqc2hvcnQgKnNiPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIG1hc2tSZWN0LCAwKTsKLSAgICBqc2hvcnQgKnNjPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGRzdFJlY3QsIDApOwotCUNvcHlEZWVwTWFzaygoQml0TWFwKilzcmNCaXRzLCAoQml0TWFwKiltYXNrQml0cywgKEJpdE1hcCopZHN0Qml0cywgKFJlY3QqKSBzYSwgKFJlY3QqKSBzYiwgKFJlY3QqKSBzYywgbW9kZSwgKFJnbkhhbmRsZSkgbWFza1Jnbik7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgc3JjUmVjdCwgc2EsIDApOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIG1hc2tSZWN0LCBzYiwgMCk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgZHN0UmVjdCwgc2MsIDApOwotfQorI2lmbmRlZiBOT19DR0NvbnRleHRTZXRGb250U2l6ZQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0U2V0Rm9udFNpemUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpmbG9hdCBhcmcxKQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dFNldEZvbnRTaXplXG4iKQogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRQb3J0Qml0TWFwRm9yQ29weUJpdHMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBncmFmUG9ydCkgewotCXJldHVybiAoamludCkgR2V0UG9ydEJpdE1hcEZvckNvcHlCaXRzKChDR3JhZlB0cilncmFmUG9ydCk7CisJQ0dDb250ZXh0U2V0Rm9udFNpemUoKENHQ29udGV4dFJlZilhcmcwLCAoZmxvYXQpYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0U2V0Rm9udFNpemUgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmV3Q0ljb24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQkJamludCBwaXhNYXBIYW5kbGUsIGppbnQgbWFza0hhbmRsZSkgewotCUNJY29uICppY29uOwotCUNJY29uSGFuZGxlIGNpaDsKLQlQaXhNYXAgKnBoPSBOVUxMOwotCUJpdE1hcCAqbWg9IE5VTEw7Ci0JaW50IHBpeG1hcFJvd2J5dGVzLCBwaXhtYXBXaWR0aCwgcGl4bWFwSGVpZ2h0LCBwaXhtYXBTaXplOwotCWludCBtYXNrUm93Ynl0ZXMsIG1hc2tIZWlnaHQsIG1hc2tTaXplOwotCVNpemUgY3RzaXplOwotCWludCBzaXplOwotCQotCWlmIChwaXhNYXBIYW5kbGUgPT0gMCkKLQkJcmV0dXJuIDA7Ci0JcGg9ICooKFBpeE1hcCoqKSBwaXhNYXBIYW5kbGUpOwotCWlmIChwaCA9PSBOVUxMKQotCQlyZXR1cm4gMDsKLQkKLQkvLyBjYWxjdWxhdGUgdGhlIENJY29uIHNpemUKLQkKLQlwaXhtYXBSb3dieXRlcz0gcGgtPnJvd0J5dGVzICYgMHgzZmZmOwotCXBpeG1hcEhlaWdodD0gcGgtPmJvdW5kcy5ib3R0b20gLSBwaC0+Ym91bmRzLnRvcDsKLQlwaXhtYXBXaWR0aD0gcGgtPmJvdW5kcy5yaWdodCAtIHBoLT5ib3VuZHMubGVmdDsKLQlwaXhtYXBTaXplPSBwaXhtYXBSb3dieXRlcyAqIHBpeG1hcEhlaWdodDsKKyNpZm5kZWYgTk9fQ0dDb250ZXh0U2V0TGluZURhc2gKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dFNldExpbmVEYXNoCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqZmxvYXQgYXJnMSwgamZsb2F0QXJyYXkgYXJnMiwgamludCBhcmczKQoreworCWpmbG9hdCAqbHBhcmcyPU5VTEw7CiAKLQltaD0gKigoQml0TWFwKiopIG1hc2tIYW5kbGUpOwotCWlmIChtaCA9PSBOVUxMKQotCQlyZXR1cm4gMDsKKwlERUJVR19DQUxMKCJDR0NvbnRleHRTZXRMaW5lRGFzaFxuIikKIAotCW1hc2tSb3dieXRlcz0gbWgtPnJvd0J5dGVzICYgMHgzZmZmOwotCW1hc2tIZWlnaHQ9IG1oLT5ib3VuZHMuYm90dG9tIC0gbWgtPmJvdW5kcy50b3A7Ci0JbWFza1NpemU9IG1hc2tSb3dieXRlcyAqIG1hc2tIZWlnaHQ7Ci0JCQkJCi0JLy8gYWxsb2NhdGUgdGhlIENJY29uCi0JY2loPSAoQ0ljb25IYW5kbGUpIE5ld0hhbmRsZUNsZWFyKHNpemVvZihDSWNvbikgKyBtYXNrU2l6ZSk7Ci0JaWYgKGNpaCA9PSBOVUxMKQotCQlyZXR1cm4gMDsKLQlpY29uPSAqY2loOwotCWlmIChpY29uID09IE5VTEwpCi0JCXJldHVybiAwOwotCQotCS8vIGNvcHkgdGhlIHBpeG1hcAotCW1lbWNweSgmaWNvbi0+aWNvblBNYXAsIHBoLCBzaXplb2YoUGl4TWFwKSk7Ci0JaWNvbi0+aWNvblBNYXAuYmFzZUFkZHI9IDA7CS8vIHRoaXMgaXMgZG9jdW1lbnRlZCBub3doZXJlIQorCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEZsb2F0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCUNHQ29udGV4dFNldExpbmVEYXNoKChDR0NvbnRleHRSZWYpYXJnMCwgKGZsb2F0KWFyZzEsIChjb25zdCBmbG9hdCAqKWxwYXJnMiwgKHNpemVfdClhcmczKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlRmxvYXRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKK30KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRTZXRMaW5lRGFzaCAqLwogCi0JLy8gYWxsb2NhdGUgdGhlIGhhbmRsZSBmb3IgdGhlIHBpeG1hcCdzIGRhdGEKLQlpY29uLT5pY29uRGF0YT0gTmV3SGFuZGxlKHBpeG1hcFNpemUpOwotCWlmIChpY29uLT5pY29uRGF0YSA9PSAwKQotCQlyZXR1cm4gMDsKLQkKLQkvLyBjb3B5IHRoZSBwaXhtYXAncyBkYXRhCi0JbWVtY3B5KCppY29uLT5pY29uRGF0YSwgcGgtPmJhc2VBZGRyLCBwaXhtYXBTaXplKTsKLQkKLQkvLyBjb3B5IGN0YWJsZSAoaWYgYW55KQotCWlmIChwaC0+cG1UYWJsZSAhPSBOVUxMKSB7Ci0JCWN0c2l6ZT0gR2V0SGFuZGxlU2l6ZSgoSGFuZGxlKXBoLT5wbVRhYmxlKTsKLQkJaWYgKGN0c2l6ZSA+IDApIHsKLQkJCUhhbmRsZSBoPSBOZXdIYW5kbGUoY3RzaXplKTsKLQkJCW1lbWNweSgqaCwgKnBoLT5wbVRhYmxlLCBjdHNpemUpOwotCQkJaWNvbi0+aWNvblBNYXAucG1UYWJsZT0gKENvbG9yVGFibGUqKikgaDsKLQkJfQotCX0KKyNpZm5kZWYgTk9fQ0dDb250ZXh0U2V0TGluZVdpZHRoCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRTZXRMaW5lV2lkdGgKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpmbG9hdCBhcmcxKQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dFNldExpbmVXaWR0aFxuIikKIAotCW1lbWNweSgmaWNvbi0+aWNvbk1hc2ssIG1oLCBzaXplb2YoQml0TWFwKSk7Ci0JLy8gY29weSBtYXNrIGRhdGEgdG8gZW5kIG9mIENJY29uCi0JbWVtY3B5KCZpY29uLT5pY29uTWFza0RhdGEsIGljb24tPmljb25NYXNrLmJhc2VBZGRyLCBtYXNrU2l6ZSk7Ci0JaWNvbi0+aWNvbk1hc2suYmFzZUFkZHI9IDA7Ci0JCQotCXJldHVybiAoamludCkgY2loOworCUNHQ29udGV4dFNldExpbmVXaWR0aCgoQ0dDb250ZXh0UmVmKWFyZzAsIChmbG9hdClhcmcxKTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRTZXRMaW5lV2lkdGggKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfZ2V0Q0ljb25JY29uRGF0YShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNJY29uSGFuZGxlKSB7Ci0JQ0ljb24gKmljb249ICooKENJY29uSGFuZGxlKSBjSWNvbkhhbmRsZSk7Ci0JcmV0dXJuIChqaW50KSBpY29uLT5pY29uRGF0YTsKKyNpZm5kZWYgTk9fQ0dDb250ZXh0U2V0UkdCRmlsbENvbG9yCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRTZXRSR0JGaWxsQ29sb3IKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpmbG9hdCBhcmcxLCBqZmxvYXQgYXJnMiwgamZsb2F0IGFyZzMsIGpmbG9hdCBhcmc0KQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dFNldFJHQkZpbGxDb2xvclxuIikKKworCUNHQ29udGV4dFNldFJHQkZpbGxDb2xvcigoQ0dDb250ZXh0UmVmKWFyZzAsIChmbG9hdClhcmcxLCAoZmxvYXQpYXJnMiwgKGZsb2F0KWFyZzMsIChmbG9hdClhcmc0KTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRTZXRSR0JGaWxsQ29sb3IgKi8KKworI2lmbmRlZiBOT19DR0NvbnRleHRTZXRSR0JTdHJva2VDb2xvcgorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0U2V0UkdCU3Ryb2tlQ29sb3IKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpmbG9hdCBhcmcxLCBqZmxvYXQgYXJnMiwgamZsb2F0IGFyZzMsIGpmbG9hdCBhcmc0KQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dFNldFJHQlN0cm9rZUNvbG9yXG4iKQogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19nZXRDSWNvbkNvbG9yVGFibGUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBjSWNvbkhhbmRsZSkgewotCUNJY29uICppY29uPSAqKChDSWNvbkhhbmRsZSkgY0ljb25IYW5kbGUpOwotCXJldHVybiAoamludCkgaWNvbi0+aWNvblBNYXAucG1UYWJsZTsKKwlDR0NvbnRleHRTZXRSR0JTdHJva2VDb2xvcigoQ0dDb250ZXh0UmVmKWFyZzAsIChmbG9hdClhcmcxLCAoZmxvYXQpYXJnMiwgKGZsb2F0KWFyZzMsIChmbG9hdClhcmc0KTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRTZXRSR0JTdHJva2VDb2xvciAqLwogCi0vLy0tLS0gR1dvcmxkcyAmIEdEZXZpY2VzCisjaWZuZGVmIE5PX0NHQ29udGV4dFNldFN0cm9rZUNvbG9yCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRTZXRTdHJva2VDb2xvcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamZsb2F0QXJyYXkgYXJnMSkKK3sKKwlqZmxvYXQgKmxwYXJnMT1OVUxMOwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OZXdHV29ybGRGcm9tUHRyKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJCWppbnRBcnJheSBvZmZzY3JlZW5HV29ybGQsIGppbnQgcGl4TWFwSGFuZGxlKSB7Ci0JCQotCVBpeE1hcEhhbmRsZSBwbT0gKFBpeE1hcEhhbmRsZSkgcGl4TWFwSGFuZGxlOwotICAgICAgICBqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgb2Zmc2NyZWVuR1dvcmxkLCAwKTsKLQkKLQlqaW50IHN0YXR1cz0gKGppbnQpIFJDKE5ld0dXb3JsZEZyb21QdHIoCi0JCQkJKEdXb3JsZFB0ciopIHNhLAotCQkJCSgqcG0pLT5waXhlbEZvcm1hdCwKLQkJCQkmKCgqcG0pLT5ib3VuZHMpLAotCQkJCSgqcG0pLT5wbVRhYmxlLAotCQkJCShHREhhbmRsZSkgTlVMTCwKLQkJCQkoR1dvcmxkRmxhZ3MpIDAsCi0JCQkJKCpwbSktPmJhc2VBZGRyLAotCQkJCSgqcG0pLT5yb3dCeXRlcyAmIDB4M0ZGRikpOworCURFQlVHX0NBTEwoIkNHQ29udGV4dFNldFN0cm9rZUNvbG9yXG4iKQogCi0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIG9mZnNjcmVlbkdXb3JsZCwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7CisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0RmxvYXRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJQ0dDb250ZXh0U2V0U3Ryb2tlQ29sb3IoKENHQ29udGV4dFJlZilhcmcwLCAoY29uc3QgZmxvYXQgKilscGFyZzEpOworCWlmIChhcmcxKSAoKmVudiktPlJlbGVhc2VGbG9hdEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOwogfQorI2VuZGlmIC8qIE5PX0NHQ29udGV4dFNldFN0cm9rZUNvbG9yICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0Rpc3Bvc2VHV29ybGQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBvZmZzY3JlZW5HV29ybGQpIHsKLQlEaXNwb3NlR1dvcmxkKChHV29ybGRQdHIpb2Zmc2NyZWVuR1dvcmxkKTsKLX0KKyNpZm5kZWYgTk9fQ0dDb250ZXh0U2V0U3Ryb2tlQ29sb3JTcGFjZQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0U2V0U3Ryb2tlQ29sb3JTcGFjZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dFNldFN0cm9rZUNvbG9yU3BhY2VcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldEdXb3JsZChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHBvcnRIYW5kbGUsIGppbnQgZ2RIYW5kbGUpIHsKLQlTZXRHV29ybGQoKENHcmFmUHRyKXBvcnRIYW5kbGUsIChHREhhbmRsZSlnZEhhbmRsZSk7CisJQ0dDb250ZXh0U2V0U3Ryb2tlQ29sb3JTcGFjZSgoQ0dDb250ZXh0UmVmKWFyZzAsIChDR0NvbG9yU3BhY2VSZWYpYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0U2V0U3Ryb2tlQ29sb3JTcGFjZSAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRHV29ybGQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludEFycmF5IHBvcnRIYW5kbGUsIGppbnRBcnJheSBnZEhhbmRsZSkgewotICAgIGppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBwb3J0SGFuZGxlLCAwKTsKLSAgICBqaW50ICpzYj0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgZ2RIYW5kbGUsIDApOwotCUdldEdXb3JsZCgoQ0dyYWZQdHIqKXNhLCAoR0RIYW5kbGUqKXNiKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgcG9ydEhhbmRsZSwgc2EsIDApOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBnZEhhbmRsZSwgc2IsIDApOworI2lmbmRlZiBOT19DR0NvbnRleHRTZXRUZXh0RHJhd2luZ01vZGUKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dFNldFRleHREcmF3aW5nTW9kZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dFNldFRleHREcmF3aW5nTW9kZVxuIikKKworCUNHQ29udGV4dFNldFRleHREcmF3aW5nTW9kZSgoQ0dDb250ZXh0UmVmKWFyZzAsIChDR1RleHREcmF3aW5nTW9kZSlhcmcxKTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRTZXRUZXh0RHJhd2luZ01vZGUgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0R0RldmljZShKTklFbnYgKmVudiwgamNsYXNzIHp6KSB7Ci0JcmV0dXJuIChqaW50KSBHZXRHRGV2aWNlKCk7Ci19CisjaWZuZGVmIE5PX0NHQ29udGV4dFNldFRleHRNYXRyaXgKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dFNldFRleHRNYXRyaXgKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpmbG9hdEFycmF5IGFyZzEpCit7CisJamZsb2F0ICpscGFyZzE9TlVMTDsKIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0TWFpbkRldmljZShKTklFbnYgKmVudiwgamNsYXNzIHp6KSB7Ci0JcmV0dXJuIChqaW50KSBHZXRNYWluRGV2aWNlKCk7Ci19CisJREVCVUdfQ0FMTCgiQ0dDb250ZXh0U2V0VGV4dE1hdHJpeFxuIikKIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfZ2V0Z2RQTWFwKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgZ2RIYW5kbGUpIHsKLQlHREhhbmRsZSBoPSAoR0RIYW5kbGUpIGdkSGFuZGxlOwotCXJldHVybiAoamludCkgKCpoKS0+Z2RQTWFwOworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEZsb2F0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCUNHQ29udGV4dFNldFRleHRNYXRyaXgoKENHQ29udGV4dFJlZilhcmcwLCAqKENHQWZmaW5lVHJhbnNmb3JtICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlRmxvYXRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRTZXRUZXh0TWF0cml4ICovCiAKLS8vLS0tLSBXaW5kb3cgTWFuYWdlcgorI2lmbmRlZiBOT19DR0NvbnRleHRTZXRUZXh0UG9zaXRpb24KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dFNldFRleHRQb3NpdGlvbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamZsb2F0IGFyZzEsIGpmbG9hdCBhcmcyKQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dFNldFRleHRQb3NpdGlvblxuIikKIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ3JlYXRlTmV3V2luZG93KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCB3aW5kb3dDbGFzcywgamludCB3aW5kb3dBdHRyaWJ1dGVzLCBqc2hvcnRBcnJheSBib3VuZHMsIGppbnRBcnJheSB3SGFuZGxlKSB7Ci0JanNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCWppbnQgKnNiPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCB3SGFuZGxlLCAwKTsKLQlqaW50IHN0YXR1cz0gKGppbnQpIFJDKENyZWF0ZU5ld1dpbmRvdygoV2luZG93Q2xhc3Mpd2luZG93Q2xhc3MsIChXaW5kb3dBdHRyaWJ1dGVzKXdpbmRvd0F0dHJpYnV0ZXMsIChjb25zdCBSZWN0KilzYSwgKFdpbmRvd1JlZiopc2IpKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIHNhLCAwKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgd0hhbmRsZSwgc2IsIDApOwotCXJldHVybiBzdGF0dXM7CisJQ0dDb250ZXh0U2V0VGV4dFBvc2l0aW9uKChDR0NvbnRleHRSZWYpYXJnMCwgKGZsb2F0KWFyZzEsIChmbG9hdClhcmcyKTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRTZXRUZXh0UG9zaXRpb24gKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0V2luZG93UG9ydChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHdIYW5kbGUpIHsKLQlyZXR1cm4gKGppbnQpIEdldFdpbmRvd1BvcnQoKFdpbmRvd1JlZikgd0hhbmRsZSk7Ci19CisjaWZuZGVmIE5PX0NHQ29udGV4dFNob3dUZXh0CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRTaG93VGV4dAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamJ5dGVBcnJheSBhcmcxLCBqaW50IGFyZzIpCit7CisJamJ5dGUgKmxwYXJnMT1OVUxMOwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19CZWdpblVwZGF0ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHdIYW5kbGUpIHsKLQlCZWdpblVwZGF0ZSgoV2luZG93UmVmKXdIYW5kbGUpOwotfQorCURFQlVHX0NBTEwoIkNHQ29udGV4dFNob3dUZXh0XG4iKQogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HbG9iYWxUb0xvY2FsKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzaG9ydEFycmF5IHBvaW50KSB7Ci0gICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBwb2ludCwgMCk7Ci0JR2xvYmFsVG9Mb2NhbCgoUG9pbnQqKXNhKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBwb2ludCwgc2EsIDApOworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJQ0dDb250ZXh0U2hvd1RleHQoKENHQ29udGV4dFJlZilhcmcwLCAoY29uc3QgY2hhciAqKWxwYXJnMSwgKHNpemVfdClhcmcyKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOwogfQorI2VuZGlmIC8qIE5PX0NHQ29udGV4dFNob3dUZXh0ICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0xvY2FsVG9HbG9iYWwoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0QXJyYXkgcG9pbnQpIHsKLSAgICBqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHBvaW50LCAwKTsKLQlMb2NhbFRvR2xvYmFsKChQb2ludCopc2EpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHBvaW50LCBzYSwgMCk7Ci19CisjaWZuZGVmIE5PX0NHQ29udGV4dFNob3dUZXh0QXRQb2ludAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0U2hvd1RleHRBdFBvaW50CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqZmxvYXQgYXJnMSwgamZsb2F0IGFyZzIsIGpieXRlQXJyYXkgYXJnMywgamludCBhcmc0KQoreworCWpieXRlICpscGFyZzM9TlVMTDsKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUURHbG9iYWxUb0xvY2FsUG9pbnQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgcG9ydCwganNob3J0QXJyYXkgcG9pbnQpIHsKLSAgICBqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHBvaW50LCAwKTsKLQlRREdsb2JhbFRvTG9jYWxQb2ludCgoQ0dyYWZQdHIpcG9ydCwgKFBvaW50KilzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgcG9pbnQsIHNhLCAwKTsKLX0KKwlERUJVR19DQUxMKCJDR0NvbnRleHRTaG93VGV4dEF0UG9pbnRcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1FETG9jYWxUb0dsb2JhbFBvaW50KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IHBvcnQsIGpzaG9ydEFycmF5IHBvaW50KSB7Ci0gICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBwb2ludCwgMCk7Ci0JUURMb2NhbFRvR2xvYmFsUG9pbnQoKENHcmFmUHRyKXBvcnQsIChQb2ludCopc2EpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHBvaW50LCBzYSwgMCk7CisJaWYgKGFyZzMpIGxwYXJnMyA9ICgqZW52KS0+R2V0Qnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmczLCBOVUxMKTsKKwlDR0NvbnRleHRTaG93VGV4dEF0UG9pbnQoKENHQ29udGV4dFJlZilhcmcwLCAoZmxvYXQpYXJnMSwgKGZsb2F0KWFyZzIsIChjb25zdCBjaGFyICopbHBhcmczLCAoc2l6ZV90KWFyZzQpOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CiB9CisjZW5kaWYgLyogTk9fQ0dDb250ZXh0U2hvd1RleHRBdFBvaW50ICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0VuZFVwZGF0ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHdIYW5kbGUpIHsKLQlFbmRVcGRhdGUoKFdpbmRvd1JlZil3SGFuZGxlKTsKKyNpZm5kZWYgTk9fQ0dDb250ZXh0U3Ryb2tlUGF0aAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0U3Ryb2tlUGF0aAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJDR0NvbnRleHRTdHJva2VQYXRoXG4iKQorCisJQ0dDb250ZXh0U3Ryb2tlUGF0aCgoQ0dDb250ZXh0UmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0NHQ29udGV4dFN0cm9rZVBhdGggKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRHJhd0NvbnRyb2xzKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSkgewotCURyYXdDb250cm9scygoV2luZG93UmVmKXdIYW5kbGUpOwotfQorI2lmbmRlZiBOT19DR0NvbnRleHRTdHJva2VSZWN0CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRTdHJva2VSZWN0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEpCit7CisJQ0dSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1VwZGF0ZUNvbnRyb2xzKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSwgamludCByZ25IYW5kbGUpIHsKLQlVcGRhdGVDb250cm9scygoV2luZG93UmVmKXdIYW5kbGUsIChSZ25IYW5kbGUpcmduSGFuZGxlKTsKLX0KKwlERUJVR19DQUxMKCJDR0NvbnRleHRTdHJva2VSZWN0XG4iKQogCi0vKgotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRHJhd0dyb3dJY29uKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSkgewotCURyYXdHcm93SWNvbigoV2luZG93UmVmKXdIYW5kbGUpOworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRDR1JlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCUNHQ29udGV4dFN0cm9rZVJlY3QoKENHQ29udGV4dFJlZilhcmcwLCAoQ0dSZWN0KSpscGFyZzEpOworCWlmIChhcmcxKSBzZXRDR1JlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOwogfQotKi8KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRTdHJva2VSZWN0ICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0Zyb250V2luZG93KEpOSUVudiAqZW52LCBqY2xhc3MgY2xhc3MpIHsKLQlyZXR1cm4gKGppbnQpIEZyb250V2luZG93KCk7Ci19CisjaWZuZGVmIE5PX0NHQ29udGV4dFRyYW5zbGF0ZUNUTQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0VHJhbnNsYXRlQ1RNCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqZmxvYXQgYXJnMSwgamZsb2F0IGFyZzIpCit7CisJREVCVUdfQ0FMTCgiQ0dDb250ZXh0VHJhbnNsYXRlQ1RNXG4iKQogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Gcm9udE5vbkZsb2F0aW5nV2luZG93KEpOSUVudiAqZW52LCBqY2xhc3MgY2xhc3MpIHsKLQlyZXR1cm4gKGppbnQpIEZyb250Tm9uRmxvYXRpbmdXaW5kb3coKTsKKwlDR0NvbnRleHRUcmFuc2xhdGVDVE0oKENHQ29udGV4dFJlZilhcmcwLCAoZmxvYXQpYXJnMSwgKGZsb2F0KWFyZzIpOwogfQorI2VuZGlmIC8qIE5PX0NHQ29udGV4dFRyYW5zbGF0ZUNUTSAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZWxlY3RXaW5kb3coSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlKSB7Ci0JU2VsZWN0V2luZG93KChXaW5kb3dSZWYpd0hhbmRsZSk7Ci19CisjaWZuZGVmIE5PX0NHQ29udGV4dFN5bmNocm9uaXplCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRTeW5jaHJvbml6ZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamZsb2F0IGFyZzEsIGpmbG9hdCBhcmcyKQoreworCURFQlVHX0NBTEwoIkNHQ29udGV4dFN5bmNocm9uaXplXG4iKQogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19BY3RpdmF0ZVdpbmRvdyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQlqaW50IHdIYW5kbGUsIGpib29sZWFuIGFjdGl2YXRlKSB7Ci0JQWN0aXZhdGVXaW5kb3coKFdpbmRvd1JlZil3SGFuZGxlLCBhY3RpdmF0ZSk7CisJQ0dDb250ZXh0U3luY2hyb25pemUoKENHQ29udGV4dFJlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19DR0NvbnRleHRTeW5jaHJvbml6ZSAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19CcmluZ1RvRnJvbnQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlKSB7Ci0JQnJpbmdUb0Zyb250KChXaW5kb3dSZWYpd0hhbmRsZSk7Ci19CisjaWZuZGVmIE5PX0NHRGF0YVByb3ZpZGVyQ3JlYXRlV2l0aERhdGEKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHRGF0YVByb3ZpZGVyQ3JlYXRlV2l0aERhdGEKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMpCit7CisJREVCVUdfQ0FMTCgiQ0dEYXRhUHJvdmlkZXJDcmVhdGVXaXRoRGF0YVxuIikKIAotSk5JRVhQT1JUIGpzaG9ydCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19GaW5kV2luZG93KEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzaG9ydEFycmF5IHdoZXJlLCBqaW50QXJyYXkgd2FycikgewotCWppbnQgKmJvZHk9IE5VTEw7Ci0JanNob3J0IHBhcnQ9IDA7Ci0JaWYgKHdhcnIgIT0gMCkKLSAgICAJYm9keT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgd2FyciwgMCk7Ci0JcGFydD0gRmluZFdpbmRvdyhwb2ludChlbnYsIHdoZXJlKSwgKFdpbmRvd1JlZiopYm9keSk7Ci0JaWYgKGJvZHkgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIHdhcnIsIGJvZHksIDApOwotCXJldHVybiBwYXJ0OworCXJldHVybiAoamludClDR0RhdGFQcm92aWRlckNyZWF0ZVdpdGhEYXRhKCh2b2lkICopYXJnMCwgKGNvbnN0IHZvaWQgKilhcmcxLCAoc2l6ZV90KWFyZzIsICh2b2lkICopYXJnMyk7CiB9CisjZW5kaWYgLyogTk9fQ0dEYXRhUHJvdmlkZXJDcmVhdGVXaXRoRGF0YSAqLwogCi0vKgotSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1Jlc2l6ZVdpbmRvdyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHdIYW5kbGUsCi0JCQkJCQlqc2hvcnRBcnJheSBzdGFydFB0LCBqc2hvcnRBcnJheSBzaXplQ29uc3RyYWludHMsIGpzaG9ydEFycmF5IG5ld0NvbnRlbnRSZWN0KSB7Ci0JamJvb2xlYW4gYjsKLQlqc2hvcnQgKnNhPSBOVUxMOwotCWlmIChuZXdDb250ZW50UmVjdCAhPSBOVUxMKQotCQlzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBuZXdDb250ZW50UmVjdCwgMCk7Ci0JYj0gUmVzaXplV2luZG93KChXaW5kb3dSZWYpIHdIYW5kbGUsIHBvaW50KGVudiwgc3RhcnRQdCksIE5VTEwsIChSZWN0Kikgc2EpOwotCWlmIChzYSAhPSBOVUxMKQotCQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBuZXdDb250ZW50UmVjdCwgc2EsIDApOwotCXJldHVybiBiOwotfQotKi8KLS8qCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EcmFnV2luZG93KEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSwKLQkJCQkJCQlqc2hvcnRBcnJheSBzdGFydFB0LCBqc2hvcnRBcnJheSBib3VuZHNSZWN0KSB7Ci0JRHJhZ1dpbmRvdygoV2luZG93UmVmKXdIYW5kbGUsIHBvaW50KGVudiwgc3RhcnRQdCksIE5VTEwpOwotfQotKi8KLS8qCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRXaW5kb3dQb3J0Qm91bmRzKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSwganNob3J0QXJyYXkgYm91bmRzKSB7Ci0gICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCUdldFdpbmRvd1BvcnRCb3VuZHMoKFdpbmRvd1JlZil3SGFuZGxlLCAoUmVjdCopIHNhKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIHNhLCAwKTsKLX0KLSovCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRXaW5kb3dCb3VuZHMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlLCBqc2hvcnQgcmVnaW9uLCBqc2hvcnRBcnJheSBib3VuZHMpIHsKLSAgICAgICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCUdldFdpbmRvd0JvdW5kcygoV2luZG93UmVmKXdIYW5kbGUsIHJlZ2lvbiwgKFJlY3QqKSBzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCBzYSwgMCk7Ci19CisjaWZuZGVmIE5PX0NHRGF0YVByb3ZpZGVyUmVsZWFzZQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dEYXRhUHJvdmlkZXJSZWxlYXNlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkNHRGF0YVByb3ZpZGVyUmVsZWFzZVxuIikKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0V2luZG93Qm91bmRzKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSwganNob3J0IHJlZ2lvbiwganNob3J0QXJyYXkgYm91bmRzKSB7Ci0JanNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCVNldFdpbmRvd0JvdW5kcygoV2luZG93UmVmKXdIYW5kbGUsIHJlZ2lvbiwgKFJlY3QqKSBzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCBzYSwgMCk7CisJQ0dEYXRhUHJvdmlkZXJSZWxlYXNlKChDR0RhdGFQcm92aWRlclJlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19DR0RhdGFQcm92aWRlclJlbGVhc2UgKi8KIAotSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0lzVmFsaWRXaW5kb3dQdHIoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBwb3J0KSB7Ci0JcmV0dXJuIChqYm9vbGVhbikgSXNWYWxpZFdpbmRvd1B0cigodm9pZCopcG9ydCk7Ci19CisjaWZuZGVmIE5PX0NHSW1hZ2VDcmVhdGUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHSW1hZ2VDcmVhdGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMsIGppbnQgYXJnNCwgamludCBhcmc1LCBqaW50IGFyZzYsIGppbnQgYXJnNywgamZsb2F0QXJyYXkgYXJnOCwgamJvb2xlYW4gYXJnOSwgamludCBhcmcxMCkKK3sKKwlqZmxvYXQgKmxwYXJnOD1OVUxMOworCWppbnQgcmM7CiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFdSZWZDb24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBHZXRXUmVmQ29uKChXaW5kb3dSZWYpd0hhbmRsZSk7Ci19CisJREVCVUdfQ0FMTCgiQ0dJbWFnZUNyZWF0ZVxuIikKIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ29weVdpbmRvd1RpdGxlQXNDRlN0cmluZyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCQlqaW50IHdIYW5kbGUsIGppbnRBcnJheSBzSGFuZGxlKSB7Ci0JamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIHNIYW5kbGUsIDApOwotCWppbnQgc3RhdHVzPSAoamludCkgUkMoQ29weVdpbmRvd1RpdGxlQXNDRlN0cmluZygoV2luZG93UmVmKXdIYW5kbGUsIChDRlN0cmluZ1JlZiopIHNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIHNIYW5kbGUsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOworCWlmIChhcmc4KSBscGFyZzggPSAoKmVudiktPkdldEZsb2F0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzgsIE5VTEwpOworCXJjID0gKGppbnQpQ0dJbWFnZUNyZWF0ZSgoc2l6ZV90KWFyZzAsIChzaXplX3QpYXJnMSwgKHNpemVfdClhcmcyLCAoc2l6ZV90KWFyZzMsIChzaXplX3QpYXJnNCwgKENHQ29sb3JTcGFjZVJlZilhcmc1LCAoQ0dJbWFnZUFscGhhSW5mbylhcmc2LCAoQ0dEYXRhUHJvdmlkZXJSZWYpYXJnNywgKGNvbnN0IGZsb2F0ICopbHBhcmc4LCAoQm9vbGVhbilhcmc5LCAoQ0dDb2xvclJlbmRlcmluZ0ludGVudClhcmcxMCk7CisJaWYgKGFyZzgpICgqZW52KS0+UmVsZWFzZUZsb2F0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzgsIGxwYXJnOCwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmIC8qIE5PX0NHSW1hZ2VDcmVhdGUgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0V2luZG93VGl0bGVXaXRoQ0ZTdHJpbmcoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlLCBqaW50IHNIYW5kbGUpIHsKLQlyZXR1cm4gUkMoU2V0V2luZG93VGl0bGVXaXRoQ0ZTdHJpbmcoKFdpbmRvd1JlZil3SGFuZGxlLCAoQ0ZTdHJpbmdSZWYpc0hhbmRsZSkpOwotfQotICAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NpemVXaW5kb3coSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlLCBqc2hvcnQgdywganNob3J0IGgsIGpib29sZWFuIHVwZGF0ZSkgewotCVNpemVXaW5kb3coKFdpbmRvd1JlZil3SGFuZGxlLCB3LCBoLCB1cGRhdGUpOwotfQorI2lmbmRlZiBOT19DR0ltYWdlR2V0QWxwaGFJbmZvCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0ltYWdlR2V0QWxwaGFJbmZvCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkNHSW1hZ2VHZXRBbHBoYUluZm9cbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX01vdmVXaW5kb3coSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlLCBqc2hvcnQgdywganNob3J0IGgsIGpib29sZWFuIHRvRnJvbnQpIHsKLQlNb3ZlV2luZG93KChXaW5kb3dSZWYpd0hhbmRsZSwgdywgaCwgdG9Gcm9udCk7CisJcmV0dXJuIChqaW50KUNHSW1hZ2VHZXRBbHBoYUluZm8oKENHSW1hZ2VSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fQ0dJbWFnZUdldEFscGhhSW5mbyAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TY3JvbGxXaW5kb3dSZWN0KEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSwKLQkJCQkJCWpzaG9ydEFycmF5IHJlY3QsIGpzaG9ydCBkeCwganNob3J0IGR5LCBqaW50IG9wdGlvbnMsIGppbnQgZXhwb3N1cmVSZ24pIHsKLQlqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHJlY3QsIDApOwotCVNjcm9sbFdpbmRvd1JlY3QoKFdpbmRvd1JlZil3SGFuZGxlLCAoUmVjdCopc2EsIGR4LCBkeSwgb3B0aW9ucywgKFJnbkhhbmRsZSkgZXhwb3N1cmVSZ24pOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHJlY3QsIHNhLCAwKTsKLX0KKyNpZm5kZWYgTk9fQ0dJbWFnZUdldEJpdHNQZXJDb21wb25lbnQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHSW1hZ2VHZXRCaXRzUGVyQ29tcG9uZW50CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkNHSW1hZ2VHZXRCaXRzUGVyQ29tcG9uZW50XG4iKQogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRXUmVmQ29uKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSwgamludCBkYXRhKSB7Ci0JU2V0V1JlZkNvbigoV2luZG93UmVmKXdIYW5kbGUsIGRhdGEpOworCXJldHVybiAoamludClDR0ltYWdlR2V0Qml0c1BlckNvbXBvbmVudCgoQ0dJbWFnZVJlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19DR0ltYWdlR2V0Qml0c1BlckNvbXBvbmVudCAqLwogCi0vKgotSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RyYWNrR29Bd2F5KEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSwganNob3J0QXJyYXkgc3RhcnRQdCkgewotCXJldHVybiBUcmFja0dvQXdheSgoV2luZG93UmVmKXdIYW5kbGUsIHBvaW50KGVudiwgc3RhcnRQdCkpOwotfQotKi8KLS8qCi1KTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVHJhY2tCb3goSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlLCBqc2hvcnRBcnJheSBzdGFydFB0LCBqc2hvcnQgcGFydCkgewotCXJldHVybiBUcmFja0JveCgoV2luZG93UmVmKXdIYW5kbGUsIHBvaW50KGVudiwgc3RhcnRQdCksIHBhcnQpOwotfQotKi8KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0Rpc3Bvc2VXaW5kb3coSk5JRW52ICplbnYsIGpjbGFzcyBjbGFzcywgamludCB3SGFuZGxlKSB7Ci0JRGlzcG9zZVdpbmRvdygoV2luZG93UmVmKXdIYW5kbGUpOwotfQotLyoKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1pvb21XaW5kb3coSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlLCBqc2hvcnQgcGFydCwgamJvb2xlYW4gdG9Gcm9udCkgewotCVpvb21XaW5kb3coKFdpbmRvd1JlZil3SGFuZGxlLCBwYXJ0LCB0b0Zyb250KTsKLX0KLSovCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19JbnZhbFdpbmRvd1JlY3QoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlLCBqc2hvcnRBcnJheSBib3VuZHMpIHsKLSAgICBqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgMCk7Ci0JSW52YWxXaW5kb3dSZWN0KChXaW5kb3dSZWYpd0hhbmRsZSwgKFJlY3QqKSBzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCBzYSwgMCk7Ci19CisjaWZuZGVmIE5PX0NHSW1hZ2VHZXRCaXRzUGVyUGl4ZWwKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHSW1hZ2VHZXRCaXRzUGVyUGl4ZWwKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiQ0dJbWFnZUdldEJpdHNQZXJQaXhlbFxuIikKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW52YWxXaW5kb3dSZ24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlLCBqaW50IHJnbkhhbmRsZSkgewotCUludmFsV2luZG93UmduKChXaW5kb3dSZWYpd0hhbmRsZSwgKFJnbkhhbmRsZSlyZ25IYW5kbGUpOworCXJldHVybiAoamludClDR0ltYWdlR2V0Qml0c1BlclBpeGVsKChDR0ltYWdlUmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0NHSW1hZ2VHZXRCaXRzUGVyUGl4ZWwgKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2hvd1dpbmRvdyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHdIYW5kbGUpIHsKLQlTaG93V2luZG93KChXaW5kb3dSZWYpIHdIYW5kbGUpOwotfQorI2lmbmRlZiBOT19DR0ltYWdlR2V0Qnl0ZXNQZXJSb3cKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHSW1hZ2VHZXRCeXRlc1BlclJvdworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJDR0ltYWdlR2V0Qnl0ZXNQZXJSb3dcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hpZGVXaW5kb3coSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlKSB7Ci0JSGlkZVdpbmRvdygoV2luZG93UmVmKSB3SGFuZGxlKTsKKwlyZXR1cm4gKGppbnQpQ0dJbWFnZUdldEJ5dGVzUGVyUm93KChDR0ltYWdlUmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0NHSW1hZ2VHZXRCeXRlc1BlclJvdyAqLwogCi1KTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSXNXaW5kb3dWaXNpYmxlKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSkgewotCXJldHVybiBJc1dpbmRvd1Zpc2libGUoKFdpbmRvd1JlZikgd0hhbmRsZSk7Ci19CisjaWZuZGVmIE5PX0NHSW1hZ2VHZXRDb2xvclNwYWNlCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0ltYWdlR2V0Q29sb3JTcGFjZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJDR0ltYWdlR2V0Q29sb3JTcGFjZVxuIikKIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0V2luZG93RGVmYXVsdEJ1dHRvbihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgd0hhbmRsZSwgamludCBjSGFuZGxlKSB7Ci0JcmV0dXJuIFJDKFNldFdpbmRvd0RlZmF1bHRCdXR0b24oKFdpbmRvd1JlZikgd0hhbmRsZSwgKENvbnRyb2xSZWYpIGNIYW5kbGUpKTsKKwlyZXR1cm4gKGppbnQpQ0dJbWFnZUdldENvbG9yU3BhY2UoKENHSW1hZ2VSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fQ0dJbWFnZUdldENvbG9yU3BhY2UgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0V2luZG93RGVmYXVsdEJ1dHRvbihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgd0hhbmRsZSwgamludEFycmF5IGNIYW5kbGUpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgY0hhbmRsZSwgMCk7Ci0JaW50IHN0YXR1cz0gUkMoR2V0V2luZG93RGVmYXVsdEJ1dHRvbigoV2luZG93UmVmKSB3SGFuZGxlLCAoQ29udHJvbFJlZiopIHNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGNIYW5kbGUsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQorI2lmbmRlZiBOT19DR0ltYWdlR2V0SGVpZ2h0CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0ltYWdlR2V0SGVpZ2h0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkNHSW1hZ2VHZXRIZWlnaHRcbiIpCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFdpbmRvd01vZGFsaXR5KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCB3SGFuZGxlLCBqaW50QXJyYXkgd2luZG93TW9kYWxpdHksIGppbnRBcnJheSBwYXJlbnRXaW5kb3dIYW5kbGUpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgd2luZG93TW9kYWxpdHksIDApOwotCWppbnQgKnNiPSBOVUxMOwotCWppbnQgc3RhdHVzPSAwOwotCWlmIChwYXJlbnRXaW5kb3dIYW5kbGUgIT0gMCkKLQkJc2I9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIHBhcmVudFdpbmRvd0hhbmRsZSwgMCk7Ci0Jc3RhdHVzPSAoamludCkgUkMoR2V0V2luZG93TW9kYWxpdHkoKFdpbmRvd1JlZikgd0hhbmRsZSwgKFdpbmRvd01vZGFsaXR5Kikgc2EsIChXaW5kb3dSZWYqKSBzYikpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCB3aW5kb3dNb2RhbGl0eSwgc2EsIDApOwotCWlmIChzYiAhPSBOVUxMKQotCQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgcGFyZW50V2luZG93SGFuZGxlLCBzYiwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKKwlyZXR1cm4gKGppbnQpQ0dJbWFnZUdldEhlaWdodCgoQ0dJbWFnZVJlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19DR0ltYWdlR2V0SGVpZ2h0ICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldFdpbmRvd01vZGFsaXR5KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCB3SGFuZGxlLCBqaW50IG1vZGFsaXR5S2luZCwgamludCBwYXJlbnRXaW5kb3cpIHsKLQlyZXR1cm4gKGppbnQpIFJDKFNldFdpbmRvd01vZGFsaXR5KChXaW5kb3dSZWYpIHdIYW5kbGUsIChXaW5kb3dNb2RhbGl0eSkgbW9kYWxpdHlLaW5kLCAoV2luZG93UmVmKSBwYXJlbnRXaW5kb3cpKTsKLX0KKyNpZm5kZWYgTk9fQ0dJbWFnZUdldFdpZHRoCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0ltYWdlR2V0V2lkdGgKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiQ0dJbWFnZUdldFdpZHRoXG4iKQogCi1KTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSXNXaW5kb3dBY3RpdmUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlKSB7Ci0JcmV0dXJuIChqYm9vbGVhbikgSXNXaW5kb3dBY3RpdmUoKFdpbmRvd1JlZikgd0hhbmRsZSk7CisJcmV0dXJuIChqaW50KUNHSW1hZ2VHZXRXaWR0aCgoQ0dJbWFnZVJlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19DR0ltYWdlR2V0V2lkdGggKi8KIAotLy8tLS0tIE1lbnUgTWFuYWdlcgotICAgCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Jbml0Q29udGV4dHVhbE1lbnVzKEpOSUVudiAqZW52LCBqY2xhc3MgenopIHsKLQlyZXR1cm4gKGppbnQpIFJDKEluaXRDb250ZXh0dWFsTWVudXMoKSk7Ci19CisjaWZuZGVmIE5PX0NHSW1hZ2VSZWxlYXNlCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0ltYWdlUmVsZWFzZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJDR0ltYWdlUmVsZWFzZVxuIikKIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ3JlYXRlTmV3TWVudShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgbWVudUlkLCBqaW50IG1lbnVBdHRyaWJ1dGVzLCBqaW50QXJyYXkgbWVudVJlZikgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBtZW51UmVmLCAwKTsKLQlqaW50IHN0YXR1cz0gKGppbnQpIFJDKENyZWF0ZU5ld01lbnUoKE1lbnVJRCltZW51SWQsIChNZW51QXR0cmlidXRlcyltZW51QXR0cmlidXRlcywgKE1lbnVSZWYqKXNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIG1lbnVSZWYsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOworCUNHSW1hZ2VSZWxlYXNlKChDR0ltYWdlUmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0NHSW1hZ2VSZWxlYXNlICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX01lbnVTZWxlY3QoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0QXJyYXkgd2hlcmUpIHsKLQlyZXR1cm4gTWVudVNlbGVjdChwb2ludChlbnYsIHdoZXJlKSk7Ci19CisjaWZuZGVmIE5PX0NhbGxOZXh0RXZlbnRIYW5kbGVyCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DYWxsTmV4dEV2ZW50SGFuZGxlcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIkNhbGxOZXh0RXZlbnRIYW5kbGVyXG4iKQogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19IaWxpdGVNZW51KEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzaG9ydCBtZW51SUQpIHsKLQlIaWxpdGVNZW51KG1lbnVJRCk7CisJcmV0dXJuIChqaW50KUNhbGxOZXh0RXZlbnRIYW5kbGVyKChFdmVudEhhbmRsZXJDYWxsUmVmKWFyZzAsIChFdmVudFJlZilhcmcxKTsKIH0KKyNlbmRpZiAvKiBOT19DYWxsTmV4dEV2ZW50SGFuZGxlciAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19JbnZhbE1lbnVCYXIoSk5JRW52ICplbnYsIGpjbGFzcyB6eikgewotCUludmFsTWVudUJhcigpOwotfQorI2lmbmRlZiBOT19DaGFyV2lkdGgKK0pOSUVYUE9SVCBqc2hvcnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ2hhcldpZHRoCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwganNob3J0IGFyZzApCit7CisJREVCVUdfQ0FMTCgiQ2hhcldpZHRoXG4iKQogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EcmF3TWVudUJhcihKTklFbnYgKmVudiwgamNsYXNzIHp6KSB7Ci0JRHJhd01lbnVCYXIoKTsKKwlyZXR1cm4gKGpzaG9ydClDaGFyV2lkdGgoKENoYXJQYXJhbWV0ZXIpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fQ2hhcldpZHRoICovCiAKLUpOSUVYUE9SVCBqc2hvcnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ291bnRNZW51SXRlbXMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlKSB7Ci0JcmV0dXJuIENvdW50TWVudUl0ZW1zKChNZW51UmVmKW1IYW5kbGUpOwotfQorI2lmbmRlZiBOT19DbGVhckN1cnJlbnRTY3JhcAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ2xlYXJDdXJyZW50U2NyYXAKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0KQoreworCURFQlVHX0NBTEwoIkNsZWFyQ3VycmVudFNjcmFwXG4iKQogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EZWxldGVNZW51SXRlbXMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgbUhhbmRsZSwganNob3J0IGZpcnN0SXRlbSwgamludCBudW1JdGVtcykgewotCXJldHVybiBSQyhEZWxldGVNZW51SXRlbXMoKE1lbnVSZWYpbUhhbmRsZSwgZmlyc3RJdGVtLCBudW1JdGVtcykpOworCXJldHVybiAoamludClDbGVhckN1cnJlbnRTY3JhcCgpOwogfQorI2VuZGlmIC8qIE5PX0NsZWFyQ3VycmVudFNjcmFwICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0Rpc3Bvc2VNZW51KEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgbUhhbmRsZSkgewotCURpc3Bvc2VNZW51KChNZW51UmVmKSBtSGFuZGxlKTsKLX0KKyNpZm5kZWYgTk9fQ2xlYXJLZXlib2FyZEZvY3VzCitKTklFWFBPUlQgamludCBKTklDQUxMIE9TX05BVElWRShDbGVhcktleWJvYXJkRm9jdXMpCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkNsZWFyS2V5Ym9hcmRGb2N1c1xuIikKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW5zZXJ0TWVudShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUsIGpzaG9ydCBpbmRleCkgewotCUluc2VydE1lbnUoKE1lbnVSZWYpIG1IYW5kbGUsIGluZGV4KTsKKwlyZXR1cm4gKGppbnQpQ2xlYXJLZXlib2FyZEZvY3VzKChXaW5kb3dSZWYpYXJnMCk7CiB9CisjZW5kaWYKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGVsZXRlTWVudShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqc2hvcnQgbWVudUlkKSB7Ci0JRGVsZXRlTWVudShtZW51SWQpOwotfQorI2lmbmRlZiBOT19DbGVhck1lbnVCYXIKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NsZWFyTWVudUJhcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiQ2xlYXJNZW51QmFyXG4iKQogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DbGVhck1lbnVCYXIoSk5JRW52ICplbnYsIGpjbGFzcyB6eikgewogCUNsZWFyTWVudUJhcigpOwogfQorI2VuZGlmIC8qIE5PX0NsZWFyTWVudUJhciAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRNZW51SXRlbVJlZkNvbihKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUsCi0JCQlqc2hvcnQgaW5kZXgsIGppbnRBcnJheSByZWZDb24pIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgcmVmQ29uLCAwKTsKLQlpbnQgc3RhdHVzPSBSQyhHZXRNZW51SXRlbVJlZkNvbigoTWVudVJlZikgbUhhbmRsZSwgaW5kZXgsIHNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIHJlZkNvbiwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7CisjaWZuZGVmIE5PX0NsaXBDR0NvbnRleHRUb1JlZ2lvbgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ2xpcENHQ29udGV4dFRvUmVnaW9uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEsIGppbnQgYXJnMikKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNsaXBDR0NvbnRleHRUb1JlZ2lvblxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlyYyA9IChqaW50KUNsaXBDR0NvbnRleHRUb1JlZ2lvbigoQ0dDb250ZXh0UmVmKWFyZzAsIChjb25zdCBSZWN0ICopbHBhcmcxLCAoUmduSGFuZGxlKWFyZzIpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fQ2xpcENHQ29udGV4dFRvUmVnaW9uICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldE1lbnVJdGVtUmVmQ29uKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgbUhhbmRsZSwKLQkJCWpzaG9ydCBpbmRleCwgamludCByZWZDb24pIHsKLQlyZXR1cm4gUkMoU2V0TWVudUl0ZW1SZWZDb24oKE1lbnVSZWYpIG1IYW5kbGUsIGluZGV4LCByZWZDb24pKTsKKyNpZm5kZWYgTk9fQ2xvc2VEYXRhQnJvd3NlckNvbnRhaW5lcgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ2xvc2VEYXRhQnJvd3NlckNvbnRhaW5lcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIkNsb3NlRGF0YUJyb3dzZXJDb250YWluZXJcbiIpCisKKwlyZXR1cm4gKGppbnQpQ2xvc2VEYXRhQnJvd3NlckNvbnRhaW5lcigoQ29udHJvbFJlZilhcmcwLCAoRGF0YUJyb3dzZXJJdGVtSUQpYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fQ2xvc2VEYXRhQnJvd3NlckNvbnRhaW5lciAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlLAotCQkJanNob3J0IGluZGV4LCBqaW50IHNIYW5kbGUpIHsKLQlyZXR1cm4gUkMoU2V0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nKChNZW51UmVmKSBtSGFuZGxlLCBpbmRleCwgKENGU3RyaW5nUmVmKSBzSGFuZGxlKSk7CisjaWZuZGVmIE5PX0Nsb3NlUG9seQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ2xvc2VQb2x5CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCkKK3sKKwlERUJVR19DQUxMKCJDbG9zZVBvbHlcbiIpCisKKwlDbG9zZVBvbHkoKTsKIH0KKyNlbmRpZiAvKiBOT19DbG9zZVBvbHkgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ29weU1lbnVJdGVtVGV4dEFzQ0ZTdHJpbmcoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgbUhhbmRsZSwganNob3J0IGluZGV4LCBqaW50QXJyYXkgc0hhbmRsZSkgewotCQkJCi0JamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIHNIYW5kbGUsIDApOwotCWppbnQgc3RhdHVzPSAoamludCkgUkMoQ29weU1lbnVJdGVtVGV4dEFzQ0ZTdHJpbmcoKE1lbnVSZWYpIG1IYW5kbGUsIGluZGV4LCAoQ0ZTdHJpbmdSZWYqKSBzYSkpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBzSGFuZGxlLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKKyNpZm5kZWYgTk9fQ29sbGFwc2VXaW5kb3cKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NvbGxhcHNlV2luZG93CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqYm9vbGVhbiBhcmcxKQoreworCURFQlVHX0NBTEwoIkNvbGxhcHNlV2luZG93XG4iKQorCisJcmV0dXJuIChqaW50KUNvbGxhcHNlV2luZG93KChXaW5kb3dSZWYpYXJnMCwgKEJvb2xlYW4pYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fQ29sbGFwc2VXaW5kb3cgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0TWVudUl0ZW1Db21tYW5kS2V5KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCWppbnQgbUhhbmRsZSwganNob3J0IGluZGV4LCBqYm9vbGVhbiB2aXJ0dWFsLCBqY2hhciBrZXkpIHsKLQlyZXR1cm4gUkMoU2V0TWVudUl0ZW1Db21tYW5kS2V5KChNZW51UmVmKSBtSGFuZGxlLCBpbmRleCwgdmlydHVhbCwga2V5KSk7CisjaWZuZGVmIE5PX0NvbnZlcnRFdmVudFJlZlRvRXZlbnRSZWNvcmQKK0pOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Db252ZXJ0RXZlbnRSZWZUb0V2ZW50UmVjb3JkCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEpCit7CisJRXZlbnRSZWNvcmQgX2FyZzEsICpscGFyZzE9TlVMTDsKKwlqYm9vbGVhbiByYzsKKworCURFQlVHX0NBTEwoIkNvbnZlcnRFdmVudFJlZlRvRXZlbnRSZWNvcmRcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0RXZlbnRSZWNvcmRGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCXJjID0gKGpib29sZWFuKUNvbnZlcnRFdmVudFJlZlRvRXZlbnRSZWNvcmQoKEV2ZW50UmVmKWFyZzAsIChFdmVudFJlY29yZCAqKWxwYXJnMSk7CisJaWYgKGFyZzEpIHNldEV2ZW50UmVjb3JkRmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fQ29udmVydEV2ZW50UmVmVG9FdmVudFJlY29yZCAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRNZW51SXRlbU1vZGlmaWVycyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQlqaW50IG1IYW5kbGUsIGpzaG9ydCBpbmRleCwgamJ5dGUgbW9kaWZpZXJzKSB7Ci0JcmV0dXJuIFJDKFNldE1lbnVJdGVtTW9kaWZpZXJzKChNZW51UmVmKSBtSGFuZGxlLCBpbmRleCwgbW9kaWZpZXJzKSk7CisjaWZuZGVmIE5PX0NvcHlCaXRzCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Db3B5Qml0cworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqb2JqZWN0IGFyZzIsIGpvYmplY3QgYXJnMywganNob3J0IGFyZzQsIGppbnQgYXJnNSkKK3sKKwlSZWN0IF9hcmcyLCAqbHBhcmcyPU5VTEw7CisJUmVjdCBfYXJnMywgKmxwYXJnMz1OVUxMOworCisJREVCVUdfQ0FMTCgiQ29weUJpdHNcbiIpCisKKwlpZiAoYXJnMikgbHBhcmcyID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzIsICZfYXJnMik7CisJaWYgKGFyZzMpIGxwYXJnMyA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmczLCAmX2FyZzMpOworCUNvcHlCaXRzKChjb25zdCBCaXRNYXAgKilhcmcwLCAoY29uc3QgQml0TWFwICopYXJnMSwgKGNvbnN0IFJlY3QgKilscGFyZzIsIChjb25zdCBSZWN0ICopbHBhcmczLCAoc2hvcnQpYXJnNCwgKFJnbkhhbmRsZSlhcmc1KTsKKwlpZiAoYXJnMikgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzIsIGxwYXJnMik7CisJaWYgKGFyZzMpIHNldFJlY3RGaWVsZHMoZW52LCBhcmczLCBscGFyZzMpOwogfQorI2VuZGlmIC8qIE5PX0NvcHlCaXRzICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldE1lbnVJdGVtS2V5R2x5cGgoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJamludCBtSGFuZGxlLCBqc2hvcnQgaW5kZXgsIGpzaG9ydCBnbHlwaCkgewotCXJldHVybiBSQyhTZXRNZW51SXRlbUtleUdseXBoKChNZW51UmVmKSBtSGFuZGxlLCBpbmRleCwgZ2x5cGgpKTsKKyNpZm5kZWYgTk9fQ29weUNvbnRyb2xUaXRsZUFzQ0ZTdHJpbmcKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NvcHlDb250cm9sVGl0bGVBc0NGU3RyaW5nCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50QXJyYXkgYXJnMSkKK3sKKwlqaW50ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQ29weUNvbnRyb2xUaXRsZUFzQ0ZTdHJpbmdcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJcmMgPSAoamludClDb3B5Q29udHJvbFRpdGxlQXNDRlN0cmluZygoQ29udHJvbFJlZilhcmcwLCAoQ0ZTdHJpbmdSZWYgKilscGFyZzEpOworCWlmIChhcmcxKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fQ29weUNvbnRyb2xUaXRsZUFzQ0ZTdHJpbmcgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW52YWxpZGF0ZU1lbnVJdGVtcyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQlqaW50IG1IYW5kbGUsIGpzaG9ydCBpbmRleCwgamludCBudW1JdGVtcykgewotCXJldHVybiBSQyhJbnZhbGlkYXRlTWVudUl0ZW1zKChNZW51UmVmKSBtSGFuZGxlLCBpbmRleCwgbnVtSXRlbXMpKTsKKyNpZm5kZWYgTk9fQ29weURlZXBNYXNrCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Db3B5RGVlcE1hc2sKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqb2JqZWN0IGFyZzMsIGpvYmplY3QgYXJnNCwgam9iamVjdCBhcmc1LCBqc2hvcnQgYXJnNiwgamludCBhcmc3KQoreworCVJlY3QgX2FyZzMsICpscGFyZzM9TlVMTDsKKwlSZWN0IF9hcmc0LCAqbHBhcmc0PU5VTEw7CisJUmVjdCBfYXJnNSwgKmxwYXJnNT1OVUxMOworCisJREVCVUdfQ0FMTCgiQ29weURlZXBNYXNrXG4iKQorCisJaWYgKGFyZzMpIGxwYXJnMyA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmczLCAmX2FyZzMpOworCWlmIChhcmc0KSBscGFyZzQgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnNCwgJl9hcmc0KTsKKwlpZiAoYXJnNSkgbHBhcmc1ID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzUsICZfYXJnNSk7CisJQ29weURlZXBNYXNrKChjb25zdCBCaXRNYXAgKilhcmcwLCAoY29uc3QgQml0TWFwICopYXJnMSwgKGNvbnN0IEJpdE1hcCAqKWFyZzIsIChjb25zdCBSZWN0ICopbHBhcmczLCAoY29uc3QgUmVjdCAqKWxwYXJnNCwgKGNvbnN0IFJlY3QgKilscGFyZzUsIChzaG9ydClhcmc2LCAoUmduSGFuZGxlKWFyZzcpOworCWlmIChhcmczKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMywgbHBhcmczKTsKKwlpZiAoYXJnNCkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzQsIGxwYXJnNCk7CisJaWYgKGFyZzUpIHNldFJlY3RGaWVsZHMoZW52LCBhcmc1LCBscGFyZzUpOwogfQorI2VuZGlmIC8qIE5PX0NvcHlEZWVwTWFzayAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19JbnNlcnRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgbUhhbmRsZSwgamludCBzSGFuZGxlLCBqc2hvcnQgaW5kZXgsIGppbnQgYXR0cmlidXRlcywgamludCBjb21tYW5kSUQpIHsKLQlyZXR1cm4gUkMoSW5zZXJ0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nKChNZW51UmVmKSBtSGFuZGxlLCAoQ0ZTdHJpbmdSZWYpIHNIYW5kbGUsIGluZGV4LCBhdHRyaWJ1dGVzLCBjb21tYW5kSUQpKTsKKyNpZm5kZWYgTk9fQ29weU1lbnVJdGVtVGV4dEFzQ0ZTdHJpbmcKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NvcHlNZW51SXRlbVRleHRBc0NGU3RyaW5nCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJamludCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNvcHlNZW51SXRlbVRleHRBc0NGU3RyaW5nXG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpQ29weU1lbnVJdGVtVGV4dEFzQ0ZTdHJpbmcoKE1lbnVSZWYpYXJnMCwgKE1lbnVJdGVtSW5kZXgpYXJnMSwgKENGU3RyaW5nUmVmICopbHBhcmcyKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmIC8qIE5PX0NvcHlNZW51SXRlbVRleHRBc0NGU3RyaW5nICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0FwcGVuZE1lbnVJdGVtVGV4dFdpdGhDRlN0cmluZyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBtSGFuZGxlLCBqaW50IHNIYW5kbGUsIGppbnQgYXR0cmlidXRlcywgamludCBjb21tYW5kSUQsIGpzaG9ydEFycmF5IG91dEl0ZW1JbmRleCkgewotCQkKLQlqaW50IHN0YXR1czsKLSAgICAgICAganNob3J0ICpzYT0gTlVMTDsKLQlpZiAob3V0SXRlbUluZGV4ICE9IDApCi0JCSgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgb3V0SXRlbUluZGV4LCAwKTsKLQlzdGF0dXM9IChqaW50KSBSQyhBcHBlbmRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcoKE1lbnVSZWYpIG1IYW5kbGUsIChDRlN0cmluZ1JlZikgc0hhbmRsZSwgYXR0cmlidXRlcywgY29tbWFuZElELCAoTWVudUl0ZW1JbmRleCopIHNhKSk7Ci0JaWYgKHNhICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIG91dEl0ZW1JbmRleCwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7CisjaWZuZGVmIE5PX0NvcHlSZ24KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NvcHlSZ24KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJDb3B5UmduXG4iKQorCisJQ29weVJnbigoUmduSGFuZGxlKWFyZzAsIChSZ25IYW5kbGUpYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fQ29weVJnbiAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19FbmFibGVNZW51Q29tbWFuZChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUsIGppbnQgY29tbWFuZElkKSB7Ci0JRW5hYmxlTWVudUNvbW1hbmQoKE1lbnVSZWYpIG1IYW5kbGUsIGNvbW1hbmRJZCk7CisjaWZuZGVmIE5PX0NvdW50TWVudUl0ZW1zCitKTklFWFBPUlQganNob3J0IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NvdW50TWVudUl0ZW1zCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkNvdW50TWVudUl0ZW1zXG4iKQorCisJcmV0dXJuIChqc2hvcnQpQ291bnRNZW51SXRlbXMoKE1lbnVSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fQ291bnRNZW51SXRlbXMgKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGlzYWJsZU1lbnVDb21tYW5kKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgbUhhbmRsZSwgamludCBjb21tYW5kSWQpIHsKLQlEaXNhYmxlTWVudUNvbW1hbmQoKE1lbnVSZWYpIG1IYW5kbGUsIGNvbW1hbmRJZCk7CisjaWZuZGVmIE5PX0NvdW50U3ViQ29udHJvbHMKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NvdW50U3ViQ29udHJvbHMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydEFycmF5IGFyZzEpCit7CisJanNob3J0ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQ291bnRTdWJDb250cm9sc1xuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCXJjID0gKGppbnQpQ291bnRTdWJDb250cm9scygoQ29udHJvbFJlZilhcmcwLCAoVUludDE2ICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fQ291bnRTdWJDb250cm9scyAqLwogCi1KTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSXNNZW51Q29tbWFuZEVuYWJsZWQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlLCBqaW50IGNvbW1hbmRJZCkgewotCXJldHVybiAoamJvb2xlYW4pIElzTWVudUNvbW1hbmRFbmFibGVkKChNZW51UmVmKSBtSGFuZGxlLCBjb21tYW5kSWQpOworI2lmbmRlZiBOT19DcmVhdGVCZXZlbEJ1dHRvbkNvbnRyb2wKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NyZWF0ZUJldmVsQnV0dG9uQ29udHJvbAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxLCBqaW50IGFyZzIsIGpzaG9ydCBhcmczLCBqc2hvcnQgYXJnNCwgamludCBhcmc1LCBqc2hvcnQgYXJnNiwganNob3J0IGFyZzcsIGpzaG9ydCBhcmc4LCBqaW50QXJyYXkgYXJnOSkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCAqbHBhcmc5PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZUJldmVsQnV0dG9uQ29udHJvbFxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlpZiAoYXJnOSkgbHBhcmc5ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnOSwgTlVMTCk7CisJcmMgPSAoamludClDcmVhdGVCZXZlbEJ1dHRvbkNvbnRyb2woKFdpbmRvd1JlZilhcmcwLCAoY29uc3QgUmVjdCAqKWxwYXJnMSwgKENGU3RyaW5nUmVmKWFyZzIsIChDb250cm9sQmV2ZWxUaGlja25lc3MpYXJnMywgKENvbnRyb2xCZXZlbEJ1dHRvbkJlaGF2aW9yKWFyZzQsIChDb250cm9sQnV0dG9uQ29udGVudEluZm9QdHIpYXJnNSwgKFNJbnQxNilhcmc2LCAoQ29udHJvbEJldmVsQnV0dG9uTWVudUJlaGF2aW9yKWFyZzcsIChDb250cm9sQmV2ZWxCdXR0b25NZW51UGxhY2VtZW50KWFyZzgsIChDb250cm9sUmVmICopbHBhcmc5KTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJaWYgKGFyZzkpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc5LCBscGFyZzksIDApOworCXJldHVybiByYzsKIH0KKyNlbmRpZgogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRJbmRNZW51SXRlbVdpdGhDb21tYW5kSUQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlLAotCQkJamludCBjb21tYW5kSWQsIGppbnQgaW5kZXgsIGppbnRBcnJheSBvdXRNZW51LCBqc2hvcnRBcnJheSBvdXRJbmRleCkgewotCWppbnQgc3RhdHVzOwotICAgICAgICBqaW50ICpzYT0gTlVMTDsKLSAgICAgICAganNob3J0ICpzYj0gTlVMTDsKLQlpZiAob3V0TWVudSAhPSBOVUxMKQotCQlzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0TWVudSwgMCk7Ci0JaWYgKG91dEluZGV4ICE9IE5VTEwpIAotCQlzYj0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBvdXRJbmRleCwgMCk7Ci0Jc3RhdHVzPSAoamludCkgUkMoR2V0SW5kTWVudUl0ZW1XaXRoQ29tbWFuZElEKChNZW51UmVmKSBtSGFuZGxlLCBjb21tYW5kSWQsIGluZGV4LCAoTWVudVJlZiopc2EsIHNiKSk7Ci0JaWYgKHNhICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBvdXRNZW51LCBzYSwgMCk7Ci0JaWYgKHNiICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIG91dEluZGV4LCBzYiwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKKyNpZm5kZWYgTk9fQ3JlYXRlQ2hlY2tCb3hDb250cm9sCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DcmVhdGVDaGVja0JveENvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMsIGpib29sZWFuIGFyZzQsIGppbnRBcnJheSBhcmc1KQoreworCVJlY3QgX2FyZzEsICpscGFyZzE9TlVMTDsKKwlqaW50ICpscGFyZzU9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQ3JlYXRlQ2hlY2tCb3hDb250cm9sXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCWlmIChhcmc1KSBscGFyZzUgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBOVUxMKTsKKwlyYyA9IChqaW50KUNyZWF0ZUNoZWNrQm94Q29udHJvbCgoV2luZG93UmVmKWFyZzAsIChjb25zdCBSZWN0ICopbHBhcmcxLCAoQ0ZTdHJpbmdSZWYpYXJnMiwgKFNJbnQzMilhcmczLCAoQm9vbGVhbilhcmc0LCAoQ29udHJvbFJlZiAqKWxwYXJnNSk7CisJaWYgKGFyZzEpIHNldFJlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGVsZXRlTWVudUl0ZW0oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlLCBqc2hvcnQgaW5kZXgpIHsKLQlEZWxldGVNZW51SXRlbSgoTWVudVJlZikgbUhhbmRsZSwgaW5kZXgpOworI2lmbmRlZiBOT19DcmVhdGVDR0NvbnRleHRGb3JQb3J0CitKTklFWFBPUlQgamludCBKTklDQUxMIE9TX05BVElWRShDcmVhdGVDR0NvbnRleHRGb3JQb3J0KQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludEFycmF5IGFyZzEpCit7CisJamludCAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZUNHQ29udGV4dEZvclBvcnRcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJcmMgPSAoamludClDcmVhdGVDR0NvbnRleHRGb3JQb3J0KChDR3JhZlB0cilhcmcwLCAoQ0dDb250ZXh0UmVmICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldE1lbnVJdGVtQ29tbWFuZElEKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgbUhhbmRsZSwganNob3J0IGluZGV4LAotCQkJamludEFycmF5IGNvbW1hbmRJZCkgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBjb21tYW5kSWQsIDApOwotCWppbnQgc3RhdHVzPSAoamludCkgUkMoR2V0TWVudUl0ZW1Db21tYW5kSUQoKE1lbnVSZWYpIG1IYW5kbGUsIGluZGV4LCAoTWVudUNvbW1hbmQqKXNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGNvbW1hbmRJZCwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7CisjaWZuZGVmIE5PX0NyZWF0ZURhdGFCcm93c2VyQ29udHJvbAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ3JlYXRlRGF0YUJyb3dzZXJDb250cm9sCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEsIGppbnQgYXJnMiwgamludEFycmF5IGFyZzMpCit7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCWppbnQgKmxwYXJnMz1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJDcmVhdGVEYXRhQnJvd3NlckNvbnRyb2xcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJaWYgKGFyZzMpIGxwYXJnMyA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIE5VTEwpOworCXJjID0gKGppbnQpQ3JlYXRlRGF0YUJyb3dzZXJDb250cm9sKChXaW5kb3dSZWYpYXJnMCwgKGNvbnN0IFJlY3QgKilscGFyZzEsIChEYXRhQnJvd3NlclZpZXdTdHlsZSlhcmcyLCAoQ29udHJvbFJlZiAqKWxwYXJnMyk7CisJaWYgKGFyZzEpIHNldFJlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fQ3JlYXRlRGF0YUJyb3dzZXJDb250cm9sICovCiAKLUpOSUVYUE9SVCBqc2hvcnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0TWVudUlEKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgbUhhbmRsZSkgewotCXJldHVybiAoanNob3J0KSBHZXRNZW51SUQoKE1lbnVSZWYpIG1IYW5kbGUpOworI2lmbmRlZiBOT19DcmVhdGVFdmVudAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ3JlYXRlRXZlbnQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqZG91YmxlIGFyZzMsIGppbnQgYXJnNCwgamludEFycmF5IGFyZzUpCit7CisJamludCAqbHBhcmc1PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZUV2ZW50XG4iKQorCisJaWYgKGFyZzUpIGxwYXJnNSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIE5VTEwpOworCXJjID0gKGppbnQpQ3JlYXRlRXZlbnQoKENGQWxsb2NhdG9yUmVmKWFyZzAsIChVSW50MzIpYXJnMSwgKFVJbnQzMilhcmcyLCAoRXZlbnRUaW1lKWFyZzMsIChFdmVudEF0dHJpYnV0ZXMpYXJnNCwgKEV2ZW50UmVmICopbHBhcmc1KTsKKwlpZiAoYXJnNSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIGxwYXJnNSwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmIC8qIE5PX0NyZWF0ZUV2ZW50ICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldE1lbnVIYW5kbGUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0IG1lbnVJZCkgewotCXJldHVybiAoamludCkgR2V0TWVudUhhbmRsZShtZW51SWQpOworI2lmbmRlZiBOT19DcmVhdGVHcm91cEJveENvbnRyb2wKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NyZWF0ZUdyb3VwQm94Q29udHJvbAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxLCBqaW50IGFyZzIsIGpib29sZWFuIGFyZzMsIGppbnRBcnJheSBhcmc0KQoreworCVJlY3QgX2FyZzEsICpscGFyZzE9TlVMTDsKKwlqaW50ICpscGFyZzQ9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQ3JlYXRlR3JvdXBCb3hDb250cm9sXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCWlmIChhcmc0KSBscGFyZzQgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlyYyA9IChqaW50KUNyZWF0ZUdyb3VwQm94Q29udHJvbCgoV2luZG93UmVmKWFyZzAsIChjb25zdCBSZWN0ICopbHBhcmcxLCAoQ0ZTdHJpbmdSZWYpYXJnMiwgKEJvb2xlYW4pYXJnMywgKENvbnRyb2xSZWYgKilscGFyZzQpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1BvcFVwTWVudVNlbGVjdChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUsCi0JCWpzaG9ydCB4LCBqc2hvcnQgeSwganNob3J0IGluZGV4KSB7Ci0JcmV0dXJuIFBvcFVwTWVudVNlbGVjdCgoTWVudVJlZikgbUhhbmRsZSwgeCwgeSwgaW5kZXgpOworI2lmbmRlZiBOT19DcmVhdGVJY29uQ29udHJvbAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBPU19OQVRJVkUoQ3JlYXRlSWNvbkNvbnRyb2wpCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEsIGpvYmplY3QgYXJnMiwgamJvb2xlYW4gYXJnMywgamludEFycmF5IGFyZzQpCit7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCUNvbnRyb2xCdXR0b25Db250ZW50SW5mbyBfYXJnMiwgKmxwYXJnMj1OVUxMOworCWppbnQgKmxwYXJnND1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJDcmVhdGVJY29uQ29udHJvbFxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlpZiAoYXJnMikgbHBhcmcyID0gZ2V0Q29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmllbGRzKGVudiwgYXJnMiwgJl9hcmcyKTsKKwlpZiAoYXJnNCkgbHBhcmc0ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNCwgTlVMTCk7CisJcmMgPSAoamludClDcmVhdGVJY29uQ29udHJvbCgoV2luZG93UmVmKWFyZzAsIGxwYXJnMSwgbHBhcmcyLCBhcmczLCAoQ29udHJvbFJlZiAqKWxwYXJnNCk7CisJaWYgKGFyZzEpIHNldFJlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmcyKSBzZXRDb250cm9sQnV0dG9uQ29udGVudEluZm9GaWVsZHMoZW52LCBhcmcyLCBscGFyZzIpOworCWlmIChhcmc0KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNCwgbHBhcmc0LCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYKIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0Um9vdE1lbnUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBSQyhTZXRSb290TWVudSgoTWVudVJlZikgbUhhbmRsZSkpOworI2lmbmRlZiBOT19DcmVhdGVOZXdNZW51CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DcmVhdGVOZXdNZW51CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwganNob3J0IGFyZzAsIGppbnQgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJamludCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZU5ld01lbnVcbiIpCisKKwlpZiAoYXJnMikgbHBhcmcyID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJcmMgPSAoamludClDcmVhdGVOZXdNZW51KChNZW51SUQpYXJnMCwgKE1lbnVBdHRyaWJ1dGVzKWFyZzEsIChNZW51UmVmICopbHBhcmcyKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmIC8qIE5PX0NyZWF0ZU5ld01lbnUgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUmV0YWluTWVudShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUpIHsKLQlyZXR1cm4gKGppbnQpIFJDKFJldGFpbk1lbnUoKE1lbnVSZWYpIG1IYW5kbGUpKTsKKyNpZm5kZWYgTk9fQ3JlYXRlTmV3V2luZG93CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DcmVhdGVOZXdXaW5kb3cKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgam9iamVjdCBhcmcyLCBqaW50QXJyYXkgYXJnMykKK3sKKwlSZWN0IF9hcmcyLCAqbHBhcmcyPU5VTEw7CisJamludCAqbHBhcmczPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZU5ld1dpbmRvd1xuIikKKworCWlmIChhcmcyKSBscGFyZzIgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMiwgJl9hcmcyKTsKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJcmMgPSAoamludClDcmVhdGVOZXdXaW5kb3coKFdpbmRvd0NsYXNzKWFyZzAsIChXaW5kb3dBdHRyaWJ1dGVzKWFyZzEsIChjb25zdCBSZWN0ICopbHBhcmcyLCAoV2luZG93UmVmICopbHBhcmczKTsKKwlpZiAoYXJnMikgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzIsIGxwYXJnMik7CisJaWYgKGFyZzMpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBscGFyZzMsIDApOworCXJldHVybiByYzsKIH0KKyNlbmRpZiAvKiBOT19DcmVhdGVOZXdXaW5kb3cgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUmVsZWFzZU1lbnUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBSQyhSZWxlYXNlTWVudSgoTWVudVJlZikgbUhhbmRsZSkpOworI2lmbmRlZiBOT19DcmVhdGVQb3B1cEFycm93Q29udHJvbAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ3JlYXRlUG9wdXBBcnJvd0NvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwganNob3J0IGFyZzIsIGpzaG9ydCBhcmczLCBqaW50QXJyYXkgYXJnNCkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCAqbHBhcmc0PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZVBvcHVwQXJyb3dDb250cm9sXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCWlmIChhcmc0KSBscGFyZzQgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlyYyA9IChqaW50KUNyZWF0ZVBvcHVwQXJyb3dDb250cm9sKChXaW5kb3dSZWYpYXJnMCwgKGNvbnN0IFJlY3QgKilscGFyZzEsIChDb250cm9sUG9wdXBBcnJvd09yaWVudGF0aW9uKWFyZzIsIChDb250cm9sUG9wdXBBcnJvd1NpemUpYXJnMywgKENvbnRyb2xSZWYgKilscGFyZzQpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldE1lbnVUaXRsZVdpdGhDRlN0cmluZyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUsIGppbnQgc0hhbmRsZSkgewotCXJldHVybiAoamludCkgUkMoU2V0TWVudVRpdGxlV2l0aENGU3RyaW5nKChNZW51UmVmKSBtSGFuZGxlLCAoQ0ZTdHJpbmdSZWYpIHNIYW5kbGUpKTsKKyNpZm5kZWYgTk9fQ3JlYXRlUG9wdXBCdXR0b25Db250cm9sCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DcmVhdGVQb3B1cEJ1dHRvbkNvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyLCBqc2hvcnQgYXJnMywgamJvb2xlYW4gYXJnNCwganNob3J0IGFyZzUsIGpzaG9ydCBhcmc2LCBqaW50IGFyZzcsIGppbnRBcnJheSBhcmc4KQoreworCVJlY3QgX2FyZzEsICpscGFyZzE9TlVMTDsKKwlqaW50ICpscGFyZzg9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQ3JlYXRlUG9wdXBCdXR0b25Db250cm9sXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCWlmIChhcmc4KSBscGFyZzggPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc4LCBOVUxMKTsKKwlyYyA9IChqaW50KUNyZWF0ZVBvcHVwQnV0dG9uQ29udHJvbCgoV2luZG93UmVmKWFyZzAsIChjb25zdCBSZWN0ICopbHBhcmcxLCAoQ0ZTdHJpbmdSZWYpYXJnMiwgKFNJbnQxNilhcmczLCAoQm9vbGVhbilhcmc0LCAoU0ludDE2KWFyZzUsIChTSW50MTYpYXJnNiwgKFN0eWxlKWFyZzcsIChDb250cm9sUmVmICopbHBhcmc4KTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJaWYgKGFyZzgpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc4LCBscGFyZzgsIDApOworCXJldHVybiByYzsKIH0KKyNlbmRpZgogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRNZW51SXRlbUhpZXJhcmNoaWNhbE1lbnUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlLCAKLQkJanNob3J0IGluZGV4LCBqaW50QXJyYXkgb3V0SGllck1lbnVIYW5kbGUpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0SGllck1lbnVIYW5kbGUsIDApOwotCWppbnQgc3RhdHVzPSAoamludCkgUkMoR2V0TWVudUl0ZW1IaWVyYXJjaGljYWxNZW51KChNZW51UmVmKSBtSGFuZGxlLCBpbmRleCwgKE1lbnVSZWYqKXNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIG91dEhpZXJNZW51SGFuZGxlLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKKyNpZm5kZWYgTk9fQ3JlYXRlUHJvZ3Jlc3NCYXJDb250cm9sCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DcmVhdGVQcm9ncmVzc0JhckNvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMsIGppbnQgYXJnNCwgamJvb2xlYW4gYXJnNSwgamludEFycmF5IGFyZzYpCit7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCWppbnQgKmxwYXJnNj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJDcmVhdGVQcm9ncmVzc0JhckNvbnRyb2xcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJaWYgKGFyZzYpIGxwYXJnNiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzYsIE5VTEwpOworCXJjID0gKGppbnQpQ3JlYXRlUHJvZ3Jlc3NCYXJDb250cm9sKChXaW5kb3dSZWYpYXJnMCwgKGNvbnN0IFJlY3QgKilscGFyZzEsIChTSW50MzIpYXJnMiwgKFNJbnQzMilhcmczLCAoU0ludDMyKSBhcmc0LCAoQm9vbGVhbilhcmc1LCAoQ29udHJvbFJlZiAqKWxwYXJnNik7CisJaWYgKGFyZzEpIHNldFJlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmc2KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNiwgbHBhcmc2LCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgTk9fQ3JlYXRlUHJvZ3Jlc3NCYXJDb250cm9sCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldE1lbnVJdGVtSGllcmFyY2hpY2FsTWVudShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUsCi0JCQlqc2hvcnQgaW5kZXgsIGppbnQgaGllck1lbnVIYW5kbGUpIHsKLQlyZXR1cm4gKGppbnQpIFJDKFNldE1lbnVJdGVtSGllcmFyY2hpY2FsTWVudSgoTWVudVJlZikgbUhhbmRsZSwgaW5kZXgsIChNZW51UmVmKSBoaWVyTWVudUhhbmRsZSkpOworI2lmbmRlZiBOT19DcmVhdGVQdXNoQnV0dG9uQ29udHJvbAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ3JlYXRlUHVzaEJ1dHRvbkNvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyLCBqaW50QXJyYXkgYXJnMykKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCAqbHBhcmczPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZVB1c2hCdXR0b25Db250cm9sXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCWlmIChhcmczKSBscGFyZzMgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBOVUxMKTsKKwlyYyA9IChqaW50KUNyZWF0ZVB1c2hCdXR0b25Db250cm9sKChXaW5kb3dSZWYpYXJnMCwgKGNvbnN0IFJlY3QgKilscGFyZzEsIChDRlN0cmluZ1JlZilhcmcyLCAoQ29udHJvbFJlZiAqKWxwYXJnMyk7CisJaWYgKGFyZzEpIHNldFJlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fQ3JlYXRlUHVzaEJ1dHRvbkNvbnRyb2wgKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW5zZXJ0TWVudUl0ZW0oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlLAotCQkJamJ5dGVBcnJheSB0ZXh0LCBqc2hvcnQgaW5kZXgpIHsKLQlqYnl0ZSAqc2E9ICgqZW52KS0+R2V0Qnl0ZUFycmF5RWxlbWVudHMoZW52LCB0ZXh0LCAwKTsKLQlJbnNlcnRNZW51SXRlbSgoTWVudVJlZikgbUhhbmRsZSwgKENvbnN0U3RyMjU1UGFyYW0pIHNhLCBpbmRleCk7Ci0JKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCB0ZXh0LCBzYSwgMCk7CisjaWZuZGVmIE5PX0NyZWF0ZVB1c2hCdXR0b25XaXRoSWNvbkNvbnRyb2wKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NyZWF0ZVB1c2hCdXR0b25XaXRoSWNvbkNvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyLCBqb2JqZWN0IGFyZzMsIGpzaG9ydCBhcmc0LCBqaW50QXJyYXkgYXJnNSkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvIF9hcmczLCAqbHBhcmczPU5VTEw7CisJamludCAqbHBhcmc1PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZVB1c2hCdXR0b25XaXRoSWNvbkNvbnRyb2xcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJaWYgKGFyZzMpIGxwYXJnMyA9IGdldENvbnRyb2xCdXR0b25Db250ZW50SW5mb0ZpZWxkcyhlbnYsIGFyZzMsICZfYXJnMyk7CisJaWYgKGFyZzUpIGxwYXJnNSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIE5VTEwpOworCXJjID0gKGppbnQpQ3JlYXRlUHVzaEJ1dHRvbldpdGhJY29uQ29udHJvbCgoV2luZG93UmVmKWFyZzAsIChjb25zdCBSZWN0ICopbHBhcmcxLCAoQ0ZTdHJpbmdSZWYpYXJnMiwgKENvbnRyb2xCdXR0b25Db250ZW50SW5mbyAqKWxwYXJnMywgKENvbnRyb2xQdXNoQnV0dG9uSWNvbkFsaWdubWVudClhcmc0LCAoQ29udHJvbFJlZiAqKWxwYXJnNSk7CisJaWYgKGFyZzEpIHNldFJlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmczKSBzZXRDb250cm9sQnV0dG9uQ29udGVudEluZm9GaWVsZHMoZW52LCBhcmczLCBscGFyZzMpOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQXBwZW5kTWVudShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUsIGpieXRlQXJyYXkgdGV4dCkgewotCWpieXRlICpzYT0gKCplbnYpLT5HZXRCeXRlQXJyYXlFbGVtZW50cyhlbnYsIHRleHQsIDApOwotCUFwcGVuZE1lbnUoKE1lbnVSZWYpIG1IYW5kbGUsIChDb25zdFN0cjI1NVBhcmFtKSBzYSk7Ci0JKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCB0ZXh0LCBzYSwgMCk7CisjaWZuZGVmIE5PX0NyZWF0ZVJhZGlvQnV0dG9uQ29udHJvbAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ3JlYXRlUmFkaW9CdXR0b25Db250cm9sCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqYm9vbGVhbiBhcmc0LCBqaW50QXJyYXkgYXJnNSkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCAqbHBhcmc1PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZVJhZGlvQnV0dG9uQ29udHJvbFxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlpZiAoYXJnNSkgbHBhcmc1ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgTlVMTCk7CisJcmMgPSAoamludClDcmVhdGVSYWRpb0J1dHRvbkNvbnRyb2woKFdpbmRvd1JlZilhcmcwLCAoY29uc3QgUmVjdCAqKWxwYXJnMSwgKENGU3RyaW5nUmVmKWFyZzIsIChTSW50MzIpYXJnMywgKEJvb2xlYW4pYXJnNCwgKENvbnRyb2xSZWYgKilscGFyZzUpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlpZiAoYXJnNSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIGxwYXJnNSwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NoYW5nZU1lbnVJdGVtQXR0cmlidXRlcyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUsCi0JCWpzaG9ydCBpbmRleCwgamludCBzZXRBdHRyaWJ1dGVzLCBqaW50IGNsZWFyQXR0cmlidXRlcykgewotCXJldHVybiBSQyhDaGFuZ2VNZW51SXRlbUF0dHJpYnV0ZXMoKE1lbnVSZWYpIG1IYW5kbGUsIGluZGV4LCBzZXRBdHRyaWJ1dGVzLCBjbGVhckF0dHJpYnV0ZXMpKTsKKyNpZm5kZWYgTk9fQ3JlYXRlUm9vdENvbnRyb2wKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NyZWF0ZVJvb3RDb250cm9sCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50QXJyYXkgYXJnMSkKK3sKKwlqaW50ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQ3JlYXRlUm9vdENvbnRyb2xcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJcmMgPSAoamludClDcmVhdGVSb290Q29udHJvbCgoV2luZG93UmVmKWFyZzAsIChDb250cm9sUmVmICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmIC8qIE5PX0NyZWF0ZVJvb3RDb250cm9sICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NoZWNrTWVudUl0ZW0oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlLAotCQlqc2hvcnQgaW5kZXgsIGpib29sZWFuIGNoZWNrZWQpIHsKLQlDaGVja01lbnVJdGVtKChNZW51UmVmKSBtSGFuZGxlLCBpbmRleCwgY2hlY2tlZCk7CisjaWZuZGVmIE5PX0NyZWF0ZVNjcm9sbEJhckNvbnRyb2wKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NyZWF0ZVNjcm9sbEJhckNvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMsIGppbnQgYXJnNCwgamludCBhcmc1LCBqYm9vbGVhbiBhcmc2LCBqaW50IGFyZzcsIGppbnRBcnJheSBhcmc4KQoreworCVJlY3QgX2FyZzEsICpscGFyZzE9TlVMTDsKKwlqaW50ICpscGFyZzg9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQ3JlYXRlU2Nyb2xsQmFyQ29udHJvbFxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlpZiAoYXJnOCkgbHBhcmc4ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnOCwgTlVMTCk7CisJcmMgPSAoamludClDcmVhdGVTY3JvbGxCYXJDb250cm9sKChXaW5kb3dSZWYpYXJnMCwgKGNvbnN0IFJlY3QgKilscGFyZzEsIChTSW50MzIpYXJnMiwgKFNJbnQzMilhcmczLCAoU0ludDMyKSBhcmc0LCAoQ29udHJvbFNsaWRlck9yaWVudGF0aW9uKWFyZzUsIChCb29sZWFuKWFyZzYsIChDb250cm9sQWN0aW9uVVBQKWFyZzcsIChDb250cm9sUmVmICopbHBhcmc4KTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJaWYgKGFyZzgpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc4LCBscGFyZzgsIDApOworCXJldHVybiByYzsKIH0KKyNlbmRpZiBOT19DcmVhdGVTY3JvbGxCYXJDb250cm9sCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldE1lbnVDb21tYW5kTWFyayhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUsCi0JCWppbnQgY29tbWFuZElkLCBqc2hvcnRBcnJheSBtYXJrQ2hhcmFjdGVyKSB7Ci0JamNoYXIgKnNhPSAoKmVudiktPkdldENoYXJBcnJheUVsZW1lbnRzKGVudiwgbWFya0NoYXJhY3RlciwgMCk7Ci0JamludCBzdGF0dXM9IChqaW50KSBSQyhHZXRNZW51Q29tbWFuZE1hcmsoKE1lbnVSZWYpIG1IYW5kbGUsIGNvbW1hbmRJZCwgKFVuaUNoYXIqKSBzYSkpOwotCSgqZW52KS0+UmVsZWFzZUNoYXJBcnJheUVsZW1lbnRzKGVudiwgbWFya0NoYXJhY3Rlciwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7CisjaWZuZGVmIE5PX0NyZWF0ZVNlcGFyYXRvckNvbnRyb2wKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NyZWF0ZVNlcGFyYXRvckNvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCWppbnQgKmxwYXJnMj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJDcmVhdGVTZXBhcmF0b3JDb250cm9sXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlyYyA9IChqaW50KUNyZWF0ZVNlcGFyYXRvckNvbnRyb2woKFdpbmRvd1JlZilhcmcwLCAoY29uc3QgUmVjdCAqKWxwYXJnMSwgKENvbnRyb2xSZWYgKilscGFyZzIpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmIC8qIE5PX0NyZWF0ZVNlcGFyYXRvckNvbnRyb2wgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0TWVudUNvbW1hbmRNYXJrKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgbUhhbmRsZSwKLQkJamludCBjb21tYW5kSWQsIGpjaGFyIG1hcmtDaGFyYWN0ZXIpIHsKLQlyZXR1cm4gKGppbnQpIFJDKFNldE1lbnVDb21tYW5kTWFyaygoTWVudVJlZikgbUhhbmRsZSwgY29tbWFuZElkLCAoVW5pQ2hhcikgbWFya0NoYXJhY3RlcikpOworI2lmbmRlZiBOT19DcmVhdGVTbGlkZXJDb250cm9sCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DcmVhdGVTbGlkZXJDb250cm9sCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqaW50IGFyZzQsIGppbnQgYXJnNSwgc2hvcnQgYXJnNiwgamJvb2xlYW4gYXJnNywgamludCBhcmc4LCBqaW50QXJyYXkgYXJnOSkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCAqbHBhcmc5PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZVNsaWRlckNvbnRyb2xcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJaWYgKGFyZzkpIGxwYXJnOSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzksIE5VTEwpOworCXJjID0gKGppbnQpQ3JlYXRlU2xpZGVyQ29udHJvbCgoV2luZG93UmVmKWFyZzAsIChjb25zdCBSZWN0ICopbHBhcmcxLCAoU0ludDMyKWFyZzIsIChTSW50MzIpYXJnMywgKFNJbnQzMikgYXJnNCwgKENvbnRyb2xTbGlkZXJPcmllbnRhdGlvbilhcmc1LCAoVUludDE2KWFyZzYsIChCb29sZWFuKWFyZzcsIChDb250cm9sQWN0aW9uVVBQKWFyZzgsIChDb250cm9sUmVmICopbHBhcmc5KTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJaWYgKGFyZzkpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc5LCBscGFyZzksIDApOworCXJldHVybiByYzsKIH0KKyNlbmRpZiBOT19DcmVhdGVTbGlkZXJDb250cm9sCiAKLUpOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Jc1ZhbGlkTWVudShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUpIHsKLQlyZXR1cm4gKGpib29sZWFuKSBJc1ZhbGlkTWVudSgoTWVudVJlZikgbUhhbmRsZSk7CisjaWZuZGVmIE5PX0NyZWF0ZVN0YW5kYXJkQWxlcnQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NyZWF0ZVN0YW5kYXJkQWxlcnQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqc2hvcnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGpvYmplY3QgYXJnMywgamludEFycmF5IGFyZzQpCit7CisJQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWMgX2FyZzMsICpscGFyZzM9TlVMTDsKKwlqaW50ICpscGFyZzQ9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQ3JlYXRlU3RhbmRhcmRBbGVydFxuIikKKworCWlmIChhcmczKSBscGFyZzMgPSBnZXRBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlY0ZpZWxkcyhlbnYsIGFyZzMsICZfYXJnMyk7CisJaWYgKGFyZzQpIGxwYXJnNCA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIE5VTEwpOworCXJjID0gKGppbnQpQ3JlYXRlU3RhbmRhcmRBbGVydCgoQWxlcnRUeXBlKWFyZzAsIChDRlN0cmluZ1JlZilhcmcxLCAoQ0ZTdHJpbmdSZWYpYXJnMiwgKGNvbnN0IEFsZXJ0U3RkQ0ZTdHJpbmdBbGVydFBhcmFtUmVjICopbHBhcmczLCAoRGlhbG9nUmVmICopbHBhcmc0KTsKKwlpZiAoYXJnMykgc2V0QWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWNGaWVsZHMoZW52LCBhcmczLCBscGFyZzMpOworCWlmIChhcmc0KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNCwgbHBhcmc0LCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0TWVudUlEKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgbUhhbmRsZSwganNob3J0IGlkKSB7Ci0JU2V0TWVudUlEKChNZW51UmVmKSBtSGFuZGxlLCBpZCk7CisjaWZuZGVmIE5PX0NyZWF0ZVN0YXRpY1RleHRDb250cm9sCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DcmVhdGVTdGF0aWNUZXh0Q29udHJvbAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxLCBqaW50IGFyZzIsIGpvYmplY3QgYXJnMywgamludEFycmF5IGFyZzQpCit7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCUNvbnRyb2xGb250U3R5bGVSZWMgX2FyZzMsICpscGFyZzM9TlVMTDsKKwlqaW50ICpscGFyZzQ9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiQ3JlYXRlU3RhdGljVGV4dENvbnRyb2xcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJaWYgKGFyZzMpIGxwYXJnMyA9IGdldENvbnRyb2xGb250U3R5bGVSZWNGaWVsZHMoZW52LCBhcmczLCAmX2FyZzMpOworCWlmIChhcmc0KSBscGFyZzQgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlyYyA9IChqaW50KUNyZWF0ZVN0YXRpY1RleHRDb250cm9sKChXaW5kb3dSZWYpYXJnMCwgKGNvbnN0IFJlY3QgKilscGFyZzEsIChDRlN0cmluZ1JlZilhcmcyLCAoY29uc3QgQ29udHJvbEZvbnRTdHlsZVJlYyAqKWxwYXJnMywgKENvbnRyb2xSZWYgKilscGFyZzQpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlpZiAoYXJnMykgc2V0Q29udHJvbEZvbnRTdHlsZVJlY0ZpZWxkcyhlbnYsIGFyZzMsIGxwYXJnMyk7CisJaWYgKGFyZzQpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBscGFyZzQsIDApOworCXJldHVybiByYzsKIH0KKyNlbmRpZiAvKiBOT19DcmVhdGVTdGF0aWNUZXh0Q29udHJvbCAqLwogCi1KTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSXNNZW51SXRlbUVuYWJsZWQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBtSGFuZGxlLCBqc2hvcnQgaW5kZXgpIHsKLQlyZXR1cm4gKGpib29sZWFuKSBJc01lbnVJdGVtRW5hYmxlZCgoTWVudVJlZikgbUhhbmRsZSwgaW5kZXgpOworI2lmbmRlZiBOT19DcmVhdGVUYWJzQ29udHJvbAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ3JlYXRlVGFic0NvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwganNob3J0IGFyZzIsIGpzaG9ydCBhcmczLCBqc2hvcnQgYXJnNCwgamludCBhcmc1LCBqaW50QXJyYXkgYXJnNikKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCAqbHBhcmc2PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZVRhYnNDb250cm9sXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCWlmIChhcmc2KSBscGFyZzYgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc2LCBOVUxMKTsKKwlyYyA9IChqaW50KUNyZWF0ZVRhYnNDb250cm9sKChXaW5kb3dSZWYpYXJnMCwgKGNvbnN0IFJlY3QgKilscGFyZzEsIChDb250cm9sVGFiU2l6ZSlhcmcyLCAoQ29udHJvbFRhYkRpcmVjdGlvbilhcmczLCAoVUludDE2KWFyZzQsIChjb25zdCBDb250cm9sVGFiRW50cnkgKilhcmc1LCAoQ29udHJvbFJlZiAqKWxwYXJnNik7CisJaWYgKGFyZzEpIHNldFJlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmc2KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNiwgbHBhcmc2LCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGlzYWJsZU1lbnVJdGVtKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgbUhhbmRsZSwganNob3J0IGluZGV4KSB7Ci0JRGlzYWJsZU1lbnVJdGVtKChNZW51UmVmKSBtSGFuZGxlLCBpbmRleCk7CisjaWZuZGVmIE5PX0NyZWF0ZUVkaXRVbmljb2RlVGV4dENvbnRyb2wKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NyZWF0ZUVkaXRVbmljb2RlVGV4dENvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyLCBqYm9vbGVhbiBhcmczLCBqb2JqZWN0IGFyZzQsIGppbnRBcnJheSBhcmc1KQoreworCVJlY3QgX2FyZzEsICpscGFyZzE9TlVMTDsKKwlDb250cm9sRm9udFN0eWxlUmVjIF9hcmc0LCAqbHBhcmc0PU5VTEw7CisJamludCAqbHBhcmc1PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZUVkaXRVbmljb2RlVGV4dENvbnRyb2xcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJaWYgKGFyZzQpIGxwYXJnNCA9IGdldENvbnRyb2xGb250U3R5bGVSZWNGaWVsZHMoZW52LCBhcmc0LCAmX2FyZzQpOworCWlmIChhcmc1KSBscGFyZzUgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBOVUxMKTsKKwlyYyA9IChqaW50KUNyZWF0ZUVkaXRVbmljb2RlVGV4dENvbnRyb2woKFdpbmRvd1JlZilhcmcwLCAoY29uc3QgUmVjdCAqKWxwYXJnMSwgKENGU3RyaW5nUmVmKWFyZzIsIChCb29sZWFuKSBhcmczLCAoY29uc3QgQ29udHJvbEZvbnRTdHlsZVJlYyAqKWxwYXJnNCwgKENvbnRyb2xSZWYgKilscGFyZzUpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlpZiAoYXJnNCkgc2V0Q29udHJvbEZvbnRTdHlsZVJlY0ZpZWxkcyhlbnYsIGFyZzQsIGxwYXJnNCk7CisJaWYgKGFyZzUpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBscGFyZzUsIDApOworCXJldHVybiByYzsKIH0KKyNlbmRpZiAvKiBOT19DcmVhdGVFZGl0VW5pY29kZVRleHRDb250cm9sICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0VuYWJsZU1lbnVJdGVtKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgbUhhbmRsZSwganNob3J0IGluZGV4KSB7Ci0JRW5hYmxlTWVudUl0ZW0oKE1lbnVSZWYpIG1IYW5kbGUsIGluZGV4KTsKKyNpZm5kZWYgTk9fQ3JlYXRlVXNlclBhbmVDb250cm9sCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DcmVhdGVVc2VyUGFuZUNvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyLCBqaW50QXJyYXkgYXJnMykKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCAqbHBhcmczPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkNyZWF0ZVVzZXJQYW5lQ29udHJvbFxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJcmMgPSAoamludClDcmVhdGVVc2VyUGFuZUNvbnRyb2woKFdpbmRvd1JlZilhcmcwLCAoY29uc3QgUmVjdCAqKWxwYXJnMSwgKFVJbnQzMilhcmcyLCAoQ29udHJvbFJlZiAqKWxwYXJnMyk7CisJaWYgKGFyZzEpIHNldFJlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fQ3JlYXRlVXNlclBhbmVDb250cm9sICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldE1lbnVGb250KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBtSGFuZGxlLCBqc2hvcnRBcnJheSBmb250SUQsIGpzaG9ydEFycmF5IHNpemUpIHsKLQlqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGZvbnRJRCwgMCk7Ci0JanNob3J0ICpzYj0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBzaXplLCAwKTsKLQlqaW50IHN0YXR1cz0gKGppbnQpIFJDKEdldE1lbnVGb250KChNZW51UmVmKSBtSGFuZGxlLCAoU0ludDE2Kikgc2EsIChVSW50MTYqKSBzYikpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGZvbnRJRCwgc2EsIDApOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHNpemUsIHNiLCAwKTsKLQlyZXR1cm4gc3RhdHVzOworI2lmbmRlZiBOT19DcmVhdGVXaW5kb3dHcm91cAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ3JlYXRlV2luZG93R3JvdXAKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnRBcnJheSBhcmcxKQoreworCWppbnQgKmxwYXJnMT1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJDcmVhdGVXaW5kb3dHcm91cFxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBOVUxMKTsKKwlyYyA9IChqaW50KUNyZWF0ZVdpbmRvd0dyb3VwKChXaW5kb3dHcm91cEF0dHJpYnV0ZXMpYXJnMCwgKFdpbmRvd0dyb3VwUmVmICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldE1lbnVGb250KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBtSGFuZGxlLCBqc2hvcnQgZm9udElELCBqc2hvcnQgc2l6ZSkgewotCXJldHVybiAoamludCkgUkMoU2V0TWVudUZvbnQoKE1lbnVSZWYpIG1IYW5kbGUsIChTSW50MTYpIGZvbnRJRCwgKFVJbnQxNikgc2l6ZSkpOworI2lmbmRlZiBOT19EZWxldGVNZW51CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EZWxldGVNZW51CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwganNob3J0IGFyZzApCit7CisJREVCVUdfQ0FMTCgiRGVsZXRlTWVudVxuIikKKworCURlbGV0ZU1lbnUoKE1lbnVJRClhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19EZWxldGVNZW51ICovCiAKLUpOSUVYUE9SVCBqc2hvcnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0TWVudVdpZHRoKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgbUhhbmRsZSkgewotCXJldHVybiAoanNob3J0KSBHZXRNZW51V2lkdGgoKE1lbnVSZWYpIG1IYW5kbGUpOworI2lmbmRlZiBOT19EZWxldGVNZW51SXRlbQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGVsZXRlTWVudUl0ZW0KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxKQoreworCURFQlVHX0NBTEwoIkRlbGV0ZU1lbnVJdGVtXG4iKQorCisJRGVsZXRlTWVudUl0ZW0oKE1lbnVSZWYpYXJnMCwgKHNob3J0KWFyZzEpOwogfQorI2VuZGlmIC8qIE5PX0RlbGV0ZU1lbnVJdGVtICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NhbGNNZW51U2l6ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IG1IYW5kbGUpIHsKLQlDYWxjTWVudVNpemUoKE1lbnVSZWYpIG1IYW5kbGUpOworI2lmbmRlZiBOT19EZWxldGVNZW51SXRlbXMKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0RlbGV0ZU1lbnVJdGVtcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGppbnQgYXJnMikKK3sKKwlERUJVR19DQUxMKCJEZWxldGVNZW51SXRlbXNcbiIpCisKKwlyZXR1cm4gKGppbnQpRGVsZXRlTWVudUl0ZW1zKChNZW51UmVmKWFyZzAsIChNZW51SXRlbUluZGV4KWFyZzEsIChJdGVtQ291bnQpYXJnMik7CiB9CisjZW5kaWYgLyogTk9fRGVsZXRlTWVudUl0ZW1zICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldE1lbnVJdGVtSWNvbkhhbmRsZShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCWppbnQgbUhhbmRsZSwganNob3J0IGluZGV4LCBqYnl0ZSB0eXBlLCBqaW50IGljb24pIHsKLQlyZXR1cm4gUkMoU2V0TWVudUl0ZW1JY29uSGFuZGxlKChNZW51UmVmKSBtSGFuZGxlLCAoU0ludDE2KWluZGV4LCAoVUludDgpdHlwZSwgKEhhbmRsZSlpY29uKSk7CisjaWZuZGVmIE5PX0RpZmZSZ24KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0RpZmZSZ24KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyKQoreworCURFQlVHX0NBTEwoIkRpZmZSZ25cbiIpCisKKwlEaWZmUmduKChSZ25IYW5kbGUpYXJnMCwgKFJnbkhhbmRsZSlhcmcxLCAoUmduSGFuZGxlKWFyZzIpOwogfQorI2VuZGlmIC8qIE5PX0RpZmZSZ24gKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0TWVudUl0ZW1Db21tYW5kSUQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQlqaW50IG1IYW5kbGUsIGpzaG9ydCBpbmRleCwgamludCBjb21tYW5kSUQpIHsKLQlyZXR1cm4gUkMoU2V0TWVudUl0ZW1Db21tYW5kSUQoKE1lbnVSZWYpIG1IYW5kbGUsIChTSW50MTYpaW5kZXgsIChNZW51Q29tbWFuZCljb21tYW5kSUQpKTsKKyNpZm5kZWYgTk9fRGlzYWJsZUNvbnRyb2wKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0Rpc2FibGVDb250cm9sCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkRpc2FibGVDb250cm9sXG4iKQorCisJcmV0dXJuIChqaW50KURpc2FibGVDb250cm9sKChDb250cm9sUmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0Rpc2FibGVDb250cm9sICovCiAKLS8vLS0tLSBDb250cm9sIE1hbmFnZXIKKyNpZm5kZWYgTk9fRGlzYWJsZU1lbnVDb21tYW5kCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EaXNhYmxlTWVudUNvbW1hbmQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJEaXNhYmxlTWVudUNvbW1hbmRcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldENvbnRyb2xBY3Rpb24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBjSGFuZGxlLCBqaW50IGFjdGlvblByb2MpIHsKLQlTZXRDb250cm9sQWN0aW9uKChDb250cm9sUmVmKWNIYW5kbGUsIChDb250cm9sQWN0aW9uVVBQKSBhY3Rpb25Qcm9jKTsKKwlEaXNhYmxlTWVudUNvbW1hbmQoKE1lbnVSZWYpYXJnMCwgKE1lbnVDb21tYW5kKWFyZzEpOwogfQorI2VuZGlmIC8qIE5PX0Rpc2FibGVNZW51Q29tbWFuZCAqLwogCi0vKiBub3QgZm9yIHByaW1ldGltZSB1c2UgKi8KLS8qCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19zZXRDb250cm9sVG9vbFRpcFRleHQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IGNIYW5kbGUsIGpzaG9ydEFycmF5IGJvdW5kcywgamludCBzSGFuZGxlKSB7Ci0gIAotCUhNSGVscENvbnRlbnRSZWMgaGVscDsKLQlqaW50IHN0YXR1czsKLQlSZWN0ICpyPSAoUmVjdCopICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCAwKTsKKyNpZm5kZWYgTk9fRGlzYWJsZU1lbnVJdGVtCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EaXNhYmxlTWVudUl0ZW0KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxKQoreworCURFQlVHX0NBTEwoIkRpc2FibGVNZW51SXRlbVxuIikKKworCURpc2FibGVNZW51SXRlbSgoTWVudVJlZilhcmcwLCAoTWVudUl0ZW1JbmRleClhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19EaXNhYmxlTWVudUl0ZW0gKi8KKworI2lmbmRlZiBOT19EaXNwb3NlQ29udHJvbAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGlzcG9zZUNvbnRyb2wKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiRGlzcG9zZUNvbnRyb2xcbiIpCisKKwlEaXNwb3NlQ29udHJvbCgoQ29udHJvbFJlZilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19EaXNwb3NlQ29udHJvbCAqLworCisjaWZuZGVmIE5PX0Rpc3Bvc2VHV29ybGQKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0Rpc3Bvc2VHV29ybGQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiRGlzcG9zZUdXb3JsZFxuIikKKworCURpc3Bvc2VHV29ybGQoKEdXb3JsZFB0cilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19EaXNwb3NlR1dvcmxkICovCisKKyNpZm5kZWYgTk9fRGlzcG9zZUhhbmRsZQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGlzcG9zZUhhbmRsZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJEaXNwb3NlSGFuZGxlXG4iKQorCisJRGlzcG9zZUhhbmRsZSgoSGFuZGxlKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0Rpc3Bvc2VIYW5kbGUgKi8KKworI2lmbmRlZiBOT19EaXNwb3NlTWVudQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGlzcG9zZU1lbnUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiRGlzcG9zZU1lbnVcbiIpCisKKwlEaXNwb3NlTWVudSgoTWVudVJlZilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19EaXNwb3NlTWVudSAqLworCisjaWZuZGVmIE5PX0Rpc3Bvc2VQdHIKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0Rpc3Bvc2VQdHIKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiRGlzcG9zZVB0clxuIikKKworCURpc3Bvc2VQdHIoKFB0cilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19EaXNwb3NlUHRyICovCisKKyNpZm5kZWYgTk9fRGlzcG9zZVJnbgorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGlzcG9zZVJnbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJEaXNwb3NlUmduXG4iKQorCisJRGlzcG9zZVJnbigoUmduSGFuZGxlKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0Rpc3Bvc2VSZ24gKi8KKworI2lmbmRlZiBOT19EaXNwb3NlV2luZG93CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EaXNwb3NlV2luZG93CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkRpc3Bvc2VXaW5kb3dcbiIpCisKKwlEaXNwb3NlV2luZG93KChXaW5kb3dSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fRGlzcG9zZVdpbmRvdyAqLworCisjaWZuZGVmIE5PX0RyYXdNZW51QmFyCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EcmF3TWVudUJhcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiRHJhd01lbnVCYXJcbiIpCisKKwlEcmF3TWVudUJhcigpOworfQorI2VuZGlmIC8qIE5PX0RyYXdNZW51QmFyICovCisKKyNpZm5kZWYgTk9fRHJhd1RleHQKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0RyYXdUZXh0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamJ5dGVBcnJheSBhcmcwLCBqc2hvcnQgYXJnMSwganNob3J0IGFyZzIpCit7CisJamJ5dGUgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgiRHJhd1RleHRcbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gKCplbnYpLT5HZXRCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIE5VTEwpOworCURyYXdUZXh0KChjb25zdCB2b2lkICopbHBhcmcwLCAoc2hvcnQpYXJnMSwgKHNob3J0KWFyZzIpOworCWlmIChhcmcwKSAoKmVudiktPlJlbGVhc2VCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIGxwYXJnMCwgMCk7Cit9CisjZW5kaWYgLyogTk9fRHJhd1RleHQgKi8KKworI2lmbmRlZiBOT19EcmF3VGhlbWVCdXR0b24KK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0RyYXdUaGVtZUJ1dHRvbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwganNob3J0IGFyZzEsIGpvYmplY3QgYXJnMiwgam9iamVjdCBhcmczLCBqaW50IGFyZzQsIGppbnQgYXJnNSwgamludCBhcmc2KQoreworCVJlY3QgX2FyZzAsICpscGFyZzA9TlVMTDsKKwlUaGVtZUJ1dHRvbkRyYXdJbmZvIF9hcmcyLCAqbHBhcmcyPU5VTEw7CisJVGhlbWVCdXR0b25EcmF3SW5mbyBfYXJnMywgKmxwYXJnMz1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJEcmF3VGhlbWVCdXR0b25cbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzAsICZfYXJnMCk7CisJaWYgKGFyZzIpIGxwYXJnMiA9IGdldFRoZW1lQnV0dG9uRHJhd0luZm9GaWVsZHMoZW52LCBhcmcyLCAmX2FyZzIpOworCWlmIChhcmczKSBscGFyZzMgPSBnZXRUaGVtZUJ1dHRvbkRyYXdJbmZvRmllbGRzKGVudiwgYXJnMywgJl9hcmczKTsKKwlyYyA9IChqaW50KURyYXdUaGVtZUJ1dHRvbigoUmVjdCAqKWxwYXJnMCwgKFRoZW1lQnV0dG9uS2luZClhcmcxLCAoY29uc3QgVGhlbWVCdXR0b25EcmF3SW5mbyAqKWxwYXJnMiwgKGNvbnN0IFRoZW1lQnV0dG9uRHJhd0luZm8gKilscGFyZzMsIChUaGVtZUVyYXNlVVBQKWFyZzQsIChUaGVtZUJ1dHRvbkRyYXdVUFApYXJnNSwgKFVJbnQzMilhcmc2KTsKKwlpZiAoYXJnMCkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7CisJaWYgKGFyZzIpIHNldFRoZW1lQnV0dG9uRHJhd0luZm9GaWVsZHMoZW52LCBhcmcyLCBscGFyZzIpOworCWlmIChhcmczKSBzZXRUaGVtZUJ1dHRvbkRyYXdJbmZvRmllbGRzKGVudiwgYXJnMywgbHBhcmczKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fRHJhd1RoZW1lQnV0dG9uICovCisKKyNpZm5kZWYgTk9fRHJhd1RoZW1lRWRpdFRleHRGcmFtZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRHJhd1RoZW1lRWRpdFRleHRGcmFtZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwgamludCBhcmcxKQoreworCVJlY3QgX2FyZzAsICpscGFyZzA9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiRHJhd1RoZW1lRWRpdFRleHRGcmFtZVxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlyYyA9IChqaW50KURyYXdUaGVtZUVkaXRUZXh0RnJhbWUoKGNvbnN0IFJlY3QgKilscGFyZzAsIChUaGVtZURyYXdTdGF0ZSlhcmcxKTsKKwlpZiAoYXJnMCkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0RyYXdUaGVtZUVkaXRUZXh0RnJhbWUgKi8KKworI2lmbmRlZiBOT19EcmF3VGhlbWVGb2N1c1JlY3QKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0RyYXdUaGVtZUZvY3VzUmVjdAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwgamJvb2xlYW4gYXJnMSkKK3sKKwlSZWN0IF9hcmcwLCAqbHBhcmcwPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkRyYXdUaGVtZUZvY3VzUmVjdFxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlyYyA9IChqaW50KURyYXdUaGVtZUZvY3VzUmVjdCgoY29uc3QgUmVjdCAqKWxwYXJnMCwgKEJvb2xlYW4pYXJnMSk7CisJaWYgKGFyZzApIHNldFJlY3RGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19EcmF3VGhlbWVGb2N1c1JlY3QgKi8KKworI2lmbmRlZiBOT19EcmF3VGhlbWVTZXBhcmF0b3IKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0RyYXdUaGVtZVNlcGFyYXRvcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwgamludCBhcmcxKQoreworCVJlY3QgX2FyZzAsICpscGFyZzA9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiRHJhd1RoZW1lU2VwYXJhdG9yXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCXJjID0gKGppbnQpRHJhd1RoZW1lU2VwYXJhdG9yKChjb25zdCBSZWN0ICopbHBhcmcwLCAoVGhlbWVEcmF3U3RhdGUpYXJnMSk7CisJaWYgKGFyZzApIHNldFJlY3RGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19EcmF3VGhlbWVTZXBhcmF0b3IgKi8KKworI2lmbmRlZiBOT19EcmF3VGhlbWVUZXh0Qm94CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EcmF3VGhlbWVUZXh0Qm94CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSwgamludCBhcmcyLCBqYm9vbGVhbiBhcmczLCBqb2JqZWN0IGFyZzQsIGpzaG9ydCBhcmc1LCBqaW50IGFyZzYpCit7CisJUmVjdCBfYXJnNCwgKmxwYXJnND1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJEcmF3VGhlbWVUZXh0Qm94XG4iKQorCisJaWYgKGFyZzQpIGxwYXJnNCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmc0LCAmX2FyZzQpOworCXJjID0gKGppbnQpRHJhd1RoZW1lVGV4dEJveCgoQ0ZTdHJpbmdSZWYpYXJnMCwgKFRoZW1lRm9udElEKWFyZzEsIChUaGVtZURyYXdTdGF0ZSlhcmcyLCAoQm9vbGVhbilhcmczLCAoY29uc3QgUmVjdCAqKWxwYXJnNCwgKFNJbnQxNilhcmc1LCAodm9pZCAqKWFyZzYpOworCWlmIChhcmc0KSBzZXRSZWN0RmllbGRzKGVudiwgYXJnNCwgbHBhcmc0KTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fRHJhd1RoZW1lVGV4dEJveCAqLworCisjaWZuZGVmIE5PX0VtYmVkQ29udHJvbAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBPU19OQVRJVkUoRW1iZWRDb250cm9sKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIkVtYmVkQ29udHJvbFxuIikKKworCXJldHVybiAoamludClFbWJlZENvbnRyb2woKENvbnRyb2xSZWYpYXJnMCwgKENvbnRyb2xSZWYpYXJnMSk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19FbXB0eVJlY3QKK0pOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19FbXB0eVJlY3QKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzApCit7CisJUmVjdCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCWpib29sZWFuIHJjOworCisJREVCVUdfQ0FMTCgiRW1wdHlSZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCXJjID0gKGpib29sZWFuKUVtcHR5UmVjdCgoY29uc3QgUmVjdCAqKWxwYXJnMCk7CisJaWYgKGFyZzApIHNldFJlY3RGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19FbXB0eVJlY3QgKi8KKworI2lmbmRlZiBOT19FbXB0eVJnbgorSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0VtcHR5UmduCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkVtcHR5UmduXG4iKQorCisJcmV0dXJuIChqYm9vbGVhbilFbXB0eVJnbigoUmduSGFuZGxlKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0VtcHR5UmduICovCisKKyNpZm5kZWYgTk9fRW5hYmxlQ29udHJvbAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRW5hYmxlQ29udHJvbAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJFbmFibGVDb250cm9sXG4iKQorCisJcmV0dXJuIChqaW50KUVuYWJsZUNvbnRyb2woKENvbnRyb2xSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fRW5hYmxlQ29udHJvbCAqLworCisjaWZuZGVmIE5PX0VuYWJsZU1lbnVDb21tYW5kCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19FbmFibGVNZW51Q29tbWFuZAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIkVuYWJsZU1lbnVDb21tYW5kXG4iKQorCisJRW5hYmxlTWVudUNvbW1hbmQoKE1lbnVSZWYpYXJnMCwgKE1lbnVDb21tYW5kKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX0VuYWJsZU1lbnVDb21tYW5kICovCisKKyNpZm5kZWYgTk9fRW5hYmxlTWVudUl0ZW0KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0VuYWJsZU1lbnVJdGVtCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJFbmFibGVNZW51SXRlbVxuIikKKworCUVuYWJsZU1lbnVJdGVtKChNZW51UmVmKWFyZzAsIChNZW51SXRlbUluZGV4KWFyZzEpOworfQorI2VuZGlmIC8qIE5PX0VuYWJsZU1lbnVJdGVtICovCisKKyNpZm5kZWYgTk9fRW5kVXBkYXRlCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19FbmRVcGRhdGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiRW5kVXBkYXRlXG4iKQorCisJRW5kVXBkYXRlKChXaW5kb3dSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fRW5kVXBkYXRlICovCisKKyNpZm5kZWYgTk9fRXF1YWxSZWN0CitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRXF1YWxSZWN0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwLCBqb2JqZWN0IGFyZzEpCit7CisJUmVjdCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCVJlY3QgX2FyZzEsICpscGFyZzE9TlVMTDsKKwlqYm9vbGVhbiByYzsKKworCURFQlVHX0NBTEwoIkVxdWFsUmVjdFxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJcmMgPSAoamJvb2xlYW4pRXF1YWxSZWN0KChjb25zdCBSZWN0ICopbHBhcmcwLCAoY29uc3QgUmVjdCAqKWxwYXJnMSk7CisJaWYgKGFyZzApIHNldFJlY3RGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fRXF1YWxSZWN0ICovCisKKyNpZm5kZWYgTk9fRXJhc2VSZWN0CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19FcmFzZVJlY3QKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzApCit7CisJUmVjdCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgiRXJhc2VSZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCUVyYXNlUmVjdCgoY29uc3QgUmVjdCAqKWxwYXJnMCk7CisJaWYgKGFyZzApIHNldFJlY3RGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworfQorI2VuZGlmIC8qIE5PX0VyYXNlUmVjdCAqLworCisjaWZuZGVmIE5PX0VyYXNlUmduCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19FcmFzZVJnbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJFcmFzZVJnblxuIikKKworCUVyYXNlUmduKChSZ25IYW5kbGUpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fRXJhc2VSZ24gKi8KKworI2lmbmRlZiBOT19GUElzRm9udFBhbmVsVmlzaWJsZQorSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0ZQSXNGb250UGFuZWxWaXNpYmxlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCkKK3sKKwlERUJVR19DQUxMKCJGUElzRm9udFBhbmVsVmlzaWJsZVxuIikKKworCXJldHVybiAoamJvb2xlYW4pRlBJc0ZvbnRQYW5lbFZpc2libGUoKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0ZldGNoRm9udEluZm8KK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgT1NfTkFUSVZFKEZldGNoRm9udEluZm8pCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwganNob3J0IGFyZzAsIGpzaG9ydCBhcmcxLCBqc2hvcnQgYXJnMiwgam9iamVjdCBhcmczKQoreworCUZvbnRJbmZvIF9hcmczLCAqbHBhcmczPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkZldGNoRm9udEluZm9cbiIpCisKKwlpZiAoYXJnMykgbHBhcmczID0gZ2V0Rm9udEluZm9GaWVsZHMoZW52LCBhcmczLCAmX2FyZzMpOworCXJjID0gKGppbnQpRmV0Y2hGb250SW5mbyhhcmcwLCBhcmcxLCBhcmcyLCBscGFyZzMpOworCWlmIChhcmczKSBzZXRGb250SW5mb0ZpZWxkcyhlbnYsIGFyZzMsIGxwYXJnMyk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fRml4MkxvbmcKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgT1NfTkFUSVZFKEZpeDJMb25nKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJGaXgyTG9uZ1xuIikKIAkKLQlITVNldEhlbHBUYWdzRGlzcGxheWVkKHRydWUpOworCXJldHVybiAoamludClGaXgyTG9uZygoRml4ZWQpYXJnMCk7Cit9CisjZW5kaWYgTk9fRml4MkxvbmcKIAotCWhlbHAudmVyc2lvbj0gMDsKLQloZWxwLmFic0hvdFJlY3QubGVmdD0gci0+bGVmdDsKLQloZWxwLmFic0hvdFJlY3QudG9wPSByLT50b3A7Ci0JaGVscC5hYnNIb3RSZWN0LnJpZ2h0PSByLT5yaWdodDsKLQloZWxwLmFic0hvdFJlY3QuYm90dG9tPSByLT5ib3R0b207Ci0JaGVscC50YWdTaWRlPSBrSE1EZWZhdWx0U2lkZTsKLQloZWxwLmNvbnRlbnRbMF0uY29udGVudFR5cGU9IGtITUNGU3RyaW5nQ29udGVudDsKLQloZWxwLmNvbnRlbnRbMF0udS50YWdDRlN0cmluZz0gKENGU3RyaW5nUmVmKSBzSGFuZGxlOwotCWhlbHAuY29udGVudFsxXS5jb250ZW50VHlwZT0ga0hNTm9Db250ZW50OwotCWhlbHAuY29udGVudFsxXS51LnRhZ0NGU3RyaW5nPSAwOwotICAKLQlzdGF0dXM9IFJDKEhNU2V0Q29udHJvbEhlbHBDb250ZW50KChDb250cm9sUmVmKSBjSGFuZGxlLCAmaGVscCkpOworI2lmbmRlZiBOT19GTUNyZWF0ZUZvbnRGYW1pbHlJdGVyYXRvcgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBPU19OQVRJVkUoRk1DcmVhdGVGb250RmFtaWx5SXRlcmF0b3IpCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczKQoreworCURFQlVHX0NBTEwoIkZNQ3JlYXRlRm9udEZhbWlseUl0ZXJhdG9yXG4iKQorCisJcmV0dXJuIChqaW50KUZNQ3JlYXRlRm9udEZhbWlseUl0ZXJhdG9yKChjb25zdCBGTUZpbHRlciAqKWFyZzAsICh2b2lkICopYXJnMSwgKE9wdGlvbkJpdHMpYXJnMiwgKEZNRm9udEZhbWlseUl0ZXJhdG9yICopYXJnMyk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19GTUNyZWF0ZUZvbnRGYW1pbHlJbnN0YW5jZUl0ZXJhdG9yCitKTklFWFBPUlQgamludCBKTklDQUxMIE9TX05BVElWRShGTUNyZWF0ZUZvbnRGYW1pbHlJbnN0YW5jZUl0ZXJhdG9yKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpzaG9ydCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiRk1DcmVhdGVGb250RmFtaWx5SW5zdGFuY2VJdGVyYXRvclxuIikKKworCXJldHVybiAoamludClGTUNyZWF0ZUZvbnRGYW1pbHlJbnN0YW5jZUl0ZXJhdG9yKChGTUZvbnRGYW1pbHkpYXJnMCwgKEZNRm9udEZhbWlseUluc3RhbmNlSXRlcmF0b3IgKilhcmcxKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0ZNRGlzcG9zZUZvbnRGYW1pbHlJdGVyYXRvcgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBPU19OQVRJVkUoRk1EaXNwb3NlRm9udEZhbWlseUl0ZXJhdG9yKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJGTURpc3Bvc2VGb250RmFtaWx5SXRlcmF0b3JcbiIpCisKKwlyZXR1cm4gKGppbnQpRk1EaXNwb3NlRm9udEZhbWlseUl0ZXJhdG9yKChGTUZvbnRGYW1pbHlJdGVyYXRvciAqKWFyZzApOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fRk1EaXNwb3NlRm9udEZhbWlseUluc3RhbmNlSXRlcmF0b3IKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgT1NfTkFUSVZFKEZNRGlzcG9zZUZvbnRGYW1pbHlJbnN0YW5jZUl0ZXJhdG9yKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJGTURpc3Bvc2VGb250RmFtaWx5SW5zdGFuY2VJdGVyYXRvclxuIikKKworCXJldHVybiAoamludClGTURpc3Bvc2VGb250RmFtaWx5SW5zdGFuY2VJdGVyYXRvcigoRk1Gb250RmFtaWx5SW5zdGFuY2VJdGVyYXRvciAqKWFyZzApOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fRk1HZXRGb250RmFtaWx5RnJvbU5hbWUKK0pOSUVYUE9SVCBqc2hvcnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRk1HZXRGb250RmFtaWx5RnJvbU5hbWUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqYnl0ZUFycmF5IGFyZzApCit7CisJamJ5dGUgKmxwYXJnMD1OVUxMOworCWpzaG9ydCByYzsKKworCURFQlVHX0NBTEwoIkZNR2V0Rm9udEZhbWlseUZyb21OYW1lXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9ICgqZW52KS0+R2V0Qnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmcwLCBOVUxMKTsKKwlyYyA9IChqc2hvcnQpRk1HZXRGb250RmFtaWx5RnJvbU5hbWUoKENvbnN0U3RyMjU1UGFyYW0pbHBhcmcwKTsKKwlpZiAoYXJnMCkgKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmcwLCBscGFyZzAsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19GTUdldEZvbnRGYW1pbHlGcm9tTmFtZSAqLworCisjaWZuZGVmIE5PX0ZNR2V0Rm9udEZhbWlseU5hbWUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0ZNR2V0Rm9udEZhbWlseU5hbWUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqc2hvcnQgYXJnMCwgamJ5dGVBcnJheSBhcmcxKQoreworCWpieXRlICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiRk1HZXRGb250RmFtaWx5TmFtZVxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJcmMgPSAoamludClGTUdldEZvbnRGYW1pbHlOYW1lKGFyZzAsIGxwYXJnMSk7CisJaWYgKGFyZzEpICgqZW52KS0+UmVsZWFzZUJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fRk1HZXRGb250RmFtaWx5TmFtZSAqLworCisjaWZuZGVmIE5PX0ZNR2V0Rm9udEZyb21Gb250RmFtaWx5SW5zdGFuY2UKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgT1NfTkFUSVZFKEZNR2V0Rm9udEZyb21Gb250RmFtaWx5SW5zdGFuY2UpCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwganNob3J0IGFyZzAsIGpzaG9ydCBhcmcxLCBqaW50QXJyYXkgYXJnMiwganNob3J0QXJyYXkgYXJnMykKK3sKKwlqaW50ICpscGFyZzI9TlVMTDsKKwlqc2hvcnQgKmxwYXJnMz1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJGTUdldEZvbnRGcm9tRm9udEZhbWlseUluc3RhbmNlXG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCWlmIChhcmczKSBscGFyZzMgPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIE5VTEwpOworCXJjID0gKGppbnQpRk1HZXRGb250RnJvbUZvbnRGYW1pbHlJbnN0YW5jZSgoRk1Gb250RmFtaWx5KWFyZzAsIChGTUZvbnRTdHlsZSlhcmcxLCAoRk1Gb250ICopbHBhcmcyLCAoRk1Gb250U3R5bGUgKilscGFyZzMpOworCWlmIChhcmcyKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKKwlpZiAoYXJnMykgKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19GTUdldE5leHRGb250RmFtaWx5CitKTklFWFBPUlQgamludCBKTklDQUxMIE9TX05BVElWRShGTUdldE5leHRGb250RmFtaWx5KQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0QXJyYXkgYXJnMSkKK3sKKwlqc2hvcnQgKmxwYXJnMT1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJGTUdldE5leHRGb250RmFtaWx5XG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJcmMgPSAoamludClGTUdldE5leHRGb250RmFtaWx5KChGTUZvbnRGYW1pbHlJdGVyYXRvciAqKWFyZzAsIChGTUZvbnRGYW1pbHkgKilscGFyZzEpOworCWlmIChhcmcxKSAoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0ZNR2V0TmV4dEZvbnRGYW1pbHlJbnN0YW5jZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBPU19OQVRJVkUoRk1HZXROZXh0Rm9udEZhbWlseUluc3RhbmNlKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludEFycmF5IGFyZzEsIGpzaG9ydEFycmF5IGFyZzIsIGpzaG9ydEFycmF5IGFyZzMpCit7CisJamludCAqbHBhcmcxPU5VTEw7CisJanNob3J0ICpscGFyZzI9TlVMTDsKKwlqc2hvcnQgKmxwYXJnMz1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJGTUdldE5leHRGb250RmFtaWx5SW5zdGFuY2VcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJaWYgKGFyZzMpIGxwYXJnMyA9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJcmMgPSAoamludClGTUdldE5leHRGb250RmFtaWx5SW5zdGFuY2UoKEZNRm9udEZhbWlseUluc3RhbmNlSXRlcmF0b3IgKilhcmcwLCAoRk1Gb250ICopbHBhcmcxLCAoRk1Gb250U3R5bGUgKilscGFyZzIsIChGTUZvbnRTaXplICopbHBhcmczKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJaWYgKGFyZzMpICgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fRlBTaG93SGlkZUZvbnRQYW5lbAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRlBTaG93SGlkZUZvbnRQYW5lbAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiRlBTaG93SGlkZUZvbnRQYW5lbFxuIikKKworCXJldHVybiAoamludClGUFNob3dIaWRlRm9udFBhbmVsKCk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19GaW5kV2luZG93CitKTklFWFBPUlQganNob3J0IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0ZpbmRXaW5kb3cKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzAsIGppbnRBcnJheSBhcmcxKQoreworCVBvaW50IF9hcmcwLCAqbHBhcmcwPU5VTEw7CisJamludCAqbHBhcmcxPU5VTEw7CisJanNob3J0IHJjOworCisJREVCVUdfQ0FMTCgiRmluZFdpbmRvd1xuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRQb2ludEZpZWxkcyhlbnYsIGFyZzAsICZfYXJnMCk7CisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCXJjID0gKGpzaG9ydClGaW5kV2luZG93KChQb2ludCkqbHBhcmcwLCAoV2luZG93UmVmICopbHBhcmcxKTsKKwlpZiAoYXJnMCkgc2V0UG9pbnRGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworCWlmIChhcmcxKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fRmluZFdpbmRvdyAqLworCisjaWZuZGVmIE5PX0ZyYW1lT3ZhbAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRnJhbWVPdmFsCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwKQoreworCVJlY3QgX2FyZzAsICpscGFyZzA9TlVMTDsKKworCURFQlVHX0NBTEwoIkZyYW1lT3ZhbFxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlGcmFtZU92YWwoKGNvbnN0IFJlY3QgKilscGFyZzApOworCWlmIChhcmcwKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgbHBhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19GcmFtZU92YWwgKi8KKworI2lmbmRlZiBOT19GcmFtZVBvbHkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0ZyYW1lUG9seQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJGcmFtZVBvbHlcbiIpCisKKwlGcmFtZVBvbHkoKFBvbHlIYW5kbGUpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fRnJhbWVQb2x5ICovCisKKyNpZm5kZWYgTk9fRnJhbWVSZWN0CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19GcmFtZVJlY3QKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzApCit7CisJUmVjdCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgiRnJhbWVSZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCUZyYW1lUmVjdCgoY29uc3QgUmVjdCAqKWxwYXJnMCk7CisJaWYgKGFyZzApIHNldFJlY3RGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworfQorI2VuZGlmIC8qIE5PX0ZyYW1lUmVjdCAqLworCisjaWZuZGVmIE5PX0ZyYW1lUm91bmRSZWN0CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19GcmFtZVJvdW5kUmVjdAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwganNob3J0IGFyZzEsIGpzaG9ydCBhcmcyKQoreworCVJlY3QgX2FyZzAsICpscGFyZzA9TlVMTDsKKworCURFQlVHX0NBTEwoIkZyYW1lUm91bmRSZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCUZyYW1lUm91bmRSZWN0KChjb25zdCBSZWN0ICopbHBhcmcwLCAoc2hvcnQpYXJnMSwgKHNob3J0KWFyZzIpOworCWlmIChhcmcwKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgbHBhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19GcmFtZVJvdW5kUmVjdCAqLworCisjaWZuZGVmIE5PX0Zyb250V2luZG93CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Gcm9udFdpbmRvdworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiRnJvbnRXaW5kb3dcbiIpCisKKwlyZXR1cm4gKGppbnQpRnJvbnRXaW5kb3coKTsKK30KKyNlbmRpZiAvKiBOT19Gcm9udFdpbmRvdyAqLworCisjaWZuZGVmIE5PX0dldEFwcEZvbnQKK0pOSUVYUE9SVCBqc2hvcnQgSk5JQ0FMTCBPU19OQVRJVkUoR2V0QXBwRm9udCkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0KQoreworCURFQlVHX0NBTEwoIkdldEFwcEZvbnRcbiIpCisKKwlyZXR1cm4gKGpzaG9ydClHZXRBcHBGb250KCk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19HZXRBcHBsaWNhdGlvbkV2ZW50VGFyZ2V0CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRBcHBsaWNhdGlvbkV2ZW50VGFyZ2V0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCkKK3sKKwlERUJVR19DQUxMKCJHZXRBcHBsaWNhdGlvbkV2ZW50VGFyZ2V0XG4iKQorCisJcmV0dXJuIChqaW50KUdldEFwcGxpY2F0aW9uRXZlbnRUYXJnZXQoKTsKK30KKyNlbmRpZiAvKiBOT19HZXRBcHBsaWNhdGlvbkV2ZW50VGFyZ2V0ICovCisKKyNpZm5kZWYgTk9fR2V0QXZhaWxhYmxlV2luZG93QXR0cmlidXRlcworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0QXZhaWxhYmxlV2luZG93QXR0cmlidXRlcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJHZXRBdmFpbGFibGVXaW5kb3dBdHRyaWJ1dGVzXG4iKQorCisJcmV0dXJuIChqaW50KUdldEF2YWlsYWJsZVdpbmRvd0F0dHJpYnV0ZXMoKFdpbmRvd0NsYXNzKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldEF2YWlsYWJsZVdpbmRvd0F0dHJpYnV0ZXMgKi8KKworI2lmbmRlZiBOT19HZXRBdmFpbGFibGVXaW5kb3dQb3NpdGlvbmluZ0JvdW5kcworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0QXZhaWxhYmxlV2luZG93UG9zaXRpb25pbmdCb3VuZHMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldEF2YWlsYWJsZVdpbmRvd1Bvc2l0aW9uaW5nQm91bmRzXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCXJjID0gKGppbnQpR2V0QXZhaWxhYmxlV2luZG93UG9zaXRpb25pbmdCb3VuZHMoKEdESGFuZGxlKWFyZzAsIChSZWN0ICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldEF2YWlsYWJsZVdpbmRvd1Bvc2l0aW9uaW5nQm91bmRzICovCisKKyNpZm5kZWYgTk9fR2V0QmVzdENvbnRyb2xSZWN0CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRCZXN0Q29udHJvbFJlY3QKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwganNob3J0QXJyYXkgYXJnMikKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJanNob3J0ICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0QmVzdENvbnRyb2xSZWN0XG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpR2V0QmVzdENvbnRyb2xSZWN0KChDb250cm9sUmVmKWFyZzAsIChSZWN0ICopbHBhcmcxLCAoU0ludDE2ICopbHBhcmcyKTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldEJlc3RDb250cm9sUmVjdCAqLworCisjaWZuZGVmIE5PX0dldENhcmV0VGltZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q2FyZXRUaW1lCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCkKK3sKKwlERUJVR19DQUxMKCJHZXRDYXJldFRpbWVcbiIpCisKKwlyZXR1cm4gKGppbnQpR2V0Q2FyZXRUaW1lKCk7Cit9CisjZW5kaWYgLyogTk9fR2V0Q2FyZXRUaW1lICovCisKKyNpZm5kZWYgTk9fR2V0Q2xpcAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q2xpcAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJHZXRDbGlwXG4iKQorCisJR2V0Q2xpcCgoUmduSGFuZGxlKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldENsaXAgKi8KKworI2lmbmRlZiBOT19HZXRDb250cm9sMzJCaXRNYXhpbXVtCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDb250cm9sMzJCaXRNYXhpbXVtCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkdldENvbnRyb2wzMkJpdE1heGltdW1cbiIpCisKKwlyZXR1cm4gKGppbnQpR2V0Q29udHJvbDMyQml0TWF4aW11bSgoQ29udHJvbFJlZilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19HZXRDb250cm9sMzJCaXRNYXhpbXVtICovCisKKyNpZm5kZWYgTk9fR2V0Q29udHJvbDMyQml0TWluaW11bQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q29udHJvbDMyQml0TWluaW11bQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJHZXRDb250cm9sMzJCaXRNaW5pbXVtXG4iKQorCisJcmV0dXJuIChqaW50KUdldENvbnRyb2wzMkJpdE1pbmltdW0oKENvbnRyb2xSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fR2V0Q29udHJvbDMyQml0TWluaW11bSAqLworCisjaWZuZGVmIE5PX0dldENvbnRyb2wzMkJpdFZhbHVlCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDb250cm9sMzJCaXRWYWx1ZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJHZXRDb250cm9sMzJCaXRWYWx1ZVxuIikKKworCXJldHVybiAoamludClHZXRDb250cm9sMzJCaXRWYWx1ZSgoQ29udHJvbFJlZilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19HZXRDb250cm9sMzJCaXRWYWx1ZSAqLworCisjaWZuZGVmIE5PX0dldENvbnRyb2xCb3VuZHMKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2xCb3VuZHMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisKKwlERUJVR19DQUxMKCJHZXRDb250cm9sQm91bmRzXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCUdldENvbnRyb2xCb3VuZHMoKENvbnRyb2xSZWYpYXJnMCwgKFJlY3QgKilscGFyZzEpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19HZXRDb250cm9sQm91bmRzICovCisKKyNpZm5kZWYgTk9fR2V0Q29udHJvbERhdGFfX0lTSUlMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9SZWN0XzJfM0kKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2xEYXRhX19JU0lJTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fUmVjdF8yXzNJCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMsIGpvYmplY3QgYXJnNCwgamludEFycmF5IGFyZzUpCit7CisJUmVjdCBfYXJnNCwgKmxwYXJnND1OVUxMOworCWppbnQgKmxwYXJnNT1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRDb250cm9sRGF0YV9fSVNJSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX1JlY3RfMl8zSVxuIikKKworCWlmIChhcmc0KSBscGFyZzQgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnNCwgJl9hcmc0KTsKKwlpZiAoYXJnNSkgbHBhcmc1ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgTlVMTCk7CisJcmMgPSAoamludClHZXRDb250cm9sRGF0YSgoQ29udHJvbFJlZilhcmcwLCAoQ29udHJvbFBhcnRDb2RlKWFyZzEsIChSZXNUeXBlKWFyZzIsIChTaXplKWFyZzMsICh2b2lkICopbHBhcmc0LCAoU2l6ZSAqKWxwYXJnNSk7CisJaWYgKGFyZzQpIHNldFJlY3RGaWVsZHMoZW52LCBhcmc0LCBscGFyZzQpOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0Q29udHJvbERhdGFfX0lTSUlMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9SZWN0XzJfM0kgKi8KKworI2lmbmRlZiBOT19HZXRDb250cm9sRGF0YV9fSVNJSV8zSV8zSQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q29udHJvbERhdGFfX0lTSUlfM0lfM0kKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMywgamludEFycmF5IGFyZzQsIGppbnRBcnJheSBhcmc1KQoreworCWppbnQgKmxwYXJnND1OVUxMOworCWppbnQgKmxwYXJnNT1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRDb250cm9sRGF0YV9fSVNJSV8zSV8zSVxuIikKKworCWlmIChhcmc0KSBscGFyZzQgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlpZiAoYXJnNSkgbHBhcmc1ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgTlVMTCk7CisJcmMgPSAoamludClHZXRDb250cm9sRGF0YSgoQ29udHJvbFJlZilhcmcwLCAoQ29udHJvbFBhcnRDb2RlKWFyZzEsIChSZXNUeXBlKWFyZzIsIChTaXplKWFyZzMsICh2b2lkICopbHBhcmc0LCAoU2l6ZSAqKWxwYXJnNSk7CisJaWYgKGFyZzQpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBscGFyZzQsIDApOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0Q29udHJvbERhdGFfX0lTSUlfM0lfM0kgKi8KKworI2lmbmRlZiBOT19HZXRDb250cm9sRGF0YV9fSVNJSV8zU18zSQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q29udHJvbERhdGFfX0lTSUlfM1NfM0kKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMywganNob3J0QXJyYXkgYXJnNCwgamludEFycmF5IGFyZzUpCit7CisJanNob3J0ICpscGFyZzQ9TlVMTDsKKwlqaW50ICpscGFyZzU9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0Q29udHJvbERhdGFfX0lTSUlfM1NfM0lcbiIpCisKKwlpZiAoYXJnNCkgbHBhcmc0ID0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlpZiAoYXJnNSkgbHBhcmc1ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgTlVMTCk7CisJcmMgPSAoamludClHZXRDb250cm9sRGF0YSgoQ29udHJvbFJlZilhcmcwLCAoQ29udHJvbFBhcnRDb2RlKWFyZzEsIChSZXNUeXBlKWFyZzIsIChTaXplKWFyZzMsICh2b2lkICopbHBhcmc0LCAoU2l6ZSAqKWxwYXJnNSk7CisJaWYgKGFyZzQpICgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJaWYgKGFyZzUpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBscGFyZzUsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXRDb250cm9sRGF0YV9fSVNJSV8zU18zSSAqLworCisjaWZuZGVmIE5PX0dldENvbnRyb2xEYXRhX19JU0lJXzNCXzNJCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDb250cm9sRGF0YV9fSVNJSV8zQl8zSQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqYnl0ZUFycmF5IGFyZzQsIGppbnRBcnJheSBhcmc1KQoreworCWpieXRlICpscGFyZzQ9TlVMTDsKKwlqaW50ICpscGFyZzU9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0Q29udHJvbERhdGFfX0lTSUlfM0JfM0lcbiIpCisKKwlpZiAoYXJnNCkgbHBhcmc0ID0gKCplbnYpLT5HZXRCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIE5VTEwpOworCWlmIChhcmc1KSBscGFyZzUgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBOVUxMKTsKKwlyYyA9IChqaW50KUdldENvbnRyb2xEYXRhKChDb250cm9sUmVmKWFyZzAsIChDb250cm9sUGFydENvZGUpYXJnMSwgKFJlc1R5cGUpYXJnMiwgKFNpemUpYXJnMywgKHZvaWQgKilscGFyZzQsIChTaXplICopbHBhcmc1KTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBscGFyZzQsIDApOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19HZXRDb250cm9sRmVhdHVyZXMKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2xGZWF0dXJlcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludEFycmF5IGFyZzEpCit7CisJamludCAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldENvbnRyb2xGZWF0dXJlc1xuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBOVUxMKTsKKwlyYyA9IChqaW50KUdldENvbnRyb2xGZWF0dXJlcygoQ29udHJvbFJlZilhcmcwLCAoVUludDMyICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldENvbnRyb2xGZWF0dXJlcyAqLworCisjaWZuZGVmIE5PX0dldENvbnRyb2xFdmVudFRhcmdldAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q29udHJvbEV2ZW50VGFyZ2V0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkdldENvbnRyb2xFdmVudFRhcmdldFxuIikKKworCXJldHVybiAoamludClHZXRDb250cm9sRXZlbnRUYXJnZXQoKENvbnRyb2xSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fR2V0Q29udHJvbEV2ZW50VGFyZ2V0ICovCisKKyNpZm5kZWYgTk9fR2V0Q29udHJvbE93bmVyCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDb250cm9sT3duZXIKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiR2V0Q29udHJvbE93bmVyXG4iKQorCisJcmV0dXJuIChqaW50KUdldENvbnRyb2xPd25lcigoQ29udHJvbFJlZilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19HZXRDb250cm9sT3duZXIgKi8KKworI2lmbmRlZiBOT19HZXRDb250cm9sUHJvcGVydHkKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2xQcm9wZXJ0eQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMywgamludEFycmF5IGFyZzQsIGppbnRBcnJheSBhcmc1KQoreworCWppbnQgKmxwYXJnND1OVUxMOworCWppbnQgKmxwYXJnNT1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRDb250cm9sUHJvcGVydHlcbiIpCisKKwlpZiAoYXJnNCkgbHBhcmc0ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNCwgTlVMTCk7CisJaWYgKGFyZzUpIGxwYXJnNSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIE5VTEwpOworCXJjID0gKGppbnQpR2V0Q29udHJvbFByb3BlcnR5KChDb250cm9sUmVmKWFyZzAsIGFyZzEsIGFyZzIsIGFyZzMsIChVSW50MzIgKilscGFyZzQsICh2b2lkICopbHBhcmc1KTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJaWYgKGFyZzUpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBscGFyZzUsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0dldENvbnRyb2xSZWZlcmVuY2UKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2xSZWZlcmVuY2UKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiR2V0Q29udHJvbFJlZmVyZW5jZVxuIikKKworCXJldHVybiAoamludClHZXRDb250cm9sUmVmZXJlbmNlKChDb250cm9sUmVmKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldENvbnRyb2xSZWZlcmVuY2UgKi8KKworI2lmbmRlZiBOT19HZXRDb250cm9sUmVnaW9uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDb250cm9sUmVnaW9uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSwgamludCBhcmcyKQoreworCURFQlVHX0NBTEwoIkdldENvbnRyb2xSZWdpb25cbiIpCisKKwlyZXR1cm4gKGppbnQpR2V0Q29udHJvbFJlZ2lvbigoQ29udHJvbFJlZilhcmcwLCAoQ29udHJvbFBhcnRDb2RlKWFyZzEsIChSZ25IYW5kbGUpYXJnMik7Cit9CisjZW5kaWYgLyogTk9fR2V0Q29udHJvbFJlZ2lvbiAqLworCisjaWZuZGVmIE5PX0dldENvbnRyb2xWYWx1ZQorSk5JRVhQT1JUIGpzaG9ydCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDb250cm9sVmFsdWUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiR2V0Q29udHJvbFZhbHVlXG4iKQorCisJcmV0dXJuIChqc2hvcnQpR2V0Q29udHJvbFZhbHVlKChDb250cm9sUmVmKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldENvbnRyb2xWYWx1ZSAqLworCisjaWZuZGVmIE5PX0dldENvbnRyb2xWaWV3U2l6ZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q29udHJvbFZpZXdTaXplCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkdldENvbnRyb2xWaWV3U2l6ZVxuIikKKworCXJldHVybiAoamludClHZXRDb250cm9sVmlld1NpemUoKENvbnRyb2xSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fR2V0Q29udHJvbFZpZXdTaXplICovCisKKyNpZm5kZWYgTk9fR2V0Q3VycmVudEV2ZW50QnV0dG9uU3RhdGUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEN1cnJlbnRFdmVudEJ1dHRvblN0YXRlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCkKK3sKKwlERUJVR19DQUxMKCJHZXRDdXJyZW50RXZlbnRCdXR0b25TdGF0ZVxuIikKKworCXJldHVybiAoamludClHZXRDdXJyZW50RXZlbnRCdXR0b25TdGF0ZSgpOworfQorI2VuZGlmIC8qIE5PX0dldEN1cnJlbnRFdmVudEJ1dHRvblN0YXRlICovCisKKyNpZm5kZWYgTk9fR2V0Q3VycmVudEV2ZW50TG9vcAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q3VycmVudEV2ZW50TG9vcAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiR2V0Q3VycmVudEV2ZW50TG9vcFxuIikKKworCXJldHVybiAoamludClHZXRDdXJyZW50RXZlbnRMb29wKCk7Cit9CisjZW5kaWYgLyogTk9fR2V0Q3VycmVudEV2ZW50TG9vcCAqLworCisjaWZuZGVmIE5PX0dldEN1cnJlbnRFdmVudEtleU1vZGlmaWVycworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q3VycmVudEV2ZW50S2V5TW9kaWZpZXJzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCkKK3sKKwlERUJVR19DQUxMKCJHZXRDdXJyZW50RXZlbnRLZXlNb2RpZmllcnNcbiIpCisKKwlyZXR1cm4gKGppbnQpR2V0Q3VycmVudEV2ZW50S2V5TW9kaWZpZXJzKCk7Cit9CisjZW5kaWYgLyogTk9fR2V0Q3VycmVudEV2ZW50S2V5TW9kaWZpZXJzICovCisKKyNpZm5kZWYgTk9fR2V0Q3VycmVudEV2ZW50UXVldWUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEN1cnJlbnRFdmVudFF1ZXVlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCkKK3sKKwlERUJVR19DQUxMKCJHZXRDdXJyZW50RXZlbnRRdWV1ZVxuIikKKworCXJldHVybiAoamludClHZXRDdXJyZW50RXZlbnRRdWV1ZSgpOworfQorI2VuZGlmIC8qIE5PX0dldEN1cnJlbnRFdmVudFF1ZXVlICovCisKKyNpZm5kZWYgTk9fR2V0Q3VycmVudFByb2Nlc3MKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEN1cnJlbnRQcm9jZXNzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludEFycmF5IGFyZzApCit7CisJamludCAqbHBhcmcwPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldEN1cnJlbnRQcm9jZXNzXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIE5VTEwpOworCXJjID0gKGppbnQpR2V0Q3VycmVudFByb2Nlc3MoKFByb2Nlc3NTZXJpYWxOdW1iZXIgKilscGFyZzApOworCWlmIChhcmcwKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMCwgbHBhcmcwLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0Q3VycmVudFByb2Nlc3MgKi8KKworI2lmbmRlZiBOT19HZXRDdXJyZW50U2NyYXAKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEN1cnJlbnRTY3JhcAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnRBcnJheSBhcmcwKQoreworCWppbnQgKmxwYXJnMD1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRDdXJyZW50U2NyYXBcbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMCwgTlVMTCk7CisJcmMgPSAoamludClHZXRDdXJyZW50U2NyYXAoKFNjcmFwUmVmICopbHBhcmcwKTsKKwlpZiAoYXJnMCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIGxwYXJnMCwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldEN1cnJlbnRTY3JhcCAqLworCisjaWZuZGVmIE5PX0dldERhdGFCcm93c2VyQ2FsbGJhY2tzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXREYXRhQnJvd3NlckNhbGxiYWNrcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxKQoreworCURhdGFCcm93c2VyQ2FsbGJhY2tzIF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldERhdGFCcm93c2VyQ2FsbGJhY2tzXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldERhdGFCcm93c2VyQ2FsbGJhY2tzRmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlyYyA9IChqaW50KUdldERhdGFCcm93c2VyQ2FsbGJhY2tzKChDb250cm9sUmVmKWFyZzAsIChEYXRhQnJvd3NlckNhbGxiYWNrcyAqKWxwYXJnMSk7CisJaWYgKGFyZzEpIHNldERhdGFCcm93c2VyQ2FsbGJhY2tzRmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0RGF0YUJyb3dzZXJDYWxsYmFja3MgKi8KKworI2lmbmRlZiBOT19HZXREYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtblBvc2l0aW9uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXREYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtblBvc2l0aW9uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnRBcnJheSBhcmcyKQoreworCWppbnQgKmxwYXJnMj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXREYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtblBvc2l0aW9uXG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpR2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdDb2x1bW5Qb3NpdGlvbigoQ29udHJvbFJlZilhcmcwLCAoRGF0YUJyb3dzZXJUYWJsZVZpZXdDb2x1bW5JRClhcmcxLCAoRGF0YUJyb3dzZXJUYWJsZVZpZXdDb2x1bW5JbmRleCAqKWxwYXJnMik7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXREYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtblBvc2l0aW9uICovCisKKyNpZm5kZWYgTk9fR2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdOYW1lZENvbHVtbldpZHRoCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXREYXRhQnJvd3NlclRhYmxlVmlld05hbWVkQ29sdW1uV2lkdGgKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwganNob3J0QXJyYXkgYXJnMikKK3sKKwlqc2hvcnQgKmxwYXJnMj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXREYXRhQnJvd3NlclRhYmxlVmlld05hbWVkQ29sdW1uV2lkdGhcbiIpCisKKwlpZiAoYXJnMikgbHBhcmcyID0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlyYyA9IChqaW50KUdldERhdGFCcm93c2VyVGFibGVWaWV3TmFtZWRDb2x1bW5XaWR0aCgoQ29udHJvbFJlZilhcmcwLCAoRGF0YUJyb3dzZXJUYWJsZVZpZXdDb2x1bW5JRClhcmcxLCAoVUludDE2ICopbHBhcmcyKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdOYW1lZENvbHVtbldpZHRoICovCisKKyNpZm5kZWYgTk9fR2V0RGF0YUJyb3dzZXJJdGVtQ291bnQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldERhdGFCcm93c2VySXRlbUNvdW50CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGpib29sZWFuIGFyZzIsIGppbnQgYXJnMywgamludEFycmF5IGFyZzQpCit7CisJamludCAqbHBhcmc0PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldERhdGFCcm93c2VySXRlbUNvdW50XG4iKQorCisJaWYgKGFyZzQpIGxwYXJnNCA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIE5VTEwpOworCXJjID0gKGppbnQpR2V0RGF0YUJyb3dzZXJJdGVtQ291bnQoKENvbnRyb2xSZWYpYXJnMCwgKERhdGFCcm93c2VySXRlbUlEKWFyZzEsIChCb29sZWFuKWFyZzIsIChEYXRhQnJvd3Nlckl0ZW1TdGF0ZSlhcmczLCAoVUludDMyICopbHBhcmc0KTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldERhdGFCcm93c2VySXRlbUNvdW50ICovCisKKyNpZm5kZWYgTk9fR2V0RGF0YUJyb3dzZXJJdGVtRGF0YUJ1dHRvblZhbHVlCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXREYXRhQnJvd3Nlckl0ZW1EYXRhQnV0dG9uVmFsdWUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydEFycmF5IGFyZzEpCit7CisJanNob3J0ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0RGF0YUJyb3dzZXJJdGVtRGF0YUJ1dHRvblZhbHVlXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJcmMgPSAoamludClHZXREYXRhQnJvd3Nlckl0ZW1EYXRhQnV0dG9uVmFsdWUoKENvbnRyb2xSZWYpYXJnMCwgKFVJbnQxNiAqKWxwYXJnMSk7CisJaWYgKGFyZzEpICgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldERhdGFCcm93c2VySXRlbURhdGFCdXR0b25WYWx1ZSAqLworCisjaWZuZGVmIE5PX0dldERhdGFCcm93c2VySXRlbVBhcnRCb3VuZHMKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldERhdGFCcm93c2VySXRlbVBhcnRCb3VuZHMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMsIGpvYmplY3QgYXJnNCkKK3sKKwlSZWN0IF9hcmc0LCAqbHBhcmc0PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldERhdGFCcm93c2VySXRlbVBhcnRCb3VuZHNcbiIpCisKKwlpZiAoYXJnNCkgbHBhcmc0ID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzQsICZfYXJnNCk7CisJcmMgPSAoamludClHZXREYXRhQnJvd3Nlckl0ZW1QYXJ0Qm91bmRzKChDb250cm9sUmVmKWFyZzAsIChEYXRhQnJvd3Nlckl0ZW1JRClhcmcxLCAoRGF0YUJyb3dzZXJQcm9wZXJ0eUlEKWFyZzIsIChEYXRhQnJvd3NlclByb3BlcnR5UGFydClhcmczLCAoUmVjdCAqKWxwYXJnNCk7CisJaWYgKGFyZzQpIHNldFJlY3RGaWVsZHMoZW52LCBhcmc0LCBscGFyZzQpOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXREYXRhQnJvd3Nlckl0ZW1QYXJ0Qm91bmRzICovCisKKyNpZm5kZWYgTk9fR2V0RGF0YUJyb3dzZXJJdGVtcworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RGF0YUJyb3dzZXJJdGVtcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqYm9vbGVhbiBhcmcyLCBqaW50IGFyZzMsIGppbnQgYXJnNCkKK3sKKwlERUJVR19DQUxMKCJHZXREYXRhQnJvd3Nlckl0ZW1zXG4iKQorCisJcmV0dXJuIChqaW50KUdldERhdGFCcm93c2VySXRlbXMoKENvbnRyb2xSZWYpYXJnMCwgKERhdGFCcm93c2VySXRlbUlEKWFyZzEsIChCb29sZWFuKWFyZzIsIChEYXRhQnJvd3Nlckl0ZW1TdGF0ZSlhcmczLCAoSGFuZGxlKWFyZzQpOworfQorI2VuZGlmIC8qIE5PX0dldERhdGFCcm93c2VySXRlbXMgKi8KKworI2lmbmRlZiBOT19HZXREYXRhQnJvd3Nlckl0ZW1TdGF0ZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RGF0YUJyb3dzZXJJdGVtU3RhdGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJamludCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldERhdGFCcm93c2VySXRlbVN0YXRlXG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpR2V0RGF0YUJyb3dzZXJJdGVtU3RhdGUoKENvbnRyb2xSZWYpYXJnMCwgKERhdGFCcm93c2VySXRlbUlEKWFyZzEsIChEYXRhQnJvd3Nlckl0ZW1TdGF0ZSAqKWxwYXJnMik7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXREYXRhQnJvd3Nlckl0ZW1TdGF0ZSAqLworCisjaWZuZGVmIE5PX0dldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJCdG5IZWlnaHQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJCdG5IZWlnaHQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydEFycmF5IGFyZzEpCit7CisJanNob3J0ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckJ0bkhlaWdodFxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCXJjID0gKGppbnQpR2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckJ0bkhlaWdodCgoQ29udHJvbFJlZilhcmcwLCAoVUludDE2ICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckJ0bkhlaWdodCAqLworCisjaWZuZGVmIE5PX0dldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzYworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqb2JqZWN0IGFyZzIpCit7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MgX2FyZzIsICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NcbiIpCisKKwlpZiAoYXJnMikgbHBhcmcyID0gZ2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGaWVsZHMoZW52LCBhcmcyLCAmX2FyZzIpOworCXJjID0gKGppbnQpR2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MoKENvbnRyb2xSZWYpYXJnMCwgKERhdGFCcm93c2VyVGFibGVWaWV3Q29sdW1uSUQpYXJnMSwgKERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjICopbHBhcmcyKTsKKwlpZiAoYXJnMikgc2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2NGaWVsZHMoZW52LCBhcmcyLCBscGFyZzIpOworCXJldHVybiByYzsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0dldERhdGFCcm93c2VyVGFibGVWaWV3SXRlbUlECitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXREYXRhQnJvd3NlclRhYmxlVmlld0l0ZW1JRAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50QXJyYXkgYXJnMikKK3sKKwlqaW50ICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdJdGVtSURcbiIpCisKKwlpZiAoYXJnMikgbHBhcmcyID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJcmMgPSAoamludClHZXREYXRhQnJvd3NlclRhYmxlVmlld0l0ZW1JRCgoQ29udHJvbFJlZilhcmcwLCAoRGF0YUJyb3dzZXJUYWJsZVZpZXdSb3dJbmRleClhcmcxLCAoRGF0YUJyb3dzZXJJdGVtSUQgKilscGFyZzIpOworCWlmIChhcmcyKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdJdGVtSUQgKi8KKworI2lmbmRlZiBOT19HZXREYXRhQnJvd3NlclRhYmxlVmlld0l0ZW1Sb3cKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldERhdGFCcm93c2VyVGFibGVWaWV3SXRlbVJvdworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50QXJyYXkgYXJnMikKK3sKKwlqaW50ICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdJdGVtUm93XG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpR2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdJdGVtUm93KChDb250cm9sUmVmKWFyZzAsIChEYXRhQnJvd3NlclRhYmxlVmlld1Jvd0luZGV4KWFyZzEsIChEYXRhQnJvd3Nlckl0ZW1JRCAqKWxwYXJnMik7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXREYXRhQnJvd3NlclRhYmxlVmlld0l0ZW1Sb3cgKi8KKworI2lmbmRlZiBOT19HZXREYXRhQnJvd3NlclRhYmxlVmlld1Jvd0hlaWdodAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdSb3dIZWlnaHQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydEFycmF5IGFyZzEpCit7CisJanNob3J0ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdSb3dIZWlnaHRcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBOVUxMKTsKKwlyYyA9IChqaW50KUdldERhdGFCcm93c2VyVGFibGVWaWV3Um93SGVpZ2h0KChDb250cm9sUmVmKWFyZzAsIChVSW50MTYgKilscGFyZzEpOworCWlmIChhcmcxKSAoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXREYXRhQnJvd3NlclRhYmxlVmlld1Jvd0hlaWdodCAqLworCisjaWZuZGVmIE5PX0dldERhdGFCcm93c2VyU2Nyb2xsQmFySW5zZXQKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldERhdGFCcm93c2VyU2Nyb2xsQmFySW5zZXQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldERhdGFCcm93c2VyU2Nyb2xsQmFySW5zZXRcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJcmMgPSAoamludCkgR2V0RGF0YUJyb3dzZXJTY3JvbGxCYXJJbnNldCgoQ29udHJvbFJlZilhcmcwLCAoUmVjdCAqKWxwYXJnMSk7CisJaWYgKGFyZzEpIHNldFJlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworfQorI2VuZGlmIC8qIE5PX0dldERhdGFCcm93c2VyU2Nyb2xsQmFySW5zZXQgKi8KKworI2lmbmRlZiBOT19HZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50QXJyYXkgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJamludCAqbHBhcmcxPU5VTEw7CisJamludCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldERhdGFCcm93c2VyU2Nyb2xsUG9zaXRpb25cbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpR2V0RGF0YUJyb3dzZXJTY3JvbGxQb3NpdGlvbigoQ29udHJvbFJlZilhcmcwLCAoVUludDMyICopbHBhcmcxLCAoVUludDMyICopbHBhcmcyKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uICovCisKKyNpZm5kZWYgTk9fR2V0RGF0YUJyb3dzZXJTZWxlY3Rpb25BbmNob3IKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldERhdGFCcm93c2VyU2VsZWN0aW9uQW5jaG9yCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50QXJyYXkgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJamludCAqbHBhcmcxPU5VTEw7CisJamludCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldERhdGFCcm93c2VyU2VsZWN0aW9uQW5jaG9yXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlyYyA9IChqaW50KUdldERhdGFCcm93c2VyU2VsZWN0aW9uQW5jaG9yKChDb250cm9sUmVmKWFyZzAsIChVSW50MzIgKilscGFyZzEsIChVSW50MzIgKilscGFyZzIpOworCWlmIChhcmcxKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldERhdGFCcm93c2VyU2VsZWN0aW9uQW5jaG9yICovCisKKyNpZm5kZWYgTk9fR2V0RGJsVGltZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RGJsVGltZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiR2V0RGJsVGltZVxuIikKKworCXJldHVybiAoamludClHZXREYmxUaW1lKCk7Cit9CisjZW5kaWYgLyogTk9fR2V0RGJsVGltZSAqLworCisjaWZuZGVmIE5PX0dldERlZkZvbnRTaXplCitKTklFWFBPUlQganNob3J0IEpOSUNBTEwgT1NfTkFUSVZFKEdldERlZkZvbnRTaXplKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiR2V0RGVmRm9udFNpemVcbiIpCisKKwlyZXR1cm4gKGpzaG9ydClHZXREZWZGb250U2l6ZSgpOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fR2V0RXZlbnRDbGFzcworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RXZlbnRDbGFzcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJHZXRFdmVudENsYXNzXG4iKQorCisJcmV0dXJuIChqaW50KUdldEV2ZW50Q2xhc3MoKEV2ZW50UmVmKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldEV2ZW50Q2xhc3MgKi8KKworI2lmbmRlZiBOT19HZXRFdmVudERpc3BhdGNoZXJUYXJnZXQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEV2ZW50RGlzcGF0Y2hlclRhcmdldAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiR2V0RXZlbnREaXNwYXRjaGVyVGFyZ2V0XG4iKQorCisJcmV0dXJuIChqaW50KUdldEV2ZW50RGlzcGF0Y2hlclRhcmdldCgpOworfQorI2VuZGlmIC8qIE5PX0dldEV2ZW50RGlzcGF0Y2hlclRhcmdldCAqLworCisjaWZuZGVmIE5PX0dldEV2ZW50S2luZAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0RXZlbnRLaW5kCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkdldEV2ZW50S2luZFxuIikKKworCXJldHVybiAoamludClHZXRFdmVudEtpbmQoKEV2ZW50UmVmKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldEV2ZW50S2luZCAqLworCisjaWZuZGVmIE5PX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJXzNCCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJSV8zSV8zQgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnRBcnJheSBhcmczLCBqaW50IGFyZzQsIGppbnRBcnJheSBhcmc1LCBqYnl0ZUFycmF5IGFyZzYpCit7CisJamludCAqbHBhcmczPU5VTEw7CisJamludCAqbHBhcmc1PU5VTEw7CisJamJ5dGUgKmxwYXJnNj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJSV8zSV8zQlxuIikKKworCWlmIChhcmczKSBscGFyZzMgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBOVUxMKTsKKwlpZiAoYXJnNSkgbHBhcmc1ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgTlVMTCk7CisJaWYgKGFyZzYpIGxwYXJnNiA9ICgqZW52KS0+R2V0Qnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmc2LCBOVUxMKTsKKwlyYyA9IChqaW50KUdldEV2ZW50UGFyYW1ldGVyKChFdmVudFJlZilhcmcwLCAoRXZlbnRQYXJhbU5hbWUpYXJnMSwgKEV2ZW50UGFyYW1UeXBlKWFyZzIsIChFdmVudFBhcmFtVHlwZSAqKWxwYXJnMywgKFVJbnQzMilhcmc0LCAoVUludDMyICopbHBhcmc1LCAodm9pZCAqKWxwYXJnNik7CisJaWYgKGFyZzMpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBscGFyZzMsIDApOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlpZiAoYXJnNikgKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmc2LCBscGFyZzYsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJSV8zSV8zQiAqLworCisjaWZuZGVmIE5PX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fSElDb21tYW5kXzIKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fSElDb21tYW5kXzIKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50QXJyYXkgYXJnMywgamludCBhcmc0LCBqaW50QXJyYXkgYXJnNSwgam9iamVjdCBhcmc2KQoreworCWppbnQgKmxwYXJnMz1OVUxMOworCWppbnQgKmxwYXJnNT1OVUxMOworCUhJQ29tbWFuZCBfYXJnNiwgKmxwYXJnNj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJSV8zSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0hJQ29tbWFuZF8yXG4iKQorCisJaWYgKGFyZzMpIGxwYXJnMyA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIE5VTEwpOworCWlmIChhcmc1KSBscGFyZzUgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBOVUxMKTsKKwlpZiAoYXJnNikgbHBhcmc2ID0gZ2V0SElDb21tYW5kRmllbGRzKGVudiwgYXJnNiwgJl9hcmc2KTsKKwlyYyA9IChqaW50KUdldEV2ZW50UGFyYW1ldGVyKChFdmVudFJlZilhcmcwLCAoRXZlbnRQYXJhbU5hbWUpYXJnMSwgKEV2ZW50UGFyYW1UeXBlKWFyZzIsIChFdmVudFBhcmFtVHlwZSAqKWxwYXJnMywgKFVJbnQzMilhcmc0LCAoVUludDMyICopbHBhcmc1LCAodm9pZCAqKWxwYXJnNik7CisJaWYgKGFyZzMpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBscGFyZzMsIDApOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlpZiAoYXJnNikgc2V0SElDb21tYW5kRmllbGRzKGVudiwgYXJnNiwgbHBhcmc2KTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0RXZlbnRQYXJhbWV0ZXJfX0lJSV8zSUlfM0lMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9ISUNvbW1hbmRfMiAqLworCisjaWZuZGVmIE5PX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJXzNJCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJSV8zSV8zSQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnRBcnJheSBhcmczLCBqaW50IGFyZzQsIGppbnRBcnJheSBhcmc1LCBqaW50QXJyYXkgYXJnNikKK3sKKwlqaW50ICpscGFyZzM9TlVMTDsKKwlqaW50ICpscGFyZzU9TlVMTDsKKwlqaW50ICpscGFyZzY9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0RXZlbnRQYXJhbWV0ZXJfX0lJSV8zSUlfM0lfM0lcbiIpCisKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJaWYgKGFyZzUpIGxwYXJnNSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIE5VTEwpOworCWlmIChhcmc2KSBscGFyZzYgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc2LCBOVUxMKTsKKwlyYyA9IChqaW50KUdldEV2ZW50UGFyYW1ldGVyKChFdmVudFJlZilhcmcwLCAoRXZlbnRQYXJhbU5hbWUpYXJnMSwgKEV2ZW50UGFyYW1UeXBlKWFyZzIsIChFdmVudFBhcmFtVHlwZSAqKWxwYXJnMywgKFVJbnQzMilhcmc0LCAoVUludDMyICopbHBhcmc1LCAodm9pZCAqKWxwYXJnNik7CisJaWYgKGFyZzMpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBscGFyZzMsIDApOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlpZiAoYXJnNikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzYsIGxwYXJnNiwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJXzNJICovCisKKyNpZm5kZWYgTk9fR2V0RXZlbnRQYXJhbWV0ZXJfX0lJSV8zSUlfM0lfM0MKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJXzNDCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludEFycmF5IGFyZzMsIGppbnQgYXJnNCwgamludEFycmF5IGFyZzUsIGpjaGFyQXJyYXkgYXJnNikKK3sKKwlqaW50ICpscGFyZzM9TlVMTDsKKwlqaW50ICpscGFyZzU9TlVMTDsKKwlqY2hhciAqbHBhcmc2PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJXzNDXG4iKQorCisJaWYgKGFyZzMpIGxwYXJnMyA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIE5VTEwpOworCWlmIChhcmc1KSBscGFyZzUgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBOVUxMKTsKKwlpZiAoYXJnNikgbHBhcmc2ID0gKCplbnYpLT5HZXRDaGFyQXJyYXlFbGVtZW50cyhlbnYsIGFyZzYsIE5VTEwpOworCXJjID0gKGppbnQpR2V0RXZlbnRQYXJhbWV0ZXIoKEV2ZW50UmVmKWFyZzAsIChFdmVudFBhcmFtTmFtZSlhcmcxLCAoRXZlbnRQYXJhbVR5cGUpYXJnMiwgKEV2ZW50UGFyYW1UeXBlICopbHBhcmczLCAoVUludDMyKWFyZzQsIChVSW50MzIgKilscGFyZzUsICh2b2lkICopbHBhcmc2KTsKKwlpZiAoYXJnMykgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CisJaWYgKGFyZzUpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBscGFyZzUsIDApOworCWlmIChhcmc2KSAoKmVudiktPlJlbGVhc2VDaGFyQXJyYXlFbGVtZW50cyhlbnYsIGFyZzYsIGxwYXJnNiwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJXzNDICovCisKKyNpZm5kZWYgTk9fR2V0RXZlbnRQYXJhbWV0ZXJfX0lJSV8zSUlfM0lfM1MKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJXzNTCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludEFycmF5IGFyZzMsIGppbnQgYXJnNCwgamludEFycmF5IGFyZzUsIGpzaG9ydEFycmF5IGFyZzYpCit7CisJamludCAqbHBhcmczPU5VTEw7CisJamludCAqbHBhcmc1PU5VTEw7CisJanNob3J0ICpscGFyZzY9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0RXZlbnRQYXJhbWV0ZXJfX0lJSV8zSUlfM0lfM1NcbiIpCisKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJaWYgKGFyZzUpIGxwYXJnNSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIE5VTEwpOworCWlmIChhcmc2KSBscGFyZzYgPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzYsIE5VTEwpOworCXJjID0gKGppbnQpR2V0RXZlbnRQYXJhbWV0ZXIoKEV2ZW50UmVmKWFyZzAsIChFdmVudFBhcmFtTmFtZSlhcmcxLCAoRXZlbnRQYXJhbVR5cGUpYXJnMiwgKEV2ZW50UGFyYW1UeXBlICopbHBhcmczLCAoVUludDMyKWFyZzQsIChVSW50MzIgKilscGFyZzUsICh2b2lkICopbHBhcmc2KTsKKwlpZiAoYXJnMykgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CisJaWYgKGFyZzUpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBscGFyZzUsIDApOworCWlmIChhcmc2KSAoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmc2LCBscGFyZzYsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJSV8zSV8zUyAqLworCisjaWZuZGVmIE5PX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fQ0dQb2ludF8yCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJSV8zSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0NHUG9pbnRfMgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnRBcnJheSBhcmczLCBqaW50IGFyZzQsIGppbnRBcnJheSBhcmc1LCBqb2JqZWN0IGFyZzYpCit7CisJamludCAqbHBhcmczPU5VTEw7CisJamludCAqbHBhcmc1PU5VTEw7CisJQ0dQb2ludCBfYXJnNiwgKmxwYXJnNj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJSV8zSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0NHUG9pbnRfMlxuIikKKworCWlmIChhcmczKSBscGFyZzMgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBOVUxMKTsKKwlpZiAoYXJnNSkgbHBhcmc1ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgTlVMTCk7CisJaWYgKGFyZzYpIGxwYXJnNiA9IGdldENHUG9pbnRGaWVsZHMoZW52LCBhcmc2LCAmX2FyZzYpOworCXJjID0gKGppbnQpR2V0RXZlbnRQYXJhbWV0ZXIoKEV2ZW50UmVmKWFyZzAsIChFdmVudFBhcmFtTmFtZSlhcmcxLCAoRXZlbnRQYXJhbVR5cGUpYXJnMiwgKEV2ZW50UGFyYW1UeXBlICopbHBhcmczLCAoVUludDMyKWFyZzQsIChVSW50MzIgKilscGFyZzUsICh2b2lkICopbHBhcmc2KTsKKwlpZiAoYXJnMykgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CisJaWYgKGFyZzUpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBscGFyZzUsIDApOworCWlmIChhcmc2KSBzZXRDR1BvaW50RmllbGRzKGVudiwgYXJnNiwgbHBhcmc2KTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19HZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJSV8zSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX1BvaW50XzIKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fUG9pbnRfMgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnRBcnJheSBhcmczLCBqaW50IGFyZzQsIGppbnRBcnJheSBhcmc1LCBqb2JqZWN0IGFyZzYpCit7CisJamludCAqbHBhcmczPU5VTEw7CisJamludCAqbHBhcmc1PU5VTEw7CisJUG9pbnQgX2FyZzYsICpscGFyZzY9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0RXZlbnRQYXJhbWV0ZXJfX0lJSV8zSUlfM0lMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9Qb2ludF8yXG4iKQorCisJaWYgKGFyZzMpIGxwYXJnMyA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIE5VTEwpOworCWlmIChhcmc1KSBscGFyZzUgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBOVUxMKTsKKwlpZiAoYXJnNikgbHBhcmc2ID0gZ2V0UG9pbnRGaWVsZHMoZW52LCBhcmc2LCAmX2FyZzYpOworCXJjID0gKGppbnQpR2V0RXZlbnRQYXJhbWV0ZXIoKEV2ZW50UmVmKWFyZzAsIChFdmVudFBhcmFtTmFtZSlhcmcxLCAoRXZlbnRQYXJhbVR5cGUpYXJnMiwgKEV2ZW50UGFyYW1UeXBlICopbHBhcmczLCAoVUludDMyKWFyZzQsIChVSW50MzIgKilscGFyZzUsICh2b2lkICopbHBhcmc2KTsKKwlpZiAoYXJnMykgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CisJaWYgKGFyZzUpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBscGFyZzUsIDApOworCWlmIChhcmc2KSBzZXRQb2ludEZpZWxkcyhlbnYsIGFyZzYsIGxwYXJnNik7CisJcmV0dXJuIHJjOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fR2V0RXZlbnRQYXJhbWV0ZXJfX0lJSV8zSUlfM0lMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9SR0JDb2xvcl8yCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJSV8zSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX1JHQkNvbG9yXzIKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50QXJyYXkgYXJnMywgamludCBhcmc0LCBqaW50QXJyYXkgYXJnNSwgam9iamVjdCBhcmc2KQoreworCWppbnQgKmxwYXJnMz1OVUxMOworCWppbnQgKmxwYXJnNT1OVUxMOworCVJHQkNvbG9yIF9hcmc2LCAqbHBhcmc2PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fUkdCQ29sb3JfMlxuIikKKworCWlmIChhcmczKSBscGFyZzMgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBOVUxMKTsKKwlpZiAoYXJnNSkgbHBhcmc1ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgTlVMTCk7CisJaWYgKGFyZzYpIGxwYXJnNiA9IGdldFJHQkNvbG9yRmllbGRzKGVudiwgYXJnNiwgJl9hcmc2KTsKKwlyYyA9IChqaW50KUdldEV2ZW50UGFyYW1ldGVyKChFdmVudFJlZilhcmcwLCAoRXZlbnRQYXJhbU5hbWUpYXJnMSwgKEV2ZW50UGFyYW1UeXBlKWFyZzIsIChFdmVudFBhcmFtVHlwZSAqKWxwYXJnMywgKFVJbnQzMilhcmc0LCAoVUludDMyICopbHBhcmc1LCAodm9pZCAqKWxwYXJnNik7CisJaWYgKGFyZzMpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBscGFyZzMsIDApOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlpZiAoYXJnNikgc2V0UkdCQ29sb3JGaWVsZHMoZW52LCBhcmc2LCBscGFyZzYpOworCXJldHVybiByYzsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0dldEV2ZW50UGFyYW1ldGVyX19JSUlfM0lJXzNJTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fUmVjdF8yCitKTklFWFBPUlQgamludCBKTklDQUxMIE9TX05BVElWRShHZXRFdmVudFBhcmFtZXRlcl9fSUlJXzNJSV8zSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX1JlY3RfMikKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50QXJyYXkgYXJnMywgamludCBhcmc0LCBqaW50QXJyYXkgYXJnNSwgam9iamVjdCBhcmc2KQoreworCWppbnQgKmxwYXJnMz1OVUxMOworCWppbnQgKmxwYXJnNT1OVUxMOworCVJlY3QgX2FyZzYsICpscGFyZzY9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0RXZlbnRQYXJhbWV0ZXJfX0lJSV8zSUlfM0lMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9SZWN0XzJcbiIpCisKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJaWYgKGFyZzUpIGxwYXJnNSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIE5VTEwpOworCWlmIChhcmc2KSBscGFyZzYgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnNiwgJl9hcmc2KTsKKwlyYyA9IChqaW50KUdldEV2ZW50UGFyYW1ldGVyKChFdmVudFJlZilhcmcwLCAoRXZlbnRQYXJhbU5hbWUpYXJnMSwgKEV2ZW50UGFyYW1UeXBlKWFyZzIsIChFdmVudFBhcmFtVHlwZSAqKWxwYXJnMywgKFVJbnQzMilhcmc0LCAoVUludDMyICopbHBhcmc1LCAodm9pZCAqKWxwYXJnNik7CisJaWYgKGFyZzMpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBscGFyZzMsIDApOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlpZiAoYXJnNikgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzYsIGxwYXJnNik7CisJcmV0dXJuIHJjOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fR2V0RXZlbnRUaW1lCitKTklFWFBPUlQgamRvdWJsZSBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRFdmVudFRpbWUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiR2V0RXZlbnRUaW1lXG4iKQorCisJcmV0dXJuIChqZG91YmxlKUdldEV2ZW50VGltZSgoRXZlbnRSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fR2V0RXZlbnRUaW1lICovCisKKyNpZm5kZWYgTk9fR2V0Rm9udEluZm8KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEZvbnRJbmZvCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwganNob3J0QXJyYXkgYXJnMCkKK3sKKwlqc2hvcnQgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgiR2V0Rm9udEluZm9cbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmcwLCBOVUxMKTsKKwlHZXRGb250SW5mbygoRm9udEluZm8gKilscGFyZzApOworCWlmIChhcmcwKSAoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmcwLCBscGFyZzAsIDApOworfQorI2VuZGlmIC8qIE5PX0dldEZvbnRJbmZvICovCisKKyNpZm5kZWYgTk9fR2V0R0RldmljZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0R0RldmljZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiR2V0R0RldmljZVxuIikKKworCXJldHVybiAoamludClHZXRHRGV2aWNlKCk7Cit9CisjZW5kaWYgLyogTk9fR2V0R0RldmljZSAqLworCisjaWZuZGVmIE5PX0dldEdXb3JsZAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0R1dvcmxkCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludEFycmF5IGFyZzAsIGppbnRBcnJheSBhcmcxKQoreworCWppbnQgKmxwYXJnMD1OVUxMOworCWppbnQgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgiR2V0R1dvcmxkXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIE5VTEwpOworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBOVUxMKTsKKwlHZXRHV29ybGQoKENHcmFmUHRyICopbHBhcmcwLCAoR0RIYW5kbGUgKilscGFyZzEpOworCWlmIChhcmcwKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMCwgbHBhcmcwLCAwKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7Cit9CisjZW5kaWYgLyogTk9fR2V0R1dvcmxkICovCisKKyNpZm5kZWYgTk9fR2V0R2xvYmFsTW91c2UKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEdsb2JhbE1vdXNlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwKQoreworCVBvaW50IF9hcmcwLCAqbHBhcmcwPU5VTEw7CisKKwlERUJVR19DQUxMKCJHZXRHbG9iYWxNb3VzZVxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRQb2ludEZpZWxkcyhlbnYsIGFyZzAsICZfYXJnMCk7CisJR2V0R2xvYmFsTW91c2UoKFBvaW50ICopbHBhcmcwKTsKKwlpZiAoYXJnMCkgc2V0UG9pbnRGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldEdsb2JhbE1vdXNlICovCisKKyNpZm5kZWYgTk9fR2V0SWNvblJlZgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0SWNvblJlZgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpzaG9ydCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludEFycmF5IGFyZzMpCit7CisJamludCAqbHBhcmczPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldEljb25SZWZcbiIpCisKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJcmMgPSAoamludClHZXRJY29uUmVmKChTSW50MTYpYXJnMCwgKE9TVHlwZSlhcmcxLCAoT1NUeXBlKWFyZzIsIChJY29uUmVmICopbHBhcmczKTsKKwlpZiAoYXJnMykgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fR2V0SGFuZGxlU2l6ZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0SGFuZGxlU2l6ZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJHZXRIYW5kbGVTaXplXG4iKQorCisJcmV0dXJuIChqaW50KUdldEhhbmRsZVNpemUoKEhhbmRsZSlhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19HZXRIYW5kbGVTaXplICovCisKKyNpZm5kZWYgTk9fR2V0SW5kTWVudUl0ZW1XaXRoQ29tbWFuZElECitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRJbmRNZW51SXRlbVdpdGhDb21tYW5kSUQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50QXJyYXkgYXJnMywganNob3J0QXJyYXkgYXJnNCkKK3sKKwlqaW50ICpscGFyZzM9TlVMTDsKKwlqc2hvcnQgKmxwYXJnND1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRJbmRNZW51SXRlbVdpdGhDb21tYW5kSURcbiIpCisKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJaWYgKGFyZzQpIGxwYXJnNCA9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNCwgTlVMTCk7CisJcmMgPSAoamludClHZXRJbmRNZW51SXRlbVdpdGhDb21tYW5kSUQoKE1lbnVSZWYpYXJnMCwgKE1lbnVDb21tYW5kKWFyZzEsIChVSW50MzIpYXJnMiwgKE1lbnVSZWYgKilscGFyZzMsIChNZW51SXRlbUluZGV4ICopbHBhcmc0KTsKKwlpZiAoYXJnMykgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CisJaWYgKGFyZzQpICgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldEluZE1lbnVJdGVtV2l0aENvbW1hbmRJRCAqLworCisjaWZuZGVmIE5PX0dldEluZGV4ZWRTdWJDb250cm9sCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRJbmRleGVkU3ViQ29udHJvbAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGppbnRBcnJheSBhcmcyKQoreworCWppbnQgKmxwYXJnMj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRJbmRleGVkU3ViQ29udHJvbFxuIikKKworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlyYyA9IChqaW50KUdldEluZGV4ZWRTdWJDb250cm9sKChDb250cm9sUmVmKWFyZzAsIChVSW50MTYpYXJnMSwgKENvbnRyb2xSZWYgKilscGFyZzIpOworCWlmIChhcmcyKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0SW5kZXhlZFN1YkNvbnRyb2wgKi8KKworI2lmbmRlZiBOT19HZXRLZXlib2FyZEZvY3VzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRLZXlib2FyZEZvY3VzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50QXJyYXkgYXJnMSkKK3sKKwlqaW50ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0S2V5Ym9hcmRGb2N1c1xuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBOVUxMKTsKKwlyYyA9IChqaW50KUdldEtleWJvYXJkRm9jdXMoKFdpbmRvd1JlZilhcmcwLCAoQ29udHJvbFJlZiAqKWxwYXJnMSk7CisJaWYgKGFyZzEpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXRLZXlib2FyZEZvY3VzICovCisKKyNpZm5kZWYgTk9fR2V0TGFzdFVzZXJFdmVudFRpbWUKK0pOSUVYUE9SVCBqZG91YmxlIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldExhc3RVc2VyRXZlbnRUaW1lCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCkKK3sKKwlERUJVR19DQUxMKCJHZXRMYXN0VXNlckV2ZW50VGltZVxuIikKKworCXJldHVybiAoamRvdWJsZSlHZXRMYXN0VXNlckV2ZW50VGltZSgpOworfQorI2VuZGlmIC8qIE5PX0dldExhc3RVc2VyRXZlbnRUaW1lICovCisKKyNpZm5kZWYgTk9fR2V0TWFpbkRldmljZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0TWFpbkRldmljZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiR2V0TWFpbkRldmljZVxuIikKKworCXJldHVybiAoamludClHZXRNYWluRGV2aWNlKCk7Cit9CisjZW5kaWYgLyogTk9fR2V0TWFpbkRldmljZSAqLworCisjaWZuZGVmIE5PX0dldE1haW5FdmVudFF1ZXVlCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRNYWluRXZlbnRRdWV1ZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiR2V0TWFpbkV2ZW50UXVldWVcbiIpCisKKwlyZXR1cm4gKGppbnQpR2V0TWFpbkV2ZW50UXVldWUoKTsKK30KKyNlbmRpZiAvKiBOT19HZXRNYWluRXZlbnRRdWV1ZSAqLworCisjaWZuZGVmIE5PX0dldE1lbnVDb21tYW5kTWFyaworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0TWVudUNvbW1hbmRNYXJrCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGpjaGFyQXJyYXkgYXJnMikKK3sKKwlqY2hhciAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldE1lbnVDb21tYW5kTWFya1xuIikKKworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldENoYXJBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJcmMgPSAoamludClHZXRNZW51Q29tbWFuZE1hcmsoKE1lbnVSZWYpYXJnMCwgKE1lbnVDb21tYW5kKWFyZzEsIChVbmlDaGFyICopbHBhcmcyKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlQ2hhckFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXRNZW51Q29tbWFuZE1hcmsgKi8KKworI2lmbmRlZiBOT19HZXRNZW51RXZlbnRUYXJnZXQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldE1lbnVFdmVudFRhcmdldAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJHZXRNZW51RXZlbnRUYXJnZXRcbiIpCisKKwlyZXR1cm4gKGppbnQpR2V0TWVudUV2ZW50VGFyZ2V0KChNZW51UmVmKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldE1lbnVFdmVudFRhcmdldCAqLworCisjaWZuZGVmIE5PX0dldE1lbnVGb250CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRNZW51Rm9udAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0QXJyYXkgYXJnMSwganNob3J0QXJyYXkgYXJnMikKK3sKKwlqc2hvcnQgKmxwYXJnMT1OVUxMOworCWpzaG9ydCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldE1lbnVGb250XG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJcmMgPSAoamludClHZXRNZW51Rm9udCgoTWVudVJlZilhcmcwLCAoU0ludDE2ICopbHBhcmcxLCAoVUludDE2ICopbHBhcmcyKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0TWVudUZvbnQgKi8KKworI2lmbmRlZiBOT19HZXRNZW51SUQKK0pOSUVYUE9SVCBqc2hvcnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0TWVudUlECisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkdldE1lbnVJRFxuIikKKworCXJldHVybiAoanNob3J0KUdldE1lbnVJRCgoTWVudVJlZilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19HZXRNZW51SUQgKi8KKworI2lmbmRlZiBOT19HZXRNZW51SXRlbUNvbW1hbmRJRAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0TWVudUl0ZW1Db21tYW5kSUQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxLCBqaW50QXJyYXkgYXJnMikKK3sKKwlqaW50ICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0TWVudUl0ZW1Db21tYW5kSURcbiIpCisKKwlpZiAoYXJnMikgbHBhcmcyID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJcmMgPSAoamludClHZXRNZW51SXRlbUNvbW1hbmRJRCgoTWVudVJlZilhcmcwLCAoU0ludDE2KWFyZzEsIChNZW51Q29tbWFuZCAqKWxwYXJnMik7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXRNZW51SXRlbUNvbW1hbmRJRCAqLworCisjaWZuZGVmIE5PX0dldE1lbnVJdGVtSGllcmFyY2hpY2FsTWVudQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0TWVudUl0ZW1IaWVyYXJjaGljYWxNZW51CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJamludCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldE1lbnVJdGVtSGllcmFyY2hpY2FsTWVudVxuIikKKworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlyYyA9IChqaW50KUdldE1lbnVJdGVtSGllcmFyY2hpY2FsTWVudSgoTWVudVJlZilhcmcwLCAoU0ludDE2KWFyZzEsIChNZW51UmVmICopbHBhcmcyKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldE1lbnVJdGVtSGllcmFyY2hpY2FsTWVudSAqLworCisjaWZuZGVmIE5PX0dldE1lbnVJdGVtUmVmQ29uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRNZW51SXRlbVJlZkNvbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGppbnRBcnJheSBhcmcyKQoreworCWppbnQgKmxwYXJnMj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRNZW51SXRlbVJlZkNvblxuIikKKworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlyYyA9IChqaW50KUdldE1lbnVJdGVtUmVmQ29uKChNZW51UmVmKWFyZzAsIChTSW50MTYpYXJnMSwgKFVJbnQzMiAqKWxwYXJnMik7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXRNZW51SXRlbVJlZkNvbiAqLworCisjaWZuZGVmIE5PX0dldE1lbnVUcmFja2luZ0RhdGEKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldE1lbnVUcmFja2luZ0RhdGEKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlNZW51VHJhY2tpbmdEYXRhIF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldE1lbnVUcmFja2luZ0RhdGFcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0TWVudVRyYWNraW5nRGF0YUZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJcmMgPSAoamludClHZXRNZW51VHJhY2tpbmdEYXRhKChNZW51UmVmKWFyZzAsIGxwYXJnMSk7CisJaWYgKGFyZzEpIHNldE1lbnVUcmFja2luZ0RhdGFGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCXJldHVybiByYzsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0dldE1vdXNlCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRNb3VzZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCkKK3sKKwlQb2ludCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgiR2V0TW91c2VcbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gZ2V0UG9pbnRGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCUdldE1vdXNlKChQb2ludCAqKWxwYXJnMCk7CisJaWYgKGFyZzApIHNldFBvaW50RmllbGRzKGVudiwgYXJnMCwgbHBhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19HZXRNb3VzZSAqLworCisjaWZuZGVmIE5PX0dldFBpeEJvdW5kcworSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0UGl4Qm91bmRzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEpCit7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgiR2V0UGl4Qm91bmRzXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCUdldFBpeEJvdW5kcygoUGl4TWFwSGFuZGxlKWFyZzAsIChSZWN0ICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fR2V0UGl4Qm91bmRzICovCisKKyNpZm5kZWYgTk9fR2V0UGl4RGVwdGgKK0pOSUVYUE9SVCBqc2hvcnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0UGl4RGVwdGgKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiR2V0UGl4RGVwdGhcbiIpCisKKwlyZXR1cm4gKGpzaG9ydClHZXRQaXhEZXB0aCgoUGl4TWFwSGFuZGxlKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldFBpeERlcHRoICovCisKKyNpZm5kZWYgTk9fR2V0UG9ydAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0UG9ydAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnRBcnJheSBhcmcwKQoreworCWppbnQgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgiR2V0UG9ydFxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcwLCBOVUxMKTsKKwlHZXRQb3J0KChHcmFmUHRyICopbHBhcmcwKTsKKwlpZiAoYXJnMCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIGxwYXJnMCwgMCk7Cit9CisjZW5kaWYgLyogTk9fR2V0UG9ydCAqLworCisjaWZuZGVmIE5PX0dldFBvcnRCaXRNYXBGb3JDb3B5Qml0cworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0UG9ydEJpdE1hcEZvckNvcHlCaXRzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkdldFBvcnRCaXRNYXBGb3JDb3B5Qml0c1xuIikKKworCXJldHVybiAoamludClHZXRQb3J0Qml0TWFwRm9yQ29weUJpdHMoKENHcmFmUHRyKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldFBvcnRCaXRNYXBGb3JDb3B5Qml0cyAqLworCisjaWZuZGVmIE5PX0dldFBvcnRCb3VuZHMKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFBvcnRCb3VuZHMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisKKwlERUJVR19DQUxMKCJHZXRQb3J0Qm91bmRzXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCUdldFBvcnRCb3VuZHMoKENHcmFmUHRyKWFyZzAsIChSZWN0ICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fR2V0UG9ydEJvdW5kcyAqLworCisjaWZuZGVmIE5PX0dldFBvcnRDbGlwUmVnaW9uCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRQb3J0Q2xpcFJlZ2lvbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIkdldFBvcnRDbGlwUmVnaW9uXG4iKQorCisJR2V0UG9ydENsaXBSZWdpb24oKENHcmFmUHRyKWFyZzAsIChSZ25IYW5kbGUpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fR2V0UG9ydENsaXBSZWdpb24gKi8KKworI2lmbmRlZiBOT19HZXRQb3J0VmlzaWJsZVJlZ2lvbgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0UG9ydFZpc2libGVSZWdpb24KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJHZXRQb3J0VmlzaWJsZVJlZ2lvblxuIikKKworCXJldHVybiAoamludClHZXRQb3J0VmlzaWJsZVJlZ2lvbigoQ0dyYWZQdHIpYXJnMCwgKFJnbkhhbmRsZSlhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19HZXRQb3J0VmlzaWJsZVJlZ2lvbiAqLworCisjaWZuZGVmIE5PX0dldFB0clNpemUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFB0clNpemUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiR2V0UHRyU2l6ZVxuIikKKworCXJldHVybiAoamludClHZXRQdHJTaXplKChQdHIpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fR2V0UHRyU2l6ZSAqLworCisjaWZuZGVmIE5PX0dldFJlZ2lvbkJvdW5kcworSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0UmVnaW9uQm91bmRzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEpCit7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgiR2V0UmVnaW9uQm91bmRzXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCUdldFJlZ2lvbkJvdW5kcygoUmduSGFuZGxlKWFyZzAsIChSZWN0ICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fR2V0UmVnaW9uQm91bmRzICovCisKKyNpZm5kZWYgTk9fR2V0Um9vdENvbnRyb2wKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFJvb3RDb250cm9sCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50QXJyYXkgYXJnMSkKK3sKKwlqaW50ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0Um9vdENvbnRyb2xcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJcmMgPSAoamludClHZXRSb290Q29udHJvbCgoV2luZG93UmVmKWFyZzAsIChDb250cm9sUmVmICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldFJvb3RDb250cm9sICovCisKKyNpZm5kZWYgTk9fR2V0U2NyYXBGbGF2b3JDb3VudAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0U2NyYXBGbGF2b3JDb3VudAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludEFycmF5IGFyZzEpCit7CisJamludCAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldFNjcmFwRmxhdm9yQ291bnRcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJcmMgPSAoamludClHZXRTY3JhcEZsYXZvckNvdW50KChTY3JhcFJlZilhcmcwLCAoVUludDMyICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldFNjcmFwRmxhdm9yQ291bnQgKi8KKworI2lmbmRlZiBOT19HZXRTY3JhcEZsYXZvckRhdGEKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFNjcmFwRmxhdm9yRGF0YQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50QXJyYXkgYXJnMiwgamJ5dGVBcnJheSBhcmczKQoreworCWppbnQgKmxwYXJnMj1OVUxMOworCWpieXRlICpscGFyZzM9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0U2NyYXBGbGF2b3JEYXRhXG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCWlmIChhcmczKSBscGFyZzMgPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJcmMgPSAoamludClHZXRTY3JhcEZsYXZvckRhdGEoKFNjcmFwUmVmKWFyZzAsIChTY3JhcEZsYXZvclR5cGUpYXJnMSwgKFNpemUgKilscGFyZzIsICh2b2lkICopbHBhcmczKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJaWYgKGFyZzMpICgqZW52KS0+UmVsZWFzZUJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0U2NyYXBGbGF2b3JEYXRhICovCisKKyNpZm5kZWYgTk9fR2V0U2NyYXBGbGF2b3JJbmZvTGlzdAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0U2NyYXBGbGF2b3JJbmZvTGlzdAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludEFycmF5IGFyZzEsIGppbnRBcnJheSBhcmcyKQoreworCWppbnQgKmxwYXJnMT1OVUxMOworCWppbnQgKmxwYXJnMj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRTY3JhcEZsYXZvckluZm9MaXN0XG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlyYyA9IChqaW50KUdldFNjcmFwRmxhdm9ySW5mb0xpc3QoKFNjcmFwUmVmKWFyZzAsIChVSW50MzIgKilscGFyZzEsIChTY3JhcEZsYXZvckluZm8gKilscGFyZzIpOworCWlmIChhcmcxKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldFNjcmFwRmxhdm9ySW5mb0xpc3QgKi8KKworI2lmbmRlZiBOT19HZXRTY3JhcEZsYXZvclNpemUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFNjcmFwRmxhdm9yU2l6ZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50QXJyYXkgYXJnMikKK3sKKwlqaW50ICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0U2NyYXBGbGF2b3JTaXplXG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpR2V0U2NyYXBGbGF2b3JTaXplKChTY3JhcFJlZilhcmcwLCAoU2NyYXBGbGF2b3JUeXBlKWFyZzEsIChTaXplICopbHBhcmcyKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldFNjcmFwRmxhdm9yU2l6ZSAqLworCisjaWZuZGVmIE5PX0dldFN1cGVyQ29udHJvbAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0U3VwZXJDb250cm9sCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50QXJyYXkgYXJnMSkKK3sKKwlqaW50ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0U3VwZXJDb250cm9sXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCXJjID0gKGppbnQpR2V0U3VwZXJDb250cm9sKChDb250cm9sUmVmKWFyZzAsIChDb250cm9sUmVmICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldFN1cGVyQ29udHJvbCAqLworCisjaWZuZGVmIE5PX0dldFRoZW1lQnJ1c2hBc0NvbG9yCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRUaGVtZUJydXNoQXNDb2xvcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpzaG9ydCBhcmcwLCBqc2hvcnQgYXJnMSwgamJvb2xlYW4gYXJnMiwgam9iamVjdCBhcmczKQoreworCVJHQkNvbG9yIF9hcmczLCAqbHBhcmczPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldFRoZW1lQnJ1c2hBc0NvbG9yXG4iKQorCisJaWYgKGFyZzMpIGxwYXJnMyA9IGdldFJHQkNvbG9yRmllbGRzKGVudiwgYXJnMywgJl9hcmczKTsKKwlyYyA9IChqaW50KUdldFRoZW1lQnJ1c2hBc0NvbG9yKGFyZzAsIGFyZzEsIGFyZzIsIChSR0JDb2xvciopbHBhcmczKTsKKwlpZiAoYXJnMykgc2V0UkdCQ29sb3JGaWVsZHMoZW52LCBhcmczLCBscGFyZzMpOworCXJldHVybiByYzsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0dldFRoZW1lRHJhd2luZ1N0YXRlCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRUaGVtZURyYXdpbmdTdGF0ZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnRBcnJheSBhcmcwKQoreworCWppbnQgKmxwYXJnMD1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRUaGVtZURyYXdpbmdTdGF0ZVxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcwLCBOVUxMKTsKKwlyYyA9IChqaW50KUdldFRoZW1lRHJhd2luZ1N0YXRlKChUaGVtZURyYXdpbmdTdGF0ZSAqKWxwYXJnMCk7CisJaWYgKGFyZzApICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcwLCBscGFyZzAsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXRUaGVtZURyYXdpbmdTdGF0ZSAqLworCisjaWZuZGVmIE5PX0dldFRoZW1lRm9udAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0VGhlbWVGb250CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwganNob3J0IGFyZzAsIGpzaG9ydCBhcmcxLCBqYnl0ZUFycmF5IGFyZzIsIGpzaG9ydEFycmF5IGFyZzMsIGpieXRlQXJyYXkgYXJnNCkKK3sKKwlqYnl0ZSAqbHBhcmcyPU5VTEw7CisJanNob3J0ICpscGFyZzM9TlVMTDsKKwlqYnl0ZSAqbHBhcmc0PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkdldFRoZW1lRm9udFxuIikKKworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJaWYgKGFyZzMpIGxwYXJnMyA9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJaWYgKGFyZzQpIGxwYXJnNCA9ICgqZW52KS0+R2V0Qnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlyYyA9IChqaW50KUdldFRoZW1lRm9udCgoVGhlbWVGb250SUQpYXJnMCwgKFNjcmlwdENvZGUpYXJnMSwgKGNoYXIgKilscGFyZzIsIChTSW50MTYgKilscGFyZzMsIChTdHlsZSAqKWxwYXJnNCk7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKKwlpZiAoYXJnMykgKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBscGFyZzQsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXRUaGVtZUZvbnQgKi8KKworI2lmbmRlZiBOT19HZXRUaGVtZU1ldHJpYworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0VGhlbWVNZXRyaWMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnRBcnJheSBhcmcxKQoreworCWppbnQgKmxwYXJnMT1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRUaGVtZVRleHREaW1lbnNpb25zXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCXJjID0gKGppbnQpR2V0VGhlbWVNZXRyaWMoKFRoZW1lTWV0cmljKWFyZzAsIChTSW50MzIgKilscGFyZzEpOworCWlmIChhcmcxKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fR2V0VGhlbWVNZXRyaWMgKi8KKworI2lmbmRlZiBOT19HZXRUaGVtZVRleHRDb2xvcgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0VGhlbWVUZXh0Q29sb3IKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqc2hvcnQgYXJnMCwganNob3J0IGFyZzEsIGpib29sZWFuIGFyZzIsIGpvYmplY3QgYXJnMykKK3sKKwlSR0JDb2xvciBfYXJnMywgKmxwYXJnMz1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJHZXRUaGVtZVRleHRDb2xvclxuIikKKworCWlmIChhcmczKSBscGFyZzMgPSBnZXRSR0JDb2xvckZpZWxkcyhlbnYsIGFyZzMsICZfYXJnMyk7CisJcmMgPSAoamludClHZXRUaGVtZVRleHRDb2xvcihhcmcwLCBhcmcxLCBhcmcyLCAoUkdCQ29sb3IgKilscGFyZzMpOworCWlmIChhcmczKSBzZXRSR0JDb2xvckZpZWxkcyhlbnYsIGFyZzMsIGxwYXJnMyk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fR2V0VGhlbWVUZXh0RGltZW5zaW9ucworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0VGhlbWVUZXh0RGltZW5zaW9ucworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGppbnQgYXJnMiwgamJvb2xlYW4gYXJnMywgam9iamVjdCBhcmc0LCBqc2hvcnRBcnJheSBhcmc1KQoreworCVBvaW50IF9hcmc0LCAqbHBhcmc0PU5VTEw7CisJanNob3J0ICpscGFyZzU9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0VGhlbWVUZXh0RGltZW5zaW9uc1xuIikKKworCWlmIChhcmc0KSBscGFyZzQgPSBnZXRQb2ludEZpZWxkcyhlbnYsIGFyZzQsICZfYXJnNCk7CisJaWYgKGFyZzUpIGxwYXJnNSA9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgTlVMTCk7CisJcmMgPSAoamludClHZXRUaGVtZVRleHREaW1lbnNpb25zKChDRlN0cmluZ1JlZilhcmcwLCAoVGhlbWVGb250SUQpYXJnMSwgKFRoZW1lRHJhd1N0YXRlKWFyZzIsIChCb29sZWFuKWFyZzMsIChQb2ludCAqKWxwYXJnNCwgKFNJbnQxNiAqKWxwYXJnNSk7CisJaWYgKGFyZzQpIHNldFBvaW50RmllbGRzKGVudiwgYXJnNCwgbHBhcmc0KTsKKwlpZiAoYXJnNSkgKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19HZXRVc2VyRm9jdXNFdmVudFRhcmdldAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0VXNlckZvY3VzRXZlbnRUYXJnZXQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0KQoreworCURFQlVHX0NBTEwoIkdldFVzZXJGb2N1c0V2ZW50VGFyZ2V0XG4iKQorCisJcmV0dXJuIChqaW50KUdldFVzZXJGb2N1c0V2ZW50VGFyZ2V0KCk7Cit9CisjZW5kaWYgLyogTk9fR2V0VXNlckZvY3VzRXZlbnRUYXJnZXQgKi8KKworI2lmbmRlZiBOT19HZXRXUmVmQ29uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRXUmVmQ29uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkdldFdSZWZDb25cbiIpCisKKwlyZXR1cm4gKGppbnQpR2V0V1JlZkNvbigoV2luZG93UmVmKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldFdSZWZDb24gKi8KKworI2lmbmRlZiBOT19HZXRXaW5kb3dCb3VuZHMKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFdpbmRvd0JvdW5kcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGpvYmplY3QgYXJnMikKK3sKKwlSZWN0IF9hcmcyLCAqbHBhcmcyPU5VTEw7CisKKwlERUJVR19DQUxMKCJHZXRXaW5kb3dCb3VuZHNcbiIpCisKKwlpZiAoYXJnMikgbHBhcmcyID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzIsICZfYXJnMik7CisJR2V0V2luZG93Qm91bmRzKChXaW5kb3dSZWYpYXJnMCwgKFdpbmRvd1JlZ2lvbkNvZGUpYXJnMSwgKFJlY3QgKilscGFyZzIpOworCWlmIChhcmcyKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMiwgbHBhcmcyKTsKK30KKyNlbmRpZiAvKiBOT19HZXRXaW5kb3dCb3VuZHMgKi8KKworI2lmbmRlZiBOT19HZXRXaW5kb3dEZWZhdWx0QnV0dG9uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRXaW5kb3dEZWZhdWx0QnV0dG9uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50QXJyYXkgYXJnMSkKK3sKKwlqaW50ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0V2luZG93RGVmYXVsdEJ1dHRvblxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBOVUxMKTsKKwlyYyA9IChqaW50KUdldFdpbmRvd0RlZmF1bHRCdXR0b24oKFdpbmRvd1JlZilhcmcwLCAoQ29udHJvbFJlZiAqKWxwYXJnMSk7CisJaWYgKGFyZzEpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19HZXRXaW5kb3dEZWZhdWx0QnV0dG9uICovCisKKyNpZm5kZWYgTk9fR2V0V2luZG93RXZlbnRUYXJnZXQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFdpbmRvd0V2ZW50VGFyZ2V0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkdldFdpbmRvd0V2ZW50VGFyZ2V0XG4iKQorCisJcmV0dXJuIChqaW50KUdldFdpbmRvd0V2ZW50VGFyZ2V0KChXaW5kb3dSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fR2V0V2luZG93RXZlbnRUYXJnZXQgKi8KKworI2lmbmRlZiBOT19HZXRXaW5kb3dGcm9tUG9ydAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0V2luZG93RnJvbVBvcnQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiR2V0V2luZG93RnJvbVBvcnRcbiIpCisKKwlyZXR1cm4gKGppbnQpR2V0V2luZG93RnJvbVBvcnQoKENHcmFmUHRyKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0dldFdpbmRvd0Zyb21Qb3J0ICovCisKKyNpZm5kZWYgTk9fR2V0V2luZG93R3JvdXBPZkNsYXNzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRXaW5kb3dHcm91cE9mQ2xhc3MKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiR2V0V2luZG93R3JvdXBPZkNsYXNzXG4iKQorCisJcmV0dXJuIChqaW50KUdldFdpbmRvd0dyb3VwT2ZDbGFzcygoV2luZG93Q2xhc3MpYXJnMCk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19HZXRXaW5kb3dNb2RhbGl0eQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0V2luZG93TW9kYWxpdHkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnRBcnJheSBhcmcxLCBqaW50QXJyYXkgYXJnMikKK3sKKwlqaW50ICpscGFyZzE9TlVMTDsKKwlqaW50ICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiR2V0V2luZG93TW9kYWxpdHlcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpR2V0V2luZG93TW9kYWxpdHkoKFdpbmRvd1JlZilhcmcwLCAoV2luZG93TW9kYWxpdHkgKilscGFyZzEsIChXaW5kb3dSZWYgKilscGFyZzIpOworCWlmIChhcmcxKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0dldFdpbmRvd01vZGFsaXR5ICovCisKKyNpZm5kZWYgTk9fR2V0V2luZG93UG9ydAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0V2luZG93UG9ydAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJHZXRXaW5kb3dQb3J0XG4iKQorCisJcmV0dXJuIChqaW50KUdldFdpbmRvd1BvcnQoKFdpbmRvd1JlZilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19HZXRXaW5kb3dQb3J0ICovCisKKyNpZm5kZWYgTk9fR2V0V2luZG93U3RydWN0dXJlV2lkdGhzCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRXaW5kb3dTdHJ1Y3R1cmVXaWR0aHMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisKKwlERUJVR19DQUxMKCJHZXRXaW5kb3dTdHJ1Y3R1cmVXaWR0aHNcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJR2V0V2luZG93U3RydWN0dXJlV2lkdGhzKChXaW5kb3dSZWYpYXJnMCwgKFJlY3QgKilscGFyZzEpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19HZXRXaW5kb3dTdHJ1Y3R1cmVXaWR0aHMgKi8KKworI2lmbmRlZiBOT19IYW5kbGVDb250cm9sU2V0Q3Vyc29yCitKTklFWFBPUlQgamludCBKTklDQUxMIE9TX05BVElWRShIYW5kbGVDb250cm9sU2V0Q3Vyc29yKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxLCBqaW50IGFyZzIsIGpib29sZWFuQXJyYXkgYXJnMykKK3sKKwlQb2ludCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCWpib29sZWFuICpscGFyZzM9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiSGFuZGxlQ29udHJvbFNldEN1cnNvclxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRQb2ludEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJaWYgKGFyZzMpIGxwYXJnMyA9ICgqZW52KS0+R2V0Qm9vbGVhbkFycmF5RWxlbWVudHMoZW52LCBhcmczLCBOVUxMKTsKKwlyYyA9IChqaW50KUhhbmRsZUNvbnRyb2xTZXRDdXJzb3IoKENvbnRyb2xSZWYpYXJnMCwgKihQb2ludCAqKWxwYXJnMSwgKEV2ZW50TW9kaWZpZXJzKWFyZzIsIChCb29sZWFuICopbHBhcmczKTsKKwlpZiAoYXJnMSkgc2V0UG9pbnRGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VCb29sZWFuQXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fSElDb21ib0JveEFwcGVuZFRleHRJdGVtCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISUNvbWJvQm94QXBwZW5kVGV4dEl0ZW0KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJamludCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkhJQ29tYm9Cb3hBcHBlbmRUZXh0SXRlbVxuIikKKworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlyYyA9IChqaW50KUhJQ29tYm9Cb3hBcHBlbmRUZXh0SXRlbSgoSElWaWV3UmVmKWFyZzAsIChDRlN0cmluZ1JlZilhcmcxLCAoQ0ZJbmRleCAqKWxwYXJnMik7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19ISUNvbWJvQm94QXBwZW5kVGV4dEl0ZW0gKi8KKworI2lmbmRlZiBOT19ISUNvbWJvQm94Q29weVRleHRJdGVtQXRJbmRleAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElDb21ib0JveENvcHlUZXh0SXRlbUF0SW5kZXgKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJamludCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkhJQ29tYm9Cb3hDb3B5VGV4dEl0ZW1BdEluZGV4XG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpSElDb21ib0JveENvcHlUZXh0SXRlbUF0SW5kZXgoKEhJVmlld1JlZilhcmcwLCAoQ0ZJbmRleClhcmcxLCAoQ0ZTdHJpbmdSZWYgKilscGFyZzIpOworCWlmIChhcmcyKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fSElDb21ib0JveENvcHlUZXh0SXRlbUF0SW5kZXggKi8KKworI2lmbmRlZiBOT19ISUNvbWJvQm94Q3JlYXRlCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISUNvbWJvQm94Q3JlYXRlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwLCBqaW50IGFyZzEsIGpvYmplY3QgYXJnMiwgamludCBhcmczLCBqaW50IGFyZzQsIGppbnRBcnJheSBhcmc1KQoreworCUNHUmVjdCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCUNvbnRyb2xGb250U3R5bGVSZWMgX2FyZzIsICpscGFyZzI9TlVMTDsKKwlqaW50ICpscGFyZzU9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiSElDb21ib0JveENyZWF0ZVxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRDR1JlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCWlmIChhcmcyKSBscGFyZzIgPSBnZXRDb250cm9sRm9udFN0eWxlUmVjRmllbGRzKGVudiwgYXJnMiwgJl9hcmcyKTsKKwlpZiAoYXJnNSkgbHBhcmc1ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgTlVMTCk7CisJcmMgPSAoamludClISUNvbWJvQm94Q3JlYXRlKChjb25zdCBISVJlY3QgKilscGFyZzAsIChDRlN0cmluZ1JlZilhcmcxLCAoY29uc3QgQ29udHJvbEZvbnRTdHlsZVJlYyAqKWxwYXJnMiwgKENGQXJyYXlSZWYpYXJnMywgKE9wdGlvbkJpdHMpYXJnNCwgKEhJVmlld1JlZiAqKWxwYXJnNSk7CisJaWYgKGFyZzApIHNldENHUmVjdEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7CisJaWYgKGFyZzIpIHNldENvbnRyb2xGb250U3R5bGVSZWNGaWVsZHMoZW52LCBhcmcyLCBscGFyZzIpOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fSElDb21ib0JveENyZWF0ZSAqLworCisjaWZuZGVmIE5PX0hJQ29tYm9Cb3hHZXRJdGVtQ291bnQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJQ29tYm9Cb3hHZXRJdGVtQ291bnQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiSElDb21ib0JveEdldEl0ZW1Db3VudFxuIikKKworCXJldHVybiAoamludClISUNvbWJvQm94R2V0SXRlbUNvdW50KChISVZpZXdSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fSElDb21ib0JveEdldEl0ZW1Db3VudCAqLworCisjaWZuZGVmIE5PX0hJQ29tYm9Cb3hJbnNlcnRUZXh0SXRlbUF0SW5kZXgKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJQ29tYm9Cb3hJbnNlcnRUZXh0SXRlbUF0SW5kZXgKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyKQoreworCURFQlVHX0NBTEwoIkhJQ29tYm9Cb3hJbnNlcnRUZXh0SXRlbUF0SW5kZXhcbiIpCisKKwlyZXR1cm4gKGppbnQpSElDb21ib0JveEluc2VydFRleHRJdGVtQXRJbmRleCgoSElWaWV3UmVmKWFyZzAsIChDRkluZGV4KWFyZzEsIChDRlN0cmluZ1JlZilhcmcyKTsKK30KKyNlbmRpZiAvKiBOT19ISUNvbWJvQm94SW5zZXJ0VGV4dEl0ZW1BdEluZGV4ICovCisKKyNpZm5kZWYgTk9fSElDb21ib0JveFJlbW92ZUl0ZW1BdEluZGV4CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISUNvbWJvQm94UmVtb3ZlSXRlbUF0SW5kZXgKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJISUNvbWJvQm94UmVtb3ZlSXRlbUF0SW5kZXhcbiIpCisKKwlyZXR1cm4gKGppbnQpSElDb21ib0JveFJlbW92ZUl0ZW1BdEluZGV4KChISVZpZXdSZWYpYXJnMCwgKENGSW5kZXgpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fSElDb21ib0JveFJlbW92ZUl0ZW1BdEluZGV4ICovCisKKyNpZm5kZWYgTk9fSElPYmplY3RDb3B5Q2xhc3NJRAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElPYmplY3RDb3B5Q2xhc3NJRAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJISU9iamVjdENvcHlDbGFzc0lEXG4iKQorCisJcmV0dXJuIChqaW50KUhJT2JqZWN0Q29weUNsYXNzSUQoKEhJT2JqZWN0UmVmKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0hJT2JqZWN0Q29weUNsYXNzSUQgKi8KKworI2lmbmRlZiBOT19ISU9iamVjdENyZWF0ZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElPYmplY3RDcmVhdGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJamludCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkhJT2JqZWN0Q3JlYXRlXG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpSElPYmplY3RDcmVhdGUoKENGU3RyaW5nUmVmKWFyZzAsIChFdmVudFJlZilhcmcxLCAoSElPYmplY3RSZWYgKilscGFyZzIpOworCWlmIChhcmcyKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fSElPYmplY3RDcmVhdGUgKi8KKworI2lmbmRlZiBOT19ISU9iamVjdFJlZ2lzdGVyU3ViY2xhc3MKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJT2JqZWN0UmVnaXN0ZXJTdWJjbGFzcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMywgamludCBhcmc0LCBqaW50QXJyYXkgYXJnNSwgamludCBhcmc2LCBqaW50QXJyYXkgYXJnNykKK3sKKwlqaW50ICpscGFyZzU9TlVMTDsKKwlqaW50ICpscGFyZzc9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiSElPYmplY3RSZWdpc3RlclN1YmNsYXNzXG4iKQorCisJaWYgKGFyZzUpIGxwYXJnNSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIE5VTEwpOworCWlmIChhcmc3KSBscGFyZzcgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc3LCBOVUxMKTsKKwlyYyA9IChqaW50KUhJT2JqZWN0UmVnaXN0ZXJTdWJjbGFzcygoQ0ZTdHJpbmdSZWYpYXJnMCwgKENGU3RyaW5nUmVmKWFyZzEsIChPcHRpb25CaXRzKWFyZzIsIChFdmVudEhhbmRsZXJVUFApYXJnMywgKFVJbnQzMilhcmc0LCAoY29uc3QgRXZlbnRUeXBlU3BlYyAqKWxwYXJnNSwgKHZvaWQgKilhcmc2LCAoSElPYmplY3RDbGFzc1JlZiAqKWxwYXJnNyk7CisJaWYgKGFyZzUpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBscGFyZzUsIDApOworCWlmIChhcmc3KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNywgbHBhcmc3LCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fSElPYmplY3RSZWdpc3RlclN1YmNsYXNzICovCisKKyNpZm5kZWYgTk9fSElWaWV3QWRkU3VidmlldworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3QWRkU3VidmlldworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIkhJVmlld0FkZFN1YnZpZXdcbiIpCisKKwlyZXR1cm4gKGppbnQpSElWaWV3QWRkU3VidmlldygoSElWaWV3UmVmKWFyZzAsIChISVZpZXdSZWYpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fSElWaWV3QWRkU3VidmlldyAqLworCisjaWZuZGVmIE5PX0hJVmlld0NsaWNrCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdDbGljaworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIkhJVmlld0NsaWNrXG4iKQorCisJcmV0dXJuIChqaW50KUhJVmlld0NsaWNrKChISVZpZXdSZWYpYXJnMCwgKEV2ZW50UmVmKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX0hJVmlld0NsaWNrICovCisKKyNpZm5kZWYgTk9fSElWaWV3Q29udmVydFBvaW50CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdDb252ZXJ0UG9pbnQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyKQoreworCUNHUG9pbnQgX2FyZzAsICpscGFyZzA9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiSElWaWV3Q29udmVydFBvaW50XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldENHUG9pbnRGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCXJjID0gKGppbnQpSElWaWV3Q29udmVydFBvaW50KChISVBvaW50ICopbHBhcmcwLCAoSElWaWV3UmVmKWFyZzEsIChISVZpZXdSZWYpYXJnMik7CisJaWYgKGFyZzApIHNldENHUG9pbnRGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19ISVZpZXdDb252ZXJ0UG9pbnQgKi8KKworI2lmbmRlZiBOT19ISVZpZXdGaW5kQnlJRAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3RmluZEJ5SUQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJamludCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkhJVmlld0ZpbmRCeUlEXG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpSElWaWV3RmluZEJ5SUQoKEhJVmlld1JlZilhcmcwLCAqKEhJVmlld0lEICopYXJnMSwgKEhJVmlld1JlZiAqKWxwYXJnMik7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19ISVZpZXdGaW5kQnlJRCAqLworCisjaWZuZGVmIE5PX0hJVmlld0dldEZpcnN0U3VidmlldworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3R2V0Rmlyc3RTdWJ2aWV3CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkhJVmlld0dldEZpcnN0U3Vidmlld1xuIikKKworCXJldHVybiAoamludClISVZpZXdHZXRGaXJzdFN1YnZpZXcoKEhJVmlld1JlZilhcmcwKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0hJVmlld0dldEZyYW1lCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdHZXRGcmFtZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxKQoreworCUNHUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJISVZpZXdHZXRGcmFtZVxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRDR1JlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCXJjID0gKGppbnQpSElWaWV3R2V0RnJhbWUoKEhJVmlld1JlZilhcmcwLCAoSElSZWN0ICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgc2V0Q0dSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fSElWaWV3R2V0RnJhbWUgKi8KKworI2lmbmRlZiBOT19ISVZpZXdHZXRMYXN0U3VidmlldworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3R2V0TGFzdFN1YnZpZXcKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiSElWaWV3R2V0TGFzdFN1YnZpZXdcbiIpCisKKwlyZXR1cm4gKGppbnQpSElWaWV3R2V0TGFzdFN1YnZpZXcoKEhJVmlld1JlZilhcmcwKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0hJVmlld0dldE5leHRWaWV3CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdHZXROZXh0VmlldworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJISVZpZXdHZXROZXh0Vmlld1xuIikKKworCXJldHVybiAoamludClISVZpZXdHZXROZXh0VmlldygoSElWaWV3UmVmKWFyZzApOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fSElWaWV3R2V0Um9vdAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3R2V0Um9vdAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJISVZpZXdHZXRSb290XG4iKQorCisJcmV0dXJuIChqaW50KUhJVmlld0dldFJvb3QoKFdpbmRvd1JlZilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19ISVZpZXdHZXRSb290ICovCisKKyNpZm5kZWYgTk9fSElWaWV3R2V0U2l6ZUNvbnN0cmFpbnRzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdHZXRTaXplQ29uc3RyYWludHMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgam9iamVjdCBhcmcyKQoreworCUNHUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCUNHUmVjdCBfYXJnMiwgKmxwYXJnMj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJISVZpZXdHZXRTaXplQ29uc3RyYWludHNcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0Q0dSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlpZiAoYXJnMikgbHBhcmcyID0gZ2V0Q0dSZWN0RmllbGRzKGVudiwgYXJnMiwgJl9hcmcyKTsKKwlyYyA9IChqaW50KUhJVmlld0dldFNpemVDb25zdHJhaW50cygoSElWaWV3UmVmKWFyZzAsIChISVNpemUgKilscGFyZzEsIChISVNpemUgKilscGFyZzIpOworCWlmIChhcmcxKSBzZXRDR1JlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmcyKSBzZXRDR1JlY3RGaWVsZHMoZW52LCBhcmcyLCBscGFyZzIpOworCXJldHVybiByYzsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0hJVmlld0dldFN1YnZpZXdIaXQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJVmlld0dldFN1YnZpZXdIaXQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamJvb2xlYW4gYXJnMiwgamludEFycmF5IGFyZzMpCit7CisJQ0dQb2ludCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCWppbnQgKmxwYXJnMz1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJISVZpZXdHZXRTdWJ2aWV3SGl0XG4iKQogCQotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgKGpzaG9ydCopIHIsIDApOworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRDR1BvaW50RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJcmMgPSAoamludClISVZpZXdHZXRTdWJ2aWV3SGl0KChISVZpZXdSZWYpYXJnMCwgKENHUG9pbnQgKilscGFyZzEsIChCb29sZWFuKWFyZzIsIChISVZpZXdSZWYgKilscGFyZzMpOworCWlmIChhcmcxKSBzZXRDR1BvaW50RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlpZiAoYXJnMykgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0hJVmlld0dldFN1YnZpZXdIaXQgKi8KKworI2lmbmRlZiBOT19ISVZpZXdHZXRWaWV3Rm9yTW91c2VFdmVudAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3R2V0Vmlld0Zvck1vdXNlRXZlbnQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJamludCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkhJVmlld0dldFZpZXdGb3JNb3VzZUV2ZW50XG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpSElWaWV3R2V0Vmlld0Zvck1vdXNlRXZlbnQoKEhJVmlld1JlZilhcmcwLCAoRXZlbnRSZWYpYXJnMSwgKEhJVmlld1JlZiAqKWxwYXJnMik7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19ISVZpZXdHZXRWaWV3Rm9yTW91c2VFdmVudCAqLworCisjaWZuZGVmIE5PX0hJVmlld0lzVmlzaWJsZQorSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJVmlld0lzVmlzaWJsZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJISVZpZXdJc1Zpc2libGVcbiIpCisKKwlyZXR1cm4gKGpib29sZWFuKSBISVZpZXdJc1Zpc2libGUoKEhJVmlld1JlZilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19ISVZpZXdJc1Zpc2libGUgKi8KKworI2lmbmRlZiBOT19ISVZpZXdSZW1vdmVGcm9tU3VwZXJ2aWV3CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdSZW1vdmVGcm9tU3VwZXJ2aWV3CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkhJVmlld1JlbW92ZUZyb21TdXBlcnZpZXdcbiIpCisKKwlyZXR1cm4gKGppbnQpSElWaWV3UmVtb3ZlRnJvbVN1cGVydmlldygoSElWaWV3UmVmKWFyZzApOworfQorI2VuZGlmIC8qIE5PX0hJVmlld1JlbW92ZUZyb21TdXBlcnZpZXcgKi8KKworI2lmbmRlZiBOT19ISVZpZXdTZXRCb3VuZHNPcmlnaW4KK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgT1NfTkFUSVZFKEhJVmlld1NldEJvdW5kc09yaWdpbikKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpmbG9hdCBhcmcxLCBqZmxvYXQgYXJnMikKK3sKKwlERUJVR19DQUxMKCJISVZpZXdTZXRCb3VuZHNPcmlnaW5cbiIpCisKKwlyZXR1cm4gKGppbnQpSElWaWV3U2V0Qm91bmRzT3JpZ2luKChISVZpZXdSZWYpYXJnMCwgKGZsb2F0KWFyZzEsIChmbG9hdClhcmcyKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX0hJVmlld1NldERyYXdpbmdFbmFibGVkCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdTZXREcmF3aW5nRW5hYmxlZAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamJvb2xlYW4gYXJnMSkKK3sKKwlERUJVR19DQUxMKCJISVZpZXdTZXREcmF3aW5nRW5hYmxlZFxuIikKKworCXJldHVybiAoamludClISVZpZXdTZXREcmF3aW5nRW5hYmxlZCgoSElWaWV3UmVmKWFyZzAsIChCb29sZWFuKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX0hJVmlld1NldERyYXdpbmdFbmFibGVkICovCisKKyNpZm5kZWYgTk9fSElWaWV3U2V0RnJhbWUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJVmlld1NldEZyYW1lCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEpCit7CisJQ0dSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkhJVmlld1NldEZyYW1lXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldENHUmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJcmMgPSAoamludClISVZpZXdTZXRGcmFtZSgoSElWaWV3UmVmKWFyZzAsIChjb25zdCBISVJlY3QgKilscGFyZzEpOworCWlmIChhcmcxKSBzZXRDR1JlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19ISVZpZXdTZXRGcmFtZSAqLworCisjaWZuZGVmIE5PX0hJVmlld1NldE5lZWRzRGlzcGxheQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3U2V0TmVlZHNEaXNwbGF5CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqYm9vbGVhbiBhcmcxKQoreworCURFQlVHX0NBTEwoIkhJVmlld1NldE5lZWRzRGlzcGxheVxuIikKKworCXJldHVybiAoamludClISVZpZXdTZXROZWVkc0Rpc3BsYXkoKEhJVmlld1JlZilhcmcwLCAoQm9vbGVhbilhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19ISVZpZXdTZXROZWVkc0Rpc3BsYXkgKi8KKworI2lmbmRlZiBOT19ISVZpZXdTZXROZWVkc0Rpc3BsYXlJblJlZ2lvbgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3U2V0TmVlZHNEaXNwbGF5SW5SZWdpb24KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamJvb2xlYW4gYXJnMikKK3sKKwlERUJVR19DQUxMKCJISVZpZXdTZXROZWVkc0Rpc3BsYXlJblJlZ2lvblxuIikKKworCXJldHVybiAoamludClISVZpZXdTZXROZWVkc0Rpc3BsYXlJblJlZ2lvbigoSElWaWV3UmVmKWFyZzAsIChSZ25IYW5kbGUpYXJnMSwgKEJvb2xlYW4pYXJnMik7Cit9CisjZW5kaWYgLyogTk9fSElWaWV3U2V0TmVlZHNEaXNwbGF5SW5SZWdpb24gKi8KKworI2lmbmRlZiBOT19ISVZpZXdTZXRWaXNpYmxlCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdTZXRWaXNpYmxlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqYm9vbGVhbiBhcmcxKQoreworCURFQlVHX0NBTEwoIkhJVmlld1NldFZpc2libGVcbiIpCisKKwlyZXR1cm4gKGppbnQpSElWaWV3U2V0VmlzaWJsZSgoSElWaWV3UmVmKWFyZzAsIChCb29sZWFuKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX0hJVmlld1NldFZpc2libGUgKi8KKworI2lmbmRlZiBOT19ISVZpZXdTZXRaT3JkZXIKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJVmlld1NldFpPcmRlcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIpCit7CisJREVCVUdfQ0FMTCgiSElWaWV3U2V0Wk9yZGVyXG4iKQorCisJcmV0dXJuIChqaW50KUhJVmlld1NldFpPcmRlcigoSElWaWV3UmVmKWFyZzAsIChISVZpZXdaT3JkZXJPcClhcmcxLCAoSElWaWV3UmVmKWFyZzIpOworfQorI2VuZGlmIC8qIE5PX0hJVmlld1NldFpPcmRlciAqLworCisjaWZuZGVmIE5PX0hJVmlld1NpbXVsYXRlQ2xpY2sKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJVmlld1NpbXVsYXRlQ2xpY2sKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxLCBqaW50IGFyZzIsIGpzaG9ydEFycmF5IGFyZzMpCit7CisJanNob3J0ICpscGFyZzM9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiSElWaWV3U2ltdWxhdGVDbGlja1xuIikKKworCWlmIChhcmczKSBscGFyZzMgPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIE5VTEwpOworCXJjID0gKGppbnQpSElWaWV3U2ltdWxhdGVDbGljaygoSElWaWV3UmVmKWFyZzAsIChISVZpZXdQYXJ0Q29kZSlhcmcxLCAoVUludDMyKWFyZzIsIChDb250cm9sUGFydENvZGUgKilscGFyZzMpOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBscGFyZzMsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19ISVZpZXdTaW11bGF0ZUNsaWNrICovCisKKyNpZm5kZWYgTk9fSGFuZGxlQ29udHJvbENsaWNrCitKTklFWFBPUlQganNob3J0IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hhbmRsZUNvbnRyb2xDbGljaworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMykKK3sKKwlQb2ludCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCWpzaG9ydCByYzsKKworCURFQlVHX0NBTEwoIkhhbmRsZUNvbnRyb2xDbGlja1xuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRQb2ludEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJcmMgPSAoanNob3J0KUhhbmRsZUNvbnRyb2xDbGljaygoQ29udHJvbFJlZilhcmcwLCAoUG9pbnQpKmxwYXJnMSwgKEV2ZW50TW9kaWZpZXJzKWFyZzIsIChDb250cm9sQWN0aW9uVVBQKWFyZzMpOworCWlmIChhcmcxKSBzZXRQb2ludEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX0hhbmRsZUNvbnRyb2xDbGljayAqLworCisjaWZuZGVmIE5PX0hpV29yZAorSk5JRVhQT1JUIGpzaG9ydCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19IaVdvcmQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiSGlXb3JkXG4iKQorCisJcmV0dXJuIChqc2hvcnQpSGlXb3JkKGFyZzApOworfQorI2VuZGlmIC8qIE5PX0hpV29yZCAqLworCisjaWZuZGVmIE5PX0hpZGVXaW5kb3cKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hpZGVXaW5kb3cKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiSGlkZVdpbmRvd1xuIikKKworCUhpZGVXaW5kb3coKFdpbmRvd1JlZilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19IaWRlV2luZG93ICovCisKKyNpZm5kZWYgTk9fSGlsaXRlTWVudQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSGlsaXRlTWVudQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpzaG9ydCBhcmcwKQoreworCURFQlVHX0NBTEwoIkhpbGl0ZU1lbnVcbiIpCisKKwlIaWxpdGVNZW51KChNZW51SUQpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fSGlsaXRlTWVudSAqLworCisjaWZuZGVmIE5PX0hMb2NrCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ITG9jaworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJITG9ja1xuIikKKworCUhMb2NrKChIYW5kbGUpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fSExvY2sgKi8KKworI2lmbmRlZiBOT19ITUdldFRhZ0RlbGF5CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ITUdldFRhZ0RlbGF5CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludEFycmF5IGFyZzApCit7CisJamludCAqbHBhcmcwPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkhNR2V0VGFnRGVsYXlcbiIpCiAJCi0JcmV0dXJuIHN0YXR1czsKKwlpZiAoYXJnMCkgbHBhcmcwID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMCwgTlVMTCk7CisJcmMgPSAoamludClITUdldFRhZ0RlbGF5KChEdXJhdGlvbiAqKWxwYXJnMCk7CisJaWYgKGFyZzApICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcwLCBscGFyZzAsIDApOworCXJldHVybiByYzsKIH0KLSovCisjZW5kaWYgLyogTk9fSE1HZXRUYWdEZWxheSAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OZXdDb250cm9sKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IHdIYW5kbGUsIGpib29sZWFuIHZpc2libGUsIGpzaG9ydCBpbml0aWFsVmFsdWUsIGpzaG9ydCBtaW5WYWx1ZSwganNob3J0IG1heFZhbHVlLCBqc2hvcnQgcHJvY0lEKSB7Ci0JcmV0dXJuIChqaW50KSBOZXdDb250cm9sKChXaW5kb3dSZWYpIHdIYW5kbGUsICZOVUxMX1JFQ1QsICIiLCB2aXNpYmxlLCBpbml0aWFsVmFsdWUsIG1pblZhbHVlLCBtYXhWYWx1ZSwgcHJvY0lELCAwKTsKLX0KKyNpZm5kZWYgTk9fSE1IaWRlVGFnCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ITUhpZGVUYWcKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50QXJyYXkgYXJnMCkKK3sKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGlzcG9zZUNvbnRyb2woSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBjSGFuZGxlKSB7Ci0JRGlzcG9zZUNvbnRyb2woKENvbnRyb2xSZWYpIGNIYW5kbGUpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DcmVhdGVVc2VyUGFuZUNvbnRyb2woSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgd0hhbmRsZSwganNob3J0QXJyYXkgYm91bmRzLCBqaW50IGZlYXR1cmVzLCBqaW50QXJyYXkgY0hhbmRsZSkgewotCWpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCAwKTsKLQlqaW50ICpzYj0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgY0hhbmRsZSwgMCk7Ci0JamludCBzdGF0dXM9IChqaW50KSBSQyhDcmVhdGVVc2VyUGFuZUNvbnRyb2woKFdpbmRvd1JlZikgd0hhbmRsZSwgKGNvbnN0IFJlY3QqKSBzYSwgZmVhdHVyZXMsIChDb250cm9sUmVmKikgc2IpKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIHNhLCAwKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgY0hhbmRsZSwgc2IsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFJvb3RDb250cm9sKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSwgamludEFycmF5IGNIYW5kbGUpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgY0hhbmRsZSwgMCk7Ci0JamludCBzdGF0dXM9IChqaW50KSBSQyhHZXRSb290Q29udHJvbCgoV2luZG93UmVmKSB3SGFuZGxlLCAoQ29udHJvbFJlZiopc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgY0hhbmRsZSwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NyZWF0ZVJvb3RDb250cm9sKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgd0hhbmRsZSwgamludEFycmF5IGNIYW5kbGUpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgY0hhbmRsZSwgMCk7Ci0JamludCBzdGF0dXM9IChqaW50KSBSQyhDcmVhdGVSb290Q29udHJvbCgoV2luZG93UmVmKSB3SGFuZGxlLCAoQ29udHJvbFJlZiopc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgY0hhbmRsZSwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0VtYmVkQ29udHJvbChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUsIGppbnQgcGFyZW50SGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBSQyhFbWJlZENvbnRyb2woKENvbnRyb2xSZWYpIGNIYW5kbGUsIChDb250cm9sUmVmKSBwYXJlbnRIYW5kbGUpKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q29udHJvbE93bmVyKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSkgewotCXJldHVybiAoamludCkgR2V0Q29udHJvbE93bmVyKChDb250cm9sUmVmKSBjSGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRmluZENvbnRyb2xVbmRlck1vdXNlKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzaG9ydEFycmF5IHdoZXJlLAotCQkJCQkJCQkJCQkJCSBqaW50IHdIYW5kbGUsIGpzaG9ydEFycmF5IGNIYW5kbGUpIHsKLQlqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGNIYW5kbGUsIDApOwotCUNvbnRyb2xSZWYgYz0gRmluZENvbnRyb2xVbmRlck1vdXNlKHBvaW50KGVudiwgd2hlcmUpLCAoV2luZG93UmVmKSB3SGFuZGxlLCBzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgY0hhbmRsZSwgc2EsIDApOwotCXJldHVybiAoamludCkgYzsKLX0KLQotSk5JRVhQT1JUIGpzaG9ydCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UZXN0Q29udHJvbChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwganNob3J0QXJyYXkgd2hlcmUpIHsKLQlyZXR1cm4gKGpzaG9ydCkgVGVzdENvbnRyb2woKENvbnRyb2xSZWYpY0hhbmRsZSwgcG9pbnQoZW52LCB3aGVyZSkpOwotfQotCi1KTklFWFBPUlQganNob3J0IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hhbmRsZUNvbnRyb2xDbGljayhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUsCi0JCQkJCQkJCQkJCQkJanNob3J0QXJyYXkgd2hlcmUsIGppbnQgbW9kaWZpZXJzLCBqaW50IGFjdGlvbikgewotCXJldHVybiBIYW5kbGVDb250cm9sQ2xpY2soKENvbnRyb2xSZWYpY0hhbmRsZSwgcG9pbnQoZW52LCB3aGVyZSksIG1vZGlmaWVycywgKENvbnRyb2xBY3Rpb25VUFApIGFjdGlvbik7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX01vdmVDb250cm9sKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSwganNob3J0IHgsIGpzaG9ydCB5KSB7Ci0JTW92ZUNvbnRyb2woKENvbnRyb2xSZWYpIGNIYW5kbGUsIHgsIHkpOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TaXplQ29udHJvbChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUsIGpzaG9ydCB3LCBqc2hvcnQgaCkgewotCVNpemVDb250cm9sKChDb250cm9sUmVmKSBjSGFuZGxlLCB3LCBoKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2hvd0NvbnRyb2woSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBjSGFuZGxlKSB7Ci0JU2hvd0NvbnRyb2woKENvbnRyb2xSZWYpIGNIYW5kbGUpOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19IaWRlQ29udHJvbChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUpIHsKLQlIaWRlQ29udHJvbCgoQ29udHJvbFJlZikgY0hhbmRsZSk7Ci19Ci0KLUpOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Jc0NvbnRyb2xWaXNpYmxlKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSkgewotCXJldHVybiAoamJvb2xlYW4pIElzQ29udHJvbFZpc2libGUoKENvbnRyb2xSZWYpIGNIYW5kbGUpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sVmlzaWJpbGl0eShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUsCi0gICAgICAgICAgICAgICAgamJvb2xlYW4gaXNWaXNpYmxlLCBqYm9vbGVhbiBkb0RyYXcpIHsKLQlyZXR1cm4gKGppbnQpIFJDKFNldENvbnRyb2xWaXNpYmlsaXR5KChDb250cm9sUmVmKWNIYW5kbGUsIGlzVmlzaWJsZSwgZG9EcmF3KSk7Ci19Ci0KLUpOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Jc0NvbnRyb2xBY3RpdmUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBjSGFuZGxlKSB7Ci0JcmV0dXJuIChqYm9vbGVhbikgSXNDb250cm9sQWN0aXZlKChDb250cm9sUmVmKSBjSGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0Q29udHJvbEJvdW5kcyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUsIGpzaG9ydEFycmF5IGJvdW5kcykgewotICAgICAgICBqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgMCk7Ci0JUmVjdCAqcj0gKFJlY3QqKSBzYTsKLQlpZiAoci0+Ym90dG9tIC0gci0+dG9wIDwgMCB8fCByLT5yaWdodCAtIHItPmxlZnQgPCAwKSB7Ci0JCS8vZnByaW50ZihzdGRvdXQsICItKi0qLSotKi0qXyotKl8qIFNldENvbnRyb2xCb3VuZHM6ICVkICVkICVkICVkXG4iLCByLT5sZWZ0LCByLT50b3AsIHItPnJpZ2h0LXItPmxlZnQsIHItPmJvdHRvbS1yLT50b3ApOwotCX0gZWxzZQotCQlTZXRDb250cm9sQm91bmRzKChDb250cm9sUmVmKWNIYW5kbGUsIHIpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgc2EsIDApOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDb250cm9sQm91bmRzKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSwganNob3J0QXJyYXkgYm91bmRzKSB7Ci0JanNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBib3VuZHMsIDApOwotCUdldENvbnRyb2xCb3VuZHMoKENvbnRyb2xSZWYpY0hhbmRsZSwgKFJlY3QqKSBzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCBzYSwgMCk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2xSZWdpb24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IGNIYW5kbGUsIGpzaG9ydCBwYXJ0LCBqaW50IHJlZ2lvbikgewotCXJldHVybiAoamludCkgUkMoR2V0Q29udHJvbFJlZ2lvbigoQ29udHJvbFJlZiljSGFuZGxlLCAoQ29udHJvbFBhcnRDb2RlKSBwYXJ0LCAoUmduSGFuZGxlKSByZWdpb24pKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ291bnRTdWJDb250cm9scyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUsIGpzaG9ydEFycmF5IGNvdW50KSB7Ci0JanNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBjb3VudCwgMCk7Ci0JamludCBzdGF0dXM9IChqaW50KSBSQyhDb3VudFN1YkNvbnRyb2xzKChDb250cm9sUmVmKWNIYW5kbGUsIHNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgY291bnQsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRJbmRleGVkU3ViQ29udHJvbChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwganNob3J0IGluZGV4LCBqaW50QXJyYXkgb3V0Q0hhbmRsZSkgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBvdXRDSGFuZGxlLCAwKTsKLQlqaW50IHN0YXR1cz0gKGppbnQpIFJDKEdldEluZGV4ZWRTdWJDb250cm9sKChDb250cm9sUmVmKSBjSGFuZGxlLCBpbmRleCwgKENvbnRyb2xSZWYqKSBzYSkpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBvdXRDSGFuZGxlLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0U3VwZXJDb250cm9sKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSwgamludEFycmF5IHBhcmVudEhhbmRsZSkgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBwYXJlbnRIYW5kbGUsIDApOwotCWppbnQgc3RhdHVzPSAoamludCkgUkMoR2V0U3VwZXJDb250cm9sKChDb250cm9sUmVmKWNIYW5kbGUsIChDb250cm9sUmVmKikgc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgcGFyZW50SGFuZGxlLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0lzVmFsaWRDb250cm9sSGFuZGxlKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSkgewotCXJldHVybiAoamJvb2xlYW4pIElzVmFsaWRDb250cm9sSGFuZGxlKChDb250cm9sUmVmKWNIYW5kbGUpOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sUmVmZXJlbmNlKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSwgamludCBkYXRhKSB7Ci0JU2V0Q29udHJvbFJlZmVyZW5jZSgoQ29udHJvbFJlZiljSGFuZGxlLCBkYXRhKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q29udHJvbFJlZmVyZW5jZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUpIHsKLQlyZXR1cm4gKGppbnQpIEdldENvbnRyb2xSZWZlcmVuY2UoKENvbnRyb2xSZWYpY0hhbmRsZSk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2xUaXRsZUFzQ0ZTdHJpbmcoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IGNIYW5kbGUsIGppbnRBcnJheSBzSGFuZGxlKSB7Ci0JamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIHNIYW5kbGUsIDApOwotCWppbnQgc3RhdHVzPSAoamludCkgUkMoQ29weUNvbnRyb2xUaXRsZUFzQ0ZTdHJpbmcoKENvbnRyb2xSZWYpY0hhbmRsZSwgKENGU3RyaW5nUmVmKikgc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgc0hhbmRsZSwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldENvbnRyb2xUaXRsZVdpdGhDRlN0cmluZyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUsIGppbnQgc0hhbmRsZSkgewotCXJldHVybiAoamludCkgUkMoU2V0Q29udHJvbFRpdGxlV2l0aENGU3RyaW5nKChDb250cm9sUmVmKWNIYW5kbGUsIChDRlN0cmluZ1JlZikgc0hhbmRsZSkpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19FbmFibGVDb250cm9sKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSkgewotCXJldHVybiAoamludCkgUkMoRW5hYmxlQ29udHJvbCgoQ29udHJvbFJlZiljSGFuZGxlKSk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0Rpc2FibGVDb250cm9sKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSkgewotCXJldHVybiAoamludCkgUkMoRGlzYWJsZUNvbnRyb2woKENvbnRyb2xSZWYpY0hhbmRsZSkpOwotfQotCi1KTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSXNDb250cm9sRW5hYmxlZChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUpIHsKLQlyZXR1cm4gKGpib29sZWFuKSBJc0NvbnRyb2xFbmFibGVkKChDb250cm9sUmVmKWNIYW5kbGUpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDb250cm9sMzJCaXRNYXhpbXVtKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSkgewotCXJldHVybiBHZXRDb250cm9sMzJCaXRNYXhpbXVtKChDb250cm9sUmVmKWNIYW5kbGUpOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sMzJCaXRNYXhpbXVtKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSwgamludCBtYXgpIHsKLQlTZXRDb250cm9sMzJCaXRNYXhpbXVtKChDb250cm9sUmVmKWNIYW5kbGUsIG1heCk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2wzMkJpdE1pbmltdW0oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBjSGFuZGxlKSB7Ci0JcmV0dXJuIEdldENvbnRyb2wzMkJpdE1pbmltdW0oKENvbnRyb2xSZWYpY0hhbmRsZSk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldENvbnRyb2xNaW5pbXVtKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSwganNob3J0IG1pbikgewotCVNldENvbnRyb2xNaW5pbXVtKChDb250cm9sUmVmKWNIYW5kbGUsIG1pbik7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldENvbnRyb2wzMkJpdE1pbmltdW0oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBjSGFuZGxlLCBqaW50IG1pbikgewotCVNldENvbnRyb2wzMkJpdE1pbmltdW0oKENvbnRyb2xSZWYpY0hhbmRsZSwgbWluKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q29udHJvbDMyQml0VmFsdWUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBjSGFuZGxlKSB7Ci0JcmV0dXJuIEdldENvbnRyb2wzMkJpdFZhbHVlKChDb250cm9sUmVmKWNIYW5kbGUpOwotfQotCi1KTklFWFBPUlQganNob3J0IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2xWYWx1ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUpIHsKLQlyZXR1cm4gR2V0Q29udHJvbFZhbHVlKChDb250cm9sUmVmKWNIYW5kbGUpOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sMzJCaXRWYWx1ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUsIGppbnQgdmFsdWUpIHsKLQlTZXRDb250cm9sMzJCaXRWYWx1ZSgoQ29udHJvbFJlZiljSGFuZGxlLCB2YWx1ZSk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2xWaWV3U2l6ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUpIHsKLQlyZXR1cm4gKGppbnQpIEdldENvbnRyb2xWaWV3U2l6ZSgoQ29udHJvbFJlZiljSGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0Q29udHJvbFZpZXdTaXplKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSwgamludCB2aWV3U2l6ZSkgewotCVNldENvbnRyb2xWaWV3U2l6ZSgoQ29udHJvbFJlZiljSGFuZGxlLCB2aWV3U2l6ZSk7Ci19Ci0KLS8qCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19JZGxlQ29udHJvbHMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB3SGFuZGxlKSB7Ci0JSWRsZUNvbnRyb2xzKChXaW5kb3dSZWYpd0hhbmRsZSk7Ci19Ci0qLwotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRCZXN0Q29udHJvbFJlY3QoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBjSGFuZGxlLAotCQlqc2hvcnRBcnJheSByZWN0LCBqc2hvcnRBcnJheSBiYXNlKSB7Ci0gICAgICAgIGpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgcmVjdCwgMCk7Ci0gICAgICAgIGpzaG9ydCAqc2I9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYmFzZSwgMCk7Ci0JamludCBzdGF0dXM9IChqaW50KSBSQyhHZXRCZXN0Q29udHJvbFJlY3QoKENvbnRyb2xSZWYpY0hhbmRsZSwgKFJlY3QqKSBzYSwgKHNob3J0Kikgc2IpKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCByZWN0LCBzYSwgMCk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYmFzZSwgc2IsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2xLaW5kKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgY0hhbmRsZSwgamludEFycmF5IGtpbmQpIHsKLSAgICAgICAgamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGtpbmQsIDApOwotCWppbnQgc3RhdHVzPSAoamludCkgUkMoR2V0Q29udHJvbEtpbmQoKENvbnRyb2xSZWYpY0hhbmRsZSwgKENvbnRyb2xLaW5kKikgc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwga2luZCwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldENvbnRyb2xEYXRhX19JU0lfM0koSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBjSGFuZGxlLAotCQlqc2hvcnQgcGFydENvZGUsIGppbnQgdGFnLCBqaW50QXJyYXkgZGF0YSkgewotCVNpemUgb3V0U2l6ZTsKLSAgICAgICAgamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGRhdGEsIDApOwotCWpzaXplIGxlbmd0aD0gKCplbnYpLT5HZXRBcnJheUxlbmd0aChlbnYsIGRhdGEpOwotCU9TRXJyIGVycm9yPSBSQyhHZXRDb250cm9sRGF0YSgoQ29udHJvbFJlZikgY0hhbmRsZSwgcGFydENvZGUsIHRhZywgc2l6ZW9mKGludCkqbGVuZ3RoLCBzYSwgJm91dFNpemUpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgZGF0YSwgc2EsIDApOwotCXJldHVybiBlcnJvcjsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0Q29udHJvbERhdGFfX0lTSV8zUyhKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IGNIYW5kbGUsCi0JCWpzaG9ydCBwYXJ0Q29kZSwgamludCB0YWcsIGpzaG9ydEFycmF5IGRhdGEpIHsKLQlTaXplIG91dFNpemU7Ci0gICAgICAgIGpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgZGF0YSwgMCk7Ci0JanNpemUgbGVuZ3RoPSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgZGF0YSk7Ci0JT1NFcnIgZXJyb3I9IFJDKEdldENvbnRyb2xEYXRhKChDb250cm9sUmVmKSBjSGFuZGxlLCBwYXJ0Q29kZSwgdGFnLCBzaXplb2Yoc2hvcnQpKmxlbmd0aCwgc2EsICZvdXRTaXplKSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgZGF0YSwgc2EsIDApOwotCXJldHVybiBlcnJvcjsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0Q29udHJvbERhdGFfX0lTSUkoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJamludCBjSGFuZGxlLCBqc2hvcnQgcGFydENvZGUsIGppbnQgdGFnLCBqaW50IGRhdGEpIHsKLQlyZXR1cm4gUkMoU2V0Q29udHJvbERhdGEoKENvbnRyb2xSZWYpIGNIYW5kbGUsIHBhcnRDb2RlLCB0YWcsIHNpemVvZihpbnQpLCAoUHRyKSAmZGF0YSkpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sRGF0YV9fSVNJXzNTKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCWppbnQgY0hhbmRsZSwganNob3J0IHBhcnRDb2RlLCBqaW50IHRhZywganNob3J0QXJyYXkgZGF0YSkgewotCWpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgZGF0YSwgMCk7Ci0JanNpemUgbGVuZ3RoPSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgZGF0YSk7Ci0JamludCBzdGF0dXM9IChqaW50KSBSQyhTZXRDb250cm9sRGF0YSgoQ29udHJvbFJlZikgY0hhbmRsZSwgcGFydENvZGUsIHRhZywgc2l6ZW9mKHNob3J0KSpsZW5ndGgsIChQdHIpIHNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgZGF0YSwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldEJldmVsQnV0dG9uQ29udGVudEluZm8oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJamludCBjSGFuZGxlLCBqc2hvcnQgY29udHJvbENvbnRlbnRUeXBlLCBqaW50IGNvbnRyb2xDb250ZW50KSB7Ci0JCQotCUNvbnRyb2xCdXR0b25Db250ZW50SW5mbyBpbmZvOworCURFQlVHX0NBTEwoIkhNSGlkZVRhZ1xuIikKIAkKLQlpbmZvLmNvbnRlbnRUeXBlPSAoQ29udHJvbENvbnRlbnRUeXBlKSBjb250cm9sQ29udGVudFR5cGU7Ci0JaW5mby51LmNJY29uSGFuZGxlPSAoQ0ljb25IYW5kbGUpIGNvbnRyb2xDb250ZW50OwotCQotCXJldHVybiBSQyhTZXRCZXZlbEJ1dHRvbkNvbnRlbnRJbmZvKChDb250cm9sUmVmKSBjSGFuZGxlLCAmaW5mbykpOworCXJldHVybiAoamludClITUhpZGVUYWcoKTsKIH0KKyNlbmRpZiAvKiBOT19ITUhpZGVUYWcgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0Q29udHJvbEZvbnRTdHlsZShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgY0hhbmRsZSwganNob3J0IGZvbnQsIGpzaG9ydCBzaXplLCBqc2hvcnQgc3R5bGUpIHsKLQlDb250cm9sRm9udFN0eWxlUmVjIGZvbnRSZWM7Ci0JZm9udFJlYy5mbGFncz0ga0NvbnRyb2xVc2VGb250TWFzayB8IGtDb250cm9sVXNlU2l6ZU1hc2sgfCBrQ29udHJvbFVzZUZhY2VNYXNrOwotCWZvbnRSZWMuZm9udD0gZm9udDsKLQlmb250UmVjLnNpemU9IHNpemU7Ci0JZm9udFJlYy5zdHlsZT0gc3R5bGU7Ci0JcmV0dXJuIChqaW50KSBSQyhTZXRDb250cm9sRm9udFN0eWxlKChDb250cm9sUmVmKSBjSGFuZGxlLCAmZm9udFJlYykpOwotfQorI2lmbmRlZiBOT19ITVNldFRhZ0RlbGF5CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ITVNldFRhZ0RlbGF5CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkhNU2V0VGFnRGVsYXlcbiIpCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldFVwQ29udHJvbEJhY2tncm91bmQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IGNIYW5kbGUsIGpzaG9ydCBkZXB0aCwgamJvb2xlYW4gaXNDb2xvckRldmljZSkgewotCXJldHVybiAoamludCkgUkMoU2V0VXBDb250cm9sQmFja2dyb3VuZCgoQ29udHJvbFJlZikgY0hhbmRsZSwgZGVwdGgsIGlzQ29sb3JEZXZpY2UpKTsKKwlyZXR1cm4gKGppbnQpIEhNU2V0VGFnRGVsYXkoKER1cmF0aW9uKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0hNU2V0VGFnRGVsYXkgKi8KIAotSk5JRVhQT1JUIGpzaG9ydCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19IYW5kbGVDb250cm9sS2V5KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGNIYW5kbGUsIGpzaG9ydCBpbktleUNvZGUsIGpjaGFyIGluQ2hhckNvZGUsIGppbnQgbW9kaWZpZXJzKSB7Ci0JcmV0dXJuIChDb250cm9sUGFydENvZGUpIEhhbmRsZUNvbnRyb2xLZXkoKENvbnRyb2xSZWYpY0hhbmRsZSwgKFNJbnQxNilpbktleUNvZGUsIChTSW50MTYpaW5DaGFyQ29kZSwgKEV2ZW50TW9kaWZpZXJzKSBtb2RpZmllcnMpOwotfQorI2lmbmRlZiBOT19ITUluc3RhbGxDb250cm9sQ29udGVudENhbGxiYWNrCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ITUluc3RhbGxDb250cm9sQ29udGVudENhbGxiYWNrCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiSE1JbnN0YWxsQ29udHJvbENvbnRlbnRDYWxsYmFja1xuIikKIAotLy8tLS0tIHN0YW5kYXJkIGRpYWxvZ3MKLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUGlja0NvbG9yKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqc2hvcnRBcnJheSByZ2IsIGpzaG9ydEFycmF5IHdoZXJlLCBqYnl0ZUFycmF5IHRpdGxlLCBqYm9vbGVhbkFycmF5IHN1Y2Nlc3MpIHsKLQotCWppbnQgc3RhdHVzOwotCUNvbG9yUGlja2VySW5mbyBpbmZvOwotCi0gICAganNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCByZ2IsIDApOwotICAgIGpzaG9ydCAqc2I9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgd2hlcmUsIDApOwotICAgIGpieXRlICpzYz0gKCplbnYpLT5HZXRCeXRlQXJyYXlFbGVtZW50cyhlbnYsIHRpdGxlLCAwKTsKLSAgICBqYm9vbGVhbiAqc2Q9ICgqZW52KS0+R2V0Qm9vbGVhbkFycmF5RWxlbWVudHMoZW52LCBzdWNjZXNzLCAwKTsKLQkKLQlpbmZvLnRoZUNvbG9yLnByb2ZpbGU9IE5VTEw7Ci0JaW5mby50aGVDb2xvci5jb2xvci5yZ2IucmVkPSBzYVswXTsKLQlpbmZvLnRoZUNvbG9yLmNvbG9yLnJnYi5ncmVlbj0gc2FbMV07Ci0JaW5mby50aGVDb2xvci5jb2xvci5yZ2IuYmx1ZT0gc2FbMl07Ci0JaW5mby5kc3RQcm9maWxlPSBOVUxMOwotCWluZm8uZmxhZ3M9IGtDb2xvclBpY2tlckRpYWxvZ0lzTW92ZWFibGUgfCBrQ29sb3JQaWNrZXJEaWFsb2dJc01vZGFsOwotCWluZm8ucGxhY2VXaGVyZT0ga0F0U3BlY2lmaWVkT3JpZ2luOwotCWluZm8uZGlhbG9nT3JpZ2luLnY9IHNiWzBdOwotCWluZm8uZGlhbG9nT3JpZ2luLmg9IHNiWzFdOwotCWluZm8ucGlja2VyVHlwZT0gMDsKLQlpbmZvLmV2ZW50UHJvYz0gTlVMTDsKLQlpbmZvLmNvbG9yUHJvYz0gTlVMTDsKLQlpbmZvLmNvbG9yUHJvY0RhdGE9IDA7Ci0JbWVtY3B5KGluZm8ucHJvbXB0LCBzYywgKHNpemVfdCkgc2NbMF0pOwotCWluZm8ubUluZm8uZWRpdE1lbnVJRD0gMDsKLQlpbmZvLm1JbmZvLmN1dEl0ZW09IDA7Ci0JaW5mby5tSW5mby5jb3B5SXRlbT0gMDsKLQlpbmZvLm1JbmZvLnBhc3RlSXRlbT0gMDsKLQlpbmZvLm1JbmZvLmNsZWFySXRlbT0gMDsKLQlpbmZvLm1JbmZvLnVuZG9JdGVtPSAwOwotCQotCXN0YXR1cz0gKGppbnQpIFJDKFBpY2tDb2xvcigmaW5mbykpOwotCQotCXNkWzBdPSBpbmZvLm5ld0NvbG9yQ2hvc2VuOwotCQotCWlmIChpbmZvLm5ld0NvbG9yQ2hvc2VuKSB7Ci0JCXNhWzBdPSBpbmZvLnRoZUNvbG9yLmNvbG9yLnJnYi5yZWQ7Ci0JCXNhWzFdPSBpbmZvLnRoZUNvbG9yLmNvbG9yLnJnYi5ncmVlbjsKLQkJc2FbMl09IGluZm8udGhlQ29sb3IuY29sb3IucmdiLmJsdWU7Ci0JfQotCQotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHJnYiwgc2EsIDApOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHdoZXJlLCBzYiwgMCk7Ci0JKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCB0aXRsZSwgc2MsIDApOwotCSgqZW52KS0+UmVsZWFzZUJvb2xlYW5BcnJheUVsZW1lbnRzKGVudiwgc3VjY2Vzcywgc2QsIDApOwotCi0JcmV0dXJuIHN0YXR1czsKKwlyZXR1cm4gKGppbnQpIEhNSW5zdGFsbENvbnRyb2xDb250ZW50Q2FsbGJhY2soKENvbnRyb2xSZWYpYXJnMCwgKEhNQ29udHJvbENvbnRlbnRVUFApYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fSE1JbnN0YWxsQ29udHJvbENvbnRlbnRDYWxsYmFjayAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OYXZDcmVhdGVHZXRGaWxlRGlhbG9nKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBvcHRpb25GbGFncywgamludCB3aW5kb3dUaXRsZSwgamludCB3aGFuZGxlLCBqaW50QXJyYXkgZGlhbG9nSGFuZGxlKSB7Ci0JCi0JTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zIG9wdGlvbnM7Ci0JamludCBzdGF0dXM7Ci0gICAgICAgIGppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBkaWFsb2dIYW5kbGUsIDApOwotCQotCU5hdkdldERlZmF1bHREaWFsb2dDcmVhdGlvbk9wdGlvbnMoJm9wdGlvbnMpOwotCW9wdGlvbnMub3B0aW9uRmxhZ3MgfD0gb3B0aW9uRmxhZ3M7Ci0Jb3B0aW9ucy5wYXJlbnRXaW5kb3c9IChXaW5kb3dSZWYpIHdoYW5kbGU7Ci0JCi0Jc3RhdHVzPSBSQyhOYXZDcmVhdGVHZXRGaWxlRGlhbG9nKCZvcHRpb25zLCBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMLCAoTmF2RGlhbG9nUmVmKilzYSkpOwotCQotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBkaWFsb2dIYW5kbGUsIHNhLCAwKTsKLQkKLQlyZXR1cm4gc3RhdHVzOwotfQorI2lmbmRlZiBOT19IVW5sb2NrCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19IVW5sb2NrCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkhVbmxvY2tcbiIpCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05hdkNyZWF0ZVB1dEZpbGVEaWFsb2coSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IGZpbGVDcmVhdG9yLCBqaW50IHdpbmRvd1RpdGxlLCBqaW50IHdoYW5kbGUsIGppbnRBcnJheSBkaWFsb2dIYW5kbGUsIAotCQkJCWppbnQgb3B0aW9uRmxhZ3MsIGppbnQgZmlsZVR5cGUpIHsKLQkKLQlOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnMgb3B0aW9uczsKLQlqaW50IHN0YXR1czsKLSAgICAgICAgamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGRpYWxvZ0hhbmRsZSwgMCk7Ci0JCi0JTmF2R2V0RGVmYXVsdERpYWxvZ0NyZWF0aW9uT3B0aW9ucygmb3B0aW9ucyk7Ci0Jb3B0aW9ucy5vcHRpb25GbGFncyB8PSBvcHRpb25GbGFnczsKLQlvcHRpb25zLnBhcmVudFdpbmRvdz0gKFdpbmRvd1JlZikgd2hhbmRsZTsKLQlvcHRpb25zLndpbmRvd1RpdGxlPSAoQ0ZTdHJpbmdSZWYpIHdpbmRvd1RpdGxlOwotCQotCXN0YXR1cz0gUkMoTmF2Q3JlYXRlUHV0RmlsZURpYWxvZygmb3B0aW9ucywgZmlsZVR5cGUsIGZpbGVDcmVhdG9yLCBOVUxMLCBOVUxMLCAoTmF2RGlhbG9nUmVmKilzYSkpOwotCQotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBkaWFsb2dIYW5kbGUsIHNhLCAwKTsKLQkKLQlyZXR1cm4gc3RhdHVzOworCUhVbmxvY2soKEhhbmRsZSlhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19IVW5sb2NrICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05hdkNyZWF0ZUNob29zZUZvbGRlckRpYWxvZyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgb3B0aW9uRmxhZ3MsIGppbnQgd2luZG93VGl0bGUsIGppbnQgbWVzc2FnZUhhbmRsZSwgamludCB3aGFuZGxlLCBqaW50QXJyYXkgZGlhbG9nSGFuZGxlKSB7Ci0JCi0JTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zIG9wdGlvbnM7Ci0JamludCBzdGF0dXM7Ci0gICAgICAgIGppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBkaWFsb2dIYW5kbGUsIDApOwotCQotCU5hdkdldERlZmF1bHREaWFsb2dDcmVhdGlvbk9wdGlvbnMoJm9wdGlvbnMpOwotCW9wdGlvbnMub3B0aW9uRmxhZ3MgfD0gb3B0aW9uRmxhZ3M7Ci0Jb3B0aW9ucy5wYXJlbnRXaW5kb3c9IChXaW5kb3dSZWYpIHdoYW5kbGU7Ci0Jb3B0aW9ucy53aW5kb3dUaXRsZT0gKENGU3RyaW5nUmVmKSB3aW5kb3dUaXRsZTsKLQlvcHRpb25zLm1lc3NhZ2U9IChDRlN0cmluZ1JlZikgbWVzc2FnZUhhbmRsZTsKLQkKLQlzdGF0dXM9IFJDKE5hdkNyZWF0ZUNob29zZUZvbGRlckRpYWxvZygmb3B0aW9ucywgTlVMTCwgTlVMTCwgTlVMTCwgKE5hdkRpYWxvZ1JlZiopc2EpKTsKLQkKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgZGlhbG9nSGFuZGxlLCBzYSwgMCk7Ci0JCi0JcmV0dXJuIHN0YXR1czsKLX0KKyNpZm5kZWYgTk9fSW5pdENvbnRleHR1YWxNZW51cworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW5pdENvbnRleHR1YWxNZW51cworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiSW5pdENvbnRleHR1YWxNZW51c1xuIikKIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmF2RGlhbG9nU2V0U2F2ZUZpbGVOYW1lKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGRpYWxvZ0hhbmRsZSwgamludCBmaWxlTmFtZSkgewotCXJldHVybiAoamludCkgUkMoTmF2RGlhbG9nU2V0U2F2ZUZpbGVOYW1lKChOYXZEaWFsb2dSZWYpIGRpYWxvZ0hhbmRsZSwgKENGU3RyaW5nUmVmKSBmaWxlTmFtZSkpOworCXJldHVybiAoamludClJbml0Q29udGV4dHVhbE1lbnVzKCk7CiB9CisjZW5kaWYgLyogTk9fSW5pdENvbnRleHR1YWxNZW51cyAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OYXZEaWFsb2dHZXRTYXZlRmlsZU5hbWUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgZGlhbG9nSGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBOYXZEaWFsb2dHZXRTYXZlRmlsZU5hbWUoKE5hdkRpYWxvZ1JlZikgZGlhbG9nSGFuZGxlKTsJCi19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05hdkRpYWxvZ1J1bihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgZGlhbG9nSGFuZGxlKSB7CQotCXJldHVybiAoamludCkgUkMoTmF2RGlhbG9nUnVuKChOYXZEaWFsb2dSZWYpIGRpYWxvZ0hhbmRsZSkpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OYXZEaWFsb2dHZXRVc2VyQWN0aW9uKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBkaWFsb2dIYW5kbGUpIHsJCi0JcmV0dXJuIChqaW50KSBSQyhOYXZEaWFsb2dHZXRVc2VyQWN0aW9uKChOYXZEaWFsb2dSZWYpIGRpYWxvZ0hhbmRsZSkpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OYXZEaWFsb2dHZXRSZXBseShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgZGlhbG9nSGFuZGxlLCBqaW50QXJyYXkgcmVwbHlIYW5kbGUpIHsKLQlOYXZSZXBseVJlY29yZCAqcmVwbHk9IChOYXZSZXBseVJlY29yZCopIG1hbGxvYyhzaXplb2YoTmF2UmVwbHlSZWNvcmQpKTsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgcmVwbHlIYW5kbGUsIDApOwotCXNhWzBdPSAoamludCkgcmVwbHk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIHJlcGx5SGFuZGxlLCBzYSwgMCk7Ci0JcmV0dXJuIChqaW50KSBSQyhOYXZEaWFsb2dHZXRSZXBseSgoTmF2RGlhbG9nUmVmKSBkaWFsb2dIYW5kbGUsIHJlcGx5KSk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05hdkRpYWxvZ0Rpc3Bvc2VSZXBseShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgcmVwbHlIYW5kbGUpIHsKLQlmcmVlKChOYXZSZXBseVJlY29yZCopIHJlcGx5SGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmF2UmVwbHlSZWNvcmRHZXRTZWxlY3Rpb24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IHJlcGx5SGFuZGxlKSB7Ci0JTmF2UmVwbHlSZWNvcmQgKnJlcGx5PSAoTmF2UmVwbHlSZWNvcmQqKSByZXBseUhhbmRsZTsKLQlyZXR1cm4gKGppbnQpICZyZXBseS0+c2VsZWN0aW9uOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19BRUNvdW50SXRlbXMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IGFlRGVzY0xpc3QsIGppbnRBcnJheSBjb3VudCkgewotICAgICAgICBqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgY291bnQsIDApOwotCWludCBzdGF0dXM9IChqaW50KSBSQyhBRUNvdW50SXRlbXMoKGNvbnN0IEFFRGVzY0xpc3QqKWFlRGVzY0xpc3QsIChsb25nKilzYSkpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBjb3VudCwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0FFR2V0TnRoUHRyKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBhZURlc2NMaXN0LCBqaW50IGluZGV4LCBqaW50QXJyYXkgc0hhbmRsZSkgewotCUFFS2V5d29yZCBrZXlXb3JkOwotCURlc2NUeXBlIHJldHVybmVkVHlwZTsKLQlGU1JlZiBmaWxlU3BlYzsKLQlTaXplIGFjdHVhbFNpemU7Ci0gICAgICAgIGppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBzSGFuZGxlLCAwKTsKLQkKLQlqaW50IHN0YXR1cz0gUkMoQUVHZXROdGhQdHIoKGNvbnN0IEFFRGVzY0xpc3QqKWFlRGVzY0xpc3QsIGluZGV4LCB0eXBlRlNSZWYsICZrZXlXb3JkLCAmcmV0dXJuZWRUeXBlLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmaWxlU3BlYywgc2l6ZW9mKGZpbGVTcGVjKSwgJmFjdHVhbFNpemUpKTsKLQotCWlmIChzdGF0dXMgPT0gMCkgewotCQlDRlVSTFJlZiB1cmw9IENGVVJMQ3JlYXRlRnJvbUZTUmVmKGtDRkFsbG9jYXRvckRlZmF1bHQsICZmaWxlU3BlYyk7Ci0JCXNhWzBdPSAoamludCkgQ0ZVUkxDb3B5RmlsZVN5c3RlbVBhdGgodXJsLCBrQ0ZVUkxQT1NJWFBhdGhTdHlsZSk7Ci0JfQotCQotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBzSGFuZGxlLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmF2RGlhbG9nRGlzcG9zZShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgZGlhbG9nSGFuZGxlKSB7CQotCU5hdkRpYWxvZ0Rpc3Bvc2UoKE5hdkRpYWxvZ1JlZikgZGlhbG9nSGFuZGxlKTsKLX0KLQotLy8gU3RyaW5ncwotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGpzdHJpbmcgcykgewotCWNvbnN0IGpjaGFyICpidWZmZXI9ICgqZW52KS0+R2V0U3RyaW5nQ2hhcnMoZW52LCBzLCBOVUxMKTsKLQlDRkluZGV4IGxlbmd0aD0gKCplbnYpLT5HZXRTdHJpbmdMZW5ndGgoZW52LCBzKTsKLQlDRlN0cmluZ1JlZiBzcmVmPSBDRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzKE5VTEwsIChjb25zdCBVbmlDaGFyKikgYnVmZmVyLCBsZW5ndGgpOwotCSgqZW52KS0+UmVsZWFzZVN0cmluZ0NoYXJzKGVudiwgcywgYnVmZmVyKTsKLQlyZXR1cm4gKGppbnQpIHNyZWY7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NGUmVsZWFzZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHNIYW5kbGUpIHsKLQlDRlJlbGVhc2UoKENGU3RyaW5nUmVmKXNIYW5kbGUpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DRlN0cmluZ0dldExlbmd0aChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHNIYW5kbGUpIHsKLQlyZXR1cm4gKGppbnQpIENGU3RyaW5nR2V0TGVuZ3RoKChDRlN0cmluZ1JlZilzSGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0ZTdHJpbmdHZXRDaGFyYWN0ZXJzKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJCWppbnQgc0hhbmRsZSwgamludCBzdGFydCwgamludCBsZW5ndGgsIGpjaGFyQXJyYXkgYnVmZmVyKSB7CQkJCi0JamNoYXIgKnNhPSAoKmVudiktPkdldENoYXJBcnJheUVsZW1lbnRzKGVudiwgYnVmZmVyLCAwKTsKLSAJQ0ZTdHJpbmdHZXRDaGFyYWN0ZXJzKChDRlN0cmluZ1JlZilzSGFuZGxlLCBDRlJhbmdlTWFrZShzdGFydCwgbGVuZ3RoKSwgKFVuaUNoYXIqKSBzYSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYnVmZmVyLCBzYSwgMCk7Ci19Ci0KLS8vLS0tLSBBbGVydHMKLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ3JlYXRlU3RhbmRhcmRBbGVydChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCQkJanNob3J0IGFsZXJ0VHlwZSwgamludCBtZXNzYWdlSGFuZGxlLCBqaW50IGV4cGxhbmF0aW9uSGFuZGxlLCBqaW50IHBhcmFtLCBqaW50QXJyYXkgZGlhbG9nSGFuZGxlKSB7Ci0JCi0gICAgICAgIGppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBkaWFsb2dIYW5kbGUsIDApOwotCWppbnQgc3RhdHVzPSBSQyhDcmVhdGVTdGFuZGFyZEFsZXJ0KChBbGVydFR5cGUpYWxlcnRUeXBlLCAoQ0ZTdHJpbmdSZWYpbWVzc2FnZUhhbmRsZSwgKENGU3RyaW5nUmVmKWV4cGxhbmF0aW9uSGFuZGxlLAotCQkJCShjb25zdCBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlYyopIHBhcmFtLCAoRGlhbG9nUmVmKilzYSkpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBkaWFsb2dIYW5kbGUsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQkKLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUnVuU3RhbmRhcmRBbGVydChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCQkJamludCBhbGVydEhhbmRsZSwgamludCBmaWx0ZXJQcm9jLCBqc2hvcnRBcnJheSBpdGVtSGl0KSB7Ci0gICAgICAgIGpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgaXRlbUhpdCwgMCk7Ci0JamludCBzdGF0dXM9IChqaW50KSBSQyhSdW5TdGFuZGFyZEFsZXJ0KChEaWFsb2dSZWYpYWxlcnRIYW5kbGUsIChNb2RhbEZpbHRlclVQUClmaWx0ZXJQcm9jLCAoRGlhbG9nSXRlbUluZGV4KilzYSkpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGl0ZW1IaXQsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQotCi0vLy0tLS0gTUxURSBUZXh0Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTkluaXRUZXh0ZW5zaW9uKEpOSUVudiAqZW52LCBqY2xhc3MgenopIHsKLQlyZXR1cm4gKGppbnQpIFJDKFRYTkluaXRUZXh0ZW5zaW9uKE5VTEwsIDAsIDApKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOTmV3T2JqZWN0KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGZpbGVTcGVjLCBqaW50IHdIYW5kbGUsIGpzaG9ydEFycmF5IGJvdW5kcywgamludCBmcmFtZU9wdGlvbnMsIGppbnQgZnJhbWVUeXBlLCBqaW50IGZpbGVUeXBlLAotCQkJCQlqaW50IHBlcm1hbmVudEVuY29kaW5nLCBqaW50QXJyYXkgdHhIYW5kbGUsIGppbnRBcnJheSBmcmFtZUlELCBqaW50IHJlZmNvbikgewotCQkJCi0gICAgICAgIGpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCAwKTsKLSAgICAgICAgamludCAqc2I9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIHR4SGFuZGxlLCAwKTsKLSAgICAgICAgamludCAqc2M9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGZyYW1lSUQsIDApOwotCQkJCQotCWppbnQgc3RhdHVzPSAoamludCkgUkMoVFhOTmV3T2JqZWN0KChjb25zdCBGU1NwZWMqKWZpbGVTcGVjLCAoV2luZG93UmVmKXdIYW5kbGUsIChSZWN0Kilib3VuZHMsIChUWE5GcmFtZU9wdGlvbnMpZnJhbWVPcHRpb25zLAotCQkJCShUWE5GcmFtZVR5cGUpZnJhbWVUeXBlLCAoVFhORmlsZVR5cGUpZmlsZVR5cGUsIChUWE5QZXJtYW5lbnRUZXh0RW5jb2RpbmdUeXBlKXBlcm1hbmVudEVuY29kaW5nLAotCQkJCQkoVFhOT2JqZWN0KilzYiwgKFRYTkZyYW1lSUQqKXNjLCAoVFhOT2JqZWN0UmVmY29uKXJlZmNvbikpOwotCQotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgc2EsIDApOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCB0eEhhbmRsZSwgc2IsIDApOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBmcmFtZUlELCBzYywgMCk7Ci0JCi0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhORGVsZXRlT2JqZWN0KEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgdHhIYW5kbGUpIHsKLQlUWE5EZWxldGVPYmplY3QoKFRYTk9iamVjdCl0eEhhbmRsZSk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTlNldEZyYW1lQm91bmRzKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IHR4SGFuZGxlLCBqaW50IHRvcCwgamludCBsZWZ0LCBqaW50IGJvdHRvbSwgamludCByaWdodCwgamludCBmcmFtZUlEKSB7Ci0JVFhOU2V0RnJhbWVCb3VuZHMoKFRYTk9iamVjdCl0eEhhbmRsZSwgdG9wLCBsZWZ0LCBib3R0b20sIHJpZ2h0LCAoVFhORnJhbWVJRCkgZnJhbWVJRCk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTkRyYXcoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB0eEhhbmRsZSwgamludCBnRGV2aWNlKSB7Ci0JVFhORHJhdygoVFhOT2JqZWN0KXR4SGFuZGxlLCAoR1dvcmxkUHRyKWdEZXZpY2UpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5HZXREYXRhKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJCWppbnQgdHhIYW5kbGUsIGppbnQgc3RhcnRPZmZzZXQsIGppbnQgZW5kT2Zmc2V0LCBqaW50QXJyYXkgZGF0YUhhbmRsZSkgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBkYXRhSGFuZGxlLCAwKTsKLQlqaW50IHN0YXR1cz0gKGppbnQpIFJDKFRYTkdldERhdGEoKFRYTk9iamVjdCl0eEhhbmRsZSwgc3RhcnRPZmZzZXQsIGVuZE9mZnNldCwgKEhhbmRsZSopc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgZGF0YUhhbmRsZSwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05ld0hhbmRsZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHNpemUpIHsKLQlyZXR1cm4gKGppbnQpIE5ld0hhbmRsZShzaXplKTsJCi19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05ld0hhbmRsZUNsZWFyKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgc2l6ZSkgewotCXJldHVybiAoamludCkgTmV3SGFuZGxlQ2xlYXIoc2l6ZSk7CQotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19EaXNwb3NlSGFuZGxlKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgaGFuZGxlKSB7Ci0JRGlzcG9zZUhhbmRsZSgoSGFuZGxlKWhhbmRsZSk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEhhbmRsZVNpemUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBoYW5kbGUpIHsKLQlyZXR1cm4gR2V0SGFuZGxlU2l6ZSgoSGFuZGxlKWhhbmRsZSk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0RlcmVmSGFuZGxlKEpOSUVudiAqZW52LCBqY2xhc3MgenosIGppbnQgaGFuZGxlKSB7Ci0JSGFuZGxlIGg9IChIYW5kbGUpIGhhbmRsZTsKLQlyZXR1cm4gKGppbnQpICpoOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OZXdQdHIoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBzaXplKSB7Ci0JcmV0dXJuIChqaW50KSBOZXdQdHIoc2l6ZSk7CQotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OZXdQdHJDbGVhcihKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHNpemUpIHsKLQlyZXR1cm4gKGppbnQpIE5ld1B0ckNsZWFyKHNpemUpOwkKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfRGlzcG9zZVB0cihKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHB0cikgewotCURpc3Bvc2VQdHIoKHZvaWQqKXB0cik7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFB0clNpemUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBwdHIpIHsKLQlyZXR1cm4gKGppbnQpIEdldFB0clNpemUoKHZvaWQqKXB0cik7Ci19Ci0KLS8qCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19NZW1FcnJvcihKTklFbnYgKmVudiwgamNsYXNzIHp6KSB7Ci0JcmV0dXJuIChqaW50KSBNZW1FcnJvcigpOwkKLX0KLSovCi0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX2dldEhhbmRsZURhdGFfX0lfM0MoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IGhuZGwsIGpjaGFyQXJyYXkgZGF0YSkgewotCUhhbmRsZSBoYW5kbGU9IChIYW5kbGUpaG5kbDsKLQlqY2hhciAqc2E9ICgqZW52KS0+R2V0Q2hhckFycmF5RWxlbWVudHMoZW52LCBkYXRhLCAwKTsKLQlpbnQgbGVuZ3RoPSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgZGF0YSk7Ci0JbWVtY3B5KHNhLCAqaGFuZGxlLCBsZW5ndGgqc2l6ZW9mKGpjaGFyKSk7Ci0JKCplbnYpLT5SZWxlYXNlQ2hhckFycmF5RWxlbWVudHMoZW52LCBkYXRhLCBzYSwgMCk7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX2dldEhhbmRsZURhdGFfX0lfM0koSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IGhuZGwsIGppbnRBcnJheSBkYXRhKSB7Ci0JSGFuZGxlIGhhbmRsZT0gKEhhbmRsZSlobmRsOwotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBkYXRhLCAwKTsKLQlpbnQgbGVuZ3RoPSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgZGF0YSk7Ci0JbWVtY3B5KHNhLCAqaGFuZGxlLCBsZW5ndGgqc2l6ZW9mKGppbnQpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgZGF0YSwgc2EsIDApOwotfQotCi0vLyBtZW0gZnVuY3Rpb25zCi0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX21lbWNweV9fSUlJKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBkZXN0LCBqaW50IHNyYywgamludCBuKSB7Ci0JbWVtY3B5KCh2b2lkKilkZXN0LCAoY29uc3Qgdm9pZCopc3JjLCAoc2l6ZV90KW4pOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19tZW1jcHlfX0lfM0JJKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBkZXN0LCBqYnl0ZUFycmF5IHNyYywgamludCBuKSB7Ci0JamJ5dGUgKnNhPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgc3JjLCAwKTsKLQltZW1jcHkoKHZvaWQqKWRlc3QsIChjb25zdCB2b2lkKilzYSwgKHNpemVfdCluKTsKLQkoKmVudiktPlJlbGVhc2VCeXRlQXJyYXlFbGVtZW50cyhlbnYsIHNyYywgc2EsIDApOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19tZW1jcHlfX18zQklJKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamJ5dGVBcnJheSBkZXN0LCBqaW50IHNyYywgamludCBuKSB7Ci0JamJ5dGUgKnNhPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgZGVzdCwgMCk7Ci0JbWVtY3B5KCh2b2lkKilzYSwgKGNvbnN0IHZvaWQqKXNyYywgKHNpemVfdCluKTsKLQkoKmVudiktPlJlbGVhc2VCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGRlc3QsIHNhLCAwKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfbWVtc2V0KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCBkZXN0LCBqaW50IHZhbHVlLCBqaW50IHNpemUpIHsKLQltZW1zZXQoKHZvaWQqKWRlc3QsIChpbnQpdmFsdWUsIChzaXplX3Qpc2l6ZSk7Ci19Ci0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOU2V0RGF0YShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCQlqaW50IHR4SGFuZGxlLCBqY2hhckFycmF5IHVuaWNvZGVDaGFycywgamludCBzdGFydE9mZnNldCwgamludCBlbmRPZmZzZXQpIHsKLSAgICAgICAgamNoYXIgKnNhPSAoKmVudiktPkdldENoYXJBcnJheUVsZW1lbnRzKGVudiwgdW5pY29kZUNoYXJzLCAwKTsKLSAgICAgICAganNpemUgbGVuZ3RoPSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgdW5pY29kZUNoYXJzKTsKLQlqaW50IHN0YXR1cz0gKGppbnQpIFJDKFRYTlNldERhdGEoKFRYTk9iamVjdCl0eEhhbmRsZSwga1RYTlVuaWNvZGVUZXh0RGF0YSwgKHZvaWQqKSBzYSwgbGVuZ3RoKnNpemVvZihqY2hhciksIHN0YXJ0T2Zmc2V0LCBlbmRPZmZzZXQpKTsKLQkoKmVudiktPlJlbGVhc2VDaGFyQXJyYXlFbGVtZW50cyhlbnYsIHVuaWNvZGVDaGFycywgc2EsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTkdldExpbmVDb3VudChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCQlqaW50IHR4SGFuZGxlLCBqaW50QXJyYXkgbGluZUNvdW50KSB7Ci0gICAgICAgIGppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBsaW5lQ291bnQsIDApOwotCWppbnQgc3RhdHVzPSAoamludCkgUkMoVFhOR2V0TGluZUNvdW50KChUWE5PYmplY3QpdHhIYW5kbGUsIChJdGVtQ291bnQqKSBzYSkpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBsaW5lQ291bnQsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5EYXRhU2l6ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHR4SGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBUWE5EYXRhU2l6ZSgoVFhOT2JqZWN0KXR4SGFuZGxlKTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOR2V0U2VsZWN0aW9uKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IHR4SGFuZGxlLCBqaW50QXJyYXkgc3RhcnQsIGppbnRBcnJheSBlbmQpIHsKLSAgICAgICAgamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIHN0YXJ0LCAwKTsKLSAgICAgICAgamludCAqc2I9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGVuZCwgMCk7Ci0JVFhOR2V0U2VsZWN0aW9uKChUWE5PYmplY3QpdHhIYW5kbGUsIChUWE5PZmZzZXQqKXNhLCAoVFhOT2Zmc2V0KilzYik7CQotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBzdGFydCwgc2EsIDApOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBlbmQsIHNiLCAwKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOU2V0U2VsZWN0aW9uKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IHR4SGFuZGxlLCBqaW50IHN0YXJ0LCBqaW50IGVuZCkgewotCXJldHVybiAoamludCkgUkMoVFhOU2V0U2VsZWN0aW9uKChUWE5PYmplY3QpdHhIYW5kbGUsIChUWE5PZmZzZXQpc3RhcnQsIChUWE5PZmZzZXQpZW5kKSk7CQotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5TZWxlY3RBbGwoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB0eEhhbmRsZSkgewotCVRYTlNlbGVjdEFsbCgoVFhOT2JqZWN0KXR4SGFuZGxlKTsJCi19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTlNob3dTZWxlY3Rpb24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgdHhIYW5kbGUsIGpib29sZWFuIHNob3dFbmQpIHsKLQlUWE5TaG93U2VsZWN0aW9uKChUWE5PYmplY3QpdHhIYW5kbGUsIChCb29sZWFuKXNob3dFbmQpOwkKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOS2V5RG93bihKTklFbnYgKmVudiwgamNsYXNzIHp6LAkKLQkJCQkJamludCB0eEhhbmRsZSwgamludEFycmF5IGV2ZW50RGF0YSkgewotCUV2ZW50UmVjb3JkIGV2ZW50OwotCWNvcHlFdmVudERhdGEoZW52LCAmZXZlbnQsIGV2ZW50RGF0YSk7Ci0JVFhOS2V5RG93bigoVFhOT2JqZWN0KXR4SGFuZGxlLCAmZXZlbnQpOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5DbGljayhKTklFbnYgKmVudiwgamNsYXNzIHp6LAkKLQkJCQkJamludCB0eEhhbmRsZSwgamludEFycmF5IGV2ZW50RGF0YSkgewotCUV2ZW50UmVjb3JkIGV2ZW50OwotCWNvcHlFdmVudERhdGEoZW52LCAmZXZlbnQsIGV2ZW50RGF0YSk7Ci0JVFhOQ2xpY2soKFRYTk9iamVjdCl0eEhhbmRsZSwgJmV2ZW50KTsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhORm9jdXMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgdHhIYW5kbGUsIGpib29sZWFuIGJlY29taW5nRm9jdXNlZCkgewotCVRYTkZvY3VzKChUWE5PYmplY3QpdHhIYW5kbGUsIChCb29sZWFuKWJlY29taW5nRm9jdXNlZCk7CQotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5DdXQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB0eEhhbmRsZSkgewotCXJldHVybiAoamludCkgUkMoVFhOQ3V0KChUWE5PYmplY3QpdHhIYW5kbGUpKTsJCi19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTkNvcHkoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCB0eEhhbmRsZSkgewotCXJldHVybiAoamludCkgUkMoVFhOQ29weSgoVFhOT2JqZWN0KXR4SGFuZGxlKSk7CQotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5QYXN0ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHR4SGFuZGxlKSB7Ci0JcmV0dXJuIChqaW50KSBSQyhUWE5QYXN0ZSgoVFhOT2JqZWN0KXR4SGFuZGxlKSk7CQotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5HZXRSZWN0Qm91bmRzKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IHR4SGFuZGxlLCBqc2hvcnRBcnJheSB2aWV3UmVjdCwgamludEFycmF5IGRlc3RSZWN0LCBqaW50QXJyYXkgdGV4dFJlY3QpIHsKLSAgICAgICAganNob3J0ICpzYT0gTlVMTDsKLSAgICAgICAgamludCAqc2I9IE5VTEw7Ci0gICAgICAgIGppbnQgKnNjPSBOVUxMOwotCWppbnQgc3RhdHVzOwotCWlmICh2aWV3UmVjdCAhPSBOVUxMKQotCQlzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCB2aWV3UmVjdCwgMCk7Ci0JaWYgKGRlc3RSZWN0ICE9IE5VTEwpCi0JCXNiPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBkZXN0UmVjdCwgMCk7Ci0JaWYgKHRleHRSZWN0ICE9IE5VTEwpCi0JCXNjPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCB0ZXh0UmVjdCwgMCk7Ci0Jc3RhdHVzPSAoamludCkgUkMoVFhOR2V0UmVjdEJvdW5kcygoVFhOT2JqZWN0KXR4SGFuZGxlLCAoUmVjdCopc2EsIChUWE5Mb25nUmVjdCopc2IsIChUWE5Mb25nUmVjdCopc2MpKTsKLQlpZiAoc2EgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgdmlld1JlY3QsIHNhLCAwKTsKLQlpZiAoc2IgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGRlc3RSZWN0LCBzYiwgMCk7Ci0JaWYgKHNjICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCB0ZXh0UmVjdCwgc2MsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTlNldFJlY3RCb3VuZHMoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgdHhIYW5kbGUsIGpzaG9ydEFycmF5IHZpZXdSZWN0LCBqaW50QXJyYXkgZGVzdFJlY3QsIGpib29sZWFuIHVwZGF0ZSkgewotICAgICAgICBqc2hvcnQgKnNhPSBOVUxMOwotICAgICAgICBqaW50ICpzYj0gTlVMTDsKLQlpZiAodmlld1JlY3QgIT0gTlVMTCkKLQkJc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgdmlld1JlY3QsIDApOwotCWlmIChkZXN0UmVjdCAhPSBOVUxMKQotCQlzYj0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgZGVzdFJlY3QsIDApOwotCVRYTlNldFJlY3RCb3VuZHMoKFRYTk9iamVjdCl0eEhhbmRsZSwgKFJlY3QqKXNhLCAoVFhOTG9uZ1JlY3QqKXNiLCB1cGRhdGUpOwotCWlmIChzYSAhPSBOVUxMKQotCQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCB2aWV3UmVjdCwgc2EsIDApOwotCWlmIChzYiAhPSBOVUxMKQotCQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgZGVzdFJlY3QsIHNiLCAwKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOQWN0aXZhdGUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IHR4SGFuZGxlLCBqaW50IGZyYW1lSUQsIGpib29sZWFuIHNjcm9sbEJhclN0YXRlKSB7Ci0JcmV0dXJuIChqaW50KSBSQyhUWE5BY3RpdmF0ZSgoVFhOT2JqZWN0KXR4SGFuZGxlLCAoVFhORnJhbWVJRClmcmFtZUlELCAoVFhOU2Nyb2xsQmFyU3RhdGUpc2Nyb2xsQmFyU3RhdGUpKTsJCi19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTkVjaG9Nb2RlKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCB0eEhhbmRsZSwgamNoYXIgZWNob0NoYXJhY3RlciwgamludCBlbmNvZGluZywgamJvb2xlYW4gb24pIHsKLQlyZXR1cm4gKGppbnQpIFJDKFRYTkVjaG9Nb2RlKChUWE5PYmplY3QpdHhIYW5kbGUsIGVjaG9DaGFyYWN0ZXIsIGVuY29kaW5nLCBvbikpOwkKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOT2Zmc2V0VG9Qb2ludChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgdHhIYW5kbGUsIGppbnQgb2Zmc2V0LCBqc2hvcnRBcnJheSBsb2NhdGlvbikgewotCWpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgbG9jYXRpb24sIDApOwotCWppbnQgc3RhdHVzPSAoamludCkgUkMoVFhOT2Zmc2V0VG9Qb2ludCgoVFhOT2JqZWN0KXR4SGFuZGxlLCBvZmZzZXQsIChQb2ludCopIHNhKSk7CQotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGxvY2F0aW9uLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOUmVzaXplRnJhbWUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IHR4SGFuZGxlLCBqaW50IHdpZHRoLCBqaW50IGhlaWdodCwgamludCBmcmFtZUlEKSB7Ci0JVFhOUmVzaXplRnJhbWUoKFRYTk9iamVjdCl0eEhhbmRsZSwgd2lkdGgsIGhlaWdodCwgZnJhbWVJRCk7CQotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5HZXRWaWV3UmVjdChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgdHhIYW5kbGUsIGpzaG9ydEFycmF5IHZpZXdSZWN0KSB7Ci0JanNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCB2aWV3UmVjdCwgMCk7Ci0JVFhOR2V0Vmlld1JlY3QoKFRYTk9iamVjdCl0eEhhbmRsZSwgKFJlY3QqKSBzYSk7CQotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHZpZXdSZWN0LCBzYSwgMCk7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTkdldExpbmVNZXRyaWNzKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQkJamludCB0eEhhbmRsZSwgamludCBsaW5lTnVtYmVyLCBqaW50QXJyYXkgbGluZVdpZHRoLCBqaW50QXJyYXkgbGluZUhlaWdodCkgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBsaW5lV2lkdGgsIDApOwotCWppbnQgKnNiPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBsaW5lSGVpZ2h0LCAwKTsKLQlqaW50IHN0YXR1cz0gKGppbnQpIFJDKFRYTkdldExpbmVNZXRyaWNzKChUWE5PYmplY3QpdHhIYW5kbGUsIChVSW50MzIpbGluZU51bWJlciwgKEZpeGVkKilzYSwgKEZpeGVkKilzYikpOwkKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgbGluZVdpZHRoLCBzYSwgMCk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGxpbmVIZWlnaHQsIHNiLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5Gb3JjZVVwZGF0ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50IHR4SGFuZGxlKSB7Ci0JVFhORm9yY2VVcGRhdGUoKFRYTk9iamVjdCl0eEhhbmRsZSk7CQotfQotCi0vKgotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1Nfc2V0VFhOV29yZFdyYXAoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCQlqaW50IHR4SGFuZGxlLCBqYm9vbGVhbiB3cmFwKSB7Ci0gICAgVFhOQ29udHJvbFRhZyBjb250cm9sVGFnWzFdOwotICAgIFRYTkNvbnRyb2xEYXRhIGNvbnRyb2xEYXRhWzFdOwotICAgIGNvbnRyb2xUYWdbMF09IGtUWE5Xb3JkV3JhcFN0YXRlVGFnOwotCWNvbnRyb2xEYXRhWzBdLnVWYWx1ZT0gd3JhcCA/IGtUWE5BdXRvV3JhcCA6IGtUWE5Ob0F1dG9XcmFwOyAKLQlUWE5TZXRUWE5PYmplY3RDb250cm9scygoVFhOT2JqZWN0KXR4SGFuZGxlLCBmYWxzZSwgMSwgY29udHJvbFRhZywgY29udHJvbERhdGEpOwotfQotKi8KLQotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1Nfc2V0VFhOTWFyZ2lucyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJCWppbnQgdHhIYW5kbGUsIGpzaG9ydCBtYXJnaW4pIHsKLSAgICBUWE5Db250cm9sVGFnIGNvbnRyb2xUYWdbMV07Ci0gICAgVFhOQ29udHJvbERhdGEgY29udHJvbERhdGFbMV07Ci0gICAgVFhOTWFyZ2lucyBtOwotICAgIG0udG9wTWFyZ2luPSBtYXJnaW47Ci0gICAgbS5sZWZ0TWFyZ2luPSBtYXJnaW47Ci0gICAgbS5ib3R0b21NYXJnaW49IG1hcmdpbjsKLSAgICBtLnJpZ2h0TWFyZ2luPSBtYXJnaW47ICAgIAotICAgIGNvbnRyb2xUYWdbMF09IGtUWE5NYXJnaW5zVGFnOwotCWNvbnRyb2xEYXRhWzBdLm1hcmdpbnNQdHI9ICZtOyAKLQlUWE5TZXRUWE5PYmplY3RDb250cm9scygoVFhOT2JqZWN0KXR4SGFuZGxlLCBmYWxzZSwgMSwgY29udHJvbFRhZywgY29udHJvbERhdGEpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5TZXRUWE5PYmplY3RDb250cm9scyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCB0eEhhbmRsZSwgamJvb2xlYW4gY2xlYXJBbGwsIGppbnQgY29udHJvbENvdW50LCBqaW50QXJyYXkgY29udHJvbFRhZ3MsIGppbnRBcnJheSBjb250cm9sRGF0YSkgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBjb250cm9sVGFncywgMCk7Ci0JamludCAqc2I9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGNvbnRyb2xEYXRhLCAwKTsKLQlqaW50IHN0YXR1cz0gUkMoVFhOU2V0VFhOT2JqZWN0Q29udHJvbHMoKFRYTk9iamVjdCl0eEhhbmRsZSwgKEJvb2xlYW4pY2xlYXJBbGwsIChJdGVtQ291bnQpIGNvbnRyb2xDb3VudCwKLQkJCQkJCQkJKFRYTkNvbnRyb2xUYWcqKXNhLCAoVFhOQ29udHJvbERhdGEqKXNiKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGNvbnRyb2xUYWdzLCBzYSwgMCk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGNvbnRyb2xEYXRhLCBzYiwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotLy8tLS0tIFNjcmFwCi0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldEN1cnJlbnRTY3JhcChKTklFbnYgKmVudiwgamNsYXNzIHp6LCBqaW50QXJyYXkgc2NyYXByZWYpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgc2NyYXByZWYsIDApOwotCWppbnQgc3RhdHVzPSBSQyhHZXRDdXJyZW50U2NyYXAoKFNjcmFwUmVmKilzYSkpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBzY3JhcHJlZiwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NsZWFyQ3VycmVudFNjcmFwKEpOSUVudiAqZW52LCBqY2xhc3MgenopIHsKLQlyZXR1cm4gKGppbnQpIFJDKENsZWFyQ3VycmVudFNjcmFwKCkpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRTY3JhcEZsYXZvclNpemUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJamludCBzY3JhcEhhbmRsZSwgamludCBmbGF2b3JUeXBlLCBqaW50QXJyYXkgc2l6ZVJlZikgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBzaXplUmVmLCAwKTsKLQlqaW50IHN0YXR1cz0gUkMoR2V0U2NyYXBGbGF2b3JTaXplKChTY3JhcFJlZilzY3JhcEhhbmRsZSwgKFNjcmFwRmxhdm9yVHlwZSkgZmxhdm9yVHlwZSwgKFNpemUqKXNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIHNpemVSZWYsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRTY3JhcEZsYXZvckRhdGEoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJamludCBzY3JhcEhhbmRsZSwgamludCBmbGF2b3JUeXBlLCBqaW50QXJyYXkgc2l6ZVJlZiwgamJ5dGVBcnJheSBkYXRhKSB7Ci0JamludCBzdGF0dXM7Ci0JamludCAqc2E9IE5VTEw7Ci0JamJ5dGUgKnNiPSBOVUxMOwotCWlmIChzaXplUmVmICE9IE5VTEwpCi0JCXNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBzaXplUmVmLCAwKTsKLQlpZiAoZGF0YSAhPSBOVUxMKQotCQlzYj0gKCplbnYpLT5HZXRCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGRhdGEsIDApOwotCXN0YXR1cz0gUkMoR2V0U2NyYXBGbGF2b3JEYXRhKChTY3JhcFJlZilzY3JhcEhhbmRsZSwgKFNjcmFwRmxhdm9yVHlwZSkgZmxhdm9yVHlwZSwgKFNpemUqKXNhLCAodm9pZCopc2IpKTsKLQlpZiAoc2EgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIHNpemVSZWYsIHNhLCAwKTsKLQlpZiAoc2IgIT0gTlVMTCkKLQkJKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBkYXRhLCBzYiwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUHV0U2NyYXBGbGF2b3IoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJamludCBzY3JhcEhhbmRsZSwgamludCBmbGF2b3JUeXBlLCBqaW50IGZsYXZvckZsYWdzLCBqYnl0ZUFycmF5IGZsYXZvckRhdGEpIHsKLQlqaW50IHN0YXR1czsKLQlqYnl0ZSAqc2E9IE5VTEw7Ci0JaW50IHNpemU9IDA7Ci0JaWYgKGZsYXZvckRhdGEgIT0gTlVMTCkgewotCQlzaXplPSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgZmxhdm9yRGF0YSk7Ci0JCXNhPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgZmxhdm9yRGF0YSwgMCk7Ci0JfQotCXN0YXR1cz0gUkMoUHV0U2NyYXBGbGF2b3IoKFNjcmFwUmVmKXNjcmFwSGFuZGxlLCAoU2NyYXBGbGF2b3JUeXBlKSBmbGF2b3JUeXBlLCAoU2NyYXBGbGF2b3JGbGFncykgZmxhdm9yRmxhZ3MsCi0JCQkJc2l6ZSwgKGNvbnN0IHZvaWQqKXNhKSk7Ci0JaWYgKHNhICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZUJ5dGVBcnJheUVsZW1lbnRzKGVudiwgZmxhdm9yRGF0YSwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7Ci19Ci0KLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0dldFNjcmFwRmxhdm9yQ291bnQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJamludCBzY3JhcEhhbmRsZSwgamludEFycmF5IGluZm9Db3VudCkgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBpbmZvQ291bnQsIDApOwotCWppbnQgc3RhdHVzPSBSQyhHZXRTY3JhcEZsYXZvckNvdW50KChTY3JhcFJlZilzY3JhcEhhbmRsZSwgKFVJbnQzMiopc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgaW5mb0NvdW50LCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0U2NyYXBGbGF2b3JJbmZvTGlzdChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQlqaW50IHNjcmFwSGFuZGxlLCBqaW50QXJyYXkgaW5mb0NvdW50LCBqaW50QXJyYXkgaW5mbykgewotCWppbnQgc3RhdHVzOwotCWppbnQgKnNhPSBOVUxMOwotCWppbnQgKnNiPSBOVUxMOwotCWlmIChpbmZvQ291bnQgIT0gTlVMTCkKLQkJc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGluZm9Db3VudCwgMCk7Ci0JaWYgKGluZm8gIT0gTlVMTCkKLQkJc2I9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGluZm8sIDApOwotCQkKLQlzdGF0dXM9IFJDKEdldFNjcmFwRmxhdm9ySW5mb0xpc3QoKFNjcmFwUmVmKXNjcmFwSGFuZGxlLCAoVUludDMyKikgc2EsIChTY3JhcEZsYXZvckluZm8qKSBzYikpOwotCWlmIChzYSAhPSBOVUxMKQotCQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgaW5mb0NvdW50LCBzYSwgMCk7Ci0JaWYgKHNiICE9IE5VTEwpCi0JCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBpbmZvLCBzYiwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKLX0KLQotLy8tLS0tIE1pc2MgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0KLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0luaXQoSk5JRW52ICplbnYsIGpjbGFzcyB6eikgewotCS8vIHdvcmthcm91bmQgZm9yIFJlZ2lzdGVyIHByb2JsZW0KLQlSZWN0IGJvdW5kcz0ge307Ci0JQ29udHJvbFJlZiBjdGw7Ci0JQ3JlYXRlUHVzaEJ1dHRvbkNvbnRyb2woTlVMTCwgJmJvdW5kcywgTlVMTCwgJmN0bCk7Ci0JRGlzcG9zZUNvbnRyb2woY3RsKTsKLX0KKyNpZm5kZWYgTk9fSW5pdEN1cnNvcgorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW5pdEN1cnNvcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiSW5pdEN1cnNvclxuIikKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW5pdEN1cnNvcihKTklFbnYgKmVudiwgamNsYXNzIHp6KSB7CiAJSW5pdEN1cnNvcigpOwogfQorI2VuZGlmIC8qIE5PX0luaXRDdXJzb3IgKi8KIAotSk5JRVhQT1JUIGpzaG9ydCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19IaVdvcmQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBpKSB7Ci0JcmV0dXJuIEhpV29yZChpKTsKLX0KKyNpZm5kZWYgTk9fSW5pdERhdGFCcm93c2VyQ2FsbGJhY2tzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Jbml0RGF0YUJyb3dzZXJDYWxsYmFja3MKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzApCit7CisJRGF0YUJyb3dzZXJDYWxsYmFja3MgX2FyZzA9ezB9LCAqbHBhcmcwPU5VTEw7CisJamludCByYzsKIAotSk5JRVhQT1JUIGpzaG9ydCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Mb1dvcmQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwgamludCBpKSB7Ci0JcmV0dXJuIExvV29yZChpKTsKLX0KKwlERUJVR19DQUxMKCJJbml0RGF0YUJyb3dzZXJDYWxsYmFja3NcbiIpCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1N5c0JlZXAoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwganNob3J0IGR1cmF0aW9uKSB7Ci0JU3lzQmVlcCgoc2hvcnQpZHVyYXRpb24pOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXREYmxUaW1lKEpOSUVudiAqZW52LCBqY2xhc3MgenopIHsKLQlyZXR1cm4gR2V0RGJsVGltZSgpOwotfQotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDYXJldFRpbWUoSk5JRW52ICplbnYsIGpjbGFzcyB6eikgewotCXJldHVybiBHZXRDYXJldFRpbWUoKTsKLX0KLQotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0QXZhaWxhYmxlV2luZG93UG9zaXRpb25pbmdCb3VuZHMoSk5JRW52ICplbnYsCi0JCQkJamNsYXNzIHp6LCBqaW50IGdIYW5kbGUsIGpzaG9ydEFycmF5IGJvdW5kcykgewotCWpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYm91bmRzLCAwKTsKLQlqaW50IHJjPSBSQyhHZXRBdmFpbGFibGVXaW5kb3dQb3NpdGlvbmluZ0JvdW5kcygoR0RIYW5kbGUpIGdIYW5kbGUsIChSZWN0KilzYSkpOwotCSgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGJvdW5kcywgc2EsIDApOworCWlmIChhcmcwKSBscGFyZzAgPSBnZXREYXRhQnJvd3NlckNhbGxiYWNrc0ZpZWxkcyhlbnYsIGFyZzAsICZfYXJnMCk7CisJcmMgPSAoamludClJbml0RGF0YUJyb3dzZXJDYWxsYmFja3MoKERhdGFCcm93c2VyQ2FsbGJhY2tzICopbHBhcmcwKTsKKwlpZiAoYXJnMCkgc2V0RGF0YUJyb3dzZXJDYWxsYmFja3NGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOwogCXJldHVybiByYzsKIH0KKyNlbmRpZiAvKiBOT19Jbml0RGF0YUJyb3dzZXJDYWxsYmFja3MgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfR2V0SWNvblJlZihKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJanNob3J0IHZSZWZOdW0sIGppbnQgY3JlYXRvciwgamludCBpY29uVHlwZSwgamludEFycmF5IGljb25SZWYpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgaWNvblJlZiwgMCk7Ci0JamludCByYz0gUkMoR2V0SWNvblJlZih2UmVmTnVtLCAoT1NUeXBlKWNyZWF0b3IsIChPU1R5cGUpaWNvblR5cGUsIChJY29uUmVmKilzYSkpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBpY29uUmVmLCBzYSwgMCk7CisjaWZuZGVmIE5PX0luaXREYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrcworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW5pdERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwKQoreworCURhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzIF9hcmcwLCAqbHBhcmcwPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIkluaXREYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc1xuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXREYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrc0ZpZWxkcyhlbnYsIGFyZzAsICZfYXJnMCk7CisJcmMgPSAoamludClJbml0RGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3MobHBhcmcwKTsKKwlpZiAoYXJnMCkgc2V0RGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3NGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOwogCXJldHVybiByYzsKIH0KKyNlbmRpZgogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19HZXRDdXJyZW50UHJvY2VzcyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludEFycmF5IHBzbikgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBwc24sIDApOwotCWppbnQgc3RhdHVzPSAoamludCkgR2V0Q3VycmVudFByb2Nlc3MoKFByb2Nlc3NTZXJpYWxOdW1iZXJQdHIpc2EpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBwc24sIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOworI2lmbmRlZiBOT19JbnNlcnRNZW51CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19JbnNlcnRNZW51CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJJbnNlcnRNZW51XG4iKQorCisJSW5zZXJ0TWVudSgoTWVudVJlZilhcmcwLCAoTWVudUlEKWFyZzEpOwogfQorI2VuZGlmIC8qIE5PX0luc2VydE1lbnUgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RnJvbnRQcm9jZXNzKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50QXJyYXkgcHNuKSB7Ci0JamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIHBzbiwgMCk7Ci0JamludCBzdGF0dXM9IChqaW50KSBTZXRGcm9udFByb2Nlc3MoKFByb2Nlc3NTZXJpYWxOdW1iZXJQdHIpc2EpOwotCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBwc24sIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOworI2lmbmRlZiBOT19JbnNlcnRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0luc2VydE1lbnVJdGVtVGV4dFdpdGhDRlN0cmluZworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqc2hvcnQgYXJnMiwgamludCBhcmczLCBqaW50IGFyZzQpCit7CisJREVCVUdfQ0FMTCgiSW5zZXJ0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nXG4iKQorCisJcmV0dXJuIChqaW50KUluc2VydE1lbnVJdGVtVGV4dFdpdGhDRlN0cmluZygoTWVudVJlZilhcmcwLCAoQ0ZTdHJpbmdSZWYpYXJnMSwgKE1lbnVJdGVtSW5kZXgpYXJnMiwgKE1lbnVJdGVtQXR0cmlidXRlcylhcmczLCAoTWVudUNvbW1hbmQpYXJnNCk7CiB9CisjZW5kaWYgLyogTk9fSW5zZXJ0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nICovCiAKLS8vLS0tLSB1dGlsaXRpZXMKKyNpZm5kZWYgTk9fSW5zdGFsbEV2ZW50SGFuZGxlcgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW5zdGFsbEV2ZW50SGFuZGxlcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnRBcnJheSBhcmczLCBqaW50IGFyZzQsIGppbnRBcnJheSBhcmc1KQoreworCWppbnQgKmxwYXJnMz1OVUxMOworCWppbnQgKmxwYXJnNT1OVUxMOworCWppbnQgcmM7CiAKLXN0YXRpYyBQb2ludCBwb2ludChKTklFbnYgKmVudiwganNob3J0QXJyYXkgYSkgewotCVBvaW50IHA7Ci0JanNob3J0ICpzYT0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhLCAwKTsKLQlwLnY9IHNhWzBdOwotCXAuaD0gc2FbMV07Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgYSwgc2EsIDApOwotCXJldHVybiBwOworCURFQlVHX0NBTEwoIkluc3RhbGxFdmVudEhhbmRsZXJcbiIpCisKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJaWYgKGFyZzUpIGxwYXJnNSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIE5VTEwpOworCXJjID0gKGppbnQpSW5zdGFsbEV2ZW50SGFuZGxlcigoRXZlbnRUYXJnZXRSZWYpYXJnMCwgKEV2ZW50SGFuZGxlclVQUClhcmcxLCAoVUludDMyKWFyZzIsIChjb25zdCBFdmVudFR5cGVTcGVjICopbHBhcmczLCAodm9pZCAqKWFyZzQsIChFdmVudEhhbmRsZXJSZWYgKilscGFyZzUpOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlpZiAoYXJnNSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIGxwYXJnNSwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmIC8qIE5PX0luc3RhbGxFdmVudEhhbmRsZXIgKi8KIAotc3RhdGljIHZvaWQgY29weUV2ZW50KEpOSUVudiAqZW52LCBqaW50QXJyYXkgZURhdGEsIEV2ZW50UmVjb3JkICpldmVudCkgewotCWlmIChlRGF0YSAhPSBOVUxMKSB7Ci0JCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBlRGF0YSwgMCk7Ci0JCXNhWzBdPSAoaW50KSBldmVudC0+d2hhdDsKLQkJc2FbMV09IChpbnQpIGV2ZW50LT5tZXNzYWdlOwotCQlzYVsyXT0gKGludCkgZXZlbnQtPndoZW47Ci0JCXNhWzNdPSAoaW50KSBldmVudC0+d2hlcmUudjsKLQkJc2FbNF09IChpbnQpIGV2ZW50LT53aGVyZS5oOwotCQlzYVs1XT0gKGludCkgZXZlbnQtPm1vZGlmaWVyczsKLQkJKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGVEYXRhLCBzYSwgMCk7Ci0JfQorI2lmbmRlZiBOT19JbnN0YWxsRXZlbnRMb29wVGltZXIKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0luc3RhbGxFdmVudExvb3BUaW1lcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamRvdWJsZSBhcmcxLCBqZG91YmxlIGFyZzIsIGppbnQgYXJnMywgamludCBhcmc0LCBqaW50QXJyYXkgYXJnNSkKK3sKKwlqaW50ICpscGFyZzU9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiSW5zdGFsbEV2ZW50TG9vcFRpbWVyXG4iKQorCisJaWYgKGFyZzUpIGxwYXJnNSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIE5VTEwpOworCXJjID0gKGppbnQpSW5zdGFsbEV2ZW50TG9vcFRpbWVyKChFdmVudExvb3BSZWYpYXJnMCwgKEV2ZW50VGltZXJJbnRlcnZhbClhcmcxLCAoRXZlbnRUaW1lckludGVydmFsKWFyZzIsIChFdmVudExvb3BUaW1lclVQUClhcmczLCAodm9pZCAqKWFyZzQsIChFdmVudExvb3BUaW1lclJlZiAqKWxwYXJnNSk7CisJaWYgKGFyZzUpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBscGFyZzUsIDApOworCXJldHVybiByYzsKIH0KKyNlbmRpZiAvKiBOT19JbnN0YWxsRXZlbnRMb29wVGltZXIgKi8KIAotc3RhdGljIHZvaWQgY29weUV2ZW50RGF0YShKTklFbnYgKmVudiwgRXZlbnRSZWNvcmQgKmV2ZW50LCBqaW50QXJyYXkgZURhdGEpIHsKLQlpZiAoZURhdGEgIT0gTlVMTCkgewotCQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgZURhdGEsIDApOwotCQlldmVudC0+d2hhdD0gKHNob3J0KSBzYVswXTsKLQkJZXZlbnQtPm1lc3NhZ2U9IHNhWzFdOwotCQlldmVudC0+d2hlbj0gc2FbMl07Ci0JCWV2ZW50LT53aGVyZS52PSAoc2hvcnQpIHNhWzNdOwotCQlldmVudC0+d2hlcmUuaD0gKHNob3J0KSBzYVs0XTsKLQkJZXZlbnQtPm1vZGlmaWVycz0gc2FbNV07Ci0JCSgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBlRGF0YSwgc2EsIDApOwkKLQl9CisjaWZuZGVmIE5PX0ludmFsV2luZG93UmVjdAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW52YWxXaW5kb3dSZWN0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEpCit7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgiSW52YWxXaW5kb3dSZWN0XG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCUludmFsV2luZG93UmVjdCgoV2luZG93UmVmKWFyZzAsIChjb25zdCBSZWN0ICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fSW52YWxXaW5kb3dSZWN0ICovCiAKLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLS8vIEphZ3VhcgotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworI2lmbmRlZiBOT19JbnZhbFdpbmRvd1JnbgorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW52YWxXaW5kb3dSZ24KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJJbnZhbFdpbmRvd1JnblxuIikKIAotLy8vLyBISU9iamVjdAotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISU9iamVjdFJlZ2lzdGVyU3ViY2xhc3MoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5DbGFzc0lELAotCQkJamludCBpbkJhc2VDbGFzc0lELAotCQkJamludCBpbk9wdGlvbnMsCi0JCQlqaW50IGluQ29uc3RydWN0UHJvYywKLQkJCWppbnRBcnJheSBpbkV2ZW50TGlzdCwKLQkJCWppbnQgaW5Db25zdHJ1Y3REYXRhLAotCQkJamludEFycmF5IG91dENsYXNzUmVmKSB7Ci0JCQkJCi0JamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGluRXZlbnRMaXN0LCAwKTsKLQlqc2l6ZSBsZW5ndGg9ICgqZW52KS0+R2V0QXJyYXlMZW5ndGgoZW52LCBpbkV2ZW50TGlzdCk7Ci0JCi0JamludCAqc2I9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIG91dENsYXNzUmVmLCAwKTsKLQlqaW50IHN0YXR1czsKLQkJCi0Jc3RhdHVzPSBSQyhISU9iamVjdFJlZ2lzdGVyU3ViY2xhc3MoCi0JIAkJKENGU3RyaW5nUmVmKSBpbkNsYXNzSUQsCi0JIAkJKENGU3RyaW5nUmVmKSBpbkJhc2VDbGFzc0lELAotCQkJKE9wdGlvbkJpdHMpIGluT3B0aW9ucywKLQkgCQkoRXZlbnRIYW5kbGVyVVBQKSBpbkNvbnN0cnVjdFByb2MsCi0JIAkJKFVJbnQzMikgKGxlbmd0aC8yKSwKLQkgCQkoY29uc3QgRXZlbnRUeXBlU3BlYyopIHNhLAotCSAJCU5VTEwsIC8vICh2b2lkKikgaW5Db25zdHJ1Y3REYXRhLAotCSAJCShISU9iamVjdENsYXNzUmVmKikgc2IpKTsKLQkJCQkKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgaW5FdmVudExpc3QsIHNhLCAwKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0Q2xhc3NSZWYsIHNiLCAwKTsKLQotCXJldHVybiBzdGF0dXM7CisJSW52YWxXaW5kb3dSZ24oKFdpbmRvd1JlZilhcmcwLCAoUmduSGFuZGxlKWFyZzEpOwogfQorI2VuZGlmIC8qIE5PX0ludmFsV2luZG93UmduICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJT2JqZWN0Q3JlYXRlKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGluQ2xhc3NJRCwgamludCBpbkNvbnN0cnVjdERhdGEsIGppbnRBcnJheSBvdXRPYmplY3QpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0T2JqZWN0LCAwKTsKLQlqaW50IHN0YXR1cz0gUkMoSElPYmplY3RDcmVhdGUoKENGU3RyaW5nUmVmKWluQ2xhc3NJRCwgKEV2ZW50UmVmKSBpbkNvbnN0cnVjdERhdGEsIChISU9iamVjdFJlZiopc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0T2JqZWN0LCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKKyNpZm5kZWYgTk9fSW52ZXJ0UmVjdAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSW52ZXJ0UmVjdAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCkKK3sKKwlSZWN0IF9hcmcwLCAqbHBhcmcwPU5VTEw7CisKKwlERUJVR19DQUxMKCJJbnZlcnRSZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCUludmVydFJlY3QoKGNvbnN0IFJlY3QgKilscGFyZzApOworCWlmIChhcmcwKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgbHBhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19JbnZlcnRSZWN0ICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJT2JqZWN0Q29weUNsYXNzSUQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5PYmplY3QpIHsKLQlyZXR1cm4oamludCkgSElPYmplY3RDb3B5Q2xhc3NJRCgoSElPYmplY3RSZWYpaW5PYmplY3QpOworI2lmbmRlZiBOT19JbnZlcnRSZ24KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0ludmVydFJnbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJJbnZlcnRSZ25cbiIpCisKKwlJbnZlcnRSZ24oKFJnbkhhbmRsZSlhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19JbnZlcnRSZ24gKi8KIAorI2lmbmRlZiBOT19Jc0NvbnRyb2xBY3RpdmUKK0pOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Jc0NvbnRyb2xBY3RpdmUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiSXNDb250cm9sQWN0aXZlXG4iKQogCi0vLy8vIEhJVmlldwotCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdBZGRTdWJ2aWV3KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGluUGFyZW50LCBqaW50IGluTmV3Q2hpbGQpIHsKLQlyZXR1cm4gUkMoSElWaWV3QWRkU3VidmlldygoSElWaWV3UmVmKWluUGFyZW50LCAoSElWaWV3UmVmKSBpbk5ld0NoaWxkKSk7CisJcmV0dXJuIChqYm9vbGVhbilJc0NvbnRyb2xBY3RpdmUoKENvbnRyb2xSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fSXNDb250cm9sQWN0aXZlICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJVmlld1JlbW92ZUZyb21TdXBlcnZpZXcoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5WaWV3KSB7Ci0JcmV0dXJuIFJDKEhJVmlld1JlbW92ZUZyb21TdXBlcnZpZXcoKEhJVmlld1JlZikgaW5WaWV3KSk7CisjaWZuZGVmIE5PX0lzQ29udHJvbEVuYWJsZWQKK0pOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Jc0NvbnRyb2xFbmFibGVkCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIklzQ29udHJvbEVuYWJsZWRcbiIpCisKKwlyZXR1cm4gKGpib29sZWFuKUlzQ29udHJvbEVuYWJsZWQoKENvbnRyb2xSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fSXNDb250cm9sRW5hYmxlZCAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdTZXREcmF3aW5nRW5hYmxlZChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpblZpZXcsIGpib29sZWFuIGluRW5hYmxlZCkgewotCXJldHVybiBSQyhISVZpZXdTZXREcmF3aW5nRW5hYmxlZCgoSElWaWV3UmVmKWluVmlldywgKEJvb2xlYW4pIGluRW5hYmxlZCkpOworI2lmbmRlZiBOT19Jc0NvbnRyb2xWaXNpYmxlCitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSXNDb250cm9sVmlzaWJsZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJJc0NvbnRyb2xWaXNpYmxlXG4iKQorCisJcmV0dXJuIChqYm9vbGVhbilJc0NvbnRyb2xWaXNpYmxlKChDb250cm9sUmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0lzQ29udHJvbFZpc2libGUgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3U2ltdWxhdGVDbGljayhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpblZpZXcsIGpzaG9ydCBpblBhcnRUb0NsaWNrLCBqaW50IGluTW9kaWZpZXJzLCBqc2hvcnRBcnJheSBvdXRQYXJ0Q2xpY2tlZCkgewotCWpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgb3V0UGFydENsaWNrZWQsIDApOwotCWppbnQgc3RhdHVzPSBSQyhISVZpZXdTaW11bGF0ZUNsaWNrKChISVZpZXdSZWYpaW5WaWV3LCAoSElWaWV3UGFydENvZGUpaW5QYXJ0VG9DbGljaywgKFVJbnQzMilpbk1vZGlmaWVycywgKENvbnRyb2xQYXJ0Q29kZSopIHNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgb3V0UGFydENsaWNrZWQsIHNhLCAwKTsKLQlyZXR1cm4gc3RhdHVzOworI2lmbmRlZiBOT19Jc0RhdGFCcm93c2VySXRlbVNlbGVjdGVkCitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSXNEYXRhQnJvd3Nlckl0ZW1TZWxlY3RlZAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIklzRGF0YUJyb3dzZXJJdGVtU2VsZWN0ZWRcbiIpCisKKwlyZXR1cm4gKGpib29sZWFuKUlzRGF0YUJyb3dzZXJJdGVtU2VsZWN0ZWQoKENvbnRyb2xSZWYpYXJnMCwgKERhdGFCcm93c2VySXRlbUlEKWFyZzEpOwogfQorI2VuZGlmIC8qIE5PX0lzRGF0YUJyb3dzZXJJdGVtU2VsZWN0ZWQgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3U2V0Wk9yZGVyKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGluVmlldywgamludCBpbk9wLCBqaW50IGluT3RoZXIpIHsKLQlyZXR1cm4gUkMoSElWaWV3U2V0Wk9yZGVyKChISVZpZXdSZWYpaW5WaWV3LCAoSElWaWV3Wk9yZGVyT3ApIGluT3AsIChISVZpZXdSZWYpaW5PdGhlcikpOworI2lmbmRlZiBOT19Jc01lbnVDb21tYW5kRW5hYmxlZAorSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0lzTWVudUNvbW1hbmRFbmFibGVkCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiSXNNZW51Q29tbWFuZEVuYWJsZWRcbiIpCisKKwlyZXR1cm4gKGpib29sZWFuKUlzTWVudUNvbW1hbmRFbmFibGVkKChNZW51UmVmKWFyZzAsIChNZW51Q29tbWFuZClhcmcxKTsKIH0KKyNlbmRpZiAvKiBOT19Jc01lbnVDb21tYW5kRW5hYmxlZCAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdTZXRGcmFtZShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpblZpZXcsIGppbnQgeCwgamludCB5LCBqaW50IHdpZHRoLCBqaW50IGhlaWdodCkgewotCUhJUmVjdCByOwotCXIub3JpZ2luLng9IHg7Ci0Jci5vcmlnaW4ueT0geTsKLQlyLnNpemUud2lkdGg9IHdpZHRoOwotCXIuc2l6ZS5oZWlnaHQ9IGhlaWdodDsKLQlyZXR1cm4gUkMoSElWaWV3U2V0RnJhbWUoKEhJVmlld1JlZilpblZpZXcsIChjb25zdCBISVJlY3QqKSAmcikpOworI2lmbmRlZiBOT19Jc01lbnVJdGVtRW5hYmxlZAorSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0lzTWVudUl0ZW1FbmFibGVkCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJJc01lbnVJdGVtRW5hYmxlZFxuIikKKworCXJldHVybiAoamJvb2xlYW4pSXNNZW51SXRlbUVuYWJsZWQoKE1lbnVSZWYpYXJnMCwgKE1lbnVJdGVtSW5kZXgpYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fSXNNZW51SXRlbUVuYWJsZWQgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3R2V0RnJhbWUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5WaWV3LCBqZmxvYXRBcnJheSBvdXRISVJlY3QpIHsKLQlISVJlY3QgcjsKLQlqaW50IHN0YXR1cz0gUkMoSElWaWV3R2V0RnJhbWUoKEhJVmlld1JlZilpblZpZXcsIChISVJlY3QqKSAmcikpOwotCWpmbG9hdCAqc2E9ICgqZW52KS0+R2V0RmxvYXRBcnJheUVsZW1lbnRzKGVudiwgb3V0SElSZWN0LCAwKTsKLQlzYVswXT0gci5vcmlnaW4ueDsKLQlzYVsxXT0gci5vcmlnaW4ueTsKLQlzYVsyXT0gci5zaXplLndpZHRoOwotCXNhWzNdPSByLnNpemUuaGVpZ2h0OwotCSgqZW52KS0+UmVsZWFzZUZsb2F0QXJyYXlFbGVtZW50cyhlbnYsIG91dEhJUmVjdCwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7CisjaWZuZGVmIE5PX0lzVmFsaWRDb250cm9sSGFuZGxlCitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSXNWYWxpZENvbnRyb2xIYW5kbGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiSXNWYWxpZENvbnRyb2xIYW5kbGVcbiIpCisKKwlyZXR1cm4gKGpib29sZWFuKUlzVmFsaWRDb250cm9sSGFuZGxlKChDb250cm9sUmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0lzVmFsaWRDb250cm9sSGFuZGxlICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJVmlld0NsaWNrKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGluVmlldywgamludCBpbkV2ZW50KSB7Ci0JcmV0dXJuIFJDKEhJVmlld0NsaWNrKChISVZpZXdSZWYpaW5WaWV3LCAoRXZlbnRSZWYpIGluRXZlbnQpKTsKKyNpZm5kZWYgTk9fSXNWYWxpZE1lbnUKK0pOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Jc1ZhbGlkTWVudQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJJc1ZhbGlkTWVudVxuIikKKworCXJldHVybiAoamJvb2xlYW4pSXNWYWxpZE1lbnUoKE1lbnVSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fSXNWYWxpZE1lbnUgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3Q29udmVydFBvaW50KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqZmxvYXRBcnJheSBpb1BvaW50LCBqaW50IGluU291cmNlVmlldywgamludCBpbkRlc3RWaWV3KSB7Ci0JamZsb2F0ICpzYT0gKCplbnYpLT5HZXRGbG9hdEFycmF5RWxlbWVudHMoZW52LCBpb1BvaW50LCAwKTsKLQlISVBvaW50IHB0OwotCXB0Lng9IHNhWzBdOwotCXB0Lnk9IHNhWzFdOwotCWppbnQgc3RhdHVzPSBSQyhISVZpZXdDb252ZXJ0UG9pbnQoKEhJUG9pbnQqKSZwdCwgKEhJVmlld1JlZilpblNvdXJjZVZpZXcsIChISVZpZXdSZWYpIGluRGVzdFZpZXcpKTsKLQlzYVswXT0gcHQueDsKLQlzYVsxXT0gcHQueTsKLQkoKmVudiktPlJlbGVhc2VGbG9hdEFycmF5RWxlbWVudHMoZW52LCBpb1BvaW50LCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKKyNpZm5kZWYgTk9fSXNWYWxpZFdpbmRvd1B0cgorSk5JRVhQT1JUIGpib29sZWFuIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0lzVmFsaWRXaW5kb3dQdHIKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiSXNWYWxpZFdpbmRvd1B0clxuIikKKworCXJldHVybiAoamJvb2xlYW4pSXNWYWxpZFdpbmRvd1B0cigoV2luZG93UmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX0lzVmFsaWRXaW5kb3dQdHIgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3R2V0Um9vdChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpbldpbmRvdykgewotCXJldHVybiAoamludCkgSElWaWV3R2V0Um9vdCgoV2luZG93UmVmKSBpbldpbmRvdyk7CisjaWZuZGVmIE5PX0lzV2luZG93QWN0aXZlCitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSXNXaW5kb3dBY3RpdmUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiSXNXaW5kb3dBY3RpdmVcbiIpCisKKwlyZXR1cm4gKGpib29sZWFuKUlzV2luZG93QWN0aXZlKChXaW5kb3dSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fSXNXaW5kb3dBY3RpdmUgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3U2V0TmVlZHNEaXNwbGF5SW5SZWdpb24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5WaWV3LCBqaW50IGluUmduLCBqYm9vbGVhbiBpbk5lZWRzRGlzcGxheSkgewotCXJldHVybiBSQyhISVZpZXdTZXROZWVkc0Rpc3BsYXlJblJlZ2lvbigoSElWaWV3UmVmKSBpblZpZXcsIChSZ25IYW5kbGUpIGluUmduLCAoQm9vbGVhbikgaW5OZWVkc0Rpc3BsYXkpKTsKKyNpZm5kZWYgTk9fSXNXaW5kb3dDb2xsYXBzZWQKK0pOSUVYUE9SVCBqYm9vbGVhbiBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Jc1dpbmRvd0NvbGxhcHNlZAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJJc1dpbmRvd0NvbGxhcHNlZFxuIikKKworCXJldHVybiAoamJvb2xlYW4pSXNXaW5kb3dDb2xsYXBzZWQoKFdpbmRvd1JlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19Jc1dpbmRvd0NvbGxhcHNlZCAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdTZXROZWVkc0Rpc3BsYXkoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5WaWV3LCBqYm9vbGVhbiBpbk5lZWRzRGlzcGxheSkgewotCXJldHVybiBSQyhISVZpZXdTZXROZWVkc0Rpc3BsYXkoKEhJVmlld1JlZikgaW5WaWV3LCAoQm9vbGVhbikgaW5OZWVkc0Rpc3BsYXkpKTsKKyNpZm5kZWYgTk9fSXNXaW5kb3dWaXNpYmxlCitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSXNXaW5kb3dWaXNpYmxlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIklzV2luZG93VmlzaWJsZVxuIikKKworCXJldHVybiAoamJvb2xlYW4pSXNXaW5kb3dWaXNpYmxlKChXaW5kb3dSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fSXNXaW5kb3dWaXNpYmxlICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJVmlld1NldFZpc2libGUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5WaWV3LCBqYm9vbGVhbiBpblZpc2libGUpIHsKLQlyZXR1cm4gUkMoSElWaWV3U2V0VmlzaWJsZSgoSElWaWV3UmVmKSBpblZpZXcsIChCb29sZWFuKSBpblZpc2libGUpKTsKKyNpZm5kZWYgTk9fS2lsbFBvbHkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0tpbGxQb2x5CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIktpbGxQb2x5XG4iKQorCisJS2lsbFBvbHkoKFBvbHlIYW5kbGUpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fS2lsbFBvbHkgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElWaWV3Q2hhbmdlQXR0cmlidXRlcyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpblZpZXcsIGppbnQgaW5BdHRyc1RvU2V0LCBqaW50IGluQXR0cnNUb0NsZWFyKSB7Ci0JcmV0dXJuIFJDKEhJVmlld0NoYW5nZUF0dHJpYnV0ZXMoKEhJVmlld1JlZikgaW5WaWV3LCAoT3B0aW9uQml0cykgaW5BdHRyc1RvU2V0LCAoT3B0aW9uQml0cykgaW5BdHRyc1RvQ2xlYXIpKTsKKyNpZm5kZWYgTk9fTGluZVRvCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19MaW5lVG8KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqc2hvcnQgYXJnMCwganNob3J0IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiTGluZVRvXG4iKQorCisJTGluZVRvKChzaG9ydClhcmcwLCAoc2hvcnQpYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fTGluZVRvICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJVmlld0ZpbmRCeUlEKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGluU3RhcnRWaWV3LCBqaW50IGluSUQsIGppbnRBcnJheSBvdXRDb250cm9sKSB7Ci0JamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIG91dENvbnRyb2wsIDApOwotCWppbnQgc3RhdHVzPSBSQyhISVZpZXdGaW5kQnlJRCgoSElWaWV3UmVmKSBpblN0YXJ0VmlldywgKEhJVmlld0lEKSBrSElWaWV3V2luZG93Q29udGVudElELCAoSElWaWV3UmVmKikgc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0Q29udHJvbCwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7CisjaWZuZGVmIE5PX0xvV29yZAorSk5JRVhQT1JUIGpzaG9ydCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Mb1dvcmQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiTG9Xb3JkXG4iKQorCisJcmV0dXJuIChqc2hvcnQpTG9Xb3JkKGFyZzApOwogfQorI2VuZGlmIC8qIE5PX0xvV29yZCAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISVZpZXdHZXRWaWV3Rm9yTW91c2VFdmVudChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpblZpZXcsIGppbnQgaW5FdmVudCwgamludEFycmF5IG91dFZpZXcpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0VmlldywgMCk7Ci0JamludCBzdGF0dXM9IFJDKEhJVmlld0dldFZpZXdGb3JNb3VzZUV2ZW50KChISVZpZXdSZWYpIGluVmlldywgKEV2ZW50UmVmKSBpbkV2ZW50LCAoSElWaWV3UmVmKikgc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0Vmlldywgc2EsIDApOwotCXJldHVybiBzdGF0dXM7CisjaWZuZGVmIE5PX0xvY2tQb3J0Qml0cworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTG9ja1BvcnRCaXRzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIkxvY2tQb3J0Qml0c1xuIikKKworCXJldHVybiAoamludClMb2NrUG9ydEJpdHMoKEdyYWZQdHIpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fTG9ja1BvcnRCaXRzICovCiAKLS8vLy8vLy8KKyNpZm5kZWYgTk9fTWVudVNlbGVjdAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTWVudVNlbGVjdAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCkKK3sKKwlQb2ludCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCWppbnQgcmM7CiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJQ29tYm9Cb3hDcmVhdGUoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnRBcnJheSBvdXRDb21ib0JveCwgamludCBhdHRyaWJ1dGVzKSB7Ci0JSElSZWN0IHI9IHt9OwotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBvdXRDb21ib0JveCwgMCk7Ci0JamludCBzdGF0dXM9IFJDKEhJQ29tYm9Cb3hDcmVhdGUoJnIsIE5VTEwsIE5VTEwsIE5VTEwsIChPcHRpb25CaXRzKWF0dHJpYnV0ZXMsIChISVZpZXdSZWYqKXNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIG91dENvbWJvQm94LCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKKwlERUJVR19DQUxMKCJNZW51U2VsZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFBvaW50RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlyYyA9IChqaW50KU1lbnVTZWxlY3QoKFBvaW50KSpscGFyZzApOworCWlmIChhcmcwKSBzZXRQb2ludEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmIC8qIE5PX01lbnVTZWxlY3QgKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElDb21ib0JveEdldEl0ZW1Db3VudChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpbkNvbWJvQm94KSB7Ci0JcmV0dXJuIChqaW50KSBISUNvbWJvQm94R2V0SXRlbUNvdW50KChISVZpZXdSZWYpaW5Db21ib0JveCk7CisjaWZuZGVmIE5PX01vdmVDb250cm9sCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Nb3ZlQ29udHJvbAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGpzaG9ydCBhcmcyKQoreworCURFQlVHX0NBTEwoIk1vdmVDb250cm9sXG4iKQorCisJTW92ZUNvbnRyb2woKENvbnRyb2xSZWYpYXJnMCwgKFNJbnQxNilhcmcxLCAoU0ludDE2KWFyZzIpOwogfQorI2VuZGlmIC8qIE5PX01vdmVDb250cm9sICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJQ29tYm9Cb3hBcHBlbmRUZXh0SXRlbShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpblZpZXcsIGppbnQgaW5UZXh0KSB7Ci0JcmV0dXJuIFJDKEhJQ29tYm9Cb3hBcHBlbmRUZXh0SXRlbSgoSElWaWV3UmVmKWluVmlldywgKENGU3RyaW5nUmVmKSBpblRleHQsIChDRkluZGV4KikgTlVMTCkpOworI2lmbmRlZiBOT19Nb3ZlVG8KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX01vdmVUbworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpzaG9ydCBhcmcwLCBqc2hvcnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJNb3ZlVG9cbiIpCisKKwlNb3ZlVG8oKHNob3J0KWFyZzAsIChzaG9ydClhcmcxKTsKIH0KKyNlbmRpZiAvKiBOT19Nb3ZlVG8gKi8KIAotSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfSElDb21ib0JveEluc2VydFRleHRJdGVtQXRJbmRleChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpblZpZXcsIGppbnQgaW5JbmRleCwgamludCBpblRleHQpIHsKLQlyZXR1cm4gUkMoSElDb21ib0JveEluc2VydFRleHRJdGVtQXRJbmRleCgoSElWaWV3UmVmKWluVmlldywgKENGSW5kZXgpIGluSW5kZXgsIChDRlN0cmluZ1JlZikgaW5UZXh0KSk7CisjaWZuZGVmIE5PX01vdmVXaW5kb3cKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX01vdmVXaW5kb3cKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxLCBqc2hvcnQgYXJnMiwgamJvb2xlYW4gYXJnMykKK3sKKwlERUJVR19DQUxMKCJNb3ZlV2luZG93XG4iKQorCisJTW92ZVdpbmRvdygoV2luZG93UmVmKWFyZzAsIChzaG9ydClhcmcxLCAoc2hvcnQpYXJnMiwgKEJvb2xlYW4pYXJnMyk7CiB9CisjZW5kaWYgLyogTk9fTW92ZVdpbmRvdyAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ISUNvbWJvQm94UmVtb3ZlSXRlbUF0SW5kZXgoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5WaWV3LCBqaW50IGluSW5kZXgpIHsKLQlyZXR1cm4gUkMoSElDb21ib0JveFJlbW92ZUl0ZW1BdEluZGV4KChISVZpZXdSZWYpaW5WaWV3LCAoQ0ZJbmRleCkgaW5JbmRleCkpOworI2lmbmRlZiBOT19OYXZDcmVhdGVDaG9vc2VGb2xkZXJEaWFsb2cKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05hdkNyZWF0ZUNob29zZUZvbGRlckRpYWxvZworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMywgamludEFycmF5IGFyZzQpCit7CisJTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zIF9hcmcwLCAqbHBhcmcwPU5VTEw7CisJamludCAqbHBhcmc0PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIk5hdkNyZWF0ZUNob29zZUZvbGRlckRpYWxvZ1xuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXROYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCWlmIChhcmc0KSBscGFyZzQgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlyYyA9IChqaW50KU5hdkNyZWF0ZUNob29zZUZvbGRlckRpYWxvZygoY29uc3QgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zICopbHBhcmcwLCAoTmF2RXZlbnRVUFApYXJnMSwgKE5hdk9iamVjdEZpbHRlclVQUClhcmcyLCAodm9pZCAqKWFyZzMsIChOYXZEaWFsb2dSZWYgKilscGFyZzQpOworCWlmIChhcmcwKSBzZXROYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworCWlmIChhcmc0KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNCwgbHBhcmc0LCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fTmF2Q3JlYXRlQ2hvb3NlRm9sZGVyRGlhbG9nICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0hJQ29tYm9Cb3hDb3B5VGV4dEl0ZW1BdEluZGV4KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGluVmlldywgamludCBpbkluZGV4LCBqaW50QXJyYXkgb3V0U3RyaW5nKSB7Ci0JamludCAqc2E9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIG91dFN0cmluZywgMCk7Ci0JamludCBzdGF0dXM9IFJDKEhJQ29tYm9Cb3hDb3B5VGV4dEl0ZW1BdEluZGV4KChISVZpZXdSZWYpaW5WaWV3LCAoQ0ZJbmRleCkgaW5JbmRleCwgKENGU3RyaW5nUmVmKikgc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0U3RyaW5nLCBzYSwgMCk7Ci0JcmV0dXJuIHN0YXR1czsKKyNpZm5kZWYgTk9fTmF2Q3JlYXRlR2V0RmlsZURpYWxvZworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmF2Q3JlYXRlR2V0RmlsZURpYWxvZworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMywgamludCBhcmc0LCBqaW50IGFyZzUsIGppbnRBcnJheSBhcmc2KQoreworCU5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucyBfYXJnMCwgKmxwYXJnMD1OVUxMOworCWppbnQgKmxwYXJnNj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJOYXZDcmVhdGVHZXRGaWxlRGlhbG9nXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9uc0ZpZWxkcyhlbnYsIGFyZzAsICZfYXJnMCk7CisJaWYgKGFyZzYpIGxwYXJnNiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzYsIE5VTEwpOworCXJjID0gKGppbnQpTmF2Q3JlYXRlR2V0RmlsZURpYWxvZygoY29uc3QgTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zICopbHBhcmcwLCAoTmF2VHlwZUxpc3RIYW5kbGUpYXJnMSwgKE5hdkV2ZW50VVBQKWFyZzIsIChOYXZQcmV2aWV3VVBQKWFyZzMsIChOYXZPYmplY3RGaWx0ZXJVUFApYXJnNCwgKHZvaWQgKilhcmc1LCAoTmF2RGlhbG9nUmVmICopbHBhcmc2KTsKKwlpZiAoYXJnMCkgc2V0TmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmllbGRzKGVudiwgYXJnMCwgbHBhcmcwKTsKKwlpZiAoYXJnNikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzYsIGxwYXJnNiwgMCk7CisJcmV0dXJuIHJjOwogfQorI2VuZGlmIC8qIE5PX05hdkNyZWF0ZUdldEZpbGVEaWFsb2cgKi8KIAotLy8gY29yZSBncmFwaGljcworI2lmbmRlZiBOT19OYXZDcmVhdGVQdXRGaWxlRGlhbG9nCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OYXZDcmVhdGVQdXRGaWxlRGlhbG9nCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqaW50IGFyZzQsIGppbnRBcnJheSBhcmc1KQoreworCU5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucyBfYXJnMCwgKmxwYXJnMD1OVUxMOworCWppbnQgKmxwYXJnNT1OVUxMOworCWppbnQgcmM7CiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1FEQmVnaW5DR0NvbnRleHQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5Qb3J0LCBqaW50QXJyYXkgb3V0Q29udGV4dCkgewotCWppbnQgKnNhPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBvdXRDb250ZXh0LCAwKTsKLQlqaW50IHN0YXR1cz0gUkMoUURCZWdpbkNHQ29udGV4dCgoQ0dyYWZQdHIpaW5Qb3J0LCAoQ0dDb250ZXh0UmVmKikgc2EpKTsKLQkoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgb3V0Q29udGV4dCwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7CisJREVCVUdfQ0FMTCgiTmF2Q3JlYXRlUHV0RmlsZURpYWxvZ1xuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXROYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCWlmIChhcmc1KSBscGFyZzUgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBOVUxMKTsKKwlyYyA9IChqaW50KU5hdkNyZWF0ZVB1dEZpbGVEaWFsb2coKGNvbnN0IE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucyAqKWxwYXJnMCwgKE9TVHlwZSlhcmcxLCAoT1NUeXBlKWFyZzIsIChOYXZFdmVudFVQUClhcmczLCAodm9pZCAqKWFyZzQsIChOYXZEaWFsb2dSZWYgKilscGFyZzUpOworCWlmIChhcmcwKSBzZXROYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworCWlmIChhcmc1KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNSwgbHBhcmc1LCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fTmF2Q3JlYXRlUHV0RmlsZURpYWxvZyAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19RREVuZENHQ29udGV4dChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpblBvcnQsIGppbnRBcnJheSBpbm91dENvbnRleHQpIHsKLQlqaW50ICpzYT0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgaW5vdXRDb250ZXh0LCAwKTsKLQlqaW50IHN0YXR1cz0gUkMoUURFbmRDR0NvbnRleHQoKENHcmFmUHRyKWluUG9ydCwgKENHQ29udGV4dFJlZiopIHNhKSk7Ci0JKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGlub3V0Q29udGV4dCwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7CisjaWZuZGVmIE5PX05hdkRpYWxvZ0Rpc3Bvc2UKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05hdkRpYWxvZ0Rpc3Bvc2UKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiTmF2RGlhbG9nRGlzcG9zZVxuIikKKworCU5hdkRpYWxvZ0Rpc3Bvc2UoKE5hdkRpYWxvZ1JlZilhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19OYXZEaWFsb2dEaXNwb3NlICovCiAKLUpOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1N5bmNDR0NvbnRleHRPcmlnaW5XaXRoUG9ydChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpbkNvbnRleHQsIGppbnQgcG9ydCkgewotCXJldHVybiBSQyhTeW5jQ0dDb250ZXh0T3JpZ2luV2l0aFBvcnQoKENHQ29udGV4dFJlZilpbkNvbnRleHQsIChDR3JhZlB0cikgcG9ydCkpOworI2lmbmRlZiBOT19OYXZEaWFsb2dHZXRSZXBseQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmF2RGlhbG9nR2V0UmVwbHkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlOYXZSZXBseVJlY29yZCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJOYXZEaWFsb2dHZXRSZXBseVxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXROYXZSZXBseVJlY29yZEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJcmMgPSAoamludClOYXZEaWFsb2dHZXRSZXBseSgoTmF2RGlhbG9nUmVmKWFyZzAsIChOYXZSZXBseVJlY29yZCAqKWxwYXJnMSk7CisJaWYgKGFyZzEpIHNldE5hdlJlcGx5UmVjb3JkRmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fTmF2RGlhbG9nR2V0UmVwbHkgKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0U2F2ZUdTdGF0ZShKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpbkNvbnRleHQpIHsKLQlDR0NvbnRleHRTYXZlR1N0YXRlKChDR0NvbnRleHRSZWYpaW5Db250ZXh0KTsKKyNpZm5kZWYgTk9fTmF2RGlhbG9nR2V0U2F2ZUZpbGVOYW1lCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OYXZEaWFsb2dHZXRTYXZlRmlsZU5hbWUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiTmF2RGlhbG9nR2V0U2F2ZUZpbGVOYW1lXG4iKQorCisJcmV0dXJuIChqaW50KU5hdkRpYWxvZ0dldFNhdmVGaWxlTmFtZSgoTmF2RGlhbG9nUmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX05hdkRpYWxvZ0dldFNhdmVGaWxlTmFtZSAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRSZXN0b3JlR1N0YXRlKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGluQ29udGV4dCkgewotCUNHQ29udGV4dFJlc3RvcmVHU3RhdGUoKENHQ29udGV4dFJlZilpbkNvbnRleHQpOworI2lmbmRlZiBOT19OYXZEaWFsb2dHZXRVc2VyQWN0aW9uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OYXZEaWFsb2dHZXRVc2VyQWN0aW9uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIk5hdkRpYWxvZ0dldFVzZXJBY3Rpb25cbiIpCisKKwlyZXR1cm4gKGppbnQpTmF2RGlhbG9nR2V0VXNlckFjdGlvbigoTmF2RGlhbG9nUmVmKWFyZzApOwogfQorI2VuZGlmIC8qIE5PX05hdkRpYWxvZ0dldFVzZXJBY3Rpb24gKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0U3Ryb2tlUmVjdChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpbkNvbnRleHQsIGpmbG9hdCB4LCBqZmxvYXQgeSwgamZsb2F0IHdpZHRoLCBqZmxvYXQgaGVpZ2h0KSB7Ci0JQ0dSZWN0IHI7Ci0Jci5vcmlnaW4ueD0geDsKLQlyLm9yaWdpbi55PSB5OwotCXIuc2l6ZS53aWR0aD0gd2lkdGg7Ci0Jci5zaXplLmhlaWdodD0gaGVpZ2h0OwotCUNHQ29udGV4dFN0cm9rZVJlY3QoKENHQ29udGV4dFJlZilpbkNvbnRleHQsIHIpOworI2lmbmRlZiBOT19OYXZEaWFsb2dSdW4KK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05hdkRpYWxvZ1J1bgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJOYXZEaWFsb2dSdW5cbiIpCisKKwlyZXR1cm4gKGppbnQpTmF2RGlhbG9nUnVuKChOYXZEaWFsb2dSZWYpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fTmF2RGlhbG9nUnVuICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dEZpbGxSZWN0KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGluQ29udGV4dCwgamZsb2F0IHgsIGpmbG9hdCB5LCBqZmxvYXQgd2lkdGgsIGpmbG9hdCBoZWlnaHQpIHsKLQlDR1JlY3QgcjsKLQlyLm9yaWdpbi54PSB4OwotCXIub3JpZ2luLnk9IHk7Ci0Jci5zaXplLndpZHRoPSB3aWR0aDsKLQlyLnNpemUuaGVpZ2h0PSBoZWlnaHQ7Ci0JQ0dDb250ZXh0RmlsbFJlY3QoKENHQ29udGV4dFJlZilpbkNvbnRleHQsIHIpOworI2lmbmRlZiBOT19OYXZEaWFsb2dTZXRTYXZlRmlsZU5hbWUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05hdkRpYWxvZ1NldFNhdmVGaWxlTmFtZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIk5hdkRpYWxvZ1NldFNhdmVGaWxlTmFtZVxuIikKKworCXJldHVybiAoamludClOYXZEaWFsb2dTZXRTYXZlRmlsZU5hbWUoKE5hdkRpYWxvZ1JlZilhcmcwLCAoQ0ZTdHJpbmdSZWYpYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fTmF2RGlhbG9nU2V0U2F2ZUZpbGVOYW1lICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dFNjYWxlQ1RNKEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGluQ29udGV4dCwgamZsb2F0IHN4LCBqZmxvYXQgc3kpIHsKLQlDR0NvbnRleHRTY2FsZUNUTSgoQ0dDb250ZXh0UmVmKWluQ29udGV4dCwgc3gsIHN5KTsKKyNpZm5kZWYgTk9fTmF2R2V0RGVmYXVsdERpYWxvZ0NyZWF0aW9uT3B0aW9ucworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmF2R2V0RGVmYXVsdERpYWxvZ0NyZWF0aW9uT3B0aW9ucworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCkKK3sKKwlOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnMgX2FyZzAsICpscGFyZzA9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiTmF2R2V0RGVmYXVsdERpYWxvZ0NyZWF0aW9uT3B0aW9uc1xuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXROYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnNGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCXJjID0gKGppbnQpTmF2R2V0RGVmYXVsdERpYWxvZ0NyZWF0aW9uT3B0aW9ucygoTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zICopbHBhcmcwKTsKKwlpZiAoYXJnMCkgc2V0TmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zRmllbGRzKGVudiwgYXJnMCwgbHBhcmcwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fTmF2R2V0RGVmYXVsdERpYWxvZ0NyZWF0aW9uT3B0aW9ucyAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRUcmFuc2xhdGVDVE0oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5Db250ZXh0LCBqZmxvYXQgdHgsIGpmbG9hdCB0eSkgewotCUNHQ29udGV4dFRyYW5zbGF0ZUNUTSgoQ0dDb250ZXh0UmVmKWluQ29udGV4dCwgdHgsIHR5KTsKKyNpZm5kZWYgTk9fTmV3Q29udHJvbAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmV3Q29udHJvbAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxLCBqYnl0ZUFycmF5IGFyZzIsIGpib29sZWFuIGFyZzMsIGpzaG9ydCBhcmc0LCBqc2hvcnQgYXJnNSwganNob3J0IGFyZzYsIGpzaG9ydCBhcmc3LCBqaW50IGFyZzgpCit7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCWpieXRlICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiTmV3Q29udHJvbFxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlpZiAoYXJnMikgbHBhcmcyID0gKCplbnYpLT5HZXRCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpTmV3Q29udHJvbCgoV2luZG93UmVmKWFyZzAsIChjb25zdCBSZWN0ICopbHBhcmcxLCAoQ29uc3RTdHIyNTVQYXJhbSlscGFyZzIsIChCb29sZWFuKWFyZzMsIChTSW50MTYpYXJnNCwgKFNJbnQxNilhcmc1LCAoU0ludDE2KWFyZzYsIChTSW50MTYpYXJnNywgKFNJbnQzMilhcmc4KTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fTmV3Q29udHJvbCAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRDbGlwVG9SZWN0KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGluQ29udGV4dCwgamZsb2F0IHgsIGpmbG9hdCB5LCBqZmxvYXQgd2lkdGgsIGpmbG9hdCBoZWlnaHQpIHsKLQlDR1JlY3QgcjsKLQlyLm9yaWdpbi54PSB4OwotCXIub3JpZ2luLnk9IHk7Ci0Jci5zaXplLndpZHRoPSB3aWR0aDsKLQlyLnNpemUuaGVpZ2h0PSBoZWlnaHQ7Ci0JQ0dDb250ZXh0Q2xpcFRvUmVjdCgoQ0dDb250ZXh0UmVmKWluQ29udGV4dCwgcik7CisjaWZuZGVmIE5PX05ld0dXb3JsZEZyb21QdHIKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX05ld0dXb3JsZEZyb21QdHIKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50QXJyYXkgYXJnMCwgamludCBhcmcxLCBqb2JqZWN0IGFyZzIsIGppbnQgYXJnMywgamludCBhcmc0LCBqaW50IGFyZzUsIGppbnQgYXJnNiwgamludCBhcmc3KQoreworCWppbnQgKmxwYXJnMD1OVUxMOworCVJlY3QgX2FyZzIsICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiTmV3R1dvcmxkRnJvbVB0clxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcwLCBOVUxMKTsKKwlpZiAoYXJnMikgbHBhcmcyID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzIsICZfYXJnMik7CisJcmMgPSAoamludClOZXdHV29ybGRGcm9tUHRyKChHV29ybGRQdHIgKilscGFyZzAsICh1bnNpZ25lZCBsb25nKWFyZzEsIChjb25zdCBSZWN0ICopbHBhcmcyLCAoQ1RhYkhhbmRsZSlhcmczLCAoR0RIYW5kbGUpYXJnNCwgKEdXb3JsZEZsYWdzKWFyZzUsIChQdHIpYXJnNiwgKGxvbmcpYXJnNyk7CisJaWYgKGFyZzApICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcwLCBscGFyZzAsIDApOworCWlmIChhcmcyKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMiwgbHBhcmcyKTsKKwlyZXR1cm4gcmM7CiB9CisjZW5kaWYgLyogTk9fTmV3R1dvcmxkRnJvbVB0ciAqLwogCi1KTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DbGlwQ0dDb250ZXh0VG9SZWdpb24oSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5Db250ZXh0LCBqc2hvcnRBcnJheSBwb3J0UmVjdCwgamludCByZ25IYW5kbGUpIHsKLQlqc2hvcnQgKnNhPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIHBvcnRSZWN0LCAwKTsKLQlqaW50IHN0YXR1cz0gUkMoQ2xpcENHQ29udGV4dFRvUmVnaW9uKChDR0NvbnRleHRSZWYpaW5Db250ZXh0LCAoY29uc3QgUmVjdCopIHNhLCAoUmduSGFuZGxlKSByZ25IYW5kbGUpKTsKLQkoKmVudiktPlJlbGVhc2VTaG9ydEFycmF5RWxlbWVudHMoZW52LCBwb3J0UmVjdCwgc2EsIDApOwotCXJldHVybiBzdGF0dXM7CisjaWZuZGVmIE5PX05ld0hhbmRsZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmV3SGFuZGxlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIk5ld0hhbmRsZVxuIikKKworCXJldHVybiAoamludClOZXdIYW5kbGUoKFNpemUpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fTmV3SGFuZGxlICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dEJlZ2luUGF0aChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpbkNvbnRleHQpIHsKLQlDR0NvbnRleHRCZWdpblBhdGgoKENHQ29udGV4dFJlZilpbkNvbnRleHQpOworI2lmbmRlZiBOT19OZXdIYW5kbGVDbGVhcgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmV3SGFuZGxlQ2xlYXIKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiTmV3SGFuZGxlQ2xlYXJcbiIpCisKKwlyZXR1cm4gKGppbnQpTmV3SGFuZGxlQ2xlYXIoKFNpemUpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fTmV3SGFuZGxlQ2xlYXIgKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0TW92ZVRvUG9pbnQoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5Db250ZXh0LCBqZmxvYXQgeCwgamZsb2F0IHkpIHsKLQlDR0NvbnRleHRNb3ZlVG9Qb2ludCgoQ0dDb250ZXh0UmVmKWluQ29udGV4dCwgeCwgeSk7CisjaWZuZGVmIE5PX05ld1B0cgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfTmV3UHRyCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIk5ld1B0clxuIikKKworCXJldHVybiAoamludClOZXdQdHIoKFNpemUpYXJnMCk7CiB9CisjZW5kaWYgLyogTk9fTmV3UHRyICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dEFkZEFyYyhKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpbkNvbnRleHQsIGpmbG9hdCB4LCBqZmxvYXQgeSwgamZsb2F0IHJhZGl1cywgamZsb2F0IHN0YXJ0QW5nbGUsIGpmbG9hdCBlbmRBbmdsZSwgamludCBjbG9ja3dpc2UpIHsKLQlDR0NvbnRleHRBZGRBcmMoKENHQ29udGV4dFJlZilpbkNvbnRleHQsIHgsIHksIHJhZGl1cywgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIGNsb2Nrd2lzZSk7CisjaWZuZGVmIE5PX05ld1B0ckNsZWFyCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OZXdQdHJDbGVhcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJOZXdQdHJDbGVhclxuIikKKworCXJldHVybiAoamludClOZXdQdHJDbGVhcigoU2l6ZSlhcmcwKTsKIH0KKyNlbmRpZiAvKiBOT19OZXdQdHJDbGVhciAqLwogCi1KTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19DR0NvbnRleHRDbG9zZVBhdGgoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5Db250ZXh0KSB7Ci0JQ0dDb250ZXh0Q2xvc2VQYXRoKChDR0NvbnRleHRSZWYpaW5Db250ZXh0KTsKKyNpZm5kZWYgTk9fTmV3UmduCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19OZXdSZ24KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0KQoreworCURFQlVHX0NBTEwoIk5ld1JnblxuIikKKworCXJldHVybiAoamludClOZXdSZ24oKTsKIH0KKyNlbmRpZiAvKiBOT19OZXdSZ24gKi8KIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0U3Ryb2tlUGF0aChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpbkNvbnRleHQpIHsKLQlDR0NvbnRleHRTdHJva2VQYXRoKChDR0NvbnRleHRSZWYpaW5Db250ZXh0KTsKKyNpZm5kZWYgTk9fT2Zmc2V0UmVjdAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBPU19OQVRJVkUoT2Zmc2V0UmVjdCkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzAsIGpzaG9ydCBhcmcxLCBqc2hvcnQgYXJnMikKK3sKKwlSZWN0IF9hcmcwLCAqbHBhcmcwPU5VTEw7CisKKwlERUJVR19DQUxMKCJPZmZzZXRSZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCU9mZnNldFJlY3QobHBhcmcwLCBhcmcxLCBhcmcyKTsKKwlpZiAoYXJnMCkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7CiB9CisjZW5kaWYKIAotSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfQ0dDb250ZXh0RmlsbFBhdGgoSk5JRW52ICplbnYsIGpjbGFzcyB6eiwKLQkJCWppbnQgaW5Db250ZXh0KSB7Ci0JQ0dDb250ZXh0RmlsbFBhdGgoKENHQ29udGV4dFJlZilpbkNvbnRleHQpOworI2lmbmRlZiBOT19PZmZzZXRSZ24KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX09mZnNldFJnbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGpzaG9ydCBhcmcyKQoreworCURFQlVHX0NBTEwoIk9mZnNldFJnblxuIikKKworCU9mZnNldFJnbigoUmduSGFuZGxlKWFyZzAsIChzaG9ydClhcmcxLCAoc2hvcnQpYXJnMik7CiB9CisjZW5kaWYgLyogTk9fT2Zmc2V0UmduICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dFNob3dHbHlwaHNBdFBvaW50KEpOSUVudiAqZW52LCBqY2xhc3MgenosCi0JCQlqaW50IGluQ29udGV4dCwgamZsb2F0IHgsIGpmbG9hdCB5LCBqY2hhckFycmF5IGdseXBocykgewotCWpzaG9ydCAqc2E9ICgqZW52KS0+R2V0U2hvcnRBcnJheUVsZW1lbnRzKGVudiwgZ2x5cGhzLCAwKTsKLQlzaXplX3QgY291bnQ9ICgqZW52KS0+R2V0QXJyYXlMZW5ndGgoZW52LCBnbHlwaHMpOwotCUNHQ29udGV4dFNob3dHbHlwaHNBdFBvaW50KChDR0NvbnRleHRSZWYpaW5Db250ZXh0LCB4LCB5LCAoY29uc3QgQ0dHbHlwaCopIHNhLCBjb3VudCk7Ci0JKCplbnYpLT5SZWxlYXNlU2hvcnRBcnJheUVsZW1lbnRzKGVudiwgZ2x5cGhzLCBzYSwgMCk7CisjaWZuZGVmIE5PX09wZW5EYXRhQnJvd3NlckNvbnRhaW5lcgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfT3BlbkRhdGFCcm93c2VyQ29udGFpbmVyCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiT3BlbkRhdGFCcm93c2VyQ29udGFpbmVyXG4iKQorCisJcmV0dXJuIChqaW50KU9wZW5EYXRhQnJvd3NlckNvbnRhaW5lcigoQ29udHJvbFJlZilhcmcwLCAoRGF0YUJyb3dzZXJJdGVtSUQpYXJnMSk7CiB9CisjZW5kaWYgLyogTk9fT3BlbkRhdGFCcm93c2VyQ29udGFpbmVyICovCiAKLUpOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX0NHQ29udGV4dFNob3dUZXh0QXRQb2ludChKTklFbnYgKmVudiwgamNsYXNzIHp6LAotCQkJamludCBpbkNvbnRleHQsIGpmbG9hdCB4LCBqZmxvYXQgeSwgamJ5dGVBcnJheSBjc3RyaW5nKSB7Ci0JamJ5dGUgKnNhPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgY3N0cmluZywgMCk7Ci0Jc2l6ZV90IGNvdW50PSAoKmVudiktPkdldEFycmF5TGVuZ3RoKGVudiwgY3N0cmluZyk7Ci0JQ0dDb250ZXh0U2hvd1RleHRBdFBvaW50KChDR0NvbnRleHRSZWYpaW5Db250ZXh0LCB4LCB5LCAoY29uc3QgY2hhciopIHNhLCBjb3VudCk7Ci0JKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBjc3RyaW5nLCBzYSwgMCk7CisjaWZuZGVmIE5PX09wZW5Qb2x5CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19PcGVuUG9seQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiT3BlblBvbHlcbiIpCisKKwlyZXR1cm4gKGppbnQpT3BlblBvbHkoKTsKIH0KKyNlbmRpZiAvKiBOT19PcGVuUG9seSAqLworCisjaWZuZGVmIE5PX1BhaW50T3ZhbAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUGFpbnRPdmFsCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwKQoreworCVJlY3QgX2FyZzAsICpscGFyZzA9TlVMTDsKKworCURFQlVHX0NBTEwoIlBhaW50T3ZhbFxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlQYWludE92YWwoKGNvbnN0IFJlY3QgKilscGFyZzApOworCWlmIChhcmcwKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgbHBhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19QYWludE92YWwgKi8KKworI2lmbmRlZiBOT19QYWludFBvbHkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1BhaW50UG9seQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJQYWludFBvbHlcbiIpCisKKwlQYWludFBvbHkoKFBvbHlIYW5kbGUpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fUGFpbnRQb2x5ICovCisKKyNpZm5kZWYgTk9fUGFpbnRSZWN0CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19QYWludFJlY3QKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzApCit7CisJUmVjdCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgiUGFpbnRSZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCVBhaW50UmVjdCgoY29uc3QgUmVjdCAqKWxwYXJnMCk7CisJaWYgKGFyZzApIHNldFJlY3RGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworfQorI2VuZGlmIC8qIE5PX1BhaW50UmVjdCAqLworCisjaWZuZGVmIE5PX1BhaW50Um91bmRSZWN0CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19QYWludFJvdW5kUmVjdAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwganNob3J0IGFyZzEsIGpzaG9ydCBhcmcyKQoreworCVJlY3QgX2FyZzAsICpscGFyZzA9TlVMTDsKKworCURFQlVHX0NBTEwoIlBhaW50Um91bmRSZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCVBhaW50Um91bmRSZWN0KChjb25zdCBSZWN0ICopbHBhcmcwLCAoc2hvcnQpYXJnMSwgKHNob3J0KWFyZzIpOworCWlmIChhcmcwKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgbHBhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19QYWludFJvdW5kUmVjdCAqLworCisjaWZuZGVmIE5PX1BlblNpemUKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1BlblNpemUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqc2hvcnQgYXJnMCwganNob3J0IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiUGVuU2l6ZVxuIikKKworCVBlblNpemUoKHNob3J0KWFyZzAsIChzaG9ydClhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19QZW5TaXplICovCisKKyNpZm5kZWYgTk9fUGlja0NvbG9yCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19QaWNrQ29sb3IKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzApCit7CisJQ29sb3JQaWNrZXJJbmZvIF9hcmcwLCAqbHBhcmcwPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIlBpY2tDb2xvclxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRDb2xvclBpY2tlckluZm9GaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCXJjID0gKGppbnQpUGlja0NvbG9yKChDb2xvclBpY2tlckluZm8gKilscGFyZzApOworCWlmIChhcmcwKSBzZXRDb2xvclBpY2tlckluZm9GaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19QaWNrQ29sb3IgKi8KKworI2lmbmRlZiBOT19Qb3BVcE1lbnVTZWxlY3QKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1BvcFVwTWVudVNlbGVjdAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGpzaG9ydCBhcmcyLCBqc2hvcnQgYXJnMykKK3sKKwlERUJVR19DQUxMKCJQb3BVcE1lbnVTZWxlY3RcbiIpCisKKwlyZXR1cm4gKGppbnQpUG9wVXBNZW51U2VsZWN0KChNZW51UmVmKWFyZzAsIChzaG9ydClhcmcxLCAoc2hvcnQpYXJnMiwgKHNob3J0KWFyZzMpOworfQorI2VuZGlmIC8qIE5PX1BvcFVwTWVudVNlbGVjdCAqLworCisjaWZuZGVmIE5PX1Bvc3RFdmVudAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUG9zdEV2ZW50CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwganNob3J0IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJQb3N0RXZlbnRcbiIpCisKKwlyZXR1cm4gKGppbnQpUG9zdEV2ZW50KChFdmVudEtpbmQpYXJnMCwgKFVJbnQzMilhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19Qb3N0RXZlbnQgKi8KKworI2lmbmRlZiBOT19Qb3N0RXZlbnRUb1F1ZXVlCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19Qb3N0RXZlbnRUb1F1ZXVlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGpzaG9ydCBhcmcyKQoreworCURFQlVHX0NBTEwoIlBvc3RFdmVudFRvUXVldWVcbiIpCisKKwlyZXR1cm4gKGppbnQpUG9zdEV2ZW50VG9RdWV1ZSgoRXZlbnRRdWV1ZVJlZilhcmcwLCAoRXZlbnRSZWYpYXJnMSwgKEV2ZW50UHJpb3JpdHkpYXJnMik7Cit9CisjZW5kaWYgLyogTk9fUG9zdEV2ZW50VG9RdWV1ZSAqLworCisjaWZuZGVmIE5PX1B0SW5SZWN0CitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUHRJblJlY3QKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlQb2ludCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCVJlY3QgX2FyZzEsICpscGFyZzE9TlVMTDsKKwlqYm9vbGVhbiByYzsKKworCURFQlVHX0NBTEwoIlB0SW5SZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFBvaW50RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJcmMgPSAoamJvb2xlYW4pUHRJblJlY3QoKFBvaW50KSpscGFyZzAsIChjb25zdCBSZWN0ICopbHBhcmcxKTsKKwlpZiAoYXJnMCkgc2V0UG9pbnRGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fUHRJblJlY3QgKi8KKworI2lmbmRlZiBOT19QdEluUmduCitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUHRJblJnbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwgamludCBhcmcxKQoreworCVBvaW50IF9hcmcwLCAqbHBhcmcwPU5VTEw7CisJamJvb2xlYW4gcmM7CisKKwlERUJVR19DQUxMKCJQdEluUmduXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFBvaW50RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlyYyA9IChqYm9vbGVhbilQdEluUmduKChQb2ludCkqbHBhcmcwLCAoUmduSGFuZGxlKWFyZzEpOworCWlmIChhcmcwKSBzZXRQb2ludEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1B0SW5SZ24gKi8KKworI2lmbmRlZiBOT19QdXRTY3JhcEZsYXZvcgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUHV0U2NyYXBGbGF2b3IKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMsIGpieXRlQXJyYXkgYXJnNCkKK3sKKwlqYnl0ZSAqbHBhcmc0PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIlB1dFNjcmFwRmxhdm9yXG4iKQorCisJaWYgKGFyZzQpIGxwYXJnNCA9ICgqZW52KS0+R2V0Qnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlyYyA9IChqaW50KVB1dFNjcmFwRmxhdm9yKChTY3JhcFJlZilhcmcwLCAoU2NyYXBGbGF2b3JUeXBlKWFyZzEsIChTY3JhcEZsYXZvckZsYWdzKWFyZzIsIChTaXplKWFyZzMsIChjb25zdCB2b2lkICopbHBhcmc0KTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBscGFyZzQsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19QdXRTY3JhcEZsYXZvciAqLworCisjaWZuZGVmIE5PX1FEQmVnaW5DR0NvbnRleHQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1FEQmVnaW5DR0NvbnRleHQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnRBcnJheSBhcmcxKQoreworCWppbnQgKmxwYXJnMT1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJRREJlZ2luQ0dDb250ZXh0XG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCXJjID0gKGppbnQpUURCZWdpbkNHQ29udGV4dCgoQ0dyYWZQdHIpYXJnMCwgKENHQ29udGV4dFJlZiAqKWxwYXJnMSk7CisJaWYgKGFyZzEpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19RREJlZ2luQ0dDb250ZXh0ICovCisKKyNpZm5kZWYgTk9fUURFbmRDR0NvbnRleHQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1FERW5kQ0dDb250ZXh0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50QXJyYXkgYXJnMSkKK3sKKwlqaW50ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiUURFbmRDR0NvbnRleHRcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJcmMgPSAoamludClRREVuZENHQ29udGV4dCgoQ0dyYWZQdHIpYXJnMCwgKENHQ29udGV4dFJlZiAqKWxwYXJnMSk7CisJaWYgKGFyZzEpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19RREVuZENHQ29udGV4dCAqLworCisjaWZuZGVmIE5PX1FERmx1c2hQb3J0QnVmZmVyCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19RREZsdXNoUG9ydEJ1ZmZlcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIlFERmx1c2hQb3J0QnVmZmVyXG4iKQorCisJUURGbHVzaFBvcnRCdWZmZXIoKENHcmFmUHRyKWFyZzAsIChSZ25IYW5kbGUpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fUURGbHVzaFBvcnRCdWZmZXIgKi8KKworI2lmbmRlZiBOT19RREdsb2JhbFRvTG9jYWxQb2ludAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUURHbG9iYWxUb0xvY2FsUG9pbnQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlQb2ludCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgiUURHbG9iYWxUb0xvY2FsUG9pbnRcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UG9pbnRGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCVFER2xvYmFsVG9Mb2NhbFBvaW50KChDR3JhZlB0cilhcmcwLCAoUG9pbnQgKilscGFyZzEpOworCWlmIChhcmcxKSBzZXRQb2ludEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fUURHbG9iYWxUb0xvY2FsUG9pbnQgKi8KKworI2lmbmRlZiBOT19RRExvY2FsVG9HbG9iYWxQb2ludAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUURMb2NhbFRvR2xvYmFsUG9pbnQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlQb2ludCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgiUURMb2NhbFRvR2xvYmFsUG9pbnRcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UG9pbnRGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCVFETG9jYWxUb0dsb2JhbFBvaW50KChDR3JhZlB0cilhcmcwLCAoUG9pbnQgKilscGFyZzEpOworCWlmIChhcmcxKSBzZXRQb2ludEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fUURMb2NhbFRvR2xvYmFsUG9pbnQgKi8KKworI2lmbmRlZiBOT19RRFNldFBhdHRlcm5PcmlnaW4KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1FEU2V0UGF0dGVybk9yaWdpbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCkKK3sKKwlQb2ludCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgiUURTZXRQYXR0ZXJuT3JpZ2luXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFBvaW50RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlRRFNldFBhdHRlcm5PcmlnaW4oKFBvaW50KSpscGFyZzApOworCWlmIChhcmcwKSBzZXRQb2ludEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fUURTZXRQYXR0ZXJuT3JpZ2luICovCisKKyNpZm5kZWYgTk9fUURTd2FwVGV4dEZsYWdzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19RRFN3YXBUZXh0RmxhZ3MKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiUURTd2FwVGV4dEZsYWdzXG4iKQorCisJcmV0dXJuIChqaW50KVFEU3dhcFRleHRGbGFncygoVUludDMyKWFyZzApOworfQorI2VuZGlmIC8qIE5PX1FEU3dhcFRleHRGbGFncyAqLworCisjaWZuZGVmIE5PX1JHQkJhY2tDb2xvcgorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUkdCQmFja0NvbG9yCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwKQoreworCVJHQkNvbG9yIF9hcmcwLCAqbHBhcmcwPU5VTEw7CisKKwlERUJVR19DQUxMKCJSR0JCYWNrQ29sb3JcbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gZ2V0UkdCQ29sb3JGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCVJHQkJhY2tDb2xvcigoY29uc3QgUkdCQ29sb3IgKilscGFyZzApOworCWlmIChhcmcwKSBzZXRSR0JDb2xvckZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fUkdCQmFja0NvbG9yICovCisKKyNpZm5kZWYgTk9fUkdCRm9yZUNvbG9yCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SR0JGb3JlQ29sb3IKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzApCit7CisJUkdCQ29sb3IgX2FyZzAsICpscGFyZzA9TlVMTDsKKworCURFQlVHX0NBTEwoIlJHQkZvcmVDb2xvclxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRSR0JDb2xvckZpZWxkcyhlbnYsIGFyZzAsICZfYXJnMCk7CisJUkdCRm9yZUNvbG9yKChjb25zdCBSR0JDb2xvciAqKWxwYXJnMCk7CisJaWYgKGFyZzApIHNldFJHQkNvbG9yRmllbGRzKGVudiwgYXJnMCwgbHBhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19SR0JGb3JlQ29sb3IgKi8KKworI2lmbmRlZiBOT19SZWNlaXZlTmV4dEV2ZW50CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SZWNlaXZlTmV4dEV2ZW50CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50QXJyYXkgYXJnMSwgamRvdWJsZSBhcmcyLCBqYm9vbGVhbiBhcmczLCBqaW50QXJyYXkgYXJnNCkKK3sKKwlqaW50ICpscGFyZzE9TlVMTDsKKwlqaW50ICpscGFyZzQ9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiUmVjZWl2ZU5leHRFdmVudFxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBOVUxMKTsKKwlpZiAoYXJnNCkgbHBhcmc0ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNCwgTlVMTCk7CisJcmMgPSAoamludClSZWNlaXZlTmV4dEV2ZW50KChVSW50MzIpYXJnMCwgKGNvbnN0IEV2ZW50VHlwZVNwZWMgKilscGFyZzEsIChFdmVudFRpbWVvdXQpYXJnMiwgKEJvb2xlYW4pYXJnMywgKEV2ZW50UmVmICopbHBhcmc0KTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJaWYgKGFyZzQpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBscGFyZzQsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19SZWNlaXZlTmV4dEV2ZW50ICovCisKKyNpZm5kZWYgTk9fUmVjdEluUmduCitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUmVjdEluUmduCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwLCBqaW50IGFyZzEpCit7CisJUmVjdCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCWpib29sZWFuIHJjOworCisJREVCVUdfQ0FMTCgiUmVjdEluUmduXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCXJjID0gKGpib29sZWFuKVJlY3RJblJnbigoY29uc3QgUmVjdCAqKWxwYXJnMCwgKFJnbkhhbmRsZSlhcmcxKTsKKwlpZiAoYXJnMCkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1JlY3RJblJnbiAqLworCisjaWZuZGVmIE5PX1JlY3RSZ24KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1JlY3RSZ24KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisKKwlERUJVR19DQUxMKCJSZWN0UmduXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCVJlY3RSZ24oKFJnbkhhbmRsZSlhcmcwLCAoY29uc3QgUmVjdCAqKWxwYXJnMSk7CisJaWYgKGFyZzEpIHNldFJlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworfQorI2VuZGlmIC8qIE5PX1JlY3RSZ24gKi8KKworI2lmbmRlZiBOT19SZWdpc3RlckFwcGVhcmFuY2VDbGllbnQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1JlZ2lzdGVyQXBwZWFyYW5jZUNsaWVudAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgiUmVnaXN0ZXJBcHBlYXJhbmNlQ2xpZW50XG4iKQorCisJcmV0dXJuIChqaW50KVJlZ2lzdGVyQXBwZWFyYW5jZUNsaWVudCgpOworfQorI2VuZGlmIC8qIE5PX1JlZ2lzdGVyQXBwZWFyYW5jZUNsaWVudCAqLworCisjaWZuZGVmIE5PX1JlbGVhc2VFdmVudAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUmVsZWFzZUV2ZW50CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIlJlbGVhc2VFdmVudFxuIikKKworCVJlbGVhc2VFdmVudCgoRXZlbnRSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fUmVsZWFzZUV2ZW50ICovCisKKyNpZm5kZWYgTk9fUmVsZWFzZU1lbnUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1JlbGVhc2VNZW51CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIlJlbGVhc2VNZW51XG4iKQorCisJcmV0dXJuIChqaW50KVJlbGVhc2VNZW51KChNZW51UmVmKWFyZzApOworfQorI2VuZGlmIC8qIE5PX1JlbGVhc2VNZW51ICovCisKKyNpZm5kZWYgTk9fUmVsZWFzZVdpbmRvd0dyb3VwCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SZWxlYXNlV2luZG93R3JvdXAKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiUmVsZWFzZVdpbmRvd0dyb3VwXG4iKQorCisJcmV0dXJuIChqaW50KVJlbGVhc2VXaW5kb3dHcm91cCgoV2luZG93R3JvdXBSZWYpYXJnMCk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19SZW1vdmVDb250cm9sUHJvcGVydHkKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1JlbW92ZUNvbnRyb2xQcm9wZXJ0eQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIpCit7CisJREVCVUdfQ0FMTCgiUmVtb3ZlQ29udHJvbFByb3BlcnR5XG4iKQorCisJcmV0dXJuIChqaW50KVJlbW92ZUNvbnRyb2xQcm9wZXJ0eSgoQ29udHJvbFJlZilhcmcwLCBhcmcxLCBhcmcyKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX1JlbW92ZURhdGFCcm93c2VySXRlbXMKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1JlbW92ZURhdGFCcm93c2VySXRlbXMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50QXJyYXkgYXJnMywgamludCBhcmc0KQoreworCWppbnQgKmxwYXJnMz1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJSZW1vdmVEYXRhQnJvd3Nlckl0ZW1zXG4iKQorCisJaWYgKGFyZzMpIGxwYXJnMyA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIE5VTEwpOworCXJjID0gKGppbnQpUmVtb3ZlRGF0YUJyb3dzZXJJdGVtcygoQ29udHJvbFJlZilhcmcwLCAoRGF0YUJyb3dzZXJJdGVtSUQpYXJnMSwgKFVJbnQzMilhcmcyLCAoY29uc3QgRGF0YUJyb3dzZXJJdGVtSUQgKilscGFyZzMsIChEYXRhQnJvd3NlclByb3BlcnR5SUQpYXJnNCk7CisJaWYgKGFyZzMpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBscGFyZzMsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19SZW1vdmVEYXRhQnJvd3Nlckl0ZW1zICovCisKKyNpZm5kZWYgTk9fUmVtb3ZlRGF0YUJyb3dzZXJUYWJsZVZpZXdDb2x1bW4KK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1JlbW92ZURhdGFCcm93c2VyVGFibGVWaWV3Q29sdW1uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiUmVtb3ZlRGF0YUJyb3dzZXJUYWJsZVZpZXdDb2x1bW5cbiIpCisKKwlyZXR1cm4gKGppbnQpUmVtb3ZlRGF0YUJyb3dzZXJUYWJsZVZpZXdDb2x1bW4oKENvbnRyb2xSZWYpYXJnMCwgKERhdGFCcm93c2VyVGFibGVWaWV3Q29sdW1uSUQpYXJnMSk7CisKK30KKyNlbmRpZiAvKiBOT19SZW1vdmVEYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtbiAqLworCisjaWZuZGVmIE5PX1JlbW92ZUV2ZW50SGFuZGxlcgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUmVtb3ZlRXZlbnRIYW5kbGVyCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIlJlbW92ZUV2ZW50SGFuZGxlclxuIikKKworCXJldHVybiAoamludClSZW1vdmVFdmVudEhhbmRsZXIoKEV2ZW50SGFuZGxlclJlZilhcmcwKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX1JlbW92ZUV2ZW50TG9vcFRpbWVyCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SZW1vdmVFdmVudExvb3BUaW1lcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJSZW1vdmVFdmVudExvb3BUaW1lclxuIikKKworCXJldHVybiAoamludClSZW1vdmVFdmVudExvb3BUaW1lcigoRXZlbnRMb29wVGltZXJSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fUmVtb3ZlRXZlbnRMb29wVGltZXIgKi8KKworI2lmbmRlZiBOT19SZXBvc2l0aW9uV2luZG93CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19SZXBvc2l0aW9uV2luZG93CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMikKK3sKKwlERUJVR19DQUxMKCJSZXBvc2l0aW9uV2luZG93XG4iKQorCisJcmV0dXJuIChqaW50KVJlcG9zaXRpb25XaW5kb3coKFdpbmRvd1JlZilhcmcwLCAoV2luZG93UmVmKWFyZzEsIGFyZzIpOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fUmV0YWluTWVudQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUmV0YWluTWVudQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJSZXRhaW5NZW51XG4iKQorCisJcmV0dXJuIChqaW50KVJldGFpbk1lbnUoKE1lbnVSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fUmV0YWluTWVudSAqLworCisjaWZuZGVmIE5PX1JldmVhbERhdGFCcm93c2VySXRlbQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUmV2ZWFsRGF0YUJyb3dzZXJJdGVtCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamJ5dGUgYXJnMykKK3sKKwlERUJVR19DQUxMKCJSZXZlYWxEYXRhQnJvd3Nlckl0ZW1cbiIpCisKKwlyZXR1cm4gKGppbnQpUmV2ZWFsRGF0YUJyb3dzZXJJdGVtKChDb250cm9sUmVmKWFyZzAsIChEYXRhQnJvd3Nlckl0ZW1JRClhcmcxLCAoRGF0YUJyb3dzZXJQcm9wZXJ0eUlEKWFyZzIsIChEYXRhQnJvd3NlclJldmVhbE9wdGlvbnMpYXJnMyk7Cit9CisjZW5kaWYgLyogTk9fUmV2ZWFsRGF0YUJyb3dzZXJJdGVtICovCisKKyNpZm5kZWYgTk9fUnVuU3RhbmRhcmRBbGVydAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfUnVuU3RhbmRhcmRBbGVydAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqc2hvcnRBcnJheSBhcmcyKQoreworCWpzaG9ydCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIlJ1blN0YW5kYXJkQWxlcnRcbiIpCisKKwlpZiAoYXJnMikgbHBhcmcyID0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlyYyA9IChqaW50KVJ1blN0YW5kYXJkQWxlcnQoKERpYWxvZ1JlZilhcmcwLCAoTW9kYWxGaWx0ZXJVUFApYXJnMSwgKERpYWxvZ0l0ZW1JbmRleCAqKWxwYXJnMik7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1J1blN0YW5kYXJkQWxlcnQgKi8KKworI2lmbmRlZiBOT19TY3JvbGxSZWN0CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TY3JvbGxSZWN0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwLCBqc2hvcnQgYXJnMSwganNob3J0IGFyZzIsIGppbnQgYXJnMykKK3sKKwlSZWN0IF9hcmcwLCAqbHBhcmcwPU5VTEw7CisKKwlERUJVR19DQUxMKCJTY3JvbGxSZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCVNjcm9sbFJlY3QoKGNvbnN0IFJlY3QgKilscGFyZzAsIChzaG9ydClhcmcxLCAoc2hvcnQpYXJnMiwgKFJnbkhhbmRsZSlhcmczKTsKKwlpZiAoYXJnMCkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fU2Nyb2xsUmVjdCAqLworCisjaWZuZGVmIE5PX1NlY3RSZWN0CitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBPU19OQVRJVkUoU2VjdFJlY3QpCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwLCBqb2JqZWN0IGFyZzEsIGpvYmplY3QgYXJnMikKK3sKKwlSZWN0IF9hcmcwLCAqbHBhcmcwPU5VTEw7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCVJlY3QgX2FyZzIsICpscGFyZzI9TlVMTDsKKwlqYm9vbGVhbiByYzsKKworCURFQlVHX0NBTEwoIlNlY3RSZWN0XG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlpZiAoYXJnMikgbHBhcmcyID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzIsICZfYXJnMik7CisJcmMgPSAoamJvb2xlYW4pU2VjdFJlY3QobHBhcmcwLCBscGFyZzEsIGxwYXJnMik7CisJaWYgKGFyZzApIHNldFJlY3RGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlpZiAoYXJnMikgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzIsIGxwYXJnMik7CisJcmV0dXJuIHJjOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fU2VjdFJnbgorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2VjdFJnbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIpCit7CisJREVCVUdfQ0FMTCgiU2VjdFJnblxuIikKKworCVNlY3RSZ24oKFJnbkhhbmRsZSlhcmcwLCAoUmduSGFuZGxlKWFyZzEsIChSZ25IYW5kbGUpYXJnMik7Cit9CisjZW5kaWYgLyogTk9fU2VjdFJnbiAqLworCisjaWZuZGVmIE5PX1NlbGVjdFdpbmRvdworSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2VsZWN0V2luZG93CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIlNlbGVjdFdpbmRvd1xuIikKKworCVNlbGVjdFdpbmRvdygoV2luZG93UmVmKWFyZzApOworfQorI2VuZGlmIC8qIE5PX1NlbGVjdFdpbmRvdyAqLworCisjaWZuZGVmIE5PX1NlbmRCZWhpbmQKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NlbmRCZWhpbmQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJTZW5kQmVoaW5kXG4iKQorCisJU2VuZEJlaGluZCgoV2luZG93UmVmKWFyZzAsIChXaW5kb3dSZWYpYXJnMSk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19TZW5kRXZlbnRUb0V2ZW50VGFyZ2V0CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZW5kRXZlbnRUb0V2ZW50VGFyZ2V0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiU2VuZEV2ZW50VG9FdmVudFRhcmdldFxuIikKKworCXJldHVybiAoamludClTZW5kRXZlbnRUb0V2ZW50VGFyZ2V0KChFdmVudFJlZilhcmcwLCAoRXZlbnRUYXJnZXRSZWYpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fU2VuZEV2ZW50VG9FdmVudFRhcmdldCAqLworCisjaWZuZGVmIE5PX1NldEJldmVsQnV0dG9uQ29udGVudEluZm8KK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldEJldmVsQnV0dG9uQ29udGVudEluZm8KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlDb250cm9sQnV0dG9uQ29udGVudEluZm8gX2FyZzEsICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiU2V0QmV2ZWxCdXR0b25Db250ZW50SW5mb1xuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRDb250cm9sQnV0dG9uQ29udGVudEluZm9GaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCXJjID0gKGppbnQpU2V0QmV2ZWxCdXR0b25Db250ZW50SW5mbygoQ29udHJvbFJlZilhcmcwLCAoQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvUHRyKWxwYXJnMSk7CisJaWYgKGFyZzEpIHNldENvbnRyb2xCdXR0b25Db250ZW50SW5mb0ZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1NldEJldmVsQnV0dG9uQ29udGVudEluZm8gKi8KKworI2lmbmRlZiBOT19TZXRDbGlwCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDbGlwCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIlNldENsaXBcbiIpCisKKwlTZXRDbGlwKChSZ25IYW5kbGUpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fU2V0Q2xpcCAqLworCisjaWZuZGVmIE5PX1NldENvbnRyb2wzMkJpdE1heGltdW0KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldENvbnRyb2wzMkJpdE1heGltdW0KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJTZXRDb250cm9sMzJCaXRNYXhpbXVtXG4iKQorCisJU2V0Q29udHJvbDMyQml0TWF4aW11bSgoQ29udHJvbFJlZilhcmcwLCAoU0ludDMyKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1NldENvbnRyb2wzMkJpdE1heGltdW0gKi8KKworI2lmbmRlZiBOT19TZXRDb250cm9sMzJCaXRNaW5pbXVtCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sMzJCaXRNaW5pbXVtCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiU2V0Q29udHJvbDMyQml0TWluaW11bVxuIikKKworCVNldENvbnRyb2wzMkJpdE1pbmltdW0oKENvbnRyb2xSZWYpYXJnMCwgKFNJbnQzMilhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19TZXRDb250cm9sMzJCaXRNaW5pbXVtICovCisKKyNpZm5kZWYgTk9fU2V0Q29udHJvbDMyQml0VmFsdWUKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldENvbnRyb2wzMkJpdFZhbHVlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiU2V0Q29udHJvbDMyQml0VmFsdWVcbiIpCisKKwlTZXRDb250cm9sMzJCaXRWYWx1ZSgoQ29udHJvbFJlZilhcmcwLCAoU0ludDMyKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1NldENvbnRyb2wzMkJpdFZhbHVlICovCisKKyNpZm5kZWYgTk9fU2V0Q29udHJvbEFjdGlvbgorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0Q29udHJvbEFjdGlvbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIlNldENvbnRyb2xBY3Rpb25cbiIpCisKKwlTZXRDb250cm9sQWN0aW9uKChDb250cm9sUmVmKWFyZzAsIChDb250cm9sQWN0aW9uVVBQKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1NldENvbnRyb2xBY3Rpb24gKi8KKworI2lmbmRlZiBOT19TZXRDb250cm9sQm91bmRzCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sQm91bmRzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEpCit7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgiU2V0Q29udHJvbEJvdW5kc1xuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlTZXRDb250cm9sQm91bmRzKChDb250cm9sUmVmKWFyZzAsIChjb25zdCBSZWN0ICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fU2V0Q29udHJvbEJvdW5kcyAqLworCisjaWZuZGVmIE5PX1NldENvbnRyb2xEYXRhX19JSUlJTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fUmVjdF8yCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sRGF0YV9fSUlJSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX1JlY3RfMgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMywgam9iamVjdCBhcmc0KQoreworCVJlY3QgX2FyZzQsICpscGFyZzQ9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiU2V0Q29udHJvbERhdGFfX0lJSUlMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9SZWN0XzJcbiIpCisKKwlpZiAoYXJnNCkgbHBhcmc0ID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzQsICZfYXJnNCk7CisJcmMgPSAoamludClTZXRDb250cm9sRGF0YSgoQ29udHJvbFJlZilhcmcwLCAoQ29udHJvbFBhcnRDb2RlKWFyZzEsIChSZXNUeXBlKWFyZzIsIChTaXplKWFyZzMsIChjb25zdCB2b2lkICopbHBhcmc0KTsKKwlpZiAoYXJnNCkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzQsIGxwYXJnNCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1NldENvbnRyb2xEYXRhX19JSUlJTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fUmVjdF8yICovCisKKyNpZm5kZWYgTk9fU2V0Q29udHJvbERhdGFfX0lJSUlfM0kKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldENvbnRyb2xEYXRhX19JSUlJXzNJCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqaW50QXJyYXkgYXJnNCkKK3sKKwlqaW50ICpscGFyZzQ9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiU2V0Q29udHJvbERhdGFfX0lJSUlfM0lcbiIpCisKKwlpZiAoYXJnNCkgbHBhcmc0ID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnNCwgTlVMTCk7CisJcmMgPSAoamludClTZXRDb250cm9sRGF0YSgoQ29udHJvbFJlZilhcmcwLCAoQ29udHJvbFBhcnRDb2RlKWFyZzEsIChSZXNUeXBlKWFyZzIsIChTaXplKWFyZzMsIChjb25zdCB2b2lkICopbHBhcmc0KTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1NldENvbnRyb2xEYXRhX19JSUlJXzNJICovCisKKyNpZm5kZWYgTk9fU2V0Q29udHJvbERhdGFfX0lJSUlJCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sRGF0YV9fSUlJSUkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyLCBqaW50IGFyZzMsIGppbnQgYXJnNCkKK3sKKwlERUJVR19DQUxMKCJTZXRDb250cm9sRGF0YV9fSUlJSUlcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0Q29udHJvbERhdGEoKENvbnRyb2xSZWYpYXJnMCwgKENvbnRyb2xQYXJ0Q29kZSlhcmcxLCAoUmVzVHlwZSlhcmcyLCAoU2l6ZSlhcmczLCAoY29uc3Qgdm9pZCAqKWFyZzQpOworfQorI2VuZGlmIC8qIE5PX1NldENvbnRyb2xEYXRhX19JSUlJSSAqLworCisjaWZuZGVmIE5PX1NldENvbnRyb2xEYXRhX19JSUlJXzNTCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sRGF0YV9fSUlJSV8zUworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMywganNob3J0QXJyYXkgYXJnNCkKK3sKKwlqc2hvcnQgKmxwYXJnND1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJTZXRDb250cm9sRGF0YV9fSUlJSV8zU1xuIikKKworCWlmIChhcmc0KSBscGFyZzQgPSAoKmVudiktPkdldFNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIE5VTEwpOworCXJjID0gKGppbnQpU2V0Q29udHJvbERhdGEoKENvbnRyb2xSZWYpYXJnMCwgKENvbnRyb2xQYXJ0Q29kZSlhcmcxLCAoUmVzVHlwZSlhcmcyLCAoU2l6ZSlhcmczLCAoY29uc3Qgdm9pZCAqKWxwYXJnNCk7CisJaWYgKGFyZzQpICgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1NldENvbnRyb2xEYXRhX19JSUlJXzNTICovCisKKyNpZm5kZWYgTk9fU2V0Q29udHJvbERhdGFfX0lJSUlMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9Db250cm9sVGFiSW5mb1JlY1YxXzIKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldENvbnRyb2xEYXRhX19JSUlJTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fQ29udHJvbFRhYkluZm9SZWNWMV8yCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqb2JqZWN0IGFyZzQpCit7CisJQ29udHJvbFRhYkluZm9SZWNWMSBfYXJnNCwgKmxwYXJnND1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJTZXRDb250cm9sRGF0YV9fSUlJSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0NvbnRyb2xUYWJJbmZvUmVjVjFfMlxuIikKKworCWlmIChhcmc0KSBscGFyZzQgPSBnZXRDb250cm9sVGFiSW5mb1JlY1YxRmllbGRzKGVudiwgYXJnNCwgJl9hcmc0KTsKKwlyYyA9IChqaW50KVNldENvbnRyb2xEYXRhKChDb250cm9sUmVmKWFyZzAsIChDb250cm9sUGFydENvZGUpYXJnMSwgKFJlc1R5cGUpYXJnMiwgKFNpemUpYXJnMywgKGNvbnN0IHZvaWQgKilscGFyZzQpOworCWlmIChhcmc0KSBzZXRDb250cm9sVGFiSW5mb1JlY1YxRmllbGRzKGVudiwgYXJnNCwgbHBhcmc0KTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fU2V0Q29udHJvbERhdGFfX0lJSUlMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9Db250cm9sVGFiSW5mb1JlY1YxXzIgKi8KKworI2lmbmRlZiBOT19TZXRDb250cm9sRGF0YV9fSUlJSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0NvbnRyb2xCdXR0b25Db250ZW50SW5mb18yCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sRGF0YV9fSUlJSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0NvbnRyb2xCdXR0b25Db250ZW50SW5mb18yCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqb2JqZWN0IGFyZzQpCit7CisJQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvIF9hcmc0LCAqbHBhcmc0PU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIlNldENvbnRyb2xEYXRhX19JSUlJTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvXzJcbiIpCisKKwlpZiAoYXJnNCkgbHBhcmc0ID0gZ2V0Q29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvRmllbGRzKGVudiwgYXJnNCwgJl9hcmc0KTsKKwlyYyA9IChqaW50KVNldENvbnRyb2xEYXRhKChDb250cm9sUmVmKWFyZzAsIChDb250cm9sUGFydENvZGUpYXJnMSwgKFJlc1R5cGUpYXJnMiwgKFNpemUpYXJnMywgKGNvbnN0IHZvaWQgKilscGFyZzQpOworCWlmIChhcmc0KSBzZXRDb250cm9sQnV0dG9uQ29udGVudEluZm9GaWVsZHMoZW52LCBhcmc0LCBscGFyZzQpOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19TZXRDb250cm9sRGF0YV9fSUlJSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0NvbnRyb2xCdXR0b25Db250ZW50SW5mb18yICovCisKKyNpZm5kZWYgTk9fU2V0Q29udHJvbERhdGFfX0lJSUlfM0IKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldENvbnRyb2xEYXRhX19JSUlJXzNCCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqYnl0ZUFycmF5IGFyZzQpCit7CisJamJ5dGUgKmxwYXJnND1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJTZXRDb250cm9sRGF0YV9fSUlJSV8zQlxuIikKKworCWlmIChhcmc0KSBscGFyZzQgPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnNCwgTlVMTCk7CisJcmMgPSAoamludClTZXRDb250cm9sRGF0YSgoQ29udHJvbFJlZilhcmcwLCAoQ29udHJvbFBhcnRDb2RlKWFyZzEsIChSZXNUeXBlKWFyZzIsIChTaXplKWFyZzMsIChjb25zdCB2b2lkICopbHBhcmc0KTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlQnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBscGFyZzQsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19TZXRDb250cm9sRGF0YV9fSUlJSV8zQiAqLworCisjaWZuZGVmIE5PX1NldENvbnRyb2xGb250U3R5bGUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldENvbnRyb2xGb250U3R5bGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlDb250cm9sRm9udFN0eWxlUmVjIF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIlNldENvbnRyb2xGb250U3R5bGVcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0Q29udHJvbEZvbnRTdHlsZVJlY0ZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJcmMgPSAoamludClTZXRDb250cm9sRm9udFN0eWxlKChDb250cm9sUmVmKWFyZzAsIChjb25zdCBDb250cm9sRm9udFN0eWxlUmVjICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgc2V0Q29udHJvbEZvbnRTdHlsZVJlY0ZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1NldENvbnRyb2xGb250U3R5bGUgKi8KKworI2lmbmRlZiBOT19TZXRDb250cm9sUG9wdXBNZW51SGFuZGxlCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sUG9wdXBNZW51SGFuZGxlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiU2V0Q29udHJvbFBvcHVwTWVudUhhbmRsZVxuIikKKworCVNldENvbnRyb2xQb3B1cE1lbnVIYW5kbGUoKENvbnRyb2xSZWYpYXJnMCwgKE1lbnVSZWYpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fU2V0Q29udHJvbFBvcHVwTWVudUhhbmRsZSAqLworCisjaWZuZGVmIE5PX1NldENvbnRyb2xQcm9wZXJ0eQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0Q29udHJvbFByb3BlcnR5CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqaW50QXJyYXkgYXJnNCkKK3sKKwlqaW50ICpscGFyZzQ9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiU2V0Q29udHJvbFByb3BlcnR5XG4iKQorCisJaWYgKGFyZzQpIGxwYXJnNCA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIE5VTEwpOworCXJjID0gKGppbnQpU2V0Q29udHJvbFByb3BlcnR5KChDb250cm9sUmVmKWFyZzAsIGFyZzEsIGFyZzIsIGFyZzMsIChjb25zdCB2b2lkICopbHBhcmc0KTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fU2V0Q29udHJvbFJlZmVyZW5jZQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0Q29udHJvbFJlZmVyZW5jZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIlNldENvbnRyb2xSZWZlcmVuY2VcbiIpCisKKwlTZXRDb250cm9sUmVmZXJlbmNlKChDb250cm9sUmVmKWFyZzAsIChTSW50MzIpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fU2V0Q29udHJvbFJlZmVyZW5jZSAqLworCisjaWZuZGVmIE5PX1NldENvbnRyb2xUaXRsZVdpdGhDRlN0cmluZworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0Q29udHJvbFRpdGxlV2l0aENGU3RyaW5nCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiU2V0Q29udHJvbFRpdGxlV2l0aENGU3RyaW5nXG4iKQorCisJcmV0dXJuIChqaW50KVNldENvbnRyb2xUaXRsZVdpdGhDRlN0cmluZygoQ29udHJvbFJlZilhcmcwLCAoQ0ZTdHJpbmdSZWYpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fU2V0Q29udHJvbFRpdGxlV2l0aENGU3RyaW5nICovCisKKyNpZm5kZWYgTk9fU2V0Q29udHJvbFZpZXdTaXplCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRDb250cm9sVmlld1NpemUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJTZXRDb250cm9sVmlld1NpemVcbiIpCisKKwlTZXRDb250cm9sVmlld1NpemUoKENvbnRyb2xSZWYpYXJnMCwgKFNJbnQzMilhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19TZXRDb250cm9sVmlld1NpemUgKi8KKworI2lmbmRlZiBOT19TZXRDdXJzb3IKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldEN1cnNvcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJTZXRDdXJzb3JcbiIpCisKKwlTZXRDdXJzb3IoKGNvbnN0IEN1cnNvciAqKWFyZzApOworfQorI2VuZGlmIC8qIE5PX1NldEN1cnNvciAqLworCisjaWZuZGVmIE5PX1NldERhdGFCcm93c2VyQ2FsbGJhY2tzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3NlckNhbGxiYWNrcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxKQoreworCURhdGFCcm93c2VyQ2FsbGJhY2tzIF9hcmcxPXswfSwgKmxwYXJnMT1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJTZXREYXRhQnJvd3NlckNhbGxiYWNrc1xuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXREYXRhQnJvd3NlckNhbGxiYWNrc0ZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJcmMgPSAoamludClTZXREYXRhQnJvd3NlckNhbGxiYWNrcygoQ29udHJvbFJlZilhcmcwLCAoY29uc3QgRGF0YUJyb3dzZXJDYWxsYmFja3MgKilscGFyZzEpOworCWlmIChhcmcxKSBzZXREYXRhQnJvd3NlckNhbGxiYWNrc0ZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1NldERhdGFCcm93c2VyQ2FsbGJhY2tzICovCisKKyNpZm5kZWYgTk9fU2V0RGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3MKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEpCit7CisJRGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3MgX2FyZzE9ezB9LCAqbHBhcmcxPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIlNldERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlyYyA9IChqaW50KVNldERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzKChDb250cm9sUmVmKWFyZzAsIChjb25zdCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrcyAqKWxwYXJnMSk7CisJaWYgKGFyZzEpIHNldERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzRmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fU2V0RGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3MgKi8KKworI2lmbmRlZiBOT19TZXREYXRhQnJvd3NlclRhYmxlVmlld05hbWVkQ29sdW1uV2lkdGgKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldERhdGFCcm93c2VyVGFibGVWaWV3TmFtZWRDb2x1bW5XaWR0aAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqc2hvcnQgYXJnMikKK3sKKwlERUJVR19DQUxMKCJTZXREYXRhQnJvd3NlclRhYmxlVmlld05hbWVkQ29sdW1uV2lkdGhcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdOYW1lZENvbHVtbldpZHRoKChDb250cm9sUmVmKWFyZzAsIChEYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtbklEKWFyZzEsIChVSW50MTYpYXJnMik7Cit9CisjZW5kaWYgLyogTk9fU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdOYW1lZENvbHVtbldpZHRoICovCisKKyNpZm5kZWYgTk9fU2V0RGF0YUJyb3dzZXJIYXNTY3JvbGxCYXJzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3Nlckhhc1Njcm9sbEJhcnMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpib29sZWFuIGFyZzEsIGpib29sZWFuIGFyZzIpCit7CisJREVCVUdfQ0FMTCgiU2V0RGF0YUJyb3dzZXJIYXNTY3JvbGxCYXJzXG4iKQorCisJcmV0dXJuIChqaW50KVNldERhdGFCcm93c2VySGFzU2Nyb2xsQmFycygoQ29udHJvbFJlZilhcmcwLCAoQm9vbGVhbilhcmcxLCAoQm9vbGVhbilhcmcyKTsKK30KKyNlbmRpZiAvKiBOT19TZXREYXRhQnJvd3Nlckhhc1Njcm9sbEJhcnMgKi8KKworI2lmbmRlZiBOT19TZXREYXRhQnJvd3Nlckl0ZW1EYXRhQm9vbGVhblZhbHVlCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3Nlckl0ZW1EYXRhQm9vbGVhblZhbHVlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqYm9vbGVhbiBhcmcxKQoreworCURFQlVHX0NBTEwoIlNldERhdGFCcm93c2VySXRlbURhdGFCb29sZWFuVmFsdWVcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUJvb2xlYW5WYWx1ZSgoRGF0YUJyb3dzZXJJdGVtRGF0YVJlZilhcmcwLCAoQm9vbGVhbilhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19TZXREYXRhQnJvd3Nlckl0ZW1EYXRhQm9vbGVhblZhbHVlICovCisKKyNpZm5kZWYgTk9fU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUJ1dHRvblZhbHVlCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3Nlckl0ZW1EYXRhQnV0dG9uVmFsdWUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxKQoreworCURFQlVHX0NBTEwoIlNldERhdGFCcm93c2VySXRlbURhdGFCdXR0b25WYWx1ZVxuIikKKworCXJldHVybiAoamludClTZXREYXRhQnJvd3Nlckl0ZW1EYXRhQnV0dG9uVmFsdWUoKERhdGFCcm93c2VySXRlbURhdGFSZWYpYXJnMCwgKFRoZW1lQnV0dG9uVmFsdWUpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUJ1dHRvblZhbHVlICovCisKKyNpZm5kZWYgTk9fU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUljb24KK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldERhdGFCcm93c2VySXRlbURhdGFJY29uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUljb25cbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUljb24oKERhdGFCcm93c2VySXRlbURhdGFSZWYpYXJnMCwgKEljb25SZWYpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUljb24gKi8KKworI2lmbmRlZiBOT19TZXREYXRhQnJvd3Nlckl0ZW1EYXRhSXRlbUlECitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3Nlckl0ZW1EYXRhSXRlbUlECisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUl0ZW1JRFxuIikKKworCXJldHVybiAoamludClTZXREYXRhQnJvd3Nlckl0ZW1EYXRhSXRlbUlEKChEYXRhQnJvd3Nlckl0ZW1EYXRhUmVmKWFyZzAsIChEYXRhQnJvd3Nlckl0ZW1JRClhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19TZXREYXRhQnJvd3Nlckl0ZW1EYXRhSXRlbUlEICovCisKKyNpZm5kZWYgTk9fU2V0RGF0YUJyb3dzZXJJdGVtRGF0YVRleHQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldERhdGFCcm93c2VySXRlbURhdGFUZXh0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiU2V0RGF0YUJyb3dzZXJJdGVtRGF0YVRleHRcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0RGF0YUJyb3dzZXJJdGVtRGF0YVRleHQoKERhdGFCcm93c2VySXRlbURhdGFSZWYpYXJnMCwgKENGU3RyaW5nUmVmKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1NldERhdGFCcm93c2VySXRlbURhdGFUZXh0ICovCisKKyNpZm5kZWYgTk9fU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0Rpc2Nsb3N1cmVDb2x1bW4KK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldERhdGFCcm93c2VyTGlzdFZpZXdEaXNjbG9zdXJlQ29sdW1uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGpib29sZWFuIGFyZzIpCit7CisJREVCVUdfQ0FMTCgiU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0Rpc2Nsb3N1cmVDb2x1bW5cbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0Rpc2Nsb3N1cmVDb2x1bW4oKENvbnRyb2xSZWYpYXJnMCwgKERhdGFCcm93c2VyVGFibGVWaWV3Q29sdW1uSUQpYXJnMSwgKEJvb2xlYW4pYXJnMik7Cit9CisjZW5kaWYgLyogTk9fU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0Rpc2Nsb3N1cmVDb2x1bW4gKi8KKworI2lmbmRlZiBOT19TZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyQnRuSGVpZ2h0CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyQnRuSGVpZ2h0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJTZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyQnRuSGVpZ2h0XG4iKQorCisJcmV0dXJuIChqaW50KVNldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJCdG5IZWlnaHQoKENvbnRyb2xSZWYpYXJnMCwgKFVJbnQxNilhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19TZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyQnRuSGVpZ2h0ICovCiAKIAorI2lmbmRlZiBOT19TZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzYworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgam9iamVjdCBhcmcyKQoreworCURhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjIF9hcmcyLCAqbHBhcmcyPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIlNldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjXG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9IGdldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmllbGRzKGVudiwgYXJnMiwgJl9hcmcyKTsKKwlyYyA9IChqaW50KVNldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjKChDb250cm9sUmVmKWFyZzAsIChEYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtbklEKWFyZzEsIChEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzYyAqKWxwYXJnMik7CisJaWYgKGFyZzIpIHNldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjRmllbGRzKGVudiwgYXJnMiwgbHBhcmcyKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19TZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMikKK3sKKwlERUJVR19DQUxMKCJTZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uXG4iKQorCisJcmV0dXJuIChqaW50KVNldERhdGFCcm93c2VyU2Nyb2xsUG9zaXRpb24oKENvbnRyb2xSZWYpYXJnMCwgKFVJbnQzMilhcmcxLCAoVUludDMyKWFyZzIpOworfQorI2VuZGlmIC8qIE5PX1NldERhdGFCcm93c2VyU2Nyb2xsUG9zaXRpb24gKi8KKworI2lmbmRlZiBOT19TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50QXJyYXkgYXJnMiwgamludCBhcmczKQoreworCWppbnQgKmxwYXJnMj1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJTZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXNcbiIpCisKKwlpZiAoYXJnMikgbHBhcmcyID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJcmMgPSAoamludClTZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMoKENvbnRyb2xSZWYpYXJnMCwgKFVJbnQzMilhcmcxLCAoY29uc3QgRGF0YUJyb3dzZXJJdGVtSUQgKilscGFyZzIsIChEYXRhQnJvd3NlclNldE9wdGlvbilhcmczKTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIGxwYXJnMiwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1NldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyAqLworCisjaWZuZGVmIE5PX1NldERhdGFCcm93c2VyU2VsZWN0aW9uRmxhZ3MKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldERhdGFCcm93c2VyU2VsZWN0aW9uRmxhZ3MKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJTZXREYXRhQnJvd3NlclNlbGVjdGlvbkZsYWdzXG4iKQorCisJcmV0dXJuIChqaW50KVNldERhdGFCcm93c2VyU2VsZWN0aW9uRmxhZ3MoKENvbnRyb2xSZWYpYXJnMCwgKERhdGFCcm93c2VyU2VsZWN0aW9uRmxhZ3MpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fU2V0RGF0YUJyb3dzZXJTZWxlY3Rpb25GbGFncyAqLworCisjaWZuZGVmIE5PX1NldERhdGFCcm93c2VyVGFibGVWaWV3Q29sdW1uUG9zaXRpb24KK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldERhdGFCcm93c2VyVGFibGVWaWV3Q29sdW1uUG9zaXRpb24KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyKQoreworCisJREVCVUdfQ0FMTCgiU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdDb2x1bW5Qb3NpdGlvblxuIikKKworCXJldHVybiAoamludClTZXREYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtblBvc2l0aW9uKChDb250cm9sUmVmKWFyZzAsIChEYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtbklEKWFyZzEsIChEYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtbkluZGV4KWFyZzIpOworCit9CisjZW5kaWYgLyogTk9fU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdDb2x1bW5Qb3NpdGlvbiAqLworCisjaWZuZGVmIE5PX1NldERhdGFCcm93c2VyVGFibGVWaWV3SXRlbVJvdworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdJdGVtUm93CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMikKK3sKKworCURFQlVHX0NBTEwoIlNldERhdGFCcm93c2VyVGFibGVWaWV3SXRlbVJvd1xuIikKKworCXJldHVybiAoamludClTZXREYXRhQnJvd3NlclRhYmxlVmlld0l0ZW1Sb3coKENvbnRyb2xSZWYpYXJnMCwgKERhdGFCcm93c2VySXRlbUlEKWFyZzEsIChEYXRhQnJvd3NlclRhYmxlVmlld1Jvd0luZGV4KWFyZzIpOworCit9CisjZW5kaWYgLyogTk9fU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdJdGVtUm93ICovCisKKyNpZm5kZWYgTk9fU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdIaWxpdGVTdHlsZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdIaWxpdGVTdHlsZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIlNldERhdGFCcm93c2VyVGFibGVWaWV3SGlsaXRlU3R5bGVcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdIaWxpdGVTdHlsZSgoQ29udHJvbFJlZilhcmcwLCAoRGF0YUJyb3dzZXJUYWJsZVZpZXdIaWxpdGVTdHlsZSlhcmcxKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX1NldERhdGFCcm93c2VyVGFyZ2V0CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXREYXRhQnJvd3NlclRhcmdldAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIlNldERhdGFCcm93c2VyVGFyZ2V0XG4iKQorCisJcmV0dXJuIChqaW50KVNldERhdGFCcm93c2VyVGFyZ2V0KChDb250cm9sUmVmKWFyZzAsIChEYXRhQnJvd3Nlckl0ZW1JRClhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19TZXREYXRhQnJvd3NlclRhcmdldCAqLworCisjaWZuZGVmIE5PX1NldEV2ZW50TG9vcFRpbWVyTmV4dEZpcmVUaW1lCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRFdmVudExvb3BUaW1lck5leHRGaXJlVGltZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamRvdWJsZSBhcmcxKQoreworCURFQlVHX0NBTEwoIlNldEV2ZW50TG9vcFRpbWVyTmV4dEZpcmVUaW1lXG4iKQorCisJcmV0dXJuIChqaW50KVNldEV2ZW50TG9vcFRpbWVyTmV4dEZpcmVUaW1lKChFdmVudExvb3BUaW1lclJlZilhcmcwLCAoRXZlbnRUaW1lckludGVydmFsKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1NldEV2ZW50TG9vcFRpbWVyTmV4dEZpcmVUaW1lICovCisKKyNpZm5kZWYgTk9fU2V0RXZlbnRQYXJhbWV0ZXIKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldEV2ZW50UGFyYW1ldGVyCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqY2hhckFycmF5IGFyZzQpCit7CisJamNoYXIgKmxwYXJnND1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJTZXRFdmVudFBhcmFtZXRlclxuIikKKworCWlmIChhcmc0KSBscGFyZzQgPSAoKmVudiktPkdldENoYXJBcnJheUVsZW1lbnRzKGVudiwgYXJnNCwgTlVMTCk7CisJcmMgPSAoamludClTZXRFdmVudFBhcmFtZXRlcigoRXZlbnRSZWYpYXJnMCwgKEV2ZW50UGFyYW1OYW1lKWFyZzEsIChFdmVudFBhcmFtVHlwZSlhcmcyLCAoVUludDMyKWFyZzMsIChjb25zdCB2b2lkICopbHBhcmc0KTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlQ2hhckFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBscGFyZzQsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19TZXRFdmVudFBhcmFtZXRlciAqLworCisjaWZuZGVmIE5PX1NldEZvbnRJbmZvRm9yU2VsZWN0aW9uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRGb250SW5mb0ZvclNlbGVjdGlvbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnQgYXJnMykKK3sKKwlERUJVR19DQUxMKCJTZXRGb250SW5mb0ZvclNlbGVjdGlvblxuIikKKworCXJldHVybiAoamludClTZXRGb250SW5mb0ZvclNlbGVjdGlvbigoT1NUeXBlKWFyZzAsIChVSW50MzIpYXJnMSwgKHZvaWQgKilhcmcyLCAoSElPYmplY3RSZWYpYXJnMyk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19TZXRGcm9udFByb2Nlc3MKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldEZyb250UHJvY2VzcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnRBcnJheSBhcmcwKQoreworCWppbnQgKmxwYXJnMD1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJTZXRGcm9udFByb2Nlc3NcbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMCwgTlVMTCk7CisJcmMgPSAoamludClTZXRGcm9udFByb2Nlc3MoKGNvbnN0IFByb2Nlc3NTZXJpYWxOdW1iZXIgKilscGFyZzApOworCWlmIChhcmcwKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMCwgbHBhcmcwLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fU2V0RnJvbnRQcm9jZXNzICovCisKKyNpZm5kZWYgTk9fU2V0R1dvcmxkCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRHV29ybGQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJTZXRHV29ybGRcbiIpCisKKwlTZXRHV29ybGQoKENHcmFmUHRyKWFyZzAsIChHREhhbmRsZSlhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19TZXRHV29ybGQgKi8KKworI2lmbmRlZiBOT19TZXRLZXlib2FyZEZvY3VzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRLZXlib2FyZEZvY3VzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGpzaG9ydCBhcmcyKQoreworCURFQlVHX0NBTEwoIlNldEtleWJvYXJkRm9jdXNcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0S2V5Ym9hcmRGb2N1cygoV2luZG93UmVmKWFyZzAsIChDb250cm9sUmVmKWFyZzEsIChDb250cm9sRm9jdXNQYXJ0KWFyZzIpOworfQorI2VuZGlmIC8qIE5PX1NldEtleWJvYXJkRm9jdXMgKi8KKworI2lmbmRlZiBOT19TZXRNZW51Q29tbWFuZE1hcmsKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldE1lbnVDb21tYW5kTWFyaworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqY2hhciBhcmcyKQoreworCURFQlVHX0NBTEwoIlNldE1lbnVDb21tYW5kTWFya1xuIikKKworCXJldHVybiAoamludClTZXRNZW51Q29tbWFuZE1hcmsoKE1lbnVSZWYpYXJnMCwgKE1lbnVDb21tYW5kKWFyZzEsIChVbmlDaGFyKWFyZzIpOworfQorI2VuZGlmIC8qIE5PX1NldE1lbnVDb21tYW5kTWFyayAqLworCisjaWZuZGVmIE5PX1NldE1lbnVGb250CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRNZW51Rm9udAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGpzaG9ydCBhcmcyKQoreworCURFQlVHX0NBTEwoIlNldE1lbnVGb250XG4iKQorCisJcmV0dXJuIChqaW50KVNldE1lbnVGb250KChNZW51UmVmKWFyZzAsIChTSW50MTYpYXJnMSwgKFVJbnQxNilhcmcyKTsKK30KKyNlbmRpZiAvKiBOT19TZXRNZW51Rm9udCAqLworCisjaWZuZGVmIE5PX1NldE1lbnVJdGVtQ29tbWFuZEtleQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0TWVudUl0ZW1Db21tYW5kS2V5CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSwgamJvb2xlYW4gYXJnMiwgamNoYXIgYXJnMykKK3sKKwlERUJVR19DQUxMKCJTZXRNZW51SXRlbUNvbW1hbmRLZXlcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0TWVudUl0ZW1Db21tYW5kS2V5KChNZW51UmVmKWFyZzAsIChNZW51SXRlbUluZGV4KWFyZzEsIChCb29sZWFuKWFyZzIsIChVSW50MTYpYXJnMyk7Cit9CisjZW5kaWYgLyogTk9fU2V0TWVudUl0ZW1Db21tYW5kS2V5ICovCisKKyNpZm5kZWYgTk9fU2V0TWVudUl0ZW1IaWVyYXJjaGljYWxNZW51CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRNZW51SXRlbUhpZXJhcmNoaWNhbE1lbnUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxLCBqaW50IGFyZzIpCit7CisJREVCVUdfQ0FMTCgiU2V0TWVudUl0ZW1IaWVyYXJjaGljYWxNZW51XG4iKQorCisJcmV0dXJuIChqaW50KVNldE1lbnVJdGVtSGllcmFyY2hpY2FsTWVudSgoTWVudVJlZilhcmcwLCAoTWVudUl0ZW1JbmRleClhcmcxLCAoTWVudVJlZilhcmcyKTsKK30KKyNlbmRpZiAvKiBOT19TZXRNZW51SXRlbUhpZXJhcmNoaWNhbE1lbnUgKi8KKworI2lmbmRlZiBOT19TZXRNZW51SXRlbUljb25IYW5kbGUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldE1lbnVJdGVtSWNvbkhhbmRsZQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGpieXRlIGFyZzIsIGppbnQgYXJnMykKK3sKKwlERUJVR19DQUxMKCJTZXRNZW51SXRlbUljb25IYW5kbGVcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0TWVudUl0ZW1JY29uSGFuZGxlKChNZW51UmVmKWFyZzAsIChTSW50MTYpYXJnMSwgKFVJbnQ4KWFyZzIsIChIYW5kbGUpYXJnMyk7Cit9CisjZW5kaWYgLyogTk9fU2V0TWVudUl0ZW1JY29uSGFuZGxlICovCisKKyNpZm5kZWYgTk9fU2V0TWVudUl0ZW1LZXlHbHlwaAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0TWVudUl0ZW1LZXlHbHlwaAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGpzaG9ydCBhcmcyKQoreworCURFQlVHX0NBTEwoIlNldE1lbnVJdGVtS2V5R2x5cGhcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0TWVudUl0ZW1LZXlHbHlwaCgoTWVudVJlZilhcmcwLCAoU0ludDE2KWFyZzEsIChTSW50MTYpYXJnMik7Cit9CisjZW5kaWYgLyogTk9fU2V0TWVudUl0ZW1LZXlHbHlwaCAqLworCisjaWZuZGVmIE5PX1NldE1lbnVJdGVtTW9kaWZpZXJzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRNZW51SXRlbU1vZGlmaWVycworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGpieXRlIGFyZzIpCit7CisJREVCVUdfQ0FMTCgiU2V0TWVudUl0ZW1Nb2RpZmllcnNcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0TWVudUl0ZW1Nb2RpZmllcnMoKE1lbnVSZWYpYXJnMCwgKFNJbnQxNilhcmcxLCAoVUludDgpYXJnMik7Cit9CisjZW5kaWYgLyogTk9fU2V0TWVudUl0ZW1Nb2RpZmllcnMgKi8KKworI2lmbmRlZiBOT19TZXRNZW51SXRlbVJlZkNvbgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0TWVudUl0ZW1SZWZDb24KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxLCBqaW50IGFyZzIpCit7CisJREVCVUdfQ0FMTCgiU2V0TWVudUl0ZW1SZWZDb25cbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0TWVudUl0ZW1SZWZDb24oKE1lbnVSZWYpYXJnMCwgKFNJbnQxNilhcmcxLCAoVUludDMyKWFyZzIpOworfQorI2VuZGlmIC8qIE5PX1NldE1lbnVJdGVtUmVmQ29uICovCisKKyNpZm5kZWYgTk9fU2V0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxLCBqaW50IGFyZzIpCit7CisJREVCVUdfQ0FMTCgiU2V0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nXG4iKQorCisJcmV0dXJuIChqaW50KVNldE1lbnVJdGVtVGV4dFdpdGhDRlN0cmluZygoTWVudVJlZilhcmcwLCAoTWVudUl0ZW1JbmRleClhcmcxLCAoQ0ZTdHJpbmdSZWYpYXJnMik7Cit9CisjZW5kaWYgLyogTk9fU2V0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nICovCisKKyNpZm5kZWYgTk9fU2V0TWVudVRpdGxlV2l0aENGU3RyaW5nCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRNZW51VGl0bGVXaXRoQ0ZTdHJpbmcKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJTZXRNZW51VGl0bGVXaXRoQ0ZTdHJpbmdcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0TWVudVRpdGxlV2l0aENGU3RyaW5nKChNZW51UmVmKWFyZzAsIChDRlN0cmluZ1JlZilhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19TZXRNZW51VGl0bGVXaXRoQ0ZTdHJpbmcgKi8KKworI2lmbmRlZiBOT19TZXRPcmlnaW4KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldE9yaWdpbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpzaG9ydCBhcmcwLCBqc2hvcnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJTZXRPcmlnaW5cbiIpCisKKwlTZXRPcmlnaW4oKHNob3J0KWFyZzAsIChzaG9ydClhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19TZXRPcmlnaW4gKi8KKworI2lmbmRlZiBOT19TZXRQb3J0CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRQb3J0CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIlNldFBvcnRcbiIpCisKKwlTZXRQb3J0KChHcmFmUHRyKWFyZzApOworfQorI2VuZGlmIC8qIE5PX1NldFBvcnQgKi8KKworI2lmbmRlZiBOT19TZXRQb3J0Qm91bmRzCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIE9TX05BVElWRShTZXRQb3J0Qm91bmRzKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxKQoreworCVJlY3QgX2FyZzEsICpscGFyZzE9TlVMTDsKKworCURFQlVHX0NBTEwoIlNldFBvcnRCb3VuZHNcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJU2V0UG9ydEJvdW5kcygoQ0dyYWZQdHIpYXJnMCwgKGNvbnN0IFJlY3QgKilscGFyZzEpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX1NldFBvcnRXaW5kb3dQb3J0CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRQb3J0V2luZG93UG9ydAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJTZXRQb3J0V2luZG93UG9ydFxuIikKKworCVNldFBvcnRXaW5kb3dQb3J0KChXaW5kb3dSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fU2V0UG9ydFdpbmRvd1BvcnQgKi8KKworI2lmbmRlZiBOT19TZXRQdAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0UHQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzAsIGpzaG9ydCBhcmcxLCBqc2hvcnQgYXJnMikKK3sKKwlQb2ludCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgiU2V0UHRcbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gZ2V0UG9pbnRGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCVNldFB0KChQb2ludCAqKWxwYXJnMCwgKHNob3J0KWFyZzEsIChzaG9ydClhcmcyKTsKKwlpZiAoYXJnMCkgc2V0UG9pbnRGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworfQorI2VuZGlmIC8qIE5PX1NldFB0ICovCisKKyNpZm5kZWYgTk9fU2V0UmVjdAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0UmVjdAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwganNob3J0IGFyZzEsIGpzaG9ydCBhcmcyLCBqc2hvcnQgYXJnMywganNob3J0IGFyZzQpCit7CisJUmVjdCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgiU2V0UmVjdFxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlTZXRSZWN0KChSZWN0ICopbHBhcmcwLCAoc2hvcnQpYXJnMSwgKHNob3J0KWFyZzIsIChzaG9ydClhcmczLCAoc2hvcnQpYXJnNCk7CisJaWYgKGFyZzApIHNldFJlY3RGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworfQorI2VuZGlmIC8qIE5PX1NldFJlY3QgKi8KKworI2lmbmRlZiBOT19TZXRSZWN0UmduCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRSZWN0UmduCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSwganNob3J0IGFyZzIsIGpzaG9ydCBhcmczLCBqc2hvcnQgYXJnNCkKK3sKKwlERUJVR19DQUxMKCJTZXRSZWN0UmduXG4iKQorCisJU2V0UmVjdFJnbigoUmduSGFuZGxlKWFyZzAsIChzaG9ydClhcmcxLCAoc2hvcnQpYXJnMiwgKHNob3J0KWFyZzMsIChzaG9ydClhcmc0KTsKK30KKyNlbmRpZiAvKiBOT19TZXRSZWN0UmduICovCisKKyNpZm5kZWYgTk9fU2V0Um9vdE1lbnUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldFJvb3RNZW51CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIlNldFJvb3RNZW51XG4iKQorCisJcmV0dXJuIChqaW50KVNldFJvb3RNZW51KChNZW51UmVmKWFyZzApOworfQorI2VuZGlmIC8qIE5PX1NldFJvb3RNZW51ICovCisKKyNpZm5kZWYgTk9fU2V0VGhlbWVCYWNrZ3JvdW5kCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRUaGVtZUJhY2tncm91bmQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqc2hvcnQgYXJnMCwganNob3J0IGFyZzEsIGpib29sZWFuIGFyZzIpCit7CisJREVCVUdfQ0FMTCgiU2V0VGhlbWVCYWNrZ3JvdW5kXG4iKQorCisJcmV0dXJuIChqaW50KVNldFRoZW1lQmFja2dyb3VuZCgoVGhlbWVCcnVzaClhcmcwLCAoU0ludDE2KWFyZzEsIChCb29sZWFuKWFyZzIpOworfQorI2VuZGlmIC8qIE5PX1NldFRoZW1lQmFja2dyb3VuZCAqLworCisjaWZuZGVmIE5PX1NldFRoZW1lQ3Vyc29yCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRUaGVtZUN1cnNvcgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJTZXRUaGVtZUN1cnNvclxuIikKKworCXJldHVybiAoamludClTZXRUaGVtZUN1cnNvcigoVGhlbWVDdXJzb3IpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fU2V0VGhlbWVDdXJzb3IgKi8KKworI2lmbmRlZiBOT19TZXRUaGVtZURyYXdpbmdTdGF0ZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0VGhlbWVEcmF3aW5nU3RhdGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpib29sZWFuIGFyZzEpCit7CisJREVCVUdfQ0FMTCgiU2V0VGhlbWVEcmF3aW5nU3RhdGVcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0VGhlbWVEcmF3aW5nU3RhdGUoKFRoZW1lRHJhd2luZ1N0YXRlKWFyZzAsIChCb29sZWFuKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1NldFRoZW1lRHJhd2luZ1N0YXRlICovCisKKyNpZm5kZWYgTk9fU2V0VGhlbWVXaW5kb3dCYWNrZ3JvdW5kCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRUaGVtZVdpbmRvd0JhY2tncm91bmQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxLCBqYm9vbGVhbiBhcmcyKQoreworCURFQlVHX0NBTEwoIlNldFRoZW1lV2luZG93QmFja2dyb3VuZFxuIikKKworCXJldHVybiAoamludClTZXRUaGVtZVdpbmRvd0JhY2tncm91bmQoKFdpbmRvd1JlZilhcmcwLCAoVGhlbWVCcnVzaClhcmcxLCAoQm9vbGVhbilhcmcyKTsKK30KKyNlbmRpZiAvKiBOT19TZXRUaGVtZVdpbmRvd0JhY2tncm91bmQgKi8KKworI2lmbmRlZiBOT19TZXRVcENvbnRyb2xCYWNrZ3JvdW5kCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRVcENvbnRyb2xCYWNrZ3JvdW5kCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqc2hvcnQgYXJnMSwgamJvb2xlYW4gYXJnMikKK3sKKwlERUJVR19DQUxMKCJTZXRVcENvbnRyb2xCYWNrZ3JvdW5kXG4iKQorCisJcmV0dXJuIChqaW50KVNldFVwQ29udHJvbEJhY2tncm91bmQoKENvbnRyb2xSZWYpYXJnMCwgKFNJbnQxNilhcmcxLCAoQm9vbGVhbilhcmcyKTsKK30KKyNlbmRpZiAvKiBOT19TZXRVcENvbnRyb2xCYWNrZ3JvdW5kICovCisKKyNpZm5kZWYgTk9fU2V0V1JlZkNvbgorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0V1JlZkNvbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIlNldFdSZWZDb25cbiIpCisKKwlTZXRXUmVmQ29uKChXaW5kb3dSZWYpYXJnMCwgKGxvbmcpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fU2V0V1JlZkNvbiAqLworCisjaWZuZGVmIE5PX1NldFdpbmRvd0FjdGl2YXRpb25TY29wZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0V2luZG93QWN0aXZhdGlvblNjb3BlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiU2V0V2luZG93QWN0aXZhdGlvblNjb3BlXG4iKQorCisJcmV0dXJuIChqaW50KVNldFdpbmRvd0FjdGl2YXRpb25TY29wZSgoV2luZG93UmVmKWFyZzAsIChXaW5kb3dBY3RpdmF0aW9uU2NvcGUpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fU2V0V2luZG93QWN0aXZhdGlvblNjb3BlICovCisKKyNpZm5kZWYgTk9fU2V0V2luZG93Qm91bmRzCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TZXRXaW5kb3dCb3VuZHMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxLCBqb2JqZWN0IGFyZzIpCit7CisJUmVjdCBfYXJnMiwgKmxwYXJnMj1OVUxMOworCisJREVCVUdfQ0FMTCgiU2V0V2luZG93Qm91bmRzXG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcyLCAmX2FyZzIpOworCVNldFdpbmRvd0JvdW5kcygoV2luZG93UmVmKWFyZzAsIChXaW5kb3dSZWdpb25Db2RlKWFyZzEsIChSZWN0ICopbHBhcmcyKTsKKwlpZiAoYXJnMikgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzIsIGxwYXJnMik7Cit9CisjZW5kaWYgLyogTk9fU2V0V2luZG93Qm91bmRzICovCisKKyNpZm5kZWYgTk9fU2V0V2luZG93RGVmYXVsdEJ1dHRvbgorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0V2luZG93RGVmYXVsdEJ1dHRvbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIlNldFdpbmRvd0RlZmF1bHRCdXR0b25cbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0V2luZG93RGVmYXVsdEJ1dHRvbigoV2luZG93UmVmKWFyZzAsIChDb250cm9sUmVmKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1NldFdpbmRvd0RlZmF1bHRCdXR0b24gKi8KKworI2lmbmRlZiBOT19TZXRXaW5kb3dHcm91cAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0V2luZG93R3JvdXAKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJTZXRXaW5kb3dHcm91cFxuIikKKworCXJldHVybiAoamludClTZXRXaW5kb3dHcm91cCgoV2luZG93UmVmKWFyZzAsIChXaW5kb3dHcm91cFJlZilhcmcxKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX1NldFdpbmRvd0dyb3VwT3duZXIKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldFdpbmRvd0dyb3VwT3duZXIKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJTZXRXaW5kb3dHcm91cE93bmVyXG4iKQorCisJcmV0dXJuIChqaW50KVNldFdpbmRvd0dyb3VwT3duZXIoKFdpbmRvd0dyb3VwUmVmKWFyZzAsIChXaW5kb3dSZWYpYXJnMSk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19TZXRXaW5kb3dHcm91cFBhcmVudAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2V0V2luZG93R3JvdXBQYXJlbnQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSkKK3sKKwlERUJVR19DQUxMKCJTZXRXaW5kb3dHcm91cFBhcmVudFxuIikKKworCXJldHVybiAoamludClTZXRXaW5kb3dHcm91cFBhcmVudCgoV2luZG93R3JvdXBSZWYpYXJnMCwgKFdpbmRvd0dyb3VwUmVmKWFyZzEpOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fU2V0V2luZG93TW9kYWxpdHkKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldFdpbmRvd01vZGFsaXR5CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMikKK3sKKwlERUJVR19DQUxMKCJTZXRXaW5kb3dNb2RhbGl0eVxuIikKKworCXJldHVybiAoamludClTZXRXaW5kb3dNb2RhbGl0eSgoV2luZG93UmVmKWFyZzAsIChXaW5kb3dNb2RhbGl0eSlhcmcxLCAoV2luZG93UmVmKWFyZzIpOworfQorI2VuZGlmIC8qIE5PX1NldFdpbmRvd01vZGFsaXR5ICovCisKKyNpZm5kZWYgTk9fU2V0V2luZG93VGl0bGVXaXRoQ0ZTdHJpbmcKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1NldFdpbmRvd1RpdGxlV2l0aENGU3RyaW5nCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiU2V0V2luZG93VGl0bGVXaXRoQ0ZTdHJpbmdcbiIpCisKKwlyZXR1cm4gKGppbnQpU2V0V2luZG93VGl0bGVXaXRoQ0ZTdHJpbmcoKFdpbmRvd1JlZilhcmcwLCAoQ0ZTdHJpbmdSZWYpYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fU2V0V2luZG93VGl0bGVXaXRoQ0ZTdHJpbmcgKi8KKworI2lmbmRlZiBOT19TaG93V2luZG93CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TaG93V2luZG93CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIlNob3dXaW5kb3dcbiIpCisKKwlTaG93V2luZG93KChXaW5kb3dSZWYpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fU2hvd1dpbmRvdyAqLworCisjaWZuZGVmIE5PX1NpemVDb250cm9sCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TaXplQ29udHJvbAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGpzaG9ydCBhcmcyKQoreworCURFQlVHX0NBTEwoIlNpemVDb250cm9sXG4iKQorCisJU2l6ZUNvbnRyb2woKENvbnRyb2xSZWYpYXJnMCwgKFNJbnQxNilhcmcxLCAoU0ludDE2KWFyZzIpOworfQorI2VuZGlmIC8qIE5PX1NpemVDb250cm9sICovCisKKyNpZm5kZWYgTk9fU2l6ZVdpbmRvdworSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU2l6ZVdpbmRvdworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwganNob3J0IGFyZzEsIGpzaG9ydCBhcmcyLCBqYm9vbGVhbiBhcmczKQoreworCURFQlVHX0NBTEwoIlNpemVXaW5kb3dcbiIpCisKKwlTaXplV2luZG93KChXaW5kb3dSZWYpYXJnMCwgKHNob3J0KWFyZzEsIChzaG9ydClhcmcyLCAoQm9vbGVhbilhcmczKTsKK30KKyNlbmRpZiAvKiBOT19TaXplV2luZG93ICovCisKKyNpZm5kZWYgTk9fU3RpbGxEb3duCitKTklFWFBPUlQgamJvb2xlYW4gSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfU3RpbGxEb3duCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCkKK3sKKwlERUJVR19DQUxMKCJTdGlsbERvd25cbiIpCisKKwlyZXR1cm4gKGpib29sZWFuKVN0aWxsRG93bigpOworfQorI2VuZGlmIC8qIE5PX1N0aWxsRG93biAqLworCisjaWZuZGVmIE5PX1N5bmNDR0NvbnRleHRPcmlnaW5XaXRoUG9ydAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBPU19OQVRJVkUoU3luY0NHQ29udGV4dE9yaWdpbldpdGhQb3J0KQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIlN5bmNDR0NvbnRleHRPcmlnaW5XaXRoUG9ydFxuIikKKworCXJldHVybiAoamludClTeW5jQ0dDb250ZXh0T3JpZ2luV2l0aFBvcnQoKENHQ29udGV4dFJlZilhcmcwLCAoQ0dyYWZQdHIpYXJnMSk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19TeXNCZWVwCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19TeXNCZWVwCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwganNob3J0IGFyZzApCit7CisJREVCVUdfQ0FMTCgiU3lzQmVlcFxuIikKKworCVN5c0JlZXAoKHNob3J0KWFyZzApOworfQorI2VuZGlmIC8qIE5PX1N5c0JlZXAgKi8KKworI2lmbmRlZiBOT19UWE5BY3RpdmF0ZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOQWN0aXZhdGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamJvb2xlYW4gYXJnMikKK3sKKwlERUJVR19DQUxMKCJUWE5BY3RpdmF0ZVxuIikKKworCXJldHVybiAoamludClUWE5BY3RpdmF0ZSgoVFhOT2JqZWN0KWFyZzAsIChUWE5GcmFtZUlEKWFyZzEsIChUWE5TY3JvbGxCYXJTdGF0ZSlhcmcyKTsKK30KKyNlbmRpZiAvKiBOT19UWE5BY3RpdmF0ZSAqLworCisjaWZuZGVmIE5PX1RYTkFkanVzdEN1cnNvcgorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOQWRqdXN0Q3Vyc29yCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiVFhOQWN0aXZhdGVcbiIpCisKKwlUWE5BZGp1c3RDdXJzb3IoKFRYTk9iamVjdClhcmcwLCAoUmduSGFuZGxlKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1RYTkFkanVzdEN1cnNvciAqLworCisjaWZuZGVmIE5PX1RYTkNsaWNrCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5DbGljaworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxKQoreworCUV2ZW50UmVjb3JkIF9hcmcxLCAqbHBhcmcxPU5VTEw7CisKKwlERUJVR19DQUxMKCJUWE5DbGlja1xuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRFdmVudFJlY29yZEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJVFhOQ2xpY2soKFRYTk9iamVjdClhcmcwLCAoY29uc3QgRXZlbnRSZWNvcmQgKilscGFyZzEpOworCWlmIChhcmcxKSBzZXRFdmVudFJlY29yZEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fVFhOQ2xpY2sgKi8KKworI2lmbmRlZiBOT19UWE5Db3B5CitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5Db3B5CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIlRYTkNvcHlcbiIpCisKKwlyZXR1cm4gKGppbnQpVFhOQ29weSgoVFhOT2JqZWN0KWFyZzApOworfQorI2VuZGlmIC8qIE5PX1RYTkNvcHkgKi8KKworI2lmbmRlZiBOT19UWE5DdXQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTkN1dAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJUWE5DdXRcbiIpCisKKwlyZXR1cm4gKGppbnQpVFhOQ3V0KChUWE5PYmplY3QpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fVFhOQ3V0ICovCisKKyNpZm5kZWYgTk9fVFhORGF0YVNpemUKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTkRhdGFTaXplCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIlRYTkRhdGFTaXplXG4iKQorCisJcmV0dXJuIChqaW50KVRYTkRhdGFTaXplKChUWE5PYmplY3QpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fVFhORGF0YVNpemUgKi8KKworI2lmbmRlZiBOT19UWE5EZWxldGVPYmplY3QKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTkRlbGV0ZU9iamVjdAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJUWE5EZWxldGVPYmplY3RcbiIpCisKKwlUWE5EZWxldGVPYmplY3QoKFRYTk9iamVjdClhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19UWE5EZWxldGVPYmplY3QgKi8KKworI2lmbmRlZiBOT19UWE5EcmF3CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5EcmF3CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEpCit7CisJREVCVUdfQ0FMTCgiVFhORHJhd1xuIikKKworCVRYTkRyYXcoKFRYTk9iamVjdClhcmcwLCAoR1dvcmxkUHRyKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1RYTkRyYXcgKi8KKworI2lmbmRlZiBOT19UWE5FY2hvTW9kZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhORWNob01vZGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpjaGFyIGFyZzEsIGppbnQgYXJnMiwgamJvb2xlYW4gYXJnMykKK3sKKwlERUJVR19DQUxMKCJUWE5FY2hvTW9kZVxuIikKKworCXJldHVybiAoamludClUWE5FY2hvTW9kZSgoVFhOT2JqZWN0KWFyZzAsIChVbmlDaGFyKWFyZzEsIChUZXh0RW5jb2RpbmcpYXJnMiwgKEJvb2xlYW4pYXJnMyk7Cit9CisjZW5kaWYgLyogTk9fVFhORWNob01vZGUgKi8KKworI2lmbmRlZiBOT19UWE5Gb2N1cworSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhORm9jdXMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpib29sZWFuIGFyZzEpCit7CisJREVCVUdfQ0FMTCgiVFhORm9jdXNcbiIpCisKKwlUWE5Gb2N1cygoVFhOT2JqZWN0KWFyZzAsIChCb29sZWFuKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1RYTkZvY3VzICovCisKKyNpZm5kZWYgTk9fVFhOR2V0UmVjdEJvdW5kcworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOR2V0UmVjdEJvdW5kcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxLCBqb2JqZWN0IGFyZzIsIGpvYmplY3QgYXJnMykKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJVFhOTG9uZ1JlY3QgX2FyZzIsICpscGFyZzI9TlVMTDsKKwlUWE5Mb25nUmVjdCBfYXJnMywgKmxwYXJnMz1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJUWE5HZXRSZWN0Qm91bmRzXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCWlmIChhcmcyKSBscGFyZzIgPSBnZXRUWE5Mb25nUmVjdEZpZWxkcyhlbnYsIGFyZzIsICZfYXJnMik7CisJaWYgKGFyZzMpIGxwYXJnMyA9IGdldFRYTkxvbmdSZWN0RmllbGRzKGVudiwgYXJnMywgJl9hcmczKTsKKwlyYyA9IChqaW50KVRYTkdldFJlY3RCb3VuZHMoKFRYTk9iamVjdClhcmcwLCAoUmVjdCAqKWxwYXJnMSwgKFRYTkxvbmdSZWN0ICopbHBhcmcyLCAoVFhOTG9uZ1JlY3QgKilscGFyZzMpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlpZiAoYXJnMikgc2V0VFhOTG9uZ1JlY3RGaWVsZHMoZW52LCBhcmcyLCBscGFyZzIpOworCWlmIChhcmczKSBzZXRUWE5Mb25nUmVjdEZpZWxkcyhlbnYsIGFyZzMsIGxwYXJnMyk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1RYTkdldFJlY3RCb3VuZHMgKi8KKworI2lmbmRlZiBOT19UWE5HZXREYXRhCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5HZXREYXRhCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludEFycmF5IGFyZzMpCit7CisJamludCAqbHBhcmczPU5VTEw7CisJamludCByYzsKKworCURFQlVHX0NBTEwoIlRYTkdldERhdGFcbiIpCisKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJcmMgPSAoamludClUWE5HZXREYXRhKChUWE5PYmplY3QpYXJnMCwgKFRYTk9mZnNldClhcmcxLCAoVFhOT2Zmc2V0KWFyZzIsIChIYW5kbGUgKilscGFyZzMpOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fVFhOR2V0RGF0YSAqLworCisjaWZuZGVmIE5PX1RYTkdldExpbmVDb3VudAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOR2V0TGluZUNvdW50CisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50QXJyYXkgYXJnMSkKK3sKKwlqaW50ICpscGFyZzE9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiVFhOR2V0TGluZUNvdW50XG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCXJjID0gKGppbnQpVFhOR2V0TGluZUNvdW50KChUWE5PYmplY3QpYXJnMCwgKEl0ZW1Db3VudCAqKWxwYXJnMSk7CisJaWYgKGFyZzEpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19UWE5HZXRMaW5lQ291bnQgKi8KKworI2lmbmRlZiBOT19UWE5HZXRMaW5lTWV0cmljcworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOR2V0TGluZU1ldHJpY3MKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludEFycmF5IGFyZzIsIGppbnRBcnJheSBhcmczKQoreworCWppbnQgKmxwYXJnMj1OVUxMOworCWppbnQgKmxwYXJnMz1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJUWE5HZXRMaW5lTWV0cmljc1xuIikKKworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJcmMgPSAoamludClUWE5HZXRMaW5lTWV0cmljcygoVFhOT2JqZWN0KWFyZzAsIChVSW50MzIpYXJnMSwgKEZpeGVkICopbHBhcmcyLCAoRml4ZWQgKilscGFyZzMpOworCWlmIChhcmcyKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKKwlpZiAoYXJnMykgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzMsIGxwYXJnMywgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1RYTkdldExpbmVNZXRyaWNzKi8KKworI2lmbmRlZiBOT19UWE5HZXRWaWV3UmVjdAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOR2V0Vmlld1JlY3QKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSkKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisKKwlERUJVR19DQUxMKCJUWE5HZXRWaWV3UmVjdFxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlUWE5HZXRWaWV3UmVjdCgoVFhOT2JqZWN0KWFyZzAsIChSZWN0ICopbHBhcmcxKTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYgLyogTk9fVFhOR2V0Vmlld1JlY3QgKi8KKworI2lmbmRlZiBOT19UWE5HZXRUWE5PYmplY3RDb250cm9scworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOR2V0VFhOT2JqZWN0Q29udHJvbHMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludEFycmF5IGFyZzIsIGppbnRBcnJheSBhcmczKQoreworCWppbnQgKmxwYXJnMj1OVUxMOworCWppbnQgKmxwYXJnMz1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJUWE5HZXRUWE5PYmplY3RDb250cm9sc1xuIikKKworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJcmMgPSAoamludClUWE5HZXRUWE5PYmplY3RDb250cm9scygoVFhOT2JqZWN0KWFyZzAsIChJdGVtQ291bnQpYXJnMSwgKGNvbnN0IFRYTkNvbnRyb2xUYWcgKilscGFyZzIsIChUWE5Db250cm9sRGF0YSAqKWxwYXJnMyk7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fVFhOR2V0VFhOT2JqZWN0Q29udHJvbHMgKi8KKworI2lmbmRlZiBOT19UWE5HZXRTZWxlY3Rpb24KK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTkdldFNlbGVjdGlvbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludEFycmF5IGFyZzEsIGppbnRBcnJheSBhcmcyKQoreworCWppbnQgKmxwYXJnMT1OVUxMOworCWppbnQgKmxwYXJnMj1OVUxMOworCisJREVCVUdfQ0FMTCgiVFhOR2V0U2VsZWN0aW9uXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBOVUxMKTsKKwlUWE5HZXRTZWxlY3Rpb24oKFRYTk9iamVjdClhcmcwLCAoVFhOT2Zmc2V0ICopbHBhcmcxLCAoVFhOT2Zmc2V0ICopbHBhcmcyKTsKKwlpZiAoYXJnMSkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7CisJaWYgKGFyZzIpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworfQorI2VuZGlmIC8qIE5PX1RYTkdldFNlbGVjdGlvbiAqLworCisjaWZuZGVmIE5PX1RYTkluaXRUZXh0ZW5zaW9uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5Jbml0VGV4dGVuc2lvbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIpCit7CisJREVCVUdfQ0FMTCgiVFhOSW5pdFRleHRlbnNpb25cbiIpCisKKwlyZXR1cm4gKGppbnQpVFhOSW5pdFRleHRlbnNpb24oKGNvbnN0IFRYTk1hY09TUHJlZmVycmVkRm9udERlc2NyaXB0aW9uICopYXJnMCwgKEl0ZW1Db3VudClhcmcxLCAoVFhOSW5pdE9wdGlvbnMpYXJnMik7Cit9CisjZW5kaWYgLyogTk9fVFhOSW5pdFRleHRlbnNpb24gKi8KKworI2lmbmRlZiBOT19UWE5OZXdPYmplY3QKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTk5ld09iamVjdAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqb2JqZWN0IGFyZzIsIGppbnQgYXJnMywgamludCBhcmc0LCBqaW50IGFyZzUsIGppbnQgYXJnNiwgamludEFycmF5IGFyZzcsIGppbnRBcnJheSBhcmc4LCBqaW50IGFyZzkpCit7CisJUmVjdCBfYXJnMiwgKmxwYXJnMj1OVUxMOworCWppbnQgKmxwYXJnNz1OVUxMOworCWppbnQgKmxwYXJnOD1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJUWE5OZXdPYmplY3RcbiIpCisKKwlpZiAoYXJnMikgbHBhcmcyID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzIsICZfYXJnMik7CisJaWYgKGFyZzcpIGxwYXJnNyA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzcsIE5VTEwpOworCWlmIChhcmc4KSBscGFyZzggPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc4LCBOVUxMKTsKKwlyYyA9IChqaW50KVRYTk5ld09iamVjdCgoY29uc3QgRlNTcGVjICopYXJnMCwgKFdpbmRvd1JlZilhcmcxLCAoY29uc3QgUmVjdCAqKWxwYXJnMiwgKFRYTkZyYW1lT3B0aW9ucylhcmczLCAoVFhORnJhbWVUeXBlKWFyZzQsIChUWE5GaWxlVHlwZSlhcmc1LCAoVFhOUGVybWFuZW50VGV4dEVuY29kaW5nVHlwZSlhcmc2LCAoVFhOT2JqZWN0ICopbHBhcmc3LCAoVFhORnJhbWVJRCAqKWxwYXJnOCwgKFRYTk9iamVjdFJlZmNvbilhcmc5KTsKKwlpZiAoYXJnMikgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzIsIGxwYXJnMik7CisJaWYgKGFyZzcpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmc3LCBscGFyZzcsIDApOworCWlmIChhcmc4KSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnOCwgbHBhcmc4LCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fVFhOTmV3T2JqZWN0ICovCisKKyNpZm5kZWYgTk9fVFhOT2Zmc2V0VG9Qb2ludAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOT2Zmc2V0VG9Qb2ludAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqb2JqZWN0IGFyZzIpCit7CisJUG9pbnQgX2FyZzIsICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiVFhOT2Zmc2V0VG9Qb2ludFxuIikKKworCWlmIChhcmcyKSBscGFyZzIgPSBnZXRQb2ludEZpZWxkcyhlbnYsIGFyZzIsICZfYXJnMik7CisJcmMgPSAoamludClUWE5PZmZzZXRUb1BvaW50KChUWE5PYmplY3QpYXJnMCwgKFRYTk9mZnNldClhcmcxLCAoUG9pbnQgKilscGFyZzIpOworCWlmIChhcmcyKSBzZXRQb2ludEZpZWxkcyhlbnYsIGFyZzIsIGxwYXJnMik7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1RYTk9mZnNldFRvUG9pbnQgKi8KKworI2lmbmRlZiBOT19UWE5QYXN0ZQorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOUGFzdGUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzApCit7CisJREVCVUdfQ0FMTCgiVFhOUGFzdGVcbiIpCisKKwlyZXR1cm4gKGppbnQpVFhOUGFzdGUoKFRYTk9iamVjdClhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19UWE5QYXN0ZSAqLworCisjaWZuZGVmIE5PX1RYTlBvaW50VG9PZmZzZXQKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTlBvaW50VG9PZmZzZXQKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludEFycmF5IGFyZzIpCit7CisJUG9pbnQgX2FyZzEsICpscGFyZzE9TlVMTDsKKwlqaW50ICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiVFhOUG9pbnRUb09mZnNldFxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRQb2ludEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJaWYgKGFyZzIpIGxwYXJnMiA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzIsIE5VTEwpOworCXJjID0gKGppbnQpVFhOUG9pbnRUb09mZnNldCgoVFhOT2JqZWN0KWFyZzAsIChQb2ludCkqbHBhcmcxLCAoVFhOT2Zmc2V0ICopbHBhcmcyKTsKKwlpZiAoYXJnMSkgc2V0UG9pbnRGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmcyKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgbHBhcmcyLCAwKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fVFhOUG9pbnRUb09mZnNldCAqLworCisjaWZuZGVmIE5PX1RYTlNlbGVjdEFsbAorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOU2VsZWN0QWxsCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwKQoreworCURFQlVHX0NBTEwoIlRYTlNlbGVjdEFsbFxuIikKKworCVRYTlNlbGVjdEFsbCgoVFhOT2JqZWN0KWFyZzApOworfQorI2VuZGlmIC8qIE5PX1RYTlNlbGVjdEFsbCAqLworCisjaWZuZGVmIE5PX1RYTlNldERhdGEKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTlNldERhdGEKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamNoYXJBcnJheSBhcmcyLCBqaW50IGFyZzMsIGppbnQgYXJnNCwgamludCBhcmc1KQoreworCWpjaGFyICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiVFhOU2V0RGF0YVxuIikKKworCWlmIChhcmcyKSBscGFyZzIgPSAoKmVudiktPkdldENoYXJBcnJheUVsZW1lbnRzKGVudiwgYXJnMiwgTlVMTCk7CisJcmMgPSAoamludClUWE5TZXREYXRhKChUWE5PYmplY3QpYXJnMCwgKFRYTkRhdGFUeXBlKWFyZzEsIChjb25zdCB2b2lkICopbHBhcmcyLCAoQnl0ZUNvdW50KWFyZzMsIChUWE5PZmZzZXQpYXJnNCwgKFRYTk9mZnNldClhcmc1KTsKKwlpZiAoYXJnMikgKCplbnYpLT5SZWxlYXNlQ2hhckFycmF5RWxlbWVudHMoZW52LCBhcmcyLCBscGFyZzIsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19UWE5TZXREYXRhICovCisKKyNpZm5kZWYgTk9fVFhOU2V0RnJhbWVCb3VuZHMKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTlNldEZyYW1lQm91bmRzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMiwgamludCBhcmczLCBqaW50IGFyZzQsIGppbnQgYXJnNSkKK3sKKwlERUJVR19DQUxMKCJUWE5TZXRGcmFtZUJvdW5kc1xuIikKKworCVRYTlNldEZyYW1lQm91bmRzKChUWE5PYmplY3QpYXJnMCwgKFNJbnQzMilhcmcxLCAoU0ludDMyKWFyZzIsIChTSW50MzIpYXJnMywgKFNJbnQzMilhcmc0LCAoVFhORnJhbWVJRClhcmc1KTsKK30KKyNlbmRpZiAvKiBOT19UWE5TZXRGcmFtZUJvdW5kcyAqLworCisjaWZuZGVmIE5PX1RYTlNldFJlY3RCb3VuZHMKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTlNldFJlY3RCb3VuZHMKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgam9iamVjdCBhcmcyLCBqYm9vbGVhbiBhcmczKQoreworCVJlY3QgX2FyZzEsICpscGFyZzE9TlVMTDsKKwlUWE5Mb25nUmVjdCBfYXJnMiwgKmxwYXJnMj1OVUxMOworCisJREVCVUdfQ0FMTCgiVFhOU2V0UmVjdEJvdW5kc1xuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwlpZiAoYXJnMikgbHBhcmcyID0gZ2V0VFhOTG9uZ1JlY3RGaWVsZHMoZW52LCBhcmcyLCAmX2FyZzIpOworCVRYTlNldFJlY3RCb3VuZHMoKFRYTk9iamVjdClhcmcwLCAoUmVjdCAqKWxwYXJnMSwgKFRYTkxvbmdSZWN0ICopbHBhcmcyLCAoQm9vbGVhbilhcmczKTsKKwlpZiAoYXJnMSkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7CisJaWYgKGFyZzIpIHNldFRYTkxvbmdSZWN0RmllbGRzKGVudiwgYXJnMiwgbHBhcmcyKTsKK30KKyNlbmRpZiAvKiBOT19UWE5TZXRSZWN0Qm91bmRzICovCisKKyNpZm5kZWYgTk9fVFhOU2V0U2VsZWN0aW9uCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UWE5TZXRTZWxlY3Rpb24KKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyKQoreworCURFQlVHX0NBTEwoIlRYTlNldFNlbGVjdGlvblxuIikKKworCXJldHVybiAoamludClUWE5TZXRTZWxlY3Rpb24oKFRYTk9iamVjdClhcmcwLCAoVFhOT2Zmc2V0KWFyZzEsIChUWE5PZmZzZXQpYXJnMik7Cit9CisjZW5kaWYgLyogTk9fVFhOU2V0U2VsZWN0aW9uICovCisKKyNpZm5kZWYgTk9fVFhOU2V0VFhOT2JqZWN0Q29udHJvbHMKK0pOSUVYUE9SVCBqaW50IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RYTlNldFRYTk9iamVjdENvbnRyb2xzCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqYm9vbGVhbiBhcmcxLCBqaW50IGFyZzIsIGppbnRBcnJheSBhcmczLCBqaW50QXJyYXkgYXJnNCkKK3sKKwlqaW50ICpscGFyZzM9TlVMTDsKKwlqaW50ICpscGFyZzQ9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiVFhOU2V0VFhOT2JqZWN0Q29udHJvbHNcbiIpCisKKwlpZiAoYXJnMykgbHBhcmczID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgTlVMTCk7CisJaWYgKGFyZzQpIGxwYXJnNCA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIE5VTEwpOworCXJjID0gKGppbnQpVFhOU2V0VFhOT2JqZWN0Q29udHJvbHMoKFRYTk9iamVjdClhcmcwLCAoQm9vbGVhbilhcmcxLCAoSXRlbUNvdW50KWFyZzIsIChjb25zdCBUWE5Db250cm9sVGFnICopbHBhcmczLCAoY29uc3QgVFhOQ29udHJvbERhdGEgKilscGFyZzQpOworCWlmIChhcmczKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMywgbHBhcmczLCAwKTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1RYTlNldFRYTk9iamVjdENvbnRyb2xzICovCisKKyNpZm5kZWYgTk9fVFhOU2hvd1NlbGVjdGlvbgorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVFhOU2hvd1NlbGVjdGlvbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamJvb2xlYW4gYXJnMSkKK3sKKwlERUJVR19DQUxMKCJUWE5TaG93U2VsZWN0aW9uXG4iKQorCisJVFhOU2hvd1NlbGVjdGlvbigoVFhOT2JqZWN0KWFyZzAsIChCb29sZWFuKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1RYTlNob3dTZWxlY3Rpb24gKi8KKworI2lmbmRlZiBOT19UZXN0Q29udHJvbAorSk5JRVhQT1JUIGpzaG9ydCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UZXN0Q29udHJvbAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxKQoreworCVBvaW50IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisJanNob3J0IHJjOworCisJREVCVUdfQ0FMTCgiVGVzdENvbnRyb2xcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UG9pbnRGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCXJjID0gKGpzaG9ydClUZXN0Q29udHJvbCgoQ29udHJvbFJlZilhcmcwLCAoUG9pbnQpKmxwYXJnMSk7CisJaWYgKGFyZzEpIHNldFBvaW50RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKKwlyZXR1cm4gcmM7Cit9CisjZW5kaWYgLyogTk9fVGVzdENvbnRyb2wgKi8KKworI2lmbmRlZiBOT19UZXh0RmFjZQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVGV4dEZhY2UKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqc2hvcnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJUZXh0RmFjZVxuIikKKworCVRleHRGYWNlKChTdHlsZVBhcmFtZXRlcilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19UZXh0RmFjZSAqLworCisjaWZuZGVmIE5PX1RleHRGb250CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UZXh0Rm9udAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpzaG9ydCBhcmcwKQoreworCURFQlVHX0NBTEwoIlRleHRGb250XG4iKQorCisJVGV4dEZvbnQoKHNob3J0KWFyZzApOworfQorI2VuZGlmIC8qIE5PX1RleHRGb250ICovCisKKyNpZm5kZWYgTk9fVGV4dE1vZGUKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX1RleHRNb2RlCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwganNob3J0IGFyZzApCit7CisJREVCVUdfQ0FMTCgiVGV4dE1vZGVcbiIpCisKKwlUZXh0TW9kZSgoc2hvcnQpYXJnMCk7Cit9CisjZW5kaWYgLyogTk9fVGV4dE1vZGUgKi8KKworI2lmbmRlZiBOT19UZXh0U2l6ZQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVGV4dFNpemUKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqc2hvcnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJUZXh0U2l6ZVxuIikKKworCVRleHRTaXplKChzaG9ydClhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19UZXh0U2l6ZSAqLworCisjaWZuZGVmIE5PX1RleHRXaWR0aAorSk5JRVhQT1JUIGpzaG9ydCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UZXh0V2lkdGgKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqYnl0ZUFycmF5IGFyZzAsIGpzaG9ydCBhcmcxLCBqc2hvcnQgYXJnMikKK3sKKwlqYnl0ZSAqbHBhcmcwPU5VTEw7CisJanNob3J0IHJjOworCisJREVCVUdfQ0FMTCgiVGV4dFdpZHRoXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9ICgqZW52KS0+R2V0Qnl0ZUFycmF5RWxlbWVudHMoZW52LCBhcmcwLCBOVUxMKTsKKwlyYyA9IChqc2hvcnQpVGV4dFdpZHRoKChjb25zdCB2b2lkICopbHBhcmcwLCAoc2hvcnQpYXJnMSwgKHNob3J0KWFyZzIpOworCWlmIChhcmcwKSAoKmVudiktPlJlbGVhc2VCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIGxwYXJnMCwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1RleHRXaWR0aCAqLworCisjaWZuZGVmIE5PX1RyYWNrTW91c2VMb2NhdGlvbldpdGhPcHRpb25zCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19UcmFja01vdXNlTG9jYXRpb25XaXRoT3B0aW9ucworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqZG91YmxlIGFyZzIsIGpvYmplY3QgYXJnMywgamludEFycmF5IGFyZzQsIGpzaG9ydEFycmF5IGFyZzUpCit7CisJUG9pbnQgX2FyZzMsICpscGFyZzM9TlVMTDsKKwlqaW50ICpscGFyZzQ9TlVMTDsKKwlqc2hvcnQgKmxwYXJnNT1OVUxMOworCWppbnQgcmM7CisKKwlERUJVR19DQUxMKCJUcmFja01vdXNlTG9jYXRpb25cbiIpCisKKwlpZiAoYXJnMykgbHBhcmczID0gZ2V0UG9pbnRGaWVsZHMoZW52LCBhcmczLCAmX2FyZzMpOworCWlmIChhcmc0KSBscGFyZzQgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmc0LCBOVUxMKTsKKwlpZiAoYXJnNSkgbHBhcmc1ID0gKCplbnYpLT5HZXRTaG9ydEFycmF5RWxlbWVudHMoZW52LCBhcmc1LCBOVUxMKTsKKwlyYyA9IChqaW50KVRyYWNrTW91c2VMb2NhdGlvbldpdGhPcHRpb25zKChHcmFmUHRyKWFyZzAsIChPcHRpb25CaXRzKWFyZzEsIChFdmVudFRpbWVvdXQpYXJnMiwgKFBvaW50ICopbHBhcmczLCAoVUludDMyICopbHBhcmc0LCAoTW91c2VUcmFja2luZ1Jlc3VsdCAqKWxwYXJnNSk7CisJaWYgKGFyZzMpIHNldFBvaW50RmllbGRzKGVudiwgYXJnMywgbHBhcmczKTsKKwlpZiAoYXJnNCkgKCplbnYpLT5SZWxlYXNlSW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzQsIGxwYXJnNCwgMCk7CisJaWYgKGFyZzUpICgqZW52KS0+UmVsZWFzZVNob3J0QXJyYXlFbGVtZW50cyhlbnYsIGFyZzUsIGxwYXJnNSwgMCk7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1RyYWNrTW91c2VMb2NhdGlvbldpdGhPcHRpb25zICovCisKKyNpZm5kZWYgTk9fVW5pb25SZWN0CitKTklFWFBPUlQgdm9pZCBKTklDQUxMIE9TX05BVElWRShVbmlvblJlY3QpCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwLCBqb2JqZWN0IGFyZzEsIGpvYmplY3QgYXJnMikKK3sKKwlSZWN0IF9hcmcwLCAqbHBhcmcwPU5VTEw7CisJUmVjdCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCVJlY3QgX2FyZzIsICpscGFyZzI9TlVMTDsKKworCURFQlVHX0NBTEwoIlVuaW9uUmVjdFxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0UmVjdEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJaWYgKGFyZzIpIGxwYXJnMiA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcyLCAmX2FyZzIpOworCVVuaW9uUmVjdChscGFyZzAsIGxwYXJnMSwgbHBhcmcyKTsKKwlpZiAoYXJnMCkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7CisJaWYgKGFyZzEpIHNldFJlY3RGaWVsZHMoZW52LCBhcmcxLCBscGFyZzEpOworCWlmIChhcmcyKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMiwgbHBhcmcyKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX1VuaW9uUmduCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19VbmlvblJnbgorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIpCit7CisJREVCVUdfQ0FMTCgiVW5pb25SZ25cbiIpCisKKwlVbmlvblJnbigoUmduSGFuZGxlKWFyZzAsIChSZ25IYW5kbGUpYXJnMSwgKFJnbkhhbmRsZSlhcmcyKTsKK30KKyNlbmRpZiAvKiBOT19VbmlvblJnbiAqLworCisjaWZuZGVmIE5PX1VubG9ja1BvcnRCaXRzCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19VbmxvY2tQb3J0Qml0cworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCkKK3sKKwlERUJVR19DQUxMKCJVbmxvY2tQb3J0Qml0c1xuIikKKworCXJldHVybiAoamludClVbmxvY2tQb3J0Qml0cygoR3JhZlB0cilhcmcwKTsKK30KKyNlbmRpZiAvKiBOT19VbmxvY2tQb3J0Qml0cyAqLworCisjaWZuZGVmIE5PX1VwZGF0ZUNvbnRyb2xzCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19VcGRhdGVDb250cm9scworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxKQoreworCURFQlVHX0NBTEwoIlVwZGF0ZUNvbnRyb2xzXG4iKQorCisJVXBkYXRlQ29udHJvbHMoKFdpbmRvd1JlZilhcmcwLCAoUmduSGFuZGxlKWFyZzEpOworfQorI2VuZGlmIC8qIE5PX1VwZGF0ZUNvbnRyb2xzICovCisKKyNpZm5kZWYgTk9fVXBkYXRlRGF0YUJyb3dzZXJJdGVtcworSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfVXBkYXRlRGF0YUJyb3dzZXJJdGVtcworCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIsIGppbnRBcnJheSBhcmczLCBqaW50IGFyZzQsIGppbnQgYXJnNSkKK3sKKwlqaW50ICpscGFyZzM9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiVXBkYXRlRGF0YUJyb3dzZXJJdGVtc1xuIikKKworCWlmIChhcmczKSBscGFyZzMgPSAoKmVudiktPkdldEludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBOVUxMKTsKKwlyYyA9IChqaW50KVVwZGF0ZURhdGFCcm93c2VySXRlbXMoKENvbnRyb2xSZWYpYXJnMCwgKERhdGFCcm93c2VySXRlbUlEKWFyZzEsIChVSW50MzIpYXJnMiwgKGNvbnN0IERhdGFCcm93c2VySXRlbUlEICopbHBhcmczLCAoRGF0YUJyb3dzZXJQcm9wZXJ0eUlEKWFyZzQsIChEYXRhQnJvd3NlclByb3BlcnR5SUQpYXJnNSk7CisJaWYgKGFyZzMpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmczLCBscGFyZzMsIDApOworCXJldHVybiByYzsKK30KKyNlbmRpZiAvKiBOT19VcGRhdGVEYXRhQnJvd3Nlckl0ZW1zICovCisKKyNpZm5kZWYgTk9fa0hJVmlld1dpbmRvd0NvbnRlbnRJRAorSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1Nfa0hJVmlld1dpbmRvd0NvbnRlbnRJRAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQpCit7CisJREVCVUdfQ0FMTCgia0hJVmlld1dpbmRvd0NvbnRlbnRJRFxuIikKKworCXJldHVybiAoamludCkma0hJVmlld1dpbmRvd0NvbnRlbnRJRDsKK30KKyNlbmRpZiAvKiBOT19rSElWaWV3V2luZG93Q29udGVudElEICovCisKKyNpZm5kZWYgTk9fbWVtY3B5X19JXzNCSQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfbWVtY3B5X19JXzNCSQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamJ5dGVBcnJheSBhcmcxLCBqaW50IGFyZzIpCit7CisJamJ5dGUgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgibWVtY3B5X19JXzNCSVxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSAoKmVudiktPkdldEJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJbWVtY3B5KCh2b2lkICopYXJnMCwgKGNvbnN0IHZvaWQgKilscGFyZzEsIChzaXplX3QpYXJnMik7CisJaWYgKGFyZzEpICgqZW52KS0+UmVsZWFzZUJ5dGVBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgbHBhcmcxLCAwKTsKK30KKyNlbmRpZiAvKiBOT19tZW1jcHlfX0lfM0JJICovCisKKyNpZm5kZWYgTk9fbWVtY3B5X19JSUkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX21lbWNweV9fSUlJCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMikKK3sKKwlERUJVR19DQUxMKCJtZW1jcHlfX0lJSVxuIikKKworCW1lbWNweSgodm9pZCAqKWFyZzAsIChjb25zdCB2b2lkICopYXJnMSwgKHNpemVfdClhcmcyKTsKK30KKyNlbmRpZiAvKiBOT19tZW1jcHlfX0lJSSAqLworCisjaWZuZGVmIE5PX21lbWNweV9fXzNCSUkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX21lbWNweV9fXzNCSUkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqYnl0ZUFycmF5IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyKQoreworCWpieXRlICpscGFyZzA9TlVMTDsKKworCURFQlVHX0NBTEwoIm1lbWNweV9fXzNCSUlcbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gKCplbnYpLT5HZXRCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIE5VTEwpOworCW1lbWNweSgodm9pZCAqKWxwYXJnMCwgKGNvbnN0IHZvaWQgKilhcmcxLCAoc2l6ZV90KWFyZzIpOworCWlmIChhcmcwKSAoKmVudiktPlJlbGVhc2VCeXRlQXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIGxwYXJnMCwgMCk7Cit9CisjZW5kaWYgLyogTk9fbWVtY3B5X19fM0JJSSAqLworCisjaWZuZGVmIE5PX21lbWNweV9fXzNDSUkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX21lbWNweV9fXzNDSUkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqY2hhckFycmF5IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyKQoreworCWpjaGFyICpscGFyZzA9TlVMTDsKKworCURFQlVHX0NBTEwoIm1lbWNweV9fXzNDSUlcbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gKCplbnYpLT5HZXRDaGFyQXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIE5VTEwpOworCW1lbWNweSgodm9pZCAqKWxwYXJnMCwgKGNvbnN0IHZvaWQgKilhcmcxLCAoc2l6ZV90KWFyZzIpOworCWlmIChhcmcwKSAoKmVudiktPlJlbGVhc2VDaGFyQXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIGxwYXJnMCwgMCk7Cit9CisjZW5kaWYgLyogTk9fbWVtY3B5X19fM0NJSSAqLworCisjaWZuZGVmIE5PX21lbWNweV9fXzNJSUkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX21lbWNweV9fXzNJSUkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50QXJyYXkgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIpCit7CisJamludCAqbHBhcmcwPU5VTEw7CisKKwlERUJVR19DQUxMKCJtZW1jcHlfX18zSUlJXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9ICgqZW52KS0+R2V0SW50QXJyYXlFbGVtZW50cyhlbnYsIGFyZzAsIE5VTEwpOworCW1lbWNweSgodm9pZCAqKWxwYXJnMCwgKGNvbnN0IHZvaWQgKilhcmcxLCAoc2l6ZV90KWFyZzIpOworCWlmIChhcmcwKSAoKmVudiktPlJlbGVhc2VJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMCwgbHBhcmcwLCAwKTsKK30KKyNlbmRpZiAvKiBOT19tZW1jcHlfX18zSUlJICovCisKKyNpZm5kZWYgTk9fbWVtY3B5X19Mb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9BVFNUcmFwZXpvaWRfMklJCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIE9TX05BVElWRShtZW1jcHlfX0xvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0FUU1RyYXBlem9pZF8ySUkpCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgam9iamVjdCBhcmcwLCBqaW50IGFyZzEsIGppbnQgYXJnMikKK3sKKwlBVFNUcmFwZXpvaWQgX2FyZzAsICpscGFyZzA9TlVMTDsKKworCURFQlVHX0NBTEwoIm1lbWNweV9fTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fQVRTVHJhcGV6b2lkXzJJSVxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRBVFNUcmFwZXpvaWRGaWVsZHMoZW52LCBhcmcwLCAmX2FyZzApOworCW1lbWNweSgodm9pZCAqKWxwYXJnMCwgKGNvbnN0IHZvaWQgKilhcmcxLCAoc2l6ZV90KWFyZzIpOworCWlmIChhcmcwKSBzZXRBVFNUcmFwZXpvaWRGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fbWVtY3B5X19JXzNDSQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBPU19OQVRJVkUobWVtY3B5X19JXzNDSSkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpjaGFyQXJyYXkgYXJnMSwgamludCBhcmcyKQoreworCWpjaGFyICpscGFyZzE9TlVMTDsKKworCURFQlVHX0NBTEwoIm1lbWNweV9fSV8zQ0lcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRDaGFyQXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIE5VTEwpOworCW1lbWNweSgodm9pZCAqKWFyZzAsIChjb25zdCB2b2lkICopbHBhcmcxLCAoc2l6ZV90KWFyZzIpOworCWlmIChhcmcxKSAoKmVudiktPlJlbGVhc2VDaGFyQXJyYXlFbGVtZW50cyhlbnYsIGFyZzEsIGxwYXJnMSwgMCk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19tZW1jcHlfX0lfM0lJCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIE9TX05BVElWRShtZW1jcHlfX0lfM0lJKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludEFycmF5IGFyZzEsIGppbnQgYXJnMikKK3sKKwlqaW50ICpscGFyZzE9TlVMTDsKKworCURFQlVHX0NBTEwoIm1lbWNweV9fSV8zSUlcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gKCplbnYpLT5HZXRJbnRBcnJheUVsZW1lbnRzKGVudiwgYXJnMSwgTlVMTCk7CisJbWVtY3B5KCh2b2lkICopYXJnMCwgKGNvbnN0IHZvaWQgKilscGFyZzEsIChzaXplX3QpYXJnMik7CisJaWYgKGFyZzEpICgqZW52KS0+UmVsZWFzZUludEFycmF5RWxlbWVudHMoZW52LCBhcmcxLCBscGFyZzEsIDApOworfQorI2VuZGlmCisKKworI2lmbmRlZiBOT19tZW1jcHlfX0xvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0dEZXZpY2VfMklJCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIE9TX05BVElWRShtZW1jcHlfX0xvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0dEZXZpY2VfMklJKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIpCit7CisJR0RldmljZSBfYXJnMCwgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgibWVtY3B5X19Mb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9HRGV2aWNlXzJJSVxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRHRGV2aWNlRmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwltZW1jcHkoKHZvaWQgKilscGFyZzAsIChjb25zdCB2b2lkICopYXJnMSwgKHNpemVfdClhcmcyKTsKKwlpZiAoYXJnMCkgc2V0R0RldmljZUZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19tZW1jcHlfX0lMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9CaXRNYXBfMkkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgT1NfTkFUSVZFKG1lbWNweV9fSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0JpdE1hcF8ySSkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyKQoreworCUJpdE1hcCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgibWVtY3B5X19JTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fQml0TWFwXzJJXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldEJpdE1hcEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJbWVtY3B5KCh2b2lkICopYXJnMCwgKGNvbnN0IHZvaWQgKilscGFyZzEsIChzaXplX3QpYXJnMik7CisJaWYgKGFyZzEpIHNldEJpdE1hcEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19tZW1jcHlfX0lMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9DdXJzb3JfMkkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgT1NfTkFUSVZFKG1lbWNweV9fSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0N1cnNvcl8ySSkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyKQoreworCUN1cnNvciBfYXJnMSwgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgibWVtY3B5X19JTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fQ3Vyc29yXzJJXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldEN1cnNvckZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJbWVtY3B5KCh2b2lkICopYXJnMCwgKGNvbnN0IHZvaWQgKilscGFyZzEsIChzaXplX3QpYXJnMik7CisJaWYgKGFyZzEpIHNldEN1cnNvckZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19tZW1jcHlfX0lMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9QaXhNYXBfMkkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgT1NfTkFUSVZFKG1lbWNweV9fSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX1BpeE1hcF8ySSkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpvYmplY3QgYXJnMSwgamludCBhcmcyKQoreworCVBpeE1hcCBfYXJnMSwgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgibWVtY3B5X19JTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fUGl4TWFwXzJJXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFBpeE1hcEZpZWxkcyhlbnYsIGFyZzEsICZfYXJnMSk7CisJbWVtY3B5KCh2b2lkICopYXJnMCwgKGNvbnN0IHZvaWQgKilscGFyZzEsIChzaXplX3QpYXJnMik7CisJaWYgKGFyZzEpIHNldFBpeE1hcEZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19tZW1jcHlfX0xvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX1BpeE1hcF8ySUkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgT1NfTkFUSVZFKG1lbWNweV9fTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fUGl4TWFwXzJJSSkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyKQoreworCVBpeE1hcCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgibWVtY3B5X19Mb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9QaXhNYXBfMklJXG4iKQorCisJaWYgKGFyZzApIGxwYXJnMCA9IGdldFBpeE1hcEZpZWxkcyhlbnYsIGFyZzAsICZfYXJnMCk7CisJbWVtY3B5KCh2b2lkICopbHBhcmcwLCAoY29uc3Qgdm9pZCAqKWFyZzEsIChzaXplX3QpYXJnMik7CisJaWYgKGFyZzApIHNldFBpeE1hcEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19tZW1jcHlfX0lMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9SZWN0XzJJCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19tZW1jcHlfX0lMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9SZWN0XzJJCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEsIGppbnQgYXJnMikKK3sKKwlSZWN0IF9hcmcxLCAqbHBhcmcxPU5VTEw7CisKKwlERUJVR19DQUxMKCJtZW1jcHlfX0lMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9SZWN0XzJJXG4iKQorCisJaWYgKGFyZzEpIGxwYXJnMSA9IGdldFJlY3RGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCW1lbWNweSgodm9pZCAqKWFyZzAsIChjb25zdCB2b2lkICopbHBhcmcxLCAoc2l6ZV90KWFyZzIpOworCWlmIChhcmcxKSBzZXRSZWN0RmllbGRzKGVudiwgYXJnMSwgbHBhcmcxKTsKK30KKyNlbmRpZiAvKiBOT19tZW1jcHlfX0lMb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9SZWN0XzJJICovCisKKyNpZm5kZWYgTk9fbWVtY3B5X19JTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fRm9udFNlbGVjdGlvblFEU3R5bGVfMkkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX21lbWNweV9fSUxvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0ZvbnRTZWxlY3Rpb25RRFN0eWxlXzJJCisJKEpOSUVudiAqZW52LCBqY2xhc3MgdGhhdCwgamludCBhcmcwLCBqb2JqZWN0IGFyZzEsIGppbnQgYXJnMikKK3sKKwlGb250U2VsZWN0aW9uUURTdHlsZSBfYXJnMSwgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgibWVtY3B5X19JTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fRm9udFNlbGVjdGlvblFEU3R5bGVfMklcbiIpCisKKwlpZiAoYXJnMSkgbHBhcmcxID0gZ2V0Rm9udFNlbGVjdGlvblFEU3R5bGVGaWVsZHMoZW52LCBhcmcxLCAmX2FyZzEpOworCW1lbWNweSgodm9pZCAqKWFyZzAsIChjb25zdCB2b2lkICopbHBhcmcxLCAoc2l6ZV90KWFyZzIpOworCWlmIChhcmcxKSBzZXRGb250U2VsZWN0aW9uUURTdHlsZUZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19tZW1jcHlfX0xvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0ZvbnRTZWxlY3Rpb25RRFN0eWxlXzJJSQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfbWVtY3B5X19Mb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9Gb250U2VsZWN0aW9uUURTdHlsZV8ySUkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyKQoreworCUZvbnRTZWxlY3Rpb25RRFN0eWxlIF9hcmcwLCAqbHBhcmcwPU5VTEw7CisKKwlERUJVR19DQUxMKCJtZW1jcHlfX0xvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX0ZvbnRTZWxlY3Rpb25RRFN0eWxlXzJJSVxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRGb250U2VsZWN0aW9uUURTdHlsZUZpZWxkcyhlbnYsIGFyZzAsICZfYXJnMCk7CisJbWVtY3B5KCh2b2lkICopbHBhcmcwLCAoY29uc3Qgdm9pZCAqKWFyZzEsIChzaXplX3QpYXJnMik7CisJaWYgKGFyZzApIHNldEZvbnRTZWxlY3Rpb25RRFN0eWxlRmllbGRzKGVudiwgYXJnMCwgbHBhcmcwKTsKK30KKyNlbmRpZgorCisjaWZuZGVmIE5PX21lbWNweV9fTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fSE1IZWxwQ29udGVudFJlY18ySUkKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX21lbWNweV9fTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fSE1IZWxwQ29udGVudFJlY18ySUkKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqb2JqZWN0IGFyZzAsIGppbnQgYXJnMSwgamludCBhcmcyKQoreworCUhNSGVscENvbnRlbnRSZWMgX2FyZzAsICpscGFyZzA9TlVMTDsKKworCURFQlVHX0NBTEwoIm1lbWNweV9fTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fSE1IZWxwQ29udGVudFJlY18ySUlcbiIpCisKKwlpZiAoYXJnMCkgbHBhcmcwID0gZ2V0SE1IZWxwQ29udGVudFJlY0ZpZWxkcyhlbnYsIGFyZzAsICZfYXJnMCk7CisJbWVtY3B5KCh2b2lkICopbHBhcmcwLCAoY29uc3Qgdm9pZCAqKWFyZzEsIChzaXplX3QpYXJnMik7CisJaWYgKGFyZzApIHNldEhNSGVscENvbnRlbnRSZWNGaWVsZHMoZW52LCBhcmcwLCBscGFyZzApOworfQorI2VuZGlmCisKKyNpZm5kZWYgTk9fbWVtY3B5X19JTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fSE1IZWxwQ29udGVudFJlY18ySQorSk5JRVhQT1JUIHZvaWQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fT1NfbWVtY3B5X19JTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fSE1IZWxwQ29udGVudFJlY18ySQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgam9iamVjdCBhcmcxLCBqaW50IGFyZzIpCit7CisJSE1IZWxwQ29udGVudFJlYyBfYXJnMSwgKmxwYXJnMT1OVUxMOworCisJREVCVUdfQ0FMTCgibWVtY3B5X19JTG9yZ19lY2xpcHNlX3N3dF9pbnRlcm5hbF9jYXJib25fSE1IZWxwQ29udGVudFJlY18ySVxuIikKKworCWlmIChhcmcxKSBscGFyZzEgPSBnZXRITUhlbHBDb250ZW50UmVjRmllbGRzKGVudiwgYXJnMSwgJl9hcmcxKTsKKwltZW1jcHkoKHZvaWQgKilhcmcwLCAoY29uc3Qgdm9pZCAqKWxwYXJnMSwgKHNpemVfdClhcmcyKTsKKwlpZiAoYXJnMSkgc2V0SE1IZWxwQ29udGVudFJlY0ZpZWxkcyhlbnYsIGFyZzEsIGxwYXJnMSk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19tZW1jcHlfX0xvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX1JlY3RfMklJCitKTklFWFBPUlQgdm9pZCBKTklDQUxMIE9TX05BVElWRShtZW1jcHlfX0xvcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX1JlY3RfMklJKQorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGpvYmplY3QgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIpCit7CisJUmVjdCBfYXJnMCwgKmxwYXJnMD1OVUxMOworCisJREVCVUdfQ0FMTCgibWVtY3B5X19Mb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9SZWN0XzJJSVxuIikKKworCWlmIChhcmcwKSBscGFyZzAgPSBnZXRSZWN0RmllbGRzKGVudiwgYXJnMCwgJl9hcmcwKTsKKwltZW1jcHkoKHZvaWQgKilscGFyZzAsIChjb25zdCB2b2lkICopYXJnMSwgKHNpemVfdClhcmcyKTsKKwlpZiAoYXJnMCkgc2V0UmVjdEZpZWxkcyhlbnYsIGFyZzAsIGxwYXJnMCk7Cit9CisjZW5kaWYKKworI2lmbmRlZiBOT19tZW1zZXQKK0pOSUVYUE9SVCB2b2lkIEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV9zd3RfaW50ZXJuYWxfY2FyYm9uX09TX21lbXNldAorCShKTklFbnYgKmVudiwgamNsYXNzIHRoYXQsIGppbnQgYXJnMCwgamludCBhcmcxLCBqaW50IGFyZzIpCit7CisJREVCVUdfQ0FMTCgibWVtc2V0XG4iKQorCisJbWVtc2V0KCh2b2lkICopYXJnMCwgYXJnMSwgYXJnMik7Cit9CisjZW5kaWYgLyogTk9fbWVtc2V0ICovCisKKyNpZm5kZWYgTk9fWm9vbVdpbmRvd0lkZWFsCitKTklFWFBPUlQgamludCBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2Vfc3d0X2ludGVybmFsX2NhcmJvbl9PU19ab29tV2luZG93SWRlYWwKKwkoSk5JRW52ICplbnYsIGpjbGFzcyB0aGF0LCBqaW50IGFyZzAsIGpzaG9ydCBhcmcxLCBqb2JqZWN0IGFyZzIpCit7CisJUG9pbnQgX2FyZzIsICpscGFyZzI9TlVMTDsKKwlqaW50IHJjOworCisJREVCVUdfQ0FMTCgiWm9vbVdpbmRvd0lkZWFsXG4iKQorCisJaWYgKGFyZzIpIGxwYXJnMiA9IGdldFBvaW50RmllbGRzKGVudiwgYXJnMiwgJl9hcmcyKTsKKwlyYyA9IChqaW50KVpvb21XaW5kb3dJZGVhbCgoV2luZG93UmVmKWFyZzAsIChXaW5kb3dQYXJ0Q29kZSlhcmcxLCAoUG9pbnQgKilscGFyZzIpOworCWlmIChhcmcyKSBzZXRQb2ludEZpZWxkcyhlbnYsIGFyZzIsIGxwYXJnMik7CisJcmV0dXJuIHJjOworfQorI2VuZGlmIC8qIE5PX1pvb21XaW5kb3dJZGVhbCAqLwpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQUVEZXNjLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9BRURlc2MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNDAzNTU0Ci0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQUVEZXNjLmphdmEKQEAgLTAsMCArMSwxNCBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworIAorcHVibGljIGNsYXNzIEFFRGVzYyB7CisJcHVibGljIGludCBkZXNjcmlwdG9yVHlwZTsKKwlwdWJsaWMgaW50IGRhdGFIYW5kbGU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2l6ZW9mID0gODsKK30KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0FUU1RyYXBlem9pZC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQVRTVHJhcGV6b2lkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjA3MGYzYQotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0FUU1RyYXBlem9pZC5qYXZhCkBAIC0wLDAgKzEsMjQgQEAKK3BhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKworcHVibGljIGNsYXNzIEFUU1RyYXBlem9pZCB7CisJLy9GaXhlZFBvaW50IHVwcGVyTGVmdDsKKwlwdWJsaWMgaW50IHVwcGVyTGVmdF94OworCXB1YmxpYyBpbnQgdXBwZXJMZWZ0X3k7CisJLy9GaXhlZFBvaW50IHVwcGVyUmlnaHQ7CisJcHVibGljIGludCB1cHBlclJpZ2h0X3g7CisJcHVibGljIGludCB1cHBlclJpZ2h0X3k7CisJLy9GaXhlZFBvaW50IGxvd2VyUmlnaHQ7CisJcHVibGljIGludCBsb3dlclJpZ2h0X3g7CisJcHVibGljIGludCBsb3dlclJpZ2h0X3k7CisJLy9GaXhlZFBvaW50IGxvd2VyTGVmdDsKKwlwdWJsaWMgaW50IGxvd2VyTGVmdF94OworCXB1YmxpYyBpbnQgbG93ZXJMZWZ0X3k7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2l6ZW9mID0gMzI7Cit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9BbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlYy5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMWEzZWM2Ci0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWMuamF2YQpAQCAtMCwwICsxLDIzIEBACitwYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247CisKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKKyAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAorICovCisgCitwdWJsaWMgY2xhc3MgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWMgeworCXB1YmxpYyBpbnQgdmVyc2lvbjsKKwlwdWJsaWMgYm9vbGVhbiBtb3ZhYmxlOworCXB1YmxpYyBib29sZWFuIGhlbHBCdXR0b247CisJcHVibGljIGludCBkZWZhdWx0VGV4dDsKKwlwdWJsaWMgaW50IGNhbmNlbFRleHQ7CisJcHVibGljIGludCBvdGhlclRleHQ7CisJcHVibGljIHNob3J0IGRlZmF1bHRCdXR0b247CisJcHVibGljIHNob3J0IGNhbmNlbEJ1dHRvbjsKKwlwdWJsaWMgc2hvcnQgcG9zaXRpb247CisJcHVibGljIGludCBmbGFnczsKKwkKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzaXplb2YgPSAyODsKK30KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0JpdE1hcC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQml0TWFwLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmU1ZTBjMAotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0JpdE1hcC5qYXZhCkBAIC0wLDAgKzEsMTkgQEAKK3BhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKworcHVibGljIGNsYXNzIEJpdE1hcCB7CisJcHVibGljIGludCBiYXNlQWRkcjsKKwlwdWJsaWMgc2hvcnQgcm93Qnl0ZXM7CisJLy9SZWN0IGJvdW5kczsKKwlwdWJsaWMgc2hvcnQgdG9wOworCXB1YmxpYyBzaG9ydCBsZWZ0OworCXB1YmxpYyBzaG9ydCBib3R0b207CisJcHVibGljIHNob3J0IHJpZ2h0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNpemVvZiA9IDE0OworfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQ0ZSYW5nZS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQ0ZSYW5nZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiZTc1YmQKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9DRlJhbmdlLmphdmEKQEAgLTAsMCArMSwxNCBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworCitwdWJsaWMgY2xhc3MgQ0ZSYW5nZSB7CisJcHVibGljIGludCBsb2NhdGlvbjsKKwlwdWJsaWMgaW50IGxlbmd0aDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzaXplb2YgPSA4OworfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQ0dQb2ludC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQ0dQb2ludC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNhMDY5ZTYKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9DR1BvaW50LmphdmEKQEAgLTAsMCArMSwxNCBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworCitwdWJsaWMgY2xhc3MgQ0dQb2ludCB7CisJcHVibGljIGZsb2F0IHg7CisJcHVibGljIGZsb2F0IHk7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2l6ZW9mID0gODsKK30KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0NHUmVjdC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQ0dSZWN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTAzOGRhMgotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0NHUmVjdC5qYXZhCkBAIC0wLDAgKzEsMTYgQEAKK3BhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKworcHVibGljIGNsYXNzIENHUmVjdCB7CisJcHVibGljIGZsb2F0IHg7CisJcHVibGljIGZsb2F0IHk7CisJcHVibGljIGZsb2F0IHdpZHRoOworCXB1YmxpYyBmbG9hdCBoZWlnaHQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2l6ZW9mID0gMTY7Cit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9Db2xvclBpY2tlckluZm8uamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0NvbG9yUGlja2VySW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiOWUwMzIKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9Db2xvclBpY2tlckluZm8uamF2YQpAQCAtMCwwICsxLDM4IEBACitwYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247CisKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKKyAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAorICovCisKK3B1YmxpYyBjbGFzcyBDb2xvclBpY2tlckluZm8geworLy8JUE1Db2xvciB0aGVDb2xvcjsKKwlwdWJsaWMgaW50IHByb2ZpbGU7CisJcHVibGljIHNob3J0IHJlZDsKKwlwdWJsaWMgc2hvcnQgZ3JlZW47CisJcHVibGljIHNob3J0IGJsdWU7CisJcHVibGljIGludCBkc3RQcm9maWxlOworCXB1YmxpYyBpbnQgZmxhZ3M7CisJcHVibGljIHNob3J0IHBsYWNlV2hlcmU7CisvLwlQb2ludCBkaWFsb2dPcmlnaW4KKwlwdWJsaWMgc2hvcnQgaDsKKwlwdWJsaWMgc2hvcnQgdjsKKwlwdWJsaWMgaW50IHBpY2tlclR5cGU7CisJcHVibGljIGludCBldmVudFByb2M7CisJcHVibGljIGludCBjb2xvclByb2M7CisJcHVibGljIGludCBjb2xvclByb2NEYXRhOworLy8JU3RyMjU1IHByb21wdDsKKwlwdWJsaWMgYnl0ZSBbXSBwcm9tcHQgPSBuZXcgYnl0ZSBbMjU2XTsKKy8vCVBpY2tlck1lbnVJdGVtSW5mbyAgbUluZm87CisJcHVibGljIHNob3J0IGVkaXRNZW51SUQ7CisJcHVibGljIHNob3J0IGN1dEl0ZW07CisJcHVibGljIHNob3J0IGNvcHlJdGVtOworCXB1YmxpYyBzaG9ydCBwYXN0ZUl0ZW07CisJcHVibGljIHNob3J0IGNsZWFySXRlbTsKKwlwdWJsaWMgc2hvcnQgdW5kb0l0ZW07CisJcHVibGljIGJvb2xlYW4gbmV3Q29sb3JDaG9zZW47CisvLwlTSW50OCBmaWxsZXI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2l6ZW9mID0gMzEyOworfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9Db250cm9sQnV0dG9uQ29udGVudEluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZGQ4MTg0Ci0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvLmphdmEKQEAgLTAsMCArMSwxNCBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworCitwdWJsaWMgY2xhc3MgQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvIHsKKwlwdWJsaWMgc2hvcnQgY29udGVudFR5cGU7CisJcHVibGljIGludCBpY29uUmVmOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNpemVvZiA9IDY7Cit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9Db250cm9sRm9udFN0eWxlUmVjLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9Db250cm9sRm9udFN0eWxlUmVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTAxNjk1YgotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0NvbnRyb2xGb250U3R5bGVSZWMuamF2YQpAQCAtMCwwICsxLDI2IEBACitwYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247CisKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKKyAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAorICovCisKK3B1YmxpYyBjbGFzcyBDb250cm9sRm9udFN0eWxlUmVjIHsKKwlwdWJsaWMgc2hvcnQgZmxhZ3M7CisJcHVibGljIHNob3J0IGZvbnQ7CisJcHVibGljIHNob3J0IHNpemU7CisJcHVibGljIHNob3J0IHN0eWxlOworCXB1YmxpYyBzaG9ydCBtb2RlOworCXB1YmxpYyBzaG9ydCBqdXN0OworLy8JUkdCQ29sb3IgZm9yZUNvbG9yOworCXB1YmxpYyBzaG9ydCBmb3JlQ29sb3JfcmVkOworCXB1YmxpYyBzaG9ydCBmb3JlQ29sb3JfZ3JlZW47CisJcHVibGljIHNob3J0IGZvcmVDb2xvcl9ibHVlOworLy8JUkdCQ29sb3IgYmFja0NvbG9yOworCXB1YmxpYyBzaG9ydCBiYWNrQ29sb3JfcmVkOworCXB1YmxpYyBzaG9ydCBiYWNrQ29sb3JfZ3JlZW47CisJcHVibGljIHNob3J0IGJhY2tDb2xvcl9ibHVlOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNpemVvZiA9IDI0OworfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQ29udHJvbFRhYkVudHJ5LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9Db250cm9sVGFiRW50cnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NjZjOGE2Ci0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQ29udHJvbFRhYkVudHJ5LmphdmEKQEAgLTAsMCArMSwxNSBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworIAorcHVibGljIGNsYXNzIENvbnRyb2xUYWJFbnRyeSB7CisJcHVibGljIGludCBpY29uOworCXB1YmxpYyBpbnQgbmFtZTsKKwlwdWJsaWMgYm9vbGVhbiBlbmFibGVkOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNpemVvZiA9IDEwOworfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQ29udHJvbFRhYkluZm9SZWNWMS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vQ29udHJvbFRhYkluZm9SZWNWMS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlN2JiN2IKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9Db250cm9sVGFiSW5mb1JlY1YxLmphdmEKQEAgLTAsMCArMSwxNSBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworIAorcHVibGljIGNsYXNzIENvbnRyb2xUYWJJbmZvUmVjVjEgeworCXB1YmxpYyBzaG9ydCB2ZXJzaW9uOworCXB1YmxpYyBzaG9ydCBpY29uU3VpdGVJRDsKKwlwdWJsaWMgaW50IG5hbWU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2l6ZW9mID0gODsgICAgICAgICAgICAgICAgICAgCit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9DdXJzb3IuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0N1cnNvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNmZDRlNDcKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9DdXJzb3IuamF2YQpAQCAtMCwwICsxLDE2IEBACitwYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247CisKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKKyAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAorICovCisKK3B1YmxpYyBjbGFzcyBDdXJzb3IgeworCXB1YmxpYyBzaG9ydFtdIGRhdGEgPSBuZXcgc2hvcnRbMTZdOworCXB1YmxpYyBzaG9ydFtdIG1hc2sgPSBuZXcgc2hvcnRbMTZdOworCXB1YmxpYyBzaG9ydCBob3RTcG90X3Y7CisJcHVibGljIHNob3J0IGhvdFNwb3RfaDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzaXplb2YgPSA2ODsKK30KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0RhdGFCcm93c2VyQ2FsbGJhY2tzLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9EYXRhQnJvd3NlckNhbGxiYWNrcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlYjkyYzIKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9EYXRhQnJvd3NlckNhbGxiYWNrcy5qYXZhCkBAIC0wLDAgKzEsMjMgQEAKK3BhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKyAKK3B1YmxpYyBjbGFzcyBEYXRhQnJvd3NlckNhbGxiYWNrcyB7CisJcHVibGljIGludCB2ZXJzaW9uOworCXB1YmxpYyBpbnQgdjFfaXRlbURhdGFDYWxsYmFjazsKKwlwdWJsaWMgaW50IHYxX2l0ZW1Db21wYXJlQ2FsbGJhY2s7CisJcHVibGljIGludCB2MV9pdGVtTm90aWZpY2F0aW9uQ2FsbGJhY2s7CisJcHVibGljIGludCB2MV9hZGREcmFnSXRlbUNhbGxiYWNrOworCXB1YmxpYyBpbnQgdjFfYWNjZXB0RHJhZ0NhbGxiYWNrOworCXB1YmxpYyBpbnQgdjFfcmVjZWl2ZURyYWdDYWxsYmFjazsKKwlwdWJsaWMgaW50IHYxX3Bvc3RQcm9jZXNzRHJhZ0NhbGxiYWNrOworCXB1YmxpYyBpbnQgdjFfaXRlbUhlbHBDb250ZW50Q2FsbGJhY2s7CisJcHVibGljIGludCB2MV9nZXRDb250ZXh0dWFsTWVudUNhbGxiYWNrOworCXB1YmxpYyBpbnQgdjFfc2VsZWN0Q29udGV4dHVhbE1lbnVDYWxsYmFjazsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzaXplb2YgPSA0NDsKK30KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0RhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9EYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhNGQ5ZDQKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9EYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrcy5qYXZhCkBAIC0wLDAgKzEsMjAgQEAKK3BhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKyAKK3B1YmxpYyBjbGFzcyBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrcyB7CisJcHVibGljIGludCB2ZXJzaW9uOworCXB1YmxpYyBpbnQgdjFfZHJhd0l0ZW1DYWxsYmFjazsKKwlwdWJsaWMgaW50IHYxX2VkaXRUZXh0Q2FsbGJhY2s7CisJcHVibGljIGludCB2MV9oaXRUZXN0Q2FsbGJhY2s7CisJcHVibGljIGludCB2MV90cmFja2luZ0NhbGxiYWNrOworCXB1YmxpYyBpbnQgdjFfZHJhZ1JlZ2lvbkNhbGxiYWNrOworCXB1YmxpYyBpbnQgdjFfYWNjZXB0RHJhZ0NhbGxiYWNrOworCXB1YmxpYyBpbnQgdjFfcmVjZWl2ZURyYWdDYWxsYmFjazsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzaXplb2YgPSAzMjsKK30KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0RhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9EYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmViZTY5NDUKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9EYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYy5qYXZhCkBAIC0wLDAgKzEsNDEgQEAKK3BhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKyAKK3B1YmxpYyBjbGFzcyBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYyB7CisJLy9EYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtbkRlc2MgIHByb3BlcnR5RGVzYzsKKwlwdWJsaWMgaW50ICBwcm9wZXJ0eURlc2NfcHJvcGVydHlJRDsKKwlwdWJsaWMgaW50ICBwcm9wZXJ0eURlc2NfcHJvcGVydHlUeXBlOworCXB1YmxpYyBpbnQgIHByb3BlcnR5RGVzY19wcm9wZXJ0eUZsYWdzOworCS8vRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MgIGhlYWRlckJ0bkRlc2M7CisgIAlwdWJsaWMgaW50IGhlYWRlckJ0bkRlc2NfdmVyc2lvbjsKKwlwdWJsaWMgc2hvcnQgaGVhZGVyQnRuRGVzY19taW5pbXVtV2lkdGg7CisJcHVibGljIHNob3J0IGhlYWRlckJ0bkRlc2NfbWF4aW11bVdpZHRoOworCXB1YmxpYyBzaG9ydCBoZWFkZXJCdG5EZXNjX3RpdGxlT2Zmc2V0OworCXB1YmxpYyBpbnQgaGVhZGVyQnRuRGVzY190aXRsZVN0cmluZzsKKwlwdWJsaWMgc2hvcnQgaGVhZGVyQnRuRGVzY19pbml0aWFsT3JkZXI7CisJLy9Db250cm9sRm9udFN0eWxlUmVjIGhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlOworCXB1YmxpYyBzaG9ydCBoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mbGFnczsKKwlwdWJsaWMgc2hvcnQgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9udDsKKwlwdWJsaWMgc2hvcnQgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfc2l6ZTsKKwlwdWJsaWMgc2hvcnQgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfc3R5bGU7CisJcHVibGljIHNob3J0IGhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX21vZGU7CisJcHVibGljIHNob3J0IGhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX2p1c3Q7CisJLy8gUkdCQ29sb3IgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9yZUNvbG9yOworCXB1YmxpYyBzaG9ydCBoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mb3JlQ29sb3JfcmVkOworIAlwdWJsaWMgc2hvcnQgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfZm9yZUNvbG9yX2dyZWVuOworCXB1YmxpYyBzaG9ydCBoZWFkZXJCdG5EZXNjX2J0bkZvbnRTdHlsZV9mb3JlQ29sb3JfYmx1ZTsKKwkvL1JHQkNvbG9yIGhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX2JhY2tDb2xvcjsKKwlwdWJsaWMgc2hvcnQgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfYmFja0NvbG9yX3JlZDsKKyAJcHVibGljIHNob3J0IGhlYWRlckJ0bkRlc2NfYnRuRm9udFN0eWxlX2JhY2tDb2xvcl9ncmVlbjsKKwlwdWJsaWMgc2hvcnQgaGVhZGVyQnRuRGVzY19idG5Gb250U3R5bGVfYmFja0NvbG9yX2JsdWU7CisJLy9wdWJsaWMgQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvIGhlYWRlckJ0bkRlc2NfYnRuQ29udGVudEluZm87CisJcHVibGljIHNob3J0IGhlYWRlckJ0bkRlc2NfYnRuQ29udGVudEluZm9fY29udGVudFR5cGU7CisJcHVibGljIGludCBoZWFkZXJCdG5EZXNjX2J0bkNvbnRlbnRJbmZvX2ljb25SZWY7IC8vIHVuaW9uIGZpZWxkIAorCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNpemVvZiA9IDU4OworfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0RhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDk4YmNmYgotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0RhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjLmphdmEKQEAgLTAsMCArMSwzNyBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworIAorcHVibGljIGNsYXNzIERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjIHsKKwlwdWJsaWMgaW50IHZlcnNpb247CisJcHVibGljIHNob3J0IG1pbmltdW1XaWR0aDsKKwlwdWJsaWMgc2hvcnQgbWF4aW11bVdpZHRoOworCXB1YmxpYyBzaG9ydCB0aXRsZU9mZnNldDsKKwlwdWJsaWMgaW50IHRpdGxlU3RyaW5nOworCXB1YmxpYyBzaG9ydCBpbml0aWFsT3JkZXI7CisJLy8gQ29udHJvbEZvbnRTdHlsZVJlYyAgYnRuRm9udFN0eWxlOworCXB1YmxpYyBzaG9ydCBidG5Gb250U3R5bGVfZmxhZ3M7CisJcHVibGljIHNob3J0IGJ0bkZvbnRTdHlsZV9mb250OworCXB1YmxpYyBzaG9ydCBidG5Gb250U3R5bGVfc2l6ZTsKKwlwdWJsaWMgc2hvcnQgYnRuRm9udFN0eWxlX3N0eWxlOworCXB1YmxpYyBzaG9ydCBidG5Gb250U3R5bGVfbW9kZTsKKwlwdWJsaWMgc2hvcnQgYnRuRm9udFN0eWxlX2p1c3Q7CisJLy9SR0JDb2xvciBidG5Gb250U3R5bGVfZm9yZUNvbG9yOworCXB1YmxpYyBzaG9ydCBidG5Gb250U3R5bGVfZm9yZUNvbG9yX3JlZDsKKwlwdWJsaWMgc2hvcnQgYnRuRm9udFN0eWxlX2ZvcmVDb2xvcl9ncmVlbjsKKwlwdWJsaWMgc2hvcnQgYnRuRm9udFN0eWxlX2ZvcmVDb2xvcl9ibHVlOworCS8vUkdCQ29sb3IgYnRuRm9udFN0eWxlX2JhY2tDb2xvcjsKKwlwdWJsaWMgc2hvcnQgYnRuRm9udFN0eWxlX2JhY2tDb2xvcl9yZWQ7CisJcHVibGljIHNob3J0IGJ0bkZvbnRTdHlsZV9iYWNrQ29sb3JfZ3JlZW47CisJcHVibGljIHNob3J0IGJ0bkZvbnRTdHlsZV9iYWNrQ29sb3JfYmx1ZTsKKwkvL0NvbnRyb2xCdXR0b25Db250ZW50SW5mbyAgYnRuQ29udGVudEluZm87CisJcHVibGljIHNob3J0IGJ0bkNvbnRlbnRJbmZvX2NvbnRlbnRUeXBlOworCXB1YmxpYyBpbnQgYnRuQ29udGVudEluZm9faWNvblJlZjsKKwkKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzaXplb2YgPSA0NjsKK30KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0V2ZW50UmVjb3JkLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9FdmVudFJlY29yZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4OTMzZDQKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9FdmVudFJlY29yZC5qYXZhCkBAIC0wLDAgKzEsMTggQEAKK3BhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KK3B1YmxpYyBjbGFzcyBFdmVudFJlY29yZCB7CisJcHVibGljIHNob3J0IHdoYXQ7CisJcHVibGljIGludCBtZXNzYWdlOworCXB1YmxpYyBpbnQgd2hlbjsKKwkvL1BvaW50IHdoZXJlOworCXB1YmxpYyBzaG9ydCB3aGVyZV92OworCXB1YmxpYyBzaG9ydCB3aGVyZV9oOworCXB1YmxpYyBzaG9ydCBtb2RpZmllcnM7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2l6ZW9mID0gMTY7Cit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9Gb250SW5mby5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vRm9udEluZm8uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMzRkNzQzCi0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vRm9udEluZm8uamF2YQpAQCAtMCwwICsxLDE2IEBACitwYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247CisKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKKyAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAorICovCisKK3B1YmxpYyBjbGFzcyBGb250SW5mbyB7CisJcHVibGljIHNob3J0IGFzY2VudDsKKwlwdWJsaWMgc2hvcnQgZGVzY2VudDsKKwlwdWJsaWMgc2hvcnQgd2lkTWF4OworCXB1YmxpYyBzaG9ydCBsZWFkaW5nOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNpemVvZiA9IDg7Cit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9Gb250U2VsZWN0aW9uUURTdHlsZS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vRm9udFNlbGVjdGlvblFEU3R5bGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNjkwNzNlCi0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vRm9udFNlbGVjdGlvblFEU3R5bGUuamF2YQpAQCAtMCwwICsxLDIzIEBACitwYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247CisKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKKyAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAorICovCisKK3B1YmxpYyBjbGFzcyBGb250U2VsZWN0aW9uUURTdHlsZSB7CisJcHVibGljIGludCB2ZXJzaW9uOworCS8vRk1Gb250RmFtaWx5SW5zdGFuY2UgaW5zdGFuY2U7CisJcHVibGljIHNob3J0IGluc3RhbmNlX2ZvbnRGYW1pbHk7CisJcHVibGljIHNob3J0IGluc3RhbmNlX2ZvbnRTdHlsZTsKKwlwdWJsaWMgc2hvcnQgc2l6ZTsKKwlwdWJsaWMgYm9vbGVhbiBoYXNDb2xvcjsKKwlwdWJsaWMgYnl0ZSByZXNlcnZlZDsKKwkvL1JHQkNvbG9yIGNvbG9yCisJcHVibGljIHNob3J0IGNvbG9yX3JlZDsKKwlwdWJsaWMgc2hvcnQgY29sb3JfZ3JlZW47CisJcHVibGljIHNob3J0IGNvbG9yX2JsdWU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2l6ZW9mID0gMTg7Cit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9HRGV2aWNlLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9HRGV2aWNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTExYzk3MWIKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9HRGV2aWNlLmphdmEKQEAgLTAsMCArMSwzNCBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworCitwdWJsaWMgY2xhc3MgR0RldmljZSB7CisJcHVibGljIHNob3J0IGdkUmVmTnVtOworCXB1YmxpYyBzaG9ydCBnZElEOworCXB1YmxpYyBzaG9ydCBnZFR5cGU7CisJcHVibGljIGludCBnZElUYWJsZTsKKwlwdWJsaWMgc2hvcnQgZ2RSZXNQcmVmOworCXB1YmxpYyBpbnQgZ2RTZWFyY2hQcm9jOworCXB1YmxpYyBpbnQgZ2RDb21wUHJvYzsKKwlwdWJsaWMgc2hvcnQgZ2RGbGFnczsKKwlwdWJsaWMgaW50IGdkUE1hcDsKKwlwdWJsaWMgaW50IGdkUmVmQ29uOworCXB1YmxpYyBpbnQgZ2ROZXh0R0Q7CisJLy9SZWN0IGdkUmVjdDsKKwlwdWJsaWMgc2hvcnQgbGVmdDsKKwlwdWJsaWMgc2hvcnQgdG9wOworCXB1YmxpYyBzaG9ydCByaWdodDsKKwlwdWJsaWMgc2hvcnQgYm90dG9tOworCXB1YmxpYyBpbnQgZ2RNb2RlOworCXB1YmxpYyBzaG9ydCBnZENDQnl0ZXM7CisJcHVibGljIHNob3J0IGdkQ0NEZXB0aDsKKwlwdWJsaWMgaW50IGdkQ0NYRGF0YTsKKwlwdWJsaWMgaW50IGdkQ0NYTWFzazsKKwlwdWJsaWMgaW50IGdkRXh0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNpemVvZiA9IDYyOworfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vSElDb21tYW5kLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9ISUNvbW1hbmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjViMDY1Ci0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vSElDb21tYW5kLmphdmEKQEAgLTAsMCArMSwxNyBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworIAorcHVibGljIGNsYXNzIEhJQ29tbWFuZCB7CisJcHVibGljIGludCBhdHRyaWJ1dGVzOworCXB1YmxpYyBpbnQgY29tbWFuZElEOworCXB1YmxpYyBpbnQgbWVudV9tZW51UmVmOworCXB1YmxpYyBzaG9ydCBtZW51X21lbnVJdGVtSW5kZXg7CisJCisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2l6ZW9mID0gMTQ7Cit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9ITUhlbHBDb250ZW50UmVjLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9ITUhlbHBDb250ZW50UmVjLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjkyMTMxNAotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL0hNSGVscENvbnRlbnRSZWMuamF2YQpAQCAtMCwwICsxLDI0IEBACitwYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247CisKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKKyAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAorICovCisgCitwdWJsaWMgY2xhc3MgSE1IZWxwQ29udGVudFJlYyB7CisJcHVibGljIGludCB2ZXJzaW9uOworLy8JUmVjdCBhYnNIb3RSZWN0OworCXB1YmxpYyBzaG9ydCBhYnNIb3RSZWN0X3RvcDsKKwlwdWJsaWMgc2hvcnQgYWJzSG90UmVjdF9sZWZ0OworCXB1YmxpYyBzaG9ydCBhYnNIb3RSZWN0X2JvdHRvbTsKKwlwdWJsaWMgc2hvcnQgYWJzSG90UmVjdF9yaWdodDsKKwlwdWJsaWMgc2hvcnQgdGFnU2lkZTsKKy8vCUhNSGVscENvbnRlbnQgICAgICAgY29udGVudFsyXTsKKwlwdWJsaWMgaW50IGNvbnRlbnQwX2NvbnRlbnRUeXBlOworCXB1YmxpYyBpbnQgY29udGVudDBfdGFnQ0ZTdHJpbmc7IAorCXB1YmxpYyBpbnQgY29udGVudDFfY29udGVudFR5cGU7CisJcHVibGljIGludCBjb250ZW50MV90YWdDRlN0cmluZzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzaXplb2YgPSA1MzQ7Cit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNDb250cm9sRXZlbnQuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL01hY0NvbnRyb2xFdmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmZDRkMGJiLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL01hY0NvbnRyb2xFdmVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNDQgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCi0gKgotICogQW5kcmUgV2VpbmFuZCwgT1RJIC0gSW5pdGlhbCB2ZXJzaW9uCi0gKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKLQotcHVibGljIGNsYXNzIE1hY0NvbnRyb2xFdmVudCB7Ci0KLQlwcml2YXRlIGludCBmQ29udHJvbGhhbmRsZTsKLQlwcml2YXRlIGludCBmUGFydENvZGU7Ci0JcHJpdmF0ZSBib29sZWFuIGZNb3VzZURvd247Ci0JcHJpdmF0ZSBpbnQgZkRhbWFnZVJlZ2lvbjsKLQotCXB1YmxpYyBNYWNDb250cm9sRXZlbnQoaW50IGhhbmRsZSwgaW50IHBhcnRDb2RlLCBib29sZWFuIG1vdXNlRG93bikgewotCQlmQ29udHJvbGhhbmRsZT0gaGFuZGxlOwotCQlmUGFydENvZGU9IHBhcnRDb2RlOwotCQlmTW91c2VEb3duPSBtb3VzZURvd247Ci0JfQotCQotCXB1YmxpYyBNYWNDb250cm9sRXZlbnQoaW50IGhhbmRsZSwgaW50IGRhbWFnZVJlZ2lvbikgewotCQlmQ29udHJvbGhhbmRsZT0gaGFuZGxlOwotCQlmRGFtYWdlUmVnaW9uPSBkYW1hZ2VSZWdpb247Ci0JfQotCQotCXB1YmxpYyBpbnQgZ2V0Q29udHJvbEhhbmRsZSgpIHsKLQkJcmV0dXJuIGZDb250cm9saGFuZGxlOwotCX0KLQkKLQlwdWJsaWMgaW50IGdldFBhcnRDb2RlKCkgewotCQlyZXR1cm4gZlBhcnRDb2RlOwotCX0KLQkKLQlwdWJsaWMgaW50IGdldERhbWFnZVJlZ2lvbkhhbmRsZSgpIHsKLQkJcmV0dXJuIGZEYW1hZ2VSZWdpb247Ci0JfQotCQotCXB1YmxpYyBib29sZWFuIGlzTW91c2VEb3duKCkgewotCQlyZXR1cm4gZk1vdXNlRG93bjsKLQl9Ci19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNFdmVudC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vTWFjRXZlbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZjBjMmJiMS4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNFdmVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjc3ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAotICoKLSAqIEFuZHJlIFdlaW5hbmQsIE9USSAtIEluaXRpYWwgdmVyc2lvbgotICovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247Ci0KLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOwotCi1wdWJsaWMgY2xhc3MgTWFjRXZlbnQgewotCi0JcHJpdmF0ZSBzdGF0aWMgaW50IGZnTW91c2VCdXR0b25TdGF0ZTsKLQkKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIEVNVUxBVEVfUklHSFRfQlVUVE9OPSB0cnVlOwotCi0JcHJpdmF0ZSBpbnQgZkV2ZW50UmVmOwotCXByaXZhdGUgaW50IGZOZXh0SGFuZGxlcjsKLQkJCi0JcHVibGljIE1hY0V2ZW50KCkgewotCQlmRXZlbnRSZWY9IC0xOwotCX0KLQotCXB1YmxpYyBNYWNFdmVudChpbnQgZXZlbnRSZWYpIHsKLQkJZkV2ZW50UmVmPSBldmVudFJlZjsKLQl9Ci0JCi0JcHVibGljIE1hY0V2ZW50KGludCBldmVudFJlZiwgaW50IG5leHRIYW5kbGVyKSB7Ci0JCWZFdmVudFJlZj0gZXZlbnRSZWY7Ci0JCWZOZXh0SGFuZGxlcj0gbmV4dEhhbmRsZXI7Ci0JfQotCQotCXB1YmxpYyBpbnQgZ2V0RXZlbnRSZWYoKSB7Ci0JCXJldHVybiBmRXZlbnRSZWY7Ci0JfQotCQotCXB1YmxpYyBpbnQgZ2V0TmV4dEhhbmRsZXIoKSB7Ci0JCXJldHVybiBmTmV4dEhhbmRsZXI7Ci0JfQotCQotCXB1YmxpYyBpbnRbXSB0b09sZE1hY0V2ZW50KCkgewotCQlpZiAoZkV2ZW50UmVmICE9IC0xKSB7Ci0JCQlpbnQgbWFjRXZlbnRbXT0gbmV3IGludFs2XTsKLQkJCWlmIChPUy5Db252ZXJ0RXZlbnRSZWZUb0V2ZW50UmVjb3JkKGZFdmVudFJlZiwgbWFjRXZlbnQpKQotCQkJCXJldHVybiBtYWNFdmVudDsKLQkJfQotCQlTeXN0ZW0ub3V0LnByaW50bG4oIk1hY0V2ZW50LnRvT2xkTWFjRXZlbnQ6IGNhbid0IGNvbnZlcnQgZXZlbnQiKTsKLQkJcmV0dXJuIG51bGw7Ci0JfQotCQotCXB1YmxpYyBpbnQgZ2V0S2luZCgpIHsKLQkJaWYgKGZFdmVudFJlZiAhPSAtMSkKLQkJCXJldHVybiBPUy5HZXRFdmVudEtpbmQoZkV2ZW50UmVmKTsKLQkJU3lzdGVtLm91dC5wcmludGxuKCJNYWNFdmVudC5nZXRLaW5kOiBubyBFdmVudFJlZiIpOwotCQlyZXR1cm4gMDsKLQl9Ci0JCi0JcHVibGljIGludCBnZXRXaGVuKCkgewotCQlpZiAoZkV2ZW50UmVmICE9IC0xKQotCQkJcmV0dXJuIChpbnQpKE9TLkdldEV2ZW50VGltZShmRXZlbnRSZWYpICogMTAwMC4wKTsKLQkJU3lzdGVtLm91dC5wcmludGxuKCJNYWNFdmVudC5nZXRNb2RpZmllcktleXM6IG5vIEV2ZW50UmVmIik7Ci0JCXJldHVybiAwOwotCX0KLQkKLQlwdWJsaWMgTWFjUG9pbnQgZ2V0V2hlcmUoKSB7Ci0JCWlmIChmRXZlbnRSZWYgIT0gLTEpIHsKLQkJCXNob3J0W10gbG9jPSBuZXcgc2hvcnRbMl07Ci0JCQlpZiAoT1MuR2V0RXZlbnRQYXJhbWV0ZXIoZkV2ZW50UmVmLCBPUy5rRXZlbnRQYXJhbU1vdXNlTG9jYXRpb24sIE9TLnR5cGVRRFBvaW50LCBudWxsLCBudWxsLCBsb2MpID09IE9TLmtOb0VycikgewotCQkJCXJldHVybiBuZXcgTWFjUG9pbnQobG9jWzFdLCBsb2NbMF0pOwotCQkJfQotCQl9Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigiTWFjRXZlbnQuZ2V0V2hlcmU6IG5vIEV2ZW50UmVmIik7Ci0JCXJldHVybiBuZXcgTWFjUG9pbnQoMCwgMCk7Ci0JfQotCQotCXB1YmxpYyBQb2ludCBnZXRXaGVyZTIoKSB7Ci0JCWlmIChmRXZlbnRSZWYgIT0gLTEpIHsKLQkJCXNob3J0W10gbG9jPSBuZXcgc2hvcnRbMl07Ci0JCQlpZiAoT1MuR2V0RXZlbnRQYXJhbWV0ZXIoZkV2ZW50UmVmLCBPUy5rRXZlbnRQYXJhbU1vdXNlTG9jYXRpb24sIE9TLnR5cGVRRFBvaW50LCBudWxsLCBudWxsLCBsb2MpID09IE9TLmtOb0VycikgewotCQkJCXJldHVybiBuZXcgUG9pbnQobG9jWzFdLCBsb2NbMF0pOwotCQkJfQotCQl9Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigiTWFjRXZlbnQuZ2V0V2hlcmUyOiBubyBFdmVudFJlZiIpOwotCQlyZXR1cm4gbmV3IFBvaW50KDAsIDApOwotCX0KLQotCS8qKgotCSAqIFJldHVybnMgdGhlIE1hYyBtb2RpZmllcnMgZm9yIHRoaXMgZXZlbnQKLQkgKi8KLQlwdWJsaWMgaW50IGdldE1vZGlmaWVycygpIHsKLQkJaWYgKGZFdmVudFJlZiAhPSAtMSkKLQkJCXJldHVybiBnZXRFdmVudE1vZGlmaWVycyhmRXZlbnRSZWYpOwotCQlTeXN0ZW0ub3V0LnByaW50bG4oIk1hY0V2ZW50LmdldE1vZGlmaWVyczogbm8gRXZlbnRSZWYiKTsKLQkJcmV0dXJuIDA7Ci0JfQotCQotCS8qKgotCSAqIFJldHVybnMgdGhlIFNXVCBtb2RpZmllcnMgZm9yIHRoaXMgZXZlbnQKLQkgKi8KLQlwdWJsaWMgaW50IGdldFN0YXRlTWFzaygpIHsKLQkJaW50IHN0YXRlTWFzaz0gZmdNb3VzZUJ1dHRvblN0YXRlOwotCQlpbnQgbW9kaWZpZXJzPSBnZXRNb2RpZmllcnMgKCk7Ci0JCWlmICgobW9kaWZpZXJzICYgT1Muc2hpZnRLZXkpICE9IDApIHN0YXRlTWFzayB8PSBTV1QuU0hJRlQ7Ci0JCWlmICgobW9kaWZpZXJzICYgT1MuY29udHJvbEtleSkgIT0gMCkgewotCQkJaWYgKEVNVUxBVEVfUklHSFRfQlVUVE9OKSB7Ci0JCQkJLy8gd2Ugb25seSByZXBvcnQgQ09OVFJPTCwgaWZmIGl0IHdhcyBub3QgdXNlZCB0byBlbXVsYXRlIHRoZSByaWdodCBtb3VzZSBidXR0b24KLQkJCQlpZiAoKHN0YXRlTWFzayAmIFNXVC5CVVRUT04zKSA9PSAwKSBzdGF0ZU1hc2sgfD0gU1dULkNPTlRST0w7Ci0JCQl9IGVsc2UgewotCQkJCXN0YXRlTWFzayB8PSBTV1QuQ09OVFJPTDsKLQkJCX0KLQkJfQotCQlpZiAoKG1vZGlmaWVycyAmIE9TLmNtZEtleSkgIT0gMCkgc3RhdGVNYXNrIHw9IFNXVC5DT01NQU5EOwotCQlpZiAoKG1vZGlmaWVycyAmIE9TLm9wdGlvbktleSkgIT0gMCkgc3RhdGVNYXNrIHw9IFNXVC5BTFQ7Ci0JCXJldHVybiBzdGF0ZU1hc2s7Ci0JfQotCQkKLQlwdWJsaWMgaW50IGdldEtleUNvZGUoKSB7Ci0JCWlmIChmRXZlbnRSZWYgIT0gLTEpCi0JCQlyZXR1cm4gZ2V0S2V5Q29kZShmRXZlbnRSZWYpOwotCQlTeXN0ZW0ub3V0LnByaW50bG4oIk1hY0V2ZW50LmdldEtleUNvZGU6IG5vIEV2ZW50UmVmIik7Ci0JCXJldHVybiAwOwotCX0KLQkKLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBTV1QgbW91c2UgYnV0dG9uCi0JICovCi0JcHVibGljIGludCBnZXRCdXR0b24oKSB7Ci0JCWlmIChmRXZlbnRSZWYgIT0gLTEpCi0JCQlyZXR1cm4gZ2V0RXZlbnRNb3VzZUJ1dHRvbihmRXZlbnRSZWYpOwotCi0JCVN5c3RlbS5vdXQucHJpbnRsbigiTWFjRXZlbnQuZ2V0QnV0dG9uOiBubyBFdmVudFJlZiIpOwotCQlyZXR1cm4gMDsKLQl9Ci0JCi0JcHVibGljIGJvb2xlYW4gaXNTaG93Q29udGV4dHVhbE1lbnVDbGljaygpIHsKLQkJaWYgKGZFdmVudFJlZiA9PSAtMSkgewotCQkJU3lzdGVtLm91dC5wcmludGxuKCJNYWNFdmVudC5pc1Nob3dDb250ZXh0dWFsTWVudUNsaWNrOiBubyBFdmVudFJlZiIpOwotCQkJcmV0dXJuIGZhbHNlOwotCQl9Ci0JCXJldHVybiAoT1MuR2V0RXZlbnRDbGFzcyhmRXZlbnRSZWYpID09IE9TLmtFdmVudENsYXNzTW91c2UpICYmIAotCQkJCQkoZ2V0S2luZCgpID09IE9TLmtFdmVudE1vdXNlRG93bikgJiYKLQkJCQkJCShnZXRCdXR0b24oKSA9PSAzKTsKLQkJLy8gcmV0dXJuIE9TLklzU2hvd0NvbnRleHR1YWxNZW51Q2xpY2soZ2V0RGF0YSgpKTsKLQl9Ci0KLQlwdWJsaWMgaW50IGdldE1hY0NoYXJDb2RlcygpIHsKLQkJaWYgKGZFdmVudFJlZiAhPSAtMSkKLQkJCXJldHVybiBnZXRDaGFyQ29kZShmRXZlbnRSZWYpOwotCQlTeXN0ZW0ub3V0LnByaW50bG4oIk1hY0V2ZW50LmdldE1hY0NoYXJDb2Rlczogbm8gRXZlbnRSZWYiKTsKLQkJcmV0dXJuIC0xOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0VGV4dCgpIHsKLQkJaWYgKGZFdmVudFJlZiA9PSAtMSkgewotCQkJU3lzdGVtLm91dC5wcmludGxuKCJNYWNFdmVudC5nZXRUZXh0OiBubyBFdmVudFJlZiIpOwotCQkJcmV0dXJuIG51bGw7Ci0JCX0KLQkJaW50W10gYWN0dWFsU2l6ZT0gbmV3IGludFsxXTsKLQkJT1MuR2V0RXZlbnRQYXJhbWV0ZXIoZkV2ZW50UmVmLCBPUy5rRXZlbnRQYXJhbVRleHRJbnB1dFNlbmRUZXh0LCBPUy50eXBlVW5pY29kZVRleHQsIG51bGwsIGFjdHVhbFNpemUsIChjaGFyW10pbnVsbCk7Ci0JCWludCBzaXplPSBhY3R1YWxTaXplWzBdIC8gMjsKLQkJaWYgKHNpemUgPiAwKSB7Ci0JCQljaGFyW10gYnVmZmVyPSBuZXcgY2hhcltzaXplXTsKLQkJCU9TLkdldEV2ZW50UGFyYW1ldGVyKGZFdmVudFJlZiwgT1Mua0V2ZW50UGFyYW1UZXh0SW5wdXRTZW5kVGV4dCwgT1MudHlwZVVuaWNvZGVUZXh0LCBudWxsLCBudWxsLCBidWZmZXIpOwotCQkJcmV0dXJuIG5ldyBTdHJpbmcoYnVmZmVyKTsJCQkKLQkJfQotCQlyZXR1cm4gIiI7Ci0JfQotCi0JLy8tLS0tIENhcmJvbiBldmVudCBhY2Nlc3NvcnMKLQkKLQlwdWJsaWMgc3RhdGljIGludCBnZXREaXJlY3RPYmplY3QoaW50IGVSZWZIYW5kbGUpIHsKLQkJaW50W10gd0hhbmRsZT0gbmV3IGludFsxXTsKLQkJaWYgKE9TLkdldEV2ZW50UGFyYW1ldGVyKGVSZWZIYW5kbGUsIE9TLmtFdmVudFBhcmFtRGlyZWN0T2JqZWN0LCBPUy50eXBlV2luZG93UmVmLCBudWxsLCBudWxsLCB3SGFuZGxlKSA9PSBPUy5rTm9FcnIpCQotCQkJcmV0dXJuIHdIYW5kbGVbMF07Ci0JCXJldHVybiAwOwotCX0KLQkKLQlwdWJsaWMgc3RhdGljIHNob3J0IGdldFdpbmRvd0RlZlBhcnQoaW50IGVSZWZIYW5kbGUpIHsKLQkJc2hvcnRbXSBwYXJ0PSBuZXcgc2hvcnRbMV07Ci0JCWlmIChPUy5HZXRFdmVudFBhcmFtZXRlcihlUmVmSGFuZGxlLCBPUy5rRXZlbnRQYXJhbVdpbmRvd0RlZlBhcnQsIE9TLnR5cGVXaW5kb3dEZWZQYXJ0Q29kZSwgbnVsbCwgbnVsbCwgcGFydCkgPT0gT1Mua05vRXJyKQkKLQkJCXJldHVybiBwYXJ0WzBdOwotCQlyZXR1cm4gMDsKLQl9Ci0JCi0JcHVibGljIHN0YXRpYyBpbnQgZ2V0Q29udHJvbFJlZihpbnQgZVJlZkhhbmRsZSkgewotCQlpbnRbXSBjSGFuZGxlPSBuZXcgaW50WzFdOwotCQlpZiAoT1MuR2V0RXZlbnRQYXJhbWV0ZXIoZVJlZkhhbmRsZSwgT1Mua0V2ZW50UGFyYW1Db250cm9sUmVmLCBPUy50eXBlQ29udHJvbFJlZiwgbnVsbCwgbnVsbCwgY0hhbmRsZSkgPT0gT1Mua05vRXJyKQkKLQkJCXJldHVybiBjSGFuZGxlWzBdOwotCQlyZXR1cm4gMDsKLQl9Ci0JCi0JcHVibGljIHN0YXRpYyBpbnQgZ2V0RXZlbnRNb2RpZmllcnMoaW50IGVSZWZIYW5kbGUpIHsKLQkJaW50W10gbW9kaWZpZXJLZXlzPSBuZXcgaW50WzFdOwotCQlpZiAoT1MuR2V0RXZlbnRQYXJhbWV0ZXIoZVJlZkhhbmRsZSwgT1Mua0V2ZW50UGFyYW1LZXlNb2RpZmllcnMsIE9TLnR5cGVVSW50MzIsIG51bGwsIG51bGwsIG1vZGlmaWVyS2V5cykgPT0gT1Mua05vRXJyKSB7CQotCQkJcmV0dXJuIG1vZGlmaWVyS2V5c1swXTsKLQkJfQotCQlTeXN0ZW0ub3V0LnByaW50bG4oIk1hY0V2ZW50LmdldE1vZGlmaWVyS2V5czogZ2V0RXZlbnRNb2RpZmllcnMgZXJyb3IiKTsJCQkKLQkJcmV0dXJuIC0xOwotCX0KLQotCXByaXZhdGUgc3RhdGljIGludCBnZXRNb3VzZUNob3JkKGludCBlUmVmSGFuZGxlKSB7Ci0JCWludFtdIG1vdXNlQ2hvcmQ9IG5ldyBpbnRbMV07Ci0JCWlmIChPUy5HZXRFdmVudFBhcmFtZXRlcihlUmVmSGFuZGxlLCBPUy5rRXZlbnRQYXJhbU1vdXNlQ2hvcmQsIE9TLnR5cGVVSW50MzIsIG51bGwsIG51bGwsIG1vdXNlQ2hvcmQpID09IE9TLmtOb0VycikgewkKLQkJCXJldHVybiBtb3VzZUNob3JkWzBdOwotCQl9Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigiTWFjRXZlbnQuZ2V0TW91c2VDaG9yZDogZ2V0TW91c2VDaG9yZCBlcnJvciIpOwkJCQotCQlyZXR1cm4gLTE7Ci0JfQotCQotCXB1YmxpYyBzdGF0aWMgaW50IGdldEtleUNvZGUoaW50IGVSZWZIYW5kbGUpIHsKLQkJaW50W10ga2V5Q29kZT0gbmV3IGludFsxXTsKLQkJaWYgKE9TLkdldEV2ZW50UGFyYW1ldGVyKGVSZWZIYW5kbGUsIE9TLmtFdmVudFBhcmFtS2V5Q29kZSwgT1MudHlwZVVJbnQzMiwgbnVsbCwgbnVsbCwga2V5Q29kZSkgPT0gT1Mua05vRXJyKQotCQkJcmV0dXJuIGtleUNvZGVbMF07Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigiTWFjRXZlbnQuZ2V0TW91c2VDaG9yZDogZ2V0S2V5Q29kZSBlcnJvciIpOwkJCQotCQlyZXR1cm4gLTE7Ci0JfQotCQotCXB1YmxpYyBzdGF0aWMgaW50IGdldENoYXJDb2RlKGludCBlUmVmSGFuZGxlKSB7Ci0JCWJ5dGVbXSBjaGFyQ29kZT0gbmV3IGJ5dGVbMV07Ci0JCWlmIChPUy5HZXRFdmVudFBhcmFtZXRlcihlUmVmSGFuZGxlLCBPUy5rRXZlbnRQYXJhbUtleU1hY0NoYXJDb2RlcywgT1MudHlwZUNoYXIsIG51bGwsIG51bGwsIGNoYXJDb2RlKSA9PSBPUy5rTm9FcnIpCQotCQkJcmV0dXJuIGNoYXJDb2RlWzBdOwotCQlyZXR1cm4gLTE7Ci0JfQotCi0JcHJpdmF0ZSBzdGF0aWMgc2hvcnQgZ2V0RXZlbnRNb3VzZUJ1dHRvbihpbnQgZVJlZkhhbmRsZSkgewotCQlzaG9ydFtdIG1vdXNlQnV0dG9ucz0gbmV3IHNob3J0WzFdOwotCQlpZiAoT1MuR2V0RXZlbnRQYXJhbWV0ZXIoZVJlZkhhbmRsZSwgT1Mua0V2ZW50UGFyYW1Nb3VzZUJ1dHRvbiwgT1MudHlwZU1vdXNlQnV0dG9uLCBudWxsLCBudWxsLCBtb3VzZUJ1dHRvbnMpID09IE9TLmtOb0VycikgewkKLQkJCXNob3J0IGJ1dHRvbj0gbW91c2VCdXR0b25zWzBdOwotCQkJc3dpdGNoIChidXR0b24pIHsKLQkJCWNhc2UgT1Mua0V2ZW50TW91c2VCdXR0b25QcmltYXJ5OgkJLy8gbGVmdCBtb3VzZSBidXR0b24KLQkJCQlpZiAoRU1VTEFURV9SSUdIVF9CVVRUT04pIHsKLQkJCQkJaWYgKChnZXRFdmVudE1vZGlmaWVycyhlUmVmSGFuZGxlKSAmIE9TLmNvbnRyb2xLZXkpICE9IDApCi0JCQkJCQlyZXR1cm4gMzsKLQkJCQl9Ci0JCQkJcmV0dXJuIDE7Ci0JCQljYXNlIE9TLmtFdmVudE1vdXNlQnV0dG9uU2Vjb25kYXJ5OgkvLyByaWdodCBtb3VzZSBidXR0b24KLQkJCQlyZXR1cm4gMzsKLQkJCWNhc2UgT1Mua0V2ZW50TW91c2VCdXR0b25UZXJ0aWFyeToJCS8vIG1pZGRsZSBtb3VzZSBidXR0b24KLQkJCQlyZXR1cm4gMjsKLQkJCWRlZmF1bHQ6Ci0JCQkJcmV0dXJuIGJ1dHRvbjsKLQkJCX0KLQkJfQotCQlyZXR1cm4gMDsKLQl9Ci0JCi0JcHVibGljIHN0YXRpYyB2b2lkIHRyYWNrU3RhdGVNYXNrKGludCBldmVudCwgaW50IGtpbmQpIHsKLQkJc3dpdGNoIChraW5kKSB7CQkJCQotCQljYXNlIE9TLmtFdmVudE1vdXNlRG93bjoKLQkJY2FzZSBPUy5rRXZlbnRNb3VzZURyYWdnZWQ6Ci0JCWNhc2UgT1Mua0V2ZW50TW91c2VVcDoKLQkJCWludCBjaG9yZD0gZ2V0TW91c2VDaG9yZChldmVudCk7Ci0JCQlpZiAoY2hvcmQgIT0gLTEpIHsKLQkJCQlmZ01vdXNlQnV0dG9uU3RhdGU9IDA7Ci0JCQkJaWYgKChjaG9yZCAmIDEpICE9IDApIHsKLQkJCQkJaW50IG1vZGlmaWVycz0gZ2V0RXZlbnRNb2RpZmllcnMoZXZlbnQpOwotCQkJCQlpZiAoRU1VTEFURV9SSUdIVF9CVVRUT04gJiYgKChtb2RpZmllcnMgJiBPUy5jb250cm9sS2V5KSAhPSAwKSkgewotCQkJCQkJZmdNb3VzZUJ1dHRvblN0YXRlIHw9IFNXVC5CVVRUT04zOwkKLQkJCQkJfSBlbHNlIHsKLQkJCQkJCWZnTW91c2VCdXR0b25TdGF0ZSB8PSBTV1QuQlVUVE9OMTsKLQkJCQkJfQotCQkJCX0KLQkJCQlpZiAoKGNob3JkICYgMikgIT0gMCkKLQkJCQkJZmdNb3VzZUJ1dHRvblN0YXRlIHw9IFNXVC5CVVRUT04zOwotCQkJCWlmICgoY2hvcmQgJiA0KSAhPSAwKQotCQkJCQlmZ01vdXNlQnV0dG9uU3RhdGUgfD0gU1dULkJVVFRPTjI7Ci0JCQl9Ci0JCQlicmVhazsJCQkKLQkJY2FzZSBPUy5rRXZlbnRNb3VzZU1vdmVkOgotCQkJZmdNb3VzZUJ1dHRvblN0YXRlPSAwOwotCQkJYnJlYWs7Ci0JCX0KLQl9Ci19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNGb250LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNGb250LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJhN2I4NzQuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vTWFjRm9udC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTEyICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAotICoKLSAqIEFuZHJlIFdlaW5hbmQsIE9USSAtIEluaXRpYWwgdmVyc2lvbgotICovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247Ci0KLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLio7Ci0KLXB1YmxpYyBjbGFzcyBNYWNGb250IHsKLQotCXB1YmxpYyBzaG9ydCBmSUQ9IDE7Ci0JcHVibGljIHNob3J0IGZTaXplPSAxMjsKLQlwdWJsaWMgc2hvcnQgZkZhY2U9IDA7Ci0KLQotCXB1YmxpYyBNYWNGb250KCkgewotCX0KLQkKLQlwdWJsaWMgTWFjRm9udChTdHJpbmcgbmFtZSwgaW50IHNpemUsIGludCBmYWNlKSB7Ci0JCi0JCWZGYWNlPSBPUy5ub3JtYWw7Ci0JCWlmICgoZmFjZSAmIFNXVC5CT0xEKSAhPSAgMCkKLQkJCWZGYWNlIHw9IE9TLmJvbGQ7Ci0JCWlmICgoZmFjZSAmIFNXVC5JVEFMSUMpICE9ICAwKQotCQkJZkZhY2UgfD0gT1MuaXRhbGljOwotCi0JCWlmICgiQ291cmllciIuZXF1YWxzKG5hbWUpKSB7Ci0JCQluYW1lPSAiTW9uYWNvIjsKLQkJfQotCQkKLQkJaWYgKCJNUyBTYW5zIFNlcmlmIi5lcXVhbHMobmFtZSkpIHsKLQkJCU1hY0ZvbnQgZj0gRGlzcGxheS5nZXRUaGVtZUZvbnQoT1Mua1RoZW1lU3lzdGVtRm9udCk7Ci0JCQlmSUQ9IGYuZklEOwotCQkJZlNpemU9IGYuZlNpemU7Ci0JCQlyZXR1cm47Ci0JCX0KLQkJCi0JCWlmIChzaXplIDwgMTApCi0JCQlzaXplPSAxMDsKLQotCQlzaG9ydCBpZD0gT1MuRk1HZXRGb250RmFtaWx5RnJvbU5hbWUoTWFjVXRpbC5TdHIyNTUobmFtZSkpOwotCQkvL1N5c3RlbS5vdXQucHJpbnQoIk1hY0ZvbnQoIiArIG5hbWUgKyAiLCAiICsgc2l6ZSArICIsICIgKyBmYWNlICsgIik6ICIpOwotCQlpZiAoaWQgPT0gT1Mua0ludmFsaWRGb250RmFtaWx5KSB7Ci0JCQlmSUQ9IChzaG9ydCkgMTsKLQkJCS8vU3lzdGVtLm91dC5wcmludGxuKCJub3QgZm91bmQiKTsKLQkJfSBlbHNlIHsKLQkJCWZJRD0gaWQ7Ci0JCQkvL1N5c3RlbS5vdXQucHJpbnRsbihmSUQpOwotCQl9Ci0JCWZTaXplPSAoc2hvcnQpc2l6ZTsKLQl9Ci0JCi0JcHVibGljIE1hY0ZvbnQoc2hvcnQgSUQsIHNob3J0IHNpemUsIHNob3J0IGZhY2UpIHsKLQkJZklEPSBJRDsKLQkJZlNpemU9IHNpemU7Ci0JCWZGYWNlPSBPUy5ub3JtYWw7Ci0JCWlmICgoZmFjZSAmIFNXVC5CT0xEKSAhPSAgMCkKLQkJCWZGYWNlIHw9IE9TLmJvbGQ7Ci0JCWlmICgoZmFjZSAmIFNXVC5JVEFMSUMpICE9ICAwKQotCQkJZkZhY2UgfD0gT1MuaXRhbGljOwotCX0KLQkKLQlwdWJsaWMgTWFjRm9udChzaG9ydCBJRCkgewotCQlmSUQ9IElEOwotCX0KLQkKLQlwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7Ci0JCWJ5dGVbXSBuYW1lPSBuZXcgYnl0ZVsyNTZdOwotCQlpZiAoT1MuRk1HZXRGb250RmFtaWx5TmFtZShmSUQsIG5hbWUpID09IE9TLmtOb0VycikKLQkJCXJldHVybiBNYWNVdGlsLnRvU3RyaW5nKG5hbWUpOwotCQlyZXR1cm4gIm5vIG5hbWUiOwotCX0KLQkKLQlwdWJsaWMgc2hvcnQgZ2V0U2l6ZSgpIHsKLQkJcmV0dXJuIGZTaXplOwotCX0KLQkKLQlwdWJsaWMgaW50IGdldEZhY2UoKSB7Ci0JCWludCBmYWNlPSAwOwotCQlpZiAoKGZGYWNlICYgT1MuYm9sZCkgIT0gMCkKLQkJCWZhY2UgfD0gU1dULkJPTEQ7Ci0JCWlmICgoZkZhY2UgJiBPUy5pdGFsaWMpICE9IDApCi0JCQlmYWNlIHw9IFNXVC5JVEFMSUM7Ci0JCXJldHVybiBmYWNlOwotCX0KLQkKLQlwdWJsaWMgdm9pZCBpbnN0YWxsSW5HcmFmUG9ydCgpIHsKLQkJT1MuVGV4dEZvbnQoZklEKTsKLQkJT1MuVGV4dFNpemUoZlNpemUpOwotCQlPUy5UZXh0RmFjZShmRmFjZSk7Ci0JfQotCQotCXB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7Ci0JCWlmIChvYmplY3QgPT0gdGhpcykgcmV0dXJuIHRydWU7Ci0JCWlmICghKG9iamVjdCBpbnN0YW5jZW9mIE1hY0ZvbnQpKSByZXR1cm4gZmFsc2U7Ci0JCU1hY0ZvbnQgZm9udD0gKE1hY0ZvbnQpIG9iamVjdDsKLQkJcmV0dXJuIGZJRCA9PSBmb250LmZJRCAmJiBmU2l6ZSA9PSBmb250LmZTaXplICYmIGZGYWNlID09IGZvbnQuZkZhY2U7Ci0JfQotCQotCXB1YmxpYyBpbnQgaGFzaENvZGUoKSB7Ci0JCXJldHVybiAoZklEIDw8IDE2KSB8IChmU2l6ZSA8PCA4KSB8IGZGYWNlOwotCX0KLQkKLQlwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCQlyZXR1cm4gZklEICsgIiwiICsgZlNpemUgKyAiLCIgKyBmRmFjZTsKLQl9Ci19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNNb3VzZUV2ZW50LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNNb3VzZUV2ZW50LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUyMWQyMzAuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vTWFjTW91c2VFdmVudC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjEgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCi0gKgotICogQW5kcmUgV2VpbmFuZCwgT1RJIC0gSW5pdGlhbCB2ZXJzaW9uCi0gKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKLQotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5Qb2ludDsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwotCi1wdWJsaWMgY2xhc3MgTWFjTW91c2VFdmVudCB7Ci0JCi0JcHJpdmF0ZSBpbnQgZldoZW47Ci0JcHJpdmF0ZSBQb2ludCBmV2hlcmU7Ci0JcHJpdmF0ZSBpbnQgZlN0YXRlOwotCXByaXZhdGUgaW50IGZCdXR0b247Ci0JcHJpdmF0ZSBNYWNFdmVudCBmTWFjRXZlbnQ7Ci0JCi0JcHVibGljIE1hY01vdXNlRXZlbnQoKSB7Ci0JfQotCi0JcHVibGljIE1hY01vdXNlRXZlbnQoaW50IGJ1dHRvbiwgUG9pbnQgd2hlcmUpIHsKLQkJZkJ1dHRvbj0gYnV0dG9uOwotCQlmV2hlcmU9IHdoZXJlOwotCQlmU3RhdGU9IFNXVC5CVVRUT04xOwotCX0KLQkKLQlwdWJsaWMgTWFjTW91c2VFdmVudChNYWNFdmVudCBtZSkgewotCQlmTWFjRXZlbnQ9IG1lOwotCQlmV2hlbj0gbWUuZ2V0V2hlbigpOwotCQlmV2hlcmU9IG1lLmdldFdoZXJlMigpOwotCQlmU3RhdGU9IG1lLmdldFN0YXRlTWFzaygpOwotCQlmQnV0dG9uPSBtZS5nZXRCdXR0b24oKTsKLQl9Ci0JCi0JcHVibGljIGludCBnZXRXaGVuKCkgewotCQlyZXR1cm4gZldoZW47Ci0JfQotCQotCXB1YmxpYyBQb2ludCBnZXRXaGVyZSgpIHsKLQkJcmV0dXJuIGZXaGVyZTsKLQl9Ci0KLQlwdWJsaWMgaW50IGdldFN0YXRlKCkgewotCQlyZXR1cm4gZlN0YXRlOwotCX0KLQkKLQlwdWJsaWMgaW50IGdldEJ1dHRvbigpIHsKLQkJcmV0dXJuIGZCdXR0b247Ci0JfQotCQotCXB1YmxpYyBpbnRbXSB0b09sZE1hY0V2ZW50KCkgewotCQlpZiAoZk1hY0V2ZW50ICE9IG51bGwpCi0JCQlyZXR1cm4gZk1hY0V2ZW50LnRvT2xkTWFjRXZlbnQoKTsKLQkJU3lzdGVtLmVyci5wcmludGxuKCJNYWNNb3VzZUV2ZW50LnRvT2xkTWFjRXZlbnQ6IG55aSIpOwotCQlyZXR1cm4gbnVsbDsKLQl9Ci19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNQb2ludC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vTWFjUG9pbnQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDZlZDM1MS4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNQb2ludC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTIgKzAsMCBAQAotLyoKLSAqIENvcHlyaWdodCAoYykgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi0gKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCi0gKgotICogQW5kcmUgV2VpbmFuZCwgT1RJIC0gSW5pdGlhbCB2ZXJzaW9uCi0gKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKLQotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5Qb2ludDsKLQotcHVibGljIGNsYXNzIE1hY1BvaW50IHsKLQotCS8vIDA6IHZlcnRpY2FsCi0JLy8gMTogaG9yaXpvbnRhbAotCXByaXZhdGUgc2hvcnRbXSBmRGF0YT0gbmV3IHNob3J0WzJdOwotCQotCXB1YmxpYyBNYWNQb2ludCgpIHsKLQl9Ci0JCi0JcHVibGljIE1hY1BvaW50KHNob3J0IHgsIHNob3J0IHkpIHsKLQkJZkRhdGFbMF09IHk7Ci0JCWZEYXRhWzFdPSB4OwotCX0KLQkKLQlwdWJsaWMgTWFjUG9pbnQoaW50IHgsIGludCB5KSB7Ci0JCWZEYXRhWzBdPSAoc2hvcnQpIHk7Ci0JCWZEYXRhWzFdPSAoc2hvcnQpIHg7Ci0JfQotCQotCXB1YmxpYyBNYWNQb2ludChQb2ludCBwKSB7Ci0JCWZEYXRhWzBdPSAoc2hvcnQpIHAueTsKLQkJZkRhdGFbMV09IChzaG9ydCkgcC54OwotCX0KLQkKLQlwdWJsaWMgc2hvcnRbXSBnZXREYXRhKCkgewotCQlyZXR1cm4gZkRhdGE7Ci0JfQotCQotCXB1YmxpYyBpbnQgZ2V0WCgpIHsKLQkJcmV0dXJuIGZEYXRhWzFdOwotCX0KLQkKLQlwdWJsaWMgaW50IGdldFkoKSB7Ci0JCXJldHVybiBmRGF0YVswXTsKLQl9Ci0JCi0JcHVibGljIFBvaW50IHRvUG9pbnQoKSB7Ci0JCXJldHVybiBuZXcgUG9pbnQoZkRhdGFbMV0sIGZEYXRhWzBdKTsKLQl9Ci19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNSZWN0LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNSZWN0LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDVhMGIzZDAuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vTWFjUmVjdC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA2ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAotICoKLSAqIEFuZHJlIFdlaW5hbmQsIE9USSAtIEluaXRpYWwgdmVyc2lvbgotICovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247Ci0KLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUmVjdGFuZ2xlOwotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5Qb2ludDsKLQotcHVibGljIGNsYXNzIE1hY1JlY3QgewotCi0JLy8gMDogdG9wCi0JLy8gMTogbGVmdAotCS8vIDI6IGJvdHRvbQotCS8vIDM6IHJpZ2h0Ci0JcHJpdmF0ZSBzaG9ydFtdIGZEYXRhPSBuZXcgc2hvcnRbNF07Ci0JCi0JcHVibGljIE1hY1JlY3QoKSB7Ci0JfQotCQotCXB1YmxpYyBNYWNSZWN0KGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoKSB7Ci0JCWZEYXRhWzBdPSAoc2hvcnQpIHk7Ci0JCWZEYXRhWzFdPSAoc2hvcnQpIHg7Ci0JCWZEYXRhWzJdPSAoc2hvcnQpICh5K2gpOwotCQlmRGF0YVszXT0gKHNob3J0KSAoeCt3KTsKLQl9Ci0JCi0JcHVibGljIE1hY1JlY3QoUmVjdGFuZ2xlIHIpIHsKLQkJZkRhdGFbMF09IChzaG9ydCkgKHIueSk7Ci0JCWZEYXRhWzFdPSAoc2hvcnQpIChyLngpOwotCQlmRGF0YVsyXT0gKHNob3J0KSAoci55K3IuaGVpZ2h0KTsKLQkJZkRhdGFbM109IChzaG9ydCkgKHIueCtyLndpZHRoKTsKLQl9Ci0JCi0JcHVibGljIHZvaWQgc2V0KGludCB4LCBpbnQgeSwgaW50IHcsIGludCBoKSB7Ci0JCWZEYXRhWzBdPSAoc2hvcnQpIHk7Ci0JCWZEYXRhWzFdPSAoc2hvcnQpIHg7Ci0JCWZEYXRhWzJdPSAoc2hvcnQpICh5K2gpOwotCQlmRGF0YVszXT0gKHNob3J0KSAoeCt3KTsKLQl9Ci0JCi0JcHVibGljIHNob3J0W10gZ2V0RGF0YSgpIHsKLQkJcmV0dXJuIGZEYXRhOwotCX0KLQkKLQlwdWJsaWMgUmVjdGFuZ2xlIHRvUmVjdGFuZ2xlKCkgewotCQlyZXR1cm4gbmV3IFJlY3RhbmdsZShmRGF0YVsxXSwgZkRhdGFbMF0sIGZEYXRhWzNdLWZEYXRhWzFdLCBmRGF0YVsyXS1mRGF0YVswXSk7Ci0JfQotCQotCXB1YmxpYyBQb2ludCBnZXRTaXplKCkgewotCQlyZXR1cm4gbmV3IFBvaW50KGZEYXRhWzNdLWZEYXRhWzFdLCBmRGF0YVsyXS1mRGF0YVswXSk7Ci0JfQotCQotCXB1YmxpYyBQb2ludCBnZXRMb2NhdGlvbigpIHsKLQkJcmV0dXJuIG5ldyBQb2ludChmRGF0YVsxXSwgZkRhdGFbMF0pOwotCX0KLQkKLQlwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbihpbnQgeCwgaW50IHkpIHsKLQkJaW50IHc9IGZEYXRhWzNdLWZEYXRhWzFdOwotCQlpbnQgaD0gZkRhdGFbMl0tZkRhdGFbMF07Ci0JCWZEYXRhWzBdPSAoc2hvcnQpKHkpOwotCQlmRGF0YVsxXT0gKHNob3J0KSh4KTsKLQkJZkRhdGFbMl09IChzaG9ydCkoeStoKTsKLQkJZkRhdGFbM109IChzaG9ydCkoeCt3KTsKLQl9Ci0JCi0JcHVibGljIHZvaWQgc2V0U2l6ZShpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKLQkJZkRhdGFbMl09IChzaG9ydCkoZkRhdGFbMF0rIGhlaWdodCk7Ci0JCWZEYXRhWzNdPSAoc2hvcnQpKGZEYXRhWzFdKyB3aWR0aCk7Ci0JfQotCQotCXB1YmxpYyBpbnQgZ2V0WCgpIHsKLQkJcmV0dXJuIGZEYXRhWzFdOwotCX0KLQkKLQlwdWJsaWMgaW50IGdldFkoKSB7Ci0JCXJldHVybiBmRGF0YVswXTsKLQl9Ci0KLQlwdWJsaWMgaW50IGdldFdpZHRoKCkgewotCQlyZXR1cm4gZkRhdGFbM10tZkRhdGFbMV07Ci0JfQotCQotCXB1YmxpYyBpbnQgZ2V0SGVpZ2h0KCkgewotCQlyZXR1cm4gZkRhdGFbMl0tZkRhdGFbMF07Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKLQkJcmV0dXJuIChmRGF0YVswXSA+PSBmRGF0YVsyXSkgfHwgKGZEYXRhWzFdID49IGZEYXRhWzNdKTsKLQl9Ci0JCi0JcHVibGljIGJvb2xlYW4gY29udGFpbnMoUG9pbnQgcCkgewotCQlyZXR1cm4gcC54ID49IGZEYXRhWzFdICYmIHAueCA8IGZEYXRhWzNdICYmIHAueSA+PSBmRGF0YVswXSAmJiBwLnkgPCBmRGF0YVsyXTsKLQl9Ci0JCi0JcHVibGljIHZvaWQgaW5zZXQoaW50IGxlZnQsIGludCB0b3AsIGludCByaWdodCwgaW50IGJvdHRvbSkgewotCQlmRGF0YVswXSs9IHRvcDsKLQkJZkRhdGFbMV0rPSBsZWZ0OwotCQlmRGF0YVsyXS09IGJvdHRvbTsKLQkJZkRhdGFbM10tPSByaWdodDsKLQl9Ci19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNVdGlsLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9NYWNVdGlsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGJhMzNiMDkuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vTWFjVXRpbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNTg1ICswLDAgQEAKLS8qCi0gKiBDb3B5cmlnaHQgKGMpIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgotICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAotICoKLSAqIEFuZHJlIFdlaW5hbmQsIE9USSAtIEluaXRpYWwgdmVyc2lvbgotICovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247Ci0KLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5DYWxsYmFjazsKLQotcHVibGljIGNsYXNzIE1hY1V0aWwgewotCi0JcHVibGljIGZpbmFsIHN0YXRpYyBib29sZWFuIERFQlVHOwotCQotCXB1YmxpYyBmaW5hbCBzdGF0aWMgYm9vbGVhbiBVU0VfTUVOVV9JQ09OUzsKLQkKLQkvKiogUHJldmVudCB1c2Ugb2Ygc3RhbmRhcmQgTWFjIHNob3J0Y3V0cyBDbWQtUSwgQ21kLUggKi8KLQlwdWJsaWMgZmluYWwgc3RhdGljIGJvb2xlYW4gS0VFUF9NQUNfU0hPUlRDVVRTOwotCXB1YmxpYyBmaW5hbCBzdGF0aWMgYm9vbGVhbiBGVUxMX0tCRF9OQVY7Ci0JCi0JLyoqIHVzZSBISVZpZXdzIGluc3RlYWQgb2YgQ29udHJvbE1hbmFnZXIgY29udHJvbHMgKi8KLQlwdWJsaWMgZmluYWwgc3RhdGljIGJvb2xlYW4gSElWSUVXOwotCS8qKiB1c2Ugc2V0RnJhbWUgY2FsbHMgaW5zdGVhZCBvZiBzZXRCb3VuZHMgKi8KLQlwdWJsaWMgZmluYWwgc3RhdGljIGJvb2xlYW4gVVNFX0ZSQU1FOwotCQotCXN0YXRpYyBmaW5hbCBjaGFyIE1ORU1PTklDID0gJyYnOwotCQkKLQlzdGF0aWMgewotCQlERUJVRz0gZmFsc2U7Ci0JCVVTRV9NRU5VX0lDT05TPSB0cnVlOwotCQlLRUVQX01BQ19TSE9SVENVVFM9IHRydWU7Ci0JCUZVTExfS0JEX05BVj0gdHJ1ZTsKLQkJSElWSUVXPSBmYWxzZTsKLQkJVVNFX0ZSQU1FPSBmYWxzZTsKLQl9Ci0JCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCQotCXByaXZhdGUgc3RhdGljIGludCBmVmlld0NsYXNzSUQ9IDA7Ci0JCi0Jc3RhdGljIGludCBjcmVhdGVDYWxsYmFjayhTdHJpbmcgbWV0aG9kLCBpbnQgYXJnQ291bnQpIHsKLQkJQ2FsbGJhY2sgY2I9IG5ldyBDYWxsYmFjayhNYWNVdGlsLmNsYXNzLCBtZXRob2QsIGFyZ0NvdW50KTsKLQkJaW50IHByb2M9IGNiLmdldEFkZHJlc3MoKTsKLQkJcmV0dXJuIHByb2M7Ci0JfQotCQotCXN0YXRpYyBpbnQgaGlvYlByb2MoaW50IGEsIGludCBiLCBpbnQgYykgewotCQlTeXN0ZW0ub3V0LnByaW50bG4oImhpb2JQcm9jIik7Ci0JCXJldHVybiBPUy5rTm9FcnI7Ci0JfQotCQotCXN0YXRpYyBpbnQgY3JlYXRlSElWaWV3KCkgewotCQlpbnQgcmM7Ci0JCQotCQlpZiAoZlZpZXdDbGFzc0lEID09IDApIHsKLQkJCQkKLQkJCWZWaWV3Q2xhc3NJRD0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycygib3JnLmVjbGlwc2Uuc3d0LmhpdmlldyIpOwotCQkJaW50IGJhc2VDbGFzc0lEPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzKCJjb20uYXBwbGUuaGl2aWV3Iik7Ci0JCQotCQkJaW50W10gZXZlbnRzPSBuZXcgaW50W10gewotCQkJCU9TLmtFdmVudENsYXNzSElPYmplY3QsIE9TLmtFdmVudEhJT2JqZWN0Q29uc3RydWN0LAotCQkJCS8vT1Mua0V2ZW50Q2xhc3NISU9iamVjdCwgT1Mua0V2ZW50SElPYmplY3RJbml0aWFsaXplLAotCQkJCU9TLmtFdmVudENsYXNzSElPYmplY3QsIE9TLmtFdmVudEhJT2JqZWN0RGVzdHJ1Y3QsCi0JCQkJCi0JCQkJT1Mua0V2ZW50Q2xhc3NDb250cm9sLAlPUy5rRXZlbnRDb250cm9sRHJhdywKLQkJCQlPUy5rRXZlbnRDbGFzc0NvbnRyb2wsCU9TLmtFdmVudENvbnRyb2xBZGRlZFN1YkNvbnRyb2wsCi0JCQkJT1Mua0V2ZW50Q2xhc3NDb250cm9sLAlPUy5rRXZlbnRDb250cm9sUmVtb3ZpbmdTdWJDb250cm9sLAotCQkJfTsKLQkJCi0JCQlpbnQgaGlvYlByb2M9IGNyZWF0ZUNhbGxiYWNrKCJoaW9iUHJvYyIsIDMpOwotCQkKLQkJCWludFtdIHRtcD0gbmV3IGludFsxXTsKLQkJCXJjPSBPUy5ISU9iamVjdFJlZ2lzdGVyU3ViY2xhc3MoZlZpZXdDbGFzc0lELCBiYXNlQ2xhc3NJRCwgMCwgaGlvYlByb2MsIGV2ZW50cywgMCwgdG1wKTsKLQkJCVN5c3RlbS5vdXQucHJpbnRsbigiSElPYmplY3RSZWdpc3RlclN1YmNsYXNzOiAiICsgcmMpOwotCQkKLQkJCU9TLkNGUmVsZWFzZShiYXNlQ2xhc3NJRCk7Ci0JCX0KLQkJCi0JCWludFtdIG9yZWY9IG5ldyBpbnRbMV07Ci0JCS8vcmM9IE9TLkhJT2JqZWN0Q3JlYXRlKGZWaWV3Q2xhc3NJRCwgMCwgb3JlZik7Ci0JCXJjPSBPUy5ISU9iamVjdENyZWF0ZShPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzKCJjb20uYXBwbGUuaGl2aWV3IiksIDAsIG9yZWYpOwotCQlTeXN0ZW0ub3V0LnByaW50bG4oIkhJT2JqZWN0Q3JlYXRlOiAiICsgcmMgKyAiICIgKyBvcmVmWzBdKTsKLQkJcmV0dXJuIG9yZWZbMF07Ci0JfQotCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCQkKLQlwdWJsaWMgc3RhdGljIGludCBnZXRDaGlsZChpbnQgaGFuZGxlLCBpbnRbXSB0LCBpbnQgbiwgaW50IGkpIHsKLQkJaW50IGluZGV4PSAobi0xIC0gaSk7Ci0JCWludCBzdGF0dXM9IE9TLkdldEluZGV4ZWRTdWJDb250cm9sKGhhbmRsZSwgKHNob3J0KShpbmRleCsxKSwgdCk7Ci0JCWlmIChzdGF0dXMgIT0gT1Mua05vRXJyKQotCQkJU3lzdGVtLm91dC5wcmludGxuKCJNYWNVdGlsLmdldENoaWxkOiBlcnJvciIpOwotCQlyZXR1cm4gc3RhdHVzOwotCX0KLQkJCi0JcHVibGljIHN0YXRpYyBpbnQgaW5kZXhPZihpbnQgcGFyZW50SGFuZGxlLCBpbnQgaGFuZGxlKSB7Ci0JCWludCBuPSBjb3VudFN1YkNvbnRyb2xzKHBhcmVudEhhbmRsZSk7Ci0JCWludFtdIG91dENvbnRyb2w9IG5ldyBpbnRbMV07Ci0JCWZvciAoaW50IGk9IDA7IGkgPCBuOyBpKyspIHsKLQkJCWlmIChnZXRDaGlsZChwYXJlbnRIYW5kbGUsIG91dENvbnRyb2wsIG4sIGkpID09IE9TLmtOb0VycikKLQkJCQlpZiAob3V0Q29udHJvbFswXSA9PSBoYW5kbGUpCi0JCQkJCXJldHVybiBpOwotCQl9Ci0JCXJldHVybiAtMTsKLQl9Ci0JCi0JLyoqCi0JICogSW5zZXJ0cyB0aGUgZ2l2ZW4gY2hpbGQgYXQgcG9zaXRpb24gaW4gdGhlIHBhcmVudC4KLQkgKiBJZiBwb3MgaXMgb3V0IG9mIHJhbmdlIHRoZSBjaGlsZCBpcyBhZGRlZCBhdCB0aGUgZW5kIChiZWxvdyBhbGwgb3RoZXIpLgotCSAqLwotCXByaXZhdGUgc3RhdGljIHZvaWQgaW5zZXJ0Q29udHJvbChpbnQgY29udHJvbEhhbmRsZSwgaW50IHBhcmVudENvbnRyb2xIYW5kbGUsIGludCBwb3MpIHsKLQkJCi0JCQotCQlpbnQgbj0gY291bnRTdWJDb250cm9scyhwYXJlbnRDb250cm9sSGFuZGxlKTsKLQkJCi0JCWludCBzaG91bGQ9IHBvczsKLQkJaWYgKHNob3VsZCA8IDAgfHwgc2hvdWxkID4gbikKLQkJCXNob3VsZD0gbjsKLQkJCi0JCWJvb2xlYW4gYWRkPSBmYWxzZTsKLQkJaWYgKGdldFN1cGVyQ29udHJvbChjb250cm9sSGFuZGxlKSAhPSBwYXJlbnRDb250cm9sSGFuZGxlKSB7Ci0JCQlhZGQ9IHRydWU7Ci0JCX0gZWxzZSB7Ci0JCQkvKgotCQkJU3RyaW5nIHcxPSBnZXRISU9iamVjdENsYXNzSUQocGFyZW50Q29udHJvbEhhbmRsZSk7Ci0JCQlTdHJpbmcgdzI9IGdldEhJT2JqZWN0Q2xhc3NJRChjb250cm9sSGFuZGxlKTsKLQkJCVN5c3RlbS5vdXQucHJpbnRsbigiTWFjVXRpbC5pbnNlcnRDb250cm9sOiBhbHJlYWR5IHRoZXJlOiAiICsgdzEgKyAiICIgKyB3Mik7Ci0JCQkqLwotCQkJaWYgKG4gPT0gMSkKLQkJCQlyZXR1cm47Ci0JCX0KLQkJCi0JCWlmIChuID09IDApIHsKLQkJCU9TLkhJVmlld0FkZFN1YnZpZXcocGFyZW50Q29udHJvbEhhbmRsZSwgY29udHJvbEhhbmRsZSk7Ci0JCQlwb3M9IDA7Ci0JCX0gZWxzZSB7Ci0JCQlpZiAocG9zID49IDAgJiYgcG9zIDwgbikgewotCQkJCWludFtdIHdoZXJlPSBuZXcgaW50WzFdOwotCQkJCWdldENoaWxkKHBhcmVudENvbnRyb2xIYW5kbGUsIHdoZXJlLCBuLCBwb3MpOwotCQkJCWlmIChhZGQpCi0JCQkJCU9TLkhJVmlld0FkZFN1YnZpZXcocGFyZW50Q29udHJvbEhhbmRsZSwgY29udHJvbEhhbmRsZSk7Ci0JCQkJT1MuSElWaWV3U2V0Wk9yZGVyKGNvbnRyb2xIYW5kbGUsIE9TLmtISVZpZXdaT3JkZXJBYm92ZSwgd2hlcmVbMF0pOwotCQkJfSBlbHNlIHsKLQkJCQlpZiAoYWRkKQotCQkJCQlPUy5ISVZpZXdBZGRTdWJ2aWV3KHBhcmVudENvbnRyb2xIYW5kbGUsIGNvbnRyb2xIYW5kbGUpOwotCQkJCWlmIChPUy5ISVZpZXdTZXRaT3JkZXIoY29udHJvbEhhbmRsZSwgT1Mua0hJVmlld1pPcmRlckJlbG93LCAwKSAhPSBPUy5rTm9FcnIpCi0JCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiZXJyb3IgMiIpOwotCQkJCXBvcz0gbjsKLQkJCX0KLQkJfQotCQotCQkvLyB2ZXJpZnkgY29ycmVjdCBwb3NpdGlvbgotCQlpbnQgaT0gaW5kZXhPZihwYXJlbnRDb250cm9sSGFuZGxlLCBjb250cm9sSGFuZGxlKTsKLQkJaWYgKGkgIT0gc2hvdWxkKQotCQkJU3lzdGVtLm91dC5wcmludGxuKCJNYWNVdGlsLmluc2VydENvbnRyb2w6IGlzOiAiK2krIiBzaG91bGQ6ICIrIHNob3VsZCAgKyAiIG46IiArIG4gKyAiIGFkZDogIiArIGFkZCk7Ci0JfQotCQotCS8qKgotCSAqIEFkZHMgdGhlIGdpdmVuIGNoaWxkIGF0IHRoZSBlbmQuCi0JICovCi0JcHVibGljIHN0YXRpYyB2b2lkIGFkZENvbnRyb2woaW50IGNvbnRyb2xIYW5kbGUsIGludCBwYXJlbnRDb250cm9sSGFuZGxlKSB7Ci0JCWluc2VydENvbnRyb2woY29udHJvbEhhbmRsZSwgcGFyZW50Q29udHJvbEhhbmRsZSwgLTEpOwotCX0KLQkJCi0JcHVibGljIHN0YXRpYyBpbnQgZ2V0VmlzaWJsZVJlZ2lvbihpbnQgY0hhbmRsZSwgaW50IHJlc3VsdCwgYm9vbGVhbiBpbmNsdWRpbmdUb3ApIHsKLQkJaW50IHRtcFJnbj0gT1MuTmV3UmduKCk7Ci0JCQotCQlnZXRDb250cm9sUmVnaW9uKGNIYW5kbGUsIE9TLmtDb250cm9sRW50aXJlQ29udHJvbCwgcmVzdWx0KTsKLQotCQlpbnQgcGFyZW50PSBjSGFuZGxlOwotCQl3aGlsZSAoKHBhcmVudD0gTWFjVXRpbC5nZXRTdXBlckNvbnRyb2wocGFyZW50KSkgIT0gMCkgewotCQkJZ2V0Q29udHJvbFJlZ2lvbihwYXJlbnQsIE9TLmtDb250cm9sQ29udGVudE1ldGFQYXJ0LCB0bXBSZ24pOwotCQkJT1MuU2VjdFJnbihyZXN1bHQsIHRtcFJnbiwgcmVzdWx0KTsKLQkJfQotCQkKLQkJaWYgKGluY2x1ZGluZ1RvcCkgewotCQkJaW50IG49IGNvdW50U3ViQ29udHJvbHMoY0hhbmRsZSk7Ci0JCQlpZiAobiA+IDApIHsKLQkJCQkvL1N5c3RlbS5vdXQucHJpbnRsbigiaGF2ZSBjaGlsZHJlbiBvbiB0b3AiKTsKLQkJCQlpbnRbXSBvdXRIYW5kbGU9IG5ldyBpbnRbMV07Ci0JCQkJZm9yIChpbnQgaT0gMDsgaSA8IG47IGkrKykgewotCQkJCQlpbnQgaW5kZXg9IGk7IC8vIHdhczogbi0xLWkKLQkJCQkJaWYgKE9TLkdldEluZGV4ZWRTdWJDb250cm9sKGNIYW5kbGUsIChzaG9ydCkoaW5kZXgrMSksIG91dEhhbmRsZSkgPT0gMCkgewkvLyBpbmRpY2VzIGFyZSAxIGJhc2VkCi0JCQkJCQlpZiAoT1MuSXNDb250cm9sVmlzaWJsZShvdXRIYW5kbGVbMF0pKSB7Ci0JCQkJCQkJZ2V0Q29udHJvbFJlZ2lvbihvdXRIYW5kbGVbMF0sIE9TLmtDb250cm9sU3RydWN0dXJlTWV0YVBhcnQsIHRtcFJnbik7Ci0JCQkJCQkJT1MuRGlmZlJnbihyZXN1bHQsIHRtcFJnbiwgcmVzdWx0KTsKLQkJCQkJCX0KLQkJCQkJfSBlbHNlCi0JCQkJCQl0aHJvdyBuZXcgU1dURXJyb3IoKTsKLQkJCQl9Ci0JCQl9Ci0JCX0KLQkJCi0JCU9TLkRpc3Bvc2VSZ24odG1wUmduKTsKLSAgICAgICAgICAgICAgICAKLQkJcmV0dXJuIE9TLmtOb0VycjsKLQl9Ci0JCi0JcHJpdmF0ZSBzdGF0aWMgaW50IGZpbmQoaW50IGNIYW5kbGUsIFJlY3RhbmdsZSBwYXJlbnRCb3VuZHMsIE1hY1JlY3QgdG1wLCBQb2ludCB3aGVyZSkgewotCQotCQlpZiAoISBPUy5Jc0NvbnRyb2xWaXNpYmxlKGNIYW5kbGUpKQotCQkJcmV0dXJuIDA7Ci0JCWlmICghIE9TLklzQ29udHJvbEFjdGl2ZShjSGFuZGxlKSkKLQkJCXJldHVybiAwOwotCi0JCU9TLkdldENvbnRyb2xCb3VuZHMoY0hhbmRsZSwgdG1wLmdldERhdGEoKSk7Ci0JCVJlY3RhbmdsZSBycj0gdG1wLnRvUmVjdGFuZ2xlKCk7Ci0JCWlmIChwYXJlbnRCb3VuZHMgIT0gbnVsbCkKLQkJCXJyPSBwYXJlbnRCb3VuZHMuaW50ZXJzZWN0aW9uKHJyKTsKLQotCQlpbnQgbj0gY291bnRTdWJDb250cm9scyhjSGFuZGxlKTsKLQkJaWYgKG4gPiAwKSB7Ci0JCQlpbnRbXSBvdXRIYW5kbGU9IG5ldyBpbnRbMV07Ci0JCQlmb3IgKGludCBpPSAwOyBpIDwgbjsgaSsrKSB7Ci0JCQkJaW50IGluZGV4PSAobi0xLWkpOwotCQkJCWlmIChPUy5HZXRJbmRleGVkU3ViQ29udHJvbChjSGFuZGxlLCAoc2hvcnQpKGluZGV4KzEpLCBvdXRIYW5kbGUpID09IDApIHsJLy8gaW5kaWNlcyBhcmUgMSBiYXNlZAotCQkJCQlpbnQgcmVzdWx0PSBmaW5kKG91dEhhbmRsZVswXSwgcnIsIHRtcCwgd2hlcmUpOwotCQkJCQlpZiAocmVzdWx0ICE9IDApCi0JCQkJCQlyZXR1cm4gcmVzdWx0OwotCQkJCX0KLQkJCX0KLQkJfQotCi0JCWlmIChyci5jb250YWlucyh3aGVyZSkpCi0JCQlyZXR1cm4gY0hhbmRsZTsKLQkJcmV0dXJuIDA7Ci0JfQotCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCQotCXB1YmxpYyBzdGF0aWMgUG9pbnQgdG9Db250cm9sKGludCBjSGFuZGxlLCBQb2ludCBwb2ludCkgewotCQlNYWNQb2ludCBtcD0gbmV3IE1hY1BvaW50KHBvaW50KTsKLQkJCi0JCWludCB3SGFuZGxlPSBPUy5HZXRDb250cm9sT3duZXIoY0hhbmRsZSk7Ci0JCWludCBwb3J0PSBPUy5HZXRXaW5kb3dQb3J0KHdIYW5kbGUpOwotCQlPUy5RREdsb2JhbFRvTG9jYWxQb2ludChwb3J0LCBtcC5nZXREYXRhKCkpOwotCQotCQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQkJT1MuR2V0Q29udHJvbEJvdW5kcyhjSGFuZGxlLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQkJCi0JCVBvaW50IHA9IG1wLnRvUG9pbnQoKTsKLQkJcC54LT0gYm91bmRzLmdldFgoKTsKLQkJcC55LT0gYm91bmRzLmdldFkoKTsKLQkJCi0JCS8qCi0JCWZsb2F0W10gcDI9IG5ldyBmbG9hdFsyXTsKLQkJcDJbMF09IG1wLmdldFgoKTsKLQkJcDJbMV09IG1wLmdldFkoKTsKLQkJT1MuSElWaWV3Q29udmVydFBvaW50KHAyLCAwLCBjSGFuZGxlKTsKLQkJU3lzdGVtLm91dC5wcmludGxuKCJNYWNVdGlsLnRvQ29udHJvbDogIiArIHAgKyAiICAiICsgcDJbMF0gKyAiICIgKyBwMlsxXSk7Ci0JCSovCi0JCQotCQlyZXR1cm4gcDsKLQl9Ci0JCi0JcHVibGljIHN0YXRpYyBQb2ludCB0b0Rpc3BsYXkoaW50IGNIYW5kbGUsIFBvaW50IHBvaW50KSB7Ci0JCU1hY1JlY3QgYm91bmRzPSBuZXcgTWFjUmVjdCgpOwotCQlPUy5HZXRDb250cm9sQm91bmRzKGNIYW5kbGUsIGJvdW5kcy5nZXREYXRhKCkpOwotCQlNYWNQb2ludCBtcD0gbmV3IE1hY1BvaW50KHBvaW50LngrYm91bmRzLmdldFgoKSwgcG9pbnQueStib3VuZHMuZ2V0WSgpKTsKLQkJCi0JCWludCB3SGFuZGxlPSBPUy5HZXRDb250cm9sT3duZXIoY0hhbmRsZSk7Ci0JCWludCBwb3J0PSBPUy5HZXRXaW5kb3dQb3J0KHdIYW5kbGUpOwotCQlPUy5RRExvY2FsVG9HbG9iYWxQb2ludChwb3J0LCBtcC5nZXREYXRhKCkpOwotCQkKLQkJcmV0dXJuIG1wLnRvUG9pbnQoKTsKLQl9Ci0JCQotCXByaXZhdGUgc3RhdGljIHZvaWQgZ2V0Q29udHJvbFJlZ2lvbihpbnQgY0hhbmRsZSwgc2hvcnQgcGFydCwgaW50IHJnbikgewotCQlpZiAodHJ1ZSkgewotCQkJc2hvcnRbXSBib3VuZHM9IG5ldyBzaG9ydFs0XTsKLQkJCU9TLkdldENvbnRyb2xCb3VuZHMoY0hhbmRsZSwgYm91bmRzKTsKLQkJCU9TLlJlY3RSZ24ocmduLCBib3VuZHMpOwotCQl9IGVsc2UgewotCQkJT1MuR2V0Q29udHJvbFJlZ2lvbihjSGFuZGxlLCBwYXJ0LCByZ24pOwotCQl9Ci0JfQotCi0JLy8gSGl0IGRldGVjdGlvbiBvbiB0aGUgTWFjIGlzIHJldmVyc2VkIGFuZCBkb2Vzbid0IGNvbnNpZGVyIGNsaXBwaW5nLAotCS8vIHNvIHdlIGhhdmUgdG8gZG8gaXQgb3Vyc2VsdmVzCi0KLQlwdWJsaWMgc3RhdGljIGludCBmaW5kQ29udHJvbFVuZGVyTW91c2UoTWFjUG9pbnQgd2hlcmUsIGludCB3SGFuZGxlLCBzaG9ydFtdIGNwYXJ0KSB7Ci0JCQotCQlpbnQgcm9vdDsKLQkJaWYgKHRydWUpIHsKLQkJCWludFtdIHJvb3RIYW5kbGU9IG5ldyBpbnRbMV07Ci0JCQlpbnQgcmM9IE9TLkdldFJvb3RDb250cm9sKHdIYW5kbGUsIHJvb3RIYW5kbGUpOwotCQkJaWYgKHJjICE9IE9TLmtOb0VycikgewotCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiTWFjVXRpbC5maW5kQ29udHJvbFVuZGVyTW91c2U6ICIgKyByYyk7Ci0JCQkJcmV0dXJuIDA7Ci0JCQl9Ci0JCQlyb290PSByb290SGFuZGxlWzBdOwotCQl9IGVsc2UgewotCQkJcm9vdD0gT1MuSElWaWV3R2V0Um9vdCh3SGFuZGxlKTsKLQkJfQotCQlQb2ludCB3PSB3aGVyZS50b1BvaW50KCk7Ci0JCWludCBjSGFuZGxlPSBmaW5kKHJvb3QsIG51bGwsIG5ldyBNYWNSZWN0KCksIHcpOwotCQlpZiAoY0hhbmRsZSAhPSAwICYmIGNwYXJ0ICE9IG51bGwgJiYgY3BhcnQubGVuZ3RoID4gMCkgewotCQkJY3BhcnRbMF09IE9TLlRlc3RDb250cm9sKGNIYW5kbGUsIHdoZXJlLmdldERhdGEoKSk7Ci0JCQkvL1N5c3RlbS5vdXQucHJpbnRsbigiZmluZENvbnRyb2xVbmRlck1vdXNlOiAiICsgY3BhcnRbMF0pOwotCQl9Ci0JCXJldHVybiBjSGFuZGxlOwotCX0KLQotCXByaXZhdGUgc3RhdGljIGludCBjb3VudFN1YkNvbnRyb2xzKGludCBjSGFuZGxlKSB7Ci0JCXNob3J0W10gY250PSBuZXcgc2hvcnRbMV07Ci0JCWludCBzdGF0dXM9IE9TLkNvdW50U3ViQ29udHJvbHMoY0hhbmRsZSwgY250KTsKLQkJc3dpdGNoIChzdGF0dXMpIHsKLQkJY2FzZSBPUy5rTm9FcnI6Ci0JCQlyZXR1cm4gY250WzBdOwkJCQotCQljYXNlIE9TLmVyckNvbnRyb2xJc05vdEVtYmVkZGVyOgotCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIk1hY1V0aWwuY291bnRTdWJDb250cm9sczogZXJyQ29udHJvbElzTm90RW1iZWRkZXIiKTsKLQkJCWJyZWFrOwotCQljYXNlIC0zMDU5OTogLy8gT1MuY29udHJvbEhhbmRsZUludmFsaWRFcnIKLQkJCVN5c3RlbS5vdXQucHJpbnRsbigiTWFjVXRpbC5jb3VudFN1YkNvbnRyb2xzOiBjb250cm9sSGFuZGxlSW52YWxpZEVyciIpOwotCQkJYnJlYWs7Ci0JCWRlZmF1bHQ6Ci0JCQlTeXN0ZW0ub3V0LnByaW50bG4oIk1hY1V0aWwuY291bnRTdWJDb250cm9sczogIiArIHN0YXR1cyk7Ci0JCQlicmVhazsKLQkJfQotCQlyZXR1cm4gMDsKLQl9Ci0JCi0JcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0U3RyaW5nQW5kUmVsZWFzZShpbnQgc0hhbmRsZSkgewotCQlpbnQgbGVuZ3RoPSBPUy5DRlN0cmluZ0dldExlbmd0aChzSGFuZGxlKTsKLQkJY2hhcltdIGJ1ZmZlcj0gbmV3IGNoYXJbbGVuZ3RoXTsKLQkJT1MuQ0ZTdHJpbmdHZXRDaGFyYWN0ZXJzKHNIYW5kbGUsIDAsIGxlbmd0aCwgYnVmZmVyKTsKLQkJT1MuQ0ZSZWxlYXNlKHNIYW5kbGUpOwotCQlyZXR1cm4gbmV3IFN0cmluZyhidWZmZXIpOwotCX0KLQkKLQlwdWJsaWMgc3RhdGljIGJ5dGVbXSBTdHIyNTUoU3RyaW5nIHMpIHsKLQkJaW50IGw9IDA7Ci0JCWlmIChzICE9IG51bGwpCi0JCQlsPSBzLmxlbmd0aCgpOwotCQlpZiAobCA+IDI1NSkgewotCQkJdGhyb3cgbmV3IFNXVEVycm9yKFNXVC5FUlJPUl9JTlZBTElEX1JBTkdFKTsKLQkJCS8vU3lzdGVtLm91dC5wcmludGxuKCJNYWNVdGlsLlN0cjI1NTogc3RyaW5nIGxlbmd0aCA+IDI1NSIpOwotCQl9Ci0JCWJ5dGVbXSBiPSBuZXcgYnl0ZVtsKzFdOwotCQliWzBdPSAoYnl0ZSkgbDsKLQkJZm9yIChpbnQgaT0gMDsgaSA8IGw7IGkrKykKLQkJCWJbaSsxXT0gKGJ5dGUpIHMuY2hhckF0KGkpOwotCQlyZXR1cm4gYjsKLQl9Ci0JCi0JcHVibGljIHN0YXRpYyBTdHJpbmcgdG9TdHJpbmcoYnl0ZVtdIHN0cjI1NSkgewotCQlpbnQgbj0gc3RyMjU1WzBdOwotCQljaGFyW10gYz0gbmV3IGNoYXJbbl07Ci0JCWZvciAoaW50IGk9IDA7IGkgPCBuOyBpKyspCi0JCQljW2ldPSAoY2hhcikgc3RyMjU1W2krMV07Ci0JCXJldHVybiBuZXcgU3RyaW5nKGMpOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgaW50IE9TVHlwZShTdHJpbmcgcykgewotCQlyZXR1cm4gKChzLmNoYXJBdCgwKSAmIDB4ZmYpIDw8IDI0KSB8ICgocy5jaGFyQXQoMSkgJiAweGZmKSA8PCAxNikgfCAoKHMuY2hhckF0KDIpICYgMHhmZikgPDwgOCkgfCAocy5jaGFyQXQoMykgJiAweGZmKTsKLQl9Ci0KLQlwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRISU9iamVjdENsYXNzSUQoaW50IGhhbmRsZSkgewotCQlpbnQgc2g9IE9TLkhJT2JqZWN0Q29weUNsYXNzSUQoaGFuZGxlKTsKLQkJcmV0dXJuIGdldFN0cmluZ0FuZFJlbGVhc2Uoc2gpOwotCX0KLQotCS8qKgotCSAqIENyZWF0ZSBhIG5ldyBjb250cm9sIGFuZCBlbWJlZCBpdCBpbiB0aGUgZ2l2ZW4gcGFyZW50IGNvbnRyb2wuCi0JICovCi0JcHVibGljIHN0YXRpYyBpbnQgbmV3Q29udHJvbChpbnQgcGFyZW50Q29udHJvbEhhbmRsZSwgc2hvcnQgcHJvY0lEKSB7Ci0JCXJldHVybiBuZXdDb250cm9sKHBhcmVudENvbnRyb2xIYW5kbGUsIC0xLCAoc2hvcnQpMCwgKHNob3J0KTAsIChzaG9ydCkwLCBwcm9jSUQpOwotCX0KLQkKLQkvKioKLQkgKiBDcmVhdGUgYSBuZXcgY29udHJvbCBhbmQgZW1iZWQgaXQgaW4gdGhlIGdpdmVuIHBhcmVudCBjb250cm9sLgotCSAqLwotCXB1YmxpYyBzdGF0aWMgaW50IG5ld0NvbnRyb2woaW50IHBhcmVudENvbnRyb2xIYW5kbGUsIHNob3J0IGluaXQsIHNob3J0IG1pbiwgc2hvcnQgbWF4LCBzaG9ydCBwcm9jSUQpIHsKLQkJcmV0dXJuIG5ld0NvbnRyb2wocGFyZW50Q29udHJvbEhhbmRsZSwgLTEsIGluaXQsIG1pbiwgbWF4LCBwcm9jSUQpOwotCX0KLQkKLQkvKioKLQkgKiBDcmVhdGUgYSBuZXcgY29udHJvbCBhbmQgZW1iZWQgaXQgaW4gdGhlIGdpdmVuIHBhcmVudCBjb250cm9sLgotCSAqLwotCXB1YmxpYyBzdGF0aWMgaW50IG5ld0NvbnRyb2woaW50IHBhcmVudENvbnRyb2xIYW5kbGUsIGludCBwb3MsIHNob3J0IGluaXQsIHNob3J0IG1pbiwgc2hvcnQgbWF4LCBzaG9ydCBwcm9jSUQpIHsKLQkJaW50IGNvbnRyb2xIYW5kbGU7Ci0JCWlmIChISVZJRVcpIHsKLQkJCWNvbnRyb2xIYW5kbGU9IE9TLk5ld0NvbnRyb2woMCwgZmFsc2UsIGluaXQsIG1pbiwgbWF4LCBwcm9jSUQpOwotCQkJaW5zZXJ0Q29udHJvbChjb250cm9sSGFuZGxlLCBwYXJlbnRDb250cm9sSGFuZGxlLCBwb3MpOwotCQkJT1MuSElWaWV3U2V0VmlzaWJsZShjb250cm9sSGFuZGxlLCB0cnVlKTsKLQkJCU9TLkhJVmlld1NldE5lZWRzRGlzcGxheShjb250cm9sSGFuZGxlLCB0cnVlKTsKLQkJfSBlbHNlIHsKLQkJCWludCB3aW5kb3dIYW5kbGU9IE9TLkdldENvbnRyb2xPd25lcihwYXJlbnRDb250cm9sSGFuZGxlKTsKLQkJCWNvbnRyb2xIYW5kbGU9IE9TLk5ld0NvbnRyb2wod2luZG93SGFuZGxlLCBmYWxzZSwgaW5pdCwgbWluLCBtYXgsIHByb2NJRCk7Ci0JCQlpbnNlcnRDb250cm9sKGNvbnRyb2xIYW5kbGUsIHBhcmVudENvbnRyb2xIYW5kbGUsIHBvcyk7Ci0JCQlpbml0TG9jYXRpb24oY29udHJvbEhhbmRsZSk7Ci0JCQlPUy5ISVZpZXdTZXRWaXNpYmxlKGNvbnRyb2xIYW5kbGUsIHRydWUpOwotCQl9Ci0KLQkJcmV0dXJuIGNvbnRyb2xIYW5kbGU7Ci0JfQotCQotCXB1YmxpYyBzdGF0aWMgaW50IGNyZWF0ZURyYXdpbmdBcmVhKGludCBwYXJlbnRDb250cm9sSGFuZGxlLCBpbnQgcG9zLCBib29sZWFuIHZpc2libGUsIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGJvcmRlcikgewotCQlpbnQgZmVhdHVyZXM9IE9TLmtDb250cm9sU3VwcG9ydHNFbWJlZGRpbmcgfCBPUy5rQ29udHJvbFN1cHBvcnRzRm9jdXMgfCBPUy5rQ29udHJvbEdldHNGb2N1c09uQ2xpY2s7Ci0JCWludCBjb250cm9sSGFuZGxlOwotCQlpZiAoSElWSUVXKSB7Ci0JCQlmZWF0dXJlcyB8PSBPUy5rQ29udHJvbEhhbmRsZXNUcmFja2luZzsKLQkJCWNvbnRyb2xIYW5kbGU9IE9TLk5ld0NvbnRyb2woMCwgZmFsc2UsIChzaG9ydClmZWF0dXJlcywgKHNob3J0KTAsIChzaG9ydCkwLCBPUy5rQ29udHJvbFVzZXJQYW5lUHJvYyk7Ci0JCQlPUy5TaXplQ29udHJvbChjb250cm9sSGFuZGxlLCAoc2hvcnQpd2lkdGgsIChzaG9ydCloZWlnaHQpOwotCQkJaW5zZXJ0Q29udHJvbChjb250cm9sSGFuZGxlLCBwYXJlbnRDb250cm9sSGFuZGxlLCBwb3MpOwotCQkJT1MuSElWaWV3U2V0VmlzaWJsZShjb250cm9sSGFuZGxlLCB2aXNpYmxlKTsKLQkJCU9TLkhJVmlld1NldE5lZWRzRGlzcGxheShjb250cm9sSGFuZGxlLCB0cnVlKTsKLQkJfSBlbHNlIHsKLQkJCWludCB3aW5kb3dIYW5kbGU9IE9TLkdldENvbnRyb2xPd25lcihwYXJlbnRDb250cm9sSGFuZGxlKTsKLQkJCWNvbnRyb2xIYW5kbGU9IE9TLk5ld0NvbnRyb2wod2luZG93SGFuZGxlLCBmYWxzZSwgKHNob3J0KWZlYXR1cmVzLCAoc2hvcnQpMCwgKHNob3J0KTAsIE9TLmtDb250cm9sVXNlclBhbmVQcm9jKTsKLQkJCU9TLlNpemVDb250cm9sKGNvbnRyb2xIYW5kbGUsIChzaG9ydCl3aWR0aCwgKHNob3J0KWhlaWdodCk7Ci0JCQlpbnNlcnRDb250cm9sKGNvbnRyb2xIYW5kbGUsIHBhcmVudENvbnRyb2xIYW5kbGUsIHBvcyk7Ci0JCQlpbml0TG9jYXRpb24oY29udHJvbEhhbmRsZSk7Ci0JCQlPUy5ISVZpZXdTZXRWaXNpYmxlKGNvbnRyb2xIYW5kbGUsIHZpc2libGUpOwotCQl9Ci0JCXJldHVybiBjb250cm9sSGFuZGxlOwotCX0JCi0JCi0JcHVibGljIHN0YXRpYyB2b2lkIGluaXRMb2NhdGlvbihpbnQgY0hhbmRsZSkgewotCQlpbnQgcGFyZW50PSBnZXRTdXBlckNvbnRyb2woY0hhbmRsZSk7Ci0JCXNob3J0W10gYm91bmRzPSBuZXcgc2hvcnRbNF07Ci0JCU9TLkdldENvbnRyb2xCb3VuZHMocGFyZW50LCBib3VuZHMpOwotCQlzaG9ydCB4PSBib3VuZHNbMV07Ci0JCXNob3J0IHk9IGJvdW5kc1swXTsKLQkJaWYgKHggPiAwIHx8IHkgPiAwKQotCQkJT1MuTW92ZUNvbnRyb2woY0hhbmRsZSwgeCwgeSk7Ci0JfQotCQotCS8qKgotCSAqIFJldHVybnMgdGhlIHBhcmVudCBvZiB0aGUgZ2l2ZW4gY29udHJvbCBvciBudWxsIGlmIHRoZSBjb250cm9sIGlzIGEgcm9vdCBjb250cm9sLgotCSAqLwotCXB1YmxpYyBzdGF0aWMgaW50IGdldFN1cGVyQ29udHJvbChpbnQgY0hhbmRsZSkgewotICAgICAgICAKLQkJaW50IHdIYW5kbGU9IE9TLkdldENvbnRyb2xPd25lcihjSGFuZGxlKTsKLQkJaWYgKHdIYW5kbGUgPT0gMCkgewotCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIk1hY1V0aWwuZ2V0U3VwZXJDb250cm9sOiBHZXRDb250cm9sT3duZXIgZXJyb3IiKTsKLQkJCXJldHVybiAwOwotCQl9Ci0JCWludFtdIHJvb3RIYW5kbGU9IG5ldyBpbnRbMV07Ci0JCU9TLkdldFJvb3RDb250cm9sKHdIYW5kbGUsIHJvb3RIYW5kbGUpOwotCQlpZiAoY0hhbmRsZSA9PSByb290SGFuZGxlWzBdKQotCQkJcmV0dXJuIDA7Ci0gICAgICAgICAgICAgICAgCi0JCWludFtdIHBhcmVudEhhbmRsZT0gbmV3IGludFsxXTsKLQkJaW50IHJjPSBPUy5HZXRTdXBlckNvbnRyb2woY0hhbmRsZSwgcGFyZW50SGFuZGxlKTsKLQkJaWYgKHJjICE9IE9TLmtOb0VycikKLQkJCVN5c3RlbS5vdXQucHJpbnRsbigiTWFjVXRpbC5nZXRTdXBlckNvbnRyb2w6ICIgKyByYyk7Ci0JCXJldHVybiBwYXJlbnRIYW5kbGVbMF07Ci0JfQotCi0JcHVibGljIHN0YXRpYyB2b2lkIGR1bXAoaW50IG1hdGNoSGFuZGxlKSB7Ci0JCWludCB3SGFuZGxlPSBPUy5HZXRDb250cm9sT3duZXIobWF0Y2hIYW5kbGUpOwotCQlpbnRbXSByb290SGFuZGxlPSBuZXcgaW50WzFdOwotCQlPUy5HZXRSb290Q29udHJvbCh3SGFuZGxlLCByb290SGFuZGxlKTsKLQkJZHVtcChyb290SGFuZGxlWzBdLCAwLCBtYXRjaEhhbmRsZSk7Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigpOwotCX0KLQkKLQlwdWJsaWMgc3RhdGljIHZvaWQgZHVtcChpbnQgY0hhbmRsZSwgaW50IGxldmVsLCBpbnQgbWF0Y2hIYW5kbGUpIHsKLQkJZm9yIChpbnQgeD0gMDsgeCA8IGxldmVsOyB4KyspCi0JCQlTeXN0ZW0ub3V0LnByaW50KCIgICIpOwotCQlXaWRnZXQgdz0gV2lkZ2V0VGFibGUuZ2V0KGNIYW5kbGUpOwotCQlpZiAodyAhPSBudWxsKQotCQkJU3lzdGVtLm91dC5wcmludCh3KTsKLQkJZWxzZQotCQkJU3lzdGVtLm91dC5wcmludChjSGFuZGxlKTsKLQkJCQotCQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQkJT1MuR2V0Q29udHJvbEJvdW5kcyhjSGFuZGxlLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQkJU3lzdGVtLm91dC5wcmludCgiICIgKyBib3VuZHMudG9SZWN0YW5nbGUoKSk7Ci0JCQotCQlpZiAoY0hhbmRsZSA9PSBtYXRjaEhhbmRsZSkKLQkJCVN5c3RlbS5vdXQucHJpbnRsbigiICoqKioqKioqKioqKioqKioqKiIpOwotCQllbHNlCi0JCQlTeXN0ZW0ub3V0LnByaW50bG4oKTsKLSAgICAgICAgICAgICAgICAgICAgCi0JCWludCBuPSBjb3VudFN1YkNvbnRyb2xzKGNIYW5kbGUpOwotCQlpZiAobiA+IDApIHsKLQkJCWludFtdIG91dEhhbmRsZT0gbmV3IGludFsxXTsKLQkJCWZvciAoaW50IGk9IDA7IGkgPCBuOyBpKyspIHsKLQkJCQlpZiAoT1MuR2V0SW5kZXhlZFN1YkNvbnRyb2woY0hhbmRsZSwgKHNob3J0KShpKzEpLCBvdXRIYW5kbGUpID09IDApCi0JCQkJCWR1bXAob3V0SGFuZGxlWzBdLCBsZXZlbCsxLCBtYXRjaEhhbmRsZSk7Ci0JCQl9Ci0JCX0KLQl9Ci0JCi0JcHVibGljIHN0YXRpYyBQb2ludCBjb21wdXRlU2l6ZShpbnQgaGFuZGxlKSB7Ci0JCWlmIChPUy5Jc1ZhbGlkQ29udHJvbEhhbmRsZShoYW5kbGUpKSB7Ci0JCQlNYWNSZWN0IHJlY3Q9IG5ldyBNYWNSZWN0KCk7Ci0JCQlzaG9ydFtdIGJhc2U9IG5ldyBzaG9ydFsxXTsKLQkJCU9TLkdldEJlc3RDb250cm9sUmVjdChoYW5kbGUsIHJlY3QuZ2V0RGF0YSgpLCBiYXNlKTsKLQkJCWlmIChyZWN0LmlzRW1wdHkoKSkKLQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIk1hY1V0aWwuY29tcHV0ZVNpemU6IDAgc2l6ZSIpOwotCQkJcmV0dXJuIHJlY3QuZ2V0U2l6ZSgpOwotCQl9Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigiTWFjVXRpbC5jb21wdXRlU2l6ZTogdW5rbm93biBoYW5kbGUgdHlwZSIpOwotCQlyZXR1cm4gbmV3IFBvaW50KDUwLCA1MCk7Ci0JfQotCQotCXB1YmxpYyBzdGF0aWMgaW50IGdldERpc3BsYXlXaWR0aCgpIHsKLQkJTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JCU9TLkdldEF2YWlsYWJsZVdpbmRvd1Bvc2l0aW9uaW5nQm91bmRzKE9TLkdldE1haW5EZXZpY2UoKSwgYm91bmRzLmdldERhdGEoKSk7Ci0JCXJldHVybiBib3VuZHMuZ2V0V2lkdGgoKTsKLQl9Ci0JCi0JcHVibGljIHN0YXRpYyBpbnQgZ2V0RGlzcGxheUhlaWdodCgpIHsKLQkJTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JCU9TLkdldEF2YWlsYWJsZVdpbmRvd1Bvc2l0aW9uaW5nQm91bmRzKE9TLkdldE1haW5EZXZpY2UoKSwgYm91bmRzLmdldERhdGEoKSk7Ci0JCXJldHVybiBib3VuZHMuZ2V0SGVpZ2h0KCk7Ci0JfQotCQotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKGludCBpKSB7Ci0JCVN0cmluZ0J1ZmZlciBzYj0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCQlzYi5hcHBlbmQoKGNoYXIpKChpICYgMHhmZjAwMDAwMCkgPj4gMjQpKTsKLQkJc2IuYXBwZW5kKChjaGFyKSgoaSAmIDB4MDBmZjAwMDApID4+IDE2KSk7Ci0JCXNiLmFwcGVuZCgoY2hhcikoKGkgJiAweDAwMDBmZjAwKSA+PiA4KSk7Ci0JCXNiLmFwcGVuZCgoY2hhcikoKGkgJiAweDAwMDAwMGZmKSA+PiAwKSk7Ci0JCXJldHVybiBzYi50b1N0cmluZygpOwotCX0KLQkKLQlwdWJsaWMgc3RhdGljIFN0cmluZyByZW1vdmVNbmVtb25pY3MoU3RyaW5nIHMpIHsKLQkJaWYgKHMgIT0gbnVsbCkgewotCQkJaW50IGw9IHMubGVuZ3RoKCk7Ci0JCQlpZiAobCA+IDApIHsKLQkJCQljaGFyW10gYnVmPSBuZXcgY2hhcltsXTsKLQkJCQlpbnQgaj0gMDsKLQkJCQlmb3IgKGludCBpPSAwOyBpIDwgbDsgaSsrKSB7Ci0JCQkJCWNoYXIgYz0gcy5jaGFyQXQoaSk7Ci0JCQkJCWlmIChjICE9IE1ORU1PTklDKQotCQkJCQkJYnVmW2orK109IGM7Ci0JCQkJfQotCQkJCXJldHVybiBuZXcgU3RyaW5nKGJ1ZiwgMCwgaik7Ci0JCQl9Ci0JCX0KLQkJcmV0dXJuIHM7Ci0JfQotCQotCXB1YmxpYyBzdGF0aWMgdm9pZCBSR0JCYWNrQ29sb3IoaW50IHBhY2tlZCkgewotCQlpZiAoKHBhY2tlZCAmIDB4ZmYwMDAwMDApID09IDApIHsKLQkJCU9TLlJHQkJhY2tDb2xvcigoc2hvcnQpKCgocGFja2VkID4+IDE2KSAmIDB4RkYpICogMjU3KSwKLQkJCQkJCQkoc2hvcnQpKCgocGFja2VkID4+IDgpICYgMHhGRikgKiAyNTcpLAotCQkJCQkJCShzaG9ydCkoKChwYWNrZWQpICYgMHhGRikgKiAyNTcpKTsKLQkJfSBlbHNlIHsKLQkJCU9TLlJHQkJhY2tDb2xvcigoc2hvcnQpMHhGRkZGLCAoc2hvcnQpMHhGRkZGLCAoc2hvcnQpMHhGRkZGKTsKLQkJfQotCX0KLQkKLQlwdWJsaWMgc3RhdGljIHZvaWQgUkdCRm9yZUNvbG9yKGludCBwYWNrZWQpIHsKLQkJaWYgKChwYWNrZWQgJiAweGZmMDAwMDAwKSA9PSAwKSB7Ci0JCQlPUy5SR0JGb3JlQ29sb3IoKHNob3J0KSgoKHBhY2tlZCA+PiAxNikgJiAweEZGKSAqIDI1NyksCi0JCQkJCQkJKHNob3J0KSgoKHBhY2tlZCA+PiA4KSAmIDB4RkYpICogMjU3KSwKLQkJCQkJCQkoc2hvcnQpKCgocGFja2VkKSAmIDB4RkYpICogMjU3KSk7Ci0JCX0gZWxzZSB7Ci0JCQlPUy5SR0JGb3JlQ29sb3IoKHNob3J0KTB4RkZGRiwgKHNob3J0KTB4RkZGRiwgKHNob3J0KTB4RkZGRik7Ci0JCX0KLQl9Ci0JCi0JcHVibGljIHN0YXRpYyBpbnRbXSBnZXREYXRhQnJvd3Nlckl0ZW1zKGludCBkYXRhQnJvd3NlckhhbmRsZSwgaW50IGNvbnRhaW5lcklELCBpbnQgc3RhdGUsIGJvb2xlYW4gcmVjdXJzZSkgewotCQlpbnQgcmVzdWx0SGFuZGxlPSAwOwotCQl0cnkgewotCQkJcmVzdWx0SGFuZGxlPSBPUy5OZXdIYW5kbGUoMCk7Ci0JCQlpZiAoT1MuR2V0RGF0YUJyb3dzZXJJdGVtcyhkYXRhQnJvd3NlckhhbmRsZSwgY29udGFpbmVySUQsIHJlY3Vyc2UsIHN0YXRlLCByZXN1bHRIYW5kbGUpID09IE9TLmtOb0VycikgewotCQkJCWludCBpdGVtQ291bnQ9IE9TLkdldEhhbmRsZVNpemUocmVzdWx0SGFuZGxlKSAvIDQ7CS8vIHNpemVvZihpbnQpCi0JCQkJaWYgKGl0ZW1Db3VudCA+IDApIHsJCi0JCQkJCWludCByZXN1bHRJRHNbXT0gbmV3IGludFtpdGVtQ291bnRdOwotCQkJCQlPUy5nZXRIYW5kbGVEYXRhKHJlc3VsdEhhbmRsZSwgcmVzdWx0SURzKTsKLQkJCQkJcmV0dXJuIHJlc3VsdElEczsKLQkJCQl9Ci0JCQl9Ci0JCX0gZmluYWxseSB7Ci0JCQlPUy5EaXNwb3NlSGFuZGxlKHJlc3VsdEhhbmRsZSk7Ci0JCX0KLQkJcmV0dXJuIG5ldyBpbnRbMF07Ci0JfQotCi0JcHVibGljIHN0YXRpYyBpbnRbXSBnZXRTZWxlY3Rpb25JRHMoaW50IGRhdGFCcm93c2VySGFuZGxlLCBpbnQgY29udGFpbmVySUQsIGJvb2xlYW4gcmVjdXJzZSkgewotCQlyZXR1cm4gZ2V0RGF0YUJyb3dzZXJJdGVtcyhkYXRhQnJvd3NlckhhbmRsZSwgY29udGFpbmVySUQsIE9TLmtEYXRhQnJvd3Nlckl0ZW1Jc1NlbGVjdGVkLCByZWN1cnNlKTsKLQl9Ci0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL01lbnVUcmFja2luZ0RhdGEuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL01lbnVUcmFja2luZ0RhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42YzE2Y2Y2Ci0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vTWVudVRyYWNraW5nRGF0YS5qYXZhCkBAIC0wLDAgKzEsMjIgQEAKK3BhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKyAKK3B1YmxpYyBjbGFzcyBNZW51VHJhY2tpbmdEYXRhIHsKKwlwdWJsaWMgaW50IG1lbnU7IAorCXB1YmxpYyBzaG9ydCBpdGVtU2VsZWN0ZWQ7IAorCXB1YmxpYyBzaG9ydCBpdGVtVW5kZXJNb3VzZTsgCisvLwkgIFJlY3QgaXRlbVJlY3Q7IAorCXB1YmxpYyBzaG9ydCB0b3A7CisJcHVibGljIHNob3J0IGxlZnQ7CisJcHVibGljIHNob3J0IGJvdHRvbTsKKwlwdWJsaWMgc2hvcnQgcmlnaHQ7CisJcHVibGljIGludCB2aXJ0dWFsTWVudVRvcDsgCisJcHVibGljIGludCB2aXJ0dWFsTWVudUJvdHRvbTsKKwlwdWJsaWMgc3RhdGljIGludCBzaXplb2YgPSAyNDsKK30KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL05hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucy5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWIxMTA0NAotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL05hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucy5qYXZhCkBAIC0wLDAgKzEsMjggQEAKK3BhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKworcHVibGljIGNsYXNzIE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucyB7CisJcHVibGljIHNob3J0IHZlcnNpb247CisJcHVibGljIGludCBvcHRpb25GbGFnczsKKy8vCVBvaW50IGxvY2F0aW9uOworCXB1YmxpYyBzaG9ydCBsb2NhdGlvbl9oOworCXB1YmxpYyBzaG9ydCBsb2NhdGlvbl92OworCXB1YmxpYyBpbnQgY2xpZW50TmFtZTsKKwlwdWJsaWMgaW50IHdpbmRvd1RpdGxlOworCXB1YmxpYyBpbnQgYWN0aW9uQnV0dG9uTGFiZWw7CisJcHVibGljIGludCBjYW5jZWxCdXR0b25MYWJlbDsKKwlwdWJsaWMgaW50IHNhdmVGaWxlTmFtZTsKKwlwdWJsaWMgaW50IG1lc3NhZ2U7CisJcHVibGljIGludCBwcmVmZXJlbmNlS2V5OworCXB1YmxpYyBpbnQgcG9wdXBFeHRlbnNpb247CisJcHVibGljIGludCBtb2RhbGl0eTsKKwlwdWJsaWMgaW50IHBhcmVudFdpbmRvdzsKKy8vCWNoYXIgcmVzZXJ2ZWRbMTZdOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNpemVvZiA9IDY2OworfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vTmF2UmVwbHlSZWNvcmQuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL05hdlJlcGx5UmVjb3JkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDBhYjA2OQotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL05hdlJlcGx5UmVjb3JkLmphdmEKQEAgLTAsMCArMSwyNyBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworIAorcHVibGljIGNsYXNzIE5hdlJlcGx5UmVjb3JkIHsKKwlwdWJsaWMgc2hvcnQgdmVyc2lvbjsKKwlwdWJsaWMgYm9vbGVhbiB2YWxpZFJlY29yZDsKKwlwdWJsaWMgYm9vbGVhbiByZXBsYWNpbmc7CisJcHVibGljIGJvb2xlYW4gaXNTdGF0aW9uZXJ5OworCXB1YmxpYyBib29sZWFuIHRyYW5zbGF0aW9uTmVlZGVkOworCS8vQUVEZXNjTGlzdCBzZWxlY3Rpb247CisJcHVibGljIGludCBzZWxlY3Rpb25fZGVzY3JpcHRvclR5cGU7CisJcHVibGljIGludCBzZWxlY3Rpb25fZGF0YUhhbmRsZTsKKwlwdWJsaWMgc2hvcnQga2V5U2NyaXB0OworCXB1YmxpYyBpbnQgZmlsZVRyYW5zbGF0aW9uOworCXB1YmxpYyBpbnQgcmVzZXJ2ZWQxOworCXB1YmxpYyBpbnQgc2F2ZUZpbGVOYW1lOworCXB1YmxpYyBib29sZWFuIHNhdmVGaWxlRXh0ZW5zaW9uSGlkZGVuOworCXB1YmxpYyBieXRlIHJlc2VydmVkMjsKKwlwdWJsaWMgYnl0ZVtdIHJlc2VydmVkID0gbmV3IGJ5dGVbMjI1XTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzaXplb2YgPSAyNTY7CQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL09TLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9PUy5qYXZhCmluZGV4IDA1NTliZTMuLjY0M2JjM2UgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL09TLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vT1MuamF2YQpAQCAtMSwxMiArMSwxMSBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCiAvKgotICogQ29weXJpZ2h0IChjKSAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAogICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCi0gKgotICogQW5kcmUgV2VpbmFuZCwgT1RJIC0gSW5pdGlhbCB2ZXJzaW9uCiAgKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKIAogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5MaWJyYXJ5OwogCkBAIC0xNywxNDE0ICsxNiwxMDYxIEBACiAJCUxpYnJhcnkubG9hZExpYnJhcnkgKCJzd3QiKTsKIAl9CiAJCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQkvLyBDYXJib24gVG9vbGJveCBuYXRpdmUgQVBJCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCS8vIHN0YXR1cwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtOb0VyciA9IDA7Ci0JCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JLy8gQXBwZWFyYW5jZSBNYW5hZ2VyCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JCi0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVCcnVzaERpYWxvZ0JhY2tncm91bmRBY3RpdmUgPSAxOyAvKiBEaWFsb2dzICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVCcnVzaERpYWxvZ0JhY2tncm91bmRJbmFjdGl2ZSA9IDI7IC8qIERpYWxvZ3MgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZUJydXNoQWxlcnRCYWNrZ3JvdW5kQWN0aXZlID0gMzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZUJydXNoQWxlcnRCYWNrZ3JvdW5kSW5hY3RpdmUgPSA0OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lQnJ1c2hNb2RlbGVzc0RpYWxvZ0JhY2tncm91bmRBY3RpdmUgPSA1OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lQnJ1c2hNb2RlbGVzc0RpYWxvZ0JhY2tncm91bmRJbmFjdGl2ZSA9IDY7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVCcnVzaFV0aWxpdHlXaW5kb3dCYWNrZ3JvdW5kQWN0aXZlID0gNzsgLyogTWlzY2VsbGFuZW91cyAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lQnJ1c2hVdGlsaXR5V2luZG93QmFja2dyb3VuZEluYWN0aXZlID0gODsgLyogTWlzY2VsbGFuZW91cyAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lQnJ1c2hMaXN0Vmlld1NvcnRDb2x1bW5CYWNrZ3JvdW5kID0gOTsgLyogRmluZGVyICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVCcnVzaExpc3RWaWV3QmFja2dyb3VuZCA9IDEwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lQnJ1c2hJY29uTGFiZWxCYWNrZ3JvdW5kID0gMTE7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVCcnVzaExpc3RWaWV3U2VwYXJhdG9yICA9IDEyOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lQnJ1c2hDaGFzaW5nQXJyb3dzICAgICAgPSAxMzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZUJydXNoRHJhZ0hpbGl0ZSAgICAgICAgID0gMTQ7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVCcnVzaERvY3VtZW50V2luZG93QmFja2dyb3VuZCA9IDE1OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lQnJ1c2hGaW5kZXJXaW5kb3dCYWNrZ3JvdW5kID0gMTY7Ci0KLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZVN5c3RlbUZvbnQgICAgICAgICAgICAgID0gMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZVNtYWxsU3lzdGVtRm9udCAgICAgICAgID0gMTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZVNtYWxsRW1waGFzaXplZFN5c3RlbUZvbnQgPSAyOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lVmlld3NGb250ICAgICAgICAgICAgICAgPSAzOyAgICAvKiBUaGUgZm9sbG93aW5nIElEJ3MgYXJlIG9ubHkgYXZhaWxhYmxlIHdpdGggTWFjT1MgWCBvciBDYXJib25MaWIgMS4zIGFuZCBsYXRlciovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVFbXBoYXNpemVkU3lzdGVtRm9udCAgICA9IDQ7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVBcHBsaWNhdGlvbkZvbnQgICAgICAgICA9IDU7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVMYWJlbEZvbnQgICAgICAgICAgICAgICA9IDY7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVNZW51VGl0bGVGb250ICAgICAgICAgICA9IDEwMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZU1lbnVJdGVtRm9udCAgICAgICAgICAgID0gMTAxOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lTWVudUl0ZW1NYXJrRm9udCAgICAgICAgPSAxMDI7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVNZW51SXRlbUNtZEtleUZvbnQgICAgICA9IDEwMzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZVdpbmRvd1RpdGxlRm9udCAgICAgICAgID0gMTA0OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lUHVzaEJ1dHRvbkZvbnQgICAgICAgICAgPSAxMDU7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVVdGlsaXR5V2luZG93VGl0bGVGb250ICA9IDEwNjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZUFsZXJ0SGVhZGVyRm9udCAgICAgICAgID0gMTA3OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lQ3VycmVudFBvcnRGb250ICAgICAgICAgPSAyMDA7Ci0JCi0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVTdGF0ZUluYWN0aXZlID0gMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZVN0YXRlQWN0aXZlID0gMTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZVN0YXRlUHJlc3NlZCA9IDI7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVTdGF0ZVJvbGxvdmVyID0gNjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZVN0YXRlVW5hdmFpbGFibGUgPSA3OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1RoZW1lU3RhdGVVbmF2YWlsYWJsZUluYWN0aXZlID0gODsKLQkKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZVNtYWxsQmV2ZWxCdXR0b24JPSA4OyAgICAvKiBzbWFsbC1zaGFkb3cgYmV2ZWwgYnV0dG9uICovCi0KLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtUaGVtZUJ1dHRvbk9mZgk9IDA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVCdXR0b25Pbgk9IDE7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrVGhlbWVCdXR0b25NaXhlZAk9IDI7Ci0KLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IHNtU3lzdGVtU2NyaXB0ID0gLTE7IAkvKiBkZXNpZ25hdGVzIHN5c3RlbSBzY3JpcHQuKi8KLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBSZWdpc3RlckFwcGVhcmFuY2VDbGllbnQoKTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRUaGVtZVdpbmRvd0JhY2tncm91bmQoaW50IHdIYW5kbGUsIHNob3J0IGJydXNoLCBib29sZWFuIHVwZGF0ZSk7Ci0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IERyYXdUaGVtZVRleHRCb3goaW50IHNIYW5kbGUsIHNob3J0IGZvbnRJRCwgaW50IHN0YXRlLCBib29sZWFuIHdyYXBUb1dpZHRoLAotCQkJc2hvcnRbXSBib3VuZHMsIHNob3J0IGp1c3QsIGludCBjb250ZXh0KTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRUaGVtZVRleHREaW1lbnNpb25zKGludCBzSGFuZGxlLCBzaG9ydCBmb250SUQsIGludCBzdGF0ZSwgYm9vbGVhbiB3cmFwVG9XaWR0aCwKLQkJCXNob3J0W10gaW9Cb3VuZHMsIHNob3J0W10gYmFzZUxpbmUpOwotCQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRHJhd1RoZW1lRWRpdFRleHRGcmFtZShzaG9ydFtdIGJvdW5kcywgaW50IHN0YXRlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRHJhd1RoZW1lRm9jdXNSZWN0KHNob3J0W10gYm91bmRzLCBib29sZWFuIGhhc0ZvY3VzKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRHJhd1RoZW1lR2VuZXJpY1dlbGwoc2hvcnRbXSBib3VuZHMsIGludCBzdGF0ZSwgYm9vbGVhbiBmaWxsQ2VudGVyKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRHJhd1RoZW1lU2VwYXJhdG9yKHNob3J0W10gYm91bmRzLCBpbnQgc3RhdGUpOwotCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRUaGVtZUZvbnQoc2hvcnQgdGhlbWVGb250SWQsIHNob3J0IHNjcmlwdENvZGUsCi0JCQkJYnl0ZVtdIGZvbnROYW1lLCBzaG9ydFtdIGZvbnRTaXplLCBieXRlW10gc3R5bGUpOwotCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBEcmF3VGhlbWVCdXR0b24oc2hvcnRbXSBib3VuZHMsIHNob3J0IGtpbmQsIHNob3J0W10gbmV3SW5mbywgc2hvcnRbXSBwcmV2SW5mbywKLQkJCQlpbnQgZXJhc2VQcm9jLCBpbnQgbGFiZWxQcm9jLCBpbnQgdXNlckRhdGEpOwotCQkJCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRUaGVtZUJhY2tncm91bmQoc2hvcnQgaW5CcnVzaCwgc2hvcnQgZGVwdGgsIGJvb2xlYW4gaXNDb2xvckRldmljZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldFRoZW1lRHJhd2luZ1N0YXRlKGludFtdIHN0YXRlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0VGhlbWVEcmF3aW5nU3RhdGUoaW50IHN0YXRlLCBib29sZWFuIGRpc3Bvc2VOb3cpOwotCQkJCQotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCS8vIEV2ZW50IE1hbmFnZXIKLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQkKLQkvLyBldmVudCB3aGF0Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBudWxsRXZlbnQJPSAwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgbW91c2VEb3duCT0gMTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IG1vdXNlVXAJPSAyOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga2V5RG93bgk9IDM7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrZXlVcAkJPSA0OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgYXV0b0tleQk9IDU7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCB1cGRhdGVFdnQJPSA2OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgZGlza0V2dAk9IDc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBhY3RpdmF0ZUV2dAk9IDg7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBvc0V2dAkJPSAxNTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtIaWdoTGV2ZWxFdmVudAk9IDIzOwotCi0JLy8gbWFza3MKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IHVwZGF0ZU1hc2sJPSAxIDw8IHVwZGF0ZUV2dDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGV2ZXJ5RXZlbnQJPSAoc2hvcnQpIDB4RkZGRjsKLQkKLQkvLyBtYXNrcwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGNoYXJDb2RlTWFzawk9IDB4MDAwMDAwRkY7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga2V5Q29kZU1hc2sJCT0gMHgwMDAwRkYwMDsKLQotCS8vIEV2ZW50TW9kaWZpZXJzCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgYWN0aXZlRmxhZwkJPSAxOwkvKiBhY3RpdmF0ZT8gKGFjdGl2YXRlRXZ0IGFuZCBtb3VzZURvd24pKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBidG5TdGF0ZQkJPSAxIDw8IDc7CS8qIHN0YXRlIG9mIGJ1dHRvbj8qLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGNtZEtleQkJCT0gMSA8PCA4OwkvKiBjb21tYW5kIGtleSBkb3duPyovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2hpZnRLZXkJCT0gMSA8PCA5OwkvKiBzaGlmdCBrZXkgZG93bj8qLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGFscGhhTG9jawkJPSAxIDw8IDEwOwkvKiBhbHBoYSBsb2NrIGRvd24/Ki8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBvcHRpb25LZXkJCT0gMSA8PCAxMTsJLyogb3B0aW9uIGtleSBkb3duPyovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgY29udHJvbEtleQkJPSAxIDw8IDEyOwkvKiBjb250cm9sIGtleSBkb3duPyovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgcmlnaHRTaGlmdEtleQk9IDEgPDwgMTM7CS8qIHJpZ2h0IHNoaWZ0IGtleSBkb3duPyovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgcmlnaHRPcHRpb25LZXkJPSAxIDw8IDE0OwkvKiByaWdodCBPcHRpb24ga2V5IGRvd24/Ki8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCByaWdodENvbnRyb2xLZXkJPSAxIDw8IDE1OwkvKiByaWdodCBDb250cm9sIGtleSBkb3duPyovCi0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBHZXROZXh0RXZlbnQoc2hvcnQgZXZlbnRNYXNrLCBpbnRbXSBldmVudERhdGEpOwotICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gV2FpdE5leHRFdmVudChzaG9ydCBldmVudE1hc2ssIGludFtdIGV2ZW50RGF0YSwgaW50IHNsZWVwVGltZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBTdGlsbERvd24oKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEdldE1vdXNlKHNob3J0W10gd2hlcmUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQUVQcm9jZXNzQXBwbGVFdmVudChpbnRbXSBldmVudERhdGEpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBNZW51RXZlbnQoaW50W10gZXZlbnREYXRhKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgUG9zdEV2ZW50KHNob3J0IGV2ZW50TnVtLCBpbnQgZXZlbnRNc2cpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRLZXlib2FyZEZvY3VzKGludCB3SGFuZGxlLCBpbnRbXSBjSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0S2V5Ym9hcmRGb2N1cyhpbnQgd0hhbmRsZSwgaW50IGNIYW5kbGUsIHNob3J0IGluUGFydCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEFkdmFuY2VLZXlib2FyZEZvY3VzKGludCB3SGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIElzU2hvd0NvbnRleHR1YWxNZW51Q2xpY2soaW50W10gZXZlbnREYXRhKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgQ29udGV4dHVhbE1lbnVTZWxlY3QoaW50IG1IYW5kbGUsIHNob3J0W10gbG9jYXRpb24sIHNob3J0W10gbWVudUlkLCBzaG9ydFtdIGluZGV4KTsKLQotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCS8vIENhcmJvbiBFdmVudCBNYW5hZ2VyCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JCi0JcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUga0V2ZW50RHVyYXRpb25Gb3JldmVyCT0gLTEuMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGRvdWJsZSBrRXZlbnREdXJhdGlvbk5vV2FpdAkJPSAwLjA7Ci0JCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgZXZlbnROb3RIYW5kbGVkRXJyCT0gLTk4NzQ7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgZXZlbnRMb29wVGltZWRPdXRFcnI9IC05ODc1OwotCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50QXR0cmlidXRlTm9uZQkJCT0gMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRBdHRyaWJ1dGVVc2VyRXZlbnQJPSAxIDw8IDA7Ci0KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDbGFzc01vdXNlCQk9ICgnbSc8PDI0KSArICgnbyc8PDE2KSArICgndSc8PDgpICsgJ3MnOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudENsYXNzS2V5Ym9hcmQJCT0gKCdrJzw8MjQpICsgKCdlJzw8MTYpICsgKCd5Jzw8OCkgKyAnYic7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q2xhc3NUZXh0SW5wdXQJPSAoJ3QnPDwyNCkgKyAoJ2UnPDwxNikgKyAoJ3gnPDw4KSArICd0JzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDbGFzc0FwcGxpY2F0aW9uCT0gKCdhJzw8MjQpICsgKCdwJzw8MTYpICsgKCdwJzw8OCkgKyAnbCc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q2xhc3NBcHBsZUV2ZW50CT0gKCdlJzw8MjQpICsgKCdwJzw8MTYpICsgKCdwJzw8OCkgKyAnYyc7Ci0JCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudEFwcGxlRXZlbnQJPSAxOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudENsYXNzTWVudQkJCT0gKCdtJzw8MjQpICsgKCdlJzw8MTYpICsgKCduJzw8OCkgKyAndSc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q2xhc3NXaW5kb3cJCT0gKCd3Jzw8MjQpICsgKCdpJzw8MTYpICsgKCduJzw8OCkgKyAnZCc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q2xhc3NDb250cm9sCQk9ICgnYyc8PDI0KSArICgnbic8PDE2KSArICgndCc8PDgpICsgJ2wnOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudENsYXNzVGFibGV0CQk9ICgndCc8PDI0KSArICgnYic8PDE2KSArICgnbCc8PDgpICsgJ3QnOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudENsYXNzVm9sdW1lCQk9ICgndic8PDI0KSArICgnbyc8PDE2KSArICgnbCc8PDgpICsgJyAnOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudENsYXNzQXBwZWFyYW5jZQk9ICgnYSc8PDI0KSArICgncCc8PDE2KSArICgncCc8PDgpICsgJ20nOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudENsYXNzU2VydmljZQkJPSAoJ3MnPDwyNCkgKyAoJ2UnPDwxNikgKyAoJ3InPDw4KSArICd2JzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDbGFzc0NvbW1hbmQJCT0gKCdjJzw8MjQpICsgKCdtJzw8MTYpICsgKCdkJzw8OCkgKyAncyc7Ci0JCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFByb2Nlc3NDb21tYW5kCT0gMTsKLQotCQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVVSW50MzI9ICgnbSc8PDI0KSArICgnYSc8PDE2KSArICgnZyc8PDgpICsgJ24nOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVDaGFyPSAoJ1QnPDwyNCkgKyAoJ0UnPDwxNikgKyAoJ1gnPDw4KSArICdUJzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlVW5pY29kZVRleHQ9ICgndSc8PDI0KSArICgndCc8PDE2KSArICgneCc8PDgpICsgJ3QnOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVXaW5kb3dSZWY9ICgndyc8PDI0KSArICgnaSc8PDE2KSArICgnbic8PDgpICsgJ2QnOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVXaW5kb3dEZWZQYXJ0Q29kZT0gKCd3Jzw8MjQpICsgKCdkJzw8MTYpICsgKCdwJzw8OCkgKyAndCc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgdHlwZUNvbnRyb2xSZWY9ICgnYyc8PDI0KSArICgndCc8PDE2KSArICgncic8PDgpICsgJ2wnOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVNb3VzZUJ1dHRvbj0gKCdtJzw8MjQpICsgKCdiJzw8MTYpICsgKCd0Jzw8OCkgKyAnbic7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgdHlwZVFEUG9pbnQ9ICgnUSc8PDI0KSArICgnRCc8PDE2KSArICgncCc8PDgpICsgJ3QnOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVUeXBlPSAoJ3QnPDwyNCkgKyAoJ3knPDwxNikgKyAoJ3AnPDw4KSArICdlJzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlU0ludDMyPSAoJ2wnPDwyNCkgKyAoJ28nPDwxNikgKyAoJ24nPDw4KSArICdnJzsKLQkKLQkKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbURpcmVjdE9iamVjdAk9ICgnLSc8PDI0KSArICgnLSc8PDE2KSArICgnLSc8PDgpICsgJy0nOyAvKiB0eXBlIHZhcmllcyBkZXBlbmRpbmcgb24gZXZlbnQqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtQXR0cmlidXRlcwk9ICgnYSc8PDI0KSArICgndCc8PDE2KSArICgndCc8PDgpICsgJ3InOyAvKiB0eXBlVUludDMyKi8KLQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtV2luZG93RGVmUGFydD0gKCd3Jzw8MjQpICsgKCdkJzw8MTYpICsgKCdwJzw8OCkgKyAnYyc7Ci0JCi0JLy8gR2VuZXJpYyB0b29sYm94IHBhcmFtZXRlcnMgYW5kIHR5cGVzCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1XaW5kb3dSZWYgCT0gKCd3Jzw8MjQpICsgKCdpJzw8MTYpICsgKCduJzw8OCkgKyAnZCc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1Db250cm9sUmVmPSAoJ2MnPDwyNCkgKyAoJ3QnPDwxNikgKyAoJ3InPDw4KSArICdsJzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbUFFRXZlbnRJRD0gKCdlJzw8MjQpICsgKCd2Jzw8MTYpICsgKCd0Jzw8OCkgKyAnaSc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1BRUV2ZW50Q2xhc3M9ICgnZSc8PDI0KSArICgndic8PDE2KSArICgnYyc8PDgpICsgJ2wnOwotCi0JLy8gTW91c2UgRXZlbnQKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbVdpbmRvd01vdXNlTG9jYXRpb249ICgndyc8PDI0KSArICgnbSc8PDE2KSArICgnbyc8PDgpICsgJ3UnOwkvKiB0eXBlSElQb2ludCovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1Nb3VzZUJ1dHRvbj0gKCdtJzw8MjQpICsgKCdiJzw8MTYpICsgKCd0Jzw8OCkgKyAnbic7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1Nb3VzZUxvY2F0aW9uPSAoJ20nPDwyNCkgKyAoJ2wnPDwxNikgKyAoJ28nPDw4KSArICdjJzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbU1vdXNlQ2hvcmQ9ICgnYyc8PDI0KSArICgnaCc8PDE2KSArICgnbyc8PDgpICsgJ3InOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtTW91c2VXaGVlbERlbHRhPSAoJ20nPDwyNCkgKyAoJ3cnPDwxNikgKyAoJ2QnPDw4KSArICdsJzsKLQotCS8vIFdpbmRvdyBldmVudCBwYXJhbWV0ZXJzIGFuZCB0eXBlcwotCQotCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1UZXh0SW5wdXRTZW5kVGV4dD0gKCd0Jzw8MjQpICsgKCdzJzw8MTYpICsgKCd0Jzw8OCkgKyAneCc7Ci0KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbUtleUNvZGU9ICgnayc8PDI0KSArICgnYyc8PDE2KSArICgnbyc8PDgpICsgJ2QnOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtS2V5TWFjQ2hhckNvZGVzPSAoJ2snPDwyNCkgKyAoJ2MnPDwxNikgKyAoJ2gnPDw4KSArICdyJzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbUtleU1vZGlmaWVycz0gKCdrJzw8MjQpICsgKCdtJzw8MTYpICsgKCdvJzw8OCkgKyAnZCc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1LZXlVbmljb2Rlcz0gKCdrJzw8MjQpICsgKCd1Jzw8MTYpICsgKCduJzw8OCkgKyAnaSc7Ci0JCi0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrRXZlbnRNb3VzZUJ1dHRvblByaW1hcnk9IDE7CQkvLyB0aGUgbGVmdCBtb3VzZSBidXR0b24KLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtFdmVudE1vdXNlQnV0dG9uU2Vjb25kYXJ5PSAyOwkvLyB0aGUgcmlnaHQgbW91c2UgYnV0dG9uCi0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrRXZlbnRNb3VzZUJ1dHRvblRlcnRpYXJ5PSAzOwkJLy8gdGhlIG1pZGRsZSBtb3VzZSBidXR0b24KLQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudE1vdXNlRG93bgkJPSAxOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudE1vdXNlVXAJCT0gMjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRNb3VzZU1vdmVkCT0gNTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRNb3VzZURyYWdnZWQJPSA2OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudE1vdXNlRW50ZXJlZAk9IDg7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50TW91c2VFeGl0ZWQJPSA5OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudE1vdXNlV2hlZWxNb3ZlZD0gMTA7Ci0JCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UmF3S2V5RG93bgk9IDE7ICAgIC8vIEEga2V5IHdhcyBwcmVzc2VkCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UmF3S2V5UmVwZWF0CT0gMjsJLy8gU2VudCBwZXJpb2RpY2FsbHkgYXMgYSBrZXkgaXMgaGVsZCBkb3duIGJ5IHRoZSB1c2VyCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UmF3S2V5VXAJCT0gMzsJLy8gQSBrZXkgd2FzIHJlbGVhc2VkCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UmF3S2V5TW9kaWZpZXJzQ2hhbmdlZD0gNDsJLy8gVGhlIGtleWJvYXJkIG1vZGlmaWVycyAoYnVja3kgYml0cykgaGF2ZSBjaGFuZ2VkLgotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudEhvdEtleVByZXNzZWQJPSA1OwkvLyBBIHJlZ2lzdGVyZWQgSG90IEtleSB3YXMgcHJlc3NlZC4KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRIb3RLZXlSZWxlYXNlZD0gNjsJLy8gQSByZWdpc3RlcmVkIEhvdCBLZXkgd2FzIHJlbGVhc2VkICh0aGlzIGlzIG9ubHkgc2VudCBvbiBNYWMgT1MgWCkuCi0JCQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFdpbmRvd0RyYXdDb250ZW50CT0gMjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRXaW5kb3dBY3RpdmF0ZWQJPSA1OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFdpbmRvd0RlYWN0aXZhdGVkCT0gNjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRXaW5kb3dCb3VuZHNDaGFuZ2VkID0gMjc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50V2luZG93Q2xvc2UJCT0gNzI7Ci0JCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd0JvdW5kc0NoYW5nZVVzZXJEcmFnICAgPSAoMSA8PCAwKTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93Qm91bmRzQ2hhbmdlVXNlclJlc2l6ZSA9ICgxIDw8IDEpOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dCb3VuZHNDaGFuZ2VTaXplQ2hhbmdlZCA9ICgxIDw8IDIpOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dCb3VuZHNDaGFuZ2VPcmlnaW5DaGFuZ2VkID0gKDEgPDwgMyk7Ci0KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRNZW51QmVnaW5UcmFja2luZyA9IDE7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50TWVudUVuZFRyYWNraW5nID0gMjsKLQkJCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50VGV4dElucHV0VW5pY29kZUZvcktleUV2ZW50ID0gMjsKLQkKKwkvKiogQ29uc3RhbnRzICovCisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkdCRGlyZWN0ID0gMTY7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgYm9sZCA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgY2hlY2tNYXJrID0gMTg7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgY21kS2V5ID0gMSA8PCA4OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGNvbnRyb2xLZXkgPSAxIDw8IDEyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGRpYW1vbmRNYXJrID0gMTk7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgZXJyQ29udHJvbElzTm90RW1iZWRkZXIgPSAtMzA1OTA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgZXJyVW5rbm93bkNvbnRyb2wgPSAtMzA1ODQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgZXZlbnRMb29wVGltZWRPdXRFcnIgPSAtOTg3NTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBldmVudE5vdEhhbmRsZWRFcnIgPSAtOTg3NDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpbkNvbnRlbnQgPSAzOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGluTWVudUJhciA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaW5TdHJ1Y3R1cmUgPSAxNTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpblpvb21JbiA9IDc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgaW5ab29tT3V0ID0gODsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBpdGFsaWMgPSAyOwogCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtBRVF1aXRBcHBsaWNhdGlvbiA9ICgncSc8PDI0KSArICgndSc8PDE2KSArICgnaSc8PDgpICsgJ3QnOwotCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IENhbGxOZXh0RXZlbnRIYW5kbGVyKGludCBuZXh0SGFuZGxlciwgaW50IGV2ZW50UmVmSGFuZGxlKTsgCi0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEluc3RhbGxFdmVudEhhbmRsZXIoaW50IGV2ZW50VGFyZ2V0UmVmLCBpbnQgY29udHJvbEhhbmRsZXJVUFAsIGludFtdIGV2ZW50VHlwZXMsIGludCBjbGllbnREYXRhKTsKLQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0RXZlbnRISUNvbW1hbmQoaW50IGVSZWZIYW5kbGUsIGludFtdIG91dFBhcmFtVHlwZSk7Ci0JCQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0RXZlbnRQYXJhbWV0ZXIoaW50IGVSZWZIYW5kbGUsIGludCBwYXJhbU5hbWUsIGludCBwYXJhbVR5cGUsIGludFtdIG91dFBhcmFtVHlwZSwKLQkJCWludFtdIG91dEFjdHVhbFNpemUsIGJ5dGVbXSBkYXRhKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0RXZlbnRQYXJhbWV0ZXIoaW50IGVSZWZIYW5kbGUsIGludCBwYXJhbU5hbWUsIGludCBwYXJhbVR5cGUsIGludFtdIG91dFBhcmFtVHlwZSwKLQkJCWludFtdIG91dEFjdHVhbFNpemUsIGNoYXJbXSBkYXRhKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0RXZlbnRQYXJhbWV0ZXIoaW50IGVSZWZIYW5kbGUsIGludCBwYXJhbU5hbWUsIGludCBwYXJhbVR5cGUsIGludFtdIG91dFBhcmFtVHlwZSwKLQkJCWludFtdIG91dEFjdHVhbFNpemUsIHNob3J0W10gZGF0YSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldEV2ZW50UGFyYW1ldGVyKGludCBlUmVmSGFuZGxlLCBpbnQgcGFyYW1OYW1lLCBpbnQgcGFyYW1UeXBlLCBpbnRbXSBvdXRQYXJhbVR5cGUsCi0JCQlpbnRbXSBvdXRBY3R1YWxTaXplLCBpbnRbXSBkYXRhKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0RXZlbnRQYXJhbWV0ZXIoaW50IGVSZWZIYW5kbGUsIGludCBwYXJhbU5hbWUsIGludCBwYXJhbVR5cGUsIGNoYXJbXSBkYXRhKTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRDb250cm9sRXZlbnRUYXJnZXQoaW50IGNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRNZW51RXZlbnRUYXJnZXQoaW50IGNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRVc2VyRm9jdXNFdmVudFRhcmdldCgpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRBcHBsaWNhdGlvbkV2ZW50VGFyZ2V0KCk7Ci0JCQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0VXNlckZvY3VzV2luZG93KCk7Ci0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldEN1cnJlbnRFdmVudExvb3AoKTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBJbnN0YWxsRXZlbnRMb29wVGltZXIoaW50IGluRXZlbnRMb29wLCBkb3VibGUgaW5GaXJlRGVsYXksIAotCQkJZG91YmxlIGluSW50ZXJ2YWwsIGludCBpblRpbWVyUHJvYywgaW50IGluVGltZXJEYXRhLCBpbnRbXSBvdXRUaW1lcik7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFJlbW92ZUV2ZW50TG9vcFRpbWVyKGludCBpblRpbWVyKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBkb3VibGUgR2V0TGFzdFVzZXJFdmVudFRpbWUoKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgUmVjZWl2ZU5leHRFdmVudChpbnRbXSBldmVudFR5cGVTcGVjTGlzdCwgZG91YmxlIGluVGltZW91dCwgYm9vbGVhbiBpblB1bGxFdmVudCwgaW50W10gb3V0RXZlbnQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRFdmVudERpc3BhdGNoZXJUYXJnZXQoKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2VuZEV2ZW50VG9FdmVudFRhcmdldChpbnQgdGhlRXZlbnQsIGludCB0aGVUYXJnZXQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgUmVsZWFzZUV2ZW50KGludCB0aGVFdmVudCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBDb252ZXJ0RXZlbnRSZWZUb0V2ZW50UmVjb3JkKGludCBlSGFuZGxlLCBpbnRbXSBvdXRFdmVudCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEluc3RhbGxTdGFuZGFyZEV2ZW50SGFuZGxlcihpbnQgaW5UYXJnZXQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRXaW5kb3dFdmVudFRhcmdldChpbnQgd0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldEV2ZW50Q2xhc3MoaW50IGVIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRFdmVudEtpbmQoaW50IGVIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGRvdWJsZSBHZXRFdmVudFRpbWUoaW50IGVIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRNb3VzZUxvY2F0aW9uKGludCBlSGFuZGxlLCBzaG9ydFtdIGxvY2F0aW9uKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgVHJhY2tNb3VzZUxvY2F0aW9uKGludCBwb3J0SGFuZGxlLCBzaG9ydFtdIG91dFB0LCBzaG9ydFtdIG91dFJlc3VsdCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBHZXRHbG9iYWxNb3VzZShzaG9ydFtdIHdoZXJlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgQ3JlYXRlRXZlbnQoaW50IGFsbG9jYXRvciwgaW50IGluQ2xhc3NJRCwgaW50IGtpbmQsIGRvdWJsZSB3aGVuLCBpbnQgZmxhZ3MsIGludFtdIG91dEV2ZW50UmVmKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgUG9zdEV2ZW50VG9RdWV1ZShpbnQgaW5RdWV1ZSwgaW50IGluRXZlbnQsIHNob3J0IGluUHJpb3JpdHkpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRNYWluRXZlbnRRdWV1ZSgpOwotCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JLy8gRm9udCBtYW5hZ2VyCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JCi0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrSW52YWxpZEZvbnRGYW1pbHkJPSAtMTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHNob3J0IEZNR2V0Rm9udEZhbWlseUZyb21OYW1lKGJ5dGVbXSBuYW1lKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRk1HZXRGb250RmFtaWx5TmFtZShzaG9ydCBpZCwgYnl0ZVtdIG5hbWUpOwotCQotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCS8vIEN1cnNvcnMKLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVBcnJvd0N1cnNvciA9IDA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lQ29weUFycm93Q3Vyc29yID0gMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVBbGlhc0Fycm93Q3Vyc29yID0gMjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVDb250ZXh0dWFsTWVudUFycm93Q3Vyc29yID0gMzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVJQmVhbUN1cnNvciA9IDQ7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lQ3Jvc3NDdXJzb3IgPSA1OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZVBsdXNDdXJzb3IgPSA2OwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZVdhdGNoQ3Vyc29yID0gNzsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVDbG9zZWRIYW5kQ3Vyc29yID0gODsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVPcGVuSGFuZEN1cnNvciA9IDk7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lUG9pbnRpbmdIYW5kQ3Vyc29yID0gMTA7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lQ291bnRpbmdVcEhhbmRDdXJzb3IgPSAxMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVDb3VudGluZ0Rvd25IYW5kQ3Vyc29yID0gMTI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lQ291bnRpbmdVcEFuZERvd25IYW5kQ3Vyc29yID0gMTM7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lU3Bpbm5pbmdDdXJzb3IgPSAxNDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVSZXNpemVMZWZ0Q3Vyc29yID0gMTU7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lUmVzaXplUmlnaHRDdXJzb3IgPSAxNjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVSZXNpemVMZWZ0UmlnaHRDdXJzb3IgPSAxNzsKLSAKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGlCZWFtQ3Vyc29yID0gMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGNyb3NzQ3Vyc29yID0gMjsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IHBsdXNDdXJzb3IgPSAzOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgd2F0Y2hDdXJzb3IgPSA0OwotCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBJbml0Q3Vyc29yKCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IE5ld0N1cnNvcihzaG9ydCBob3RYLCBzaG9ydCBob3RZLCBzaG9ydFtdIGRhdGEsIHNob3J0W10gbWFzayk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldEN1cnNvcihzaG9ydCBpZCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTZXRDdXJzb3IoaW50IGN1cnNvcik7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldFRoZW1lQ3Vyc29yKGludCB0aGVtZUN1cnNvcik7Ci0KLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQkvLyBRdWlja0RyYXcKLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQkKLQkvLyB0cmFuc2ZlciBtb2RlcwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgc3JjQ29weQk9IDA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBzcmNPcgkJPSAxOwotCQotCS8vIHRleHQgZmFjZXMKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IG5vcm1hbAk9IDA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBib2xkCQk9IDE7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBpdGFsaWMJPSAyOwotCQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtRRFVzZURlZmF1bHRUZXh0UmVuZGVyaW5nID0gMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrUURVc2VUcnVlVHlwZVNjYWxlckdseXBocyA9ICgxIDw8IDApOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtRRFVzZUNHVGV4dFJlbmRlcmluZyA9ICgxIDw8IDEpOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtBbGVydENhdXRpb25BbGVydCA9IDI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0FsZXJ0Tm90ZUFsZXJ0ID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQWxlcnRQbGFpbkFsZXJ0ID0gMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQWxlcnRTdG9wQWxlcnQgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtBbGVydERlZmF1bHRPS1RleHQgICAgICAgICAgID0gLTE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0FsZXJ0RGVmYXVsdENhbmNlbFRleHQgICAgICAgPSAtMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQWxlcnRTdGRBbGVydE9LQnV0dG9uICAgICAgICA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0FsZXJ0U3RkQWxlcnRDYW5jZWxCdXR0b24gICAgPSAyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtBbGVydFN0ZEFsZXJ0T3RoZXJCdXR0b24gICAgID0gMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQXRTcGVjaWZpZWRPcmlnaW4gPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtBVFNVQ0dDb250ZXh0VGFnID0gMzI3Njc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0FUU1VGb250VGFnID0gMjYxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtBVFNVUURCb2xkZmFjZVRhZyA9IDI1NjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQVRTVVFESXRhbGljVGFnID0gMjU3OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtBVFNVc2VEZXZpY2VPcmlnaW5zID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQVRTVVNpemVUYWcgPSAyNjI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NGQWxsb2NhdG9yRGVmYXVsdCA9IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NGVVJMUE9TSVhQYXRoU3R5bGUgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDR0ltYWdlQWxwaGFGaXJzdCA9IDQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NHSW1hZ2VBbHBoYU5vbmVTa2lwRmlyc3QgPSA2OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb2xvclBpY2tlckRpYWxvZ0lzTW92ZWFibGUgPSAgMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29sb3JQaWNrZXJEaWFsb2dJc01vZGFsID0gMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEJlaGF2aW9yUHVzaGJ1dHRvbiA9IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xCZWhhdmlvclRvZ2dsZXMgPSAweDAxMDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xCZXZlbEJ1dHRvbkFsaWduQ2VudGVyID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEJldmVsQnV0dG9uQWxpZ25MZWZ0ICA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xCZXZlbEJ1dHRvbkFsaWduUmlnaHQgPSAyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sQmV2ZWxCdXR0b25BbGlnblRleHRDZW50ZXIgPSAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sQmV2ZWxCdXR0b25BbGlnblRleHRGbHVzaFJpZ2h0ID0gLTE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xCZXZlbEJ1dHRvbkFsaWduVGV4dEZsdXNoTGVmdCA9IC0yOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sQmV2ZWxCdXR0b25Ob3JtYWxCZXZlbFByb2MgPSAzMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEJldmVsQnV0dG9uU21hbGxCZXZlbCA9IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xCZXZlbEJ1dHRvbkxhcmdlQmV2ZWwgPSAyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sQmV2ZWxCdXR0b25NZW51UmVmVGFnID0gKCdtJzw8MjQpICsgKCdoJzw8MTYpICsgKCduJzw8OCkgKyAnZCc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xCZXZlbEJ1dHRvbk5vcm1hbEJldmVsID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEJldmVsQnV0dG9uUGxhY2VCZWxvd0dyYXBoaWMgPSAzOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sQmV2ZWxCdXR0b25QbGFjZVRvUmlnaHRPZkdyYXBoaWMgPSAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sQmV2ZWxCdXR0b25LaW5kVGFnID0gKCdiJzw8MjQpICsgKCdlJzw8MTYpICsgKCdiJzw8OCkgKyAnayc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xCZXZlbEJ1dHRvblRleHRBbGlnblRhZyA9ICgndCc8PDI0KSArICgnYSc8PDE2KSArICgnbCc8PDgpICsgJ2knOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sQmV2ZWxCdXR0b25UZXh0UGxhY2VUYWcgPSAoJ3QnPDwyNCkgKyAoJ3AnPDwxNikgKyAoJ2wnPDw4KSArICdjJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEJldmVsQnV0dG9uR3JhcGhpY0FsaWduVGFnID0gKCdnJzw8MjQpICsgKCdhJzw8MTYpICsgKCdsJzw8OCkgKyAnaSc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xCb3VuZHNDaGFuZ2VTaXplQ2hhbmdlZCA9IDEgPDwgMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEJvdW5kc0NoYW5nZVBvc2l0aW9uQ2hhbmdlZCA9IDEgPDwgMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbENoZWNrQm94QXV0b1RvZ2dsZVByb2MgPSAzNzE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xDb250ZW50Q0ljb25IYW5kbGUgPSAxMzA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xDb250ZW50SWNvblJlZiA9IDEzMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbENvbnRlbnRNZXRhUGFydCA9IC0yOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sQ29udGVudFRleHRPbmx5ID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbERvd25CdXR0b25QYXJ0ID0gMjE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xFZGl0VGV4dENGU3RyaW5nVGFnID0gKCdjJzw8MjQpICsgKCdmJzw8MTYpICsgKCdzJzw8OCkgKyAndCc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xFZGl0VGV4dFNpbmdsZUxpbmVUYWcgPSAoJ3MnPDwyNCkgKyAoJ2cnPDwxNikgKyAoJ2wnPDw4KSArICdjJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEVkaXRUZXh0U2VsZWN0aW9uVGFnID0gKCdzJzw8MjQpICsgKCdlJzw8MTYpICsgKCdsJzw8OCkgKyAnZSc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xFZGl0VGV4dFRleHRUYWcgPSAoJ3QnPDwyNCkgKyAoJ2UnPDwxNikgKyAoJ3gnPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEVudGlyZUNvbnRyb2wgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sR2V0c0ZvY3VzT25DbGljayA9IDEgPDwgODsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEdyb3VwQm94VGV4dFRpdGxlUHJvYyA9IDE2MDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEhhbmRsZXNUcmFja2luZyA9IDEgPDwgNTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEljb25UcmFuc2Zvcm1UYWcgPSAoJ3QnPDwyNCkgKyAoJ3InPDwxNikgKyAoJ2YnPDw4KSArICdtJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEluZGljYXRvclBhcnQgPSAxMjk7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xQYWdlRG93blBhcnQgPSAyMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFBhZ2VVcFBhcnQgPSAyMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFBvcHVwQXJyb3dFYXN0UHJvYyA9IDE5MjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFBvcHVwQXJyb3dPcmllbnRhdGlvbkVhc3QgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sUG9wdXBBcnJvd09yaWVudGF0aW9uV2VzdCA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xQb3B1cEFycm93T3JpZW50YXRpb25Ob3J0aCA9IDI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xQb3B1cEFycm93T3JpZW50YXRpb25Tb3V0aCA9IDM7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xQb3B1cEFycm93U2l6ZU5vcm1hbCAgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sUG9wdXBBcnJvd1NpemVTbWFsbCAgID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFBvcHVwQnV0dG9uUHJvYyA9IDQwMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFByb2dyZXNzQmFySW5kZXRlcm1pbmF0ZVRhZyA9ICgnaSc8PDI0KSArICgnbic8PDE2KSArICgnZCc8PDgpICsgJ2UnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sUHJvZ3Jlc3NCYXJQcm9jID0gODA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xQdXNoQnV0dG9uUHJvYyA9IDM2ODsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFJhZGlvQnV0dG9uQXV0b1RvZ2dsZVByb2MgPSAzNzI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xTY3JvbGxCYXJMaXZlUHJvYyA9IDM4NjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFNlcGFyYXRvckxpbmVQcm9jID0gMTQ0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sU2xpZGVyTGl2ZUZlZWRiYWNrID0gKDEgPDwgMCk7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xTbGlkZXJOb25EaXJlY3Rpb25hbCA9ICgxIDw8IDMpOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sU2xpZGVyUHJvYyA9IDQ4OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sU3RydWN0dXJlTWV0YVBhcnQgPSAtMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN1cHBvcnRzRW1iZWRkaW5nID0gMSA8PCAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sU3VwcG9ydHNGb2N1cyA9IDEgPDwgMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN0YXRpY1RleHRDRlN0cmluZ1RhZyA9ICgnYyc8PDI0KSArICgnZic8PDE2KSArICgncyc8PDgpICsgJ3QnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVGFiQ29udGVudFJlY3RUYWcgPSAoJ3InPDwyNCkgKyAoJ2UnPDwxNikgKyAoJ2MnPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFRhYkRpcmVjdGlvbk5vcnRoID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFRhYkltYWdlQ29udGVudFRhZyA9ICgnYyc8PDI0KSArICgnbyc8PDE2KSArICgnbic8PDgpICsgJ3QnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVGFiSW5mb1ZlcnNpb25PbmUgPSAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVGFiSW5mb1RhZyA9ICgndCc8PDI0KSArICgnYSc8PDE2KSArICgnYic8PDgpICsgJ2knOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVGFiU2l6ZUxhcmdlID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFRhYlNtYWxsUHJvYyA9IDEyOTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFVwQnV0dG9uUGFydCA9IDIwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVXNlclBhbmVEcmF3UHJvY1RhZyA9ICgnZCc8PDI0KSArICgncic8PDE2KSArICgnYSc8PDgpICsgJ3cnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVXNlclBhbmVIaXRUZXN0UHJvY1RhZyA9ICgnaCc8PDI0KSArICgnaSc8PDE2KSArICgndCc8PDgpICsgJ3QnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVXNlclBhbmVQcm9jID0gMjU2OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVXNlclBhbmVUcmFja2luZ1Byb2NUYWcgPSAoJ3QnPDwyNCkgKyAoJ3InPDwxNikgKyAoJ2EnPDw4KSArICdrJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFVzZUZvbnRNYXNrID0gMHgxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVXNlU2l6ZU1hc2sgPSAweDQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xVc2VUaGVtZUZvbnRJRE1hc2sgPSAweDgwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVXNlRmFjZU1hc2sgPSAweDI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0N1cnJlbnRQcm9jZXNzID0gMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJDaGVja2JveFR5cGUgPSAoJ2MnPDwyNCkgKyAoJ2gnPDwxNikgKyAoJ2InPDw4KSArICd4JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJDbWRUb2dnbGVzU2VsZWN0aW9uID0gMSA8PCAzOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckNvbnRhaW5lckNsb3NlZCA9IDEwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckNvbnRhaW5lckNsb3NpbmcgPSA5OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckNvbnRhaW5lcklzQ2xvc2FibGVQcm9wZXJ0eSA9IDY7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyQ29udGFpbmVySXNPcGVuID0gMSA8PCAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckNvbnRhaW5lcklzT3BlbmFibGVQcm9wZXJ0eSA9IDU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyQ29udGFpbmVySXNTb3J0YWJsZVByb3BlcnR5ID0gNzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJDb250YWluZXJPcGVuZWQgPSA4OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckN1c3RvbVR5cGUgPSAweDNGM0YzRjNGOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckRlZmF1bHRQcm9wZXJ0eUZsYWdzID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJEcmFnU2VsZWN0ID0gMSA8PCAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckljb25BbmRUZXh0VHlwZSA9ICgndCc8PDI0KSArICgnaSc8PDE2KSArICgnYyc8PDgpICsgJ24nOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckl0ZW1Jc0FjdGl2ZVByb3BlcnR5ID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJJdGVtSXNDb250YWluZXJQcm9wZXJ0eSA9IDQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbUlzRWRpdGFibGVQcm9wZXJ0eSA9IDM7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbUlzU2VsZWN0YWJsZVByb3BlcnR5ID0gMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJJdGVtSXNTZWxlY3RlZCA9IDEgPDwgMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJJdGVtTm9Qcm9wZXJ0eSA9IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbVBhcmVudENvbnRhaW5lclByb3BlcnR5ID0gMTE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbXNBZGQgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJJdGVtc1JlbW92ZSA9IDM7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbVJlbW92ZWQgPSAyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckl0ZW1TZWxlY3RlZCA9IDU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbURlc2VsZWN0ZWQgPSA2OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckl0ZW1Eb3VibGVDbGlja2VkID0gNzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJMYXRlc3RDYWxsYmFja3MgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckxhdGVzdEN1c3RvbUNhbGxiYWNrcyA9IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyTGlzdFZpZXcgPSAoJ2wnPDwyNCkgKyAoJ3MnPDwxNikgKyAoJ3QnPDw4KSArICd2JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJMaXN0Vmlld0xhdGVzdEhlYWRlckRlc2MgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckxpc3RWaWV3U2VsZWN0aW9uQ29sdW1uID0gMSA8PCBPUy5rRGF0YUJyb3dzZXJWaWV3U3BlY2lmaWNGbGFnc09mZnNldDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJOZXZlckVtcHR5U2VsZWN0aW9uU2V0ID0gMSA8PCA2OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlck5vSXRlbSA9IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyT3JkZXJJbmNyZWFzaW5nID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJQcm9wZXJ0eUVuY2xvc2luZ1BhcnQgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlclByb3BlcnR5SXNNdXRhYmxlID0gMSA8PCAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlclJldmVhbE9ubHkgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlclJldmVhbEFuZENlbnRlckluVmlldyA9IDEgPDwgMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJSZXZlYWxXaXRob3V0U2VsZWN0aW5nID0gMSA8PCAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlclNlbGVjdE9ubHlPbmUgPSAxIDw8IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyVGV4dFR5cGUgPSAoJ3QnPDwyNCkgKyAoJ2UnPDwxNikgKyAoJ3gnPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJUYWJsZVZpZXdGaWxsSGlsaXRlID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJWaWV3U3BlY2lmaWNGbGFnc09mZnNldCA9IDE2OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEb2N1bWVudFdpbmRvd0NsYXNzID0gNjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRBcHBsZUV2ZW50ID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRBdHRyaWJ1dGVVc2VyRXZlbnQgPSAxIDw8IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q2xhc3NBcHBsZUV2ZW50ID0gKCdlJzw8MjQpICsgKCdwJzw8MTYpICsgKCdwJzw8OCkgKyAnYyc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q2xhc3NDb21tYW5kID0gKCdjJzw8MjQpICsgKCdtJzw8MTYpICsgKCdkJzw8OCkgKyAncyc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q2xhc3NDb250cm9sID0gKCdjJzw8MjQpICsgKCduJzw8MTYpICsgKCd0Jzw8OCkgKyAnbCc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q2xhc3NGb250PSAoJ2YnPDwyNCkgKyAoJ28nPDwxNikgKyAoJ24nPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDbGFzc0hJT2JqZWN0ID0gKCdoJzw8MjQpICsgKCdpJzw8MTYpICsgKCdvJzw8OCkgKyAnYic7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q2xhc3NLZXlib2FyZCA9ICgnayc8PDI0KSArICgnZSc8PDE2KSArICgneSc8PDgpICsgJ2InOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudENsYXNzTWVudSA9ICgnbSc8PDI0KSArICgnZSc8PDE2KSArICgnbic8PDgpICsgJ3UnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudENsYXNzTW91c2UgPSAoJ20nPDwyNCkgKyAoJ28nPDwxNikgKyAoJ3UnPDw4KSArICdzJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDbGFzc1RleHRJbnB1dCA9ICgndCc8PDI0KSArICgnZSc8PDE2KSArICgneCc8PDgpICsgJ3QnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudENsYXNzV2luZG93ID0gKCd3Jzw8MjQpICsgKCdpJzw8MTYpICsgKCduJzw8OCkgKyAnZCc7CisgIAlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDb250cm9sQWN0aXZhdGUgPSA5OworICAJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q29udHJvbEFkZGVkU3ViQ29udHJvbCA9IDE1MjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDb250cm9sQm91bmRzQ2hhbmdlZCA9IDE1NDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDb250cm9sQ2xpY2sgPSAxMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDb250cm9sQ29udGV4dHVhbE1lbnVDbGljayA9IDEyOworICAJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q29udHJvbERlYWN0aXZhdGUgPSAxMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDb250cm9sRHJhdyA9IDQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xGb2N1c05leHRQYXJ0ID0gLTE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q29udHJvbEhpdCA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q29udHJvbFNldEN1cnNvciA9IDExOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudENvbnRyb2xTZXRGb2N1c1BhcnQgPSA3OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudENvbnRyb2xSZW1vdmluZ1N1YkNvbnRyb2wgPSAxNTM7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UHJpb3JpdHlTdGFuZGFyZCA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBkb3VibGUga0V2ZW50RHVyYXRpb25Gb3JldmVyID0gLTEuMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGRvdWJsZSBrRXZlbnREdXJhdGlvbk5vV2FpdCA9IDAuMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRGb250U2VsZWN0aW9uID0gMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRGb250UGFuZWxDbG9zZWQgPSAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudEhJT2JqZWN0Q29uc3RydWN0ID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRISU9iamVjdERlc3RydWN0ID0gMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRNZW51Q2xvc2VkID0gNTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRNZW51T3BlbmluZyA9IDQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50TWVudVBvcHVsYXRlID0gOTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRNb3VzZUJ1dHRvblByaW1hcnkgPSAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudE1vdXNlQnV0dG9uU2Vjb25kYXJ5ID0gMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRNb3VzZUJ1dHRvblRlcnRpYXJ5ID0gMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRNb3VzZURvd24gPSAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudE1vdXNlRHJhZ2dlZCA9IDY7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50TW91c2VFbnRlcmVkID0gODsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRNb3VzZUV4aXRlZCA9IDk7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50TW91c2VNb3ZlZCA9IDU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50TW91c2VVcCA9IDI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50TW91c2VXaGVlbE1vdmVkID0gMTA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1BRUV2ZW50Q2xhc3MgPSAoJ2UnPDwyNCkgKyAoJ3YnPDwxNikgKyAoJ2MnPDw4KSArICdsJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbUFFRXZlbnRJRCA9ICgnZSc8PDI0KSArICgndic8PDE2KSArICgndCc8PDgpICsgJ2knOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtQXR0cmlidXRlcyA9ICgnYSc8PDI0KSArICgndCc8PDE2KSArICgndCc8PDgpICsgJ3InOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtQ0dDb250ZXh0UmVmPSAoJ2MnPDwyNCkgKyAoJ24nPDwxNikgKyAoJ3QnPDw4KSArICd4JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbUNsaWNrQ291bnQgPSAoJ2MnPDwyNCkgKyAoJ2MnPDwxNikgKyAoJ24nPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbUNvbnRyb2xQYXJ0PSAoJ2MnPDwyNCkgKyAoJ3AnPDwxNikgKyAoJ3InPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbUNvbnRyb2xSZWYgPSAoJ2MnPDwyNCkgKyAoJ3QnPDwxNikgKyAoJ3InPDw4KSArICdsJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbUN1cnJlbnRCb3VuZHMgPSAoJ2MnPDwyNCkgKyAoJ3InPDwxNikgKyAoJ2MnPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbURpcmVjdE9iamVjdCA9ICgnLSc8PDI0KSArICgnLSc8PDE2KSArICgnLSc8PDgpICsgJy0nOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtRk1Gb250RmFtaWx5ID0gKCdmJzw8MjQpICsgKCdtJzw8MTYpICsgKCdmJzw8OCkgKyAnbSc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1GTUZvbnRTdHlsZSA9ICgnZic8PDI0KSArICgnbSc8PDE2KSArICgncyc8PDgpICsgJ3QnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtRk1Gb250U2l6ZSA9ICgnZic8PDI0KSArICgnbSc8PDE2KSArICgncyc8PDgpICsgJ3onOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtRm9udENvbG9yID0gKCdmJzw8MjQpICsgKCdjJzw8MTYpICsgKCdsJzw8OCkgKyAncic7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1LZXlDb2RlID0gKCdrJzw8MjQpICsgKCdjJzw8MTYpICsgKCdvJzw8OCkgKyAnZCc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1LZXlNYWNDaGFyQ29kZXMgPSAoJ2snPDwyNCkgKyAoJ2MnPDwxNikgKyAoJ2gnPDw4KSArICdyJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbUtleU1vZGlmaWVycyA9ICgnayc8PDI0KSArICgnbSc8PDE2KSArICgnbyc8PDgpICsgJ2QnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtTW91c2VCdXR0b24gPSAoJ20nPDwyNCkgKyAoJ2InPDwxNikgKyAoJ3QnPDw4KSArICduJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbU1vdXNlQ2hvcmQgPSAoJ2MnPDwyNCkgKyAoJ2gnPDwxNikgKyAoJ28nPDw4KSArICdyJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbU1vdXNlTG9jYXRpb24gPSAoJ20nPDwyNCkgKyAoJ2wnPDwxNikgKyAoJ28nPDw4KSArICdjJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbU1vdXNlV2hlZWxEZWx0YSA9ICgnbSc8PDI0KSArICgndyc8PDE2KSArICgnZCc8PDgpICsgJ2wnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtUHJldmlvdXNCb3VuZHMgPSAoJ3AnPDwyNCkgKyAoJ3InPDwxNikgKyAoJ2MnPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRQYXJhbU9yaWdpbmFsQm91bmRzID0gKCdvJzw8MjQpICsgKCdyJzw8MTYpICsgKCdjJzw8OCkgKyAndCc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1SZ25IYW5kbGUgPSAgKCdyJzw8MjQpICsgKCdnJzw8MTYpICsgKCduJzw8OCkgKyAnaCc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UGFyYW1UZXh0SW5wdXRTZW5kVGV4dCA9ICgndCc8PDI0KSArICgncyc8PDE2KSArICgndCc8PDgpICsgJ3gnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtV2luZG93RGVmUGFydCA9ICgndyc8PDI0KSArICgnZCc8PDE2KSArICgncCc8PDgpICsgJ2MnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtV2luZG93TW91c2VMb2NhdGlvbiA9ICgndyc8PDI0KSArICgnbSc8PDE2KSArICgnbyc8PDgpICsgJ3UnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFBhcmFtV2luZG93UmVmID0gKCd3Jzw8MjQpICsgKCdpJzw8MTYpICsgKCduJzw8OCkgKyAnZCc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UHJvY2Vzc0NvbW1hbmQgPSAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFJhd0tleURvd24gPSAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFJhd0tleVJlcGVhdCA9IDI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50UmF3S2V5VXAgPSAzOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFJhd0tleU1vZGlmaWVyc0NoYW5nZWQgPSA0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFRleHRJbnB1dFVuaWNvZGVGb3JLZXlFdmVudCA9IDI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50V2luZG93QWN0aXZhdGVkID0gNTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRXaW5kb3dCb3VuZHNDaGFuZ2VkID0gMjc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50V2luZG93Q2xvc2UgPSA3MjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRXaW5kb3dDb2xsYXBzZWQgPSA2NzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRXaW5kb3dEZWFjdGl2YXRlZCA9IDY7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50V2luZG93RHJhd0NvbnRlbnQgPSAyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudFdpbmRvd0V4cGFuZGVkID0gNzA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50V2luZG93Rm9jdXNBY3F1aXJlZCA9IDIwMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRXaW5kb3dGb2N1c1JlbGlucXVpc2ggPSAyMDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50V2luZG93SGlkZGVuID0gMjU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50V2luZG93U2hvd24gPSAyNDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRXaW5kb3dVcGRhdGUgPSAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtGTUl0ZXJhdGlvbkNvbXBsZXRlZCA9IC05ODA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0Zsb2F0aW5nV2luZG93Q2xhc3MgPSA1OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtGb250U2VsZWN0aW9uUURTdHlsZVZlcnNpb25aZXJvID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRm9udFNlbGVjdGlvblFEVHlwZSA9ICgncSc8PDI0KSArICgncyc8PDE2KSArICgndCc8PDgpICsgJ2wnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtISUNvbWJvQm94QXV0b0NvbXBsZXRpb25BdHRyaWJ1dGUgPSAoMSA8PCAwKTsJCisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0hJQ29tYm9Cb3hBdXRvU2l6ZUxpc3RBdHRyaWJ1dGUgPSAoMSA8PCAzKTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrSElDb21ib0JveEVkaXRUZXh0UGFydCA9IDU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0hJQ29tbWFuZEZyb21NZW51ID0gMSA8PCAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtISVZpZXdaT3JkZXJBYm92ZSA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0hJVmlld1pPcmRlckJlbG93ID0gMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrSE1DRlN0cmluZ0NvbnRlbnQgPSAoJ2MnPDwyNCkgKyAoJ2YnPDwxNikgKyAoJ3MnPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrSE1BYnNvbHV0ZUNlbnRlckFsaWduZWQgPSAyMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrSE1Db250ZW50UHJvdmlkZWQgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtITUNvbnRlbnROb3RQcm92aWRlZCA9IC0xOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtITUNvbnRlbnROb3RQcm92aWRlZERvbnRQcm9wYWdhdGUgPSAtMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrSE1EZWZhdWx0U2lkZSA9IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0hNRGlzcG9zZUNvbnRlbnQgPSAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtITVN1cHBseUNvbnRlbnQgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtIZWxwV2luZG93Q2xhc3MgPSAxMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrSW52YWxpZEZvbnRGYW1pbHkgPSAtMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWFjSGVscFZlcnNpb24gPSAzOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51QmxhbmtHbHlwaCA9IDk3OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51Q2Fwc0xvY2tHbHlwaCA9IDk5OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51Q0dJbWFnZVJlZlR5cGUgPSA3OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51Q2hlY2ttYXJrR2x5cGggPSAxODsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudUNsZWFyR2x5cGggPSAyODsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudUNvbW1hbmRHbHlwaCA9IDE3OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51Q29udGV4dHVhbE1lbnVHbHlwaCA9IDEwOTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudUNvbnRyb2xHbHlwaCA9IDY7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVDb250cm9sSVNPR2x5cGggPSAxMzg7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVDb250cm9sTW9kaWZpZXIgPSA0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51RGVsZXRlTGVmdEdseXBoID0gMjM7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVEZWxldGVSaWdodEdseXBoID0gMTA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVEaWFtb25kR2x5cGggPSAxOTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudURvd25BcnJvd0dseXBoID0gMTA2OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51RG93bndhcmRBcnJvd0Rhc2hlZEdseXBoID0gMTY7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVFbnRlckdseXBoID0gNDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudUVzY2FwZUdseXBoID0gMjc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVGMTBHbHlwaCA9IDEyMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudUYxMUdseXBoID0gMTIxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51RjEyR2x5cGggPSAxMjI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVGMUdseXBoID0gMTExOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51RjJHbHlwaCA9IDExMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudUYzR2x5cGggPSAxMTM7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVGNEdseXBoID0gMTE0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51RjVHbHlwaCA9IDExNTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudUY2R2x5cGggPSAxMTY7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVGN0dseXBoID0gMTE3OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51RjhHbHlwaCA9IDExODsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudUY5R2x5cGggPSAxMTk7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVIZWxwR2x5cGggPSAxMDM7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVJdGVtQXR0clNlcGFyYXRvciA9IDY0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51TGVmdEFycm93RGFzaGVkR2x5cGggPSAyNDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudUxlZnRBcnJvd0dseXBoID0gMTAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51Tm9Db21tYW5kTW9kaWZpZXIgPSAoMSA8PCAzKTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudU5vSWNvbiA9IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVOb01vZGlmaWVycyA9IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVOb25tYXJraW5nUmV0dXJuR2x5cGggPSAxMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudU51bGxHbHlwaCA9IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVPcHRpb25HbHlwaCA9IDc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVPcHRpb25Nb2RpZmllciA9ICgxIDw8IDEpOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51UGFnZURvd25HbHlwaCA9IDEwNzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudVBhZ2VVcEdseXBoID0gOTg7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVQZW5jaWxHbHlwaCA9IDE1OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51UG93ZXJHbHlwaCA9IDExMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudVJldHVybkdseXBoID0gMTE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVSZXR1cm5SMkxHbHlwaCA9IDEyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51UmlnaHRBcnJvd0Rhc2hlZEdseXBoID0gMjY7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVSaWdodEFycm93R2x5cGggPSAxMDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVTaGlmdEdseXBoID0gNTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudVNoaWZ0TW9kaWZpZXIgPSAoMSA8PCAwKTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTWVudVRhYlJpZ2h0R2x5cGggPSAyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51VXBBcnJvd0Rhc2hlZEdseXBoID0gMjU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVVcEFycm93R2x5cGggPSAxMDQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01vdXNlVHJhY2tpbmdNb3VzZURvd249IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01vdXNlVHJhY2tpbmdNb3VzZVVwPSAyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNb3VzZVRyYWNraW5nTW91c2VFeGl0ZWQgID0gMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTW91c2VUcmFja2luZ01vdXNlRW50ZXJlZCA9IDQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01vdXNlVHJhY2tpbmdNb3VzZURyYWdnZWQ9IDU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01vdXNlVHJhY2tpbmdNb3VzZUtleU1vZGlmaWVyc0NoYW5nZWQ9IDY7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01vdXNlVHJhY2tpbmdVc2VyQ2FuY2VsbGVkPSA3OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNb3VzZVRyYWNraW5nVGltZWRPdXQ9IDg7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01vdXNlVHJhY2tpbmdNb3VzZU1vdmVkPSA5OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNb2RhbFdpbmRvd0NsYXNzID0gMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTW92YWJsZU1vZGFsV2luZG93Q2xhc3MgPSA0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtOYXZBbGxvd0ludmlzaWJsZUZpbGVzID0gMHgwMDAwMDEwMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTmF2QWxsb3dNdWx0aXBsZUZpbGVzID0gMHgwMDAwMDA4MDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTmF2QWxsb3dPcGVuUGFja2FnZXMgPSAweDAwMDAyMDAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtOYXZDQk5ld0xvY2F0aW9uID0gNTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTmF2R2VuZXJpY1NpZ25hdHVyZSA9ICgnKic8PDI0KSArICgnKic8PDE2KSArICgnKic8PDgpICsgJyonOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtOYXZTdXBwb3J0UGFja2FnZXMgPSAweDAwMDAxMDAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtOYXZVc2VyQWN0aW9uQ2FuY2VsID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTmF2VXNlckFjdGlvbkNob29zZSA9IDQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga05hdlVzZXJBY3Rpb25PcGVuID0gMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTmF2VXNlckFjdGlvblNhdmVBcyA9IDM7CiAJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1FEVXNlQ0dUZXh0TWV0cmljcyA9ICgxIDw8IDIpOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtRRFN1cHBvcnRlZEZsYWdzID0KLQkJCQlrUURVc2VUcnVlVHlwZVNjYWxlckdseXBocyB8IGtRRFVzZUNHVGV4dFJlbmRlcmluZyB8IGtRRFVzZUNHVGV4dE1ldHJpY3M7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1FERG9udENoYW5nZUZsYWdzID0gMHhGRkZGRkZGRjsKLQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgUURTd2FwVGV4dEZsYWdzKGludCBmbGFncyk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBRRFNldFBhdHRlcm5PcmlnaW4oc2hvcnRbXSBwb2ludCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldFFER2xvYmFsc1NjcmVlbkJpdHMoaW50IGJpdG1hcCk7Ci0KLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0UG9ydCgpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU2V0UG9ydChpbnQgcEhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBJc1ZhbGlkUG9ydChpbnQgcEhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldFdpbmRvd0Zyb21Qb3J0KGludCBwSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEdldFBvcnRCb3VuZHMoaW50IHBIYW5kbGUsIHNob3J0W10gcmVjdCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBOb3JtYWxpemVUaGVtZURyYXdpbmdTdGF0ZSgpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgUkdCRm9yZUNvbG9yKHNob3J0IHJlZCwgc2hvcnQgZ3JlZW4sIHNob3J0IGJsdWUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgUkdCQmFja0NvbG9yKHNob3J0IHJlZCwgc2hvcnQgZ3JlZW4sIHNob3J0IGJsdWUpOwotCS8vcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBHbG9iYWxUb0xvY2FsKHNob3J0W10gcG9pbnQpOwotCS8vcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBMb2NhbFRvR2xvYmFsKHNob3J0W10gcG9pbnQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgUURHbG9iYWxUb0xvY2FsUG9pbnQoaW50IHBvcnQsIHNob3J0W10gcG9pbnQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgUURMb2NhbFRvR2xvYmFsUG9pbnQoaW50IHBvcnQsIHNob3J0W10gcG9pbnQpOwotCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTY3JvbGxSZWN0KHNob3J0W10gcmVjdCwgc2hvcnQgZGgsIHNob3J0IGR2LCBpbnQgdXBkYXRlUmduKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0UG9ydFZpc2libGVSZWdpb24oaW50IHBvcnRIYW5kbGUsIGludCByZ25IYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU2V0UG9ydFZpc2libGVSZWdpb24oaW50IHBvcnRIYW5kbGUsIGludCByZ25IYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgUURGbHVzaFBvcnRCdWZmZXIoaW50IHBvcnQsIGludCByZ25IYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBRREdldERpcnR5UmVnaW9uKGludCBwb3J0SGFuZGxlLCBpbnQgcmduSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgUURTZXREaXJ0eVJlZ2lvbihpbnQgcG9ydEhhbmRsZSwgaW50IHJnbkhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IExvY2tQb3J0Qml0cyhpbnQgcG9ydEhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFVubG9ja1BvcnRCaXRzKGludCBwb3J0SGFuZGxlKTsKLQotCS8vIGNsaXBwaW5nCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBDbGlwUmVjdChzaG9ydFtdIGNsaXBSZWN0KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEdldENsaXAoaW50IHJnbkhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTZXRDbGlwKGludCByZ25IYW5kbGUpOwkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNldE9yaWdpbihzaG9ydCBoLCBzaG9ydCB2KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEdldFBvcnRDbGlwUmVnaW9uKGludCBwb3J0LCBpbnQgY2xpcFJnbik7Ci0JCi0JLy8gVGV4dAotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgVGV4dEZvbnQoc2hvcnQgZm9udElEKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFRleHRTaXplKHNob3J0IHNpemUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgVGV4dEZhY2Uoc2hvcnQgZmFjZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBUZXh0TW9kZShzaG9ydCBtb2RlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIERyYXdUZXh0KFN0cmluZyBzLCBzaG9ydCBmb250LCBzaG9ydCBzaXplLCBzaG9ydCBmYWNlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBzaG9ydCBUZXh0V2lkdGgoU3RyaW5nIHMsIHNob3J0IGZvbnQsIHNob3J0IHNpemUsIHNob3J0IGZhY2UpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHNob3J0IENoYXJXaWR0aChieXRlIGMpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgR2V0Rm9udEluZm8oc2hvcnRbXSBpbmZvKTsJLy8gRm9udEluZm86IHNob3J0WzRdCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTZXRGcmFjdEVuYWJsZShib29sZWFuIGVuYWJsZSk7Ci0JCi0JLy8gTGluZXMgJiBQb2x5Z29ucwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgUGVuU2l6ZShzaG9ydCBoLCBzaG9ydCB2KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIE1vdmVUbyhzaG9ydCBoLCBzaG9ydCB2KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIExpbmVUbyhzaG9ydCBoLCBzaG9ydCB2KTsKLQkKLQkvLyBSZWN0YW5nbGVzCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBFcmFzZVJlY3Qoc2hvcnRbXSBib3VuZHMpOwkvLyByZWN0OiBzaG9ydFs0XQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRnJhbWVSZWN0KHNob3J0W10gYm91bmRzKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFBhaW50UmVjdChzaG9ydFtdIGJvdW5kcyk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBJbnZlcnRSZWN0KHNob3J0IHgsIHNob3J0IHksIHNob3J0IHcsIHNob3J0IGgpOwotCQotCS8vIE92YWxzCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBGcmFtZU92YWwoc2hvcnRbXSBib3VuZHMpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgUGFpbnRPdmFsKHNob3J0W10gYm91bmRzKTsKLQkKLQkvLyBSb3VuZCBSZWN0YW5nbGUKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEZyYW1lUm91bmRSZWN0KHNob3J0W10gYm91bmRzLCBzaG9ydCBvdmFsV2lkdGgsIHNob3J0IG92YWxIZWlnaHQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgUGFpbnRSb3VuZFJlY3Qoc2hvcnRbXSBib3VuZHMsIHNob3J0IG92YWxXaWR0aCwgc2hvcnQgb3ZhbEhlaWdodCk7Ci0JCi0JLy8gUmVnaW9ucwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBOZXdSZ24oKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNldEVtcHR5UmduKGludCByZ25IYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgUmVjdFJnbihpbnQgcmduSGFuZGxlLCBzaG9ydFtdIHJlY3QpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU2V0UmVjdFJnbihpbnQgcmduSGFuZGxlLCBzaG9ydCBsZWZ0LCBzaG9ydCB0b3AsIHNob3J0IHJpZ2h0LCBzaG9ydCBib3R0b20pOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRGlzcG9zZVJnbihpbnQgcmduSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIEVtcHR5UmduKGludCByZ25IYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgR2V0UmVnaW9uQm91bmRzKGludCByZ25IYW5kbGUsIHNob3J0W10gYm91bmRzKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNlY3RSZ24oaW50IHNyY1JnbkEsIGludCBzcmNSZ25CLCBpbnQgZHN0UmduKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFVuaW9uUmduKGludCBzcmNSZ25BLCBpbnQgc3JjUmduQiwgaW50IGRzdFJnbik7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBEaWZmUmduKGludCBzcmNSZ25BLCBpbnQgc3JjUmduQiwgaW50IGRzdFJnbik7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBQdEluUmduKHNob3J0W10gcHQsIGludCByZ25IYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gUmVjdEluUmduKHNob3J0W10gcmVjdCwgaW50IHJnbkhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBDb3B5UmduKGludCBzcmNSZ25IYW5kbGUsIGludCBkc3RSZ25IYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgT2Zmc2V0UmduKGludCByZ25IYW5kbGUsIHNob3J0IGRoLCBzaG9ydCBkdik7Ci0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBFcmFzZVJnbihpbnQgcmduSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEludmVydFJnbihpbnQgcmduSGFuZGxlKTsKLQkKLQkvLyBQb2x5Z29ucwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBPcGVuUG9seSgpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQ2xvc2VQb2x5KCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBPZmZzZXRQb2x5KGludCBwb2x5SGFuZGxlLCBzaG9ydCBkeCwgc2hvcnQgZHkpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRnJhbWVQb2x5KGludCBwb2x5SGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFBhaW50UG9seShpbnQgcG9seUhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBLaWxsUG9seShpbnQgcG9seUhhbmRsZSk7Ci0JCi0KLSAgICAvLyBCaXRNYXBzICYgUGl4TWFwcwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgSW5kZXhlZD0gMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IFJHQkRpcmVjdD0gMTY7Ci0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IE5ld1BpeE1hcChzaG9ydCB3LCBzaG9ydCBoLCBzaG9ydCByb3dCeXRlcywKLQkJCXNob3J0IHBpeGVsVHlwZSwgc2hvcnQgcGl4ZWxTaXplLCBzaG9ydCBjbXBTaXplLCBzaG9ydCBjbXBDb3VudCwgc2hvcnQgcGl4ZWxGb3JtYXQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRGlzcG9zZVBpeE1hcChpbnQgcEhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGR1cGxpY2F0ZVBpeE1hcChpbnQgc3JjUGl4bWFwKTsKLQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgZ2V0Um93Qnl0ZXMoaW50IHBIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgc2V0Um93Qnl0ZXMoaW50IHBIYW5kbGUsIHNob3J0IHJvd0J5dGVzKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0UGl4Um93Qnl0ZXMoaW50IHBIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgR2V0UGl4Qm91bmRzKGludCBwSGFuZGxlLCBzaG9ydFtdIGJvdW5kcyk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBzZXRQaXhCb3VuZHMoaW50IHBIYW5kbGUsIHNob3J0IHRvcCwgc2hvcnQgbGVmdCwgc2hvcnQgYm90dG9tLCBzaG9ydCByaWdodCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgc2hvcnQgR2V0UGl4RGVwdGgoaW50IHBIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBnZXRQaXhIUmVzKGludCBwSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgZ2V0UGl4VlJlcyhpbnQgcEhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGdldEJhc2VBZGRyKGludCBwSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHNldEJhc2VBZGRyKGludCBwSGFuZGxlLCBpbnQgZGF0YSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGdldENvbG9yVGFibGVTaXplKGludCBwSGFuZGxlKTsJLy8gcmV0dXJucyBudW1iZXIgb2Ygc2xvdHMKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIGdldENvbG9yVGFibGUoaW50IHBIYW5kbGUsIHNob3J0W10gY29sb3JTcGVjKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHNldENvbG9yVGFibGUoaW50IHBIYW5kbGUsIHNob3J0W10gY29sb3JTcGVjKTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQ29weUJpdHMoaW50IHNyY1BpeE1hcEhhbmRsZSwgaW50IGRzdFBpeE1hcEhhbmRsZSwgc2hvcnRbXSBzcmNSZWN0LCBzaG9ydFtdIGRzdFJlY3QsCi0JCQkJCQkJCQkJCXNob3J0IG1vZGUsIGludCBtYXNrUmduKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIENvcHlNYXNrKGludCBzcmNQaXhNYXBIYW5kbGUsIGludCBtYXNrUGl4TWFwSGFuZGxlLCBpbnQgZHN0UGl4TWFwSGFuZGxlLAotCQkJCQkJCQkJCQlzaG9ydFtdIHNyY1JlY3QsIHNob3J0W10gbWFza1JlY3QsIHNob3J0W10gZHN0UmVjdCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBDb3B5RGVlcE1hc2soaW50IHNyY1BpeE1hcEhhbmRsZSwgaW50IG1hc2tQaXhNYXBIYW5kbGUsIGludCBkc3RQaXhNYXBIYW5kbGUsCi0JCQkJCQkJCQkJCXNob3J0W10gc3JjUmVjdCwgc2hvcnRbXSBtYXNrUmVjdCwgc2hvcnRbXSBkc3RSZWN0LCBzaG9ydCBtb2RlLCBpbnQgbWFza1Jnbik7Ci0KLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0UG9ydEJpdE1hcEZvckNvcHlCaXRzKGludCBwb3J0SGFuZGxlKTsKLQkKLQkvLyBDSWNvbgotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBOZXdDSWNvbihpbnQgcGl4bWFwSGFuZGxlLCBpbnQgbWFza0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGdldENJY29uSWNvbkRhdGEoaW50IGljb25IYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBnZXRDSWNvbkNvbG9yVGFibGUoaW50IGljb25IYW5kbGUpOwotCi0JLy8gR1dvcmxkcwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBOZXdHV29ybGRGcm9tUHRyKGludFtdIG9mZnNjcmVlbkdXb3JsZCwgaW50IHBIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRGlzcG9zZUdXb3JsZChpbnQgb2Zmc2NyZWVuR1dvcmxkKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNldEdXb3JsZChpbnQgcG9ydEhhbmRsZSwgaW50IGdkSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEdldEdXb3JsZChpbnRbXSBwb3J0SGFuZGxlLCBpbnRbXSBnZEhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldEdEZXZpY2UoKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0TWFpbkRldmljZSgpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBnZXRnZFBNYXAoaW50IGdkSGFuZGxlKTsKLQotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCS8vIFdpbmRvdyBNYW5hZ2VyCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JCi0JLy8gd2luZG93IGNsYXNzCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0FsZXJ0V2luZG93Q2xhc3MgICAgICAgICAgICAgPSAxOyAgIC8qIEkgbmVlZCB5b3VyIGF0dGVudGlvbiBub3cuKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTW92YWJsZUFsZXJ0V2luZG93Q2xhc3MgICAgICA9IDI7ICAgLyogSSBuZWVkIHlvdXIgYXR0ZW50aW9uIG5vdywgYnV0IEknbSBraW5kIGVub3VnaCB0byBsZXQgeW91IHN3aXRjaCBvdXQgb2YgdGhpcyBhcHAgdG8gZG8gb3RoZXIgdGhpbmdzLiovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01vZGFsV2luZG93Q2xhc3MgICAgICAgICAgICAgPSAzOyAgIC8qIHN5c3RlbSBtb2RhbCwgbm90IGRyYWdnYWJsZSovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01vdmFibGVNb2RhbFdpbmRvd0NsYXNzICAgICAgPSA0OyAgIC8qIGFwcGxpY2F0aW9uIG1vZGFsLCBkcmFnZ2FibGUqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtGbG9hdGluZ1dpbmRvd0NsYXNzICAgICAgICAgID0gNTsgICAvKiBmbG9hdHMgYWJvdmUgYWxsIG90aGVyIGFwcGxpY2F0aW9uIHdpbmRvd3MqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEb2N1bWVudFdpbmRvd0NsYXNzICAgICAgICAgID0gNjsgICAvKiBkb2N1bWVudCB3aW5kb3dzKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVXRpbGl0eVdpbmRvd0NsYXNzICAgICAgICAgICA9IDg7ICAgLyogc3lzdGVtLXdpZGUgZmxvYXRpbmcgd2luZG93cyAoVFNNLCBBcHBsZUd1aWRlKSAoYXZhaWxhYmxlIGluIENhcmJvbkxpYiAxLjEpKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrSGVscFdpbmRvd0NsYXNzICAgICAgICAgICAgICA9IDEwOyAgLyogaGVscCB3aW5kb3cgKG5vIGZyYW1lOyBjb2FjaG1hcmtzLCBoZWxwIHRhZ3MgKSAoYXZhaWxhYmxlIGluIENhcmJvbkxpYiAxLjEpKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrU2hlZXRXaW5kb3dDbGFzcyAgICAgICAgICAgICA9IDExOyAgLyogc2hlZXQgd2luZG93cyBmb3IgZGlhbG9ncyAoYXZhaWxhYmxlIGluIE1hYyBPUyBYIGFuZCBDYXJib25MaWIgMS4zKSovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1Rvb2xiYXJXaW5kb3dDbGFzcyAgICAgICAgICAgPSAxMjsgIC8qIHRvb2xiYXIgd2luZG93cyAoYWJvdmUgZG9jdW1lbnRzLCBiZWxvdyBmbG9hdGluZyB3aW5kb3dzKSAoYXZhaWxhYmxlIGluIENhcmJvbkxpYiAxLjEpKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrUGxhaW5XaW5kb3dDbGFzcyAgICAgICAgICAgICA9IDEzOyAgLyogcGxhaW4gd2luZG93IChpbiBkb2N1bWVudCBsYXllcikqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtPdmVybGF5V2luZG93Q2xhc3MgICAgICAgICAgID0gMTQ7ICAvKiB0cmFuc3BhcmVudCB3aW5kb3cgd2hpY2ggYWxsb3dzICdzY3JlZW4nIGRyYXdpbmcgdmlhIENvcmVHcmFwaGljcyAoTWFjIE9TIFggb25seSkqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtTaGVldEFsZXJ0V2luZG93Q2xhc3MgICAgICAgID0gMTU7ICAvKiBzaGVldCB3aW5kb3dzIGZvciBhbGVydHMgKGF2YWlsYWJsZSBpbiBNYWMgT1MgWCBhZnRlciAxMC4wLnggYW5kIENhcmJvbkxpYiAxLjMpKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQWx0UGxhaW5XaW5kb3dDbGFzcyAgICAgICAgICA9IDE2OyAgLyogYWx0ZXJuYXRlIHBsYWluIHdpbmRvdyAoaW4gZG9jdW1lbnQgbGF5ZXIpIChhdmFpbGFibGUgaW4gTWFjIE9TIFggYWZ0ZXIgMTAuMC54IGFuZCBDYXJib25MaWIgMS4zKSovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0FsbFdpbmRvd0NsYXNzZXMgICAgICAgICAgICAgPSAweEZGRkZGRkZGOyAvKiBmb3IgdXNlIHdpdGggR2V0RnJvbnRXaW5kb3dPZkNsYXNzLCBGaW5kV2luZG93T2ZDbGFzcywgR2V0TmV4dFdpbmRvd09mQ2xhc3MqLwotCi0JLy8gd2luZG93IGF0dHJpYnV0ZXMKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93Tm9BdHRyaWJ1dGVzICAgICAgICAgICA9IDA7Ci0JLyogVGhpcyB3aW5kb3cgaGFzIGEgY2xvc2UgYm94LgotCSAqIEF2YWlsYWJsZSBmb3Igd2luZG93cyBvZiBrRG9jdW1lbnRXaW5kb3dDbGFzcywga0Zsb2F0aW5nV2luZG93Q2xhc3MsIGFuZCBrVXRpbGl0eVdpbmRvd0NsYXNzLiAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dDbG9zZUJveEF0dHJpYnV0ZSAgICAgID0gKDEgPDwgMCk7Ci0JLyogVGhpcyB3aW5kb3cgY2hhbmdlcyB3aWR0aCB3aGVuIHpvb21pbmcuCi0JICogQXZhaWxhYmxlIGZvciB3aW5kb3dzIG9mIGtEb2N1bWVudFdpbmRvd0NsYXNzLCBrRmxvYXRpbmdXaW5kb3dDbGFzcywgYW5kIGtVdGlsaXR5V2luZG93Q2xhc3MuICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd0hvcml6b250YWxab29tQXR0cmlidXRlID0gKDEgPDwgMSk7Ci0JLyogVGhpcyB3aW5kb3cgY2hhbmdlcyBoZWlnaHQgd2hlbiB6b29taW5nLgotCSAqIEF2YWlsYWJsZSBmb3Igd2luZG93cyBvZiBrRG9jdW1lbnRXaW5kb3dDbGFzcywga0Zsb2F0aW5nV2luZG93Q2xhc3MsIGFuZCBrVXRpbGl0eVdpbmRvd0NsYXNzLiAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dWZXJ0aWNhbFpvb21BdHRyaWJ1dGUgID0gKDEgPDwgMik7Ci0JLyogVGhpcyB3aW5kb3cgY2hhbmdlcyBib3RoIHdpZHRoIGFuZCBoZWlnaHQgd2hlbiB6b29taW5nLgotCSAqIEF2YWlsYWJsZSBmb3Igd2luZG93cyBvZiBrRG9jdW1lbnRXaW5kb3dDbGFzcywga0Zsb2F0aW5nV2luZG93Q2xhc3MsIGFuZCBrVXRpbGl0eVdpbmRvd0NsYXNzLiAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dGdWxsWm9vbUF0dHJpYnV0ZSA9IChrV2luZG93VmVydGljYWxab29tQXR0cmlidXRlIHwga1dpbmRvd0hvcml6b250YWxab29tQXR0cmlidXRlKTsKLQkvKiBUaGlzIHdpbmRvdyBoYXMgYSBjb2xsYXBzZSBib3guCi0JICogQXZhaWxhYmxlIGZvciB3aW5kb3dzIG9mIGtEb2N1bWVudFdpbmRvd0NsYXNzIGFuZCwgb24gTWFjIE9TIDksIGtGbG9hdGluZ1dpbmRvd0NsYXNzIGFuZAotCSAqIGtVdGlsaXR5V2luZG93Q2xhc3M7IG5vdCBhdmFpbGFibGUgZm9yIHdpbmRvd3Mgb2Yga0Zsb2F0aW5nV2luZG93Q2xhc3Mgb3Iga1V0aWxpdHlXaW5kb3dDbGFzcyBvbiBNYWMgT1MgWC4gKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93Q29sbGFwc2VCb3hBdHRyaWJ1dGUgICA9ICgxIDw8IDMpOwotCS8qIFRoaXMgd2luZG93IGNhbiBiZSByZXNpemVkLgotCSAqIEF2YWlsYWJsZSBmb3Igd2luZG93cyBvZiBrRG9jdW1lbnRXaW5kb3dDbGFzcywga01vdmFibGVNb2RhbFdpbmRvd0NsYXNzLAotCSAqIGtGbG9hdGluZ1dpbmRvd0NsYXNzLCBrVXRpbGl0eVdpbmRvd0NsYXNzLCBhbmQga1NoZWV0V2luZG93Q2xhc3MuICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd1Jlc2l6YWJsZUF0dHJpYnV0ZSAgICAgPSAoMSA8PCA0KTsKLQkvKiBUaGlzIHdpbmRvdyBoYXMgYSB2ZXJ0aWNhbCB0aXRsZWJhciBvbiB0aGUgc2lkZSBvZiB0aGUgd2luZG93LgotCSAqIEF2YWlsYWJsZSBmb3Igd2luZG93cyBvZiBrRmxvYXRpbmdXaW5kb3dDbGFzcyBhbmQga1V0aWxpdHlXaW5kb3dDbGFzcy4gKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93U2lkZVRpdGxlYmFyQXR0cmlidXRlICA9ICgxIDw8IDUpOwotCS8qIFRoaXMgd2luZG93IGhhcyBhIHRvb2xiYXIgYnV0dG9uLgotCSAqIEF2YWlsYWJsZSBmb3Igd2luZG93cyBvZiBrRG9jdW1lbnRXaW5kb3dDbGFzcyBvbiBNYWMgT1MgWC4gKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93VG9vbGJhckJ1dHRvbkF0dHJpYnV0ZSA9ICgxIDw8IDYpOwotCS8qIFRoaXMgd2luZG93IHJlY2VpdmVzIG5vIHVwZGF0ZSBldmVudHMuCi0JICogQXZhaWxhYmxlIGZvciBhbGwgd2luZG93cy4gKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93Tm9VcGRhdGVzQXR0cmlidXRlICAgICA9ICgxIDw8IDE2KTsKLQkvKiBUaGlzIHdpbmRvdyByZWNlaXZlcyBubyBhY3RpdmF0ZSBldmVudHMuCi0JICogQXZhaWxhYmxlIGZvciBhbGwgd2luZG93cy4qLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dOb0FjdGl2YXRlc0F0dHJpYnV0ZSAgID0gKDEgPDwgMTcpOwotCS8qIFRoaXMgd2luZG93IHJlY2VpdmVzIG1vdXNlIGV2ZW50cyBldmVuIGZvciBhcmVhcyBvZiB0aGUgd2luZG93Ci0JICogdGhhdCBhcmUgdHJhbnNwYXJlbnQgKGhhdmUgYW4gYWxwaGEgY2hhbm5lbCBjb21wb25lbnQgb2YgemVybykuCi0JICogQXZhaWxhYmxlIGZvciB3aW5kb3dzIG9mIGtPdmVybGF5V2luZG93Q2xhc3Mgb24gTWFjIE9TIFguKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93T3BhcXVlRm9yRXZlbnRzQXR0cmlidXRlID0gKDEgPDwgMTgpOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dDb21wb3NpdGluZ0F0dHJpYnV0ZSAgID0gKDEgPDwgMTkpOwotCS8qIFRoaXMgd2luZG93IGhhcyBubyBzaGFkb3cuCi0JICogQXZhaWxhYmxlIGZvciBhbGwgd2luZG93cyBvbiBNYWMgT1MgWC4KLQkgKiBUaGlzIGF0dHJpYnV0ZSBpcyBhdXRvbWF0aWNhbGx5IGdpdmVuIHRvIHdpbmRvd3Mgb2Yga092ZXJsYXlXaW5kb3dDbGFzcy4gKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93Tm9TaGFkb3dBdHRyaWJ1dGUgICAgICA9ICgxIDw8IDIxKTsKLQkvKiBUaGlzIHdpbmRvdyBpcyBhdXRvbWF0aWNhbGx5IGhpZGRlbiBvbiBzdXNwZW5kIGFuZCBzaG93biBvbiByZXN1bWUuCi0JICogQXZhaWxhYmxlIGZvciBhbGwgd2luZG93cy4gVGhpcyBhdHRyaWJ1dGUgaXMgYXV0b21hdGljYWxseQotCSAqIGdpdmVuIHRvIHdpbmRvd3Mgb2Yga0Zsb2F0aW5nV2luZG93Q2xhc3MsIGtIZWxwV2luZG93Q2xhc3MsIGFuZAotCSAqIGtUb29sYmFyV2luZG93Q2xhc3MuICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd0hpZGVPblN1c3BlbmRBdHRyaWJ1dGUgPSAoMSA8PCAyNCk7CQotCS8qIFRoaXMgd2luZG93IGhhcyB0aGUgc3RhbmRhcmQgQ2FyYm9uIHdpbmRvdyBldmVudCBoYW5kbGVyIGluc3RhbGxlZC4KLQkgKiBBdmFpbGFibGUgZm9yIGFsbCB3aW5kb3dzLiAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dTdGFuZGFyZEhhbmRsZXJBdHRyaWJ1dGUgPSAoMSA8PCAyNSk7Ci0JLyogVGhpcyB3aW5kb3cgaXMgYXV0b21hdGljYWxseSBoaWRkZW4gZHVyaW5nIGZ1bGxzY3JlZW4gbW9kZSAod2hlbiB0aGUgbWVudWJhciBpcyBpbnZpc2libGUpIGFuZCBzaG93biBhZnRlcndhcmRzLgotCSAqIEF2YWlsYWJsZSBmb3IgYWxsIHdpbmRvd3MuCi0JICogVGhpcyBhdHRyaWJ1dGUgaXMgYXV0b21hdGljYWxseSBnaXZlbiB0byB3aW5kb3dzIG9mIGtVdGlsaXR5V2luZG93Q2xhc3MuICovCSAKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93SGlkZU9uRnVsbFNjcmVlbkF0dHJpYnV0ZSA9ICgxIDw8IDI2KTsJCi0JLyogVGhpcyB3aW5kb3cgaXMgYWRkZWQgdG8gdGhlIHN0YW5kYXJkIFdpbmRvdyBtZW51LgotCSAqIEF2YWlsYWJsZSBmb3Igd2luZG93cyBvZiBrRG9jdW1lbnRXaW5kb3dDbGFzcy4KLQkgKiBUaGlzIGF0dHJpYnV0ZSBpcyBhdXRvbWF0aWNhbGx5IGdpdmVuIHRvIHdpbmRvd3Mgb2Yga0RvY3VtZW50V2luZG93Q2xhc3MuICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd0luV2luZG93TWVudUF0dHJpYnV0ZSAgPSAoMSA8PCAyNyk7Ci0JLyogVGhpcyB3aW5kb3cgc3VwcG9ydHMgbGl2ZSByZXNpemluZy4KLQkgKiBBdmFpbGFibGUgZm9yIGFsbCB3aW5kb3dzIG9uIE1hYyBPUyBYLiAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dMaXZlUmVzaXplQXR0cmlidXRlICAgID0gKDEgPDwgMjgpOwotCS8qIFRoaXMgd2luZG93IHdpbGwgbm90IGJlIHJlcG9zaXRpb25lZCBieSB0aGUgZGVmYXVsdCBrRXZlbnRXaW5kb3dDb25zdHJhaW4KLQkgKiBoYW5kbGVyIGluIHJlc3BvbnNlIHRvIGNoYW5nZXMgaW4gbW9uaXRvciBzaXplLCBEb2NrIHBvc2l0aW9uLCBhbmQgc28gb24uCi0JICogQXZhaWxhYmxlIGZvciBhbGwgd2luZG93cyBvbiBNYWMgT1MgWCBhZnRlciAxMC4wLnguICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd05vQ29uc3RyYWluQXR0cmlidXRlICAgPSAoMSA8PCAzMSk7Ci0JLyogVGhlIG1pbmltdW0gc2V0IG9mIHdpbmRvdyBhdHRyaWJ1dGVzIGNvbW1vbmx5IHVzZWQgYnkgZG9jdW1lbnQgd2luZG93cy4gKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93U3RhbmRhcmREb2N1bWVudEF0dHJpYnV0ZXMgPSAoa1dpbmRvd0Nsb3NlQm94QXR0cmlidXRlIHwga1dpbmRvd0Z1bGxab29tQXR0cmlidXRlIHwga1dpbmRvd0NvbGxhcHNlQm94QXR0cmlidXRlIHwga1dpbmRvd1Jlc2l6YWJsZUF0dHJpYnV0ZSk7Ci0JLyogVGhlIG1pbmltdW0gc2V0IG9mIHdpbmRvdyBhdHRyaWJ1dGVzIGNvbW1vbmx5IHVzZWQgYnkgZmxvYXRpbmcgd2luZG93cy4gKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93U3RhbmRhcmRGbG9hdGluZ0F0dHJpYnV0ZXMgPSAoa1dpbmRvd0Nsb3NlQm94QXR0cmlidXRlIHwga1dpbmRvd0NvbGxhcHNlQm94QXR0cmlidXRlKTsKLQkKLQkvLyB3aW5kb3cgbW9kYWxpdHkKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrUURVc2VDR1RleHRSZW5kZXJpbmcgPSAoMSA8PCAxKTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrU2NyYXBGbGF2b3JUeXBlVGV4dCA9ICgnVCc8PDI0KSArICgnRSc8PDE2KSArICgnWCc8PDgpICsgJ1QnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBrU2Nyb2xsQmFyc1N5bmNBbHdheXNBY3RpdmUgPSB0cnVlOworCXB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBrU2Nyb2xsQmFyc1N5bmNXaXRoRm9jdXMgPSBmYWxzZTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrU2hlZXRXaW5kb3dDbGFzcyA9IDExOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtTdGRDRlN0cmluZ0FsZXJ0VmVyc2lvbk9uZSA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xTbGlkZXJEb2VzTm90UG9pbnQgPSAyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUWE5BbHdheXNXcmFwQXRWaWV3RWRnZU1hc2sgPSAxIDw8IDExOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUWE5EaXNhYmxlRHJhZ0FuZERyb3BUYWcgPSAoJ2QnPDwyNCkgKyAoJ3InPDwxNikgKyAoJ2EnPDw4KSArICdnJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhORG9Gb250U3Vic3RpdHV0aW9uID0gKCdmJzw8MjQpICsgKCdzJzw8MTYpICsgKCd1Jzw8OCkgKyAnYic7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RYTkRvbnREcmF3Q2FyZXRXaGVuSW5hY3RpdmVNYXNrID0gMSA8PCAxMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhORW5kT2Zmc2V0ID0gMjE0NzQ4MzY0NzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOTWFyZ2luc1RhZyA9ICgnbSc8PDI0KSArICgnYSc8PDE2KSArICgncic8PDgpICsgJ2cnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUWE5Nb25vc3R5bGVkVGV4dE1hc2sgPSAxIDw8IDE3OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUWE5SZWFkT25seU1hc2sgPSAxIDw8IDU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RYTlNpbmdsZUxpbmVPbmx5TWFzayA9IDEgPDwgMTQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RYTlN0YXJ0T2Zmc2V0ID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOU3lzdGVtRGVmYXVsdEVuY29kaW5nID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOVGV4dEVkaXRTdHlsZUZyYW1lVHlwZSA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RYTlVuaWNvZGVUZXh0RGF0YSA9ICgndSc8PDI0KSArICgndCc8PDE2KSArICgneCc8PDgpICsgJ3QnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUWE5Vbmljb2RlVGV4dEZpbGUgPSAoJ3UnPDwyNCkgKyAoJ3QnPDwxNikgKyAoJ3gnPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOVXNlQ3VycmVudFNlbGVjdGlvbiA9IC0xOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUWE5WaXNpYmlsaXR5VGFnID0gKCd2Jzw8MjQpICsgKCdpJzw8MTYpICsgKCdzJzw8OCkgKyAnYic7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RYTldhbnRIU2Nyb2xsQmFyTWFzayA9IDEgPDwgMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOV2FudFZTY3JvbGxCYXJNYXNrID0gMSA8PCAzOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZUFycm93QnV0dG9uID0gNDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVBcnJvd0N1cnNvciA9IDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lQnJ1c2hEaWFsb2dCYWNrZ3JvdW5kQWN0aXZlID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVCcnVzaERvY3VtZW50V2luZG93QmFja2dyb3VuZCA9IDE1OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZUJydXNoUHJpbWFyeUhpZ2hsaWdodENvbG9yID0gLTM7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lQnJ1c2hTZWNvbmRhcnlIaWdobGlnaHRDb2xvciA9IC00OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZUJydXNoQnV0dG9uRmFjZUFjdGl2ZSA9IDI5OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZUJydXNoRm9jdXNIaWdobGlnaHQgPSAxOTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVCcnVzaExpc3RWaWV3QmFja2dyb3VuZCA9IDEwOyAKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVCdXR0b25PZmYgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZUJ1dHRvbk9uID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVDaGVja0JveCA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lQ3Jvc3NDdXJzb3IgPSA1OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZUN1cnJlbnRQb3J0Rm9udCA9IDIwMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVEaXNjbG9zdXJlQnV0dG9uID0gNjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVEaXNjbG9zdXJlUmlnaHQgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZURpc2Nsb3N1cmVEb3duID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVEaXNjbG9zdXJlTGVmdCA9IDI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lRW1waGFzaXplZFN5c3RlbUZvbnQgPSA0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZUlCZWFtQ3Vyc29yID0gNDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVNZXRyaWNEaXNjbG9zdXJlVHJpYW5nbGVIZWlnaHQgPSAyNTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVNZXRyaWNDaGVja0JveFdpZHRoID0gNTA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lTWV0cmljUmFkaW9CdXR0b25XaWR0aCA9IDUyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZU1ldHJpY0VkaXRUZXh0RnJhbWVPdXRzZXQgPSA1OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZU1ldHJpY0ZvY3VzUmVjdE91dHNldCA9IDc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lTWV0cmljSFNsaWRlckhlaWdodCA9IDQxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZU1ldHJpY05vcm1hbFByb2dyZXNzQmFyVGhpY2tuZXNzID0gNTg7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lTWV0cmljU2Nyb2xsQmFyV2lkdGggPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZU1ldHJpY1ZTbGlkZXJXaWR0aCA9IDQ1OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZU5vdEFsbG93ZWRDdXJzb3IgPSAxODsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVQb2ludGluZ0hhbmRDdXJzb3IgPSAxMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVQdXNoQnV0dG9uID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVQdXNoQnV0dG9uRm9udCA9IDEwNTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVSYWRpb0J1dHRvbiA9IDI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lUmVzaXplTGVmdFJpZ2h0Q3Vyc29yID0gMTc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lUmVzaXplTGVmdEN1cnNvciA9IDE1OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZVJlc2l6ZVJpZ2h0Q3Vyc29yID0gMTY7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lUm91bmRlZEJldmVsQnV0dG9uID0gMTU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lU21hbGxCZXZlbEJ1dHRvbiA9IDg7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lU21hbGxFbXBoYXNpemVkU3lzdGVtRm9udCA9IDI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RoZW1lU21hbGxTeXN0ZW1Gb250ID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVTcGlubmluZ0N1cnNvciA9IDE0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZVN0YXRlQWN0aXZlID0gMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVTdGF0ZUluYWN0aXZlID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVTdGF0ZVByZXNzZWQgPSAyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZVN5c3RlbUZvbnQgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZVRleHRDb2xvckRvY3VtZW50V2luZG93VGl0bGVBY3RpdmUgPSAyMzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVUZXh0Q29sb3JEb2N1bWVudFdpbmRvd1RpdGxlSW5hY3RpdmUgPSAyNDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVUZXh0Q29sb3JMaXN0VmlldyA9IDIyOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZVRleHRDb2xvclB1c2hCdXR0b25BY3RpdmUgPSAxMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVUb29sYmFyRm9udCA9IDEwODsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVGhlbWVWaWV3c0ZvbnQgPSAzOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUaGVtZVdhdGNoQ3Vyc29yID0gNzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVHJhbnNmb3JtU2VsZWN0ZWQgPSAweDQwMDA7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1V0aWxpdHlXaW5kb3dDbGFzcyA9IDg7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd0FjdGl2YXRpb25TY29wZU5vbmUgPSAwOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dBY3RpdmF0aW9uU2NvcGVJbmRlcGVuZGVudCA9IDE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd0FjdGl2YXRpb25TY29wZUFsbCA9IDI7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd0FsZXJ0UG9zaXRpb25QYXJlbnRXaW5kb3dTY3JlZW4gPSAweDcwMEE7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd0JvdW5kc0NoYW5nZU9yaWdpbkNoYW5nZWQgPSAxPDwzOworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dCb3VuZHNDaGFuZ2VTaXplQ2hhbmdlZCA9IDE8PDI7CisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd0Nhc2NhZGVPbk1haW5TY3JlZW4gPSA0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dDbG9zZUJveEF0dHJpYnV0ZSA9ICgxIDw8IDApOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dDb2xsYXBzZUJveEF0dHJpYnV0ZSA9ICgxIDw8IDMpOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dDb21wb3NpdGluZ0F0dHJpYnV0ZSA9ICgxIDw8IDE5KTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93Q29udGVudFJnbiA9IDMzOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dHcm91cEF0dHJIaWRlT25Db2xsYXBzZSA9IDE2OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dIb3Jpem9udGFsWm9vbUF0dHJpYnV0ZSA9IDEgPDwgMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93VmVydGljYWxab29tQXR0cmlidXRlICA9IDEgPDwgMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93RnVsbFpvb21BdHRyaWJ1dGUgPSAoT1Mua1dpbmRvd1ZlcnRpY2FsWm9vbUF0dHJpYnV0ZSB8IE9TLmtXaW5kb3dIb3Jpem9udGFsWm9vbUF0dHJpYnV0ZSk7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd0xpdmVSZXNpemVBdHRyaWJ1dGUgPSAoMSA8PCAyOCk7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd01vZGFsaXR5QXBwTW9kYWwgPSAyOwogCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dNb2RhbGl0eU5vbmUgPSAwOwogCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dNb2RhbGl0eVN5c3RlbU1vZGFsID0gMTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93TW9kYWxpdHlBcHBNb2RhbCA9IDI7CiAJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd01vZGFsaXR5V2luZG93TW9kYWwgPSAzOwotCQotCS8vIFNjcm9sbFdpbmRvd09wdGlvbnMKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrU2Nyb2xsV2luZG93Tm9PcHRpb25zPSAwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtTY3JvbGxXaW5kb3dJbnZhbGlkYXRlPSAxOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtTY3JvbGxXaW5kb3dFcmFzZVRvUG9ydEJhY2tncm91bmQ9IDI7Ci0JCi0JLy8gUmVnaW9uIHZhbHVlcyB0byBwYXNzIGludG8gR2V0V2luZG93UmVnaW9uICYgR2V0V2luZG93Qm91bmRzCi0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtXaW5kb3dUaXRsZUJhclJnbiAgICAgICAgICAgID0gMDsKLQkvL3B1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1dpbmRvd1RpdGxlVGV4dFJnbiAgICAgICAgICAgPSAxOwotCS8vcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrV2luZG93Q2xvc2VCb3hSZ24gICAgICAgICAgICA9IDI7Ci0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtXaW5kb3dab29tQm94UmduICAgICAgICAgICAgID0gMzsKLQkvL3B1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1dpbmRvd0RyYWdSZ24gICAgICAgICAgICAgICAgPSA1OwotCS8vcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrV2luZG93R3Jvd1JnbiAgICAgICAgICAgICAgICA9IDY7Ci0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtXaW5kb3dDb2xsYXBzZUJveFJnbiAgICAgICAgID0gNzsKLQkvL3B1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1dpbmRvd1RpdGxlUHJveHlJY29uUmduICAgICAgPSA4OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1dpbmRvd1N0cnVjdHVyZVJnbiAgICAgICAgICAgPSAzMjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtXaW5kb3dDb250ZW50UmduICAgICAgICAgICAgID0gMzM7ICAgLyogQ29udGVudCBhcmVhIG9mIHRoZSB3aW5kb3c7IGVtcHR5IHdoZW4gdGhlIHdpbmRvdyBpcyBjb2xsYXBzZWQqLwotCS8vcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrV2luZG93VXBkYXRlUmduICAgICAgICAgICAgICA9IDM0OyAgIC8qIENhcmJvbiBmb3J3YXJkKi8KLQkvL3B1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga1dpbmRvd09wYXF1ZVJnbiAgICAgICAgICAgICAgPSAzNTsgICAvKiBNYWMgT1MgWDogQXJlYSBvZiB3aW5kb3cgY29uc2lkZXJlZCB0byBiZSBvcGFxdWUuIE9ubHkgdmFsaWQgZm9yIHdpbmRvd3Mgd2l0aCBhbHBoYSBjaGFubmVscy4qLwotCS8vcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrV2luZG93R2xvYmFsUG9ydFJnbiAgICAgICAgICA9IDQwOyAgICAvKiBDYXJib24gZm9yd2FyZCAtIGJvdW5kcyBvZiB0aGUgd2luZG931XMgcG9ydCBpbiBnbG9iYWwgY29vcmRpbmF0ZXM7IG5vdCBhZmZlY3RlZCBieSBDb2xsYXBzZVdpbmRvdyovCisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1dpbmRvd05vU2hhZG93QXR0cmlidXRlID0gKDEgPDwgMjEpOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dSZXNpemFibGVBdHRyaWJ1dGUgPSAoMSA8PCA0KTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrV2luZG93U3RhbmRhcmRIYW5kbGVyQXR0cmlidXRlID0gKDEgPDwgMjUpOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtXaW5kb3dTdHJ1Y3R1cmVSZ24gPSAzMjsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBtb3VzZURvd24gPSAxOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IG5vRXJyID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBub3JtYWwgPSAwOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IG9wdGlvbktleSA9IDEgPDwgMTE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2hpZnRLZXkgPSAxIDw8IDk7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc21TeXN0ZW1TY3JpcHQgPSAtMTsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzcmNDb3B5ID0gMDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzcmNPciA9IDE7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgdHlwZUNHQ29udGV4dFJlZj0gKCdjJzw8MjQpICsgKCduJzw8MTYpICsgKCd0Jzw8OCkgKyAneCc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgdHlwZUNoYXIgPSAoJ1QnPDwyNCkgKyAoJ0UnPDwxNikgKyAoJ1gnPDw4KSArICdUJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlQ29udHJvbFBhcnRDb2RlID0gKCdjJzw8MjQpICsgKCdwJzw8MTYpICsgKCdyJzw8OCkgKyAndCc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgdHlwZUNvbnRyb2xSZWYgPSAoJ2MnPDwyNCkgKyAoJ3QnPDwxNikgKyAoJ3InPDw4KSArICdsJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlRmlsZVVSTD0gKCdmJzw8MjQpICsgKCd1Jzw8MTYpICsgKCdyJzw8OCkgKyAnbCc7CQorCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVGU1JlZiA9ICgnZic8PDI0KSArICgncyc8PDE2KSArICgncic8PDgpICsgJ2YnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVISUNvbW1hbmQgPSAoJ2gnPDwyNCkgKyAoJ2MnPDwxNikgKyAoJ20nPDw4KSArICdkJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlSElQb2ludCA9ICgnaCc8PDI0KSArICgnaSc8PDE2KSArICgncCc8PDgpICsgJ3QnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVNZW51UmVmID0gKCdtJzw8MjQpICsgKCdlJzw8MTYpICsgKCduJzw8OCkgKyAndSc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgdHlwZU1vdXNlQnV0dG9uID0gKCdtJzw8MjQpICsgKCdiJzw8MTYpICsgKCd0Jzw8OCkgKyAnbic7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgdHlwZVFEUG9pbnQgPSAoJ1EnPDwyNCkgKyAoJ0QnPDwxNikgKyAoJ3AnPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlUURSZWN0YW5nbGUgPSAoJ3EnPDwyNCkgKyAoJ2QnPDwxNikgKyAoJ3InPDw4KSArICd0JzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlUURSZ25IYW5kbGUgPSAoJ3InPDwyNCkgKyAoJ2cnPDwxNikgKyAoJ24nPDw4KSArICdoJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlUkdCQ29sb3IgPSAoJ2MnPDwyNCkgKyAoJ1InPDwxNikgKyAoJ0cnPDw4KSArICdCJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCB0eXBlU0ludDE2ID0gKCdzJzw8MjQpICsgKCdoJzw8MTYpICsgKCdvJzw8OCkgKyAncic7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgdHlwZVNJbnQzMiA9ICgnbCc8PDI0KSArICgnbyc8PDE2KSArICgnbic8PDgpICsgJ2cnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVUeXBlID0gKCd0Jzw8MjQpICsgKCd5Jzw8MTYpICsgKCdwJzw8OCkgKyAnZSc7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgdHlwZVVJbnQzMiA9ICgnbSc8PDI0KSArICgnYSc8PDE2KSArICgnZyc8PDgpICsgJ24nOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVVbmljb2RlVGV4dCA9ICgndSc8PDI0KSArICgndCc8PDE2KSArICgneCc8PDgpICsgJ3QnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVXaW5kb3dEZWZQYXJ0Q29kZSA9ICgndyc8PDI0KSArICgnZCc8PDE2KSArICgncCc8PDgpICsgJ3QnOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHR5cGVXaW5kb3dSZWYgPSAoJ3cnPDwyNCkgKyAoJ2knPDwxNikgKyAoJ24nPDw4KSArICdkJzsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCB1cGRhdGVFdnQgPSA2OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHVwZGF0ZU1hc2sgPSAxIDw8IHVwZGF0ZUV2dDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCB1c2VyQ2FuY2VsZWRFcnIgPSAtMTI4OwogCi0JCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBDcmVhdGVOZXdXaW5kb3coaW50IHdpbmRvd0NsYXNzLCBpbnQgYXR0cmlidXRlcywgc2hvcnRbXSBib3VuZHMsIGludFtdIHdIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRXaW5kb3dQb3J0KGludCB3SGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEJlZ2luVXBkYXRlKGludCB3SGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEVuZFVwZGF0ZShpbnQgd0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBEcmF3Q29udHJvbHMoaW50IHdIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgVXBkYXRlQ29udHJvbHMoaW50IHdIYW5kbGUsIGludCByZ25IYW5kbGUpOwotCS8vcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBEcmF3R3Jvd0ljb24oaW50IHdIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU2V0UG9ydFdpbmRvd1BvcnQoaW50IHdIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBGcm9udFdpbmRvdygpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBGcm9udE5vbkZsb2F0aW5nV2luZG93KCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTZWxlY3RXaW5kb3coaW50IHdIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQWN0aXZhdGVXaW5kb3coaW50IHdIYW5kbGUsIGJvb2xlYW4gYWN0aXZhdGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQnJpbmdUb0Zyb250KGludCB3SGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBzaG9ydCBGaW5kV2luZG93KHNob3J0W10gd2hlcmUsIGludFtdIHdIYW5kbGUpOwotCS8vcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBSZXNpemVXaW5kb3coaW50IHdIYW5kbGUsIHNob3J0W10gc3RhcnRQdCwgc2hvcnRbXSBzaXplQ29uc3RyYWludHMsIHNob3J0W10gbmV3Q29udGVudFJlY3QpOwotCS8vcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBEcmFnV2luZG93KGludCB3SGFuZGxlLCBzaG9ydFtdIHN0YXJ0UHQsIHNob3J0W10gYm91bmRzUmVjdCk7Ci0JLy9wdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEdldFdpbmRvd1BvcnRCb3VuZHMoaW50IHdIYW5kbGUsIHNob3J0W10gYm91bmRzKTsKLQkvL3B1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gVHJhY2tHb0F3YXkoaW50IHdIYW5kbGUsIHNob3J0W10gc3RhcnRQdCk7Ci0JLy9wdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIFRyYWNrQm94KGludCB3SGFuZGxlLCBzaG9ydFtdIHN0YXJ0UHQsIHNob3J0IHBhcnQpOwotCS8vcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBab29tV2luZG93KGludCB3SGFuZGxlLCBzaG9ydCBwYXJ0LCBib29sZWFuIHRvRnJvbnQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRGlzcG9zZVdpbmRvdyhpbnQgd0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBJbnZhbFdpbmRvd1JlY3QoaW50IHdIYW5kbGUsIHNob3J0W10gYm91bmRzKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEludmFsV2luZG93UmduKGludCB3SGFuZGxlLCBpbnQgcmduSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNob3dXaW5kb3coaW50IHdIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgSGlkZVdpbmRvdyhpbnQgd0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNob3dTaGVldFdpbmRvdyhpbnQgd0hhbmRsZSwgaW50IHBhcmVudGhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEhpZGVTaGVldFdpbmRvdyhpbnQgd0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTZXRXaW5kb3dCb3VuZHMoaW50IHdIYW5kbGUsIHNob3J0IHdpbmRvd1JlZ2lvbiwgc2hvcnRbXSBib3VuZHMpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgR2V0V2luZG93Qm91bmRzKGludCB3SGFuZGxlLCBzaG9ydCB3aW5kb3dSZWdpb24sIHNob3J0W10gYm91bmRzKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIElzVmFsaWRXaW5kb3dQdHIoaW50IGdyYWZQb3J0KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0V1JlZkNvbihpbnQgd0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTZXRXUmVmQ29uKGludCB3SGFuZGxlLCBpbnQgZGF0YSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTaXplV2luZG93KGludCB3SGFuZGxlLCBzaG9ydCB3LCBzaG9ydCBoLCBib29sZWFuIHVwZGF0ZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBNb3ZlV2luZG93KGludCB3SGFuZGxlLCBzaG9ydCBoLCBzaG9ydCB2LCBib29sZWFuIHRvRnJvbnQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU2Nyb2xsV2luZG93UmVjdChpbnQgd0hhbmRsZSwgc2hvcnRbXSByZWN0LCBzaG9ydCBkeCwgc2hvcnQgZHksIGludCBvcHRpb25zLCBpbnQgZXhwb3NlZFJnbik7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IENvcHlXaW5kb3dUaXRsZUFzQ0ZTdHJpbmcoaW50IHdIYW5kbGUsIGludFtdIHNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRXaW5kb3dUaXRsZVdpdGhDRlN0cmluZyhpbnQgd0hhbmRsZSwgaW50IHNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gSXNXaW5kb3dWaXNpYmxlKGludCB3SGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0V2luZG93RGVmYXVsdEJ1dHRvbihpbnQgd0hhbmRsZSwgaW50IGNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRXaW5kb3dEZWZhdWx0QnV0dG9uKGludCB3SGFuZGxlLCBpbnRbXSBjSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0V2luZG93TW9kYWxpdHkoaW50IHdIYW5kbGUsIGludFtdIG1vZGFsaXR5S2luZCwgaW50W10gdW5hdmFpbGFibGVXaW5kb3dIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRXaW5kb3dNb2RhbGl0eShpbnQgd0hhbmRsZSwgaW50IG1vZGFsaXR5S2luZCwgaW50IHVuYXZhaWxhYmxlV2luZG93SGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgQ29sbGFwc2VXaW5kb3coaW50IHdIYW5kbGUsIGJvb2xlYW4gY29sbGFwc2UpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gSXNXaW5kb3dBY3RpdmUoaW50IHdIYW5kbGUpOwotCQotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCS8vIE1lbnUgTWFuYWdlcgotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCQotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtNZW51SXRlbUF0dHJEaXNhYmxlZCA9IDE7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga01lbnVJdGVtQXR0clNlcGFyYXRvciA9IDY0OwotCQotCS8vIG1lbnUgaXRlbSBtYXJrIGNoYXJhY3RlcnMKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGNoYXIgY2hlY2tNYXJrPSAoY2hhcikxODsJLy8gZm9yIFNXVC5DSEVDSwotCXB1YmxpYyBzdGF0aWMgZmluYWwgY2hhciBkaWFtb25kTWFyaz0gKGNoYXIpMTk7CS8vIGZvciBTV1QuUkFESU8KLQkKLQkvLyBtZW51IGdseXBocwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVOdWxsR2x5cGggPSAwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVUYWJSaWdodEdseXBoID0gMjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51VGFiTGVmdEdseXBoID0gMzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RW50ZXJHbHlwaCA9IDQ7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudVNoaWZ0R2x5cGggPSA1OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVDb250cm9sR2x5cGggPSA2OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVPcHRpb25HbHlwaCA9IDc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudVNwYWNlR2x5cGggPSA5OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVEZWxldGVSaWdodEdseXBoID0gMTA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudVJldHVybkdseXBoID0gMTE7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudVJldHVyblIyTEdseXBoID0gMTI7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudU5vbm1hcmtpbmdSZXR1cm5HbHlwaCA9IDEzOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVQZW5jaWxHbHlwaCA9IDE1OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVEb3dud2FyZEFycm93RGFzaGVkR2x5cGggPSAxNjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51Q29tbWFuZEdseXBoID0gMTc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudUNoZWNrbWFya0dseXBoID0gMTg7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudURpYW1vbmRHbHlwaCA9IDE5OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVBcHBsZUxvZ29GaWxsZWRHbHlwaCA9IDIwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVQYXJhZ3JhcGhLb3JlYW5HbHlwaCA9IDIxOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVEZWxldGVMZWZ0R2x5cGggPSAyMzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51TGVmdEFycm93RGFzaGVkR2x5cGggPSAyNDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51VXBBcnJvd0Rhc2hlZEdseXBoID0gMjU7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudVJpZ2h0QXJyb3dEYXNoZWRHbHlwaCA9IDI2OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVFc2NhcGVHbHlwaCA9IDI3OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVDbGVhckdseXBoID0gMjg7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudUxlZnREb3VibGVRdW90ZXNKYXBhbmVzZUdseXBoID0gMjk7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudVJpZ2h0RG91YmxlUXVvdGVzSmFwYW5lc2VHbHlwaCA9IDMwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVUcmFkZW1hcmtKYXBhbmVzZUdseXBoID0gMzE7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudUJsYW5rR2x5cGggPSA5NzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51UGFnZVVwR2x5cGggPSA5ODsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51Q2Fwc0xvY2tHbHlwaCA9IDk5OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVMZWZ0QXJyb3dHbHlwaCA9IDEwMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51UmlnaHRBcnJvd0dseXBoID0gMTAxOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVOb3J0aHdlc3RBcnJvd0dseXBoID0gMTAyOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVIZWxwR2x5cGggPSAxMDM7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudVVwQXJyb3dHbHlwaCA9IDEwNDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51U291dGhlYXN0QXJyb3dHbHlwaCA9IDEwNTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RG93bkFycm93R2x5cGggPSAxMDY7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudVBhZ2VEb3duR2x5cGggPSAxMDc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudUFwcGxlTG9nb091dGxpbmVHbHlwaCA9IDEwODsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51Q29udGV4dHVhbE1lbnVHbHlwaCA9IDEwOTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51UG93ZXJHbHlwaCA9IDExMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RjFHbHlwaCA9IDExMTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RjJHbHlwaCA9IDExMjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RjNHbHlwaCA9IDExMzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RjRHbHlwaCA9IDExNDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RjVHbHlwaCA9IDExNTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RjZHbHlwaCA9IDExNjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RjdHbHlwaCA9IDExNzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RjhHbHlwaCA9IDExODsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RjlHbHlwaCA9IDExOTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RjEwR2x5cGggPSAxMjA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudUYxMUdseXBoID0gMTIxOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVGMTJHbHlwaCA9IDEyMjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51RjEzR2x5cGggPSAxMzU7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrTWVudUYxNEdseXBoID0gMTM2OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga01lbnVGMTVHbHlwaCA9IDEzNzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtNZW51Q29udHJvbElTT0dseXBoID0gMTM4OworLyoqIE5hdGl2ZXMgKi8KK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBrSElWaWV3V2luZG93Q29udGVudElEKCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQWN0aXZlTm9uRmxvYXRpbmdXaW5kb3coKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBBRUNvdW50SXRlbXMoQUVEZXNjIHRoZUFFRGVzY0xpc3QsIGludFtdIHRoZUNvdW50KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBBRUdldE50aFB0cihBRURlc2MgdGhlQUVEZXNjTGlzdCwgaW50IGluZGV4LCBpbnQgZGVzaXJlZFR5cGUsIGludFtdIHRoZUFFS2V5d29yZCwgaW50W10gdHlwZUNvZGUsIGludCBkYXRhUHRyLCBpbnQgbWF4aW11bVNpemUsIGludFtdIGFjdHVhbFNpemUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEFFUHJvY2Vzc0FwcGxlRXZlbnQoRXZlbnRSZWNvcmQgdGhlRXZlbnRSZWNvcmQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEFUU1VDcmVhdGVTdHlsZShpbnRbXSBvU3R5bGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEFUU1VDcmVhdGVUZXh0TGF5b3V0KGludFtdIG9UZXh0TGF5b3V0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBBVFNVRGlzcG9zZVN0eWxlKGludCBpU3R5bGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEFUU1VEaXNwb3NlVGV4dExheW91dChpbnQgaVRleHRMYXlvdXQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEFUU1VEcmF3VGV4dChpbnQgaVRleHRMYXlvdXQsIGludCBpTGluZU9mZnNldCwgaW50IGlMaW5lTGVuZ3RoLCBpbnQgaUxvY2F0aW9uWCwgaW50IGlMb2NhdGlvblkpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEFUU1VHZXRHbHlwaEJvdW5kcyhpbnQgaVRleHRMYXlvdXQsIGludCBpVGV4dEJhc2VQb2ludFgsIGludCBpVGV4dEJhc2VQb2ludFksIGludCBpQm91bmRzQ2hhclN0YXJ0LCBpbnQgaUJvdW5kc0NoYXJMZW5ndGgsIHNob3J0IGlUeXBlT2ZCb3VuZHMsIGludCBpTWF4TnVtYmVyT2ZCb3VuZHMsIGludCBvR2x5cGhCb3VuZHMsIGludFtdIG9BY3R1YWxOdW1iZXJPZkJvdW5kcyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQVRTVVNldEF0dHJpYnV0ZXMoaW50IGlTdHlsZSwgaW50IGlBdHRyaWJ1dGVDb3VudCwgaW50W10gaVRhZywgaW50W10gaVZhbHVlU2l6ZSwgaW50W10gaVZhbHVlKTsgCitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQVRTVVNldExheW91dENvbnRyb2xzKGludCBpVGV4dExheW91dCwgaW50IGlBdHRyaWJ1dGVDb3VudCwgaW50W10gaVRhZywgaW50W10gaVZhbHVlU2l6ZSwgaW50W10gaVZhbHVlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBBVFNVU2V0UnVuU3R5bGUoaW50IGlUZXh0TGF5b3V0LCBpbnQgaVN0eWxlLCBpbnQgaVJ1blN0YXJ0LCBpbnQgaVJ1bkxlbmd0aCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQVRTVVNldFRleHRQb2ludGVyTG9jYXRpb24oaW50IGlUZXh0TGF5b3V0LCBpbnQgaVRleHQsIGludCBpVGV4dE9mZnNldCwgaW50IGlUZXh0TGVuZ3RoLCBpbnQgaVRleHRUb3RhbExlbmd0aCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQWRkRGF0YUJyb3dzZXJJdGVtcyhpbnQgY0hhbmRsZSwgaW50IGNvbnRhaW5lcklELCBpbnQgbnVtSXRlbXMsIGludFtdIGl0ZW1JRHMsIGludCBwcmVTb3J0UHJvcGVydHkpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEFkZERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW4oaW50IGJyb3dzZXIsIERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjIGNvbHVtbkRlc2MsIGludCBwb3NpdGlvbik7ICAKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBBcHBlbmRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcoaW50IG1IYW5kbGUsIGludCBzSGFuZGxlLCBpbnQgYXR0cmlidXRlcywgaW50IGNvbW1hbmRJRCwgc2hvcnRbXSBvdXRJdGVtSW5kZXgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEF1dG9TaXplRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbnMoaW50IGNIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBCZWdpblVwZGF0ZShpbnQgd0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIEJyaW5nVG9Gcm9udChpbnQgd0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENGUmVsZWFzZShpbnQgc0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ0ZTdHJpbmdDcmVhdGVXaXRoQnl0ZXMoaW50IGFsbG9jLCBieXRlW10gYnl0ZXMsIGludCBudW1CeXRlcywgaW50IGVuY29kaW5nLCBib29sZWFuIGlzRXh0ZXJuYWxSZXByZXNlbnRhdGlvbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyhpbnQgYWxsb2MsIGNoYXJbXSBjaGFycywgaW50IG51bUNoYXJzKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDRlN0cmluZ0dldEJ5dGVzKGludCB0aGVTdHJpbmcsIENGUmFuZ2UgcmFuZ2UsIGludCBlbmNvZGluZywgYnl0ZSBsb3NzQnl0ZSwgYm9vbGVhbiBpc0V4dGVybmFsUmVwcmVzZW50YXRpb24sIGJ5dGVbXSBidWZmZXIsIGludCBtYXhCdWZMZW4sIGludFtdIHVzZWRCdWZMZW4pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDRlN0cmluZ0dldENoYXJhY3RlcnMoaW50IHRoZVN0cmluZywgQ0ZSYW5nZSByYW5nZSwgY2hhcltdIGJ1ZmZlcik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ0ZTdHJpbmdHZXRMZW5ndGgoaW50IHRoZVN0cmluZyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ0ZTdHJpbmdHZXRTeXN0ZW1FbmNvZGluZygpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENGVVJMQ29weUZpbGVTeXN0ZW1QYXRoKGludCBhblVSTCwgaW50IHBhdGhTdHlsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ0ZVUkxDb3B5TGFzdFBhdGhDb21wb25lbnQoaW50IHVybCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ0ZVUkxDcmVhdGVDb3B5QXBwZW5kaW5nUGF0aENvbXBvbmVudChpbnQgYWxsb2NhdG9yLCBpbnQgdXJsLCBpbnQgcGF0aENvbXBvbmVudCwgYm9vbGVhbiBpc0RpcmVjdG9yeSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ0ZVUkxDcmVhdGVDb3B5RGVsZXRpbmdMYXN0UGF0aENvbXBvbmVudChpbnQgYWxsb2NhdG9yLCBpbnQgdXJsKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDRlVSTENyZWF0ZUZyb21GU1JlZihpbnQgYWxsb2NhdG9yLCBieXRlW10gZnNSZWYpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDR0NvbnRleHRTY2FsZUNUTShpbnQgaW5Db250ZXh0LCBmbG9hdCBzeCwgZmxvYXQgc3kpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDR0NvbnRleHRUcmFuc2xhdGVDVE0oaW50IGluQ29udGV4dCwgZmxvYXQgdHgsIGZsb2F0IHR5KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDR0JpdG1hcENvbnRleHRDcmVhdGUoaW50IGRhdGEsIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGJpdHNQZXJDb21wb25lbnQsIGludCBieXRlc1BlclJvdywgaW50IGNvbG9yc3BhY2UsIGludCBhbHBoYUluZm8pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENHQ29sb3JTcGFjZUNyZWF0ZURldmljZVJHQiAoKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb2xvclNwYWNlUmVsZWFzZSAoaW50IGNzKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0QWRkQXJjIChpbnQgY3R4LCBmbG9hdCB4LCBmbG9hdCB5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHN0YXJ0QW5nbGUsIGZsb2F0IGVuZEFuZ2xlLCBib29sZWFuIGNsb2Nrd2lzZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dEFkZEFyY1RvUG9pbnQgKGludCBjdHgsIGZsb2F0IHgxLCBmbG9hdCB5MSwgZmxvYXQgeDIsIGZsb2F0IHkyLCBmbG9hdCByYWRpdXMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDR0NvbnRleHRBZGRMaW5lVG9Qb2ludCAoaW50IGN0eCwgZmxvYXQgeCwgZmxvYXQgeSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dEFkZExpbmVzIChpbnQgY3R4LCBmbG9hdFtdIHBvaW50cywgaW50IGNvdW50KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0QmVnaW5QYXRoIChpbnQgY3R4KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0Q2xpcCAoaW50IGN0eCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dENsb3NlUGF0aCAoaW50IGN0eCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dERyYXdJbWFnZSAoaW50IGN0eCwgQ0dSZWN0IHJlY3QsIGludCBpbWFnZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dEZpbGxQYXRoIChpbnQgY3R4KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0U3Ryb2tlUmVjdCAoaW50IGN0eCwgQ0dSZWN0IHJlY3QpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDR0NvbnRleHRGaWxsUmVjdCAoaW50IGN0eCwgQ0dSZWN0IHJlY3QpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDR0NvbnRleHRGbHVzaCAoaW50IGN0eCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dEdldFRleHRQb3NpdGlvbiAoaW50IGN0eCwgQ0dQb2ludCBwb2ludCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dE1vdmVUb1BvaW50IChpbnQgY3R4LCBmbG9hdCB4LCBmbG9hdCB5KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0UmVsZWFzZShpbnQgY3R4KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0UmVzdG9yZUdTdGF0ZShpbnQgY3R4KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0U2F2ZUdTdGF0ZShpbnQgY3R4KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0U2VsZWN0Rm9udCAoaW50IGN0eCwgYnl0ZVtdIG5hbWUsIGZsb2F0IHNpemUsIGludCB0ZXh0RW5jb2RpbmcpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDR0NvbnRleHRTZXRGaWxsQ29sb3JTcGFjZSAoaW50IGN0eCwgaW50IGNvbG9yc3BhY2UpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDR0NvbnRleHRTZXRGb250U2l6ZSAoaW50IGN0eCwgZmxvYXQgc2l6ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dFNldFN0cm9rZUNvbG9yU3BhY2UgKGludCBjdHgsIGludCBjb2xvcnNwYWNlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0U2V0RmlsbENvbG9yIChpbnQgY3R4LCBmbG9hdFtdIHZhbHVlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0U2V0TGluZURhc2ggKGludCBjdHgsIGZsb2F0IHBoYXNlLCBmbG9hdFtdIGxlbmd0aHMsIGludCBjb3VudCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dFNldExpbmVXaWR0aCAoaW50IGN0eCwgZmxvYXQgd2lkdGgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDR0NvbnRleHRTZXRTdHJva2VDb2xvciAoaW50IGN0eCwgZmxvYXRbXSB2YWx1ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dFNldFJHQkZpbGxDb2xvciAoaW50IGN0eCwgZmxvYXQgciwgZmxvYXQgZywgZmxvYXQgYiwgZmxvYXQgYWxwaGEpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDR0NvbnRleHRTZXRSR0JTdHJva2VDb2xvciAoaW50IGN0eCwgZmxvYXQgciwgZmxvYXQgZywgZmxvYXQgYiwgZmxvYXQgYWxwaGEpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDR0NvbnRleHRTZXRUZXh0RHJhd2luZ01vZGUgKGludCBjdHgsIGludCBtb2RlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0U2V0VGV4dFBvc2l0aW9uIChpbnQgY3R4LCBmbG9hdCB4LCBmbG9hdCB5KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0U2hvd1RleHQgKGludCBjdHgsIGJ5dGVbXSBjc3RyaW5nLCBpbnQgbGVuZ3RoKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0U2hvd1RleHRBdFBvaW50IChpbnQgY3R4LCBmbG9hdCB4LCBmbG9hdCB5LCBieXRlW10gY3N0cmluZywgaW50IGxlbmd0aCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dFNldFRleHRNYXRyaXggKGludCBjdHgsIGZsb2F0W10gdHJhbnNmb3JtKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dDb250ZXh0U3Ryb2tlUGF0aCAoaW50IGN0eCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENHQ29udGV4dFN5bmNocm9uaXplIChpbnQgY3R4KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDR0RhdGFQcm92aWRlckNyZWF0ZVdpdGhEYXRhIChpbnQgaW5mbywgaW50IGRhdGEsIGludCBzaXplLCBpbnQgcmVsZWFzZURhdGEpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDR0RhdGFQcm92aWRlclJlbGVhc2UgKGludCBwcm92aWRlcik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ0dJbWFnZUNyZWF0ZSAoaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgYml0c1BlckNvbXBvbmVudCwgaW50IGJpdHNQZXJQaXhlbCwgaW50IGJ5dGVzUGVyUm93LCBpbnQgY29sb3JzcGFjZSwgaW50IGFscGhhSW5mbywgaW50IHByb3ZpZGVyLCBmbG9hdFtdIGRlY29kZSwgYm9vbGVhbiBzaG91bGRJbnRlcnBvbGF0ZSwgaW50IGludGVudCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ0dJbWFnZUdldEFscGhhSW5mbyAoaW50IGltYWdlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDR0ltYWdlR2V0Qml0c1BlckNvbXBvbmVudCAoaW50IGltYWdlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDR0ltYWdlR2V0Qml0c1BlclBpeGVsIChpbnQgaW1hZ2UpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENHSW1hZ2VHZXRCeXRlc1BlclJvdyAoaW50IGltYWdlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDR0ltYWdlR2V0Q29sb3JTcGFjZSAoaW50IGltYWdlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDR0ltYWdlR2V0SGVpZ2h0IChpbnQgaW1hZ2UpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENHSW1hZ2VHZXRXaWR0aCAoaW50IGltYWdlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ0dJbWFnZVJlbGVhc2UgKGludCBpbWFnZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ2FsbE5leHRFdmVudEhhbmRsZXIoaW50IG5leHRIYW5kbGVyLCBpbnQgZXZlbnRSZWZIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgc2hvcnQgQ2hhcldpZHRoKHNob3J0IGMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENsZWFyQ3VycmVudFNjcmFwKCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ2xlYXJLZXlib2FyZEZvY3VzKGludCBpbldpbmRvdyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENsZWFyTWVudUJhcigpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENsaXBDR0NvbnRleHRUb1JlZ2lvbihpbnQgaW5Db250ZXh0LCBSZWN0IHBvcnRSZWN0LCBpbnQgcmduSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDbG9zZURhdGFCcm93c2VyQ29udGFpbmVyKGludCBjSGFuZGxlLCBpbnQgY29udGFpbmVyKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ2xvc2VQb2x5KCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ29sbGFwc2VXaW5kb3coaW50IHdIYW5kbGUsIGJvb2xlYW4gY29sbGFwc2UpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgYm9vbGVhbiBDb252ZXJ0RXZlbnRSZWZUb0V2ZW50UmVjb3JkKGludCBpbkV2ZW50LCBFdmVudFJlY29yZCBvdXRFdmVudCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIENvcHlCaXRzKGludCBzcmNQaXhNYXBIYW5kbGUsIGludCBkc3RQaXhNYXBIYW5kbGUsIFJlY3Qgc3JjUmVjdCwgUmVjdCBkc3RSZWN0LCBzaG9ydCBtb2RlLCBpbnQgbWFza1Jnbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ29weUNvbnRyb2xUaXRsZUFzQ0ZTdHJpbmcoaW50IGNIYW5kbGUsIGludFtdIHNIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBDb3B5RGVlcE1hc2soaW50IHNyY1BpeE1hcEhhbmRsZSwgaW50IG1hc2tQaXhNYXBIYW5kbGUsIGludCBkc3RQaXhNYXBIYW5kbGUsIFJlY3Qgc3JjUmVjdCwgUmVjdCBtYXNrUmVjdCwgUmVjdCBkc3RSZWN0LCBzaG9ydCBtb2RlLCBpbnQgbWFza1Jnbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ29weU1lbnVJdGVtVGV4dEFzQ0ZTdHJpbmcoaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBpbnRbXSBzSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgQ29weVJnbihpbnQgc3JjUmduSGFuZGxlLCBpbnQgZHN0UmduSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHNob3J0IENvdW50TWVudUl0ZW1zKGludCBtSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDb3VudFN1YkNvbnRyb2xzKGludCBjSGFuZGxlLCBzaG9ydFtdIGNvdW50KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDcmVhdGVCZXZlbEJ1dHRvbkNvbnRyb2woaW50IHdpbmRvdywgUmVjdCBib3VuZHNSZWN0LCBpbnQgdGl0bGUsIHNob3J0IHRoaWNrbmVzcywgc2hvcnQgYmVoYXZpb3IsIGludCBpbmZvLCBzaG9ydCBtZW51SUQsIHNob3J0IG1lbnVCZWhhdmlvciwgc2hvcnQgbWVudVBsYWNlbWVudCwgaW50W10gb3V0Q29udHJvbCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ3JlYXRlQ2hlY2tCb3hDb250cm9sKGludCB3aW5kb3csIFJlY3QgYm91bmRzUmVjdCwgaW50IHRpdGxlLCBpbnQgaW5pdGlhbFZhbHVlLCBib29sZWFuIGF1dG9Ub2dnbGUsIGludFtdIG91dENvbnRyb2wpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENyZWF0ZUNHQ29udGV4dEZvclBvcnQoaW50IGluUG9ydCwgaW50W10gb3V0Q29udGV4dCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ3JlYXRlRGF0YUJyb3dzZXJDb250cm9sKGludCB3aW5kb3csIFJlY3QgYm91bmRzUmVjdCwgaW50IHN0eWxlLGludFtdIG91dENvbnRyb2wpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENyZWF0ZUV2ZW50KGludCBhbGxvY2F0b3IsIGludCBpbkNsYXNzSUQsIGludCBraW5kLCBkb3VibGUgd2hlbiwgaW50IGZsYWdzLCBpbnRbXSBvdXRFdmVudFJlZik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ3JlYXRlR3JvdXBCb3hDb250cm9sKGludCB3aW5kb3csIFJlY3QgYm91bmRzUmVjdCwgaW50IHRpdGxlLCBib29sZWFuIHByaW1hcnksIGludFtdIG91dENvbnRyb2wpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENyZWF0ZUljb25Db250cm9sKGludCB3aW5kb3csIFJlY3QgYm91bmRzUmVjdCwgQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvIGljb24sIGJvb2xlYW4gZG9udFRyYWNrLCBpbnRbXSBvdXRDb250cm9sKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDcmVhdGVOZXdNZW51KHNob3J0IG1lbnVJRCwgaW50IG1lbnVBdHRyaWJ1dGVzLCBpbnRbXSBvdXRNZW51UmVmKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDcmVhdGVOZXdXaW5kb3coaW50IHdpbmRvd0NsYXNzLCBpbnQgYXR0cmlidXRlcywgUmVjdCBib3VuZHMsIGludFtdIHdIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENyZWF0ZVBvcHVwQXJyb3dDb250cm9sKGludCB3aW5kb3csIFJlY3QgYm91bmRzUmVjdCwgc2hvcnQgb3JpZW50YXRpb24sIHNob3J0IHNpemUsIGludFtdIG91dENvbnRyb2wpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENyZWF0ZVBvcHVwQnV0dG9uQ29udHJvbChpbnQgd2luZG93LCBSZWN0IGJvdW5kc1JlY3QsIGludCB0aXRsZSwgc2hvcnQgbWVudUlELCBib29sZWFuIHZhcmlhYmxlV2lkdGgsIHNob3J0IHRpdGxlV2lkdGgsIHNob3J0IHRpdGxlSnVzdGlmaWNhdGlvbiwgaW50IHRpdGxlU3R5bGUsIGludFtdIG91dENvbnRyb2wpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENyZWF0ZVByb2dyZXNzQmFyQ29udHJvbChpbnQgd2luZG93LCBSZWN0IGJvdW5kc1JlY3QsIGludCB2YWx1ZSwgaW50IG1pbmltaW0sIGludCBtYXhpbXVtLCBib29sZWFuIGluZGV0ZXJtaW5hdGUsIGludCBbXSBvdXRDb250cm9sKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDcmVhdGVQdXNoQnV0dG9uQ29udHJvbChpbnQgd2luZG93LCBSZWN0IGJvdW5kc1JlY3QsIGludCB0aXRsZSwgaW50W10gb3V0Q29udHJvbCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ3JlYXRlUHVzaEJ1dHRvbldpdGhJY29uQ29udHJvbChpbnQgd2luZG93LCBSZWN0IGJvdW5kc1JlY3QsIGludCB0aXRsZSwgQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvIGljb24sIHNob3J0IGljb25BbGlnbm1lbnQsIGludFtdIG91dENvbnRyb2wpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENyZWF0ZVJhZGlvQnV0dG9uQ29udHJvbChpbnQgd2luZG93LCBSZWN0IGJvdW5kc1JlY3QsIGludCB0aXRsZSwgaW50IGluaXRpYWxWYWx1ZSwgYm9vbGVhbiBhdXRvVG9nZ2xlLCBpbnRbXSBvdXRDb250cm9sKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDcmVhdGVSb290Q29udHJvbChpbnQgd2luZG93SGFuZGxlLCBpbnRbXSBjSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDcmVhdGVTbGlkZXJDb250cm9sKGludCB3aW5kb3csIFJlY3QgYm91bmRzUmVjdCwgaW50IHZhbHVlLCBpbnQgbWluaW11bSwgaW50IG1heGltdW0sIGludCBvcmllbnRhdGlvbiwgc2hvcnQgbnVtVGlja01hcmtzLCBib29sZWFuIGxpdmVUcmFja2luZywgaW50IGxpdmVUcmFja2luZ1Byb2MsIGludCBbXSBvdXRDb250cm9sKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDcmVhdGVTY3JvbGxCYXJDb250cm9sKGludCB3aW5kb3csIFJlY3QgYm91bmRzUmVjdCwgaW50IHZhbHVlLCBpbnQgbWluaW11bSwgaW50IG1heGltdW0sIGludCB2aWV3U2l6ZSwgYm9vbGVhbiBsaXZlVHJhY2tpbmcsIGludCBsaXZlVHJhY2tpbmdQcm9jLCBpbnQgW10gb3V0Q29udHJvbCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ3JlYXRlU2VwYXJhdG9yQ29udHJvbChpbnQgd2luZG93LCBSZWN0IGJvdW5kc1JlY3QsIGludCBbXSBvdXRDb250cm9sKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDcmVhdGVTdGFuZGFyZEFsZXJ0KHNob3J0IGFsZXJ0VHlwZSwgaW50IGVycm9yU0hhbmRsZSwgaW50IGV4cGxhbmF0aW9uU0hhbmRsZSwgQWxlcnRTdGRDRlN0cmluZ0FsZXJ0UGFyYW1SZWMgYWxlcnRQYXJhbUhhbmRsZSwgaW50W10gZGlhbG9nSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBDcmVhdGVTdGF0aWNUZXh0Q29udHJvbChpbnQgd2luZG93LCBSZWN0IGJvdW5kc1JlY3QsIGludCB0ZXh0LCBDb250cm9sRm9udFN0eWxlUmVjIHN0eWxlLCBpbnQgW10gb3V0Q29udHJvbCk7ICAgIAorcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENyZWF0ZVRhYnNDb250cm9sKGludCB3aW5kb3csIFJlY3QgYm91bmRzUmVjdCwgc2hvcnQgc2l6ZSwgc2hvcnQgZGlyZWN0aW9uLCBzaG9ydCBudW1UYWJzLCBpbnQgdGFiQXJyYXksIGludFtdIG91dENvbnRyb2wpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IENyZWF0ZUVkaXRVbmljb2RlVGV4dENvbnRyb2woaW50IHdpbmRvdywgUmVjdCBib3VuZHNSZWN0LCBpbnQgdGV4dCwgYm9vbGVhbiBpc1Bhc3N3b3JkLCBDb250cm9sRm9udFN0eWxlUmVjIHN0eWxlLCBpbnQgW10gb3V0Q29udHJvbCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ3JlYXRlVXNlclBhbmVDb250cm9sKGludCB3aW5kb3csIFJlY3QgYm91bmRzUmVjdCwgaW50IGZlYXR1cmVzLCBpbnQgW10gb3V0Q29udHJvbCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgQ3JlYXRlV2luZG93R3JvdXAgKGludCBpbkF0dHJpYnV0ZXMsIGludCBbXSBvdXRHcm91cCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIERlbGV0ZU1lbnUoc2hvcnQgbWVudUlEKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgRGVsZXRlTWVudUl0ZW0oaW50IG1IYW5kbGUsIHNob3J0IGluZGV4KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBEZWxldGVNZW51SXRlbXMoaW50IG1IYW5kbGUsIHNob3J0IGZpcnN0SXRlbSwgaW50IG51bUl0ZW1zKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgRGlmZlJnbihpbnQgc3JjUmduQSwgaW50IHNyY1JnbkIsIGludCBkc3RSZ24pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IERpc2FibGVDb250cm9sKGludCBjSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgRGlzYWJsZU1lbnVDb21tYW5kKGludCBtSGFuZGxlLCBpbnQgY29tbWFuZElkKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgRGlzYWJsZU1lbnVJdGVtKGludCBtSGFuZGxlLCBzaG9ydCBpbmRleCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIERpc3Bvc2VDb250cm9sKGludCBjSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgRGlzcG9zZUdXb3JsZChpbnQgb2Zmc2NyZWVuR1dvcmxkKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgRGlzcG9zZUhhbmRsZShpbnQgaGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgRGlzcG9zZU1lbnUoaW50IG1IYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBEaXNwb3NlUHRyKGludCBwdHIpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBEaXNwb3NlUmduKGludCByZ25IYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBEaXNwb3NlV2luZG93KGludCB3SGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgRHJhd01lbnVCYXIoKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgRHJhd1RleHQoYnl0ZVtdIHRleHRCdWYsIHNob3J0IGZpcnN0Qnl0ZSwgc2hvcnQgYnl0ZUNvdW50KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBEcmF3VGhlbWVCdXR0b24oUmVjdCBpbkJvdW5kcywgc2hvcnQgaW5LaW5kLCBUaGVtZUJ1dHRvbkRyYXdJbmZvIGluTmV3SW5mbywgVGhlbWVCdXR0b25EcmF3SW5mbyBpblByZXZJbmZvLCBpbnQgaW5FcmFzZVByb2MsIGludCBpbkxhYmVsUHJvYywgaW50IGluVXNlckRhdGEpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IERyYXdUaGVtZUVkaXRUZXh0RnJhbWUoUmVjdCBib3VuZHMsIGludCBzdGF0ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgRHJhd1RoZW1lRm9jdXNSZWN0KFJlY3QgYm91bmRzLCBib29sZWFuIGhhc0ZvY3VzKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBEcmF3VGhlbWVTZXBhcmF0b3IoUmVjdCBib3VuZHMsIGludCBzdGF0ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgRHJhd1RoZW1lVGV4dEJveChpbnQgc0hhbmRsZSwgc2hvcnQgZm9udElELCBpbnQgc3RhdGUsIGJvb2xlYW4gd3JhcFRvV2lkdGgsIFJlY3QgYm91bmRzLCBzaG9ydCBqdXN0LCBpbnQgY29udGV4dCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgRW1iZWRDb250cm9sKGludCBpbkNvbnRyb2wsIGludCBpbkNvbnRhaW5lcik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBib29sZWFuIEVtcHR5UmVjdChSZWN0IHIpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgYm9vbGVhbiBFbXB0eVJnbihpbnQgcmduSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBFbmFibGVDb250cm9sKGludCBjSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgRW5hYmxlTWVudUNvbW1hbmQoaW50IG1IYW5kbGUsIGludCBjb21tYW5kSWQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBFbmFibGVNZW51SXRlbShpbnQgbUhhbmRsZSwgc2hvcnQgaW5kZXgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBFbmRVcGRhdGUoaW50IHdIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgYm9vbGVhbiBFcXVhbFJlY3QoUmVjdCByZWN0MSwgUmVjdCByZWN0Mik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIEVyYXNlUmVjdChSZWN0IGJvdW5kcyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIEVyYXNlUmduKGludCByZ25IYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEZldGNoRm9udEluZm8oc2hvcnQgZm9udElELCBzaG9ydCBmb250U2l6ZSwgc2hvcnQgZm9udFN0eWxlLCBGb250SW5mbyBpbmZvKTsgCitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgRml4MkxvbmcoaW50IHgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEZNQ3JlYXRlRm9udEZhbWlseUluc3RhbmNlSXRlcmF0b3Ioc2hvcnQgaUZvbnRGYW1pbHksIGludCBpb0l0ZXJhdG9yKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBGTUNyZWF0ZUZvbnRGYW1pbHlJdGVyYXRvcihpbnQgaUZpbHRlciwgaW50IGlSZWZDb24sIGludCBpT3B0aW9ucywgaW50IGlvSXRlcmF0b3IpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEZNRGlzcG9zZUZvbnRGYW1pbHlJdGVyYXRvcihpbnQgaW9JdGVyYXRvcik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgRk1EaXNwb3NlRm9udEZhbWlseUluc3RhbmNlSXRlcmF0b3IoaW50IGlvSXRlcmF0b3IpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEZNR2V0Rm9udEZhbWlseU5hbWUoc2hvcnQgaWQsIGJ5dGVbXSBuYW1lKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHNob3J0IEZNR2V0Rm9udEZhbWlseUZyb21OYW1lKGJ5dGVbXSBuYW1lKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBGTUdldEZvbnRGcm9tRm9udEZhbWlseUluc3RhbmNlKHNob3J0IGlGb250RmFtaWx5LCBzaG9ydCBpU3R5bGUsIGludFtdIG9Gb250LCBzaG9ydFtdIG9JbnRyaW5zaWNTdHlsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgRk1HZXROZXh0Rm9udEZhbWlseShpbnQgaW9JdGVyYXRvciwgc2hvcnRbXSBvRm9udEZhbWlseSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgRk1HZXROZXh0Rm9udEZhbWlseUluc3RhbmNlKGludCBpb0l0ZXJhdG9yLCBpbnRbXSBvRm9udCwgc2hvcnRbXSBvU3R5bGUsIHNob3J0W10gb1NpemUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgYm9vbGVhbiBGUElzRm9udFBhbmVsVmlzaWJsZSgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEZQU2hvd0hpZGVGb250UGFuZWwoKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHNob3J0IEZpbmRXaW5kb3coUG9pbnQgd2hlcmUsIGludFtdIHdIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBGcmFtZU92YWwoUmVjdCBib3VuZHMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBGcmFtZVBvbHkoaW50IHBvbHlIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBGcmFtZVJlY3QoUmVjdCBib3VuZHMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBGcmFtZVJvdW5kUmVjdChSZWN0IGJvdW5kcywgc2hvcnQgb3ZhbFdpZHRoLCBzaG9ydCBvdmFsSGVpZ2h0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBGcm9udFdpbmRvdygpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgc2hvcnQgR2V0QXBwRm9udCgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldEFwcGxpY2F0aW9uRXZlbnRUYXJnZXQoKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRBdmFpbGFibGVXaW5kb3dBdHRyaWJ1dGVzKGludCB3aW5kb3dDbGFzcyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0QXZhaWxhYmxlV2luZG93UG9zaXRpb25pbmdCb3VuZHMoaW50IGluRGV2aWNlLCBSZWN0IG91dEF2YWlsYWJsZVJlY3QpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldEJlc3RDb250cm9sUmVjdChpbnQgaW5Db250cm9sLCBSZWN0IG91dFJlY3QsIHNob3J0W10gb3V0QmFzZUxpbmVPZmZzZXQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldENhcmV0VGltZSgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBHZXRDbGlwKGludCByZ25IYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldENvbnRyb2wzMkJpdE1heGltdW0oaW50IGNIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldENvbnRyb2wzMkJpdE1pbmltdW0oaW50IGNIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldENvbnRyb2wzMkJpdFZhbHVlKGludCBjSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgR2V0Q29udHJvbEJvdW5kcyhpbnQgY0hhbmRsZSwgUmVjdCBib3VuZHMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldENvbnRyb2xEYXRhKGludCBpbkNvbnRyb2wsIHNob3J0IGluUGFydCwgaW50IGluVGFnTmFtZSwgaW50IGluQnVmZmVyU2l6ZSwgUmVjdCBpbkJ1ZmZlciwgaW50W10gb3V0QWN0dWFsU2l6ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0Q29udHJvbERhdGEoaW50IGluQ29udHJvbCwgc2hvcnQgaW5QYXJ0LCBpbnQgaW5UYWdOYW1lLCBpbnQgaW5CdWZmZXJTaXplLCBpbnRbXSBpbkJ1ZmZlciwgaW50W10gb3V0QWN0dWFsU2l6ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0Q29udHJvbERhdGEoaW50IGluQ29udHJvbCwgc2hvcnQgaW5QYXJ0LCBpbnQgaW5UYWdOYW1lLCBpbnQgaW5CdWZmZXJTaXplLCBzaG9ydFtdIGluQnVmZmVyLCBpbnRbXSBvdXRBY3R1YWxTaXplKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRDb250cm9sRGF0YShpbnQgaW5Db250cm9sLCBzaG9ydCBpblBhcnQsIGludCBpblRhZ05hbWUsIGludCBpbkJ1ZmZlclNpemUsIGJ5dGVbXSBpbkJ1ZmZlciwgaW50W10gb3V0QWN0dWFsU2l6ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0Q29udHJvbEV2ZW50VGFyZ2V0KGludCBjSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRDb250cm9sRmVhdHVyZXMoaW50IGluQ29udHJvbCwgaW50W10gb3V0RmVhdHVyZXMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldENvbnRyb2xPd25lcihpbnQgY0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0Q29udHJvbFByb3BlcnR5KGludCBjb250cm9sLCBpbnQgIHByb3BlcnR5Q3JlYXRvciwgaW50IHByb3BlcnR5VGFnLCBpbnQgYnVmZmVyU2l6ZSwgaW50W10gYWN0dWFsU2l6ZSwgIGludFtdIHByb3BlcnR5QnVmZmVyKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRDb250cm9sUmVmZXJlbmNlKGludCBjSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRDb250cm9sUmVnaW9uKGludCBjSGFuZGxlLCBzaG9ydCBpblBhcnQsIGludCByZ25IYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgc2hvcnQgR2V0Q29udHJvbFZhbHVlKGludCBjSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRDb250cm9sVmlld1NpemUoaW50IGNIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldEN1cnJlbnRFdmVudEJ1dHRvblN0YXRlKCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0Q3VycmVudEV2ZW50TG9vcCgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldEN1cnJlbnRFdmVudEtleU1vZGlmaWVycygpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldEN1cnJlbnRFdmVudFF1ZXVlKCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0Q3VycmVudFByb2Nlc3MoaW50W10gcHNuKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRDdXJyZW50U2NyYXAoaW50W10gc2NyYXApOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldERhdGFCcm93c2VyQ2FsbGJhY2tzKGludCBicm93c2VyLCBEYXRhQnJvd3NlckNhbGxiYWNrcyAgY2FsbGJhY2tzKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXREYXRhQnJvd3Nlckl0ZW1Db3VudChpbnQgY0hhbmRsZSwgaW50IGNvbnRhaW5lciwgYm9vbGVhbiByZWN1cnNlLCBpbnQgc3RhdGUsIGludFtdIG51bUl0ZW1zKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXREYXRhQnJvd3Nlckl0ZW1EYXRhQnV0dG9uVmFsdWUoaW50IGl0ZW1EYXRhLCBzaG9ydCBbXSB0aGVEYXRhKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXREYXRhQnJvd3Nlckl0ZW1QYXJ0Qm91bmRzKGludCBjSGFuZGxlLCBpbnQgaXRlbSwgaW50IHByb3BlcnR5LCBpbnQgcGFydCwgUmVjdCBib3VuZHMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldERhdGFCcm93c2VySXRlbXMoaW50IGJyb3dzZXIsIGludCBjb250YWluZXIsIGJvb2xlYW4gcmVjdXJzZSwgaW50IHN0YXRlLCBpbnQgaXRlbXMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldERhdGFCcm93c2VySXRlbVN0YXRlKGludCBicm93c2VyLCBpbnQgaXRlbSwgaW50IFtdIHN0YXRlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyQnRuSGVpZ2h0KGludCBicm93c2VyLCBzaG9ydCBbXSBoZWlnaHQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjKGludCBicm93c2VyLCBpbnQgY29sdW1uLCBEYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzYyBkZXNjKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXREYXRhQnJvd3NlclRhYmxlVmlld0l0ZW1JRChpbnQgYnJvd3NlciwgaW50IHJvdywgaW50IFtdIGl0ZW0pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldERhdGFCcm93c2VyVGFibGVWaWV3SXRlbVJvdyhpbnQgYnJvd3NlciwgaW50IGl0ZW0sIGludCBbXSByb3cpOyAgICAgICAgICAgICAgICAgICAgICAgICAKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXREYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtblBvc2l0aW9uKGludCBicm93c2VyLCBpbnQgY29sdW1uLCBpbnQgW10gcG9zaXRpb24pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldERhdGFCcm93c2VyVGFibGVWaWV3TmFtZWRDb2x1bW5XaWR0aChpbnQgYnJvd3NlciwgaW50IGNvbHVtbiwgc2hvcnQgW10gd2lkdGgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldERhdGFCcm93c2VyVGFibGVWaWV3Um93SGVpZ2h0KGludCBicm93c2VyLCBzaG9ydCBbXSBoZWlnaHQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldERhdGFCcm93c2VyU2Nyb2xsQmFySW5zZXQoaW50IGJyb3dzZXIsIFJlY3QgaW5zZXRSZWN0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uKGludCBjSGFuZGxlLCBpbnRbXSB0b3AsIGludFtdIGxlZnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldERhdGFCcm93c2VyU2VsZWN0aW9uQW5jaG9yKGludCBicm93c2VyLCBpbnQgW10gZmlyc3QsIGludCBbXSBsYXN0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXREYmxUaW1lKCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBzaG9ydCBHZXREZWZGb250U2l6ZSgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldEV2ZW50Q2xhc3MoaW50IGVIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldEV2ZW50RGlzcGF0Y2hlclRhcmdldCgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldEV2ZW50S2luZChpbnQgZUhhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0RXZlbnRQYXJhbWV0ZXIoaW50IGluRXZlbnQsIGludCBpbk5hbWUsIGludCBpbkRlc2lyZWRUeXBlLCBpbnRbXSBvdXRBY3R1YWxUeXBlLCBpbnQgaW5CdWZmZXJTaXplLCBpbnRbXSBvdXRBY3R1YWxTaXplLCBpbnRbXSBvdXREYXRhKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRFdmVudFBhcmFtZXRlcihpbnQgaW5FdmVudCwgaW50IGluTmFtZSwgaW50IGluRGVzaXJlZFR5cGUsIGludFtdIG91dEFjdHVhbFR5cGUsIGludCBpbkJ1ZmZlclNpemUsIGludFtdIG91dEFjdHVhbFNpemUsIGNoYXJbXSBvdXREYXRhKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRFdmVudFBhcmFtZXRlcihpbnQgaW5FdmVudCwgaW50IGluTmFtZSwgaW50IGluRGVzaXJlZFR5cGUsIGludFtdIG91dEFjdHVhbFR5cGUsIGludCBpbkJ1ZmZlclNpemUsIGludFtdIG91dEFjdHVhbFNpemUsIHNob3J0W10gb3V0RGF0YSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0RXZlbnRQYXJhbWV0ZXIoaW50IGluRXZlbnQsIGludCBpbk5hbWUsIGludCBpbkRlc2lyZWRUeXBlLCBpbnRbXSBvdXRBY3R1YWxUeXBlLCBpbnQgaW5CdWZmZXJTaXplLCBpbnRbXSBvdXRBY3R1YWxTaXplLCBieXRlW10gb3V0RGF0YSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0RXZlbnRQYXJhbWV0ZXIoaW50IGluRXZlbnQsIGludCBpbk5hbWUsIGludCBpbkRlc2lyZWRUeXBlLCBpbnRbXSBvdXRBY3R1YWxUeXBlLCBpbnQgaW5CdWZmZXJTaXplLCBpbnRbXSBvdXRBY3R1YWxTaXplLCBISUNvbW1hbmQgb3V0RGF0YSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0RXZlbnRQYXJhbWV0ZXIoaW50IGluRXZlbnQsIGludCBpbk5hbWUsIGludCBpbkRlc2lyZWRUeXBlLCBpbnRbXSBvdXRBY3R1YWxUeXBlLCBpbnQgaW5CdWZmZXJTaXplLCBpbnRbXSBvdXRBY3R1YWxTaXplLCBQb2ludCBvdXREYXRhKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRFdmVudFBhcmFtZXRlcihpbnQgaW5FdmVudCwgaW50IGluTmFtZSwgaW50IGluRGVzaXJlZFR5cGUsIGludFtdIG91dEFjdHVhbFR5cGUsIGludCBpbkJ1ZmZlclNpemUsIGludFtdIG91dEFjdHVhbFNpemUsIENHUG9pbnQgb3V0RGF0YSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0RXZlbnRQYXJhbWV0ZXIoaW50IGluRXZlbnQsIGludCBpbk5hbWUsIGludCBpbkRlc2lyZWRUeXBlLCBpbnRbXSBvdXRBY3R1YWxUeXBlLCBpbnQgaW5CdWZmZXJTaXplLCBpbnRbXSBvdXRBY3R1YWxTaXplLCBSR0JDb2xvciBvdXREYXRhKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRFdmVudFBhcmFtZXRlcihpbnQgaW5FdmVudCwgaW50IGluTmFtZSwgaW50IGluRGVzaXJlZFR5cGUsIGludFtdIG91dEFjdHVhbFR5cGUsIGludCBpbkJ1ZmZlclNpemUsIGludFtdIG91dEFjdHVhbFNpemUsIFJlY3Qgb3V0RGF0YSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBkb3VibGUgR2V0RXZlbnRUaW1lKGludCBlSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgR2V0Rm9udEluZm8oc2hvcnRbXSBpbmZvKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRHRGV2aWNlKCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIEdldEdXb3JsZChpbnRbXSBwb3J0SGFuZGxlLCBpbnRbXSBnZEhhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIEdldEdsb2JhbE1vdXNlKFBvaW50IHdoZXJlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRIYW5kbGVTaXplKGludCBoYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldEljb25SZWYoc2hvcnQgdlJlZk51bSwgaW50IGNyZWF0b3IsIGludCBpY29uVHlwZSwgaW50W10gdGhlSWNvblJlZik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0SW5kTWVudUl0ZW1XaXRoQ29tbWFuZElEKGludCBtSGFuZGxlLCBpbnQgY29tbWFuZElkLCBpbnQgaW5kZXgsIGludFtdIG91dE1lbnUsIHNob3J0W10gb3V0SW5kZXgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldEluZGV4ZWRTdWJDb250cm9sKGludCBjSGFuZGxlLCBzaG9ydCBpbmRleCwgaW50W10gb3V0SGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRLZXlib2FyZEZvY3VzKGludCB3SGFuZGxlLCBpbnRbXSBjSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGRvdWJsZSBHZXRMYXN0VXNlckV2ZW50VGltZSgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldE1haW5EZXZpY2UoKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRNYWluRXZlbnRRdWV1ZSgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldE1lbnVDb21tYW5kTWFyayhpbnQgdGhlTWVudSwgaW50IGNvbW1hbmRJZCwgY2hhcltdIG91dE1hcmspOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldE1lbnVFdmVudFRhcmdldChpbnQgY0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0TWVudUZvbnQoaW50IGluTWVudSwgc2hvcnRbXSBvdXRGb250SUQsIHNob3J0W10gb3V0Rm9udFNpemUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgc2hvcnQgR2V0TWVudUlEKGludCBtZW51KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRNZW51SXRlbUNvbW1hbmRJRChpbnQgaW5NZW51LCBzaG9ydCBpbkl0ZW0sIGludFtdIG91dENvbW1hbmRJRCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0TWVudUl0ZW1IaWVyYXJjaGljYWxNZW51KGludCBpbk1lbnUsIHNob3J0IGluSXRlbSwgaW50IFtdb3V0SGllck1lbnUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldE1lbnVJdGVtUmVmQ29uKGludCBpbk1lbnUsIHNob3J0IGludEl0ZW0sIGludFtdIG91dFJlZkNvbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0TWVudVRyYWNraW5nRGF0YShpbnQgbWVudSwgTWVudVRyYWNraW5nRGF0YSBvdXREYXRhKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgR2V0TW91c2UoUG9pbnQgd2hlcmUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBHZXRQaXhCb3VuZHMoaW50IHBIYW5kbGUsIFJlY3QgYm91bmRzKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHNob3J0IEdldFBpeERlcHRoKGludCBwSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgR2V0UG9ydChpbnRbXSBwb3J0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRQb3J0Qml0TWFwRm9yQ29weUJpdHMoaW50IHBvcnRIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBHZXRQb3J0Qm91bmRzKGludCBwSGFuZGxlLCBSZWN0IHJlY3QpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBHZXRQb3J0Q2xpcFJlZ2lvbihpbnQgcG9ydCwgaW50IGNsaXBSZ24pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldFBvcnRWaXNpYmxlUmVnaW9uKGludCBwb3J0SGFuZGxlLCBpbnQgcmduSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRQdHJTaXplKGludCBwdHIpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBHZXRSZWdpb25Cb3VuZHMoaW50IHJnbkhhbmRsZSwgUmVjdCBib3VuZHMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldFJvb3RDb250cm9sKGludCB3aW5kb3dIYW5kbGUsIGludFtdIGNIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldFNjcmFwRmxhdm9yQ291bnQoaW50IHNjcmFwLCBpbnRbXSBpbmZvQ291bnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldFNjcmFwRmxhdm9yRGF0YShpbnQgc2NyYXAsIGludCBmbGF2b3JUeXBlLCBpbnRbXSBieXRlQ291bnQsIGJ5dGVbXSBkZXN0aW5hdGlvbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0U2NyYXBGbGF2b3JJbmZvTGlzdChpbnQgc2NyYXAsIGludFtdIGluZm9Db3VudCwgaW50W10gaW5mbyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0U2NyYXBGbGF2b3JTaXplKGludCBzY3JhcCwgaW50IGZsYXZvclR5cGUsIGludFtdIGJ5dGVDb3VudCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0U3VwZXJDb250cm9sKGludCBjSGFuZGxlLCBpbnRbXSBwYXJlbnRIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldFRoZW1lQnJ1c2hBc0NvbG9yKHNob3J0IGluQnJ1c2gsIHNob3J0IGluRGVwdGgsIGJvb2xlYW4gaW5Db2xvckRldiwgUkdCQ29sb3Igb3V0Q29sb3IpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldFRoZW1lRHJhd2luZ1N0YXRlKGludFtdIHN0YXRlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRUaGVtZUZvbnQoc2hvcnQgdGhlbWVGb250SWQsIHNob3J0IHNjcmlwdENvZGUsIGJ5dGVbXSBmb250TmFtZSwgc2hvcnRbXSBmb250U2l6ZSwgYnl0ZVtdIHN0eWxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRUaGVtZU1ldHJpYyhpbnQgaW5NZXRyaWMsIGludCBbXSBvdXRNZXRyaWMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldFRoZW1lVGV4dENvbG9yKHNob3J0IGluQ29sb3IsIHNob3J0IGluRGVwdGgsIGJvb2xlYW4gaW5Db2xvckRldiwgUkdCQ29sb3Igb3V0Q29sb3IpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldFRoZW1lVGV4dERpbWVuc2lvbnMoaW50IHNIYW5kbGUsIHNob3J0IGZvbnRJRCwgaW50IHN0YXRlLCBib29sZWFuIHdyYXBUb1dpZHRoLCBQb2ludCBpb0JvdW5kcywgc2hvcnRbXSBiYXNlTGluZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0VXNlckZvY3VzRXZlbnRUYXJnZXQoKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRXUmVmQ29uKGludCB3SGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgR2V0V2luZG93Qm91bmRzKGludCB3SGFuZGxlLCBzaG9ydCB3aW5kb3dSZWdpb24sIFJlY3QgYm91bmRzKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRXaW5kb3dEZWZhdWx0QnV0dG9uKGludCB3SGFuZGxlLCBpbnRbXSBjSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRXaW5kb3dFdmVudFRhcmdldChpbnQgd0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgR2V0V2luZG93RnJvbVBvcnQoaW50IHBIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldFdpbmRvd0dyb3VwT2ZDbGFzcyAoaW50IHdpbmRvd0NsYXNzKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBHZXRXaW5kb3dNb2RhbGl0eShpbnQgaW5XaW5kb3csIGludFtdIG91dE1vZGFsS2luZCwgaW50W10gb3V0VW5hdmFpbGFibGVXaW5kb3cpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEdldFdpbmRvd1BvcnQoaW50IHdIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBHZXRXaW5kb3dTdHJ1Y3R1cmVXaWR0aHMoaW50IGludFdpbmRvdywgUmVjdCBvdXRSZWN0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBIYW5kbGVDb250cm9sU2V0Q3Vyc29yKGludCBjb250cm9sLCBQb2ludCBsb2NhbFBvaW50LCBpbnQgbW9kaWZpZXJzLCBib29sZWFuW10gY3Vyc29yV2FzU2V0KTsgIAorcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJQ29tYm9Cb3hBcHBlbmRUZXh0SXRlbShpbnQgaW5Db21ib0JveCwgaW50IGluVGV4dCwgaW50W10gb3V0SW5kZXgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJQ29tYm9Cb3hDb3B5VGV4dEl0ZW1BdEluZGV4KGludCBpbkNvbWJvQm94LCBpbnQgaW5JbmRleCwgaW50W10gb3V0U3RyaW5nKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBISUNvbWJvQm94Q3JlYXRlKENHUmVjdCBib3VuZHNSZWN0LCBpbnQgdGV4dCwgQ29udHJvbEZvbnRTdHlsZVJlYyBzdHlsZSwgaW50IGxpc3QsIGludCBpbkF0dHJpYnV0ZXMsIGludFtdIG91dENvbWJvQm94KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBISUNvbWJvQm94R2V0SXRlbUNvdW50KGludCBpbkNvbWJvQm94KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBISUNvbWJvQm94SW5zZXJ0VGV4dEl0ZW1BdEluZGV4KGludCBpbkNvbWJvQm94LCBpbnQgaW5JbmRleCwgaW50IGluVGV4dCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSElDb21ib0JveFJlbW92ZUl0ZW1BdEluZGV4KGludCBpbkNvbWJvQm94LCBpbnQgaW5JbmRleCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSElPYmplY3RDb3B5Q2xhc3NJRChpbnQgaW5PYmplY3QpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJT2JqZWN0Q3JlYXRlKGludCBpbkNsYXNzSUQsIGludCBpbkNvbnN0cnVjdERhdGEsIGludFtdIG91dE9iamVjdCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSElPYmplY3RSZWdpc3RlclN1YmNsYXNzKGludCBpbkNsYXNzSUQsIGludCBpbkJhc2VDbGFzc0lELCBpbnQgaW5PcHRpb25zLCBpbnQgaW5Db25zdHJ1Y3RQcm9jLCBpbnQgaW5OdW1FdmVudHMsIGludFtdIGluRXZlbnRMaXN0LCBpbnQgaW5Db25zdHJ1Y3REYXRhLCBpbnRbXSBvdXRDbGFzc1JlZik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSElWaWV3QWRkU3VidmlldyhpbnQgcGFyZW50LCBpbnQgY2hpbGQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld0NsaWNrKGludCBpblZpZXcsIGludCBpbkV2ZW50KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBISVZpZXdDb252ZXJ0UG9pbnQoQ0dQb2ludCBpb1BvaW50LCBpbnQgaW5Tb3VyY2VWaWV3LCBpbnQgaW5EZXN0Vmlldyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSElWaWV3RmluZEJ5SUQoaW50IGluU3RhcnRWaWV3LCBpbnQgaW5JRCwgaW50W10gb3V0Q29udHJvbCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSElWaWV3R2V0Rmlyc3RTdWJ2aWV3KGludCBpblZpZXcpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld0dldExhc3RTdWJ2aWV3KGludCBpblZpZXcpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld0dldE5leHRWaWV3KGludCBpblZpZXcpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld0dldEZyYW1lKGludCBpblZpZXcsIENHUmVjdCBvdXRSZWN0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBISVZpZXdHZXRSb290KGludCB3SGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBISVZpZXdHZXRTaXplQ29uc3RyYWludHMoaW50IGluVmlldywgQ0dSZWN0IG91dE1pblNpemUsIENHUmVjdCBvdXRNYXhTaXplKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBISVZpZXdHZXRTdWJ2aWV3SGl0KGludCBpblZpZXcsIENHUG9pbnQgaW5Qb2ludCwgYm9vbGVhbiBpbkRlZXAsIGludFtdIG91dFZpZXcpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld0dldFZpZXdGb3JNb3VzZUV2ZW50KGludCBpblZpZXcsIGludCBpbkV2ZW50LCBpbnRbXSBvdXRWaWV3KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGJvb2xlYW4gSElWaWV3SXNWaXNpYmxlKGludCBpblZpZXcpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld1JlbW92ZUZyb21TdXBlcnZpZXcoaW50IGluVmlldyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSElWaWV3U2V0RHJhd2luZ0VuYWJsZWQoaW50IGluVmlldywgYm9vbGVhbiBpc0VuYWJsZWQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld1NldEZyYW1lKGludCBpblZpZXcsIENHUmVjdCBpblJlY3QpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld1NldE5lZWRzRGlzcGxheShpbnQgaW5WaWV3LCBib29sZWFuIGluTmVlZHNEaXNwbGF5KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBISVZpZXdTZXROZWVkc0Rpc3BsYXlJblJlZ2lvbihpbnQgaW5WaWV3LCBpbnQgaW5SZ24sIGJvb2xlYW4gaW5OZWVkc0Rpc3BsYXkpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld1NldFZpc2libGUoaW50IGluVmlldywgYm9vbGVhbiBpblZpc2libGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld1NldFpPcmRlcihpbnQgaW5WaWV3LCBpbnQgaW5PcCwgaW50IGluT3RoZXIpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld1NpbXVsYXRlQ2xpY2soaW50IGluVmlldywgc2hvcnQgaW5QYXJ0VG9DbGljaywgaW50IG1vZGlmaWVycywgc2hvcnRbXSBvdXRQYXJ0Q2xpY2tlZCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBzaG9ydCBIYW5kbGVDb250cm9sQ2xpY2soaW50IGNIYW5kbGUsIFBvaW50IHdoZXJlLCBpbnQgbW9kaWZpZXJzLCBpbnQgYWN0aW9uVVBQKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHNob3J0IEhpV29yZChpbnQgZG91YmxlV29yZCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIEhpZGVXaW5kb3coaW50IHdIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBIaWxpdGVNZW51KHNob3J0IG1lbnVJRCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIEhMb2NrKGludCBoKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBITUdldFRhZ0RlbGF5IChpbnQgW10gb3V0RGVsYXkpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhNSGlkZVRhZyAoKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBITVNldFRhZ0RlbGF5IChpbnQgaW5EZWxheSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIEhNSW5zdGFsbENvbnRyb2xDb250ZW50Q2FsbGJhY2soaW50IGluQ29udHJvbCwgaW50IGluQ29udGVudFVQUCk7ICAKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgSFVubG9jayhpbnQgaCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSW5pdENvbnRleHR1YWxNZW51cygpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBJbml0Q3Vyc29yKCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSW5pdERhdGFCcm93c2VyQ2FsbGJhY2tzKERhdGFCcm93c2VyQ2FsbGJhY2tzIGNhbGxiYWNrcyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSW5pdERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzKERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzIGNhbGxiYWNrcyk7IAorcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBJbnNlcnRNZW51KGludCBtSGFuZGxlLCBzaG9ydCBiZWZvcmVJRCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSW5zZXJ0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nKGludCBtSGFuZGxlLCBpbnQgc0hhbmRsZSwgc2hvcnQgaW5kZXgsIGludCBhdHRyaWJ1dGVzLCBpbnQgY29tbWFuZElEKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBJbnN0YWxsRXZlbnRIYW5kbGVyKGludCBpblRhcmdldCwgaW50IGluSGFuZGxlciwgaW50IGluTnVtVHlwZXMsIGludFtdIGluTGlzdCwgaW50IGluVXNlckRhdGEsIGludFtdIG91dFJlZik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgSW5zdGFsbEV2ZW50TG9vcFRpbWVyKGludCBpbkV2ZW50TG9vcCwgZG91YmxlIGluRmlyZURlbGF5LCBkb3VibGUgaW5JbnRlcnZhbCwgaW50IGluVGltZXJQcm9jLCBpbnQgaW5UaW1lckRhdGEsIGludFtdIG91dFRpbWVyKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgSW52YWxXaW5kb3dSZWN0KGludCB3SGFuZGxlLCBSZWN0IGJvdW5kcyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIEludmFsV2luZG93UmduKGludCB3SGFuZGxlLCBpbnQgcmduSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgSW52ZXJ0UmVjdChSZWN0IHIpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBJbnZlcnRSZ24oaW50IHJnbkhhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBib29sZWFuIElzQ29udHJvbEFjdGl2ZShpbnQgaW5Db250cm9sKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGJvb2xlYW4gSXNDb250cm9sRW5hYmxlZChpbnQgY0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBib29sZWFuIElzQ29udHJvbFZpc2libGUoaW50IGNIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgYm9vbGVhbiBJc0RhdGFCcm93c2VySXRlbVNlbGVjdGVkKGludCBjSGFuZGxlLCBpbnQgaXRlbUlEKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGJvb2xlYW4gSXNNZW51Q29tbWFuZEVuYWJsZWQoaW50IG1IYW5kbGUsIGludCBjb21tYW5kSWQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgYm9vbGVhbiBJc01lbnVJdGVtRW5hYmxlZChpbnQgbUhhbmRsZSwgc2hvcnQgaW5kZXgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgYm9vbGVhbiBJc1ZhbGlkQ29udHJvbEhhbmRsZShpbnQgY0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBib29sZWFuIElzVmFsaWRNZW51KGludCBtSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGJvb2xlYW4gSXNWYWxpZFdpbmRvd1B0cihpbnQgZ3JhZlBvcnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgYm9vbGVhbiBJc1dpbmRvd0FjdGl2ZShpbnQgd2luZG93KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGJvb2xlYW4gSXNXaW5kb3dDb2xsYXBzZWQoaW50IHdpbmRvdyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBib29sZWFuIElzV2luZG93VmlzaWJsZShpbnQgd2luZG93KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgS2lsbFBvbHkoaW50IHBvbHlIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBMaW5lVG8oc2hvcnQgaCwgc2hvcnQgdik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBzaG9ydCBMb1dvcmQoaW50IGRvdWJsZVdvcmQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IExvY2tQb3J0Qml0cyhpbnQgcG9ydEhhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgTWVudVNlbGVjdChQb2ludCBtSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgTW92ZUNvbnRyb2woaW50IHRoZUNvbnRyb2wsIHNob3J0IGgsIHNob3J0IHYpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBNb3ZlVG8oc2hvcnQgaCwgc2hvcnQgdik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIE1vdmVXaW5kb3coaW50IHdIYW5kbGUsIHNob3J0IGgsIHNob3J0IHYsIGJvb2xlYW4gdG9Gcm9udCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgTmF2Q3JlYXRlQ2hvb3NlRm9sZGVyRGlhbG9nKE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucyBpbk9wdGlvbnMsIGludCBpbkV2ZW50UHJvYywgaW50IGluRmlsdGVyUHJvYywgaW50IGluQ2xpZW50RGF0YSwgaW50W10gb3V0RGlhbG9nKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBOYXZDcmVhdGVHZXRGaWxlRGlhbG9nKE5hdkRpYWxvZ0NyZWF0aW9uT3B0aW9ucyBpbk9wdGlvbnMsIGludCBpblR5cGVMaXN0LCBpbnQgaW5FdmVudFByb2MsIGludCBpblByZXZpZXdQcm9jLCBpbnQgaW5GaWx0ZXJQcm9jLCBpbnQgaW5DbGllbnREYXRhLCBpbnRbXSBvdXREaWFsb2cpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IE5hdkNyZWF0ZVB1dEZpbGVEaWFsb2coTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zIGluT3B0aW9ucywgaW50IGluRmlsZVR5cGUsIGludCBpbkZpbGVDcmVhdG9yLCBpbnQgaW5FdmVudFByb2MsIGludCBpbkNsaWVudERhdGEsIGludFtdIG91dERpYWxvZyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIE5hdkRpYWxvZ0Rpc3Bvc2UoaW50IGRpYWxvZ0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgTmF2RGlhbG9nR2V0U2F2ZUZpbGVOYW1lKGludCBkaWFsb2dIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IE5hdkRpYWxvZ0dldFVzZXJBY3Rpb24oaW50IGRpYWxvZ0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgTmF2RGlhbG9nUnVuKGludCBkaWFsb2dIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IE5hdkRpYWxvZ1NldFNhdmVGaWxlTmFtZShpbnQgZGlhbG9nSGFuZGxlLCBpbnQgZmlsZU5hbWVIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IE5hdkdldERlZmF1bHREaWFsb2dDcmVhdGlvbk9wdGlvbnMoTmF2RGlhbG9nQ3JlYXRpb25PcHRpb25zIG91dE9wdGlvbnMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IE5hdkRpYWxvZ0dldFJlcGx5KGludCBpbkRpYWxvZywgTmF2UmVwbHlSZWNvcmQgb3V0UmVwbHkpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IE5ld0NvbnRyb2woaW50IG93bmluZ1dpbmRvdywgUmVjdCBib3VuZHNSZWN0LCBieXRlW10gY29udHJvbFRpdGxlLCBib29sZWFuIGluaXRpYWxseVZpc2libGUsIHNob3J0IGluaXRpYWxWYWx1ZSwgc2hvcnQgbWluaW11bVZhbHVlLCBzaG9ydCBtYXhpbXVtVmFsdWUsIHNob3J0IHByb2NJRCwgaW50IGNvbnRyb2xSZWZlcmVuY2UpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IE5ld0dXb3JsZEZyb21QdHIoaW50W10gb2Zmc2NyZWVuR1dvcmxkLCBpbnQgUGl4ZWxGb3JtYXQsIFJlY3QgYm91bmRzUmVjdCwgaW50IGNUYWJsZSwgaW50IGFHRGV2aWNlLCBpbnQgZmxhZ3MsIGludCBuZXdCdWZmZXIsIGludCByb3dCeXRlcyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgTmV3SGFuZGxlKGludCBzaXplKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBOZXdIYW5kbGVDbGVhcihpbnQgc2l6ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgTmV3UHRyKGludCBzaXplKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBOZXdQdHJDbGVhcihpbnQgc2l6ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgTmV3UmduKCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIE9mZnNldFJlY3QoUmVjdCByZWN0LCBzaG9ydCBkaCwgc2hvcnQgZHYpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBPZmZzZXRSZ24oaW50IHJnbkhhbmRsZSwgc2hvcnQgZGgsIHNob3J0IGR2KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBPcGVuRGF0YUJyb3dzZXJDb250YWluZXIoaW50IGNIYW5kbGUsIGludCBjb250YWluZXIpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IE9wZW5Qb2x5KCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFBhaW50T3ZhbChSZWN0IGJvdW5kcyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFBhaW50UG9seShpbnQgcG9seUhhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFBhaW50UmVjdChSZWN0IGJvdW5kcyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFBhaW50Um91bmRSZWN0KFJlY3QgYm91bmRzLCBzaG9ydCBvdmFsV2lkdGgsIHNob3J0IG92YWxIZWlnaHQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBQZW5TaXplKHNob3J0IGgsIHNob3J0IHYpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFBpY2tDb2xvcihDb2xvclBpY2tlckluZm8gdGhlQ29sb3JJbmZvKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBQb3BVcE1lbnVTZWxlY3QoaW50IG1IYW5kbGUsIHNob3J0IHRvcCwgc2hvcnQgbGVmdCwgc2hvcnQgcG9wVXBJdGVtKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBQb3N0RXZlbnQoc2hvcnQgZXZlbnROdW0sIGludCBldmVudE1zZyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgUG9zdEV2ZW50VG9RdWV1ZShpbnQgaW5RdWV1ZSwgaW50IGluRXZlbnQsIHNob3J0IGluUHJpb3JpdHkpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgYm9vbGVhbiBQdEluUmVjdChQb2ludCBwdCwgUmVjdCByKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGJvb2xlYW4gUHRJblJnbihQb2ludCBwdCwgaW50IHJnbkhhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgUHV0U2NyYXBGbGF2b3IoaW50IHNjcmFwLCBpbnQgZmxhdm9yVHlwZSwgaW50IGZsYXZvckZsYWdzLCBpbnQgZmxhdm9yU2l6ZSwgYnl0ZVtdIGZsYXZvckRhdGEpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFFEQmVnaW5DR0NvbnRleHQoaW50IGluUG9ydCwgaW50W10gb3V0Q29udGV4dCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgUURFbmRDR0NvbnRleHQoaW50IGluUG9ydCwgaW50W10gaW5vdXRDb250ZXh0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgUURGbHVzaFBvcnRCdWZmZXIoaW50IHBvcnQsIGludCByZ25IYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBRREdsb2JhbFRvTG9jYWxQb2ludChpbnQgcG9ydCwgUG9pbnQgcG9pbnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBRRExvY2FsVG9HbG9iYWxQb2ludChpbnQgcG9ydCwgUG9pbnQgcG9pbnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBRRFNldFBhdHRlcm5PcmlnaW4oUG9pbnQgcG9pbnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFFEU3dhcFRleHRGbGFncyhpbnQgZmxhZ3MpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBSR0JCYWNrQ29sb3IoUkdCQ29sb3IgY29sb3IpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBSR0JGb3JlQ29sb3IoUkdCQ29sb3IgY29sb3IpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFJlY2VpdmVOZXh0RXZlbnQoaW50IGluTnVtVHlwZXMsIGludFtdIGluTGlzdCwgZG91YmxlIGluVGltZW91dCwgYm9vbGVhbiBpblB1bGxFdmVudCwgaW50W10gb3V0RXZlbnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgYm9vbGVhbiBSZWN0SW5SZ24oUmVjdCByZWN0LCBpbnQgcmduSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgUmVjdFJnbihpbnQgcmduSGFuZGxlLCBSZWN0IGxlZnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFJlZ2lzdGVyQXBwZWFyYW5jZUNsaWVudCgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBSZWxlYXNlRXZlbnQoaW50IHRoZUV2ZW50KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBSZWxlYXNlTWVudShpbnQgbUhhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgUmVsZWFzZVdpbmRvd0dyb3VwIChpbnQgaW5Hcm91cCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgUmVtb3ZlQ29udHJvbFByb3BlcnR5KGludCBjb250cm9sLCBpbnQgcHJvcGVydHlDcmVhdG9yLCBpbnQgcHJvcGVydHlUYWcpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFJlbW92ZURhdGFCcm93c2VySXRlbXMoaW50IGNIYW5kbGUsIGludCBjb250YWluZXJJRCwgaW50IG51bUl0ZW1zLCBpbnRbXSBpdGVtSURzLCBpbnQgcHJlU29ydFByb3BlcnR5KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBSZW1vdmVEYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtbihpbnQgYnJvd3NlciwgaW50IGNvbHVtbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgUmVtb3ZlRXZlbnRIYW5kbGVyKGludCBpbkhhbmRsZXJSZWYpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFJlbW92ZUV2ZW50TG9vcFRpbWVyKGludCBpblRpbWVyKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBSZXBvc2l0aW9uV2luZG93KGludCB3aW5kb3csIGludCBwYXJlbnRXaW5kb3csIGludCBtZXRob2QpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFJldGFpbk1lbnUoaW50IG1IYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFJldmVhbERhdGFCcm93c2VySXRlbShpbnQgYnJvd3NlciwgaW50IGl0ZW0sIGludCBwcm9wZXJ0eSwgYnl0ZSBvcHRpb25zKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBSdW5TdGFuZGFyZEFsZXJ0KGludCBkaWFsb2dIYW5kbGUsIGludCBtb2RhbEZpbHRlclVQUCwgc2hvcnRbXSBpdGVtSGl0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgU2Nyb2xsUmVjdChSZWN0IHJlY3QsIHNob3J0IGRoLCBzaG9ydCBkdiwgaW50IHVwZGF0ZVJnbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBib29sZWFuIFNlY3RSZWN0KFJlY3Qgc3JjMSwgUmVjdCBzcmMyLCBSZWN0IGRzdFJlY3QpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBTZWN0UmduKGludCBzcmNSZ25BLCBpbnQgc3JjUmduQiwgaW50IGRzdFJnbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFNlbGVjdFdpbmRvdyhpbnQgd0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFNlbmRCZWhpbmQoaW50IHdpbmRvdywgaW50IGJlaGluZFdpbmRvdyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2VuZEV2ZW50VG9FdmVudFRhcmdldChpbnQgdGhlRXZlbnQsIGludCB0aGVUYXJnZXQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldEJldmVsQnV0dG9uQ29udGVudEluZm8oaW50IGluQnV0dG9uLCBDb250cm9sQnV0dG9uQ29udGVudEluZm8gaW5Db250ZW50KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgU2V0Q2xpcChpbnQgcmduSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgU2V0Q29udHJvbDMyQml0TWF4aW11bShpbnQgY0hhbmRsZSwgaW50IG1heGltdW0pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBTZXRDb250cm9sMzJCaXRNaW5pbXVtKGludCBjSGFuZGxlLCBpbnQgbWluaW11bSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFNldENvbnRyb2wzMkJpdFZhbHVlKGludCBjSGFuZGxlLCBpbnQgdmFsdWUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBTZXRDb250cm9sQWN0aW9uKGludCBjSGFuZGxlLCBpbnQgYWN0aW9uUHJvYyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFNldENvbnRyb2xCb3VuZHMoaW50IGNIYW5kbGUsIFJlY3QgYm91bmRzKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRDb250cm9sRGF0YShpbnQgaW5Db250cm9sLCBpbnQgaW5QYXJ0LCBpbnQgaW5UYWdOYW1lLCBpbnQgaW5TaXplLCBDb250cm9sQnV0dG9uQ29udGVudEluZm8gaW5EYXRhKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRDb250cm9sRGF0YShpbnQgaW5Db250cm9sLCBpbnQgaW5QYXJ0LCBpbnQgaW5UYWdOYW1lLCBpbnQgaW5TaXplLCBDb250cm9sVGFiSW5mb1JlY1YxIGluRGF0YSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0Q29udHJvbERhdGEoaW50IGluQ29udHJvbCwgaW50IGluUGFydCwgaW50IGluVGFnTmFtZSwgaW50IGluU2l6ZSwgUmVjdCBpbkRhdGEpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldENvbnRyb2xEYXRhKGludCBpbkNvbnRyb2wsIGludCBpblBhcnQsIGludCBpblRhZ05hbWUsIGludCBpblNpemUsIHNob3J0W10gaW5EYXRhKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRDb250cm9sRGF0YShpbnQgaW5Db250cm9sLCBpbnQgaW5QYXJ0LCBpbnQgaW5UYWdOYW1lLCBpbnQgaW5TaXplLCBpbnRbXSBpbkRhdGEpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldENvbnRyb2xEYXRhKGludCBpbkNvbnRyb2wsIGludCBpblBhcnQsIGludCBpblRhZ05hbWUsIGludCBpblNpemUsIGludCBpbkRhdGEpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldENvbnRyb2xEYXRhKGludCBpbkNvbnRyb2wsIGludCBpblBhcnQsIGludCBpblRhZ05hbWUsIGludCBpblNpemUsIGJ5dGVbXSBpbkRhdGEpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldENvbnRyb2xGb250U3R5bGUoaW50IGluQ29udHJvbCwgQ29udHJvbEZvbnRTdHlsZVJlYyBpblN0eWxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgU2V0Q29udHJvbFBvcHVwTWVudUhhbmRsZShpbnQgY0hhbmRsZSwgaW50IHBvcHVwTWVudUhhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0Q29udHJvbFByb3BlcnR5KGludCBjb250cm9sLCBpbnQgcHJvcGVydHlDcmVhdG9yLCBpbnQgcHJvcGVydHlUYWcsIGludCBwcm9wZXJ0eVNpemUsIGludFtdIHByb3BlcnR5RGF0YSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFNldENvbnRyb2xSZWZlcmVuY2UoaW50IGNIYW5kbGUsIGludCBkYXRhKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRDb250cm9sVGl0bGVXaXRoQ0ZTdHJpbmcoaW50IGNIYW5kbGUsIGludCBzSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgU2V0Q29udHJvbFZpZXdTaXplKGludCBjSGFuZGxlLCBpbnQgdmlld1NpemUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBTZXRDdXJzb3IoaW50IGN1cnNvcik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0RGF0YUJyb3dzZXJDYWxsYmFja3MoaW50IGJyb3dzZXIsIERhdGFCcm93c2VyQ2FsbGJhY2tzICBjYWxsYmFja3MpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzKGludCBicm93c2VyLCBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrcyAgY2FsbGJhY2tzKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXREYXRhQnJvd3Nlckhhc1Njcm9sbEJhcnMoaW50IGNIYW5kbGUsIGJvb2xlYW4gaFNjcm9sbCwgYm9vbGVhbiB2U2Nyb2xsKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXREYXRhQnJvd3Nlckl0ZW1EYXRhQm9vbGVhblZhbHVlKGludCBpdGVtUmVmLCBib29sZWFuIGRhdGEpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldERhdGFCcm93c2VySXRlbURhdGFCdXR0b25WYWx1ZShpbnQgaXRlbVJlZiwgc2hvcnQgdGhlbWVCdXR0b25WYWx1ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUljb24oaW50IGl0ZW1SZWYsIGludCBpY29uUmVmKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXREYXRhQnJvd3Nlckl0ZW1EYXRhSXRlbUlEKGludCBpdGVtUmVmLCBpbnQgaXRlbUlEKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXREYXRhQnJvd3Nlckl0ZW1EYXRhVGV4dChpbnQgaXRlbVJlZiwgaW50IHNIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldERhdGFCcm93c2VyTGlzdFZpZXdEaXNjbG9zdXJlQ29sdW1uKGludCBjSGFuZGxlLCBpbnQgY29sSUQsIGJvb2xlYW4gYik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckJ0bkhlaWdodChpbnQgY0hhbmRsZSwgc2hvcnQgaGVpZ2h0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzYyhpbnQgYnJvd3NlciwgaW50IGNvbHVtbiwgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MgZGVzYyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0RGF0YUJyb3dzZXJTY3JvbGxQb3NpdGlvbihpbnQgY0hhbmRsZSwgaW50IHRvcCwgaW50IGxlZnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyhpbnQgY0hhbmRsZSwgaW50IG51bUl0ZW1zLCBpbnRbXSBpdGVtcywgaW50IG9wZXJhdGlvbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0RGF0YUJyb3dzZXJTZWxlY3Rpb25GbGFncyhpbnQgY0hhbmRsZSwgaW50IHNlbGVjdGlvbkZsYWdzKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXREYXRhQnJvd3NlclRhYmxlVmlld0NvbHVtblBvc2l0aW9uKGludCBicm93c2VyLCBpbnQgY29sdW1uLCBpbnQgcG9zaXRpb24pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldERhdGFCcm93c2VyVGFibGVWaWV3SGlsaXRlU3R5bGUoaW50IGJyb3dzZXIsIGludCBoaWxpdGVTdHlsZSk7ICAKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXREYXRhQnJvd3NlclRhYmxlVmlld0l0ZW1Sb3coaW50IGJyb3dzZXIsIGludCBpdGVtLCBpbnQgcm93KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXREYXRhQnJvd3NlclRhYmxlVmlld05hbWVkQ29sdW1uV2lkdGgoaW50IGJyb3dzZXIsIGludCBjb2x1bW4sIHNob3J0IHdpZHRoKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXREYXRhQnJvd3NlclRhcmdldChpbnQgY0hhbmRsZSwgaW50IHJvb3RJRCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0RXZlbnRMb29wVGltZXJOZXh0RmlyZVRpbWUoaW50IGluVGltZXIsIGRvdWJsZSBpbk5leHRGaXJlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRFdmVudFBhcmFtZXRlcihpbnQgaW5FdmVudCwgaW50IGluTmFtZSwgaW50IGluVHlwZSwgaW50IGluU2l6ZSwgY2hhcltdIGluRGF0YVB0cik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0Rm9udEluZm9Gb3JTZWxlY3Rpb24oaW50IGlTdHlsZVR5cGUsIGludCBpTnVtU3R5bGVzLCBpbnQgaVN0eWxlcywgaW50IGlGUEV2ZW50VGFyZ2V0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRGcm9udFByb2Nlc3MoaW50W10gcHNuKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgU2V0R1dvcmxkKGludCBwb3J0SGFuZGxlLCBpbnQgZ2RIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldEtleWJvYXJkRm9jdXMoaW50IHdIYW5kbGUsIGludCBjSGFuZGxlLCBzaG9ydCBpblBhcnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldE1lbnVDb21tYW5kTWFyayhpbnQgbUhhbmRsZSwgaW50IGNvbW1hbmRJZCwgY2hhciBtYXJrKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRNZW51Rm9udChpbnQgbUhhbmRsZSwgc2hvcnQgZm9udElELCBzaG9ydCBzaXplKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRNZW51SXRlbUNvbW1hbmRLZXkoaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBib29sZWFuIHZpcnR1YWxLZXksIGNoYXIga2V5KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRNZW51SXRlbUhpZXJhcmNoaWNhbE1lbnUoaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBpbnQgaGllck1lbnVIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldE1lbnVJdGVtSWNvbkhhbmRsZShpbnQgbUhhbmRsZSwgc2hvcnQgaXRlbSwgYnl0ZSBpY29uVHlwZSwgaW50IGljb25IYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldE1lbnVJdGVtS2V5R2x5cGgoaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBzaG9ydCBnbHlwaCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0TWVudUl0ZW1Nb2RpZmllcnMoaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBieXRlIG1vZGlmaWVycyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0TWVudUl0ZW1SZWZDb24oaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBpbnQgcmVmQ29uKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcoaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBpbnQgc0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0TWVudVRpdGxlV2l0aENGU3RyaW5nKGludCBtSGFuZGxlLCBpbnQgc0hhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFNldE9yaWdpbihzaG9ydCBoLCBzaG9ydCB2KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgU2V0UG9ydChpbnQgcEhhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFNldFBvcnRCb3VuZHMoaW50IHBvcnQsIFJlY3QgcmVjdCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFNldFBvcnRXaW5kb3dQb3J0KGludCB3SGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgU2V0UHQoUG9pbnQgcCwgc2hvcnQgaCwgc2hvcnQgdik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFNldFJlY3QoUmVjdCByLCBzaG9ydCBsZWZ0LCBzaG9ydCB0b3AsIHNob3J0IHJpZ2h0LCBzaG9ydCBib3R0b20pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBTZXRSZWN0UmduKGludCByZ25IYW5kbGUsIHNob3J0IGxlZnQsIHNob3J0IHRvcCwgc2hvcnQgcmlnaHQsIHNob3J0IGJvdHRvbSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0Um9vdE1lbnUoaW50IG1IYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldFRoZW1lQmFja2dyb3VuZChzaG9ydCBpbkJydXNoLCBzaG9ydCBkZXB0aCwgYm9vbGVhbiBpc0NvbG9yRGV2aWNlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRUaGVtZUN1cnNvcihpbnQgdGhlbWVDdXJzb3IpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldFRoZW1lRHJhd2luZ1N0YXRlKGludCBzdGF0ZSwgYm9vbGVhbiBkaXNwb3NlTm93KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRUaGVtZVdpbmRvd0JhY2tncm91bmQoaW50IHdIYW5kbGUsIHNob3J0IGJydXNoLCBib29sZWFuIHVwZGF0ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0VXBDb250cm9sQmFja2dyb3VuZChpbnQgY0hhbmRsZSwgc2hvcnQgZGVwdGgsIGJvb2xlYW4gaXNDb2xvckRldmljZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFNldFdSZWZDb24oaW50IHdIYW5kbGUsIGludCBkYXRhKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRXaW5kb3dBY3RpdmF0aW9uU2NvcGUoaW50IHdIYW5kbGUsIGludCBzY29wZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFNldFdpbmRvd0JvdW5kcyhpbnQgd2luZG93LCBpbnQgcmVnaW9uQ29kZSwgUmVjdCBnbG9iYWxCb3VuZHMpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldFdpbmRvd0RlZmF1bHRCdXR0b24oaW50IHdIYW5kbGUsIGludCBjSGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRXaW5kb3dHcm91cChpbnQgaW5XaW5kb3csIGludCBpbk5ld0dyb3VwKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRXaW5kb3dHcm91cE93bmVyKGludCBpbkdyb3VwLCBpbnQgaW5XaW5kb3cpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFNldFdpbmRvd0dyb3VwUGFyZW50KGludCBpbkdyb3VwLCBpbnQgaW5OZXdHcm91cCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgU2V0V2luZG93TW9kYWxpdHkoaW50IGluV2luZG93LCBpbnQgaW5Nb2RhbEtpbmQsIGludCBpblVuYXZhaWxhYmxlV2luZG93KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBTZXRXaW5kb3dUaXRsZVdpdGhDRlN0cmluZyhpbnQgd0hhbmRsZSwgaW50IHNIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBTaG93V2luZG93KGludCB3SGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgU2l6ZUNvbnRyb2woaW50IGNIYW5kbGUsIHNob3J0IHcsIHNob3J0IGgpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBTaXplV2luZG93KGludCB3SGFuZGxlLCBzaG9ydCB3LCBzaG9ydCBoLCBib29sZWFuIHVwZGF0ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBib29sZWFuIFN0aWxsRG93bigpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFN5bmNDR0NvbnRleHRPcmlnaW5XaXRoUG9ydChpbnQgaW5Db250ZXh0LCBpbnQgcG9ydCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFN5c0JlZXAoc2hvcnQgZHVyYXRpb24pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFRYTkFjdGl2YXRlKGludCB0eEhhbmRsZSwgaW50IGZyYW1lSUQsIGJvb2xlYW4gc2Nyb2xsQmFyU3RhdGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFRYTkFkanVzdEN1cnNvciAoaW50IGlUWE5PYmplY3QsIGludCBpb0N1cnNvclJnbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFRYTkNsaWNrKGludCBpVFhOT2JqZWN0LCBFdmVudFJlY29yZCBpRXZlbnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFRYTkNvcHkoaW50IHR4SGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBUWE5DdXQoaW50IHR4SGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBUWE5EYXRhU2l6ZShpbnQgdHhIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBUWE5EZWxldGVPYmplY3QoaW50IHR4SGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgVFhORHJhdyhpbnQgdHhIYW5kbGUsIGludCBnRGV2aWNlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBUWE5FY2hvTW9kZShpbnQgdHhIYW5kbGUsIGNoYXIgZWNob0NoYXJhY3RlciwgaW50IGVuY29kaW5nLCBib29sZWFuIG9uKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgVFhORm9jdXMoaW50IHR4SGFuZGxlLCBib29sZWFuIGJlY29taW5nRm9jdXNlZCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgVFhOR2V0RGF0YShpbnQgdHhIYW5kbGUsIGludCBzdGFydE9mZnNldCwgaW50IGVuZE9mZnNldCwgaW50W10gZGF0YUhhbmRsZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgVFhOR2V0TGluZUNvdW50KGludCB0eEhhbmRsZSwgaW50W10gbGluZVRvdGFsKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBUWE5HZXRMaW5lTWV0cmljcyhpbnQgaVRYTk9iamVjdCwgaW50IGlMaW5lTnVtYmVyLCBpbnQgW10gb0xpbmVXaWR0aCwgaW50IFtdIG9MaW5lSGVpZ2h0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBUWE5HZXRUWE5PYmplY3RDb250cm9scyhpbnQgaVRYTk9iamVjdCwgaW50IGlDb250cm9sQ291bnQsIGludCBbXSBpQ29udHJvbFRhZ3MsIGludCBbXSBvQ29udHJvbERhdGEpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFRYTkdldFJlY3RCb3VuZHMoaW50IGlUWE5PYmplY3QsIFJlY3Qgb1ZpZXdSZWN0LCBUWE5Mb25nUmVjdCBvRGVzdGluYXRpb25SZWN0LCBUWE5Mb25nUmVjdCBvVGV4dFJlY3QpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBUWE5HZXRTZWxlY3Rpb24oaW50IHR4SGFuZGxlLCBpbnRbXSBzdGFydE9mZnNldCwgaW50W10gZW5kT2Zmc2V0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgVFhOR2V0Vmlld1JlY3QgKGludCBpVFhOT2JqZWN0LCBSZWN0IG9WaWV3UmVjdCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgVFhOSW5pdFRleHRlbnNpb24oaW50IGlEZWZhdWx0Rm9udHMsIGludCBpQ291bnREZWZhdWx0Rm9udHMsIGludCBpVXNhZ2VGbGFncyk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgVFhOTmV3T2JqZWN0KGludCBpRmlsZVNwZWMsIGludCBpV2luZHcsIFJlY3QgaUZyYW1lLCBpbnQgaUZyYW1lT3B0aW9ucywgaW50IGlGcmFtZVR5cGUsIGludCBpRmlsZVR5cGUsIGludCBpUGVybWFuZW50RW5jb2RpbmcsIGludCBbXSBvVFhOT2JqZWN0LCBpbnRbXSBvVFhORnJhbWVJRCwgaW50IGlSZWZDcG0pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFRYTk9mZnNldFRvUG9pbnQoaW50IHR4SGFuZGxlLCBpbnQgb2Zmc2V0LCBQb2ludCBwb2ludCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgVFhOUGFzdGUoaW50IHR4SGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBUWE5Qb2ludFRvT2Zmc2V0IChpbnQgaVRYTk9iamVjdCwgUG9pbnQgaVBvaW50LCBpbnQgW10gb09mZnNldCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFRYTlNlbGVjdEFsbChpbnQgdHhIYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBUWE5TZXRSZWN0Qm91bmRzKGludCBpVFhOT2JqZWN0LCBSZWN0IGlWaWV3UmVjdCwgVFhOTG9uZ1JlY3QgaURlc3RpbmF0aW9uUmVjdCwgYm9vbGVhbiBpVXBkYXRlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBUWE5TZXREYXRhKGludCBpVFhOT2JqZWN0LCBpbnQgaURhdGFUeXBlLCBjaGFyW10gaURhdGFQdHIsIGludCBpRGF0YVNpemUsIGludCBpU3RhcnRPZmZzZXQsIGludCBpRW5kT2Zmc2V0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgVFhOU2V0RnJhbWVCb3VuZHMoaW50IHR4SGFuZGxlLCBpbnQgdG9wLCBpbnQgbGVmdCwgaW50IGJvdHRvbSwgaW50IHJpZ2h0LCBpbnQgZnJhbWVJRCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSBpbnQgVFhOU2V0U2VsZWN0aW9uKGludCB0eEhhbmRsZSwgaW50IHN0YXJ0T2Zmc2V0LCBpbnQgZW5kT2Zmc2V0KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBUWE5TZXRUWE5PYmplY3RDb250cm9scyhpbnQgaVRYTk9iamVjdCwgYm9vbGVhbiBpQ2xlYXJBbGwsIGludCBpQ29udHJvbENvdW50LCBpbnRbXSBpQ29udHJvbFRhZ3MsIGludFtdIGlDb250cm9sRGF0YSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFRYTlNob3dTZWxlY3Rpb24oaW50IHR4SGFuZGxlLCBib29sZWFuIHNob3dFbmQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgc2hvcnQgVGVzdENvbnRyb2woaW50IGNvbnRyb2wsIFBvaW50IHBvaW50KTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgVGV4dEZhY2Uoc2hvcnQgZmFjZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFRleHRGb250KHNob3J0IGZvbnRJRCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFRleHRNb2RlKHNob3J0IG1vZGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBUZXh0U2l6ZShzaG9ydCBzaXplKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHNob3J0IFRleHRXaWR0aChieXRlW10gdGV4dEJ1Ziwgc2hvcnQgZmlyc3RCeXRlLCBzaG9ydCBieXRlQ291bnQpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFRyYWNrTW91c2VMb2NhdGlvbldpdGhPcHRpb25zKGludCBpblBvcnQsIGludCBpbk9wdGlvbnMsIGRvdWJsZSBpblRpbWUsIFBvaW50IG91dFB0LCBpbnQgW10gb3V0TW9kaWZpZXJzLCBzaG9ydFtdIG91dFJlc3VsdCk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIFVuaW9uUmVjdChSZWN0IHNyY0EsIFJlY3Qgc3JjQiwgUmVjdCBkc3QpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBVbmlvblJnbihpbnQgc3JjUmduQSwgaW50IHNyY1JnbkIsIGludCBkc3RSZ24pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFVubG9ja1BvcnRCaXRzKGludCBwb3J0SGFuZGxlKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgVXBkYXRlQ29udHJvbHMoaW50IHdIYW5kbGUsIGludCByZ25IYW5kbGUpOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IFVwZGF0ZURhdGFCcm93c2VySXRlbXMoaW50IGNIYW5kbGUsIGludCBjb250YWluZXIsIGludCBudW1JdGVtcywgaW50W10gaXRlbXMsIGludCBwcmVTb3J0UHJvcGVydHksIGludCBwcm9wZXJ0eUlEKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIGludCBab29tV2luZG93SWRlYWwoaW50IGluV2luZG93LCBzaG9ydCBpblBhcnRDb2RlLCBQb2ludCBpb0lkZWFsU2l6ZSk7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIG1lbWNweShBVFNUcmFwZXpvaWQgZGVzdCwgaW50IHNyYywgaW50IG4pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBtZW1jcHkoYnl0ZVtdIGRlc3QsIGludCBzcmMsIGludCBuKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgbWVtY3B5KGNoYXJbXSBkZXN0LCBpbnQgc3JjLCBpbnQgbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIG1lbWNweShpbnRbXSBkZXN0LCBpbnQgc3JjLCBpbnQgbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIG1lbWNweShpbnQgZGVzdCwgaW50W10gc3JjLCBpbnQgbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIG1lbWNweShpbnQgZGVzdCwgUGl4TWFwIHNyYywgaW50IG4pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBtZW1jcHkoaW50IGRlc3QsIEN1cnNvciBzcmMsIGludCBuKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgbWVtY3B5KEdEZXZpY2UgZGVzdCwgaW50IHNyYywgaW50IG4pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBtZW1jcHkoUGl4TWFwIGRlc3QsIGludCBzcmMsIGludCBuKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgbWVtY3B5KEZvbnRTZWxlY3Rpb25RRFN0eWxlIGRlc3QsIGludCBzcmMsIGludCBuKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgbWVtY3B5KEhNSGVscENvbnRlbnRSZWMgZGVzdCwgaW50IHNyYywgaW50IG4pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBtZW1jcHkoaW50IGRlc3QsIEhNSGVscENvbnRlbnRSZWMgc3JjLCBpbnQgbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIG1lbWNweShpbnQgZGVzdCwgQml0TWFwIHNyYywgaW50IG4pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBtZW1jcHkoaW50IGRlc3QsIGNoYXJbXSBzcmMsIGludCBuKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgbWVtY3B5KGludCBkZXN0LCBpbnQgc3JjLCBpbnQgbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIG1lbWNweShpbnQgZGVzdCwgYnl0ZVtdIHNyYywgaW50IG4pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBtZW1jcHkoaW50IGRlc3QsIEZvbnRTZWxlY3Rpb25RRFN0eWxlIHNyYywgaW50IG4pOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgdm9pZCBtZW1jcHkoUmVjdCBkZXN0LCBpbnQgc3JjLCBpbnQgbik7CitwdWJsaWMgc3RhdGljIGZpbmFsIG5hdGl2ZSB2b2lkIG1lbWNweShpbnQgZGVzdCwgUmVjdCBzcmMsIGludCBuKTsKK3B1YmxpYyBzdGF0aWMgZmluYWwgbmF0aXZlIHZvaWQgbWVtc2V0KGludCBkZXN0LCBpbnQgdmFsdWUsIGludCBzaXplKTsKIAotCS8vIG1lbnUgZXZlbnQgdHlwZXMKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRNZW51T3BlbmluZz0JNDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRNZW51Q2xvc2VkPQk1OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudE1lbnVQb3B1bGF0ZT0JOTsKLQkKLQkvLyBGb3IgdXNlIHdpdGggR2V0L1NldE1lbnVJdGVtTW9kaWZpZXJzCi0JcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIGtNZW51Tm9Nb2RpZmllcnMJCT0gMDsJCS8qIE1hc2sgZm9yIG5vIG1vZGlmaWVycyovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIGtNZW51U2hpZnRNb2RpZmllcgkJPSAoMSA8PCAwKTsgLyogTWFzayBmb3Igc2hpZnQga2V5IG1vZGlmaWVyKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUga01lbnVPcHRpb25Nb2RpZmllcgk9ICgxIDw8IDEpOyAvKiBNYXNrIGZvciBvcHRpb24ga2V5IG1vZGlmaWVyKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUga01lbnVDb250cm9sTW9kaWZpZXIJPSAoMSA8PCAyKTsgLyogTWFzayBmb3IgY29udHJvbCBrZXkgbW9kaWZpZXIqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBrTWVudU5vQ29tbWFuZE1vZGlmaWVyCT0gKDEgPDwgMyk7IC8qIE1hc2sgZm9yIG5vIGNvbW1hbmQga2V5IG1vZGlmaWVyKi8KLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBNZW51U2VsZWN0KHNob3J0W10gd2hlcmUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgSGlsaXRlTWVudShzaG9ydCBtZW51SUQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRHJhd01lbnVCYXIoKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEludmFsTWVudUJhcigpOwotCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IENyZWF0ZU5ld01lbnUoaW50IG1lbnVJRCwgaW50IG1lbnVBdHRyaWJ1dGVzLCBpbnRbXSBtZW51UmVmKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIERpc3Bvc2VNZW51KGludCBtSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgSW5pdENvbnRleHR1YWxNZW51cygpOwotCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBJbnNlcnRNZW51KGludCBtSGFuZGxlLCBzaG9ydCBiZWZvcmVJRCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBEZWxldGVNZW51KHNob3J0IG1lbnVJRCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBDbGVhck1lbnVCYXIoKTsKLQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBzaG9ydCBDb3VudE1lbnVJdGVtcyhpbnQgbUhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IERlbGV0ZU1lbnVJdGVtcyhpbnQgbUhhbmRsZSwgc2hvcnQgZmlyc3RJdGVtLCBpbnQgbnVtSXRlbXMpOwotCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldE1lbnVJdGVtUmVmQ29uKGludCBtSGFuZGxlLCBzaG9ydCBpbmRleCwgaW50W10gcmVmQ29uKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0TWVudUl0ZW1SZWZDb24oaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBpbnQgcmVmQ29uKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0TWVudUl0ZW1Db21tYW5kS2V5KGludCBtSGFuZGxlLCBzaG9ydCBpbmRleCwgYm9vbGVhbiB2aXJ0dWFsS2V5LCBjaGFyIGtleSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldE1lbnVJdGVtTW9kaWZpZXJzKGludCBtSGFuZGxlLCBzaG9ydCBpbmRleCwgYnl0ZSBtb2RpZmllcnMpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRNZW51SXRlbUtleUdseXBoKGludCBtSGFuZGxlLCBzaG9ydCBpbmRleCwgc2hvcnQgZ2x5cGgpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBJbnZhbGlkYXRlTWVudUl0ZW1zKGludCBtSGFuZGxlLCBzaG9ydCBpbmRleCwgaW50IG51bUl0ZW1zKTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBBcHBlbmRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcoaW50IG1IYW5kbGUsIGludCBzSGFuZGxlLCBpbnQgYXR0cmlidXRlcywgaW50IGNvbW1hbmRJRCwgc2hvcnRbXSBvdXRJdGVtSW5kZXgpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBJbnNlcnRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcoaW50IG1IYW5kbGUsIGludCBzSGFuZGxlLCBzaG9ydCBpbmRleCwgaW50IGF0dHJpYnV0ZXMsIGludCBjb21tYW5kSUQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcoaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBpbnQgc0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IENvcHlNZW51SXRlbVRleHRBc0NGU3RyaW5nKGludCBtSGFuZGxlLCBzaG9ydCBpbmRleCwgaW50W10gc0hhbmRsZSk7Ci0KLQkvL3B1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRNZW51SXRlbUNvbW1hbmRJRChpbnQgbUhhbmRsZSwgc2hvcnQgaW5kZXgsIGludCBjb21tYW5kSWQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRW5hYmxlTWVudUNvbW1hbmQoaW50IG1IYW5kbGUsIGludCBjb21tYW5kSWQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRGlzYWJsZU1lbnVDb21tYW5kKGludCBtSGFuZGxlLCBpbnQgY29tbWFuZElkKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIElzTWVudUNvbW1hbmRFbmFibGVkIChpbnQgbUhhbmRsZSwgaW50IGNvbW1hbmRJZCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldEluZE1lbnVJdGVtV2l0aENvbW1hbmRJRChpbnQgbUhhbmRsZSwgaW50IGNvbW1hbmRJZCwgaW50IGluZGV4LCBpbnRbXSBvdXRNZW51LCBzaG9ydFtdIG91dEluZGV4KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIERlbGV0ZU1lbnVJdGVtKGludCBtSGFuZGxlLCBzaG9ydCBpbmRleCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldE1lbnVJdGVtQ29tbWFuZElEKGludCBtSGFuZGxlLCBzaG9ydCBpbmRleCwgaW50W10gb3V0Q29tbWFuZElEKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBzaG9ydCBHZXRNZW51SUQoaW50IG1IYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRNZW51SGFuZGxlKHNob3J0IG1lbnVJRCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFBvcFVwTWVudVNlbGVjdChpbnQgbUhhbmRsZSwgc2hvcnQgdG9wLCBzaG9ydCBsZWZ0LCBzaG9ydCBwb3BVcEl0ZW0pOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRSb290TWVudShpbnQgbUhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFJldGFpbk1lbnUoaW50IG1IYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBSZWxlYXNlTWVudShpbnQgbUhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldE1lbnVUaXRsZVdpdGhDRlN0cmluZyhpbnQgbUhhbmRsZSwgaW50IHNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRNZW51SXRlbUhpZXJhcmNoaWNhbE1lbnUoaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBpbnQgaGllck1lbnVIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRNZW51SXRlbUhpZXJhcmNoaWNhbE1lbnUoaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBpbnRbXSBvdXRIaWVyTWVudUhhbmRsZSk7Ci0JLy9wdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEluc2VydE1lbnVJdGVtKGludCBtSGFuZGxlLCBieXRlW10gdGV4dCwgc2hvcnQgaW5kZXgpOwotCS8vcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBBcHBlbmRNZW51KGludCBtSGFuZGxlLCBieXRlW10gdGV4dCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IENoYW5nZU1lbnVJdGVtQXR0cmlidXRlcyhpbnQgbUhhbmRsZSwgc2hvcnQgaW5kZXgsIGludCBzZXRBdHRyaWJ1dGVzLCBpbnQgY2xlYXJBdHRyaWJ1dGVzKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIENoZWNrTWVudUl0ZW0oaW50IG1IYW5kbGUsIHNob3J0IGluZGV4LCBib29sZWFuIGNoZWNrZWQpOwkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0TWVudUNvbW1hbmRNYXJrKGludCBtSGFuZGxlLCBpbnQgY29tbWFuZElkLCBjaGFyW10gb3V0TWFyayk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldE1lbnVDb21tYW5kTWFyayhpbnQgbUhhbmRsZSwgaW50IGNvbW1hbmRJZCwgY2hhciBtYXJrKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIElzVmFsaWRNZW51KGludCBtSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNldE1lbnVJRChpbnQgbUhhbmRsZSwgc2hvcnQgaWQpOwkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIElzTWVudUl0ZW1FbmFibGVkKGludCBtSGFuZGxlLCBzaG9ydCBpbmRleCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBEaXNhYmxlTWVudUl0ZW0oaW50IG1IYW5kbGUsIHNob3J0IGluZGV4KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEVuYWJsZU1lbnVJdGVtKGludCBtSGFuZGxlLCBzaG9ydCBpbmRleCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldE1lbnVGb250KGludCBtSGFuZGxlLCBzaG9ydCBmb250SUQsIHNob3J0IHNpemUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRNZW51Rm9udChpbnQgbUhhbmRsZSwgc2hvcnRbXSBmb250SUQsIHNob3J0W10gc2l6ZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgc2hvcnQgR2V0TWVudVdpZHRoKGludCBtSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIENhbGNNZW51U2l6ZShpbnQgbUhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldE1lbnVJdGVtSWNvbkhhbmRsZShpbnQgbUhhbmRsZSwgc2hvcnQgaXRlbSwgYnl0ZSBpY29uVHlwZSwgaW50IGljb25IYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRNZW51SXRlbUNvbW1hbmRJRChpbnQgbUhhbmRsZSwgc2hvcnQgaXRlbSwgaW50IGNvbW1hbmRJRCk7Ci0KLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQkvLyBDb250cm9sIE1hbmFnZXIKLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCS8vIGVyciBjb2RlcwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGVyckNvdWxkbnRTZXRGb2N1cyAgICAgICAgICAgIAk9IC0zMDU4NTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBlcnJDb250cm9sSXNOb3RFbWJlZGRlcgkJCT0gLTMwNTkwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGVyckNhbnRFbWJlZFJvb3QJCQkJPSAtMzA1OTU7Ci0KLQkvLyBjb250cm9sIHByb2MgSURzCi0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbEJldmVsQnV0dG9uU21hbGxCZXZlbFByb2M9IDMyOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xCZXZlbEJ1dHRvbk5vcm1hbEJldmVsUHJvYz0gMzM7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbEJldmVsQnV0dG9uTGFyZ2VCZXZlbFByb2M9IDM0OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xTbGlkZXJQcm9jICAgICAgICAgICAgPSA0ODsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sUHJvZ3Jlc3NCYXJQcm9jICAgICAgID0gODA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbFRhYlNtYWxsUHJvYwkJCT0gMTI5OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xTZXBhcmF0b3JMaW5lUHJvYwkJPSAxNDQ7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbEdyb3VwQm94VGV4dFRpdGxlUHJvYyA9IDE2MDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sUG9wdXBBcnJvd0Vhc3RQcm9jCT0gMTkyOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xVc2VyUGFuZVByb2MJCQk9IDI1NjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sRWRpdFRleHRQcm9jCQkJPSAyNzI7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbFN0YXRpY1RleHRQcm9jICAgICAgICA9IDI4ODsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sTGlzdEJveFByb2MgICAJCT0gMzUyOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xMaXN0Qm94QXV0b1NpemVQcm9jICAgPSAzNTM7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbFB1c2hCdXR0b25Qcm9jICAgCQk9IDM2ODsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sQ2hlY2tCb3hQcm9jICAgCQk9IDM2OTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sUmFkaW9CdXR0b25Qcm9jICAgCT0gMzcwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xDaGVja0JveEF1dG9Ub2dnbGVQcm9jPSAzNzE7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbFJhZGlvQnV0dG9uQXV0b1RvZ2dsZVByb2M9IDM3MjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sUHVzaEJ1dExlZnRJY29uUHJvYyAgID0gMzc0OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xTY3JvbGxCYXJMaXZlUHJvYyAgICAgPSAzODY7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbFBvcHVwQnV0dG9uUHJvYyAgICAgICA9IDQwMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sRWRpdFVuaWNvZGVUZXh0UHJvYyAgID0gOTEyOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgcG9wdXBNZW51UHJvYyAgICAgICAgICAgICAgICAgPSAxMDA4OwotCi0JLy8gbWV0YSBwYXJ0IGNvZGVzIGZvciBHZXRDb250cm9sUmVnaW9uIGV0Yy4KLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sRW50aXJlQ29udHJvbAkJCT0gMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sU3RydWN0dXJlTWV0YVBhcnQgICAgID0gKHNob3J0KSAtMTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sQ29udGVudE1ldGFQYXJ0ICAgICAgID0gKHNob3J0KSAtMjsKLQotCS8vIHBhcnQgY29kZXMKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGluRGVzawkJPSAwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgaW5Ob1dpbmRvdwk9IDA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBpbk1lbnVCYXIJCT0gMTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGluU3lzV2luZG93CT0gMjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGluQ29udGVudAkJPSAzOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgaW5EcmFnCQk9IDQ7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBpbkdyb3cJCT0gNTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGluR29Bd2F5CQk9IDY7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBpblpvb21JbiAJCT0gNzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGluWm9vbU91dAkJPSA4OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgaW5Db2xsYXBzZUJveAk9IDExOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQgaW5Qcm94eUljb24JCT0gMTI7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBpblRvb2xiYXJCdXR0b24JPSAxMzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGluU3RydWN0dXJlCQk9IDE1OwotCQotCS8vIG90aGVyIHBhcnQgY29kZXMKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sVXBCdXR0b25QYXJ0CT0gMjA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbERvd25CdXR0b25QYXJ0PSAyMTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sUGFnZVVwUGFydAk9IDIyOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xQYWdlRG93blBhcnQJPSAyMzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sSW5kaWNhdG9yUGFydAk9IDEyOTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IHRodW1iRHJhZwkJCQk9IDk5OTsKLQkKLQkvLyB0YWdzCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xQcm9ncmVzc0JhckluZGV0ZXJtaW5hdGVUYWcgPSAoJ2knPDwyNCkgKyAoJ24nPDwxNikgKyAoJ2QnPDw4KSArICdlJzsKLQkKLQkvLyBCZXZlbEJ1dHRvbiBjb250cm9sIHR5cGVzCi0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbEJlaGF2aW9yUHVzaGJ1dHRvbiAgICA9IDA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbEJlaGF2aW9yVG9nZ2xlcyAgICAgICA9IDB4MDEwMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sQmVoYXZpb3JTdGlja3kgICAgICAgID0gMHgwMjAwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xCZWhhdmlvclNpbmdsZVZhbHVlTWVudSA9IDA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbEJlaGF2aW9yQ29tbWFuZE1lbnUgICA9IDB4MjAwMDsgLyogbWVudSBob2xkcyBjb21tYW5kcywgbm90IGNob2ljZXMuIE92ZXJyaWRlcyBtdWx0aS12YWx1ZSBiaXQuKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sQmVoYXZpb3JNdWx0aVZhbHVlTWVudSA9IDB4NDAwMDsgLyogb25seSBtYWtlcyBzZW5zZSB3aGVuIGEgbWVudSBpcyBhdHRhY2hlZC4qLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xCZWhhdmlvck9mZnNldENvbnRlbnRzID0gKHNob3J0KSAweDgwMDA7Ci0KLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sQmV2ZWxCdXR0b25NZW51T25Cb3R0b20gPSAwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xCZXZlbEJ1dHRvbk1lbnVPblJpZ2h0ID0gKDEgPDwgMik7Ci0KLQkKLQkvLyBjb250cm9sIGV2ZW50IHR5cGVzCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q29udHJvbEJvdW5kc0NoYW5nZWQJPSAxNTQ7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTZXRDb250cm9sQWN0aW9uKGludCBjSGFuZGxlLCBpbnQgYWN0aW9uUHJvYyk7Ci0KLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgTmV3Q29udHJvbChpbnQgd2luZG93SGFuZGxlLCBib29sZWFuIGluaXRpYWxseVZpc2libGUsIHNob3J0IGluaXRpYWwsIHNob3J0IG1pbiwgc2hvcnQgbWF4LCBzaG9ydCBwcm9jSUQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgRGlzcG9zZUNvbnRyb2woaW50IGNIYW5kbGUpOwotCQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0Um9vdENvbnRyb2woaW50IHdpbmRvd0hhbmRsZSwgaW50W10gY0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IENyZWF0ZVJvb3RDb250cm9sKGludCB3aW5kb3dIYW5kbGUsIGludFtdIGNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBFbWJlZENvbnRyb2woaW50IGNIYW5kbGUsIGludCBwYXJlbnRDb250cm9sSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgQ291bnRTdWJDb250cm9scyhpbnQgY0hhbmRsZSwgc2hvcnRbXSBjb3VudCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldEluZGV4ZWRTdWJDb250cm9sKGludCBjSGFuZGxlLCBzaG9ydCBpbmRleCwgaW50W10gb3V0SGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0U3VwZXJDb250cm9sKGludCBjSGFuZGxlLCBpbnRbXSBwYXJlbnRIYW5kbGUpOwotCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldENvbnRyb2xPd25lcihpbnQgY0hhbmRsZSk7Ci0JLy9wdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgRmluZENvbnRyb2xVbmRlck1vdXNlKHNob3J0W10gd2hlcmUsIGludCB3aW5kb3dIYW5kbGUsIHNob3J0W10gY3BhcnQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHNob3J0IFRlc3RDb250cm9sKGludCBjSGFuZGxlLCBzaG9ydFtdIHdoZXJlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBzaG9ydCBIYW5kbGVDb250cm9sQ2xpY2soaW50IGNIYW5kbGUsIHNob3J0W10gd2hlcmUsIGludCBtb2RpZmllcnMsIGludCBhY3Rpb25VUFApOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgTW92ZUNvbnRyb2woaW50IGNIYW5kbGUsIHNob3J0IHgsIHNob3J0IHkpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU2l6ZUNvbnRyb2woaW50IGNIYW5kbGUsIHNob3J0IHcsIHNob3J0IGgpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU2hvd0NvbnRyb2woaW50IGNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgSGlkZUNvbnRyb2woaW50IGNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gSXNWYWxpZENvbnRyb2xIYW5kbGUoaW50IGNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU2V0Q29udHJvbFJlZmVyZW5jZShpbnQgY0hhbmRsZSwgaW50IGRhdGEpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRDb250cm9sUmVmZXJlbmNlKGludCBjSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0Q29udHJvbFRpdGxlV2l0aENGU3RyaW5nKGludCBjSGFuZGxlLCBpbnQgc0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldENvbnRyb2xUaXRsZUFzQ0ZTdHJpbmcoaW50IGNIYW5kbGUsIGludFtdIHNIYW5kbGUpOwotCS8vcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IHNldENvbnRyb2xUb29sVGlwVGV4dChpbnQgY0hhbmRsZSwgc2hvcnRbXSBib3VuZHMsIGludCBzSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEdldENvbnRyb2xCb3VuZHMoaW50IGNIYW5kbGUsIHNob3J0W10gYm91bmRzKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNldENvbnRyb2xCb3VuZHMoaW50IGNIYW5kbGUsIHNob3J0W10gYm91bmRzKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgQ3JlYXRlVXNlclBhbmVDb250cm9sKGludCB3aW5kb3dIYW5kbGUsIHNob3J0W10gYm91bmRzLCBpbnQgZmVhdHVyZXMsIGludFtdIGNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGJvb2xlYW4gSXNDb250cm9sVmlzaWJsZShpbnQgY0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldENvbnRyb2xWaXNpYmlsaXR5KGludCBjSGFuZGxlLCBib29sZWFuIGluSXNWaXNpYmxlLCBib29sZWFuIGluRG9EcmF3KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIElzQ29udHJvbEFjdGl2ZShpbnQgY0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEVuYWJsZUNvbnRyb2woaW50IGNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBEaXNhYmxlQ29udHJvbChpbnQgY0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgYm9vbGVhbiBJc0NvbnRyb2xFbmFibGVkKGludCBjSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0Q29udHJvbDMyQml0TWluaW11bShpbnQgY0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTZXRDb250cm9sMzJCaXRNaW5pbXVtKGludCBjSGFuZGxlLCBpbnQgbWluaW11bSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTZXRDb250cm9sTWluaW11bShpbnQgY0hhbmRsZSwgc2hvcnQgbWluaW11bSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldENvbnRyb2wzMkJpdE1heGltdW0oaW50IGNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU2V0Q29udHJvbDMyQml0TWF4aW11bShpbnQgY0hhbmRsZSwgaW50IG1heGltdW0pOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRDb250cm9sMzJCaXRWYWx1ZShpbnQgY0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgc2hvcnQgR2V0Q29udHJvbFZhbHVlKGludCBjSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFNldENvbnRyb2wzMkJpdFZhbHVlKGludCBjSGFuZGxlLCBpbnQgdmFsdWUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRDb250cm9sVmlld1NpemUoaW50IGNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU2V0Q29udHJvbFZpZXdTaXplKGludCBjSGFuZGxlLCBpbnQgdmlld1NpemUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRCZXN0Q29udHJvbFJlY3QoaW50IGNIYW5kbGUsIHNob3J0W10gb3V0UmVjdCwgc2hvcnRbXSBvdXRCYXNlTGluZU9mZnNldCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldENvbnRyb2xLaW5kKGludCBjSGFuZGxlLCBpbnRbXSBvdXRDb250cm9sS2luZCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldENvbnRyb2xEYXRhKGludCBjSGFuZGxlLCBzaG9ydCBwYXJ0LCBpbnQgdGFnLCBzaG9ydFtdIGRhdGEpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRDb250cm9sRGF0YShpbnQgY0hhbmRsZSwgc2hvcnQgcGFydCwgaW50IHRhZywgaW50W10gZGF0YSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldENvbnRyb2xEYXRhKGludCBjSGFuZGxlLCBzaG9ydCBwYXJ0LCBpbnQgdGFnLCBpbnQgZGF0YSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldENvbnRyb2xEYXRhKGludCBjSGFuZGxlLCBzaG9ydCBwYXJ0LCBpbnQgdGFnLCBzaG9ydFtdIGRhdGEpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHNob3J0IEhhbmRsZUNvbnRyb2xLZXkoaW50IGNIYW5kbGUsIHNob3J0IGtleUNvZGUsIGNoYXIgY2hhckNvZGUsIGludCBtb2RpZmllcnMpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRDb250cm9sRm9udFN0eWxlKGludCBjSGFuZGxlLCBzaG9ydCBmb250LCBzaG9ydCBzaXplLCBzaG9ydCBzdHlsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldFVwQ29udHJvbEJhY2tncm91bmQoaW50IGNIYW5kbGUsIHNob3J0IGRlcHRoLCBib29sZWFuIGlzQ29sb3JEZXZpY2UpOwotCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldENvbnRyb2xSZWdpb24oaW50IGNIYW5kbGUsIHNob3J0IGluUGFydCwgaW50IHJnbkhhbmRsZSk7Ci0JCi0JcHVibGljIHN0YXRpYyBzaG9ydCBrQ29udHJvbENvbnRlbnRDSWNvbkhhbmRsZT0gMTMwOwotCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xCZXZlbEJ1dHRvbk93bmVkTWVudVJlZlRhZyA9ICgnbyc8PDI0KSArICgnbSc8PDE2KSArICgncic8PDgpICsgJ2YnOyAvKiBNZW51UmVmIChjb250cm9sIHdpbGwgZGlzcG9zZSkqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sQmV2ZWxCdXR0b25DZW50ZXJQb3B1cEdseXBoVGFnID0gKCdwJzw8MjQpICsgKCdnJzw8MTYpICsgKCdsJzw8OCkgKyAnYyc7IC8qIEJvb2xlYW46IHRydWUgPSBjZW50ZXIsIGZhbHNlID0gYm90dG9tIHJpZ2h0Ki8KLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXRCZXZlbEJ1dHRvbkNvbnRlbnRJbmZvKGludCBjSGFuZGxlLCBzaG9ydCBjb250cm9sQ29udGVudFR5cGUsIGludCBjb250cm9sQ29udGVudEhhbmRsZSk7CQotCi0JCi0JLy8gU2xpZGVyIHZhcmlhbnRzCi0JcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQ29udHJvbFNsaWRlckxpdmVGZWVkYmFjawk9ICgxIDw8IDApOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xTbGlkZXJIYXNUaWNrTWFya3MJPSAoMSA8PCAxKTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtDb250cm9sU2xpZGVyUmV2ZXJzZURpcmVjdGlvbgk9ICgxIDw8IDIpOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0NvbnRyb2xTbGlkZXJOb25EaXJlY3Rpb25hbAk9ICgxIDw8IDMpOwotCi0JLy8gRGF0YSBCcm93c2VyCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbU5vUHJvcGVydHkgPSAwOyAgIC8qIFRoZSBhbnRpLXByb3BlcnR5IChubyBhc3NvY2lhdGVkIGRhdGEpICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbUlzQWN0aXZlUHJvcGVydHkgPSAxOyAvKiBCb29sZWFuIHR5cGVkIGRhdGEgKGRlZmF1bHRzIHRvIHRydWUpICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbUlzU2VsZWN0YWJsZVByb3BlcnR5ID0gMjsgLyogQm9vbGVhbiB0eXBlZCBkYXRhIChkZWZhdWx0cyB0byB0cnVlKSAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckl0ZW1Jc0VkaXRhYmxlUHJvcGVydHkgPSAzOyAvKiBCb29sZWFuIHR5cGVkIGRhdGEgKGRlZmF1bHRzIHRvIGZhbHNlLCB1c2VkIGZvciBlZGl0YWJsZSBwcm9wZXJ0aWVzKSAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckl0ZW1Jc0NvbnRhaW5lclByb3BlcnR5ID0gNDsgLyogQm9vbGVhbiB0eXBlZCBkYXRhIChkZWZhdWx0cyB0byBmYWxzZSkgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJDb250YWluZXJJc09wZW5hYmxlUHJvcGVydHkgPSA1OyAvKiBCb29sZWFuIHR5cGVkIGRhdGEgKGRlZmF1bHRzIHRvIHRydWUpICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyQ29udGFpbmVySXNDbG9zYWJsZVByb3BlcnR5ID0gNjsgLyogQm9vbGVhbiB0eXBlZCBkYXRhIChkZWZhdWx0cyB0byB0cnVlKSAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckNvbnRhaW5lcklzU29ydGFibGVQcm9wZXJ0eSA9IDc7IC8qIEJvb2xlYW4gdHlwZWQgZGF0YSAoZGVmYXVsdHMgdG8gdHJ1ZSkgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJJdGVtU2VsZklkZW50aXR5UHJvcGVydHkgPSA4OyAvKiBrRGF0YUJyb3dzZXJJY29uQW5kVGV4dFR5cGUgKGRpc3BsYXkgcHJvcGVydHk7IENvbHVtblZpZXcgb25seSkgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJDb250YWluZXJBbGlhc0lEUHJvcGVydHkgPSA5OyAvKiBEYXRhQnJvd3Nlckl0ZW1JRCAoYWxpYXMvc3ltbGluayBhbiBpdGVtIHRvIGEgY29udGFpbmVyIGl0ZW0pICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyQ29sdW1uVmlld1ByZXZpZXdQcm9wZXJ0eSA9IDEwOyAvKiBrRGF0YUJyb3dzZXJDdXN0b21UeXBlIChkaXNwbGF5IHByb3BlcnR5OyBDb2x1bW5WaWV3IG9ubHkpICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbVBhcmVudENvbnRhaW5lclByb3BlcnR5ID0gMTE7IC8qIERhdGFCcm93c2VySXRlbUlEICh0aGUgcGFyZW50IG9mIHRoZSBzcGVjaWZpZWQgaXRlbSwgdXNlZCBieSBDb2x1bW5WaWV3KSAqLwotCi0JLy8gTm90aWZpY2F0aW9ucyB1c2VkIGluIERhdGFCcm93c2VySXRlbU5vdGlmaWNhdGlvblByb2NQdHIKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJJdGVtQWRkZWQgICAgICAgICA9IDE7ICAgIC8qIFRoZSBzcGVjaWZpZWQgaXRlbSBoYXMgYmVlbiBhZGRlZCB0byB0aGUgYnJvd3NlciAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckl0ZW1SZW1vdmVkICAgICAgID0gMjsgICAgLyogVGhlIHNwZWNpZmllZCBpdGVtIGhhcyBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgYnJvd3NlciAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckVkaXRTdGFydGVkICAgICAgID0gMzsgICAgLyogU3RhcnRpbmcgYW4gRWRpdFRleHQgc2Vzc2lvbiBmb3Igc3BlY2lmaWVkIGl0ZW0gKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJFZGl0U3RvcHBlZCAgICAgICA9IDQ7ICAgIC8qIFN0b3BwaW5nIGFuIEVkaXRUZXh0IHNlc3Npb24gZm9yIHNwZWNpZmllZCBpdGVtICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbVNlbGVjdGVkICAgICAgPSA1OyAgICAvKiBJdGVtIGhhcyBqdXN0IGJlZW4gYWRkZWQgdG8gdGhlIHNlbGVjdGlvbiBzZXQgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJJdGVtRGVzZWxlY3RlZCAgICA9IDY7ICAgIC8qIEl0ZW0gaGFzIGp1c3QgYmVlbiByZW1vdmVkIGZyb20gdGhlIHNlbGVjdGlvbiBzZXQgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJJdGVtRG91YmxlQ2xpY2tlZCA9IDc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyQ29udGFpbmVyT3BlbmVkICAgPSA4OyAgICAvKiBDb250YWluZXIgaXMgb3BlbiAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckNvbnRhaW5lckNsb3NpbmcgID0gOTsgICAgLyogQ29udGFpbmVyIGlzIGFib3V0IHRvIGNsb3NlIChhbmQgd2lsbCByZWFsIHNvb24gbm93LCB5J2FsbCkgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJDb250YWluZXJDbG9zZWQgICA9IDEwOyAgIC8qIENvbnRhaW5lciBpcyBjbG9zZWQgKHknYWxsIGNvbWUgYmFjayBub3chKSAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckNvbnRhaW5lclNvcnRpbmcgID0gMTE7ICAgLyogQ29udGFpbmVyIGlzIGFib3V0IHRvIGJlIHNvcnRlZCAobG9jayBhbnkgdm9sYXRpbGUgcHJvcGVydGllcykgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJDb250YWluZXJTb3J0ZWQgICA9IDEyOyAgIC8qIENvbnRhaW5lciBoYXMgYmVlbiBzb3J0ZWQgKHlvdSBtYXkgcmVsZWFzZSBhbnkgcHJvcGVydHkgbG9ja3MpICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyVXNlclRvZ2dsZWRDb250YWluZXIgPSAxNjsgLyogX1VzZXJfIHJlcXVlc3RlZCBjb250YWluZXIgb3Blbi9jbG9zZSBzdGF0ZSB0byBiZSB0b2dnbGVkICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyVGFyZ2V0Q2hhbmdlZCAgICAgPSAxNTsgICAvKiBUaGUgdGFyZ2V0IGhhcyBjaGFuZ2VkIHRvIHRoZSBzcGVjaWZpZWQgaXRlbSAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlclVzZXJTdGF0ZUNoYW5nZWQgID0gMTM7ICAgLyogVGhlIHVzZXIgaGFzIHJlZm9ybWF0dGVkIHRoZSB2aWV3IGZvciB0aGUgdGFyZ2V0ICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyU2VsZWN0aW9uU2V0Q2hhbmdlZCA9IDE0OyAgLyogVGhlIHNlbGVjdGlvbiBzZXQgaGFzIGJlZW4gbW9kaWZpZWQgKG5ldCByZXN1bHQgbWF5IGJlIHRoZSBzYW1lKSAqLwotCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyTm9JdGVtPSAwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckRlZmF1bHRQcm9wZXJ0eUZsYWdzID0gMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJQcm9wZXJ0eUlzTXV0YWJsZSA9IDEgPDwgMDsKLQkKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJUZXh0VHlwZT0gKCd0Jzw8MjQpICsgKCdlJzw8MTYpICsgKCd4Jzw8OCkgKyAndCc7CS8qIENGU3RyaW5nUmVmICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySWNvbkFuZFRleHRUeXBlPSAoJ3QnPDwyNCkgKyAoJ2knPDwxNikgKyAoJ2MnPDw4KSArICduJzsJLyogSWNvblJlZiwgQ0ZTdHJpbmdSZWYsIGV0YyAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckNoZWNrYm94VHlwZT0gKCdjJzw8MjQpICsgKCdoJzw8MTYpICsgKCdiJzw8OCkgKyAneCc7CS8qIFRoZW1lQnV0dG9uVmFsdWUgKi8KLQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckxpc3RWaWV3TGF0ZXN0SGVhZGVyRGVzYyA9IDA7Ci0JCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyRHJhZ1NlbGVjdCAgICAgICAgPSAxIDw8IDA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyU2VsZWN0T25seU9uZSAgICAgPSAxIDw8IDE7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyUmVzZXRTZWxlY3Rpb24gICAgPSAxIDw8IDI7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyQ21kVG9nZ2xlc1NlbGVjdGlvbiA9IDEgPDwgMzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJOb0Rpc2pvaW50U2VsZWN0aW9uID0gMSA8PCA0OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckFsd2F5c0V4dGVuZFNlbGVjdGlvbiA9IDEgPDwgNTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJOZXZlckVtcHR5U2VsZWN0aW9uU2V0ID0gMSA8PCA2OwotCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyVmlld1NwZWNpZmljRmxhZ3NPZmZzZXQgPSAxNjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJMaXN0Vmlld1NlbGVjdGlvbkNvbHVtbj0gMSA8PCBrRGF0YUJyb3dzZXJWaWV3U3BlY2lmaWNGbGFnc09mZnNldDsKLSAKLSAJLy8gZGF0YSBicm93c2VyIGl0ZW0gc3RhdGVzIAotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBuZXdDb2x1bW5EZXNjKGludCBwcm9wZXJ0eUlELCBpbnQgcHJvcGVydHlUeXBlLCBpbnQgcHJvcGVydHlGbGFncywKLQkJCXNob3J0IG1pbmltdW1XaWR0aCwgc2hvcnQgbWF4aW11bVdpZHRoKTsKLQkJCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBBZGREYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uKGludCBjSGFuZGxlLCBpbnQgaGFuZGxlLCBpbnQgaW5kZXgpOwotCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBjcmVhdGVEYXRhQnJvd3NlckNvbnRyb2woaW50IHdIYW5kbGUpOwotCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBBdXRvU2l6ZURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5zKGludCBjSGFuZGxlKTsKLQkJCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBzZXREYXRhQnJvd3NlckNhbGxiYWNrcyhpbnQgY0hhbmRsZSwgaW50IGRhdGFDYWxsYmFja1VQUCwKLQkJCQkJCQkJCQlpbnQgY29tcGFyZUNhbGxiYWNrVVBQLCBpbnQgaXRlbU5vdGlmaWNhdGlvbkNhbGxiYWNrVVBQKTsKLQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0RGF0YUJyb3dzZXJBY3RpdmVJdGVtcyhpbnQgY0hhbmRsZSwgYm9vbGVhbiBhY3RpdmUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBBZGREYXRhQnJvd3Nlckl0ZW1zKGludCBjSGFuZGxlLCBpbnQgY29udGFpbmVySUQsIGludCBudW1JdGVtcywgaW50W10gaXRlbUlEcywgaW50IHByZVNvcnRQcm9wZXJ0eSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFJlbW92ZURhdGFCcm93c2VySXRlbXMoaW50IGNIYW5kbGUsIGludCBjb250YWluZXJJRCwgaW50IG51bUl0ZW1zLCBpbnRbXSBpdGVtSURzLCBpbnQgcHJlU29ydFByb3BlcnR5KTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXREYXRhQnJvd3Nlckl0ZW1EYXRhVGV4dChpbnQgaXRlbVJlZiwgaW50IHNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXREYXRhQnJvd3Nlckl0ZW1EYXRhQm9vbGVhblZhbHVlKGludCBpdGVtUmVmLCBib29sZWFuIGRhdGEpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXREYXRhQnJvd3Nlckl0ZW1EYXRhSXRlbUlEKGludCBpdGVtUmVmLCBpbnQgaXRlbUlEKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUljb24oaW50IGl0ZW1SZWYsIGludCBpY29uUmVmKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUJ1dHRvblZhbHVlKGludCBpdGVtUmVmLCBzaG9ydCB0aGVtZUJ1dHRvblZhbHVlKTsKLQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0RGF0YUJyb3dzZXJIYXNTY3JvbGxCYXJzKGludCBjSGFuZGxlLCBib29sZWFuIGhTY3JvbGwsIGJvb2xlYW4gdlNjcm9sbCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJCdG5IZWlnaHQoaW50IGNIYW5kbGUsIHNob3J0IGhlaWdodCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFVwZGF0ZURhdGFCcm93c2VySXRlbXMoaW50IGNIYW5kbGUsIGludCBjb250YWluZXIsIGludCBudW1JdGVtcywgaW50W10gaXRlbXMsIGludCBwcmVTb3J0UHJvcGVydHksIGludCBwcm9wZXJ0eUlEKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0RGF0YUJyb3dzZXJJdGVtQ291bnQoaW50IGNIYW5kbGUsIGludCBjb250YWluZXIsIGJvb2xlYW4gcmVjdXJzZSwgaW50IHN0YXRlLCBpbnRbXSBudW1JdGVtcyk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldERhdGFCcm93c2VySXRlbXMoaW50IGNIYW5kbGUsIGludCBjb250YWluZXIsIGJvb2xlYW4gcmVjdXJzZSwgaW50IHN0YXRlLCBpbnQgaGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgUmV2ZWFsRGF0YUJyb3dzZXJJdGVtKGludCBjSGFuZGxlLCBpbnQgaXRlbUlELCBpbnQgY29sSUQsIGJvb2xlYW4gY2VudGVyKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBib29sZWFuIElzRGF0YUJyb3dzZXJJdGVtU2VsZWN0ZWQoaW50IGNIYW5kbGUsIGludCBpdGVtSUQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uKGludCBjSGFuZGxlLCBpbnRbXSB0b3AsIGludFtdIGxlZnQpOwotICAgIHB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBTZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uKGludCBjSGFuZGxlLCBpbnQgdG9wLCBpbnQgbGVmdCk7Ci0KLQkvKiBTZXQgb3BlcmF0aW9ucyBmb3IgdXNlIHdpdGggU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbXNBZGQgICAgICAgICAgPSAwOyAgICAvKiBhZGQgc3BlY2lmaWVkIGl0ZW1zIHRvIGV4aXN0aW5nIHNldCAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduICAgICAgID0gMTsgICAgLyogYXNzaWduIGRlc3RpbmF0aW9uIHNldCB0byBzcGVjaWZpZWQgaXRlbXMgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJJdGVtc1RvZ2dsZSAgICAgICA9IDI7ICAgIC8qIHRvZ2dsZSBtZW1iZXJzaGlwIHN0YXRlIG9mIHNwZWNpZmllZCBpdGVtcyAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3Nlckl0ZW1zUmVtb3ZlICAgICAgID0gMzsJICAvKiByZW1vdmUgc3BlY2lmaWVkIGl0ZW1zIGZyb20gZXhpc3Rpbmcgc2V0ICovCi0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldERhdGFCcm93c2VyU2VsZWN0aW9uRmxhZ3MoaW50IGNIYW5kbGUsIGludCBzZWxlY3Rpb25GbGFncyk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyhpbnQgY0hhbmRsZSwgaW50IG51bUl0ZW1zLCBpbnRbXSBpdGVtcywgaW50IG9wZXJhdGlvbik7Ci0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldERhdGFCcm93c2VyVGFyZ2V0KGludCBjSGFuZGxlLCBpbnQgcm9vdElEKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0Rpc2Nsb3N1cmVDb2x1bW4oaW50IGNIYW5kbGUsIGludCBjb2xJRCwgYm9vbGVhbiBiKTsKLQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlclByb3BlcnR5RW5jbG9zaW5nUGFydCA9IDA7Ci0vLwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJQcm9wZXJ0eUNvbnRlbnRQYXJ0ID0gKCctJzw8MjQpICsgKCctJzw8MTYpICsgKCctJzw8OCkgKyAnLSc7Ci0vLwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJQcm9wZXJ0eURpc2Nsb3N1cmVQYXJ0ID0gKCdkJzw8MjQpICsgKCdpJzw8MTYpICsgKCdzJzw8OCkgKyAnYyc7Ci0vLwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJQcm9wZXJ0eVRleHRQYXJ0ID0ga0RhdGFCcm93c2VyVGV4dFR5cGU7Ci0vLwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJQcm9wZXJ0eUljb25QYXJ0ID0ga0RhdGFCcm93c2VySWNvblR5cGU7Ci0vLwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJQcm9wZXJ0eVNsaWRlclBhcnQgPSBrRGF0YUJyb3dzZXJTbGlkZXJUeXBlOwotLy8JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VyUHJvcGVydHlDaGVja2JveFBhcnQgPSBrRGF0YUJyb3dzZXJDaGVja2JveFR5cGU7Ci0vLwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRGF0YUJyb3dzZXJQcm9wZXJ0eVByb2dyZXNzQmFyUGFydCA9IGtEYXRhQnJvd3NlclByb2dyZXNzQmFyVHlwZTsKLS8vCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlclByb3BlcnR5UmVsZXZhbmNlUmFua1BhcnQgPSBrRGF0YUJyb3dzZXJSZWxldmFuY2VSYW5rVHlwZTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXREYXRhQnJvd3Nlckl0ZW1QYXJ0Qm91bmRzKGludCBjSGFuZGxlLCBpbnQgaXRlbSwgaW50IHByb3BlcnR5LAotCQkJaW50IHBhcnQsIHNob3J0W10gYm91bmRzKTsKLQkJCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBPcGVuRGF0YUJyb3dzZXJDb250YWluZXIoaW50IGNIYW5kbGUsIGludCBjb250YWluZXIpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBDbG9zZURhdGFCcm93c2VyQ29udGFpbmVyKGludCBjSGFuZGxlLCBpbnQgY29udGFpbmVyKTsKLSAKLSAJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbUlzU2VsZWN0ZWQgPSAxIDw8IDA7Ci0gCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtEYXRhQnJvd3NlckNvbnRhaW5lcklzT3BlbiA9IDEgPDwgMTsKLSAJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0RhdGFCcm93c2VySXRlbUlzRHJhZ1RhcmdldCA9IDEgPDwgMjsgLyogRHVyaW5nIGEgZHJhZyBvcGVyYXRpb24gKi8KLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXREYXRhQnJvd3Nlckl0ZW1TdGF0ZShpbnQgY0hhbmRsZSwgaW50IGl0ZW0sIGludFtdIHN0YXRlKTsKLSAKLQkvLy0tLS0gVXNlciBQYW5lCi0JCi0JLy8gZmVhdHVyZSBiaXRzCi0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN1cHBvcnRzR2hvc3RpbmcgICAgICA9IDEgPDwgMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN1cHBvcnRzRW1iZWRkaW5nICAgICA9IDEgPDwgMTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN1cHBvcnRzRm9jdXMgICAgICAgICA9IDEgPDwgMjsKLQkvL3B1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sV2FudHNJZGxlICAgICAgICAgICAgID0gMSA8PCAzOwotCS8vcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xXYW50c0FjdGl2YXRlICAgICAgICAgPSAxIDw8IDQ7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xIYW5kbGVzVHJhY2tpbmcgICAgICAgPSAxIDw8IDU7Ci0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN1cHBvcnRzRGF0YUFjY2VzcyAgICA9IDEgPDwgNjsKLQkvL3B1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sSGFzU3BlY2lhbEJhY2tncm91bmQgID0gMSA8PCA3OwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sR2V0c0ZvY3VzT25DbGljayAgICAgID0gMSA8PCA4OwotCS8vcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xTdXBwb3J0c0NhbGNCZXN0UmVjdCAgPSAxIDw8IDk7Ci0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN1cHBvcnRzTGl2ZUZlZWRiYWNrICA9IDEgPDwgMTA7Ci0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEhhc1JhZGlvQmVoYXZpb3IgICAgICA9IDEgPDwgMTE7Ci0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN1cHBvcnRzRHJhZ0FuZERyb3AgICA9IDEgPDwgMTI7Ci0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbEF1dG9Ub2dnbGVzICAgICAgICAgICA9IDEgPDwgMTQ7Ci0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN1cHBvcnRzR2V0UmVnaW9uICAgICA9IDEgPDwgMTc7Ci0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN1cHBvcnRzRmxhdHRlbmluZyAgICA9IDEgPDwgMTk7Ci0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN1cHBvcnRzU2V0Q3Vyc29yICAgICA9IDEgPDwgMjA7Ci0JLy9wdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFN1cHBvcnRzQ29udGV4dHVhbE1lbnVzID0gMSA8PCAyMTsKLQkvL3B1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sU3VwcG9ydHNDbGlja0FjdGl2YXRpb24gPSAxIDw8IDIyOwotCS8vcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xJZGxlc1dpdGhUaW1lciAgICAgICAgPSAxIDw8IDIzOwotCQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVXNlclBhbmVEcmF3UHJvY1RhZz0gKCdkJzw8MjQpICsgKCdyJzw8MTYpICsgKCdhJzw8OCkgKyAndyc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xVc2VyUGFuZUhpdFRlc3RQcm9jVGFnPSAoJ2gnPDwyNCkgKyAoJ2knPDwxNikgKyAoJ3QnPDw4KSArICd0JzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrQ29udHJvbFVzZXJQYW5lVHJhY2tpbmdQcm9jVGFnPSAoJ3QnPDwyNCkgKyAoJ3InPDwxNikgKyAoJ2EnPDw4KSArICdrJzsKLQkKLQkvLyBTdGF0aWNUZXh0Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xTdGF0aWNUZXh0Q0ZTdHJpbmdUYWc9ICgnYyc8PDI0KSArICgnZic8PDE2KSArICgncyc8PDgpICsgJ3QnOwotCQotCS8vIFRleHRFZGl0Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xFZGl0VGV4dFRleHRUYWc9ICgndCc8PDI0KSArICgnZSc8PDE2KSArICgneCc8PDgpICsgJ3QnOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sRWRpdFRleHRTZWxlY3Rpb25UYWc9ICgncyc8PDI0KSArICgnZSc8PDE2KSArICgnbCc8PDgpICsgJ2UnOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sRWRpdFRleHRDRlN0cmluZ1RhZz0gKCdjJzw8MjQpICsgKCdmJzw8MTYpICsgKCdzJzw8OCkgKyAndCc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xFZGl0VGV4dExvY2tlZFRhZz0gKCdsJzw8MjQpICsgKCdvJzw8MTYpICsgKCdjJzw8OCkgKyAnayc7Ci0JCi0JLyoKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgQ3JlYXRlRWRpdFVuaWNvZGVUZXh0Q29udHJvbChpbnQgd0hhbmRsZSwgc2hvcnRbXSBib3VuZHMsIGludCBzSGFuZGxlLAotCQlib29sZWFuIGlzUGFzc3dvcmQsIGludCBzdHlsZUhhbmRsZSwgaW50W10gb3V0Q29udHJvbCk7Ci0JKi8KLQkKLQkvLy8vLyBNTFRFIFRleHQKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOV2FudEhTY3JvbGxCYXJNYXNrICAgICAgICA9IDEgPDwgMjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOV2FudFZTY3JvbGxCYXJNYXNrICAgICAgICA9IDEgPDwgMzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOUmVhZE9ubHlNYXNrICAgICAgICAgICAgICA9IDEgPDwgNTsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOQWx3YXlzV3JhcEF0Vmlld0VkZ2VNYXNrICA9IDEgPDwgMTE7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RYTkRvbnREcmF3Q2FyZXRXaGVuSW5hY3RpdmVNYXNrID0gMSA8PCAxMjsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOU2luZ2xlTGluZU9ubHlNYXNrICAgICAgICA9IDEgPDwgMTQ7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RYTk1vbm9zdHlsZWRUZXh0TWFzawkJID0gMSA8PCAxNzsKLQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUWE5UZXh0RWRpdFN0eWxlRnJhbWVUeXBlICAgID0gMTsKLQkKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOVW5pY29kZVRleHRGaWxlICAgICAgICAgICA9ICgndSc8PDI0KSArICgndCc8PDE2KSArICgneCc8PDgpICsgJ3QnOwotCQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUWE5TeXN0ZW1EZWZhdWx0RW5jb2RpbmcgICAgID0gMDsKLQkKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhOVW5pY29kZVRleHREYXRhICAgICAgICAgICA9ICgndSc8PDI0KSArICgndCc8PDE2KSArICgneCc8PDgpICsgJ3QnOwotCQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUWE5Xb3JkV3JhcFN0YXRlVGFnICAgICAgICAgID0gKCd3Jzw8MjQpICsgKCd3Jzw8MTYpICsgKCdyJzw8OCkgKyAncyc7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RYTlRhYlNldHRpbmdzVGFnICAgICAgICAgICAgPSAoJ3QnPDwyNCkgKyAoJ2EnPDwxNikgKyAoJ2InPDw4KSArICdzJzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhORG9Gb250U3Vic3RpdHV0aW9uICAgICAgICA9ICgnZic8PDI0KSArICgncyc8PDE2KSArICgndSc8PDgpICsgJ2InOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUWE5WaXNpYmlsaXR5VGFnCQkJID0gKCd2Jzw8MjQpICsgKCdpJzw8MTYpICsgKCdzJzw8OCkgKyAnYic7Ci0KLQkvKiBrVFhOV29yZFdyYXBTdGF0ZVRhZyAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBrVFhOQXV0b1dyYXAgICAgICAgICAgICAgICAgICA9IGZhbHNlOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBrVFhOTm9BdXRvV3JhcCAgICAgICAgICAgICAgICA9IHRydWU7Ci0JCi0JLyogVFhOU2Nyb2xsQmFyU3RhdGUgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGJvb2xlYW4ga1Njcm9sbEJhcnNBbHdheXNBY3RpdmUgICAgICAgPSB0cnVlOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgYm9vbGVhbiBrU2Nyb2xsQmFyc1N5bmNXaXRoRm9jdXMgICAgICA9IGZhbHNlOwotCi0JLy8gT2Zmc2V0cwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtUWE5Vc2VDdXJyZW50U2VsZWN0aW9uID0gLTE7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga1RYTlN0YXJ0T2Zmc2V0ID0gMDsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrVFhORW5kT2Zmc2V0ID0gMjE0NzQ4MzY0NzsKLQkKLQkJCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFRYTkluaXRUZXh0ZW5zaW9uKCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFRYTk5ld09iamVjdChpbnQgZmlsZVNwZWMsIGludCB3SGFuZGxlLCBzaG9ydFtdIGJvdW5kcywgaW50IGZyYW1lT3B0aW9ucywKLQkJaW50IGZyYW1lVHlwZSwgaW50IGZpbGVUeXBlLCBpbnQgaVBlcm1hbmVudEVuY29kaW5nLCBpbnRbXSBoYW5kbGUsIGludFtdIGZyYW1lSUQsIGludCByZWZjb24pOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgVFhORGVsZXRlT2JqZWN0KGludCB0eEhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBUWE5TZXRGcmFtZUJvdW5kcyhpbnQgdHhIYW5kbGUsIGludCB0b3AsIGludCBsZWZ0LCBpbnQgYm90dG9tLCBpbnQgcmlnaHQsIGludCBmcmFtZUlEKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFRYTkRyYXcoaW50IHR4SGFuZGxlLCBpbnQgZ0RldmljZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFRYTkdldERhdGEoaW50IHR4SGFuZGxlLCBpbnQgc3RhcnRPZmZzZXQsIGludCBlbmRPZmZzZXQsIGludFtdIGRhdGFIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBUWE5TZXREYXRhKGludCB0eEhhbmRsZSwgY2hhcltdIGRhdGEsIGludCBzdGFydE9mZnNldCwgaW50IGVuZE9mZnNldCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFRYTkdldExpbmVDb3VudChpbnQgdHhIYW5kbGUsIGludFtdIGxpbmVUb3RhbCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFRYTkRhdGFTaXplKGludCB0eEhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBUWE5HZXRTZWxlY3Rpb24oaW50IHR4SGFuZGxlLCBpbnRbXSBzdGFydE9mZnNldCwgaW50W10gZW5kT2Zmc2V0KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgVFhOU2V0U2VsZWN0aW9uKGludCB0eEhhbmRsZSwgaW50IHN0YXJ0T2Zmc2V0LCBpbnQgZW5kT2Zmc2V0KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFRYTlNlbGVjdEFsbChpbnQgdHhIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgVFhOU2hvd1NlbGVjdGlvbihpbnQgdHhIYW5kbGUsIGJvb2xlYW4gc2hvd0VuZCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBUWE5LZXlEb3duKGludCB0eEhhbmRsZSwgaW50W10gZXZlbnREYXRhKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFRYTkNsaWNrKGludCB0eEhhbmRsZSwgaW50W10gZXZlbnREYXRhKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFRYTkZvY3VzKGludCB0eEhhbmRsZSwgYm9vbGVhbiBiZWNvbWluZ0ZvY3VzZWQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBUWE5DdXQoaW50IHR4SGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgVFhOQ29weShpbnQgdHhIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBUWE5QYXN0ZShpbnQgdHhIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBUWE5HZXRSZWN0Qm91bmRzKGludCB0eEhhbmRsZSwgc2hvcnRbXSB2aWV3UmVjdCwgaW50W10gZGVzdGluYXRpb25SZWN0LCBpbnRbXSB0ZXh0UmVjdCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBUWE5TZXRSZWN0Qm91bmRzKGludCB0eEhhbmRsZSwgc2hvcnRbXSB2aWV3UmVjdCwgaW50W10gZGVzdFJlY3QsIGJvb2xlYW4gdXBkYXRlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgVFhOQWN0aXZhdGUoaW50IHR4SGFuZGxlLCBpbnQgZnJhbWVJRCwgYm9vbGVhbiBzY3JvbGxCYXJTdGF0ZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFRYTkVjaG9Nb2RlKGludCB0eEhhbmRsZSwgY2hhciBlY2hvQ2hhcmFjdGVyLCBpbnQgZW5jb2RpbmcsIGJvb2xlYW4gb24pOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBUWE5PZmZzZXRUb1BvaW50KGludCB0eEhhbmRsZSwgaW50IG9mZnNldCwgc2hvcnRbXSBwb2ludCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBUWE5SZXNpemVGcmFtZShpbnQgdHhIYW5kbGUsIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGZyYW1lSUQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgVFhOR2V0Vmlld1JlY3QoaW50IHR4SGFuZGxlLCBzaG9ydFtdIHZpZXdSZWN0KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgVFhOR2V0TGluZU1ldHJpY3MoaW50IHR4SGFuZGxlLCBpbnQgbGluZU51bWJlciwgaW50W10gbGluZVdpZHRoLCBpbnRbXSBsaW5lSGVpZ2h0KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIFRYTkZvcmNlVXBkYXRlKGludCB0eEhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFRYTlNldFRYTk9iamVjdENvbnRyb2xzKGludCB0eEhhbmRsZSwgYm9vbGVhbiBjbGVhckFsbCwgaW50IGNvbnRyb2xDb3VudCwgaW50W10gY29udHJvbFRhZ3MsIGludFtdIGNvbnRyb2xEYXRhKTsKLQkvL3B1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBUWE5TZXRCYWNrZ3JvdW5kKGludCB0eEhhbmRsZSwgVFhOQmFja2dyb3VuZCAqaUJhY2tncm91bmRJbmZvKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIHNldFRYTk1hcmdpbnMoaW50IHR4SGFuZGxlLCBzaG9ydCBtYXJnaW4pOwotCi0JLy8gVGFiRm9sZGVyCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xUYWJJbmZvVGFnPSAoJ3QnPDwyNCkgKyAoJ2EnPDwxNikgKyAoJ2InPDw4KSArICdpJzsJLyogQ29udHJvbFRhYkluZm9SZWMqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sVGFiQ29udGVudFJlY3RUYWc9ICgncic8PDI0KSArICgnZSc8PDE2KSArICgnYyc8PDgpICsgJ3QnOwkvKiBSZWN0Ki8KLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBDcmVhdGVUYWJGb2xkZXJDb250cm9sKGludCB3SGFuZGxlLCBpbnRbXSBjSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgc2V0VGFiVGV4dChpbnQgY0hhbmRsZSwgaW50IGluZGV4LCBpbnQgc0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IHNldFRhYkljb24oaW50IGNIYW5kbGUsIGludCBpbmRleCwgaW50IGljb25IYW5kbGUpOwotCQotCS8vIFBvcHVwIG1lbnVzCi0JLyogCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xQb3B1cEJ1dHRvbk1lbnVSZWZUYWcgPSBPU1R5cGUoIm1oYW4iKTsgLy8gTWVudVJlZgotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDb250cm9sUG9wdXBCdXR0b25FeHRyYUhlaWdodFRhZyA9IE9TVHlwZSgiZXhodCIpOyAvLyBTSW50MTYgLSBleHRyYSB2ZXJ0aWNhbCB3aGl0ZXNwYWNlIHdpdGhpbiB0aGUgYnV0dG9uCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xQb3B1cEJ1dHRvbk93bmVkTWVudVJlZlRhZyA9IE9TVHlwZSgib21yZiIpOyAvLyBNZW51UmVmCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0NvbnRyb2xQb3B1cEJ1dHRvbkNoZWNrQ3VycmVudFRhZyA9IE9TVHlwZSgiY2hjayIpOyAvLyBCb29sZWFuIC0gd2hldGhlciB0aGUgcG9wdXAgcHV0cyBhIGNoZWNrbWFyayBuZXh0IHRvIHRoZSBjdXJyZW50IGl0ZW0gKGRlZmF1bHRzIHRvIHRydWUpCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IENyZWF0ZVBvcHVwQnV0dG9uQ29udHJvbChpbnQgd0hhbmRsZSwgc2hvcnRbXSBib3VuZHMsIGludCBzSGFuZGxlLCBzaG9ydCBtZW51SUQsCi0JCQlib29sZWFuIHZhcmlhYmxlV2lkdGgsIHNob3J0IHRpdGxlV2lkdGgsIHNob3J0IHRpdGxlSnVzdGlmaWNhdGlvbiwgYnl0ZSB0aXRsZVN0eWxlLCBpbnRbXSBvdXRDb250cm9sKTsKLQkqLwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgU2V0Q29udHJvbFBvcHVwTWVudUhhbmRsZShpbnQgY0hhbmRsZSwgaW50IHBvcHVwTWVudUhhbmRsZSk7Ci0JCi0JLy8tLS0tIEFsZXJ0cyBhbmQgRGlhbG9ncwotCS8vIEFsZXJ0IHR5cGVzCi0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQWxlcnRTdG9wQWxlcnQgPSAwOwotICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgc2hvcnQga0FsZXJ0Tm90ZUFsZXJ0ID0gMTsKLSAgICBwdWJsaWMgc3RhdGljIGZpbmFsIHNob3J0IGtBbGVydENhdXRpb25BbGVydCA9IDI7Ci0gICAgcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrQWxlcnRQbGFpbkFsZXJ0ID0gMzsKLQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgQ3JlYXRlU3RhbmRhcmRBbGVydChzaG9ydCBhbGVydFR5cGUsIGludCBlcnJvclNIYW5kbGUsIGludCBleHBsYW5hdGlvblNIYW5kbGUsCi0JCQkJaW50IGFsZXJ0UGFyYW1IYW5kbGUsIGludFtdIGRpYWxvZ0hhbmRsZSk7Ci0KLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgUnVuU3RhbmRhcmRBbGVydChpbnQgZGlhbG9nSGFuZGxlLCBpbnQgbW9kYWxGaWx0ZXJVUFAsIHNob3J0W10gaXRlbUhpdCk7Ci0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFBpY2tDb2xvcihzaG9ydFtdIHJnYiwgc2hvcnRbXSB3aGVyZSwgYnl0ZVtdIHRpdGxlLCBib29sZWFuW10gc3VjY2Vzcyk7Ci0JCi0JLy8gRmlsZSBkaWFsb2cKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTmF2QWxsb3dNdWx0aXBsZUZpbGVzPSAweDAwMDAwMDgwOyAvKiBhbGxvdyBtdWx0aXBsZSBpdGVtcyB0byBiZSBzZWxlY3RlZCAqLwotICAKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTmF2VXNlckFjdGlvbk5vbmUgPSAwOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtOYXZVc2VyQWN0aW9uQ2FuY2VsID0gMTsJLyogVGhlIHVzZXIgY2FuY2VsbGVkIHRoZSBkaWFsb2cuICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga05hdlVzZXJBY3Rpb25PcGVuID0gMjsJLyogT3BlbiBidXR0b24gaW4gdGhlIEdldEZpbGUgZGlhbG9nLiAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtOYXZVc2VyQWN0aW9uU2F2ZUFzID0gMzsgLyogU2F2ZSBidXR0b24gaW4gdGhlIFB1dEZpbGUgZGlhbG9nLiAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtOYXZVc2VyQWN0aW9uQ2hvb3NlID0gNDsJLyogQ2hvb3NlIGJ1dHRvbiBpbiB0aGUgQ2hvb3NlRmlsZSwgQ2hvb3NlRm9sZGVyLCBDaG9vc2VWb2x1bWUgb3IgQ2hvb3NlT2JqZWN0IGRpYWxvZ3MuKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTmF2VXNlckFjdGlvbk5ld0ZvbGRlciA9IDU7IC8qIE5ldyBGb2xkZXIgYnV0dG9uIGluIHRoZSBOZXcgRm9sZGVyIGRpYWxvZy4gKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTmF2VXNlckFjdGlvblNhdmVDaGFuZ2VzID0gNjsgLyogU2F2ZSBidXR0b24gaW4gYW4gQXNrU2F2ZUNoYW5nZXMgZGlhbG9nLiAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtOYXZVc2VyQWN0aW9uRG9udFNhdmVDaGFuZ2VzID0gNzsgLyogRG9uJ3QgU2F2ZSBidXR0b24gaW4gYW4gQXNrU2F2ZUNoYW5nZXMgZGlhbG9nLiAqLwotICAJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga05hdlVzZXJBY3Rpb25EaXNjYXJkQ2hhbmdlcyA9IDg7IC8qIERpc2NhcmQgYnV0dG9uIGluIHRoZSBBc2tEaXNjYXJkQ2hhbmdlcyBkaWFsb2cuICovCi0gIAlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTmF2VXNlckFjdGlvblJldmlld0RvY3VtZW50cyA9IDk7IC8qIFJldmlldyBVbnNhdmVkIGJ1dHRvbiBpbiB0aGUgQXNrUmV2aWV3RG9jdW1lbnRzIGRpYWxvZyAoTWFjIE9TIFggb25seSkuICovCi0gIAlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrTmF2VXNlckFjdGlvbkRpc2NhcmREb2N1bWVudHMgPSAxMDsgLyogVGhlIHVzZXIgY2xpY2tlZCB0aGUgRGlzY2FyZCBDaGFuZ2VzIGJ1dHRvbiBpbiB0aGUgQXNrUmV2aWV3RG9jdW1lbnRzIGRpYWxvZyAoTWFjIE9TIFggb25seSkuICovCi0JCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBOYXZDcmVhdGVHZXRGaWxlRGlhbG9nKGludCBvcHRpb25zLCBpbnQgdGl0bGVIYW5kbGUsIGludCBwYXJlbnRIYW5kbGUsIGludFtdIGRpYWxvZ0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IE5hdkNyZWF0ZVB1dEZpbGVEaWFsb2coaW50IG9wdGlvbnMsIGludCB0aXRsZUhhbmRsZSwgaW50IHBhcmVudEhhbmRsZSwgaW50W10gZGlhbG9nSGFuZGxlLAotCQkJCQkJCQkJaW50IGZpbGVUeXBlLCBpbnQgZmlsZUNyZWF0b3IpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBOYXZDcmVhdGVDaG9vc2VGb2xkZXJEaWFsb2coaW50IG9wdGlvbnMsIGludCB3aW5kb3dUaXRsZSwgaW50IG1lc3NhZ2VIYW5kbGUsCi0JCQkJCQkJCQlpbnQgcGFyZW50V2luZG93SGFuZGxlLCBpbnRbXSBkaWFsb2dIYW5kbGUpOwotCQkJCQkJCQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgTmF2RGlhbG9nU2V0U2F2ZUZpbGVOYW1lKGludCBkaWFsb2dIYW5kbGUsIGludCBmaWxlTmFtZUhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IE5hdkRpYWxvZ0dldFNhdmVGaWxlTmFtZShpbnQgZGlhbG9nSGFuZGxlKTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBOYXZEaWFsb2dSdW4oaW50IGRpYWxvZ0hhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IE5hdkRpYWxvZ0dldFVzZXJBY3Rpb24oaW50IGRpYWxvZ0hhbmRsZSk7Ci0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IE5hdkRpYWxvZ0dldFJlcGx5KGludCBkaWFsb2dIYW5kbGUsIGludFtdIHJlcGx5SGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgTmF2UmVwbHlSZWNvcmRHZXRTZWxlY3Rpb24oaW50IHJlcGx5SGFuZGxlKTsJLy8gcmV0dXJucyBBRURlc2NMaXN0Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBOYXZEaWFsb2dEaXNwb3NlUmVwbHkoaW50IHJlcGx5SGFuZGxlKTsKLQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgQUVDb3VudEl0ZW1zKGludCBhZURlc2NMaXN0LCBpbnRbXSBjb3VudCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEFFR2V0TnRoUHRyKGludCBhZURlc2NMaXN0LCBpbnQgb25lQmFzZWRJbmRleCwgaW50W10gc0hhbmRsZSk7Ci0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IGdldEZpbGVzKGludCBkaWFsb2dIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgTmF2RGlhbG9nRGlzcG9zZShpbnQgZGlhbG9nSGFuZGxlKTsKLQkKLQkKLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCS8vIENGU3RyaW5ncwotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IENGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMoU3RyaW5nIHMpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQ0ZSZWxlYXNlKGludCBzSGFuZGxlKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgQ0ZTdHJpbmdHZXRMZW5ndGgoaW50IHNIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQ0ZTdHJpbmdHZXRDaGFyYWN0ZXJzKGludCBzSGFuZGxlLCBpbnQgc3RhcnQsIGludCBsZW5ndGgsIGNoYXJbXSBidWZmZXIpOwotCQotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JLy8gSGFuZGxlcwotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IE5ld0hhbmRsZShpbnQgc2l6ZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IE5ld0hhbmRsZUNsZWFyKGludCBzaXplKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIERpc3Bvc2VIYW5kbGUoaW50IGhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldEhhbmRsZVNpemUoaW50IGhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBnZXRIYW5kbGVEYXRhKGludCBoYW5kbGUsIGNoYXJbXSBkYXRhKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIGdldEhhbmRsZURhdGEoaW50IGhhbmRsZSwgaW50W10gZGF0YSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IERlcmVmSGFuZGxlKGludCBoYW5kbGUpOwotCQotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JLy8gUHRycwotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBOZXdQdHIoaW50IHNpemUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBOZXdQdHJDbGVhcihpbnQgc2l6ZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBEaXNwb3NlUHRyKGludCBwdHIpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRQdHJTaXplKGludCBwdHIpOwotCS8vcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IE1lbUVycm9yKCk7Ci0KLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCS8vIFVuaXggbWVtb3J5IHV0aWxpdGllcwotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgbWVtY3B5KGludCBkZXN0LCBpbnQgc3JjLCBpbnQgbik7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBtZW1jcHkoaW50IGRlc3QsIGJ5dGVbXSBzcmMsIGludCBuKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIG1lbWNweShieXRlW10gZGVzdCwgaW50IHNyYywgaW50IG4pOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgbWVtc2V0KGludCBkZXN0LCBpbnQgdmFsdWUsIGludCBzaXplKTsKLQotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JLy8gU2NyYXAKLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldEN1cnJlbnRTY3JhcChpbnRbXSBzY3JhcEhhbmRsZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldFNjcmFwRmxhdm9yQ291bnQoaW50IHNjcmFwSGFuZGxlLCBpbnRbXSBmbGF2b3JDb3VudCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldFNjcmFwRmxhdm9ySW5mb0xpc3QoaW50IHNjcmFwSGFuZGxlLCBpbnRbXSBmbGF2b3JDb3VudCwgaW50W10gaW5mbyk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldFNjcmFwRmxhdm9yU2l6ZShpbnQgc2NyYXBIYW5kbGUsIGludCBmbGF2b3JUeXBlLCBpbnRbXSBzaXplKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0U2NyYXBGbGF2b3JEYXRhKGludCBzY3JhcEhhbmRsZSwgaW50IGZsYXZvclR5cGUsIGludFtdIHNpemUsIGJ5dGVbXSBkYXRhKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgUHV0U2NyYXBGbGF2b3IoaW50IHNjcmFwSGFuZGxlLCBpbnQgZmxhdm9yVHlwZSwgaW50IGZsYXZvckZsYWdzLCBieXRlW10gZGF0YSk7IAotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBDbGVhckN1cnJlbnRTY3JhcCgpOwotCSAKLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCS8vIE1pc2MKLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotIAlwdWJsaWMgc3RhdGljIG5hdGl2ZSBzaG9ydCBIaVdvcmQoaW50IGRvdWJsZVdvcmQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHNob3J0IExvV29yZChpbnQgZG91YmxlV29yZCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBTeXNCZWVwKHNob3J0IGR1cmF0aW9uKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0RGJsVGltZSgpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRDYXJldFRpbWUoKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgR2V0QXZhaWxhYmxlV2luZG93UG9zaXRpb25pbmdCb3VuZHMoaW50IGdIYW5kbGUsIHNob3J0W10gbWFpblNjcmVlblJlY3QpOwotCQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBHZXRJY29uUmVmKHNob3J0IHZSZWZOdW0sIGludCBjcmVhdG9yLCBpbnQgaWNvblR5cGUsIGludFtdIGljb25SZWYpOwotCQotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0JLy8gSmFndWFyCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQkKLQkvLyBISU9iamVjdAotCQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDbGFzc0hJT2JqZWN0PSAoJ2gnPDwyNCkgKyAoJ2knPDwxNikgKyAoJ28nPDw4KSArICdiJzsKLQkJCi0JCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudEhJT2JqZWN0Q29uc3RydWN0PSAxOwotCQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRISU9iamVjdEluaXRpYWxpemU9IDI7Ci0JCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudEhJT2JqZWN0RGVzdHJ1Y3Q9IDM7Ci0JCS8vcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50SElPYmplY3RJc0VxdWFsPSA0OwotCQkvL3B1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtFdmVudEhJT2JqZWN0UHJpbnREZWJ1Z0luZm89IDU7Ci0gCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEhJT2JqZWN0UmVnaXN0ZXJTdWJjbGFzcyhpbnQgaW5DbGFzc0lELCBpbnQgaW5CYXNlQ2xhc3NJRCwgaW50IGluT3B0aW9ucywKLQkJCWludCBpbkNvbnN0cnVjdFByb2MsIGludFtdIGluRXZlbnRMaXN0LCBpbnQgaW5Db25zdHJ1Y3REYXRhLCBpbnRbXSBvdXRDbGFzc1JlZik7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEhJT2JqZWN0Q3JlYXRlKGludCBpbkNsYXNzSUQsIGludCBpbkNvbnN0cnVjdERhdGEsIGludFtdIG91dE9iamVjdCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEhJT2JqZWN0Q29weUNsYXNzSUQoaW50IGluT2JqZWN0KTsKLQotCS8vIEhJVmlldwotCQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDb250cm9sRHJhdz0gNDsKLQkJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0V2ZW50Q29udHJvbEFkZGVkU3ViQ29udHJvbD0gMTUyOwotCQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrRXZlbnRDb250cm9sUmVtb3ZpbmdTdWJDb250cm9sPSAxNTM7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEhJVmlld0FkZFN1YnZpZXcoaW50IHBhcmVudCwgaW50IGNoaWxkKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgSElWaWV3UmVtb3ZlRnJvbVN1cGVydmlldyhpbnQgaW5WaWV3KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgSElWaWV3R2V0RnJhbWUoaW50IGluVmlldywgZmxvYXRbXSBvdXRSZWN0KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgSElWaWV3U2V0RnJhbWUoaW50IGluVmlldywgaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBISVZpZXdTZXREcmF3aW5nRW5hYmxlZChpbnQgaW5WaWV3LCBib29sZWFuIGlzRW5hYmxlZCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEhJVmlld1NpbXVsYXRlQ2xpY2soaW50IGluVmlldywgc2hvcnQgaW5QYXJ0VG9DbGljaywgaW50IG1vZGlmaWVycywKLQkJCQkJCQkJCQlzaG9ydFtdIG91dFBhcnRDbGlja2VkKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgSElWaWV3U2V0Wk9yZGVyKGludCBpblZpZXcsIGludCBpbk9wLCBpbnQgaW5PdGhlcik7Ci0JCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtISVZpZXdaT3JkZXJBYm92ZT0gMTsKLQkJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0hJVmlld1pPcmRlckJlbG93PSAyOwotCQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgSElWaWV3Q2xpY2soaW50IGluVmlldywgaW50IGluRXZlbnQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBISVZpZXdDb252ZXJ0UG9pbnQoZmxvYXRbXSBpb1BvaW50LCBpbnQgaW5Tb3VyY2VWaWV3LCBpbnQgaW5EZXN0Vmlldyk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEhJVmlld0dldFJvb3QoaW50IHdIYW5kbGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBISVZpZXdTZXROZWVkc0Rpc3BsYXkoaW50IGluVmlldywgYm9vbGVhbiBpbk5lZWRzRGlzcGxheSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEhJVmlld1NldE5lZWRzRGlzcGxheUluUmVnaW9uKGludCBpblZpZXcsIGludCBpblJnbiwgYm9vbGVhbiBpbk5lZWRzRGlzcGxheSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEhJVmlld1NldFZpc2libGUoaW50IGluVmlldywgYm9vbGVhbiBpblZpc2libGUpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBISVZpZXdDaGFuZ2VBdHRyaWJ1dGVzKGludCBpblZpZXcsIGludCBpbkF0dHJzVG9TZXQsIGludCBpbkF0dHJzVG9DbGVhcik7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEhJVmlld0ZpbmRCeUlEKGludCBpblN0YXJ0VmlldywgaW50IGluSUQsIGludFtdIG91dENvbnRyb2wpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBISVZpZXdHZXRWaWV3Rm9yTW91c2VFdmVudChpbnQgaW5WaWV3LCBpbnQgaW5FdmVudCwgaW50W10gb3V0Vmlldyk7Ci0KLQkvLyBISUNvbWJvQm94Ci0gIAkJcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrSElDb21ib0JveEVkaXRUZXh0UGFydD0gIDU7Ci0gIAkJcHVibGljIHN0YXRpYyBmaW5hbCBzaG9ydCBrSElDb21ib0JveERpc2Nsb3N1cmVQYXJ0PSAgMjg7Ci0KLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgSElDb21ib0JveENyZWF0ZShpbnRbXSBvdXRDb21ib0JveCwgaW50IGF0dHJpYnV0ZXMpOwotCQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrSElDb21ib0JveE5vQXR0cmlidXRlcyA9IDA7Ci0JCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtISUNvbWJvQm94QXV0b0NvbXBsZXRpb25BdHRyaWJ1dGUgPSAoMSA8PCAwKTsKLQkJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQga0hJQ29tYm9Cb3hBdXRvRGlzY2xvc3VyZUF0dHJpYnV0ZSA9ICgxIDw8IDEpOwotCQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrSElDb21ib0JveEF1dG9Tb3J0QXR0cmlidXRlICA9ICgxIDw8IDIpOwotCQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrSElDb21ib0JveEF1dG9TaXplTGlzdEF0dHJpYnV0ZSA9ICgxIDw8IDMpOwotCQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBrSElDb21ib0JveFN0YW5kYXJkQXR0cmlidXRlcyA9IChrSElDb21ib0JveEF1dG9Db21wbGV0aW9uQXR0cmlidXRlIHwga0hJQ29tYm9Cb3hBdXRvRGlzY2xvc3VyZUF0dHJpYnV0ZSB8IGtISUNvbWJvQm94QXV0b1NpemVMaXN0QXR0cmlidXRlKTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBISUNvbWJvQm94R2V0SXRlbUNvdW50KGludCBpbkNvbWJvQm94KTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSBpbnQgSElDb21ib0JveEluc2VydFRleHRJdGVtQXRJbmRleChpbnQgaW5Db21ib0JveCwgaW50IGluSW5kZXgsIGludCBpblRleHQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBISUNvbWJvQm94QXBwZW5kVGV4dEl0ZW0oaW50IGluQ29tYm9Cb3gsIGludCBpblRleHQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBISUNvbWJvQm94UmVtb3ZlSXRlbUF0SW5kZXgoaW50IGluQ29tYm9Cb3gsIGludCBpbkluZGV4KTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIGludCBISUNvbWJvQm94Q29weVRleHRJdGVtQXRJbmRleChpbnQgaW5Db21ib0JveCwgaW50IGluSW5kZXgsIGludFtdIG91dFN0cmluZyk7Ci0KLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIEluaXQoKTsKLQkKLQkvLyBjb3JlIGdyYXBoaWNzCi0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFFEQmVnaW5DR0NvbnRleHQoaW50IGluUG9ydCwgaW50W10gb3V0Q29udGV4dCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFFERW5kQ0dDb250ZXh0KGludCBpblBvcnQsIGludFtdIGlub3V0Q29udGV4dCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFN5bmNDR0NvbnRleHRPcmlnaW5XaXRoUG9ydChpbnQgaW5Db250ZXh0LCBpbnQgcG9ydCk7Ci0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBDR0NvbnRleHRTYXZlR1N0YXRlKGludCBpbkNvbnRleHQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQ0dDb250ZXh0UmVzdG9yZUdTdGF0ZShpbnQgaW5Db250ZXh0KTsKLQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIENHQ29udGV4dFN0cm9rZVJlY3QoaW50IGluQ29udGV4dCwgZmxvYXQgeCwgZmxvYXQgeSwgZmxvYXQgdywgZmxvYXQgaCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBDR0NvbnRleHRGaWxsUmVjdChpbnQgaW5Db250ZXh0LCBmbG9hdCB4LCBmbG9hdCB5LCBmbG9hdCB3LCBmbG9hdCBoKTsKLQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIENHQ29udGV4dFNjYWxlQ1RNKGludCBpbkNvbnRleHQsIGZsb2F0IHN4LCBmbG9hdCBzeSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBDR0NvbnRleHRUcmFuc2xhdGVDVE0oaW50IGluQ29udGV4dCwgZmxvYXQgdHgsIGZsb2F0IHR5KTsKLQkKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIENHQ29udGV4dENsaXBUb1JlY3QoaW50IGluQ29udGV4dCwgZmxvYXQgeCwgZmxvYXQgeSwgZmxvYXQgdywgZmxvYXQgaCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IENsaXBDR0NvbnRleHRUb1JlZ2lvbihpbnQgaW5Db250ZXh0LCBzaG9ydFtdIHBvcnRSZWN0LCBpbnQgcmduSGFuZGxlKTsKLQotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQ0dDb250ZXh0QmVnaW5QYXRoKGludCBpbkNvbnRleHQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQ0dDb250ZXh0TW92ZVRvUG9pbnQoaW50IGluQ29udGV4dCwgZmxvYXQgeCwgZmxvYXQgeSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBDR0NvbnRleHRBZGRBcmMoaW50IGluQ29udGV4dCwgZmxvYXQgeCwgZmxvYXQgeSwgZmxvYXQgcmFkaXVzLAotCQkJCQlmbG9hdCBzdGFydEFuZ2xlLCBmbG9hdCBlbmRBbmdsZSwgaW50IGNsb2Nrd2lzZSk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBDR0NvbnRleHRDbG9zZVBhdGgoaW50IGluQ29udGV4dCk7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBDR0NvbnRleHRTdHJva2VQYXRoKGludCBpbkNvbnRleHQpOwotCXB1YmxpYyBzdGF0aWMgbmF0aXZlIHZvaWQgQ0dDb250ZXh0RmlsbFBhdGgoaW50IGluQ29udGV4dCk7Ci0JCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgdm9pZCBDR0NvbnRleHRTaG93R2x5cGhzQXRQb2ludChpbnQgaW5Db250ZXh0LCBmbG9hdCB4LCBmbG9hdCB5LCBjaGFyW10gZ2x5cGhzKTsKLQlwdWJsaWMgc3RhdGljIG5hdGl2ZSB2b2lkIENHQ29udGV4dFNob3dUZXh0QXRQb2ludChpbnQgaW5Db250ZXh0LCBmbG9hdCB4LCBmbG9hdCB5LCBieXRlW10gY2hhcnMpOwotCi0JLy8gcHJvY2VzcyBtYW5hZ2VyCi0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IEdldEN1cnJlbnRQcm9jZXNzKGludFtdIHBzbik7Ci0JcHVibGljIHN0YXRpYyBuYXRpdmUgaW50IFNldEZyb250UHJvY2VzcyhpbnRbXSBwc24pOwotCQotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IGtDRkFsbG9jYXRvckRlZmF1bHQgPSAwOworcHVibGljIHN0YXRpYyBmaW5hbCBuYXRpdmUgaW50IEhJVmlld1NldEJvdW5kc09yaWdpbihpbnQgaW5WaWV3LCBmbG9hdCBpblgsIGZsb2F0IGluWSk7IAogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vUGl4TWFwLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9QaXhNYXAuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZmExNDJmCi0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vUGl4TWFwLmphdmEKQEAgLTAsMCArMSwyNCBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworCitwdWJsaWMgY2xhc3MgUGl4TWFwIGV4dGVuZHMgQml0TWFwIHsKKwlwdWJsaWMgc2hvcnQgcG1WZXJzaW9uOworCXB1YmxpYyBzaG9ydCBwYWNrVHlwZTsKKwlwdWJsaWMgaW50IHBhY2tTaXplOworCXB1YmxpYyBpbnQgaFJlczsKKwlwdWJsaWMgaW50IHZSZXM7CisJcHVibGljIHNob3J0IHBpeGVsVHlwZTsKKwlwdWJsaWMgc2hvcnQgcGl4ZWxTaXplOworCXB1YmxpYyBzaG9ydCBjbXBDb3VudDsKKwlwdWJsaWMgc2hvcnQgY21wU2l6ZTsKKwlwdWJsaWMgaW50IHBpeGVsRm9ybWF0OworCXB1YmxpYyBpbnQgcG1UYWJsZTsKKwlwdWJsaWMgaW50IHBtRXh0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNpemVvZiA9IDUwOworfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vUG9pbnQuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL1BvaW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWM4ZDRhNAotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL1BvaW50LmphdmEKQEAgLTAsMCArMSwxNCBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworCitwdWJsaWMgY2xhc3MgUG9pbnQgeworCXB1YmxpYyBzaG9ydCB2OworCXB1YmxpYyBzaG9ydCBoOworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNpemVvZiA9IDQ7Cit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9SR0JDb2xvci5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vUkdCQ29sb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYTIwOTIzCi0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vUkdCQ29sb3IuamF2YQpAQCAtMCwwICsxLDE1IEBACitwYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib247CisKKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgorICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKKyAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CisgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAorICovCisKK3B1YmxpYyBjbGFzcyBSR0JDb2xvciB7CisJcHVibGljIHNob3J0IHJlZDsKKwlwdWJsaWMgc2hvcnQgZ3JlZW47CisJcHVibGljIHNob3J0IGJsdWU7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2l6ZW9mID0gNjsKK30KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL1JlY3QuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL1JlY3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNWZlNWFkCi0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vUmVjdC5qYXZhCkBAIC0wLDAgKzEsMTYgQEAKK3BhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbjsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKyAKK3B1YmxpYyBjbGFzcyBSZWN0IHsKKwlwdWJsaWMgc2hvcnQgdG9wOworCXB1YmxpYyBzaG9ydCBsZWZ0OworCXB1YmxpYyBzaG9ydCBib3R0b207CisJcHVibGljIHNob3J0IHJpZ2h0OworCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IHNpemVvZiA9IDg7CQorfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vVFhOTG9uZ1JlY3QuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL1RYTkxvbmdSZWN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzRkZTYyNQotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUIFBJL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvaW50ZXJuYWwvY2FyYm9uL1RYTkxvbmdSZWN0LmphdmEKQEAgLTAsMCArMSwxNiBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworIAorcHVibGljIGNsYXNzIFRYTkxvbmdSZWN0IHsKKwlwdWJsaWMgaW50IHRvcDsKKwlwdWJsaWMgaW50IGxlZnQ7CisJcHVibGljIGludCBib3R0b207CisJcHVibGljIGludCByaWdodDsKKwlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBzaXplb2YgPSAxNjsJCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vVGhlbWVCdXR0b25EcmF3SW5mby5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QgUEkvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9pbnRlcm5hbC9jYXJib24vVGhlbWVCdXR0b25EcmF3SW5mby5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5ZmQzZjYKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVCBQSS9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2ludGVybmFsL2NhcmJvbi9UaGVtZUJ1dHRvbkRyYXdJbmZvLmphdmEKQEAgLTAsMCArMSwxNSBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworIAorcHVibGljIGNsYXNzIFRoZW1lQnV0dG9uRHJhd0luZm8geworCXB1YmxpYyBpbnQgc3RhdGU7CisJcHVibGljIHNob3J0IHZhbHVlOworCXB1YmxpYyBzaG9ydCBhZG9ybm1lbnQ7CisJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgc2l6b2YgPSA4OworfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9Db2xvci5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9Db2xvci5qYXZhCmluZGV4IDljN2Q2NTYuLmViMzE5MjYgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZ3JhcGhpY3MvQ29sb3IuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0NvbG9yLmphdmEKQEAgLTcsNiArNyw3IEBACiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCiAKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CiAKIC8qKgpAQCAtMjMsMjYgKzI0LDIwIEBACiAgKiBAc2VlIFJHQgogICovCiBwdWJsaWMgZmluYWwgY2xhc3MgQ29sb3IgewotCiAJLyoqCiAJICogdGhlIGhhbmRsZSB0byB0aGUgT1MgY29sb3IgcmVzb3VyY2UgCiAJICogKFdhcm5pbmc6IFRoaXMgZmllbGQgaXMgcGxhdGZvcm0gZGVwZW5kZW50KQogCSAqLwotCXB1YmxpYyBpbnQgaGFuZGxlOworCXB1YmxpYyBmbG9hdFtdIGhhbmRsZTsKIAogCS8qKgogCSAqIFRoZSBkZXZpY2Ugd2hlcmUgdGhpcyBjb2xvciB3YXMgY3JlYXRlZC4KIAkgKi8KIAlEZXZpY2UgZGV2aWNlOwotCQotCS8vIEFXCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERJU1BPU0VEID0gMHgwMTsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU1lTVEVNID0gMHgwMjsKLQlwcml2YXRlIGludCBmRmxhZ3M7Ci0JLy8gQVcKLQkKKwogQ29sb3IoKSB7CiB9CisKIC8qKgkgCiAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gYSBkZXZpY2UgYW5kIHRoZQogICogZGVzaXJlZCByZWQsIGdyZWVuIGFuZCBibHVlIHZhbHVlcyBleHByZXNzZWQgYXMgaW50cyBpbiB0aGUgcmFuZ2UKQEAgLTY3LDkgKzYyLDEwIEBACiAgKgogICogQHNlZSAjZGlzcG9zZQogICovCi1wdWJsaWMgQ29sb3IgKERldmljZSBkZXZpY2UsIGludCByZWQsIGludCBncmVlbiwgaW50IGJsdWUpIHsKK3B1YmxpYyBDb2xvcihEZXZpY2UgZGV2aWNlLCBpbnQgcmVkLCBpbnQgZ3JlZW4sIGludCBibHVlKSB7CiAJaW5pdChkZXZpY2UsIHJlZCwgZ3JlZW4sIGJsdWUpOwogfQorCiAvKioJIAogICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIGEgZGV2aWNlIGFuZCBhbgogICogPGNvZGU+UkdCPC9jb2RlPiBkZXNjcmliaW5nIHRoZSBkZXNpcmVkIHJlZCwgZ3JlZW4gYW5kIGJsdWUgdmFsdWVzLgpAQCAtOTIsMjQgKzg4LDIzIEBACiAgKgogICogQHNlZSAjZGlzcG9zZQogICovCi1wdWJsaWMgQ29sb3IgKERldmljZSBkZXZpY2UsIFJHQiByZ2IpIHsKK3B1YmxpYyBDb2xvcihEZXZpY2UgZGV2aWNlLCBSR0IgcmdiKSB7CiAJaWYgKHJnYiA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWluaXQoZGV2aWNlLCByZ2IucmVkLCByZ2IuZ3JlZW4sIHJnYi5ibHVlKTsKIH0KKwogLyoqCiAgKiBEaXNwb3NlcyBvZiB0aGUgb3BlcmF0aW5nIHN5c3RlbSByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoCiAgKiB0aGUgY29sb3IuIEFwcGxpY2F0aW9ucyBtdXN0IGRpc3Bvc2Ugb2YgYWxsIGNvbG9ycyB3aGljaAogICogdGhleSBhbGxvY2F0ZS4KICAqLwogcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKLQlpZiAoKGZGbGFncyAmIFNZU1RFTSkgIT0gMCkgewotCQlTeXN0ZW0ub3V0LnByaW50bG4oIkNvbG9yLmRpc3Bvc2U6IGF0dGVtcHQgdG8gZGlzcG9zZSBzeXN0ZW0gY29sb3I7IGlnbm9yZWQiKTsKLQkJcmV0dXJuOwotCX0KLQlpZiAoZGV2aWNlICE9IG51bGwgJiYgZGV2aWNlLmlzRGlzcG9zZWQoKSkgcmV0dXJuOworCWlmIChoYW5kbGUgPT0gbnVsbCkgcmV0dXJuOworCWlmIChkZXZpY2UuaXNEaXNwb3NlZCgpKSByZXR1cm47CiAJZGV2aWNlID0gbnVsbDsKLQlmRmxhZ3MgfD0gRElTUE9TRUQ7CisJaGFuZGxlID0gbnVsbDsKIH0KKwogLyoqCiAgKiBDb21wYXJlcyB0aGUgYXJndW1lbnQgdG8gdGhlIHJlY2VpdmVyLCBhbmQgcmV0dXJucyB0cnVlCiAgKiBpZiB0aGV5IHJlcHJlc2VudCB0aGUgPGVtPnNhbWU8L2VtPiBvYmplY3QgdXNpbmcgYSBjbGFzcwpAQCAtMTIwLDEyICsxMTUsMTYgQEAKICAqCiAgKiBAc2VlICNoYXNoQ29kZQogICovCi1wdWJsaWMgYm9vbGVhbiBlcXVhbHMgKE9iamVjdCBvYmplY3QpIHsKK3B1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CiAJaWYgKG9iamVjdCA9PSB0aGlzKSByZXR1cm4gdHJ1ZTsKIAlpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBDb2xvcikpIHJldHVybiBmYWxzZTsKIAlDb2xvciBjb2xvciA9IChDb2xvcilvYmplY3Q7Ci0JcmV0dXJuIGRldmljZSA9PSBjb2xvci5kZXZpY2UgJiYgaGFuZGxlID09IGNvbG9yLmhhbmRsZTsgCisJZmxvYXRbXSByZ2JDb2xvciA9IGNvbG9yLmhhbmRsZTsKKwlpZiAoaGFuZGxlID09IHJnYkNvbG9yKSByZXR1cm4gdHJ1ZTsKKwlyZXR1cm4gZGV2aWNlID09IGNvbG9yLmRldmljZSAmJiBoYW5kbGVbMF0gPT0gcmdiQ29sb3JbMF0gJiYKKwkJaGFuZGxlWzFdID09IHJnYkNvbG9yWzFdICYmIGhhbmRsZVsyXSA9PSByZ2JDb2xvclsyXTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIHRoZSBhbW91bnQgb2YgYmx1ZSBpbiB0aGUgY29sb3IsIGZyb20gMCB0byAyNTUuCiAgKgpAQCAtMTM1LDEwICsxMzQsMTEgQEAKICAqICAgIDxsaT5FUlJPUl9HUkFQSElDX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KICAqIDwvdWw+CiAgKi8KLXB1YmxpYyBpbnQgZ2V0Qmx1ZSAoKSB7CitwdWJsaWMgaW50IGdldEJsdWUoKSB7CiAJaWYgKGlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQlyZXR1cm4gaGFuZGxlICYgMHhGRjsKKwlyZXR1cm4gKGludCkoaGFuZGxlWzJdICogMjU1KTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIHRoZSBhbW91bnQgb2YgZ3JlZW4gaW4gdGhlIGNvbG9yLCBmcm9tIDAgdG8gMjU1LgogICoKQEAgLTE0OCwxMCArMTQ4LDExIEBACiAgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgaW50IGdldEdyZWVuICgpIHsKK3B1YmxpYyBpbnQgZ2V0R3JlZW4oKSB7CiAJaWYgKGlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQlyZXR1cm4gKGhhbmRsZSA+PiA4KSAmIDB4RkY7CisJcmV0dXJuIChpbnQpKGhhbmRsZVsxXSAqIDI1NSk7CiB9CisKIC8qKgogICogUmV0dXJucyB0aGUgYW1vdW50IG9mIHJlZCBpbiB0aGUgY29sb3IsIGZyb20gMCB0byAyNTUuCiAgKgpAQCAtMTYxLDIxICsxNjIsMTEgQEAKICAqICAgIDxsaT5FUlJPUl9HUkFQSElDX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KICAqIDwvdWw+CiAgKi8KLXB1YmxpYyBpbnQgZ2V0UmVkICgpIHsKK3B1YmxpYyBpbnQgZ2V0UmVkKCkgewogCWlmIChpc0Rpc3Bvc2VkKCkpIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JcmV0dXJuIChoYW5kbGUgPj4gMTYpICYgMHhGRjsKKwlyZXR1cm4gKGludCkoaGFuZGxlWzBdICogMjU1KTsKIH0KLS8qKgotICogUmV0dXJucyBhbiA8Y29kZT5SR0I8L2NvZGU+IHJlcHJlc2VudGluZyB0aGUgcmVjZWl2ZXIuCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0dSQVBISUNfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogPC91bD4KLSAqLwotcHVibGljIFJHQiBnZXRSR0IgKCkgewotCWlmIChpc0Rpc3Bvc2VkKCkpIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JcmV0dXJuIG5ldyBSR0IoKGhhbmRsZSA+PiAxNikgJiAweEZGLCAoaGFuZGxlID4+IDgpICYgMHhGRiwgKGhhbmRsZSA+PiAwKSAmIDB4RkYpOwotfQorCiAvKioKICAqIFJldHVybnMgYW4gaW50ZWdlciBoYXNoIGNvZGUgZm9yIHRoZSByZWNlaXZlci4gQW55IHR3byAKICAqIG9iamVjdHMgd2hpY2ggcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4gcGFzc2VkIHRvIApAQCAtMTg2LDEwICsxNzcsNDYgQEAKICAqCiAgKiBAc2VlICNlcXVhbHMKICAqLwotcHVibGljIGludCBoYXNoQ29kZSAoKSB7CitwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogCWlmIChpc0Rpc3Bvc2VkKCkpIHJldHVybiAwOwotCXJldHVybiBoYW5kbGU7CisJcmV0dXJuIChpbnQpKGhhbmRsZVswXSAqIDI1NSkgXiAoaW50KShoYW5kbGVbMV0gKiAyNTUpIF4gKGludCkoaGFuZGxlWzJdICogMjU1KTsKIH0KKworLyoqCisgKiBSZXR1cm5zIGFuIDxjb2RlPlJHQjwvY29kZT4gcmVwcmVzZW50aW5nIHRoZSByZWNlaXZlci4KKyAqCisgKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+CisgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CisgKiA8L3VsPgorICovCitwdWJsaWMgUkdCIGdldFJHQiAoKSB7CisJaWYgKGlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKKwlyZXR1cm4gbmV3IFJHQihnZXRSZWQoKSwgZ2V0R3JlZW4oKSwgZ2V0Qmx1ZSgpKTsKK30KKworLyoqCSAKKyAqIEludm9rZXMgcGxhdGZvcm0gc3BlY2lmaWMgZnVuY3Rpb25hbGl0eSB0byBhbGxvY2F0ZSBhIG5ldyBjb2xvci4KKyAqIDxwPgorICogPGI+SU1QT1JUQU5UOjwvYj4gVGhpcyBtZXRob2QgaXMgPGVtPm5vdDwvZW0+IHBhcnQgb2YgdGhlIHB1YmxpYworICogQVBJIGZvciA8Y29kZT5Db2xvcjwvY29kZT4uIEl0IGlzIG1hcmtlZCBwdWJsaWMgb25seSBzbyB0aGF0IGl0CisgKiBjYW4gYmUgc2hhcmVkIHdpdGhpbiB0aGUgcGFja2FnZXMgcHJvdmlkZWQgYnkgU1dULiBJdCBpcyBub3QKKyAqIGF2YWlsYWJsZSBvbiBhbGwgcGxhdGZvcm1zLCBhbmQgc2hvdWxkIG5ldmVyIGJlIGNhbGxlZCBmcm9tCisgKiBhcHBsaWNhdGlvbiBjb2RlLgorICogPC9wPgorICoKKyAqIEBwYXJhbSBkZXZpY2UgdGhlIGRldmljZSBvbiB3aGljaCB0byBhbGxvY2F0ZSB0aGUgY29sb3IKKyAqIEBwYXJhbSBoYW5kbGUgdGhlIGhhbmRsZSBmb3IgdGhlIGNvbG9yCisgKiAKKyAqIEBwcml2YXRlCisgKi8KK3B1YmxpYyBzdGF0aWMgQ29sb3IgY2FyYm9uX25ldyhEZXZpY2UgZGV2aWNlLCBmbG9hdFtdIHJnYkNvbG9yKSB7CisJaWYgKGRldmljZSA9PSBudWxsKSBkZXZpY2UgPSBEZXZpY2UuZ2V0RGV2aWNlKCk7CisJQ29sb3IgY29sb3IgPSBuZXcgQ29sb3IoKTsKKwljb2xvci5oYW5kbGUgPSByZ2JDb2xvcjsKKwljb2xvci5kZXZpY2UgPSBkZXZpY2U7CisJcmV0dXJuIGNvbG9yOworfQorCiB2b2lkIGluaXQoRGV2aWNlIGRldmljZSwgaW50IHJlZCwgaW50IGdyZWVuLCBpbnQgYmx1ZSkgewogCWlmIChkZXZpY2UgPT0gbnVsbCkgZGV2aWNlID0gRGV2aWNlLmdldERldmljZSgpOwogCWlmIChkZXZpY2UgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTE5OSw5ICsyMjYsMTQgQEAKIAkJKGJsdWUgPiAyNTUpIHx8IChibHVlIDwgMCkpIHsKIAkJCVNXVC5lcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CiAJfQotICAgIHRoaXMuZGV2aWNlPSBkZXZpY2U7Ci0JaGFuZGxlPSAoKHJlZCAmIDB4RkYpIDw8IDE2KSB8ICgoZ3JlZW4gJiAweEZGKSA8PCA4KSB8IChibHVlICYgMHhGRik7CisJZmxvYXRbXSByZ2JDb2xvciA9IG5ldyBmbG9hdFs0XTsKKwlyZ2JDb2xvclswXSA9IHJlZCAvIDI1NWY7CisJcmdiQ29sb3JbMV0gPSBncmVlbiAvIDI1NWY7CisJcmdiQ29sb3JbMl0gPSBibHVlIC8gMjU1ZjsKKwlyZ2JDb2xvclszXSA9IDE7CisJaGFuZGxlID0gcmdiQ29sb3I7CiB9CisKIC8qKgogICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY29sb3IgaGFzIGJlZW4gZGlzcG9zZWQsCiAgKiBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KQEAgLTIxMywxNyArMjQ1LDkgQEAKICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gd2hlbiB0aGUgY29sb3IgaXMgZGlzcG9zZWQgYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UKICAqLwogcHVibGljIGJvb2xlYW4gaXNEaXNwb3NlZCgpIHsKLQlyZXR1cm4gKGZGbGFncyAmIERJU1BPU0VEKSAhPSAwOworCXJldHVybiBoYW5kbGUgPT0gbnVsbDsKIH0KLXB1YmxpYyBzdGF0aWMgQ29sb3IgY2FyYm9uX25ldyhEZXZpY2UgZGV2aWNlLCBpbnQgcGFja2VkLCBib29sZWFuIHN5c3RlbSkgewotCWlmIChkZXZpY2UgPT0gbnVsbCkgZGV2aWNlID0gRGV2aWNlLmdldERldmljZSgpOwotCUNvbG9yIGNvbG9yID0gbmV3IENvbG9yKCk7Ci0JY29sb3IuZGV2aWNlID0gZGV2aWNlOwotCWNvbG9yLmhhbmRsZSA9IHBhY2tlZDsKLQlpZiAoc3lzdGVtKQotCQljb2xvci5mRmxhZ3MgfD0gU1lTVEVNOwotCXJldHVybiBjb2xvcjsKLX0KKwogLyoqCiAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZQogICogZGVzY3JpcHRpb24gb2YgdGhlIHJlY2VpdmVyLgpAQCAtMjM0LDQgKzI1OCw1IEBACiAJaWYgKGlzRGlzcG9zZWQoKSkgcmV0dXJuICJDb2xvciB7KkRJU1BPU0VEKn0iOwogCXJldHVybiAiQ29sb3IgeyIgKyBnZXRSZWQoKSArICIsICIgKyBnZXRHcmVlbigpICsgIiwgIiArIGdldEJsdWUoKSArICJ9IjsKIH0KKwogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9DdXJzb3IuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZ3JhcGhpY3MvQ3Vyc29yLmphdmEKaW5kZXggYjYxMzhlOS4uOTc2YzZmMyAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9DdXJzb3IuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0N1cnNvci5qYXZhCkBAIC03LDkgKzcsOCBAQAogICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKICAqLwogCitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uT1M7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuRGlzcGxheTsKIAogLyoqCiAgKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBtYW5hZ2Ugb3BlcmF0aW5nIHN5c3RlbSByZXNvdXJjZXMgdGhhdApAQCAtMzUsMjYgKzM0LDY2IEBACiAgKiBOb3RlOiBPbmx5IG9uZSBvZiB0aGUgYWJvdmUgc3R5bGVzIG1heSBiZSBzcGVjaWZpZWQuCiAgKiA8L3A+CiAgKi8KKwogcHVibGljIGZpbmFsIGNsYXNzIEN1cnNvciB7CisJCiAJLyoqCiAJICogdGhlIGhhbmRsZSB0byB0aGUgT1MgY3Vyc29yIHJlc291cmNlCiAJICogKFdhcm5pbmc6IFRoaXMgZmllbGQgaXMgcGxhdGZvcm0gZGVwZW5kZW50KQogCSAqLwogCXB1YmxpYyBpbnQgaGFuZGxlOwotCisJCiAJLyoqCi0JICogVGhlIGRldmljZSB3aGVyZSB0aGlzIEN1cnNvciB3YXMgY3JlYXRlZC4KKwkgKiB0aGUgZGV2aWNlIHdoZXJlIHRoaXMgY3Vyc29yIHdhcyBjcmVhdGVkCiAJICovCiAJRGV2aWNlIGRldmljZTsKIAkKLQkvLyBBVwotCXByaXZhdGUgYm9vbGVhbiBmRGlzcG9zZTsKKwkvKioKKwkgKiBkYXRhIGFuZCBtYXNrIHVzZWQgdG8gY3JlYXRlIGEgUmVzaXplIE5TIEN1cnNvcgorCSAqLworCXN0YXRpYyBmaW5hbCBzaG9ydCBbXSBTSVpFTlNfU09VUkNFID0gbmV3IHNob3J0W10geworCQkoc2hvcnQpMHgwMDAwLAorCQkoc2hvcnQpMHgwMTgwLAorCQkoc2hvcnQpMHgwM0MwLAorCQkoc2hvcnQpMHgwN0UwLAorCQkoc2hvcnQpMHgwMTgwLAorCQkoc2hvcnQpMHgwMTgwLAorCQkoc2hvcnQpMHgwMTgwLAorCSAJKHNob3J0KTB4N0ZGRSwKKwkgCShzaG9ydCkweDdGRkUsCisJCShzaG9ydCkweDAxODAsCisJCShzaG9ydCkweDAxODAsCisJCShzaG9ydCkweDAxODAsCisJCShzaG9ydCkweDA3RTAsCisJCShzaG9ydCkweDAzQzAsCisJCShzaG9ydCkweDAxODAsCisJCShzaG9ydCkweDAwMDAsCisJfTsKKwlzdGF0aWMgZmluYWwgc2hvcnQgW10gU0laRU5TX01BU0sgPSBuZXcgc2hvcnRbXSB7CisJCShzaG9ydCkweDAxODAsCisJCShzaG9ydCkweDAzQzAsCisJCShzaG9ydCkweDA3RTAsCisJCShzaG9ydCkweDBGRjAsCisJCShzaG9ydCkweDBGRjAsCisJCShzaG9ydCkweDAzQzAsCisJCShzaG9ydCkweEZGRkYsCisJIAkoc2hvcnQpMHhGRkZGLAorCSAJKHNob3J0KTB4RkZGRiwKKwkJKHNob3J0KTB4RkZGRiwKKwkJKHNob3J0KTB4MDNDMCwKKwkJKHNob3J0KTB4MEZGMCwKKwkJKHNob3J0KTB4MEZGMCwKKwkJKHNob3J0KTB4MDdFMCwKKwkJKHNob3J0KTB4MDNDMCwKKwkJKHNob3J0KTB4MDE4MCwKKwl9OwogCQotCXByaXZhdGUgc3RhdGljIGludCBOT19DVVJTT1I7Ci0JLy8gQVcKLQkJCi1DdXJzb3IgKCkgeworLyoqCisgKiBQcmV2ZW50cyB1bmluaXRpYWxpemVkIGluc3RhbmNlcyBmcm9tIGJlaW5nIGNyZWF0ZWQgb3V0c2lkZSB0aGUgcGFja2FnZS4KKyAqLworQ3Vyc29yKCkgewogfQorCiAvKioJIAogICogQ29uc3RydWN0cyBhIG5ldyBjdXJzb3IgZ2l2ZW4gYSBkZXZpY2UgYW5kIGEgc3R5bGUKICAqIGNvbnN0YW50IGRlc2NyaWJpbmcgdGhlIGRlc2lyZWQgY3Vyc29yIGFwcGVhcmFuY2UuCkBAIC05Niw1OCArMTM1LDQ4IEBACiAgKiBAc2VlIFNXVCNDVVJTT1JfTk8KICAqIEBzZWUgU1dUI0NVUlNPUl9IQU5ECiAgKi8KLXB1YmxpYyBDdXJzb3IgKERldmljZSBkZXZpY2UsIGludCBzdHlsZSkgeworcHVibGljIEN1cnNvcihEZXZpY2UgZGV2aWNlLCBpbnQgc3R5bGUpIHsKIAlpZiAoZGV2aWNlID09IG51bGwpIGRldmljZSA9IERldmljZS5nZXREZXZpY2UoKTsKIAlpZiAoZGV2aWNlID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJdGhpcy5kZXZpY2UgPSBkZXZpY2U7Ci0JCi0JaGFuZGxlID0gT1Mua1RoZW1lQXJyb3dDdXJzb3I7CQkvLyB0aGUgZGVmYXVsdCBjdXJzb3IKLQkKIAlzd2l0Y2ggKHN0eWxlKSB7Ci0JY2FzZSBTV1QuQ1VSU09SX0FSUk9XOgotCQloYW5kbGU9IE9TLmtUaGVtZUFycm93Q3Vyc29yOwotCQlicmVhazsKLQljYXNlIFNXVC5DVVJTT1JfV0FJVDoKLQkJaGFuZGxlPSBPUy5rVGhlbWVTcGlubmluZ0N1cnNvcjsKLQkJYnJlYWs7Ci0JY2FzZSBTV1QuQ1VSU09SX0FQUFNUQVJUSU5HOgotCQloYW5kbGU9IE9TLmtUaGVtZVdhdGNoQ3Vyc29yOwotCQlicmVhazsKLQljYXNlIFNXVC5DVVJTT1JfSEFORDoKLQkJaGFuZGxlPSBPUy5rVGhlbWVPcGVuSGFuZEN1cnNvcjsKLQkJYnJlYWs7Ci0JY2FzZSBTV1QuQ1VSU09SX0NST1NTOgotCQloYW5kbGU9IE9TLmtUaGVtZUNyb3NzQ3Vyc29yOwotCQlicmVhazsKLQljYXNlIFNXVC5DVVJTT1JfSEVMUDogCQkJCWJyZWFrOwotCWNhc2UgU1dULkNVUlNPUl9TSVpFQUxMOiAJCQlicmVhazsKLQljYXNlIFNXVC5DVVJTT1JfU0laRU5FU1c6IAkJCWJyZWFrOwotCWNhc2UgU1dULkNVUlNPUl9TSVpFTlM6IAkJCWJyZWFrOwotCWNhc2UgU1dULkNVUlNPUl9TSVpFTldTRTogCQkJYnJlYWs7Ci0JY2FzZSBTV1QuQ1VSU09SX1NJWkVXRTogCQkJYnJlYWs7Ci0JY2FzZSBTV1QuQ1VSU09SX1NJWkVOOiAJCQlicmVhazsKLQljYXNlIFNXVC5DVVJTT1JfU0laRVM6IAkJCWJyZWFrOwotCWNhc2UgU1dULkNVUlNPUl9TSVpFRTogCQkJYnJlYWs7Ci0JY2FzZSBTV1QuQ1VSU09SX1NJWkVXOiAJCQlicmVhazsKLQljYXNlIFNXVC5DVVJTT1JfU0laRU5FOiAJCQlicmVhazsKLQljYXNlIFNXVC5DVVJTT1JfU0laRVNFOiAJCQlicmVhazsKLQljYXNlIFNXVC5DVVJTT1JfU0laRVNXOiAJCQlicmVhazsKLQljYXNlIFNXVC5DVVJTT1JfU0laRU5XOiAJCQlicmVhazsKLQljYXNlIFNXVC5DVVJTT1JfVVBBUlJPVzogCQkJYnJlYWs7Ci0JY2FzZSBTV1QuQ1VSU09SX0lCRUFNOgotCQloYW5kbGU9IE9TLmtUaGVtZUlCZWFtQ3Vyc29yOwotCQlicmVhazsKLQljYXNlIFNXVC5DVVJTT1JfTk86Ci0JCWlmIChOT19DVVJTT1IgPT0gMCkgewotCQkJc2hvcnRbXSBkYXRhPSBuZXcgc2hvcnRbMTZdOwotCQkJTk9fQ1VSU09SPSBPUy5OZXdDdXJzb3IoKHNob3J0KSAwLCAoc2hvcnQpMCwgZGF0YSwgZGF0YSk7CisJCWNhc2UgU1dULkNVUlNPUl9IQU5EOiAJCQloYW5kbGUgPSBPUy5rVGhlbWVQb2ludGluZ0hhbmRDdXJzb3I7IGJyZWFrOworCQljYXNlIFNXVC5DVVJTT1JfQVJST1c6IAkJaGFuZGxlID0gT1Mua1RoZW1lQXJyb3dDdXJzb3I7IGJyZWFrOworCQljYXNlIFNXVC5DVVJTT1JfV0FJVDogCQkJaGFuZGxlID0gT1Mua1RoZW1lU3Bpbm5pbmdDdXJzb3I7IGJyZWFrOworCQljYXNlIFNXVC5DVVJTT1JfQ1JPU1M6IAkJaGFuZGxlID0gT1Mua1RoZW1lQ3Jvc3NDdXJzb3I7IGJyZWFrOworCQljYXNlIFNXVC5DVVJTT1JfQVBQU1RBUlRJTkc6IAloYW5kbGUgPSBPUy5rVGhlbWVXYXRjaEN1cnNvcjsgYnJlYWs7CisJCWNhc2UgU1dULkNVUlNPUl9IRUxQOiAJCQloYW5kbGUgPSBPUy5rVGhlbWVDcm9zc0N1cnNvcjsgYnJlYWs7CisJCWNhc2UgU1dULkNVUlNPUl9TSVpFQUxMOiAJCWhhbmRsZSA9IE9TLmtUaGVtZUNyb3NzQ3Vyc29yOyBicmVhazsKKwkJY2FzZSBTV1QuQ1VSU09SX1NJWkVORVNXOiAJCWhhbmRsZSA9IE9TLmtUaGVtZUNyb3NzQ3Vyc29yOyBicmVhazsKKwkJY2FzZSBTV1QuQ1VSU09SX1NJWkVOUzogeworCQkJb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5DdXJzb3IgY3Vyc29yID0gbmV3IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uQ3Vyc29yKCk7CisJCQljdXJzb3IuZGF0YSA9IFNJWkVOU19TT1VSQ0U7CisJCQljdXJzb3IubWFzayA9IFNJWkVOU19NQVNLOworCQkJY3Vyc29yLmhvdFNwb3RfaCA9IDc7CisJCQljdXJzb3IuaG90U3BvdF92ID0gNzsKKwkJCWhhbmRsZSA9IE9TLk5ld1B0cihvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkN1cnNvci5zaXplb2YpOworCQkJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCQkJT1MubWVtY3B5KGhhbmRsZSwgY3Vyc29yLCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkN1cnNvci5zaXplb2YpOwkKKwkgCQlicmVhazsKIAkJfQotCQloYW5kbGUgPSBOT19DVVJTT1I7Ci0JCWJyZWFrOwotCWRlZmF1bHQ6Ci0JCVNXVC5lcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CisJCWNhc2UgU1dULkNVUlNPUl9TSVpFTldTRTogCQloYW5kbGUgPSBPUy5rVGhlbWVDcm9zc0N1cnNvcjsgYnJlYWs7CisJCWNhc2UgU1dULkNVUlNPUl9TSVpFV0U6IAkJaGFuZGxlID0gT1Mua1RoZW1lUmVzaXplTGVmdFJpZ2h0Q3Vyc29yOyBicmVhazsKKwkJY2FzZSBTV1QuQ1VSU09SX1NJWkVOOiAJCWhhbmRsZSA9IE9TLmtUaGVtZUNyb3NzQ3Vyc29yOyBicmVhazsKKwkJY2FzZSBTV1QuQ1VSU09SX1NJWkVTOiAJCWhhbmRsZSA9IE9TLmtUaGVtZUNyb3NzQ3Vyc29yOyBicmVhazsKKwkJY2FzZSBTV1QuQ1VSU09SX1NJWkVFOiAJCWhhbmRsZSA9IE9TLmtUaGVtZVJlc2l6ZVJpZ2h0Q3Vyc29yOyBicmVhazsKKwkJY2FzZSBTV1QuQ1VSU09SX1NJWkVXOiAJCWhhbmRsZSA9IE9TLmtUaGVtZVJlc2l6ZUxlZnRDdXJzb3I7IGJyZWFrOworCQljYXNlIFNXVC5DVVJTT1JfU0laRU5FOiAJCWhhbmRsZSA9IE9TLmtUaGVtZUNyb3NzQ3Vyc29yOyBicmVhazsKKwkJY2FzZSBTV1QuQ1VSU09SX1NJWkVTRTogCQloYW5kbGUgPSBPUy5rVGhlbWVDcm9zc0N1cnNvcjsgYnJlYWs7CisJCWNhc2UgU1dULkNVUlNPUl9TSVpFU1c6IAkJaGFuZGxlID0gT1Mua1RoZW1lQ3Jvc3NDdXJzb3I7IGJyZWFrOworCQljYXNlIFNXVC5DVVJTT1JfU0laRU5XOiAJCWhhbmRsZSA9IE9TLmtUaGVtZUNyb3NzQ3Vyc29yOyBicmVhazsKKwkJY2FzZSBTV1QuQ1VSU09SX1VQQVJST1c6IAkJaGFuZGxlID0gT1Mua1RoZW1lQ3Jvc3NDdXJzb3I7IGJyZWFrOworCQljYXNlIFNXVC5DVVJTT1JfSUJFQU06IAkJaGFuZGxlID0gT1Mua1RoZW1lSUJlYW1DdXJzb3I7IGJyZWFrOworCQljYXNlIFNXVC5DVVJTT1JfTk86IAkJCWhhbmRsZSA9IE9TLmtUaGVtZU5vdEFsbG93ZWRDdXJzb3I7IGJyZWFrOworCQlkZWZhdWx0OgorCQkJU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKIAl9CiB9CisKIC8qKgkgCiAgKiBDb25zdHJ1Y3RzIGEgbmV3IGN1cnNvciBnaXZlbiBhIGRldmljZSwgaW1hZ2UgYW5kIG1hc2sKICAqIGRhdGEgZGVzY3JpYmluZyB0aGUgZGVzaXJlZCBjdXJzb3IgYXBwZWFyYW5jZSwgYW5kIHRoZSB4CkBAIC0xODAsMTQgKzIwOSwxNCBAQAogICogICAgPGxpPkVSUk9SX05PX0hBTkRMRVMgLSBpZiBhIGhhbmRsZSBjb3VsZCBub3QgYmUgb2J0YWluZWQgZm9yIGN1cnNvciBjcmVhdGlvbjwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgQ3Vyc29yIChEZXZpY2UgZGV2aWNlLCBJbWFnZURhdGEgc291cmNlLCBJbWFnZURhdGEgbWFzaywgaW50IGhvdHNwb3RYLCBpbnQgaG90c3BvdFkpIHsKK3B1YmxpYyBDdXJzb3IoRGV2aWNlIGRldmljZSwgSW1hZ2VEYXRhIHNvdXJjZSwgSW1hZ2VEYXRhIG1hc2ssIGludCBob3RzcG90WCwgaW50IGhvdHNwb3RZKSB7CiAJaWYgKGRldmljZSA9PSBudWxsKSBkZXZpY2UgPSBEZXZpY2UuZ2V0RGV2aWNlKCk7CiAJaWYgKGRldmljZSA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCXRoaXMuZGV2aWNlID0gZGV2aWNlOwogCWlmIChzb3VyY2UgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlpZiAobWFzayA9PSBudWxsKSB7CiAJCWlmIChzb3VyY2UuZ2V0VHJhbnNwYXJlbmN5VHlwZSgpICE9IFNXVC5UUkFOU1BBUkVOQ1lfTUFTSykgewotCQkJU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKKwkJCVNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJCX0KIAkJbWFzayA9IHNvdXJjZS5nZXRUcmFuc3BhcmVuY3lNYXNrKCk7CiAJfQpAQCAtMTk1LDcgKzIyNCw3IEBACiAJaWYgKG1hc2sud2lkdGggIT0gc291cmNlLndpZHRoIHx8IG1hc2suaGVpZ2h0ICE9IHNvdXJjZS5oZWlnaHQpIHsKIAkJU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKIAl9Ci0JLyogQ2hlY2sgZGVwdGhzICovCisJLyogQ2hlY2sgY29sb3IgZGVwdGhzICovCiAJaWYgKG1hc2suZGVwdGggIT0gMSkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKIAlpZiAoc291cmNlLmRlcHRoICE9IDEpIFNXVC5lcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CiAJLyogQ2hlY2sgdGhlIGhvdHNwb3RzICovCkBAIC0yMDMsNTEgKzIzMiw1NiBAQAogCQlob3RzcG90WSA+PSBzb3VyY2UuaGVpZ2h0IHx8IGhvdHNwb3RZIDwgMCkgewogCQlTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwogCX0KLQkKLQlpbnQgdz0gTWF0aC5taW4oMTYsIHNvdXJjZS53aWR0aCk7Ci0JaW50IGg9IE1hdGgubWluKDE2LCBzb3VyY2UuaGVpZ2h0KTsKLQkKLQlzaG9ydFtdIGRhdGE9IG5ldyBzaG9ydFsxNl07Ci0Jc2hvcnRbXSBtc2s9IG5ldyBzaG9ydFsxNl07Ci0JCi0JZm9yIChpbnQgeT0gMDsgeSA8IGg7IHkrKykgewotCQlzaG9ydCBkPSAwOwotCQlzaG9ydCBtPSAwOwotCQlmb3IgKGludCB4PSAwOyB4IDwgdzsgeCsrKSB7CisJLyogQ3JlYXRlIHRoZSBjdXJzb3IgKi8KKwlvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkN1cnNvciBjdXJzb3IgPSBuZXcgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5DdXJzb3IoKTsKKwlpbnQgd2lkdGggPSBNYXRoLm1pbigxNiwgc291cmNlLndpZHRoKTsKKwlpbnQgaGVpZ2h0ID0gTWF0aC5taW4oMTYsIHNvdXJjZS5oZWlnaHQpOworCXNob3J0W10gc3JjRGF0YSA9IGN1cnNvci5kYXRhOworCXNob3J0W10gbWFza0RhdGEgPSBjdXJzb3IubWFzazsKKwlmb3IgKGludCB5PSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKKwkJc2hvcnQgZCA9IDAsIG0gPSAwOworCQlmb3IgKGludCB4PSAwOyB4IDwgd2lkdGg7IHgrKykgewogCQkJaW50IGJpdD0gMSA+PiB4OwotCQkJaWYgKHNvdXJjZS5nZXRQaXhlbCh4LCB5KSAhPSAwKQotCQkJCWQgfD0gYml0OwotCQkJaWYgKG1hc2suZ2V0UGl4ZWwoeCwgeSkgIT0gMCkKLQkJCQltIHw9IGJpdDsKKwkJCWlmIChzb3VyY2UuZ2V0UGl4ZWwoeCwgeSkgIT0gMCkgZCB8PSBiaXQ7CisJCQlpZiAobWFzay5nZXRQaXhlbCh4LCB5KSAhPSAwKSBtIHw9IGJpdDsKIAkJfQotCQlkYXRhW3ldPSBkOwotCQltc2tbeV09IG07CisJCXNyY0RhdGFbeV0gPSBkOworCQltYXNrRGF0YVt5XSA9IG07CiAJfQotCQotCU9TLk5ld0N1cnNvcigoc2hvcnQpIGhvdHNwb3RYLCAoc2hvcnQpaG90c3BvdFksIGRhdGEsIG1zayk7CisJY3Vyc29yLmhvdFNwb3RfaCA9IChzaG9ydClNYXRoLm1pbigxNiwgaG90c3BvdFgpOworCWN1cnNvci5ob3RTcG90X3YgPSAoc2hvcnQpTWF0aC5taW4oMTYsIGhvdHNwb3RZKTsKKwloYW5kbGUgPSBPUy5OZXdQdHIob3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5DdXJzb3Iuc2l6ZW9mKTsKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JZkRpc3Bvc2U9IHRydWU7CisJT1MubWVtY3B5KGhhbmRsZSwgY3Vyc29yLCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkN1cnNvci5zaXplb2YpOwogfQotLy9wdWJsaWMgc3RhdGljIEN1cnNvciBjYXJib25fbmV3KERldmljZSBkZXZpY2UsIGludCBoYW5kbGUpIHsKLS8vCWlmIChkZXZpY2UgPT0gbnVsbCkgZGV2aWNlID0gRGV2aWNlLmdldERldmljZSgpOwotLy8JQ3Vyc29yIGN1cnNvciA9IG5ldyBDdXJzb3IoKTsKLS8vCWN1cnNvci5kZXZpY2UgPSBkZXZpY2U7Ci0vLwljdXJzb3IuaGFuZGxlID0gaGFuZGxlOwotLy8JcmV0dXJuIGN1cnNvcjsKLS8vfQorCiAvKioKICAqIERpc3Bvc2VzIG9mIHRoZSBvcGVyYXRpbmcgc3lzdGVtIHJlc291cmNlcyBhc3NvY2lhdGVkIHdpdGgKICAqIHRoZSBjdXJzb3IuIEFwcGxpY2F0aW9ucyBtdXN0IGRpc3Bvc2Ugb2YgYWxsIGN1cnNvcnMgd2hpY2gKICAqIHRoZXkgYWxsb2NhdGUuCiAgKi8KIHB1YmxpYyB2b2lkIGRpc3Bvc2UgKCkgewotCWlmIChoYW5kbGUgPT0gMCkgcmV0dXJuOworCWlmIChoYW5kbGUgPT0gLTEpIHJldHVybjsKIAlpZiAoZGV2aWNlLmlzRGlzcG9zZWQoKSkgcmV0dXJuOwotCWlmIChmRGlzcG9zZSkKLQkJT1MuRGlzcG9zZVB0cihoYW5kbGUpOwotCWRldmljZSA9IG51bGw7CisJc3dpdGNoIChoYW5kbGUpIHsKKwkJY2FzZSBPUy5rVGhlbWVQb2ludGluZ0hhbmRDdXJzb3I6CisJCWNhc2UgT1Mua1RoZW1lQXJyb3dDdXJzb3I6CisJCWNhc2UgT1Mua1RoZW1lU3Bpbm5pbmdDdXJzb3I6CisJCWNhc2UgT1Mua1RoZW1lQ3Jvc3NDdXJzb3I6CisJCWNhc2UgT1Mua1RoZW1lV2F0Y2hDdXJzb3I6CisJCWNhc2UgT1Mua1RoZW1lSUJlYW1DdXJzb3I6CisJCWNhc2UgT1Mua1RoZW1lTm90QWxsb3dlZEN1cnNvcjoKKwkJY2FzZSBPUy5rVGhlbWVSZXNpemVMZWZ0UmlnaHRDdXJzb3I6CisJCWNhc2UgT1Mua1RoZW1lUmVzaXplTGVmdEN1cnNvcjoKKwkJY2FzZSBPUy5rVGhlbWVSZXNpemVSaWdodEN1cnNvcjoKKwkJCWJyZWFrOworCQlkZWZhdWx0OgorCQkJT1MuRGlzcG9zZVB0cihoYW5kbGUpOworCX0KIAloYW5kbGUgPSAtMTsKKwlkZXZpY2UgPSBudWxsOwogfQorCiAvKioKICAqIENvbXBhcmVzIHRoZSBhcmd1bWVudCB0byB0aGUgcmVjZWl2ZXIsIGFuZCByZXR1cm5zIHRydWUKICAqIGlmIHRoZXkgcmVwcmVzZW50IHRoZSA8ZW0+c2FtZTwvZW0+IG9iamVjdCB1c2luZyBhIGNsYXNzCkBAIC0yNjEsOSArMjk1LDEwIEBACiBwdWJsaWMgYm9vbGVhbiBlcXVhbHMgKE9iamVjdCBvYmplY3QpIHsKIAlpZiAob2JqZWN0ID09IHRoaXMpIHJldHVybiB0cnVlOwogCWlmICghKG9iamVjdCBpbnN0YW5jZW9mIEN1cnNvcikpIHJldHVybiBmYWxzZTsKLQlDdXJzb3IgY3Vyc29yID0gKEN1cnNvcilvYmplY3Q7CisJQ3Vyc29yIGN1cnNvciA9IChDdXJzb3IpIG9iamVjdDsKIAlyZXR1cm4gZGV2aWNlID09IGN1cnNvci5kZXZpY2UgJiYgaGFuZGxlID09IGN1cnNvci5oYW5kbGU7CiB9CisKIC8qKgogICogUmV0dXJucyBhbiBpbnRlZ2VyIGhhc2ggY29kZSBmb3IgdGhlIHJlY2VpdmVyLiBBbnkgdHdvIAogICogb2JqZWN0cyB3aGljaCByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gd2hlbiBwYXNzZWQgdG8gCkBAIC0yNzcsNiArMzEyLDcgQEAKIHB1YmxpYyBpbnQgaGFzaENvZGUgKCkgewogCXJldHVybiBoYW5kbGU7CiB9CisKIC8qKgogICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY3Vyc29yIGhhcyBiZWVuIGRpc3Bvc2VkLAogICogYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCkBAIC0yOTAsNiArMzI2LDcgQEAKIHB1YmxpYyBib29sZWFuIGlzRGlzcG9zZWQoKSB7CiAJcmV0dXJuIGhhbmRsZSA9PSAtMTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb25jaXNlLCBodW1hbi1yZWFkYWJsZQogICogZGVzY3JpcHRpb24gb2YgdGhlIHJlY2VpdmVyLgpAQCAtMzAxLDM1ICszMzgsMjcgQEAKIAlyZXR1cm4gIkN1cnNvciB7IiArIGhhbmRsZSArICJ9IjsKIH0KIAotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLS8vIE1hYyBzdHVmZgotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCS8qKgotCSAqIE1ldGhvZCBpbnN0YWxsLgotCSAqLwotCXB1YmxpYyB2b2lkIGluc3RhbGwoRGlzcGxheSBkaXNwbGF5KSB7Ci0JCWlmIChoYW5kbGUgIT0gZGlzcGxheS5mQ3VycmVudEN1cnNvcikgewotCQkJZGlzcGxheS5mQ3VycmVudEN1cnNvcj0gaGFuZGxlOwotCQkJc3dpdGNoIChoYW5kbGUpIHsKLQkJCQkKLQkJCWNhc2UgLTE6CS8vIGRpc3Bvc2VkCi0JCQkJYnJlYWs7Ci0KLQkJCWNhc2UgT1Mua1RoZW1lQXJyb3dDdXJzb3I6Ci0JCQljYXNlIE9TLmtUaGVtZVNwaW5uaW5nQ3Vyc29yOgotCQkJY2FzZSBPUy5rVGhlbWVXYXRjaEN1cnNvcjoKLQkJCWNhc2UgT1Mua1RoZW1lT3BlbkhhbmRDdXJzb3I6Ci0JCQljYXNlIE9TLmtUaGVtZUNyb3NzQ3Vyc29yOgotCQkJY2FzZSBPUy5rVGhlbWVJQmVhbUN1cnNvcjoKLQkJCQlPUy5TZXRUaGVtZUN1cnNvcihoYW5kbGUpOwotCQkJCWJyZWFrOwotCQkJCQotCQkJZGVmYXVsdDoKLQkJCQlkaXNwbGF5LnNldEN1cnNvcihoYW5kbGUpOwotCQkJCWJyZWFrOwotCQkJfQotCQl9Ci0JfQorLyoqCSAKKyAqIEludm9rZXMgcGxhdGZvcm0gc3BlY2lmaWMgZnVuY3Rpb25hbGl0eSB0byBhbGxvY2F0ZSBhIG5ldyBjdXJzb3IuCisgKiA8cD4KKyAqIDxiPklNUE9SVEFOVDo8L2I+IFRoaXMgbWV0aG9kIGlzIDxlbT5ub3Q8L2VtPiBwYXJ0IG9mIHRoZSBwdWJsaWMKKyAqIEFQSSBmb3IgPGNvZGU+Q3Vyc29yPC9jb2RlPi4gSXQgaXMgbWFya2VkIHB1YmxpYyBvbmx5IHNvIHRoYXQgaXQKKyAqIGNhbiBiZSBzaGFyZWQgd2l0aGluIHRoZSBwYWNrYWdlcyBwcm92aWRlZCBieSBTV1QuIEl0IGlzIG5vdAorICogYXZhaWxhYmxlIG9uIGFsbCBwbGF0Zm9ybXMsIGFuZCBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkIGZyb20KKyAqIGFwcGxpY2F0aW9uIGNvZGUuCisgKiA8L3A+CisgKgorICogQHBhcmFtIGRldmljZSB0aGUgZGV2aWNlIG9uIHdoaWNoIHRvIGFsbG9jYXRlIHRoZSBjb2xvcgorICogQHBhcmFtIGhhbmRsZSB0aGUgaGFuZGxlIGZvciB0aGUgY3Vyc29yCisgKiAKKyAqIEBwcml2YXRlCisgKi8KK3B1YmxpYyBzdGF0aWMgQ3Vyc29yIGNhcmJvbl9uZXcoRGV2aWNlIGRldmljZSwgaW50IGhhbmRsZSkgeworCWlmIChkZXZpY2UgPT0gbnVsbCkgZGV2aWNlID0gRGV2aWNlLmdldERldmljZSgpOworCUN1cnNvciBjdXJzb3IgPSBuZXcgQ3Vyc29yKCk7CisJY3Vyc29yLmhhbmRsZSA9IGhhbmRsZTsKKwljdXJzb3IuZGV2aWNlID0gZGV2aWNlOworCXJldHVybiBjdXJzb3I7Cit9CiAKIH0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZ3JhcGhpY3MvRGV2aWNlLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0RldmljZS5qYXZhCmluZGV4IDM2NGE0MDQuLmVhZWI3N2QgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZ3JhcGhpY3MvRGV2aWNlLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9EZXZpY2UuamF2YQpAQCAtNyw4ICs3LDkgQEAKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAgKi8KIAotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuKjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKIAogLyoqCiAgKiBUaGlzIGNsYXNzIGlzIHRoZSBhYnN0cmFjdCBzdXBlcmNsYXNzIG9mIGFsbCBkZXZpY2Ugb2JqZWN0cywKQEAgLTE4LDM0ICsxOSwzMCBAQAogICovCiBwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRGV2aWNlIGltcGxlbWVudHMgRHJhd2FibGUgewogCQotCS8qKgotCSAqIHRoZSBoYW5kbGUgdG8gdGhlIEdEZXZpY2UKLQkgKiAoV2FybmluZzogVGhpcyBmaWVsZCBpcyBwbGF0Zm9ybSBkZXBlbmRlbnQpCi0JICovCi0JcHVibGljIGludCBmR0RldmljZUhhbmRsZTsJCi0KIAkvKiBEZWJ1Z2dpbmcgKi8KIAlwdWJsaWMgc3RhdGljIGJvb2xlYW4gREVCVUc7CiAJYm9vbGVhbiBkZWJ1ZyA9IERFQlVHOwotCXB1YmxpYyBib29sZWFuIHRyYWNraW5nID0gREVCVUc7CisJYm9vbGVhbiB0cmFja2luZyA9IERFQlVHOwogCUVycm9yIFtdIGVycm9yczsKIAlPYmplY3QgW10gb2JqZWN0czsKLQkJCi0JLyogU3lzdGVtIENvbG9ycyAqLworCQorCS8qIERpc3Bvc2VkIGZsYWcgKi8KKwlib29sZWFuIGRpc3Bvc2VkLCB3YXJuaW5nczsKKwkKKwlpbnQgY29sb3JzcGFjZTsKKwkKKwkvKgorCSogVGhlIGZvbGxvd2luZyBjb2xvcnMgYXJlIGxpc3RlZCBpbiB0aGUgV2luZG93cworCSogUHJvZ3JhbW1lcidzIFJlZmVyZW5jZSBhcyB0aGUgY29sb3JzIGluIHRoZSBkZWZhdWx0CisJKiBwYWxldHRlLgorCSovCiAJQ29sb3IgQ09MT1JfQkxBQ0ssIENPTE9SX0RBUktfUkVELCBDT0xPUl9EQVJLX0dSRUVOLCBDT0xPUl9EQVJLX1lFTExPVywgQ09MT1JfREFSS19CTFVFOwogCUNvbG9yIENPTE9SX0RBUktfTUFHRU5UQSwgQ09MT1JfREFSS19DWUFOLCBDT0xPUl9HUkFZLCBDT0xPUl9EQVJLX0dSQVksIENPTE9SX1JFRDsKIAlDb2xvciBDT0xPUl9HUkVFTiwgQ09MT1JfWUVMTE9XLCBDT0xPUl9CTFVFLCBDT0xPUl9NQUdFTlRBLCBDT0xPUl9DWUFOLCBDT0xPUl9XSElURTsKLQkKLQkvKiBTeXN0ZW0gRm9udCAqLwotCU1hY0ZvbnQgc3lzdGVtRm9udDsKIAotCS8vIEFXCi0JaW50IGZTY3JlZW5EZXB0aDsKLQkvLyBBVworCS8qIFN5c3RlbSBGb250ICovCisJRm9udCBzeXN0ZW1Gb250OwogCQotCS8qIFdhcm5pbmcgYW5kIEVycm9yIEhhbmRsZXJzICovCi0JYm9vbGVhbiB3YXJuaW5ncyA9IHRydWU7Ci0JCQogCS8qCiAJKiBURU1QT1JBUlkgQ09ERS4gV2hlbiBhIGdyYXBoaWNzIG9iamVjdCBpcwogCSogY3JlYXRlZCBhbmQgdGhlIGRldmljZSBwYXJhbWV0ZXIgaXMgbnVsbCwKQEAgLTY2LDggKzYzLDggQEAKIAkJfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHt9CiAJfQkKIAotLyogCi0qIFRFTVBPUkFSWSBDT0RFIAorLyoKKyogVEVNUE9SQVJZIENPREUuCiAqLwogc3RhdGljIERldmljZSBnZXREZXZpY2UgKCkgewogCWlmIChEZXZpY2VGaW5kZXIgIT0gbnVsbCkgRGV2aWNlRmluZGVyLnJ1bigpOwpAQCAtOTAsOCArODcsOCBAQAogICovCiBwdWJsaWMgRGV2aWNlKERldmljZURhdGEgZGF0YSkgewogCWlmIChkYXRhICE9IG51bGwpIHsKLQkJdHJhY2tpbmcgPSBkYXRhLnRyYWNraW5nOwogCQlkZWJ1ZyA9IGRhdGEuZGVidWc7CisJCXRyYWNraW5nID0gZGF0YS50cmFja2luZzsKIAl9CiAJY3JlYXRlIChkYXRhKTsKIAlpbml0ICgpOwpAQCAtOTksMjMgKzk2LDE1IEBACiAJCWVycm9ycyA9IG5ldyBFcnJvciBbMTI4XTsKIAkJb2JqZWN0cyA9IG5ldyBPYmplY3QgWzEyOF07CiAJfQotCQotCS8qIEluaXRpYWxpemUgdGhlIHN5c3RlbSBmb250IHNsb3QgKi8KLQlGb250IGZvbnQgPSBnZXRTeXN0ZW1Gb250ICgpOwotCS8vRm9udERhdGEgZmQgPSBmb250LmdldEZvbnREYXRhICgpWzBdOwotCXN5c3RlbUZvbnQgPSBmb250LmhhbmRsZTsKIH0KIAogcHJvdGVjdGVkIHZvaWQgY2hlY2tEZXZpY2UgKCkgewotCWlmIChmR0RldmljZUhhbmRsZSA9PSAwKSBTV1QuZXJyb3IgKFNXVC5FUlJPUl9ERVZJQ0VfRElTUE9TRUQpOworCWlmIChkaXNwb3NlZCkgU1dULmVycm9yKFNXVC5FUlJPUl9ERVZJQ0VfRElTUE9TRUQpOwogfQogCiBwcm90ZWN0ZWQgdm9pZCBjcmVhdGUgKERldmljZURhdGEgZGF0YSkgewogfQogCi1wcm90ZWN0ZWQgdm9pZCBkZXN0cm95ICgpIHsKLX0KLQogLyoqCiAgKiBEaXNwb3NlcyBvZiB0aGUgb3BlcmF0aW5nIHN5c3RlbSByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoCiAgKiB0aGUgcmVjZWl2ZXIuIEFmdGVyIHRoaXMgbWV0aG9kIGhhcyBiZWVuIGludm9rZWQsIHRoZSByZWNlaXZlcgpAQCAtMTMxLDcgKzEyMCw3IEBACiAJY2hlY2tEZXZpY2UgKCk7CiAJcmVsZWFzZSAoKTsKIAlkZXN0cm95ICgpOwotCWZHRGV2aWNlSGFuZGxlPSAwOworCWRpc3Bvc2VkID0gdHJ1ZTsKIAlpZiAodHJhY2tpbmcpIHsKIAkJb2JqZWN0cyA9IG51bGw7CiAJCWVycm9ycyA9IG51bGw7CkBAIC0xNDgsNiArMTM3LDkgQEAKIAl9CiB9CiAKK3Byb3RlY3RlZCB2b2lkIGRlc3Ryb3kgKCkgeworfQorCiAvKioKICAqIFJldHVybnMgYSByZWN0YW5nbGUgZGVzY3JpYmluZyB0aGUgcmVjZWl2ZXIncyBzaXplIGFuZCBsb2NhdGlvbi4KICAqCkBAIC0xNTksNTIgKzE1MSwxNCBAQAogICovCiBwdWJsaWMgUmVjdGFuZ2xlIGdldEJvdW5kcyAoKSB7CiAJY2hlY2tEZXZpY2UgKCk7Ci0JCi0JTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JaWYgKGZHRGV2aWNlSGFuZGxlICE9IDApIHsKLQkJaW50IHBtPSBPUy5nZXRnZFBNYXAoZkdEZXZpY2VIYW5kbGUpOwotCQlpZiAocG0gIT0gMCkKLQkJCU9TLkdldFBpeEJvdW5kcyhwbSwgYm91bmRzLmdldERhdGEoKSk7Ci0JfQotCXJldHVybiBib3VuZHMudG9SZWN0YW5nbGUoKTsKLX0KLQotLyoqCi0gKiBSZXR1cm5zIGEgcmVjdGFuZ2xlIHdoaWNoIGRlc2NyaWJlcyB0aGUgYXJlYSBvZiB0aGUKLSAqIHJlY2VpdmVyIHdoaWNoIGlzIGNhcGFibGUgb2YgZGlzcGxheWluZyBkYXRhLgotICogCi0gKiBAcmV0dXJuIHRoZSBjbGllbnQgYXJlYQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9ERVZJQ0VfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNnZXRCb3VuZHMKLSAqLwotcHVibGljIFJlY3RhbmdsZSBnZXRDbGllbnRBcmVhICgpIHsKLQljaGVja0RldmljZSAoKTsKLQkKLQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQlpbnQgZ2RoPSBPUy5HZXRNYWluRGV2aWNlKCk7Ci0JT1MuR2V0QXZhaWxhYmxlV2luZG93UG9zaXRpb25pbmdCb3VuZHMoZ2RoLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQlyZXR1cm4gYm91bmRzLnRvUmVjdGFuZ2xlKCk7Ci19Ci0KLS8qKgotICogUmV0dXJucyB0aGUgYml0IGRlcHRoIG9mIHRoZSBzY3JlZW4sIHdoaWNoIGlzIHRoZSBudW1iZXIgb2YKLSAqIGJpdHMgaXQgdGFrZXMgdG8gcmVwcmVzZW50IHRoZSBudW1iZXIgb2YgdW5pcXVlIGNvbG9ycyB0aGF0Ci0gKiB0aGUgc2NyZWVuIGlzIGN1cnJlbnRseSBjYXBhYmxlIG9mIGRpc3BsYXlpbmcuIFRoaXMgbnVtYmVyIAotICogd2lsbCB0eXBpY2FsbHkgYmUgb25lIG9mIDEsIDgsIDE1LCAxNiwgMjQgb3IgMzIuCi0gKgotICogQHJldHVybiB0aGUgZGVwdGggb2YgdGhlIHNjcmVlbgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9ERVZJQ0VfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogPC91bD4KLSAqLwotcHVibGljIGludCBnZXREZXB0aCAoKSB7Ci0JY2hlY2tEZXZpY2UgKCk7Ci0JcmV0dXJuIGZTY3JlZW5EZXB0aDsKKwlpbnQgZ2RldmljZSA9IE9TLkdldE1haW5EZXZpY2UoKTsKKwlpbnRbXSBwdHIgPSBuZXcgaW50WzFdOworCU9TLm1lbWNweShwdHIsIGdkZXZpY2UsIDQpOworCUdEZXZpY2UgZGV2aWNlID0gbmV3IEdEZXZpY2UoKTsKKwlPUy5tZW1jcHkoZGV2aWNlLCBwdHJbMF0sIEdEZXZpY2Uuc2l6ZW9mKTsKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCgpOworCU9TLkdldFBpeEJvdW5kcyhkZXZpY2UuZ2RQTWFwLCByZWN0KTsKKwlyZXR1cm4gbmV3IFJlY3RhbmdsZShyZWN0LmxlZnQsIHJlY3QudG9wLCByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0LCByZWN0LmJvdHRvbSAtIHJlY3QudG9wKTsKIH0KIAogLyoqCkBAIC0yMjEsNyArMTc1LDcgQEAKICAqIEBzZWUgRGV2aWNlRGF0YQogICovCiBwdWJsaWMgRGV2aWNlRGF0YSBnZXREZXZpY2VEYXRhICgpIHsKLQljaGVja0RldmljZSAoKTsKKwljaGVja0RldmljZSgpOwogCURldmljZURhdGEgZGF0YSA9IG5ldyBEZXZpY2VEYXRhICgpOwogCWRhdGEuZGVidWcgPSBkZWJ1ZzsKIAlkYXRhLnRyYWNraW5nID0gdHJhY2tpbmc7CkBAIC0yNDQsNiArMTk4LDQ5IEBACiB9CiAKIC8qKgorICogUmV0dXJucyBhIHJlY3RhbmdsZSB3aGljaCBkZXNjcmliZXMgdGhlIGFyZWEgb2YgdGhlCisgKiByZWNlaXZlciB3aGljaCBpcyBjYXBhYmxlIG9mIGRpc3BsYXlpbmcgZGF0YS4KKyAqIAorICogQHJldHVybiB0aGUgY2xpZW50IGFyZWEKKyAqCisgKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+CisgKiAgICA8bGk+RVJST1JfREVWSUNFX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KKyAqIDwvdWw+CisgKgorICogQHNlZSAjZ2V0Qm91bmRzCisgKi8KK3B1YmxpYyBSZWN0YW5nbGUgZ2V0Q2xpZW50QXJlYSAoKSB7CisJY2hlY2tEZXZpY2UgKCk7CisJaW50IGdkZXZpY2UgPSBPUy5HZXRNYWluRGV2aWNlKCk7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QoKTsKKwlPUy5HZXRBdmFpbGFibGVXaW5kb3dQb3NpdGlvbmluZ0JvdW5kcyhnZGV2aWNlLCByZWN0KTsKKwlyZXR1cm4gbmV3IFJlY3RhbmdsZShyZWN0LmxlZnQsIHJlY3QudG9wLCByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0LCByZWN0LmJvdHRvbSAtIHJlY3QudG9wKTsKK30KKworLyoqCisgKiBSZXR1cm5zIHRoZSBiaXQgZGVwdGggb2YgdGhlIHNjcmVlbiwgd2hpY2ggaXMgdGhlIG51bWJlciBvZgorICogYml0cyBpdCB0YWtlcyB0byByZXByZXNlbnQgdGhlIG51bWJlciBvZiB1bmlxdWUgY29sb3JzIHRoYXQKKyAqIHRoZSBzY3JlZW4gaXMgY3VycmVudGx5IGNhcGFibGUgb2YgZGlzcGxheWluZy4gVGhpcyBudW1iZXIgCisgKiB3aWxsIHR5cGljYWxseSBiZSBvbmUgb2YgMSwgOCwgMTUsIDE2LCAyNCBvciAzMi4KKyAqCisgKiBAcmV0dXJuIHRoZSBkZXB0aCBvZiB0aGUgc2NyZWVuCisgKgorICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgorICogICAgPGxpPkVSUk9SX0RFVklDRV9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CisgKiA8L3VsPgorICovCitwdWJsaWMgaW50IGdldERlcHRoICgpIHsKKwljaGVja0RldmljZSAoKTsJCisJaW50IGdkZXZpY2UgPSBPUy5HZXRNYWluRGV2aWNlKCk7CisJaW50W10gcHRyID0gbmV3IGludFsxXTsKKwlPUy5tZW1jcHkocHRyLCBnZGV2aWNlLCA0KTsKKwlHRGV2aWNlIGRldmljZSA9IG5ldyBHRGV2aWNlKCk7CisJT1MubWVtY3B5KGRldmljZSwgcHRyWzBdLCBHRGV2aWNlLnNpemVvZik7CisJaW50IGRlcHRoID0gT1MuR2V0UGl4RGVwdGgoZGV2aWNlLmdkUE1hcCk7CisJcmV0dXJuIGRlcHRoOworfQorCisvKioKICAqIFJldHVybnMgYSBwb2ludCB3aG9zZSB4IGNvb3JkaW5hdGUgaXMgdGhlIGhvcml6b250YWwKICAqIGRvdHMgcGVyIGluY2ggb2YgdGhlIGRpc3BsYXksIGFuZCB3aG9zZSB5IGNvb3JkaW5hdGUKICAqIGlzIHRoZSB2ZXJ0aWNhbCBkb3RzIHBlciBpbmNoIG9mIHRoZSBkaXNwbGF5LgpAQCAtMjU2LDI4ICsyNTMsMTUgQEAKICAqLwogcHVibGljIFBvaW50IGdldERQSSAoKSB7CiAJY2hlY2tEZXZpY2UgKCk7Ci0JLyogQVcKLQlpbnQgeFNjcmVlbk51bSA9IE9TLlhEZWZhdWx0U2NyZWVuICh4RGlzcGxheSk7Ci0JaW50IHdpZHRoID0gT1MuWERpc3BsYXlXaWR0aCAoeERpc3BsYXksIHhTY3JlZW5OdW0pOwotCWludCBoZWlnaHQgPSBPUy5YRGlzcGxheUhlaWdodCAoeERpc3BsYXksIHhTY3JlZW5OdW0pOwotCWludCBtbVggPSBPUy5YRGlzcGxheVdpZHRoTU0gKHhEaXNwbGF5LCB4U2NyZWVuTnVtKTsKLQlpbnQgbW1ZID0gT1MuWERpc3BsYXlIZWlnaHRNTSAoeERpc3BsYXksIHhTY3JlZW5OdW0pOwotCSovCi0JLyogMC4wMzkzNyBtbS9pbmNoICovCi0JLyogQVcKLQlkb3VibGUgaW5jaGVzWCA9IG1tWCAqIDAuMDM5Mzc7Ci0JZG91YmxlIGluY2hlc1kgPSBtbVkgKiAwLjAzOTM3OwotCWludCB4ID0gKGludCkoKHdpZHRoIC8gaW5jaGVzWCkgKyAwLjUpOwotCWludCB5ID0gKGludCkoKGhlaWdodCAvIGluY2hlc1kpICsgMC41KTsKLQlyZXR1cm4gbmV3IFBvaW50ICh4LCB5KTsKLQkqLwotCQotCWlmIChmR0RldmljZUhhbmRsZSAhPSAwKSB7Ci0JCWludCBwbT0gT1MuZ2V0Z2RQTWFwKGZHRGV2aWNlSGFuZGxlKTsKLQkJaWYgKHBtICE9IDApCi0JCQlyZXR1cm4gbmV3IFBvaW50KE9TLmdldFBpeEhSZXMocG0pID4+IDE2LCBPUy5nZXRQaXhWUmVzKHBtKSA+PiAxNik7Ci0JfQotCXJldHVybiBuZXcgUG9pbnQoNzIsIDcyKTsKKwlpbnQgZ2RldmljZSA9IE9TLkdldE1haW5EZXZpY2UoKTsKKwlpbnRbXSBwdHIgPSBuZXcgaW50WzFdOworCU9TLm1lbWNweShwdHIsIGdkZXZpY2UsIDQpOworCUdEZXZpY2UgZGV2aWNlID0gbmV3IEdEZXZpY2UoKTsKKwlPUy5tZW1jcHkoZGV2aWNlLCBwdHJbMF0sIEdEZXZpY2Uuc2l6ZW9mKTsKKwlPUy5tZW1jcHkocHRyLCBkZXZpY2UuZ2RQTWFwLCA0KTsKKwlQaXhNYXAgcGl4bWFwID0gbmV3IFBpeE1hcCgpOworCU9TLm1lbWNweShwaXhtYXAsIHB0clswXSwgUGl4TWFwLnNpemVvZik7CisJcmV0dXJuIG5ldyBQb2ludCAocGl4bWFwLmhSZXMgPj4gMTYsIHBpeG1hcC52UmVzID4+IDE2KTsKIH0KIAogLyoqCkBAIC0yOTMsNTIgKzI3Nyw1MyBAQAogICogICAgPGxpPkVSUk9SX0RFVklDRV9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgRm9udERhdGEgW10gZ2V0Rm9udExpc3QgKFN0cmluZyBmYWNlTmFtZSwgYm9vbGVhbiBzY2FsYWJsZSkgewkKK3B1YmxpYyBGb250RGF0YVtdIGdldEZvbnRMaXN0IChTdHJpbmcgZmFjZU5hbWUsIGJvb2xlYW4gc2NhbGFibGUpIHsJCiAJY2hlY2tEZXZpY2UgKCk7Ci0JLyogQVcKLQlTdHJpbmcgeGxmZDsKLQlpZiAoZmFjZU5hbWUgPT0gbnVsbCkgewotCQl4bGZkID0gIi0qLSotKi0qLSotKi0qLSotKi0qLSotKi0qLSoiOwotCX0gZWxzZSB7Ci0JCWludCBkYXNoSW5kZXggPSBmYWNlTmFtZS5pbmRleE9mKCctJyk7Ci0JCWlmIChkYXNoSW5kZXggPCAwKSB7Ci0JCQl4bGZkID0gIi0qLSIgKyBmYWNlTmFtZSArICItKi0qLSotKi0qLSotKi0qLSotKi0qLSoiOwotCQl9IGVsc2UgewotCQkJeGxmZCA9ICItIiArIGZhY2VOYW1lICsgIi0qLSotKi0qLSotKi0qLSotKi0qLSotKiI7CisJLy9OT1QgRE9ORSAtIHNjYWxhYmxlCisJaW50IG5GZHMgPSAwOworCUZvbnREYXRhW10gZmRzID0gbmV3IEZvbnREYXRhWzRdOworCisJaW50W10gZm9udCA9IG5ldyBpbnRbMV07CisJc2hvcnRbXSBmb250RmFtaWx5ID0gbmV3IHNob3J0WzFdOworCXNob3J0W10gc3R5bGUgPSBuZXcgc2hvcnRbMV07CisJc2hvcnRbXSBzaXplID0gbmV3IHNob3J0WzFdOworCWJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsyNTZdOworCWludCBmYW1pbHlJdGVyID0gT1MuTmV3UHRyKDE2ICogNCk7CisJaW50IGZvbnRJdGVyID0gT1MuTmV3UHRyKDE2ICogNCk7CisJT1MuRk1DcmVhdGVGb250RmFtaWx5SXRlcmF0b3IoMCwgMCwgMCwgZmFtaWx5SXRlcik7CisJd2hpbGUgKE9TLkZNR2V0TmV4dEZvbnRGYW1pbHkoZmFtaWx5SXRlciwgZm9udEZhbWlseSkgIT0gT1Mua0ZNSXRlcmF0aW9uQ29tcGxldGVkKSB7CisJCU9TLkZNR2V0Rm9udEZhbWlseU5hbWUoZm9udEZhbWlseVswXSwgYnVmZmVyKTsKKwkJaW50IGxlbmd0aCA9IGJ1ZmZlclswXSAmIDB4RkY7CisJCWNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW2xlbmd0aF07CisJCWZvciAoaW50IGk9MDsgaTxsZW5ndGg7IGkrKykgeworCQkJY2hhcnNbaV09IChjaGFyKWJ1ZmZlcltpKzFdOworCQl9CisJCVN0cmluZyBuYW1lID0gbmV3IFN0cmluZyhjaGFycyk7CisJCWlmIChmYWNlTmFtZSA9PSBudWxsIHx8IENvbXBhdGliaWxpdHkuZXF1YWxzSWdub3JlQ2FzZShmYWNlTmFtZSwgbmFtZSkpIHsKKwkJCU9TLkZNQ3JlYXRlRm9udEZhbWlseUluc3RhbmNlSXRlcmF0b3IoZm9udEZhbWlseVswXSwgZm9udEl0ZXIpOworCQkJd2hpbGUgKE9TLkZNR2V0TmV4dEZvbnRGYW1pbHlJbnN0YW5jZShmb250SXRlciwgZm9udCwgc3R5bGUsIHNpemUpICE9IE9TLmtGTUl0ZXJhdGlvbkNvbXBsZXRlZCkgeworCQkJCWludCBzID0gU1dULk5PUk1BTDsKKwkJCQlpZiAoKHN0eWxlWzBdICYgT1MuaXRhbGljKSAhPSAwKSBzIHw9IFNXVC5JVEFMSUM7CisJCQkJaWYgKChzdHlsZVswXSAmIE9TLmJvbGQpICE9IDApIHMgfD0gU1dULkJPTEQ7CisJCQkJRm9udERhdGEgZGF0YSA9IG5ldyBGb250RGF0YShuYW1lLCBzLCBzaXplWzBdKTsKKwkJCQlpZiAobkZkcyA9PSBmZHMubGVuZ3RoKSB7CisJCQkJCUZvbnREYXRhW10gbmV3RmRzID0gbmV3IEZvbnREYXRhW2Zkcy5sZW5ndGggKyA0XTsKKwkJCQkJU3lzdGVtLmFycmF5Y29weShmZHMsIDAsIG5ld0ZkcywgMCwgbkZkcyk7CisJCQkJCWZkcyA9IG5ld0ZkczsKKwkJCQl9CisJCQkJZmRzW25GZHMrK10gPSBkYXRhOworCQkJfQorCQkJT1MuRk1EaXNwb3NlRm9udEZhbWlseUluc3RhbmNlSXRlcmF0b3IoZm9udEl0ZXIpOwogCQl9CiAJfQotCSovCi0JLyogVXNlIHRoZSBjaGFyYWN0ZXIgZW5jb2RpbmcgZm9yIHRoZSBkZWZhdWx0IGxvY2FsZSAqLwotCS8qIEFXCi0JYnl0ZSBbXSBidWZmZXIxID0gQ29udmVydGVyLndjc1RvTWJjcyAobnVsbCwgeGxmZCwgdHJ1ZSk7Ci0JaW50IFtdIHJldCA9IG5ldyBpbnQgWzFdOwotCWludCBsaXN0UHRyID0gT1MuWExpc3RGb250cyAoeERpc3BsYXksIGJ1ZmZlcjEsIDY1NTM1LCByZXQpOwotCWludCBwdHIgPSBsaXN0UHRyOwotCWludCBbXSBpbnRCdWYgPSBuZXcgaW50IFsxXTsKLQlGb250RGF0YSBbXSBmZCA9IG5ldyBGb250RGF0YSBbcmV0IFswXV07Ci0JaW50IGZkSW5kZXggPSAwOwotCWZvciAoaW50IGkgPSAwOyBpIDwgcmV0IFswXTsgaSsrKSB7Ci0JCU9TLm1lbW1vdmUgKGludEJ1ZiwgcHRyLCA0KTsKLQkJaW50IGNoYXJQdHIgPSBpbnRCdWYgWzBdOwotCQlpbnQgbGVuZ3RoID0gT1Muc3RybGVuIChjaGFyUHRyKTsKLQkJYnl0ZSBbXSBidWZmZXIyID0gbmV3IGJ5dGUgW2xlbmd0aF07Ci0JCU9TLm1lbW1vdmUgKGJ1ZmZlcjIsIGNoYXJQdHIsIGxlbmd0aCk7Ci0JCS8vIFVzZSB0aGUgY2hhcmFjdGVyIGVuY29kaW5nIGZvciB0aGUgZGVmYXVsdCBsb2NhbGUKLQkJY2hhciBbXSBjaGFycyA9IENvbnZlcnRlci5tYmNzVG9XY3MgKG51bGwsIGJ1ZmZlcjIpOwotCQlGb250RGF0YSBkYXRhID0gRm9udERhdGEubW90aWZfbmV3IChuZXcgU3RyaW5nIChjaGFycykpOwotCQlib29sZWFuIGlzU2NhbGFibGUgPSBkYXRhLmF2ZXJhZ2VXaWR0aCA9PSAwICYmIGRhdGEucGl4ZWxzID09IDAgJiYgZGF0YS5wb2ludHMgPT0gMDsKLQkJaWYgKGlzU2NhbGFibGUgPT0gc2NhbGFibGUpIHsKLQkJCWZkIFtmZEluZGV4KytdID0gZGF0YTsKLQkJfQotCQlwdHIgKz0gNDsKLQl9Ci0JT1MuWEZyZWVGb250TmFtZXMgKGxpc3RQdHIpOwotCWlmIChmZEluZGV4ID09IHJldCBbMF0pIHJldHVybiBmZDsKLQlGb250RGF0YSBbXSByZXN1bHQgPSBuZXcgRm9udERhdGEgW2ZkSW5kZXhdOwotCVN5c3RlbS5hcnJheWNvcHkgKGZkLCAwLCByZXN1bHQsIDAsIGZkSW5kZXgpOworCU9TLkZNRGlzcG9zZUZvbnRGYW1pbHlJdGVyYXRvcihmYW1pbHlJdGVyKTsKKwlPUy5EaXNwb3NlUHRyKGZhbWlseUl0ZXIpOworCU9TLkRpc3Bvc2VQdHIoZm9udEl0ZXIpOworCQorCWlmIChuRmRzID09IGZkcy5sZW5ndGgpIHJldHVybiBmZHM7CisJRm9udERhdGFbXSByZXN1bHQgPSBuZXcgRm9udERhdGFbbkZkc107CisJU3lzdGVtLmFycmF5Y29weShmZHMsIDAsIHJlc3VsdCwgMCwgbkZkcyk7CiAJcmV0dXJuIHJlc3VsdDsKLQkqLwotCXJldHVybiBuZXcgRm9udERhdGEgWzBdOwogfQogCiAvKioKQEAgLTM2MSw5ICszNDYsNiBAQAogICovCiBwdWJsaWMgQ29sb3IgZ2V0U3lzdGVtQ29sb3IgKGludCBpZCkgewogCWNoZWNrRGV2aWNlICgpOwotCS8qIEFXCi0JWENvbG9yIHhDb2xvciA9IG51bGw7Ci0JKi8KIAlzd2l0Y2ggKGlkKSB7CiAJCWNhc2UgU1dULkNPTE9SX0JMQUNLOiAJCQkJcmV0dXJuIENPTE9SX0JMQUNLOwogCQljYXNlIFNXVC5DT0xPUl9EQVJLX1JFRDogCQkJcmV0dXJuIENPTE9SX0RBUktfUkVEOwpAQCAtMzgyLDExICszNjQsNyBAQAogCQljYXNlIFNXVC5DT0xPUl9DWUFOOiAJCQkJcmV0dXJuIENPTE9SX0NZQU47CiAJCWNhc2UgU1dULkNPTE9SX1dISVRFOiAJCQkJcmV0dXJuIENPTE9SX1dISVRFOwogCX0KLQkvKiBBVwotCWlmICh4Q29sb3IgPT0gbnVsbCkgcmV0dXJuIENPTE9SX0JMQUNLOwotCXJldHVybiBDb2xvci5tb3RpZl9uZXcgKHRoaXMsIHhDb2xvcik7Ci0JKi8KLQlyZXR1cm4gQ29sb3IuY2FyYm9uX25ldyh0aGlzLCAweDAwMDAwMCwgZmFsc2UpOworCXJldHVybiBDT0xPUl9CTEFDSzsKIH0KIAogLyoqCkBAIC00MTEsNyArMzg5LDcgQEAKICAqLwogcHVibGljIEZvbnQgZ2V0U3lzdGVtRm9udCAoKSB7CiAJY2hlY2tEZXZpY2UgKCk7Ci0JcmV0dXJuIEZvbnQuY2FyYm9uX25ldyAodGhpcywgc3lzdGVtRm9udCk7CisJcmV0dXJuIHN5c3RlbUZvbnQ7CiB9CiAKIC8qKgpAQCAtNDMxLDMwICs0MDksMzYgQEAKIH0KIAogcHJvdGVjdGVkIHZvaWQgaW5pdCAoKSB7Ci0KLQlmU2NyZWVuRGVwdGg9IGdldERldmljZURlcHRoKGZHRGV2aWNlSGFuZGxlKTsKLQotCS8qCi0JKiBUaGUgZm9sbG93aW5nIGNvbG9ycyBhcmUgbGlzdGVkIGluIHRoZSBXaW5kb3dzCi0JKiBQcm9ncmFtbWVyJ3MgUmVmZXJlbmNlIGFzIHRoZSBjb2xvcnMgaW4gdGhlIGRlZmF1bHQKLQkqIHBhbGV0dGUuCi0JKi8KLQlDT0xPUl9CTEFDSyA9IAkJQ29sb3IuY2FyYm9uX25ldyh0aGlzLCAweDAwMDAwMCwgdHJ1ZSk7Ci0JQ09MT1JfREFSS19SRUQgPSAJQ29sb3IuY2FyYm9uX25ldyh0aGlzLCAweDgwMDAwMCwgdHJ1ZSk7Ci0JQ09MT1JfREFSS19HUkVFTiA9IAlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4MDA4MDAwLCB0cnVlKTsKLQlDT0xPUl9EQVJLX1lFTExPVyA9IENvbG9yLmNhcmJvbl9uZXcodGhpcywgMHg4MDgwMDAsIHRydWUpOwotCUNPTE9SX0RBUktfQkxVRSA9IAlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4MDAwMDgwLCB0cnVlKTsKLQlDT0xPUl9EQVJLX01BR0VOVEEgPUNvbG9yLmNhcmJvbl9uZXcodGhpcywgMHg4MDAwODAsIHRydWUpOwotCUNPTE9SX0RBUktfQ1lBTiA9IAlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4MDA4MDgwLCB0cnVlKTsKLQlDT0xPUl9HUkFZID0gCQlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4QzBDMEMwLCB0cnVlKTsKLQlDT0xPUl9EQVJLX0dSQVkgPSAJQ29sb3IuY2FyYm9uX25ldyh0aGlzLCAweDgwODA4MCwgdHJ1ZSk7Ci0JQ09MT1JfUkVEID0gCQlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4RkYwMDAwLCB0cnVlKTsKLQlDT0xPUl9HUkVFTiA9IAkJQ29sb3IuY2FyYm9uX25ldyh0aGlzLCAweDAwRkYwMCwgdHJ1ZSk7Ci0JQ09MT1JfWUVMTE9XID0gCQlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4RkZGRjAwLCB0cnVlKTsKLQlDT0xPUl9CTFVFID0gCQlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4MDAwMEZGLCB0cnVlKTsKLQlDT0xPUl9NQUdFTlRBID0gCUNvbG9yLmNhcmJvbl9uZXcodGhpcywgMHhGRjAwRkYsIHRydWUpOwotCUNPTE9SX0NZQU4gPSAJCUNvbG9yLmNhcmJvbl9uZXcodGhpcywgMHgwMEZGRkYsIHRydWUpOwotCUNPTE9SX1dISVRFID0gCQlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4RkZGRkZGLCB0cnVlKTsKKwljb2xvcnNwYWNlID0gT1MuQ0dDb2xvclNwYWNlQ3JlYXRlRGV2aWNlUkdCKCk7CisJaWYgKGNvbG9yc3BhY2UgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwkKKwkvKiBDcmVhdGUgdGhlIHN0YW5kYXJkIGNvbG9ycyAqLworCUNPTE9SX0JMQUNLID0gbmV3IENvbG9yICh0aGlzLCAwLDAsMCk7CisJQ09MT1JfREFSS19SRUQgPSBuZXcgQ29sb3IgKHRoaXMsIDB4ODAsMCwwKTsKKwlDT0xPUl9EQVJLX0dSRUVOID0gbmV3IENvbG9yICh0aGlzLCAwLDB4ODAsMCk7CisJQ09MT1JfREFSS19ZRUxMT1cgPSBuZXcgQ29sb3IgKHRoaXMsIDB4ODAsMHg4MCwwKTsKKwlDT0xPUl9EQVJLX0JMVUUgPSBuZXcgQ29sb3IgKHRoaXMsIDAsMCwweDgwKTsKKwlDT0xPUl9EQVJLX01BR0VOVEEgPSBuZXcgQ29sb3IgKHRoaXMsIDB4ODAsMCwweDgwKTsKKwlDT0xPUl9EQVJLX0NZQU4gPSBuZXcgQ29sb3IgKHRoaXMsIDAsMHg4MCwweDgwKTsKKwlDT0xPUl9HUkFZID0gbmV3IENvbG9yICh0aGlzLCAweEMwLDB4QzAsMHhDMCk7CisJQ09MT1JfREFSS19HUkFZID0gbmV3IENvbG9yICh0aGlzLCAweDgwLDB4ODAsMHg4MCk7CisJQ09MT1JfUkVEID0gbmV3IENvbG9yICh0aGlzLCAweEZGLDAsMCk7CisJQ09MT1JfR1JFRU4gPSBuZXcgQ29sb3IgKHRoaXMsIDAsMHhGRiwwKTsKKwlDT0xPUl9ZRUxMT1cgPSBuZXcgQ29sb3IgKHRoaXMsIDB4RkYsMHhGRiwwKTsKKwlDT0xPUl9CTFVFID0gbmV3IENvbG9yICh0aGlzLCAwLDAsMHhGRik7CisJQ09MT1JfTUFHRU5UQSA9IG5ldyBDb2xvciAodGhpcywgMHhGRiwwLDB4RkYpOworCUNPTE9SX0NZQU4gPSBuZXcgQ29sb3IgKHRoaXMsIDAsMHhGRiwweEZGKTsKKwlDT0xPUl9XSElURSA9IG5ldyBDb2xvciAodGhpcywgMHhGRiwweEZGLDB4RkYpOworCQorCS8qIEluaXRpYWxpemUgdGhlIHN5c3RlbSBmb250IHNsb3QgKi8KKwlzaG9ydCBpZCA9IE9TLkdldEFwcEZvbnQoKTsKKwlzaG9ydCBzdHlsZSA9IChzaG9ydCkwOyAKKwlzaG9ydCBzaXplID0gT1MuR2V0RGVmRm9udFNpemUoKTsKKwlpbnRbXSBmb250ID0gbmV3IGludFsxXTsKKwlpZiAoT1MuRk1HZXRGb250RnJvbUZvbnRGYW1pbHlJbnN0YW5jZShpZCwgc3R5bGUsIGZvbnQsIG51bGwpICE9IDApIHsKKwkJU1dULmVycm9yKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwl9CisJc3lzdGVtRm9udCA9IEZvbnQuY2FyYm9uX25ldyAodGhpcywgZm9udFswXSwgaWQsIHN0eWxlLCBzaXplKTsKIH0KIAogLyoqCSAKQEAgLTUwMiw5ICs0ODYsOSBAQAogICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHRoZSBkZXZpY2UgaXMgZGlzcG9zZWQgYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UKICAqLwogcHVibGljIGJvb2xlYW4gaXNEaXNwb3NlZCAoKSB7Ci0JcmV0dXJuIGZHRGV2aWNlSGFuZGxlID09IDA7CisJcmV0dXJuIGRpc3Bvc2VkOwogfQotCQorCiB2b2lkIG5ld19PYmplY3QgKE9iamVjdCBvYmplY3QpIHsKIAlmb3IgKGludCBpPTA7IGk8b2JqZWN0cy5sZW5ndGg7IGkrKykgewogCQlpZiAob2JqZWN0cyBbaV0gPT0gbnVsbCkgewpAQCAtNTIzLDkgKzUwNywxMiBAQAogCWVycm9ycyA9IG5ld0Vycm9yczsKIH0KIAotcHJvdGVjdGVkIHZvaWQgcmVsZWFzZSAoKSB7CQotCUNPTE9SX0JMQUNLID0gQ09MT1JfREFSS19SRUQgPSBDT0xPUl9EQVJLX0dSRUVOID0gQ09MT1JfREFSS19ZRUxMT1cgPQotCUNPTE9SX0RBUktfQkxVRSA9IENPTE9SX0RBUktfTUFHRU5UQSA9IENPTE9SX0RBUktfQ1lBTiA9IENPTE9SX0dSQVkgPSBDT0xPUl9EQVJLX0dSQVkgPSBDT0xPUl9SRUQgPQorcHJvdGVjdGVkIHZvaWQgcmVsZWFzZSAoKSB7CisJT1MuQ0dDb2xvclNwYWNlUmVsZWFzZShjb2xvcnNwYWNlKTsKKwljb2xvcnNwYWNlID0gMDsKKwkKKwlDT0xPUl9CTEFDSyA9IENPTE9SX0RBUktfUkVEID0gQ09MT1JfREFSS19HUkVFTiA9IENPTE9SX0RBUktfWUVMTE9XID0gQ09MT1JfREFSS19CTFVFID0KKwlDT0xPUl9EQVJLX01BR0VOVEEgPSBDT0xPUl9EQVJLX0NZQU4gPSBDT0xPUl9HUkFZID0gQ09MT1JfREFSS19HUkFZID0gQ09MT1JfUkVEID0KIAlDT0xPUl9HUkVFTiA9IENPTE9SX1lFTExPVyA9IENPTE9SX0JMVUUgPSBDT0xPUl9NQUdFTlRBID0gQ09MT1JfQ1lBTiA9IENPTE9SX1dISVRFID0gbnVsbDsKIH0KIApAQCAtNTQ0LDE5ICs1MzEsNiBAQAogcHVibGljIHZvaWQgc2V0V2FybmluZ3MgKGJvb2xlYW4gd2FybmluZ3MpIHsKIAljaGVja0RldmljZSAoKTsKIAl0aGlzLndhcm5pbmdzID0gd2FybmluZ3M7Ci0JaWYgKGRlYnVnKSByZXR1cm47CiB9CiAKLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0vLyBNYWMgc3R1ZmYKLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQlzdGF0aWMgaW50IGdldERldmljZURlcHRoKGludCBnZCkgewotCQlpZiAoZ2QgIT0gMCkgewotCQkJaW50IHBtPSBPUy5nZXRnZFBNYXAoZ2QpOwotCQkJaWYgKHBtICE9IDApCi0JCQkJcmV0dXJuIE9TLkdldFBpeERlcHRoKHBtKTsKLQkJfQotCQlyZXR1cm4gMzI7Ci0JfQogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9Gb250LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0ZvbnQuamF2YQppbmRleCAwZTI5NjRkLi5kMjk2YzNiIDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0ZvbnQuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0ZvbnQuamF2YQpAQCAtOCw2ICs4LDcgQEAKICAqLwogCiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwogCiAvKioKQEAgLTI0LDIxICsyNSwzNiBAQAogICogQHNlZSBGb250RGF0YQogICovCiBwdWJsaWMgZmluYWwgY2xhc3MgRm9udCB7Ci0JCisKIAkvKioKLQkgKiB0aGUgaGFuZGxlIHRvIHRoZSBPUyBmb250IHJlc291cmNlCisJICogdGhlIGhhbmRsZSB0byB0aGUgT1MgZm9udCAoYSBGTUZvbnQpCiAJICogKFdhcm5pbmc6IFRoaXMgZmllbGQgaXMgcGxhdGZvcm0gZGVwZW5kZW50KQogCSAqLwotCXB1YmxpYyBNYWNGb250IGhhbmRsZTsKKwlwdWJsaWMgaW50IGhhbmRsZTsKIAkKIAkvKioKLQkgKiB0aGUgZGV2aWNlIHdoZXJlIHRoaXMgZm9udCB3YXMgY3JlYXRlZAorCSAqIHRoZSBpZCB0byB0aGUgT1MgZm9udCAoYSBGTUZvbnRGYW1pbHkpCisJICogKFdhcm5pbmc6IFRoaXMgZmllbGQgaXMgcGxhdGZvcm0gZGVwZW5kZW50KQorCSAqLworCXB1YmxpYyBzaG9ydCBpZDsKKwkKKwkvKioKKwkgKiB0aGUgc3R5bGUgdG8gdGhlIE9TIGZvbnQgKGEgRk1Gb250U3R5bGUpCisJICogKFdhcm5pbmc6IFRoaXMgZmllbGQgaXMgcGxhdGZvcm0gZGVwZW5kZW50KQorCSAqLworCXB1YmxpYyBzaG9ydCBzdHlsZTsKKworCS8qKgorCSAqIHRoZSBzaXplIHRvIHRoZSBPUyBmb250CisJICogKFdhcm5pbmc6IFRoaXMgZmllbGQgaXMgcGxhdGZvcm0gZGVwZW5kZW50KQorCSAqLworCXB1YmxpYyBzaG9ydCBzaXplOworCisJLyoqCisJICogVGhlIGRldmljZSB3aGVyZSB0aGlzIGltYWdlIHdhcyBjcmVhdGVkLgogCSAqLwogCURldmljZSBkZXZpY2U7CiAJCi0vKioKLSAqIFByZXZlbnRzIHVuaW5pdGlhbGl6ZWQgaW5zdGFuY2VzIGZyb20gYmVpbmcgY3JlYXRlZCBvdXRzaWRlIHRoZSBwYWNrYWdlLgotICovCiBGb250KCkgewogfQogCkBAIC02MCwxNyArNzYsMTYgQEAKICAqICAgIDxsaT5FUlJPUl9OT19IQU5ETEVTIC0gaWYgYSBmb250IGNvdWxkIG5vdCBiZSBjcmVhdGVkIGZyb20gdGhlIGdpdmVuIGZvbnQgZGF0YTwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgRm9udChEZXZpY2UgZGV2aWNlLCBGb250RGF0YSBmZCkgeworcHVibGljIEZvbnQoRGV2aWNlIGRpc3BsYXksIEZvbnREYXRhIGZkKSB7CiAJaWYgKGRldmljZSA9PSBudWxsKSBkZXZpY2UgPSBEZXZpY2UuZ2V0RGV2aWNlKCk7CiAJaWYgKGRldmljZSA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCWluaXQoZGV2aWNlLCBmZCk7Ci0JaWYgKGRldmljZS50cmFja2luZykgZGV2aWNlLm5ld19PYmplY3QodGhpcyk7CQorCWlmIChmZCA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWluaXQoZGV2aWNlLCBmZC5nZXROYW1lKCksIGZkLmdldEhlaWdodCgpLCBmZC5nZXRTdHlsZSgpKTsKIH0KIAogLyoqCSAKLSAqIENvbnN0cnVjdHMgYSBuZXcgZm9udCBnaXZlbiBhIGRldmljZSBhbmQgYW4gYXJyYXkKLSAqIG9mIGZvbnQgZGF0YSB3aGljaCBkZXNjcmliZXMgdGhlIGRlc2lyZWQgZm9udCdzCi0gKiBhcHBlYXJhbmNlLgorICogQ29uc3RydWN0cyBhIG5ldyBmb250IGdpdmVuIGEgZGV2aWNlIGFuZCBmb250IGRhdGFzCisgKiB3aGljaCBkZXNjcmliZXMgdGhlIGRlc2lyZWQgZm9udCdzIGFwcGVhcmFuY2UuCiAgKiA8cD4KICAqIFlvdSBtdXN0IGRpc3Bvc2UgdGhlIGZvbnQgd2hlbiBpdCBpcyBubyBsb25nZXIgcmVxdWlyZWQuIAogICogPC9wPgpAQCAtODcsMTYgKzEwMiwxNSBAQAogICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+CiAgKiAgICA8bGk+RVJST1JfTk9fSEFORExFUyAtIGlmIGEgZm9udCBjb3VsZCBub3QgYmUgY3JlYXRlZCBmcm9tIHRoZSBnaXZlbiBmb250IGRhdGE8L2xpPgogICogPC91bD4KLSAqIAotICogQHNpbmNlIDIuMQogICovCiBwdWJsaWMgRm9udChEZXZpY2UgZGV2aWNlLCBGb250RGF0YVtdIGZkcykgewogCWlmIChkZXZpY2UgPT0gbnVsbCkgZGV2aWNlID0gRGV2aWNlLmdldERldmljZSgpOwogCWlmIChkZXZpY2UgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlpZiAoZmRzID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaWYgKGZkcy5sZW5ndGggPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKLQlpbml0KGRldmljZSwgZmRzWzBdKTsKLQlpZiAoZGV2aWNlLnRyYWNraW5nKSBkZXZpY2UubmV3X09iamVjdCh0aGlzKTsJCisJRm9udERhdGEgZmQgPSBmZHNbMF07CisJaWYgKGZkID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJaW5pdChkZXZpY2UsZmQuZ2V0TmFtZSgpLCBmZC5nZXRIZWlnaHQoKSwgZmQuZ2V0U3R5bGUoKSk7CiB9CiAKIC8qKgkgCkBAIC0xMjEsMTIgKzEzNSwxMCBAQAogICogICAgPGxpPkVSUk9SX05PX0hBTkRMRVMgLSBpZiBhIGZvbnQgY291bGQgbm90IGJlIGNyZWF0ZWQgZnJvbSB0aGUgZ2l2ZW4gYXJndW1lbnRzPC9saT4KICAqIDwvdWw+CiAgKi8KLXB1YmxpYyBGb250KERldmljZSBkZXZpY2UsIFN0cmluZyBuYW1lLCBpbnQgaGVpZ2h0LCBpbnQgc3R5bGUpIHsKK3B1YmxpYyBGb250KERldmljZSBkaXNwbGF5LCBTdHJpbmcgbmFtZSwgaW50IGhlaWdodCwgaW50IHN0eWxlKSB7CiAJaWYgKGRldmljZSA9PSBudWxsKSBkZXZpY2UgPSBEZXZpY2UuZ2V0RGV2aWNlKCk7CiAJaWYgKGRldmljZSA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCWlmIChuYW1lID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0JaW5pdChkZXZpY2UsIG5ldyBGb250RGF0YSAobmFtZSwgaGVpZ2h0LCBzdHlsZSkpOwotCWlmIChkZXZpY2UudHJhY2tpbmcpIGRldmljZS5uZXdfT2JqZWN0KHRoaXMpOwkKKwlpbml0KGRldmljZSwgbmFtZSwgaGVpZ2h0LCBzdHlsZSk7CiB9CiAKIC8qKgpAQCAtMTM1LDkgKzE0Nyw4IEBACiAgKiB0aGV5IGFsbG9jYXRlLgogICovCiBwdWJsaWMgdm9pZCBkaXNwb3NlKCkgewotCWlmIChoYW5kbGUgPT0gbnVsbCkgcmV0dXJuOwotCWhhbmRsZSA9IG51bGw7Ci0JaWYgKGRldmljZS50cmFja2luZykgZGV2aWNlLmRpc3Bvc2VfT2JqZWN0KHRoaXMpOworCWhhbmRsZSA9IDA7CisJaWQgPSAtMTsKIAlkZXZpY2UgPSBudWxsOwogfQogCkBAIC0xNTQsOCArMTY1LDcgQEAKIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CiAJaWYgKG9iamVjdCA9PSB0aGlzKSByZXR1cm4gdHJ1ZTsKIAlpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBGb250KSkgcmV0dXJuIGZhbHNlOwotCUZvbnQgZm9udCA9IChGb250KSBvYmplY3Q7Ci0JcmV0dXJuIGRldmljZSA9PSBmb250LmRldmljZSAmJiBoYW5kbGUuZXF1YWxzKGZvbnQuaGFuZGxlKTsKKwlyZXR1cm4gaGFuZGxlID09ICgoRm9udClvYmplY3QpLmhhbmRsZTsKIH0KIAogLyoqCkBAIC0xNzIsNTQgKzE4MiwxOSBAQAogICovCiBwdWJsaWMgRm9udERhdGFbXSBnZXRGb250RGF0YSgpIHsKIAlpZiAoaXNEaXNwb3NlZCgpKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwotCXJldHVybiBuZXcgRm9udERhdGFbXSB7IG5ldyBGb250RGF0YShoYW5kbGUuZ2V0TmFtZSgpLCBoYW5kbGUuZ2V0U2l6ZSgpLCBoYW5kbGUuZ2V0RmFjZSgpKSB9OwotfQotCi0vKioKLSAqIFJldHVybnMgYW4gaW50ZWdlciBoYXNoIGNvZGUgZm9yIHRoZSByZWNlaXZlci4gQW55IHR3byAKLSAqIG9iamVjdHMgd2hpY2ggcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4gcGFzc2VkIHRvIAotICogPGNvZGU+ZXF1YWxzPC9jb2RlPiBtdXN0IHJldHVybiB0aGUgc2FtZSB2YWx1ZSBmb3IgdGhpcwotICogbWV0aG9kLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgaGFzaAotICoKLSAqIEBzZWUgI2VxdWFscwotICovCi1wdWJsaWMgaW50IGhhc2hDb2RlICgpIHsKLQlpZiAoaGFuZGxlICE9IG51bGwpCi0JCXJldHVybiBoYW5kbGUuaGFzaENvZGUoKTsKLQlyZXR1cm4gMDsKLX0KLQotdm9pZCBpbml0IChEZXZpY2UgZGV2aWNlLCBGb250RGF0YSBmZCkgewotCWlmIChmZCA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCXRoaXMuZGV2aWNlID0gZGV2aWNlOwotCWhhbmRsZT0gbmV3IE1hY0ZvbnQoZmQuZm9udEZhbWlseSwgZmQuaGVpZ2h0LCBmZC5zdHlsZSk7Ci19Ci0KLS8qKgotICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgZm9udCBoYXMgYmVlbiBkaXNwb3NlZCwKLSAqIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICogPHA+Ci0gKiBUaGlzIG1ldGhvZCBnZXRzIHRoZSBkaXNwb3NlIHN0YXRlIGZvciB0aGUgZm9udC4KLSAqIFdoZW4gYSBmb250IGhhcyBiZWVuIGRpc3Bvc2VkLCBpdCBpcyBhbiBlcnJvciB0bwotICogaW52b2tlIGFueSBvdGhlciBtZXRob2QgdXNpbmcgdGhlIGZvbnQuCi0gKgotICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHRoZSBmb250IGlzIGRpc3Bvc2VkIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlCi0gKi8KLXB1YmxpYyBib29sZWFuIGlzRGlzcG9zZWQoKSB7Ci0JcmV0dXJuIGhhbmRsZSA9PSBudWxsOwotfQotCi0vKioKLSAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlCi0gKiBkZXNjcmlwdGlvbiBvZiB0aGUgcmVjZWl2ZXIuCi0gKgotICogQHJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVjZWl2ZXIKLSAqLwotcHVibGljIFN0cmluZyB0b1N0cmluZyAoKSB7Ci0JaWYgKGlzRGlzcG9zZWQoKSkgcmV0dXJuICJGb250IHsqRElTUE9TRUQqfSI7Ci0JcmV0dXJuICJGb250IHsiICsgaGFuZGxlICsgIn0iOworCWJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsyNTZdOworCU9TLkZNR2V0Rm9udEZhbWlseU5hbWUoaWQsIGJ1ZmZlcik7CisJaW50IGxlbmd0aCA9IGJ1ZmZlclswXSAmIDB4RkY7CisJY2hhcltdIGNoYXJzID0gbmV3IGNoYXJbbGVuZ3RoXTsKKwlmb3IgKGludCBpPTA7IGk8bGVuZ3RoOyBpKyspIHsKKwkJY2hhcnNbaV09IChjaGFyKWJ1ZmZlcltpKzFdOworCX0KKwlTdHJpbmcgbmFtZSA9IG5ldyBTdHJpbmcoY2hhcnMpOworCWludCBzdHlsZSA9IFNXVC5OT1JNQUw7CisJaWYgKCh0aGlzLnN0eWxlICYgT1MuaXRhbGljKSAhPSAwKSBzdHlsZSB8PSBTV1QuSVRBTElDOworCWlmICgodGhpcy5zdHlsZSAmIE9TLmJvbGQpICE9IDApIHN0eWxlIHw9IFNXVC5CT0xEOworCUZvbnREYXRhIGRhdGEgPSBuZXcgRm9udERhdGEobmFtZSwgc2l6ZSwgc3R5bGUpOworCXJldHVybiBuZXcgRm9udERhdGFbXXtkYXRhfTsKIH0KIAogLyoqCSAKQEAgLTIzNCwxNSArMjA5LDgwIEBACiAgKgogICogQHBhcmFtIGRldmljZSB0aGUgZGV2aWNlIG9uIHdoaWNoIHRvIGFsbG9jYXRlIHRoZSBjb2xvcgogICogQHBhcmFtIGhhbmRsZSB0aGUgaGFuZGxlIGZvciB0aGUgZm9udAorICogQHBhcmFtIHNpemUgdGhlIHNpemUgZm9yIHRoZSBmb250CiAgKiAKICAqIEBwcml2YXRlCiAgKi8KLXB1YmxpYyBzdGF0aWMgRm9udCBjYXJib25fbmV3KERldmljZSBkZXZpY2UsIE1hY0ZvbnQgbWFjRm9udCkgeworcHVibGljIHN0YXRpYyBGb250IGNhcmJvbl9uZXcoRGV2aWNlIGRldmljZSwgaW50IGhhbmRsZSwgc2hvcnQgaWQsIHNob3J0IHN0eWxlLCBzaG9ydCBzaXplKSB7CiAJaWYgKGRldmljZSA9PSBudWxsKSBkZXZpY2UgPSBEZXZpY2UuZ2V0RGV2aWNlKCk7CiAJRm9udCBmb250ID0gbmV3IEZvbnQoKTsKLQlmb250LmhhbmRsZSA9IG1hY0ZvbnQ7CisJZm9udC5oYW5kbGUgPSBoYW5kbGU7CisJZm9udC5pZCA9IGlkOworCWZvbnQuc3R5bGUgPSBzdHlsZTsKKwlmb250LnNpemUgPSBzaXplOwogCWZvbnQuZGV2aWNlID0gZGV2aWNlOwogCXJldHVybiBmb250OwogfQogCisvKioKKyAqIFJldHVybnMgYW4gaW50ZWdlciBoYXNoIGNvZGUgZm9yIHRoZSByZWNlaXZlci4gQW55IHR3byAKKyAqIG9iamVjdHMgd2hpY2ggcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4gcGFzc2VkIHRvIAorICogPGNvZGU+ZXF1YWxzPC9jb2RlPiBtdXN0IHJldHVybiB0aGUgc2FtZSB2YWx1ZSBmb3IgdGhpcworICogbWV0aG9kLgorICoKKyAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgaGFzaAorICoKKyAqIEBzZWUgI2VxdWFscworICovCitwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworCXJldHVybiBoYW5kbGU7Cit9CisKK3ZvaWQgaW5pdChEZXZpY2UgZGV2aWNlLCBTdHJpbmcgbmFtZSwgaW50IGhlaWdodCwgaW50IHN0eWxlKSB7CisJaWYgKG5hbWUgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlpZiAoaGVpZ2h0IDwgMCkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKKwlieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbMjU2XTsKKwlpbnQgbGVuZ3RoID0gbmFtZS5sZW5ndGgoKTsKKwlpZiAobGVuZ3RoID4gMjU1KSBsZW5ndGggPSAyNTU7CisJYnVmZmVyWzBdID0gKGJ5dGUpbGVuZ3RoOworCWZvciAoaW50IGk9MDsgaTxsZW5ndGg7IGkrKykgeworCQlidWZmZXJbaSsxXT0gKGJ5dGUpbmFtZS5jaGFyQXQoaSk7CisJfQorCXRoaXMuaWQgPSBPUy5GTUdldEZvbnRGYW1pbHlGcm9tTmFtZShidWZmZXIpOworCWlmICh0aGlzLmlkID09IE9TLmtJbnZhbGlkRm9udEZhbWlseSkgdGhpcy5pZCA9IE9TLkdldEFwcEZvbnQoKTsKKwlpZiAoKHN0eWxlICYgU1dULklUQUxJQykgIT0gMCkgdGhpcy5zdHlsZSB8PSBPUy5pdGFsaWM7CisJaWYgKChzdHlsZSAmIFNXVC5CT0xEKSAhPSAwKSB0aGlzLnN0eWxlIHw9IE9TLmJvbGQ7CisJdGhpcy5zaXplID0gKHNob3J0KWhlaWdodDsKKwlpbnRbXSBmb250ID0gbmV3IGludFsxXTsKKwlpZiAoT1MuRk1HZXRGb250RnJvbUZvbnRGYW1pbHlJbnN0YW5jZShpZCwgdGhpcy5zdHlsZSwgZm9udCwgbnVsbCkgIT0gMCkgeworCQlTV1QuZXJyb3IoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCX0KKwl0aGlzLmhhbmRsZSA9IGZvbnRbMF07Cit9CisKKy8qKgorICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgZm9udCBoYXMgYmVlbiBkaXNwb3NlZCwKKyAqIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgorICogPHA+CisgKiBUaGlzIG1ldGhvZCBnZXRzIHRoZSBkaXNwb3NlIHN0YXRlIGZvciB0aGUgZm9udC4KKyAqIFdoZW4gYSBmb250IGhhcyBiZWVuIGRpc3Bvc2VkLCBpdCBpcyBhbiBlcnJvciB0bworICogaW52b2tlIGFueSBvdGhlciBtZXRob2QgdXNpbmcgdGhlIGZvbnQuCisgKgorICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHRoZSBmb250IGlzIGRpc3Bvc2VkIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlCisgKi8KK3B1YmxpYyBib29sZWFuIGlzRGlzcG9zZWQoKSB7CisJcmV0dXJuIGhhbmRsZSA9PSAwOworfQorCisvKioKKyAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlCisgKiBkZXNjcmlwdGlvbiBvZiB0aGUgcmVjZWl2ZXIuCisgKgorICogQHJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVjZWl2ZXIKKyAqLworcHVibGljIFN0cmluZyB0b1N0cmluZyAoKSB7CisJaWYgKGlzRGlzcG9zZWQoKSkgcmV0dXJuICJGb250IHsqRElTUE9TRUQqfSI7CisJcmV0dXJuICJGb250IHsiICsgaGFuZGxlICsgIn0iOworfQorCiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0ZvbnREYXRhLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0ZvbnREYXRhLmphdmEKaW5kZXggNjdkZTU0Ni4uMTE0MjUyNyAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9Gb250RGF0YS5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZ3JhcGhpY3MvRm9udERhdGEuamF2YQpAQCAtOCw3ICs4LDcgQEAKICAqLwogCiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7Ci0gCisKIC8qKgogICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgZGVzY3JpYmUgb3BlcmF0aW5nIHN5c3RlbSBmb250cy4KICAqIE9ubHkgdGhlIHB1YmxpYyBBUEkgb2YgdGhpcyB0eXBlIGlzIHBsYXRmb3JtIGluZGVwZW5kZW50LgpAQCAtMzYsMzggKzM2LDM2IEBACiAgKi8KIHB1YmxpYyBmaW5hbCBjbGFzcyBGb250RGF0YSB7CiAJLyoqCi0JICogVGhlIGZvbnQgZm91bmRyeS4KLQkgKiBXYXJuaW5nOiBUaGlzIGZpZWxkIGlzIHBsYXRmb3JtIGRlcGVuZGVudC4KKwkgKiB0aGUgZm9udCBuYW1lCisJICogKFdhcm5pbmc6IFRoaXMgZmllbGQgaXMgcGxhdGZvcm0gZGVwZW5kZW50KQogCSAqLwotCXB1YmxpYyBTdHJpbmcgZm91bmRyeTsKLQkvKioKLQkgKiBUaGUgZm9udCBmYW1pbHkuCi0JICogV2FybmluZzogVGhpcyBmaWVsZCBpcyBwbGF0Zm9ybSBkZXBlbmRlbnQuCi0JICovCi0JcHVibGljIFN0cmluZyBmb250RmFtaWx5OworCXB1YmxpYyBTdHJpbmcgbmFtZTsKKwogCS8qKgogCSAqIFRoZSBoZWlnaHQgb2YgdGhlIGZvbnQgZGF0YSBpbiBwb2ludHMKIAkgKiAoV2FybmluZzogVGhpcyBmaWVsZCBpcyBwbGF0Zm9ybSBkZXBlbmRlbnQpCiAJICovCiAJcHVibGljIGludCBoZWlnaHQ7CisKIAkvKioKLQkgKiBUaGUgZm9udCBzdHlsZS4KLQkgKiBXYXJuaW5nOiBUaGlzIGZpZWxkIGlzIHBsYXRmb3JtIGRlcGVuZGVudC4KKwkgKiB0aGUgZm9udCBzdHlsZQorCSAqIChXYXJuaW5nOiBUaGlzIGZpZWxkIGlzIHBsYXRmb3JtIGRlcGVuZGVudCkKIAkgKi8KIAlwdWJsaWMgaW50IHN0eWxlOwotCQotCS8vIEFXIGZvciBGb250RGlhbG9nCi0JcHVibGljIFN0cmluZyBhZGRTdHlsZT0gIkZvbnREYXRhLmFkZFN0eWxlIjsKLQlwdWJsaWMgU3RyaW5nIHdlaWdodD0gIkZvbnREYXRhLndlaWdodCI7Ci0JcHVibGljIFN0cmluZyBjaGFyYWN0ZXJTZXRSZWdpc3RyeT0gIkZvbnREYXRhLmNoYXJhY3RlclNldFJlZ2lzdHJ5IjsKLQlwdWJsaWMgU3RyaW5nIGNoYXJhY3RlclNldE5hbWU9ICJjaGFyYWN0ZXJTZXROYW1lIjsKLQkvLyBBVyBlbmQKKworCS8qKgorCSAqIFRoZSBsb2NhbGVzIG9mIHRoZSBmb250CisJICogKFdhcm5pbmc6IFRoZXNlIGZpZWxkcyBhcmUgcGxhdGZvcm0gZGVwZW5kZW50KQorCSAqLworCVN0cmluZyBsYW5nLCBjb3VudHJ5LCB2YXJpYW50OwogCQogLyoqCSAKICAqIENvbnN0cnVjdHMgYSBuZXcgdW4taW5pdGlhbGl6ZWQgZm9udCBkYXRhLgogICovCiBwdWJsaWMgRm9udERhdGEgKCkgeworCXRoaXMoIiIsIDEyLCBTV1QuTk9STUFMKTsKIH0KKwogLyoqCiAgKiBDb25zdHJ1Y3RzIGEgbmV3IEZvbnREYXRhIGdpdmVuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uCiAgKiBpbiB0aGUgZm9ybSBnZW5lcmF0ZWQgYnkgdGhlIDxjb2RlPkZvbnREYXRhLnRvU3RyaW5nPC9jb2RlPgpAQCAtODksMzEgKzg3LDU0IEBACiAgKi8KIHB1YmxpYyBGb250RGF0YShTdHJpbmcgc3RyaW5nKSB7CiAJaWYgKHN0cmluZyA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCS8vU3lzdGVtLm91dC5wcmludGxuKCJuZXcgRm9udERhdGE6ICIgKyBzdHJpbmcpOworCWludCBzdGFydCA9IDA7CisJaW50IGVuZCA9IHN0cmluZy5pbmRleE9mKCd8Jyk7CisJaWYgKGVuZCA9PSAtMSkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKKwlTdHJpbmcgdmVyc2lvbjEgPSBzdHJpbmcuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpOwogCQotCWludCBzdGFydD0gMDsKLQlpbnQgc3RvcD0gc3RyaW5nLmluZGV4T2YoInwiKTsKLQlTdHJpbmcgbmFtZT0gc3RyaW5nLnN1YnN0cmluZyhzdGFydCwgc3RvcCk7Ci0Jc3RhcnQ9IHN0b3ArMTsKLQlzdG9wPSBzdHJpbmcuaW5kZXhPZigifCIsIHN0YXJ0KTsKLQlpbnQgaGVpZ2h0PSAwOworCXN0YXJ0ID0gZW5kICsgMTsKKwllbmQgPSBzdHJpbmcuaW5kZXhPZignfCcsIHN0YXJ0KTsKKwlpZiAoZW5kID09IC0xKSBTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCVN0cmluZyBuYW1lID0gc3RyaW5nLnN1YnN0cmluZyhzdGFydCwgZW5kKTsKKwkKKwlzdGFydCA9IGVuZCArIDE7CisJZW5kID0gc3RyaW5nLmluZGV4T2YoJ3wnLCBzdGFydCk7CisJaWYgKGVuZCA9PSAtMSkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKKwlpbnQgaGVpZ2h0ID0gMDsKIAl0cnkgewotCQloZWlnaHQ9IEludGVnZXIucGFyc2VJbnQoc3RyaW5nLnN1YnN0cmluZyhzdGFydCwgc3RvcCkpOwotCX0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgewotCX0KLQlzdGFydD0gc3RvcCsxOwotCWludCBzdHlsZT0gMDsKLQl0cnkgewotCQlzdHlsZT0gSW50ZWdlci5wYXJzZUludChzdHJpbmcuc3Vic3RyaW5nKHN0YXJ0KSk7Ci0JfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGV4KSB7CisJCWhlaWdodCA9IEludGVnZXIucGFyc2VJbnQoc3RyaW5nLnN1YnN0cmluZyhzdGFydCwgZW5kKSk7CisJfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKwkJU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKIAl9CiAJCi0JLy9TeXN0ZW0ub3V0LnByaW50bG4oIioqKiogPCIrbmFtZSsiPjwiK3NpemUrIj48IitmYWNlKyI+Iik7Ci0JCisJc3RhcnQgPSBlbmQgKyAxOworCWVuZCA9IHN0cmluZy5pbmRleE9mKCd8Jywgc3RhcnQpOworCWlmIChlbmQgPT0gLTEpIFNXVC5lcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CisJaW50IHN0eWxlID0gMDsKKwl0cnkgeworCQlzdHlsZSA9IEludGVnZXIucGFyc2VJbnQoc3RyaW5nLnN1YnN0cmluZyhzdGFydCwgZW5kKSk7CisJfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKwkJU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKKwl9CisKKwlzdGFydCA9IGVuZCArIDE7CisJZW5kID0gc3RyaW5nLmluZGV4T2YoJ3wnLCBzdGFydCk7CiAJc2V0TmFtZShuYW1lKTsKIAlzZXRIZWlnaHQoaGVpZ2h0KTsKIAlzZXRTdHlsZShzdHlsZSk7CisJaWYgKGVuZCA9PSAtMSkgcmV0dXJuOworCVN0cmluZyBwbGF0Zm9ybSA9IHN0cmluZy5zdWJzdHJpbmcoc3RhcnQsIGVuZCk7CisKKwlzdGFydCA9IGVuZCArIDE7CisJZW5kID0gc3RyaW5nLmluZGV4T2YoJ3wnLCBzdGFydCk7CisJaWYgKGVuZCA9PSAtMSkgcmV0dXJuOworCVN0cmluZyB2ZXJzaW9uMiA9IHN0cmluZy5zdWJzdHJpbmcoc3RhcnQsIGVuZCk7CisKKwlpZiAocGxhdGZvcm0uZXF1YWxzKCJDQVJCT04iKSAmJiB2ZXJzaW9uMi5lcXVhbHMoIjEiKSkgeworCQlyZXR1cm47CisJfQogfQorCiAvKioJIAogICogQ29uc3RydWN0cyBhIG5ldyBmb250IGRhdGEgZ2l2ZW4gYSBmb250IG5hbWUsCiAgKiB0aGUgaGVpZ2h0IG9mIHRoZSBkZXNpcmVkIGZvbnQgaW4gcG9pbnRzLCAKQEAgLTEyOCwxMiArMTQ5LDEyIEBACiAgKiAgICA8bGk+RVJST1JfSU5WQUxJRF9BUkdVTUVOVCAtIGlmIHRoZSBoZWlnaHQgaXMgbmVnYXRpdmU8L2xpPgogICogPC91bD4KICAqLwotcHVibGljIEZvbnREYXRhIChTdHJpbmcgbmFtZSwgaW50IGhlaWdodCwgaW50IHN0eWxlKSB7Ci0JLy9TeXN0ZW0ub3V0LnByaW50bG4oIm5ldyBGb250RGF0YTogIiArIG5hbWUgKyAiICIgKyBoZWlnaHQgKyAiICIgKyBzdHlsZSk7CitwdWJsaWMgRm9udERhdGEoU3RyaW5nIG5hbWUsIGludCBoZWlnaHQsIGludCBzdHlsZSkgewogCXNldE5hbWUobmFtZSk7CiAJc2V0SGVpZ2h0KGhlaWdodCk7CiAJc2V0U3R5bGUoc3R5bGUpOwogfQorCiAvKioKICAqIENvbXBhcmVzIHRoZSBhcmd1bWVudCB0byB0aGUgcmVjZWl2ZXIsIGFuZCByZXR1cm5zIHRydWUKICAqIGlmIHRoZXkgcmVwcmVzZW50IHRoZSA8ZW0+c2FtZTwvZW0+IG9iamVjdCB1c2luZyBhIGNsYXNzCkBAIC0xNDUsOCArMTY2LDEyIEBACiAgKiBAc2VlICNoYXNoQ29kZQogICovCiBwdWJsaWMgYm9vbGVhbiBlcXVhbHMgKE9iamVjdCBvYmplY3QpIHsKLQlyZXR1cm4gKG9iamVjdCA9PSB0aGlzKSB8fCAoKG9iamVjdCBpbnN0YW5jZW9mIEZvbnREYXRhKSAmJiB0b1N0cmluZygpLmVxdWFscygoKEZvbnREYXRhKW9iamVjdCkudG9TdHJpbmcoKSkpOworCWlmIChvYmplY3QgPT0gdGhpcykgcmV0dXJuIHRydWU7CisJaWYgKCEob2JqZWN0IGluc3RhbmNlb2YgRm9udERhdGEpKSByZXR1cm4gZmFsc2U7CisJRm9udERhdGEgZGF0YSA9IChGb250RGF0YSlvYmplY3Q7CisJcmV0dXJuIG5hbWUuZXF1YWxzKGRhdGEubmFtZSkgJiYgaGVpZ2h0ID09IGRhdGEuaGVpZ2h0ICYmIHN0eWxlID09IGRhdGEuc3R5bGU7CiB9CisKIC8qKgogICogUmV0dXJucyB0aGUgaGVpZ2h0IG9mIHRoZSByZWNlaXZlciBpbiBwb2ludHMuCiAgKgpAQCAtMTU3LDYgKzE4Miw3IEBACiBwdWJsaWMgaW50IGdldEhlaWdodCgpIHsKIAlyZXR1cm4gaGVpZ2h0OwogfQorCiAvKioKICAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHJlY2VpdmVyLgogICogT24gcGxhdGZvcm1zIHRoYXQgc3VwcG9ydCBmb250IGZvdW5kcmllcywgdGhlIHJldHVybiB2YWx1ZSB3aWxsCkBAIC0xNjcsMTUgKzE5Myw5IEBACiAgKiBAc2VlICNzZXROYW1lCiAgKi8KIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLQlTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCWlmIChmb3VuZHJ5ICE9IG51bGwpIHsKLQkJYnVmZmVyLmFwcGVuZChmb3VuZHJ5KTsKLQkJYnVmZmVyLmFwcGVuZCgiLSIpOwotCX0KLQlpZiAoZm9udEZhbWlseSAhPSBudWxsKQotCQlidWZmZXIuYXBwZW5kKGZvbnRGYW1pbHkpOwotCXJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKKwlyZXR1cm4gbmFtZTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIHRoZSBzdHlsZSBvZiB0aGUgcmVjZWl2ZXIgd2hpY2ggaXMgYSBiaXR3aXNlIE9SIG9mIAogICogb25lIG9yIG1vcmUgb2YgdGhlIDxjb2RlPlNXVDwvY29kZT4gY29uc3RhbnRzIE5PUk1BTCwgQk9MRApAQCAtMTg4LDYgKzIwOCw3IEBACiBwdWJsaWMgaW50IGdldFN0eWxlKCkgewogCXJldHVybiBzdHlsZTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGUgcmVjZWl2ZXIuIEFueSB0d28gCiAgKiBvYmplY3RzIHdoaWNoIHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHBhc3NlZCB0byAKQEAgLTE5OSwxMSArMjIwLDkgQEAKICAqIEBzZWUgI2VxdWFscwogICovCiBwdWJsaWMgaW50IGhhc2hDb2RlICgpIHsKLQlyZXR1cm4gdG9TdHJpbmcoKS5oYXNoQ29kZSgpOworCXJldHVybiBuYW1lLmhhc2hDb2RlKCkgXiBoZWlnaHQgXiBzdHlsZTsKIH0KLXB1YmxpYyBzdGF0aWMgRm9udERhdGEgY2FyYm9uX25ldyhTdHJpbmcgeGxmZCkgewotCXJldHVybiBuZXcgRm9udERhdGEoeGxmZCk7Ci19CisKIC8qKgogICogU2V0cyB0aGUgaGVpZ2h0IG9mIHRoZSByZWNlaXZlci4gVGhlIHBhcmFtZXRlciBpcwogICogc3BlY2lmaWVkIGluIHRlcm1zIG9mIHBvaW50cywgd2hlcmUgYSBwb2ludCBpcyBvbmUKQEAgLTIyMSw2ICsyNDAsNDQgQEAKIAlpZiAoaGVpZ2h0IDwgMCkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKIAl0aGlzLmhlaWdodCA9IGhlaWdodDsKIH0KKworLyoqCisgKiBTZXRzIHRoZSBsb2NhbGUgb2YgdGhlIHJlY2VpdmVyLgorICogPHA+CisgKiBUaGUgbG9jYWxlIGRldGVybWluZXMgd2hpY2ggcGxhdGZvcm0gY2hhcmFjdGVyIHNldCB0aGlzCisgKiBmb250IGlzIGdvaW5nIHRvIHVzZS4gV2lkZ2V0cyBhbmQgZ3JhcGhpY3Mgb3BlcmF0aW9ucyB0aGF0CisgKiB1c2UgdGhpcyBmb250IHdpbGwgY29udmVydCBVTklDT0RFIHN0cmluZ3MgdG8gdGhlIHBsYXRmb3JtCisgKiBjaGFyYWN0ZXIgc2V0IG9mIHRoZSBzcGVjaWZpZWQgbG9jYWxlLgorICogPC9wPgorICogPHA+CisgKiBPbiBwbGF0Zm9ybXMgd2hpY2ggdGhlcmUgYXJlIG11bHRpcGxlIGNoYXJhY3RlciBzZXRzIGZvciBhCisgKiBnaXZlbiBsYW5ndWFnZS9jb3VudHJ5IGxvY2FsZSwgdGhlIHZhcmlhbnQgcG9ydGlvbiBvZiB0aGUKKyAqIGxvY2FsZSB3aWxsIGRldGVybWluZSB0aGUgY2hhcmFjdGVyIHNldC4KKyAqIDwvcD4KKyAqIAorICogQHBhcmFtIGxvY2FsZSB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiByZXByZXNlbnRpbmcgYSBMb2NhbGUgb2JqZWN0CisgKiBAc2VlIGphdmEudXRpbC5Mb2NhbGUjdG9TdHJpbmcKKyAqLworcHVibGljIHZvaWQgc2V0TG9jYWxlKFN0cmluZyBsb2NhbGUpIHsKKwlsYW5nID0gY291bnRyeSA9IHZhcmlhbnQgPSBudWxsOworCWlmIChsb2NhbGUgIT0gbnVsbCkgeworCQljaGFyIHNlcCA9ICdfJzsKKwkJaW50IGxlbmd0aCA9IGxvY2FsZS5sZW5ndGgoKTsKKwkJaW50IGZpcnN0U2VwLCBzZWNvbmRTZXA7CisJCQorCQlmaXJzdFNlcCA9IGxvY2FsZS5pbmRleE9mKHNlcCk7CisJCWlmIChmaXJzdFNlcCA9PSAtMSkgeworCQkJZmlyc3RTZXAgPSBzZWNvbmRTZXAgPSBsZW5ndGg7CisJCX0gZWxzZSB7CisJCQlzZWNvbmRTZXAgPSBsb2NhbGUuaW5kZXhPZihzZXAsIGZpcnN0U2VwICsgMSk7CisJCQlpZiAoc2Vjb25kU2VwID09IC0xKSBzZWNvbmRTZXAgPSBsZW5ndGg7CisJCX0KKwkJaWYgKGZpcnN0U2VwID4gMCkgbGFuZyA9IGxvY2FsZS5zdWJzdHJpbmcoMCwgZmlyc3RTZXApOworCQlpZiAoc2Vjb25kU2VwID4gZmlyc3RTZXAgKyAxKSBjb3VudHJ5ID0gbG9jYWxlLnN1YnN0cmluZyhmaXJzdFNlcCArIDEsIHNlY29uZFNlcCk7CisJCWlmIChsZW5ndGggPiBzZWNvbmRTZXAgKyAxKSB2YXJpYW50ID0gbG9jYWxlLnN1YnN0cmluZyhzZWNvbmRTZXAgKyAxKTsKKwl9CQorfQorCiAvKioKICAqIFNldHMgdGhlIG5hbWUgb2YgdGhlIHJlY2VpdmVyLgogICogPHA+CkBAIC0yNDgsMzMgKzMwNSw5IEBACiAgKi8KIHB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5hbWUpIHsKIAlpZiAobmFtZSA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCWludCBkYXNoID0gbmFtZS5pbmRleE9mKCctJyk7Ci0JaWYgKGRhc2ggIT0gLTEpIHsKLQkJZm91bmRyeSA9IG5hbWUuc3Vic3RyaW5nKDAsIGRhc2gpOwotCQlmb250RmFtaWx5ID0gbmFtZS5zdWJzdHJpbmcoZGFzaCArIDEpOwotCX0gZWxzZSB7Ci0JCWZvbnRGYW1pbHkgPSBuYW1lOwotCX0KKwl0aGlzLm5hbWUgPSBuYW1lOwogfQotLyoqCi0gKiBTZXRzIHRoZSBsb2NhbGUgb2YgdGhlIHJlY2VpdmVyLgotICogPHA+Ci0gKiBUaGUgbG9jYWxlIGRldGVybWluZXMgd2hpY2ggcGxhdGZvcm0gY2hhcmFjdGVyIHNldCB0aGlzCi0gKiBmb250IGlzIGdvaW5nIHRvIHVzZS4gV2lkZ2V0cyBhbmQgZ3JhcGhpY3Mgb3BlcmF0aW9ucyB0aGF0Ci0gKiB1c2UgdGhpcyBmb250IHdpbGwgY29udmVydCBVTklDT0RFIHN0cmluZ3MgdG8gdGhlIHBsYXRmb3JtCi0gKiBjaGFyYWN0ZXIgc2V0IG9mIHRoZSBzcGVjaWZpZWQgbG9jYWxlLgotICogPC9wPgotICogPHA+Ci0gKiBPbiBwbGF0Zm9ybXMgd2hpY2ggdGhlcmUgYXJlIG11bHRpcGxlIGNoYXJhY3RlciBzZXRzIGZvciBhCi0gKiBnaXZlbiBsYW5ndWFnZS9jb3VudHJ5IGxvY2FsZSwgdGhlIHZhcmlhbnQgcG9ydGlvbiBvZiB0aGUKLSAqIGxvY2FsZSB3aWxsIGRldGVybWluZSB0aGUgY2hhcmFjdGVyIHNldC4KLSAqIDwvcD4KLSAqIAotICogQHBhcmFtIGxvY2FsZSB0aGUgPGNvZGU+U3RyaW5nPC9jb2RlPiByZXByZXNlbnRpbmcgYSBMb2NhbGUgb2JqZWN0Ci0gKiBAc2VlIGphdmEudXRpbC5Mb2NhbGUjdG9TdHJpbmcKLSAqLwotcHVibGljIHZvaWQgc2V0TG9jYWxlKFN0cmluZyBsb2NhbGUpIHsKLX0KKwogLyoqCiAgKiBTZXRzIHRoZSBzdHlsZSBvZiB0aGUgcmVjZWl2ZXIgdG8gdGhlIGFyZ3VtZW50IHdoaWNoIG11c3QKICAqIGJlIGEgYml0d2lzZSBPUiBvZiBvbmUgb3IgbW9yZSBvZiB0aGUgPGNvZGU+U1dUPC9jb2RlPiAKQEAgLTI4NSw4ICszMTgsOSBAQAogICogQHNlZSAjZ2V0U3R5bGUKICAqLwogcHVibGljIHZvaWQgc2V0U3R5bGUoaW50IHN0eWxlKSB7Ci0JdGhpcy5zdHlsZT0gc3R5bGU7CisJdGhpcy5zdHlsZSA9IHN0eWxlOwogfQorCiAvKioKICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHJlY2VpdmVyIHdoaWNoIGlzIHN1aXRhYmxlCiAgKiBmb3IgY29uc3RydWN0aW5nIGFuIGVxdWl2YWxlbnQgaW5zdGFuY2UgdXNpbmcgdGhlIApAQCAtMjk3LDYgKzMzMSwxNiBAQAogICogQHNlZSBGb250RGF0YQogICovCiBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCXJldHVybiBnZXROYW1lKCkgKyAifCIgKyBnZXRIZWlnaHQoKSArICJ8IiArIGdldFN0eWxlKCk7CisJU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKKwlidWZmZXIuYXBwZW5kKCIxfCIpOworCWJ1ZmZlci5hcHBlbmQoZ2V0TmFtZSgpKTsKKwlidWZmZXIuYXBwZW5kKCJ8Iik7CisJYnVmZmVyLmFwcGVuZChnZXRIZWlnaHQoKSk7CisJYnVmZmVyLmFwcGVuZCgifCIpOworCWJ1ZmZlci5hcHBlbmQoZ2V0U3R5bGUoKSk7CisJYnVmZmVyLmFwcGVuZCgifCIpOworCWJ1ZmZlci5hcHBlbmQoIkNBUkJPTnwxfCIpOwkKKwlyZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7CiB9CisKIH0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZ3JhcGhpY3MvRm9udE1ldHJpY3MuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZ3JhcGhpY3MvRm9udE1ldHJpY3MuamF2YQppbmRleCBkMmRiMGJjLi41YTY1NjU3IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0ZvbnRNZXRyaWNzLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9Gb250TWV0cmljcy5qYXZhCkBAIC0xOCw5ICsxOCwxMCBAQAogICovCiBwdWJsaWMgZmluYWwgY2xhc3MgRm9udE1ldHJpY3MgewogCWludCBhc2NlbnQsIGRlc2NlbnQsIGF2ZXJhZ2VDaGFyV2lkdGgsIGxlYWRpbmcsIGhlaWdodDsKLQkKKwogRm9udE1ldHJpY3MoKSB7CiB9CisKIC8qKgogICogQ29tcGFyZXMgdGhlIGFyZ3VtZW50IHRvIHRoZSByZWNlaXZlciwgYW5kIHJldHVybnMgdHJ1ZQogICogaWYgdGhleSByZXByZXNlbnQgdGhlIDxlbT5zYW1lPC9lbT4gb2JqZWN0IHVzaW5nIGEgY2xhc3MKQEAgLTM5LDYgKzQwLDcgQEAKIAkJYXZlcmFnZUNoYXJXaWR0aCA9PSBtZXRyaWNzLmF2ZXJhZ2VDaGFyV2lkdGggJiYgbGVhZGluZyA9PSBtZXRyaWNzLmxlYWRpbmcgJiYKIAkJaGVpZ2h0ID09IG1ldHJpY3MuaGVpZ2h0OwogfQorCiAvKioKICAqIFJldHVybnMgdGhlIGFzY2VudCBvZiB0aGUgZm9udCBkZXNjcmliZWQgYnkgdGhlIHJlY2VpdmVyLiBBCiAgKiBmb250J3MgPGVtPmFzY2VudDwvZW0+IGlzIHRoZSBkaXN0YW5jZSBmcm9tIHRoZSBiYXNlbGluZSB0byB0aGUgCkBAIC01MCw2ICs1Miw3IEBACiBwdWJsaWMgaW50IGdldEFzY2VudCgpIHsKIAlyZXR1cm4gYXNjZW50OwogfQorCiAvKioKICAqIFJldHVybnMgdGhlIGF2ZXJhZ2UgY2hhcmFjdGVyIHdpZHRoLCBtZWFzdXJlZCBpbiBwaXhlbHMsCiAgKiBvZiB0aGUgZm9udCBkZXNjcmliZWQgYnkgdGhlIHJlY2VpdmVyLgpAQCAtNTksNiArNjIsNyBAQAogcHVibGljIGludCBnZXRBdmVyYWdlQ2hhcldpZHRoKCkgewogCXJldHVybiBhdmVyYWdlQ2hhcldpZHRoOwogfQorCiAvKioKICAqIFJldHVybnMgdGhlIGRlc2NlbnQgb2YgdGhlIGZvbnQgZGVzY3JpYmVkIGJ5IHRoZSByZWNlaXZlci4gQQogICogZm9udCdzIDxlbT5kZXNjZW50PC9lbT4gaXMgdGhlIGRpc3RhbmNlIGZyb20gdGhlIGJhc2VsaW5lIHRvIHRoZQpAQCAtNzAsNiArNzQsNyBAQAogcHVibGljIGludCBnZXREZXNjZW50KCkgewogCXJldHVybiBkZXNjZW50OwogfQorCiAvKioKICAqIFJldHVybnMgdGhlIGhlaWdodCBvZiB0aGUgZm9udCBkZXNjcmliZWQgYnkgdGhlIHJlY2VpdmVyLCAKICAqIG1lYXN1cmVkIGluIHBpeGVscy4gQSBmb250J3MgPGVtPmhlaWdodDwvZW0+IGlzIHRoZSBzdW0gb2YKQEAgLTg0LDYgKzg5LDcgQEAKIHB1YmxpYyBpbnQgZ2V0SGVpZ2h0KCkgewogCXJldHVybiBoZWlnaHQ7CiB9CisKIC8qKgogICogUmV0dXJucyB0aGUgbGVhZGluZyBhcmVhIG9mIHRoZSBmb250IGRlc2NyaWJlZCBieSB0aGUKICAqIHJlY2VpdmVyLiBBIGZvbnQncyA8ZW0+bGVhZGluZyBhcmVhPC9lbT4gaXMgdGhlIHNwYWNlCkBAIC05NCw2ICsxMDAsNyBAQAogcHVibGljIGludCBnZXRMZWFkaW5nKCkgewogCXJldHVybiBsZWFkaW5nOwogfQorCiAvKioKICAqIFJldHVybnMgYW4gaW50ZWdlciBoYXNoIGNvZGUgZm9yIHRoZSByZWNlaXZlci4gQW55IHR3byAKICAqIG9iamVjdHMgd2hpY2ggcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4gcGFzc2VkIHRvIApAQCAtMTA3LDEzICsxMTQsNSBAQAogcHVibGljIGludCBoYXNoQ29kZSgpIHsKIAlyZXR1cm4gYXNjZW50IF4gZGVzY2VudCBeIGF2ZXJhZ2VDaGFyV2lkdGggXiBsZWFkaW5nIF4gaGVpZ2h0OwogfQotcHVibGljIHN0YXRpYyBGb250TWV0cmljcyBjYXJib25fbmV3KGludCBhc2NlbnQsIGludCBkZXNjZW50LCBpbnQgYXZlcmFnZUNoYXJXaWR0aCwgaW50IGxlYWRpbmcsIGludCBoZWlnaHQpIHsKLQlGb250TWV0cmljcyBmb250TWV0cmljcyA9IG5ldyBGb250TWV0cmljcygpOwotCWZvbnRNZXRyaWNzLmFzY2VudCA9IGFzY2VudDsKLQlmb250TWV0cmljcy5kZXNjZW50ID0gZGVzY2VudDsKLQlmb250TWV0cmljcy5hdmVyYWdlQ2hhcldpZHRoID0gYXZlcmFnZUNoYXJXaWR0aDsKLQlmb250TWV0cmljcy5sZWFkaW5nID0gbGVhZGluZzsKLQlmb250TWV0cmljcy5oZWlnaHQgPSBoZWlnaHQ7Ci0JcmV0dXJuIGZvbnRNZXRyaWNzOwotfQorCiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0dDLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0dDLmphdmEKaW5kZXggMzJmZTY1NC4uMDQ4OWQyZiAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9HQy5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZ3JhcGhpY3MvR0MuamF2YQpAQCAtOCw4ICs4LDkgQEAKICAqLwogCiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwotIAorCiAvKioKICAqIENsYXNzIDxjb2RlPkdDPC9jb2RlPiBpcyB3aGVyZSBhbGwgb2YgdGhlIGRyYXdpbmcgY2FwYWJpbGl0aWVzIHRoYXQgYXJlIAogICogc3VwcG9ydGVkIGJ5IFNXVCBhcmUgbG9jYXRlZC4gSW5zdGFuY2VzIGFyZSB1c2VkIHRvIGRyYXcgb24gZWl0aGVyIGFuIApAQCAtMjksMjcgKzMwLDE0IEBACiAJICogdGhlIGhhbmRsZSB0byB0aGUgT1MgZGV2aWNlIGNvbnRleHQKIAkgKiAoV2FybmluZzogVGhpcyBmaWVsZCBpcyBwbGF0Zm9ybSBkZXBlbmRlbnQpCiAJICovCi0JcHVibGljIGludCBoYW5kbGU7CS8vIGEgTWFjIENHcmFmUG9ydAorCXB1YmxpYyBpbnQgaGFuZGxlOwogCQogCURyYXdhYmxlIGRyYXdhYmxlOwogCUdDRGF0YSBkYXRhOwotCQkKLQkvLy0tLS0gQVcKLQlwcml2YXRlIE1hY1JlY3QgZlJlY3Q9IG5ldyBNYWNSZWN0KCk7Ci0JcHJpdmF0ZSBpbnRbXSBmU2F2ZVBvcnQ9IG5ldyBpbnRbMV07Ci0JcHJpdmF0ZSBpbnRbXSBmU2F2ZUdXb3JsZD0gbmV3IGludFsxXTsKLQlwcml2YXRlIGludCBmU2F2ZUNsaXA9IE9TLk5ld1JnbigpOwotCXByaXZhdGUgYm9vbGVhbiBmSXNGb2N1c2VkPSBmYWxzZTsKLQlwcml2YXRlIGludCBmTGluZVdpZHRoPSAxOwotCXByaXZhdGUgYm9vbGVhbiBmWG9yTW9kZT0gZmFsc2U7Ci0JcHJpdmF0ZSBpbnQgZkRhbWFnZVJnbjsKLQlwcml2YXRlIGJvb2xlYW4gZlBlbmRpbmdDbGlwOwotCQotCXByaXZhdGUgaW50W10gZkNvbnRleHQ9IG5ldyBpbnRbMV07Ci0JLy8tLS0tIEFXCiAKIEdDKCkgewogfQorCiAvKioJIAogICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIHdoaWNoIGhhcyBiZWVuCiAgKiBjb25maWd1cmVkIHRvIGRyYXcgb24gdGhlIHNwZWNpZmllZCBkcmF3YWJsZS4gU2V0cyB0aGUKQEAgLTcxLDQ5ICs1OSwzNyBAQAogICogICAgPGxpPkVSUk9SX05PX0hBTkRMRVMgaWYgYSBoYW5kbGUgY291bGQgbm90IGJlIG9idGFpbmVkIGZvciBnYyBjcmVhdGlvbjwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgR0MgKERyYXdhYmxlIGRyYXdhYmxlKSB7CitwdWJsaWMgR0MoRHJhd2FibGUgZHJhd2FibGUpIHsKIAlpZiAoZHJhd2FibGUgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlHQ0RhdGEgZGF0YSA9IG5ldyBHQ0RhdGEoKTsKLQlpbnQgeEdDID0gZHJhd2FibGUuaW50ZXJuYWxfbmV3X0dDKGRhdGEpOwotCWluaXQoZHJhd2FibGUsIGRhdGEsIHhHQyk7CisJaW50IGdka0dDID0gZHJhd2FibGUuaW50ZXJuYWxfbmV3X0dDKGRhdGEpOworCWluaXQoZHJhd2FibGUsIGRhdGEsIGdka0dDKTsKIH0KIAotLyoqCi0gKiBDb3BpZXMgYSByZWN0YW5ndWxhciBhcmVhIG9mIHRoZSByZWNlaXZlciBhdCB0aGUgc291cmNlCi0gKiBwb3NpdGlvbiBvbnRvIHRoZSByZWNlaXZlciBhdCB0aGUgZGVzdGluYXRpb24gcG9zaXRpb24uCisvKioJIAorICogSW52b2tlcyBwbGF0Zm9ybSBzcGVjaWZpYyBmdW5jdGlvbmFsaXR5IHRvIGFsbG9jYXRlIGEgbmV3IGdyYXBoaWNzIGNvbnRleHQuCisgKiA8cD4KKyAqIDxiPklNUE9SVEFOVDo8L2I+IFRoaXMgbWV0aG9kIGlzIDxlbT5ub3Q8L2VtPiBwYXJ0IG9mIHRoZSBwdWJsaWMKKyAqIEFQSSBmb3IgPGNvZGU+R0M8L2NvZGU+LiBJdCBpcyBtYXJrZWQgcHVibGljIG9ubHkgc28gdGhhdCBpdAorICogY2FuIGJlIHNoYXJlZCB3aXRoaW4gdGhlIHBhY2thZ2VzIHByb3ZpZGVkIGJ5IFNXVC4gSXQgaXMgbm90CisgKiBhdmFpbGFibGUgb24gYWxsIHBsYXRmb3JtcywgYW5kIHNob3VsZCBuZXZlciBiZSBjYWxsZWQgZnJvbQorICogYXBwbGljYXRpb24gY29kZS4KKyAqIDwvcD4KICAqCi0gKiBAcGFyYW0gc3JjWCB0aGUgeCBjb29yZGluYXRlIGluIHRoZSByZWNlaXZlciBvZiB0aGUgYXJlYSB0byBiZSBjb3BpZWQKLSAqIEBwYXJhbSBzcmNZIHRoZSB5IGNvb3JkaW5hdGUgaW4gdGhlIHJlY2VpdmVyIG9mIHRoZSBhcmVhIHRvIGJlIGNvcGllZAotICogQHBhcmFtIHdpZHRoIHRoZSB3aWR0aCBvZiB0aGUgYXJlYSB0byBjb3B5Ci0gKiBAcGFyYW0gaGVpZ2h0IHRoZSBoZWlnaHQgb2YgdGhlIGFyZWEgdG8gY29weQotICogQHBhcmFtIGRlc3RYIHRoZSB4IGNvb3JkaW5hdGUgaW4gdGhlIHJlY2VpdmVyIG9mIHRoZSBhcmVhIHRvIGNvcHkgdG8KLSAqIEBwYXJhbSBkZXN0WSB0aGUgeSBjb29yZGluYXRlIGluIHRoZSByZWNlaXZlciBvZiB0aGUgYXJlYSB0byBjb3B5IHRvCisgKiBAcGFyYW0gZHJhd2FibGUgdGhlIERyYXdhYmxlIGZvciB0aGUgcmVjZWl2ZXIuCisgKiBAcGFyYW0gZGF0YSB0aGUgZGF0YSBmb3IgdGhlIHJlY2VpdmVyLgogICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9HUkFQSElDX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqIDwvdWw+CisgKiBAcmV0dXJuIGEgbmV3IDxjb2RlPkdDPC9jb2RlPgorICoKKyAqIEBwcml2YXRlCiAgKi8KLXB1YmxpYyB2b2lkIGNvcHlBcmVhKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgZGVzdFgsIGludCBkZXN0WSkgewotCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQlpZiAod2lkdGggPD0gMCB8fCBoZWlnaHQgPD0gMCkgcmV0dXJuOwotCWludCBkZWx0YVggPSBkZXN0WCAtIHgsIGRlbHRhWSA9IGRlc3RZIC0geTsKLQlpZiAoZGVsdGFYID09IDAgJiYgZGVsdGFZID09IDApIHJldHVybjsKLQkJCi0JUmVjdGFuZ2xlIHNyYz0gbmV3IFJlY3RhbmdsZSh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKLQlzcmM9IHNyYy51bmlvbihuZXcgUmVjdGFuZ2xlKGRlc3RYLCBkZXN0WSwgd2lkdGgsIGhlaWdodCkpOwotCU1hY1JlY3Qgcj0gbmV3IE1hY1JlY3Qoc3JjKTsKLQkKLQl0cnkgewotCQlpZiAoZm9jdXModHJ1ZSwgbnVsbCkpIHsKLQkJCWludCByZ249IE9TLk5ld1JnbigpOwotCQkJT1MuU2Nyb2xsUmVjdChyLmdldERhdGEoKSwgKHNob3J0KWRlbHRhWCwgKHNob3J0KWRlbHRhWSwgcmduKTsKLQkJCU9TLkludmFsV2luZG93UmduKE9TLkdldFdpbmRvd0Zyb21Qb3J0KGhhbmRsZSksIHJnbik7Ci0JCQlPUy5EaXNwb3NlUmduKHJnbik7Ci0JCX0KLQl9IGZpbmFsbHkgewotCQl1bmZvY3VzKHRydWUpOwotCX0KK3B1YmxpYyBzdGF0aWMgR0MgY2FyYm9uX25ldyhEcmF3YWJsZSBkcmF3YWJsZSwgR0NEYXRhIGRhdGEpIHsKKwlHQyBnYyA9IG5ldyBHQygpOworCWludCBjb250ZXh0ID0gZHJhd2FibGUuaW50ZXJuYWxfbmV3X0dDKGRhdGEpOworCWdjLmluaXQoZHJhd2FibGUsIGRhdGEsIGNvbnRleHQpOworCXJldHVybiBnYzsKIH0KKwogLyoqCiAgKiBDb3BpZXMgYSByZWN0YW5ndWxhciBhcmVhIG9mIHRoZSByZWNlaXZlciBhdCB0aGUgc3BlY2lmaWVkCiAgKiBwb3NpdGlvbiBpbnRvIHRoZSBpbWFnZSwgd2hpY2ggbXVzdCBiZSBvZiB0eXBlIDxjb2RlPlNXVC5CSVRNQVA8L2NvZGU+LgpAQCAtMTMzLDQ0ICsxMDksMTU0IEBACiAJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwogCWlmIChpbWFnZSA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWlmIChpbWFnZS50eXBlICE9IFNXVC5CSVRNQVAgfHwgaW1hZ2UuaXNEaXNwb3NlZCgpKSBTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwotCS8qIEFXCi0JUmVjdGFuZ2xlIHJlY3QgPSBpbWFnZS5nZXRCb3VuZHMoKTsKLQlpbnQgeERpc3BsYXkgPSBkYXRhLmRpc3BsYXk7Ci0JaW50IHhHQyA9IE9TLlhDcmVhdGVHQyh4RGlzcGxheSwgaW1hZ2UucGl4bWFwLCAwLCBudWxsKTsKLQlpZiAoeEdDID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JT1MuWFNldFN1YndpbmRvd01vZGUgKHhEaXNwbGF5LCB4R0MsIE9TLkluY2x1ZGVJbmZlcmlvcnMpOwotCU9TLlhDb3B5QXJlYSh4RGlzcGxheSwgZGF0YS5kcmF3YWJsZSwgaW1hZ2UucGl4bWFwLCB4R0MsIHgsIHksIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0LCAwLCAwKTsKLQlPUy5YRnJlZUdDKHhEaXNwbGF5LCB4R0MpOwotCSovCi0JU3lzdGVtLm91dC5wcmludGxuKCJHQy5jb3B5QXJlYShJbWFnZSk6IG55aSIpOworCS8vTk9UIElNUExFTUVOVEVECiB9CisKKy8qKgorICogQ29waWVzIGEgcmVjdGFuZ3VsYXIgYXJlYSBvZiB0aGUgcmVjZWl2ZXIgYXQgdGhlIHNvdXJjZQorICogcG9zaXRpb24gb250byB0aGUgcmVjZWl2ZXIgYXQgdGhlIGRlc3RpbmF0aW9uIHBvc2l0aW9uLgorICoKKyAqIEBwYXJhbSBzcmNYIHRoZSB4IGNvb3JkaW5hdGUgaW4gdGhlIHJlY2VpdmVyIG9mIHRoZSBhcmVhIHRvIGJlIGNvcGllZAorICogQHBhcmFtIHNyY1kgdGhlIHkgY29vcmRpbmF0ZSBpbiB0aGUgcmVjZWl2ZXIgb2YgdGhlIGFyZWEgdG8gYmUgY29waWVkCisgKiBAcGFyYW0gd2lkdGggdGhlIHdpZHRoIG9mIHRoZSBhcmVhIHRvIGNvcHkKKyAqIEBwYXJhbSBoZWlnaHQgdGhlIGhlaWdodCBvZiB0aGUgYXJlYSB0byBjb3B5CisgKiBAcGFyYW0gZGVzdFggdGhlIHggY29vcmRpbmF0ZSBpbiB0aGUgcmVjZWl2ZXIgb2YgdGhlIGFyZWEgdG8gY29weSB0bworICogQHBhcmFtIGRlc3RZIHRoZSB5IGNvb3JkaW5hdGUgaW4gdGhlIHJlY2VpdmVyIG9mIHRoZSBhcmVhIHRvIGNvcHkgdG8KKyAqCisgKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+CisgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CisgKiA8L3VsPgorICovCitwdWJsaWMgdm9pZCBjb3B5QXJlYShpbnQgc3JjWCwgaW50IHNyY1ksIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGRlc3RYLCBpbnQgZGVzdFkpIHsKKwlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7CisJaWYgKHdpZHRoIDw9IDAgfHwgaGVpZ2h0IDw9IDApIHJldHVybjsKKwlpbnQgZGVsdGFYID0gZGVzdFggLSBzcmNYLCBkZWx0YVkgPSBkZXN0WSAtIHNyY1k7CisJaWYgKGRlbHRhWCA9PSAwICYmIGRlbHRhWSA9PSAwKSByZXR1cm47CisJaWYgKGRhdGEuaW1hZ2UgIT0gbnVsbCkgeworIAkJT1MuQ0dDb250ZXh0U2F2ZUdTdGF0ZShoYW5kbGUpOworIAkJT1MuQ0dDb250ZXh0U2NhbGVDVE0oaGFuZGxlLCAxLCAtMSk7CisgCQlPUy5DR0NvbnRleHRUcmFuc2xhdGVDVE0oaGFuZGxlLCAwLCAtKGhlaWdodCArIDIgKiBkZXN0WSkpOworIAkJQ0dSZWN0IHJlY3QgPSBuZXcgQ0dSZWN0KCk7CisgCQlyZWN0LnggPSBkZXN0WDsKKyAJCXJlY3QueSA9IGRlc3RZOworIAkJcmVjdC53aWR0aCA9IHdpZHRoOworCQlyZWN0LmhlaWdodCA9IGhlaWdodDsKKwkJLy9OT1QgRE9ORSAtIHRyYW5zcGFyZW5jeQorIAkJT1MuQ0dDb250ZXh0RHJhd0ltYWdlKGhhbmRsZSwgcmVjdCwgZGF0YS5pbWFnZS5oYW5kbGUpOworIAkJT1MuQ0dDb250ZXh0UmVzdG9yZUdTdGF0ZShoYW5kbGUpOworIAkJcmV0dXJuOworCX0KKwlpZiAoZGF0YS5jb250cm9sICE9IDApIHsKKwkJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lcihkYXRhLmNvbnRyb2wpOworCQlpbnQgcG9ydCA9IE9TLkdldFdpbmRvd1BvcnQod2luZG93KTsKKworCQkvKiBDYWxjdWxhdGUgc3JjIGFuZCBkZXN0IHJlY3RhbmdsZXMvcmVnaW9ucyAqLworCQlSZWN0IHJlY3QgPSBuZXcgUmVjdCgpOworCQlPUy5HZXRDb250cm9sQm91bmRzKGRhdGEuY29udHJvbCwgcmVjdCk7CQkKKwkJUmVjdCBzcmNSZWN0ID0gbmV3IFJlY3QoKTsKKwkJT1MuR2V0Q29udHJvbEJvdW5kcyhkYXRhLmNvbnRyb2wsIHNyY1JlY3QpOworCQlpbnQgbGVmdCA9IHNyY1JlY3QubGVmdCArIHNyY1g7CisJCWludCB0b3AgPSBzcmNSZWN0LnRvcCArIHNyY1k7CisJCU9TLlNldFJlY3Qoc3JjUmVjdCwgKHNob3J0KWxlZnQsIChzaG9ydCl0b3AsIChzaG9ydCkobGVmdCArIHdpZHRoKSwgKHNob3J0KSh0b3AgKyBoZWlnaHQpKTsKKwkJaW50IHNyY1JnbiA9IE9TLk5ld1JnbigpOworCQlPUy5SZWN0UmduKHNyY1Jnbiwgc3JjUmVjdCk7CQkKKwkJT1MuU2VjdFJlY3QocmVjdCwgc3JjUmVjdCwgc3JjUmVjdCk7CisJCVJlY3QgZGVzdFJlY3QgPSBuZXcgUmVjdCAoKTsKKwkJZGVzdFJlY3QubGVmdCA9IHNyY1JlY3QubGVmdDsKKwkJZGVzdFJlY3QudG9wID0gc3JjUmVjdC50b3A7CisJCWRlc3RSZWN0LnJpZ2h0ID0gc3JjUmVjdC5yaWdodDsKKwkJZGVzdFJlY3QuYm90dG9tID0gc3JjUmVjdC5ib3R0b207CisJCU9TLk9mZnNldFJlY3QoZGVzdFJlY3QsIChzaG9ydClkZWx0YVgsIChzaG9ydClkZWx0YVkpOworCQlpbnQgZGVzdFJnbiA9IE9TLk5ld1JnbigpOworCQlPUy5SZWN0UmduKGRlc3RSZ24sIGRlc3RSZWN0KTsKKwkJCisJCS8qIENvcHkgYml0cyB3aXRoIGFwcHJvcHJpYXRlZCBjbGlwcGluZyByZWdpb24gKi8KKwkJaWYgKCFPUy5FbXB0eVJlY3Qoc3JjUmVjdCkpIHsKKwkJCWludCBjbGlwUmduID0gZGF0YS52aXNpYmxlUmduOworCQkJaWYgKGRhdGEuY2xpcFJnbiAhPSAwKSB7CisJCQkJY2xpcFJnbiA9IE9TLk5ld1JnbigpOworCQkJCU9TLlNlY3RSZ24oZGF0YS5jbGlwUmduLCBjbGlwUmduLCBjbGlwUmduKTsKKwkJCX0KKworCQkJLyoKKwkJCSogRmVhdHVyZSBpbiB0aGUgTWFjaW50b3NoLiAgU2Nyb2xsUmVjdCgpIG9ubHkgY29waWVzIGJpdHMKKwkJCSogdGhhdCBhcmUgaW5zaWRlIHRoZSBzcGVjaWZpZWQgcmVjdGFuZ2xlLiAgVGhpcyBtZWFucyB0aGF0CisJCQkqIGl0IGlzIG5vdCBwb3NzaWJsZSB0byBjb3B5IG5vbiBvdmVybGFwaW5nIGJpdHMgd2l0aG91dAorCQkJKiBjb3B5aW5nIHRoZSBiaXRzIGluIGJldHdlZW4gdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24KKwkJCSogcmVjdGFuZ2xlcy4gIFRoZSBmaXggaXMgdG8gY2hlY2sgaWYgdGhlIHNvdXJjZSBhbmQKKwkJCSogZGVzdGluYXRpb24gcmVjdGFuZ2xlcyBhcmUgZGlzam9pbnQgYW5kIHVzZSBDb3B5Qml0cygpCisJCQkqIGluc3RlYWQuCisJCQkqLworCQkJYm9vbGVhbiBkaXNqb2ludCA9IChkZXN0WCArIHdpZHRoIDwgc3JjWCkgfHwgKHNyY1ggKyB3aWR0aCA8IGRlc3RYKSB8fCAoZGVzdFkgKyBoZWlnaHQgPCBzcmNZKSB8fCAoc3JjWSArIGhlaWdodCA8IGRlc3RZKTsKKwkJCWlmICghZGlzam9pbnQgJiYgKGRlbHRhWCA9PSAwIHx8IGRlbHRhWSA9PSAwKSkgeworCQkJCWludFtdIGN1cnJlbnRQb3J0ID0gbmV3IGludFsxXTsKKwkJCQlPUy5HZXRQb3J0KGN1cnJlbnRQb3J0KTsKKwkJCQlPUy5TZXRQb3J0KHBvcnQpOworCQkJCWludCBvbGRDbGlwID0gT1MuTmV3UmduKCk7CisJCQkJT1MuR2V0Q2xpcChvbGRDbGlwKTsKKwkJCQlPUy5TZXRDbGlwKGNsaXBSZ24pOworCQkJCU9TLlVuaW9uUmVjdChzcmNSZWN0LCBkZXN0UmVjdCwgcmVjdCk7CisJCQkJT1MuU2Nyb2xsUmVjdChyZWN0LCAoc2hvcnQpZGVsdGFYLCAoc2hvcnQpZGVsdGFZLCAwKTsKKwkJCQlPUy5TZXRDbGlwKG9sZENsaXApOworCQkJCU9TLkRpc3Bvc2VSZ24ob2xkQ2xpcCk7CisJCQkJT1MuU2V0UG9ydChjdXJyZW50UG9ydFswXSk7CisJCQl9IGVsc2UgeworCQkJCWludCBwb3J0Qml0TWFwID0gT1MuR2V0UG9ydEJpdE1hcEZvckNvcHlCaXRzIChwb3J0KTsKKwkJCQlPUy5Db3B5Qml0cyhwb3J0Qml0TWFwLCBwb3J0Qml0TWFwLCBzcmNSZWN0LCBkZXN0UmVjdCwgKHNob3J0KU9TLnNyY0NvcHksIGNsaXBSZ24pOworCQkJCU9TLlFERmx1c2hQb3J0QnVmZmVyKHBvcnQsIGRlc3RSZ24pOworCQkJfQorCQkJCisJCQlpZiAoY2xpcFJnbiAhPSBkYXRhLnZpc2libGVSZ24pIE9TLkRpc3Bvc2VSZ24oY2xpcFJnbik7CisJCX0KKwkJCisJCS8qIEludmFsaWRhdGUgc3JjIGFuZCBvYnNjdXJlZCBhcmVhcyAqLworCQlpbnQgaW52YWxSZ24gPSBPUy5OZXdSZ24oKTsKKwkJT1MuRGlmZlJnbihzcmNSZ24sIGRhdGEudmlzaWJsZVJnbiwgaW52YWxSZ24pOworCQlPUy5PZmZzZXRSZ24oaW52YWxSZ24sIChzaG9ydClkZWx0YVgsIChzaG9ydClkZWx0YVkpOworCQlPUy5EaWZmUmduKHNyY1JnbiwgZGVzdFJnbiwgc3JjUmduKTsKKwkJT1MuVW5pb25SZ24oc3JjUmduLCBpbnZhbFJnbiwgaW52YWxSZ24pOworCQlPUy5TZWN0UmduKGRhdGEudmlzaWJsZVJnbiwgaW52YWxSZ24sIGludmFsUmduKTsKKwkJT1MuSW52YWxXaW5kb3dSZ24od2luZG93LCBpbnZhbFJnbik7CisJCU9TLkRpc3Bvc2VSZ24oaW52YWxSZ24pOworCQkKKwkJLyogRGlzcG9zZSBzcmMgYW5kIGRlc3QgcmVnaW9ucyAqLworCQlPUy5EaXNwb3NlUmduKGRlc3RSZ24pOworCQlPUy5EaXNwb3NlUmduKHNyY1Jnbik7CisJfQorfQorCiAvKioKICAqIERpc3Bvc2VzIG9mIHRoZSBvcGVyYXRpbmcgc3lzdGVtIHJlc291cmNlcyBhc3NvY2lhdGVkIHdpdGgKICAqIHRoZSBncmFwaGljcyBjb250ZXh0LiBBcHBsaWNhdGlvbnMgbXVzdCBkaXNwb3NlIG9mIGFsbCBHQ3MKICAqIHdoaWNoIHRoZXkgYWxsb2NhdGUuCiAgKi8KLXB1YmxpYyB2b2lkIGRpc3Bvc2UgKCkgeworcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKIAlpZiAoaGFuZGxlID09IDApIHJldHVybjsKIAlpZiAoZGF0YS5kZXZpY2UuaXNEaXNwb3NlZCgpKSByZXR1cm47Ci0JCisKIAkvKiBGcmVlIHJlc291cmNlcyAqLwogCWludCBjbGlwUmduID0gZGF0YS5jbGlwUmduOwogCWlmIChjbGlwUmduICE9IDApIE9TLkRpc3Bvc2VSZ24oY2xpcFJnbik7Ci0JCQogCUltYWdlIGltYWdlID0gZGF0YS5pbWFnZTsKLQlpZiAoaW1hZ2UgIT0gbnVsbCkgaW1hZ2UubWVtR0MgPSBudWxsOworCWlmIChpbWFnZSAhPSBudWxsKSB7CisJCWltYWdlLm1lbUdDID0gbnVsbDsKKy8vCQlpZiAoaW1hZ2UudHJhbnNwYXJlbnRQaXhlbCAhPSAtMSkgaW1hZ2UuY3JlYXRlTWFzaygpOworCX0KKwlpbnQgbGF5b3V0ID0gZGF0YS5sYXlvdXQ7CisJaWYgKGxheW91dCAhPSAwKSBPUy5BVFNVRGlzcG9zZVRleHRMYXlvdXQobGF5b3V0KTsKKwlpbnQgc3R5bGUgPSBkYXRhLnN0eWxlOworCWlmIChzdHlsZSAhPSAwKSBPUy5BVFNVRGlzcG9zZVRleHRMYXlvdXQoc3R5bGUpOwogCiAJLyogRGlzcG9zZSB0aGUgR0MgKi8KIAlkcmF3YWJsZS5pbnRlcm5hbF9kaXNwb3NlX0dDKGhhbmRsZSwgZGF0YSk7CiAKLQlkYXRhLmNsaXBSZ24gPSAwOwotCWRhdGEuZm9udCA9IG51bGw7CisJZGF0YS5jbGlwUmduID0gZGF0YS5zdHlsZSA9IGRhdGEubGF5b3V0ID0gMDsKIAlkcmF3YWJsZSA9IG51bGw7Ci0JZGF0YS5kZXZpY2UgPSBudWxsOwogCWRhdGEuaW1hZ2UgPSBudWxsOwogCWRhdGEgPSBudWxsOwogCWhhbmRsZSA9IDA7CiB9CisKIC8qKgogICogRHJhd3MgdGhlIG91dGxpbmUgb2YgYSBjaXJjdWxhciBvciBlbGxpcHRpY2FsIGFyYyAKICAqIHdpdGhpbiB0aGUgc3BlY2lmaWVkIHJlY3Rhbmd1bGFyIGFyZWEuCkBAIC0yMTUsMTIgKzMwMSwxNiBAQAogCX0KIAlpZiAod2lkdGggPT0gMCB8fCBoZWlnaHQgPT0gMCB8fCBlbmRBbmdsZSA9PSAwKSB7CiAJCVNXVC5lcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7Ci0JfQotCS8qIEFXCi0JT1MuWERyYXdBcmMoZGF0YS5kaXNwbGF5LGRhdGEuZHJhd2FibGUsaGFuZGxlLHgseSx3aWR0aCxoZWlnaHQsc3RhcnRBbmdsZSAqIDY0ICxlbmRBbmdsZSAqIDY0KTsKLQkqLwotCVN5c3RlbS5vdXQucHJpbnRsbigiR0MuZHJhd0FyYyIpOworCX0JCisJT1MuQ0dDb250ZXh0QmVnaW5QYXRoKGhhbmRsZSk7CisgICAgT1MuQ0dDb250ZXh0U2F2ZUdTdGF0ZShoYW5kbGUpOworICAgIE9TLkNHQ29udGV4dFRyYW5zbGF0ZUNUTShoYW5kbGUsIHggKyB3aWR0aCAvIDJmLCB5ICsgaGVpZ2h0IC8gMmYpOworICAgIE9TLkNHQ29udGV4dFNjYWxlQ1RNKGhhbmRsZSwgd2lkdGggLyAyZiwgaGVpZ2h0IC8gMmYpOworICAgIE9TLkNHQ29udGV4dEFkZEFyYyhoYW5kbGUsIDAsIDAsIDEsIC1zdGFydEFuZ2xlICogKGZsb2F0KU1hdGguUEkgLyAxODAsICAtZW5kQW5nbGUgKiAoZmxvYXQpTWF0aC5QSSAvIDE4MCwgdHJ1ZSk7CisgICAgT1MuQ0dDb250ZXh0UmVzdG9yZUdTdGF0ZShoYW5kbGUpOworCU9TLkNHQ29udGV4dFN0cm9rZVBhdGgoaGFuZGxlKTsKIH0KKwogLyoqIAogICogRHJhd3MgYSByZWN0YW5nbGUsIGJhc2VkIG9uIHRoZSBzcGVjaWZpZWQgYXJndW1lbnRzLCB3aGljaCBoYXMKICAqIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBwbGF0Zm9ybSdzIDxlbT5mb2N1cyByZWN0YW5nbGU8L2VtPiBpZiB0aGUKQEAgLTIzOCw0MCArMzI4LDEyIEBACiAgKgogICogQHNlZSAjZHJhd1JlY3RhbmdsZQogICovCi1wdWJsaWMgdm9pZCBkcmF3Rm9jdXMgKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CitwdWJsaWMgdm9pZCBkcmF3Rm9jdXMoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JLyoKLQkqIFdoZW4gdGhlIGRyYXdhYmxlIGlzIG5vdCBhIHdpZGdldCwgdGhlIGhpZ2hsaWdodAotCSogY29sb3IgaXMgemVyby4KLQkqLwotCS8qIEFXCi0JaW50IGhpZ2hsaWdodENvbG9yID0gMDsKLQlpbnQgd2lkZ2V0ID0gT1MuWHRXaW5kb3dUb1dpZGdldCAoeERpc3BsYXksIHhEcmF3YWJsZSk7Ci0JaWYgKHdpZGdldCAhPSAwKSB7Ci0JCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTmhpZ2hsaWdodENvbG9yLCAwfTsKLQkJT1MuWHRHZXRWYWx1ZXMgKHdpZGdldCwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQkJaGlnaGxpZ2h0Q29sb3IgPSBhcmdMaXN0IFsxXTsKLQl9Ci0JKi8KLQkKLQkvKiBEcmF3IHRoZSBmb2N1cyByZWN0YW5nbGUgKi8KLQlpZiAod2lkdGggPCAwKSB7Ci0JCXggPSB4ICsgd2lkdGg7Ci0JCXdpZHRoID0gLXdpZHRoOwotCX0KLQlpZiAoaGVpZ2h0IDwgMCkgewotCQl5ID0geSArIGhlaWdodDsKLQkJaGVpZ2h0ID0gLWhlaWdodDsKLQl9Ci0JLyogQVcKLQlYR0NWYWx1ZXMgdmFsdWVzID0gbmV3IFhHQ1ZhbHVlcyAoKTsKLQlPUy5YR2V0R0NWYWx1ZXMgKHhEaXNwbGF5LCBoYW5kbGUsIE9TLkdDRm9yZWdyb3VuZCwgdmFsdWVzKTsKLQlPUy5YU2V0Rm9yZWdyb3VuZCAoeERpc3BsYXksIGhhbmRsZSwgaGlnaGxpZ2h0Q29sb3IpOwotCU9TLlhEcmF3UmVjdGFuZ2xlICh4RGlzcGxheSwgeERyYXdhYmxlLCBoYW5kbGUsIHgsIHksIHdpZHRoIC0gMSwgaGVpZ2h0IC0gMSk7Ci0JT1MuWFNldEZvcmVncm91bmQgKHhEaXNwbGF5LCBoYW5kbGUsIHZhbHVlcy5mb3JlZ3JvdW5kKTsKLQkqLwotCS8vU3lzdGVtLm91dC5wcmludGxuKCJHQy5kcmF3Rm9jdXMiKTsKKwkvL05PVCBET05FCisvLwlkcmF3UmVjdGFuZ2xlICh4LCB5LCB3aWR0aCAtIDEsIGhlaWdodCAtIDEpOwogfQorCiAvKioKICAqIERyYXdzIHRoZSBnaXZlbiBpbWFnZSBpbiB0aGUgcmVjZWl2ZXIgYXQgdGhlIHNwZWNpZmllZAogICogY29vcmRpbmF0ZXMuCkBAIC0yOTcsNiArMzU5LDcgQEAKIAlpZiAoaW1hZ2UuaXNEaXNwb3NlZCgpKSBTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwogCWRyYXdJbWFnZShpbWFnZSwgMCwgMCwgLTEsIC0xLCB4LCB5LCAtMSwgLTEsIHRydWUpOwogfQorCiAvKioKICAqIENvcGllcyBhIHJlY3Rhbmd1bGFyIGFyZWEgZnJvbSB0aGUgc291cmNlIGltYWdlIGludG8gYSAocG90ZW50aWFsbHkKICAqIGRpZmZlcmVudCBzaXplZCkgcmVjdGFuZ3VsYXIgYXJlYSBpbiB0aGUgcmVjZWl2ZXIuIElmIHRoZSBzb3VyY2UKQEAgLTMzOSw3MSArNDAyLDUyIEBACiAJaWYgKGltYWdlLmlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKIAlkcmF3SW1hZ2UoaW1hZ2UsIHNyY1gsIHNyY1ksIHNyY1dpZHRoLCBzcmNIZWlnaHQsIGRlc3RYLCBkZXN0WSwgZGVzdFdpZHRoLCBkZXN0SGVpZ2h0LCBmYWxzZSk7CiB9Ci12b2lkIGRyYXdJbWFnZShJbWFnZSBzcmNJbWFnZSwgaW50IHNyY1gsIGludCBzcmNZLCBpbnQgc3JjV2lkdGgsIGludCBzcmNIZWlnaHQsIGludCBkZXN0WCwgaW50IGRlc3RZLCBpbnQgZGVzdFdpZHRoLCBpbnQgZGVzdEhlaWdodCwgYm9vbGVhbiBzaW1wbGUpIHsKLQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQlPUy5HZXRQaXhCb3VuZHMoc3JjSW1hZ2UucGl4bWFwLCBib3VuZHMuZ2V0RGF0YSgpKTsKLSAJaW50IGltZ1dpZHRoID0gYm91bmRzLmdldFdpZHRoKCk7Ci0gCWludCBpbWdIZWlnaHQgPSBib3VuZHMuZ2V0SGVpZ2h0KCk7CiAKK3ZvaWQgZHJhd0ltYWdlKEltYWdlIHNyY0ltYWdlLCBpbnQgc3JjWCwgaW50IHNyY1ksIGludCBzcmNXaWR0aCwgaW50IHNyY0hlaWdodCwgaW50IGRlc3RYLCBpbnQgZGVzdFksIGludCBkZXN0V2lkdGgsIGludCBkZXN0SGVpZ2h0LCBib29sZWFuIHNpbXBsZSkgeworIAlpbnQgaW1hZ2VIYW5kbGUgPSBzcmNJbWFnZS5oYW5kbGU7CisgCWludCBpbWdXaWR0aCA9IE9TLkNHSW1hZ2VHZXRXaWR0aChpbWFnZUhhbmRsZSk7CisgCWludCBpbWdIZWlnaHQgPSBPUy5DR0ltYWdlR2V0SGVpZ2h0KGltYWdlSGFuZGxlKTsKICAJaWYgKHNpbXBsZSkgewogIAkJc3JjV2lkdGggPSBkZXN0V2lkdGggPSBpbWdXaWR0aDsKICAJCXNyY0hlaWdodCA9IGRlc3RIZWlnaHQgPSBpbWdIZWlnaHQ7CiAgCX0gZWxzZSB7CisgCQlzaW1wbGUgPSBzcmNYID09IDAgJiYgc3JjWSA9PSAwICYmCisgCQkJc3JjV2lkdGggPT0gZGVzdFdpZHRoICYmIGRlc3RXaWR0aCA9PSBpbWdXaWR0aCAmJgorIAkJCXNyY0hlaWdodCA9PSBkZXN0SGVpZ2h0ICYmIGRlc3RIZWlnaHQgPT0gaW1nSGVpZ2h0OwogCQlpZiAoc3JjWCArIHNyY1dpZHRoID4gaW1nV2lkdGggfHwgc3JjWSArIHNyY0hlaWdodCA+IGltZ0hlaWdodCkgewogCQkJU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKIAkJfQogIAl9Ci0KLQlpZiAoc3JjSW1hZ2UuYWxwaGEgPT0gMCkJLy8gZnVsbHkgdHJhbnNwYXJlbnQKLQkJcmV0dXJuOwotCi0JaWYgKHNyY0ltYWdlLnBpeG1hcCA9PSAwKQotCQlyZXR1cm47Ci0JaW50IHNyY0JpdHM9IE9TLkRlcmVmSGFuZGxlKHNyY0ltYWdlLnBpeG1hcCk7Ci0JaWYgKHNyY0JpdHMgPT0gMCkKLQkJcmV0dXJuOwotCWludCBkZXN0Qml0cz0gT1MuR2V0UG9ydEJpdE1hcEZvckNvcHlCaXRzKGhhbmRsZSk7Ci0JaWYgKGRlc3RCaXRzID09IDApCi0JCXJldHVybjsKLQotIAl0cnkgewotCQlpZiAoZm9jdXModHJ1ZSwgbnVsbCkpIHsKLQkKLQkJCU1hY1JlY3QgaWI9IG5ldyBNYWNSZWN0KHNyY1gsIHNyY1ksIHNyY1dpZHRoLCBzcmNIZWlnaHQpOwotCQkJZlJlY3Quc2V0KGRlc3RYLCBkZXN0WSwgZGVzdFdpZHRoLCBkZXN0SGVpZ2h0KTsKLQkJCi0JCQlPUy5SR0JCYWNrQ29sb3IoKHNob3J0KTB4RkZGRiwgKHNob3J0KTB4RkZGRiwgKHNob3J0KTB4RkZGRik7Ci0JCQlPUy5SR0JGb3JlQ29sb3IoKHNob3J0KTB4MDAwMCwgKHNob3J0KTB4MDAwMCwgKHNob3J0KTB4MDAwMCk7Ci0KLQkJCWlmIChzcmNJbWFnZS5hbHBoYSAhPSAtMSB8fCBzcmNJbWFnZS5hbHBoYURhdGEgIT0gbnVsbCkgewotCQkJCQotCQkJCWlmIChzcmNJbWFnZS5hbHBoYSA9PSAyNTUpIHsJLy8gZnVsbHkgb3BhcXVlCi0JCQkJCU9TLkNvcHlCaXRzKHNyY0JpdHMsIGRlc3RCaXRzLCBpYi5nZXREYXRhKCksIGZSZWN0LmdldERhdGEoKSwgKHNob3J0KTAsIDApOwotCQkJCQlyZXR1cm47Ci0JCQkJfQotCQkJCQotCQkJCS8vT1MuQ29weURlZXBNYXNrKHNyY0JpdHMsIG1hc2tCaXRzLCBkZXN0Qml0cywgaWIuZ2V0RGF0YSgpLCBpYi5nZXREYXRhKCksIGZSZWN0LmdldERhdGEoKSwgKHNob3J0KTAsIDApOwotCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiR0MuZHJhd0ltYWdlOiBhbHBoYSBkcmF3aW5nIG5vdCBueWkiKTsKLQotCQkJfSBlbHNlIGlmIChzcmNJbWFnZS50cmFuc3BhcmVudFBpeGVsICE9IC0xIHx8IHNyY0ltYWdlLm1hc2sgIT0gMCkgewotCQkJCS8qIEdlbmVyYXRlIHRoZSBtYXNrIGlmIG5lY2Vzc2FyeS4gKi8KLQkJCQlpZiAoc3JjSW1hZ2UudHJhbnNwYXJlbnRQaXhlbCAhPSAtMSkgc3JjSW1hZ2UuY3JlYXRlTWFzaygpOwotCQotCQkJCWludCBtYXNrQml0cz0gc3JjSW1hZ2UubWFzayAhPSAwID8gT1MuRGVyZWZIYW5kbGUoc3JjSW1hZ2UubWFzaykgOiAwOwotCQkJCWlmIChtYXNrQml0cyAhPSAwKQotCQkJCQlPUy5Db3B5TWFzayhzcmNCaXRzLCBtYXNrQml0cywgZGVzdEJpdHMsIGliLmdldERhdGEoKSwgaWIuZ2V0RGF0YSgpLCBmUmVjdC5nZXREYXRhKCkpOwotCi0JCQkJLyogRGVzdHJveSB0aGUgaW1hZ2UgbWFzayBpZiB0aGVyZSBpcyBhIEdDIGNyZWF0ZWQgb24gdGhlIGltYWdlICovCi0JCQkJaWYgKHNyY0ltYWdlLnRyYW5zcGFyZW50UGl4ZWwgIT0gLTEgJiYgc3JjSW1hZ2UubWVtR0MgIT0gbnVsbCkgc3JjSW1hZ2UuZGVzdHJveU1hc2soKTsKLQotCQkJfSBlbHNlIHsKLQkJCQlPUy5Db3B5Qml0cyhzcmNCaXRzLCBkZXN0Qml0cywgaWIuZ2V0RGF0YSgpLCBmUmVjdC5nZXREYXRhKCksIChzaG9ydCkwLCAwKTsKLQkJCX0KLQkJfQotCX0gZmluYWxseSB7Ci0JCXVuZm9jdXModHJ1ZSk7Ci0JfQorIAlPUy5DR0NvbnRleHRTYXZlR1N0YXRlKGhhbmRsZSk7CisgCU9TLkNHQ29udGV4dFNjYWxlQ1RNKGhhbmRsZSwgMSwgLTEpOworIAlPUy5DR0NvbnRleHRUcmFuc2xhdGVDVE0oaGFuZGxlLCAwLCAtKGRlc3RIZWlnaHQgKyAyICogZGVzdFkpKTsKKyAJQ0dSZWN0IHJlY3QgPSBuZXcgQ0dSZWN0KCk7CisgCXJlY3QueCA9IGRlc3RYOworIAlyZWN0LnkgPSBkZXN0WTsKKyAJcmVjdC53aWR0aCA9IGRlc3RXaWR0aDsKKwlyZWN0LmhlaWdodCA9IGRlc3RIZWlnaHQ7CisgCWlmIChzaW1wbGUpIHsKKyAJCU9TLkNHQ29udGV4dERyYXdJbWFnZShoYW5kbGUsIHJlY3QsIGltYWdlSGFuZGxlKTsKKyAJfSBlbHNlIHsKKwkgCWludCB3aWR0aCA9IE9TLkNHSW1hZ2VHZXRXaWR0aChpbWFnZUhhbmRsZSk7CisJCWludCBoZWlnaHQgPSBPUy5DR0ltYWdlR2V0SGVpZ2h0KGltYWdlSGFuZGxlKTsKKwkJaW50IGJwYyA9IE9TLkNHSW1hZ2VHZXRCaXRzUGVyQ29tcG9uZW50KGltYWdlSGFuZGxlKTsKKwkJaW50IGJwcCA9IE9TLkNHSW1hZ2VHZXRCaXRzUGVyUGl4ZWwoaW1hZ2VIYW5kbGUpOworCQlpbnQgYnByID0gT1MuQ0dJbWFnZUdldEJ5dGVzUGVyUm93KGltYWdlSGFuZGxlKTsKKwkJaW50IGNvbG9yc3BhY2UgPSBPUy5DR0ltYWdlR2V0Q29sb3JTcGFjZShpbWFnZUhhbmRsZSk7CisJCWludCBhbHBoYUluZm8gPSBPUy5DR0ltYWdlR2V0QWxwaGFJbmZvKGltYWdlSGFuZGxlKTsKKwkJaW50IGRhdGEgPSBzcmNJbWFnZS5kYXRhICsgKHNyY1kgKiBicHIpICsgc3JjWCAqIDQ7CisJCWludCBwcm92aWRlciA9IE9TLkNHRGF0YVByb3ZpZGVyQ3JlYXRlV2l0aERhdGEoMCwgZGF0YSwgc3JjSGVpZ2h0ICogYnByLCAwKTsKKwkJaWYgKHByb3ZpZGVyID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7CisJCWludCBzdWJJbWFnZSA9IE9TLkNHSW1hZ2VDcmVhdGUoc3JjV2lkdGgsIHNyY0hlaWdodCwgYnBjLCBicHAsIGJwciwgY29sb3JzcGFjZSwgYWxwaGFJbmZvLCBwcm92aWRlciwgbnVsbCwgZmFsc2UsIDApOworCQlPUy5DR0RhdGFQcm92aWRlclJlbGVhc2UocHJvdmlkZXIpOworCQlpZiAoc3ViSW1hZ2UgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKyAJCU9TLkNHQ29udGV4dERyYXdJbWFnZShoYW5kbGUsIHJlY3QsIHN1YkltYWdlKTsKKyAJCU9TLkNHSW1hZ2VSZWxlYXNlKHN1YkltYWdlKTsKKyAJfQorIAlPUy5DR0NvbnRleHRSZXN0b3JlR1N0YXRlKGhhbmRsZSk7CiB9CisKIC8qKiAKICAqIERyYXdzIGEgbGluZSwgdXNpbmcgdGhlIGZvcmVncm91bmQgY29sb3IsIGJldHdlZW4gdGhlIHBvaW50cyAKICAqICg8Y29kZT54MTwvY29kZT4sIDxjb2RlPnkxPC9jb2RlPikgYW5kICg8Y29kZT54MjwvY29kZT4sIDxjb2RlPnkyPC9jb2RlPikuCkBAIC00MTcsMTkgKzQ2MSwxNCBAQAogICogICAgPGxpPkVSUk9SX0dSQVBISUNfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgogICogPC91bD4KICAqLwotcHVibGljIHZvaWQgZHJhd0xpbmUgKGludCB4MSwgaW50IHkxLCBpbnQgeDIsIGludCB5MikgeworcHVibGljIHZvaWQgZHJhd0xpbmUoaW50IHgxLCBpbnQgeTEsIGludCB4MiwgaW50IHkyKSB7CiAJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwotCXRyeSB7Ci0JCWlmIChmb2N1cyh0cnVlLCBudWxsKSkgewotCQkJTWFjVXRpbC5SR0JGb3JlQ29sb3IoZGF0YS5mb3JlZ3JvdW5kKTsKLQkJCU9TLlBlblNpemUoKHNob3J0KSBmTGluZVdpZHRoLCAoc2hvcnQpIGZMaW5lV2lkdGgpOwotCQkJT1MuTW92ZVRvKChzaG9ydCl4MSwgKHNob3J0KXkxKTsKLQkJCU9TLkxpbmVUbygoc2hvcnQpeDIsIChzaG9ydCl5Mik7Ci0JCX0KLQl9IGZpbmFsbHkgewotCQl1bmZvY3VzKHRydWUpOwotCX0KKwlPUy5DR0NvbnRleHRCZWdpblBhdGgoaGFuZGxlKTsKKwlPUy5DR0NvbnRleHRNb3ZlVG9Qb2ludChoYW5kbGUsIHgxLCB5MSk7CisJT1MuQ0dDb250ZXh0QWRkTGluZVRvUG9pbnQoaGFuZGxlLCB4MiwgeTIpOworCU9TLkNHQ29udGV4dFN0cm9rZVBhdGgoaGFuZGxlKTsKIH0KKwogLyoqIAogICogRHJhd3MgdGhlIG91dGxpbmUgb2YgYW4gb3ZhbCwgdXNpbmcgdGhlIGZvcmVncm91bmQgY29sb3IsCiAgKiB3aXRoaW4gdGhlIHNwZWNpZmllZCByZWN0YW5ndWxhciBhcmVhLgpAQCAtNDYxLDE3ICs1MDAsMTYgQEAKIAkJeSA9IHkgKyBoZWlnaHQ7CiAJCWhlaWdodCA9IC1oZWlnaHQ7CiAJfQotCXRyeSB7Ci0JCWlmIChmb2N1cyh0cnVlLCBudWxsKSkgewotCQkJTWFjVXRpbC5SR0JGb3JlQ29sb3IoZGF0YS5mb3JlZ3JvdW5kKTsKLQkJCU9TLlBlblNpemUoKHNob3J0KSBmTGluZVdpZHRoLCAoc2hvcnQpIGZMaW5lV2lkdGgpOwotCQkJZlJlY3Quc2V0KHgsIHksIHdpZHRoKzEsIGhlaWdodCsxKTsKLQkJCU9TLkZyYW1lT3ZhbChmUmVjdC5nZXREYXRhKCkpOwotCQl9Ci0JfSBmaW5hbGx5IHsKLQkJdW5mb2N1cyh0cnVlKTsKLQl9CisJT1MuQ0dDb250ZXh0QmVnaW5QYXRoKGhhbmRsZSk7CisgICAgT1MuQ0dDb250ZXh0U2F2ZUdTdGF0ZShoYW5kbGUpOworICAgIE9TLkNHQ29udGV4dFRyYW5zbGF0ZUNUTShoYW5kbGUsIHggKyB3aWR0aCAvIDJmLCB5ICsgaGVpZ2h0IC8gMmYpOworICAgIE9TLkNHQ29udGV4dFNjYWxlQ1RNKGhhbmRsZSwgd2lkdGggLyAyZiwgaGVpZ2h0IC8gMmYpOworICAgIE9TLkNHQ29udGV4dE1vdmVUb1BvaW50KGhhbmRsZSwgMSwgMCk7CisgICAgT1MuQ0dDb250ZXh0QWRkQXJjKGhhbmRsZSwgMCwgMCwgMSwgMCwgKGZsb2F0KSgyICpNYXRoLlBJKSwgdHJ1ZSk7CisgICAgT1MuQ0dDb250ZXh0UmVzdG9yZUdTdGF0ZShoYW5kbGUpOworCU9TLkNHQ29udGV4dFN0cm9rZVBhdGgoaGFuZGxlKTsKIH0KKwogLyoqIAogICogRHJhd3MgdGhlIGNsb3NlZCBwb2x5Z29uIHdoaWNoIGlzIGRlZmluZWQgYnkgdGhlIHNwZWNpZmllZCBhcnJheQogICogb2YgaW50ZWdlciBjb29yZGluYXRlcywgdXNpbmcgdGhlIHJlY2VpdmVyJ3MgZm9yZWdyb3VuZCBjb2xvci4gVGhlIGFycmF5IApAQCAtNDkyLDQ1ICs1MzAsMTYgQEAKIHB1YmxpYyB2b2lkIGRyYXdQb2x5Z29uKGludFtdIHBvaW50QXJyYXkpIHsKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7CiAJaWYgKHBvaW50QXJyYXkgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQkKLQkvLyBNb3RpZiBkb2VzIG5vdCBoYXZlIGEgbmF0aXZlIGRyYXdQb2x5Z29uKCkgY2FsbC4gSW5zdGVhZCB3ZSBlbnN1cmUgCi0JLy8gdGhhdCB0aGUgZmlyc3QgYW5kIGxhc3QgcG9pbnRzIGFyZSB0aGUgc2FtZSBhbmQgY2FsbCBkcmF3UG9seWxpbmUoKS4KLQkKLQlpbnQgbGVuZ3RoID0gcG9pbnRBcnJheS5sZW5ndGg7Ci0KLQkvLyBOZWVkIGF0IGxlYXN0IDMgcG9pbnRzIHRvIGRlZmluZSB0aGUgcG9seWdvbi4gSWYgMiBvciBmZXdlciBwb2ludHMKLQkvLyBwYXNzZWQgaW4sIGl0IGlzIGVpdGhlciBhIGxpbmUgb3IgcG9pbnQgc28ganVzdCBjYWxsIGRyYXdQb2x5bGluZSgpLgotCS8vIENoZWNrIHdoYXQgaGFwcGVucyB3aGVuIFhPUiBpcyBpbXBsZW1lbnRlZC4gV2UgbWF5IG5vdCBiZSBhYmxlIHRvCi0JLy8gZG8gdGhpcyBvcHRpbWl6YXRpb24uCi0JCi0JaWYgKGxlbmd0aCA8IDQpIHsKLQkJCWRyYXdQb2x5bGluZShwb2ludEFycmF5KTsKLQkJCXJldHVybjsKKwlmbG9hdFtdIHBvaW50cyA9IG5ldyBmbG9hdFtwb2ludEFycmF5Lmxlbmd0aF07CisJZm9yIChpbnQgaT0wOyBpPHBvaW50cy5sZW5ndGg7IGkrKykgeworCQlwb2ludHNbaV0gPSBwb2ludEFycmF5W2ldOwogCX0KLQotCS8vIElmIGZpcnN0IGFuZCBsYXN0IHBvaW50cyBhcmUgdGhlIHNhbWUsIHRoZSBwb2x5Z29uIGlzIGFscmVhZHkgY2xvc2VkLgotCS8vIEp1c3QgY2FsbCBkcmF3UG9seWxpbmUoKS4KLQkvLwotCS8vIENoZWNrIHdoYXQgaGFwcGVucyB3aGVuIFhPUiBpcyBpbXBsZW1lbnRlZC4gV2UgbWF5IG5vdCBiZSBhYmxlIHRvCi0JLy8gZG8gdGhpcyBvcHRpbWl6YXRpb24uCi0JCi0JaWYgKHBvaW50QXJyYXlbMF0gPT0gcG9pbnRBcnJheVtsZW5ndGggLSAyXSAmJiAocG9pbnRBcnJheVsxXSA9PSBwb2ludEFycmF5W2xlbmd0aCAtIDFdKSkgewotCQlkcmF3UG9seWxpbmUocG9pbnRBcnJheSk7Ci0JCXJldHVybjsKLQl9Ci0KLQkvLyBHcm93IHRoZSBsaXN0IG9mIHBvaW50cyBieSBvbmUgZWxlbWVudCBhbmQgbWFrZSBzdXJlIHRoZSBmaXJzdCBhbmQgbGFzdAotCS8vIHBvaW50cyBhcmUgdGhlIHNhbWUuIFRoaXMgd2lsbCBjbG9zZSB0aGUgcG9seWdvbiBhbmQgd2UgY2FuIHVzZSB0aGUKLQkvLyBkcmF3UG9seWxpbmUoKSBjYWxsLiAKLQkJCi0JaW50IG5ld1BvaW50c1tdID0gbmV3IGludFtsZW5ndGggKyAyXTsKLQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aCA7IGkrKykgCi0JCW5ld1BvaW50c1tpXSA9IHBvaW50QXJyYXlbaV07Ci0JbmV3UG9pbnRzW2xlbmd0aF0gPSBwb2ludEFycmF5WzBdOwotCW5ld1BvaW50c1tsZW5ndGggKyAxXSA9IHBvaW50QXJyYXlbMV07Ci0KLQlkcmF3UG9seWxpbmUobmV3UG9pbnRzKTsKKwlPUy5DR0NvbnRleHRCZWdpblBhdGgoaGFuZGxlKTsKKwlPUy5DR0NvbnRleHRBZGRMaW5lcyhoYW5kbGUsIHBvaW50cywgcG9pbnRzLmxlbmd0aCAvIDIpOworCU9TLkNHQ29udGV4dENsb3NlUGF0aChoYW5kbGUpOworCU9TLkNHQ29udGV4dFN0cm9rZVBhdGgoaGFuZGxlKTsKIH0KKwogLyoqIAogICogRHJhd3MgdGhlIHBvbHlsaW5lIHdoaWNoIGlzIGRlZmluZWQgYnkgdGhlIHNwZWNpZmllZCBhcnJheQogICogb2YgaW50ZWdlciBjb29yZGluYXRlcywgdXNpbmcgdGhlIHJlY2VpdmVyJ3MgZm9yZWdyb3VuZCBjb2xvci4gVGhlIGFycmF5IApAQCAtNTUxLDM4ICs1NjAsMTUgQEAKIHB1YmxpYyB2b2lkIGRyYXdQb2x5bGluZShpbnRbXSBwb2ludEFycmF5KSB7CiAJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwogCWlmIChwb2ludEFycmF5ID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0JLyogQVcKLQlzaG9ydFtdIHhQb2ludHMgPSBuZXcgc2hvcnRbcG9pbnRBcnJheS5sZW5ndGhdOwotCWZvciAoaW50IGkgPSAwOyBpPHBvaW50QXJyYXkubGVuZ3RoO2krKykgewotCQl4UG9pbnRzW2ldID0gKHNob3J0KSBwb2ludEFycmF5W2ldOworCWZsb2F0W10gcG9pbnRzID0gbmV3IGZsb2F0W3BvaW50QXJyYXkubGVuZ3RoXTsKKwlmb3IgKGludCBpPTA7IGk8cG9pbnRzLmxlbmd0aDsgaSsrKSB7CisJCXBvaW50c1tpXSA9IHBvaW50QXJyYXlbaV07CiAJfQotCU9TLlhEcmF3TGluZXMoZGF0YS5kaXNwbGF5LGRhdGEuZHJhd2FibGUsaGFuZGxlLHhQb2ludHMseFBvaW50cy5sZW5ndGggLyAyLCBPUy5Db29yZE1vZGVPcmlnaW4pOwotCSovCi0JCi0JaWYgKHBvaW50QXJyYXkubGVuZ3RoIDwgNCkKLQkJcmV0dXJuOwotCQotCWludCBwb2x5PSAwOwotCXRyeSB7Ci0JCWlmIChmb2N1cyh0cnVlLCBudWxsKSkgewotCQkKLQkJCXBvbHk9IE9TLk9wZW5Qb2x5KCk7Ci0JCQlPUy5Nb3ZlVG8oKHNob3J0KXBvaW50QXJyYXlbMF0sIChzaG9ydClwb2ludEFycmF5WzFdKTsKLQkJCWZvciAoaW50IGk9IDI7IGkgPCBwb2ludEFycmF5Lmxlbmd0aDsgaSs9IDIpCi0JCQkJT1MuTGluZVRvKChzaG9ydClwb2ludEFycmF5W2ldLCAoc2hvcnQpcG9pbnRBcnJheVtpKzFdKTsKLQkJCU9TLkNsb3NlUG9seSgpOwotCQkJCi0JCQlNYWNVdGlsLlJHQkZvcmVDb2xvcihkYXRhLmZvcmVncm91bmQpOwotCQkJT1MuUGVuU2l6ZSgoc2hvcnQpIGZMaW5lV2lkdGgsIChzaG9ydCkgZkxpbmVXaWR0aCk7Ci0JCQlPUy5GcmFtZVBvbHkocG9seSk7Ci0JCX0KLQl9IGZpbmFsbHkgewotCQl1bmZvY3VzKHRydWUpOwotCX0KLQkKLQlpZiAocG9seSAhPSAwKQotCQlPUy5LaWxsUG9seShwb2x5KTsKKwlPUy5DR0NvbnRleHRCZWdpblBhdGgoaGFuZGxlKTsKKwlPUy5DR0NvbnRleHRBZGRMaW5lcyhoYW5kbGUsIHBvaW50cywgcG9pbnRzLmxlbmd0aCAvIDIpOworCU9TLkNHQ29udGV4dFN0cm9rZVBhdGgoaGFuZGxlKTsKIH0KKwogLyoqIAogICogRHJhd3MgdGhlIG91dGxpbmUgb2YgdGhlIHJlY3RhbmdsZSBzcGVjaWZpZWQgYnkgdGhlIGFyZ3VtZW50cywKICAqIHVzaW5nIHRoZSByZWNlaXZlcidzIGZvcmVncm91bmQgY29sb3IuIFRoZSBsZWZ0IGFuZCByaWdodCBlZGdlcwpAQCAtNTk4LDcgKzU4NCw3IEBACiAgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgdm9pZCBkcmF3UmVjdGFuZ2xlIChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworcHVibGljIHZvaWQgZHJhd1JlY3RhbmdsZShpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgewogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKIAlpZiAod2lkdGggPCAwKSB7CiAJCXggPSB4ICsgd2lkdGg7CkBAIC02MDgsMTcgKzU5NCwxNCBAQAogCQl5ID0geSArIGhlaWdodDsKIAkJaGVpZ2h0ID0gLWhlaWdodDsKIAl9Ci0JdHJ5IHsKLQkJaWYgKGZvY3VzKHRydWUsIG51bGwpKSB7Ci0JCQlNYWNVdGlsLlJHQkZvcmVDb2xvcihkYXRhLmZvcmVncm91bmQpOwotCQkJT1MuUGVuU2l6ZSgoc2hvcnQpIGZMaW5lV2lkdGgsIChzaG9ydCkgZkxpbmVXaWR0aCk7Ci0JCQlmUmVjdC5zZXQoeC1mTGluZVdpZHRoLzIsIHktZkxpbmVXaWR0aC8yLCB3aWR0aCtmTGluZVdpZHRoLCBoZWlnaHQrZkxpbmVXaWR0aCk7Ci0JCQlPUy5GcmFtZVJlY3QoZlJlY3QuZ2V0RGF0YSgpKTsKLQkJfQotCX0gZmluYWxseSB7Ci0JCXVuZm9jdXModHJ1ZSk7Ci0JfQorCUNHUmVjdCByZWN0ID0gbmV3IENHUmVjdCgpOworCXJlY3QueCA9IHg7CisJcmVjdC55ID0geTsKKwlyZWN0LndpZHRoID0gd2lkdGg7CisJcmVjdC5oZWlnaHQgPSBoZWlnaHQ7CisJT1MuQ0dDb250ZXh0U3Ryb2tlUmVjdChoYW5kbGUsIHJlY3QpOwogfQorCiAvKiogCiAgKiBEcmF3cyB0aGUgb3V0bGluZSBvZiB0aGUgc3BlY2lmaWVkIHJlY3RhbmdsZSwgdXNpbmcgdGhlIHJlY2VpdmVyJ3MKICAqIGZvcmVncm91bmQgY29sb3IuIFRoZSBsZWZ0IGFuZCByaWdodCBlZGdlcyBvZiB0aGUgcmVjdGFuZ2xlIGFyZSBhdApAQCAtNjM1LDEwICs2MTgsMTEgQEAKICAqICAgIDxsaT5FUlJPUl9HUkFQSElDX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KICAqIDwvdWw+CiAgKi8KLXB1YmxpYyB2b2lkIGRyYXdSZWN0YW5nbGUgKFJlY3RhbmdsZSByZWN0KSB7CitwdWJsaWMgdm9pZCBkcmF3UmVjdGFuZ2xlKFJlY3RhbmdsZSByZWN0KSB7CiAJaWYgKHJlY3QgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlkcmF3UmVjdGFuZ2xlIChyZWN0LngsIHJlY3QueSwgcmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpOwogfQorCiAvKiogCiAgKiBEcmF3cyB0aGUgb3V0bGluZSBvZiB0aGUgcm91bmQtY29ybmVyZWQgcmVjdGFuZ2xlIHNwZWNpZmllZCBieSAKICAqIHRoZSBhcmd1bWVudHMsIHVzaW5nIHRoZSByZWNlaXZlcidzIGZvcmVncm91bmQgY29sb3IuIFRoZSBsZWZ0IGFuZApAQCAtNjU4LDI3ICs2NDIsMjggQEAKICAqICAgIDxsaT5FUlJPUl9HUkFQSElDX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KICAqIDwvdWw+CiAgKi8KLXB1YmxpYyB2b2lkIGRyYXdSb3VuZFJlY3RhbmdsZSAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBhcmNXaWR0aCwgaW50IGFyY0hlaWdodCkgeworcHVibGljIHZvaWQgZHJhd1JvdW5kUmVjdGFuZ2xlKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgYXJjV2lkdGgsIGludCBhcmNIZWlnaHQpIHsKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JaWYgKHdpZHRoIDwgMCkgewotCQl4ID0geCArIHdpZHRoOwotCQl3aWR0aCA9IC13aWR0aDsKKwlpZiAoYXJjV2lkdGggPT0gMCB8fCBhcmNIZWlnaHQgPT0gMCkgeworCQlkcmF3UmVjdGFuZ2xlKHgsIHksIHdpZHRoLCBoZWlnaHQpOworICAgIAlyZXR1cm47CiAJfQotCWlmIChoZWlnaHQgPCAwKSB7Ci0JCXkgPSB5ICsgaGVpZ2h0OwotCQloZWlnaHQgPSAtaGVpZ2h0OwotCX0KLQl0cnkgewotCQlpZiAoZm9jdXModHJ1ZSwgbnVsbCkpIHsKLQkJCU1hY1V0aWwuUkdCRm9yZUNvbG9yKGRhdGEuZm9yZWdyb3VuZCk7Ci0JCQlPUy5QZW5TaXplKChzaG9ydCkgZkxpbmVXaWR0aCwgKHNob3J0KSBmTGluZVdpZHRoKTsKLQkJCWZSZWN0LnNldCh4LCB5LCB3aWR0aCsxLCBoZWlnaHQrMSk7Ci0JCQlPUy5GcmFtZVJvdW5kUmVjdChmUmVjdC5nZXREYXRhKCksIChzaG9ydClhcmNXaWR0aCwgKHNob3J0KWFyY0hlaWdodCk7Ci0JCX0KLQl9IGZpbmFsbHkgewotCQl1bmZvY3VzKHRydWUpOwotCX0KKwlPUy5DR0NvbnRleHRCZWdpblBhdGgoaGFuZGxlKTsKKwlPUy5DR0NvbnRleHRTYXZlR1N0YXRlKGhhbmRsZSk7CisJT1MuQ0dDb250ZXh0VHJhbnNsYXRlQ1RNKGhhbmRsZSwgeCwgeSk7CisJT1MuQ0dDb250ZXh0U2NhbGVDVE0oaGFuZGxlLCBhcmNXaWR0aCwgYXJjSGVpZ2h0KTsKKyAgICBmbG9hdCBmdyA9IHdpZHRoIC8gKGZsb2F0KWFyY1dpZHRoOworCWZsb2F0IGZoID0gaGVpZ2h0IC8gKGZsb2F0KWFyY0hlaWdodDsKKwlPUy5DR0NvbnRleHRNb3ZlVG9Qb2ludChoYW5kbGUsIGZ3LCBmaC8yKTsKKwlPUy5DR0NvbnRleHRBZGRBcmNUb1BvaW50KGhhbmRsZSwgZncsIGZoLCBmdy8yLCBmaCwgMSk7CisJT1MuQ0dDb250ZXh0QWRkQXJjVG9Qb2ludChoYW5kbGUsIDAsIGZoLCAwLCBmaC8yLCAxKTsKKwlPUy5DR0NvbnRleHRBZGRBcmNUb1BvaW50KGhhbmRsZSwgMCwgMCwgZncvMiwgMCwgMSk7CisJT1MuQ0dDb250ZXh0QWRkQXJjVG9Qb2ludChoYW5kbGUsIGZ3LCAwLCBmdywgZmgvMiwgMSk7CisJT1MuQ0dDb250ZXh0Q2xvc2VQYXRoKGhhbmRsZSk7CisJT1MuQ0dDb250ZXh0UmVzdG9yZUdTdGF0ZShoYW5kbGUpOworCU9TLkNHQ29udGV4dFN0cm9rZVBhdGgoaGFuZGxlKTsKIH0KKwogLyoqIAogICogRHJhd3MgdGhlIGdpdmVuIHN0cmluZywgdXNpbmcgdGhlIHJlY2VpdmVyJ3MgY3VycmVudCBmb250IGFuZAogICogZm9yZWdyb3VuZCBjb2xvci4gTm8gdGFiIGV4cGFuc2lvbiBvciBjYXJyaWFnZSByZXR1cm4gcHJvY2Vzc2luZwpAQCAtNzAwLDYgKzY4NSw3IEBACiBwdWJsaWMgdm9pZCBkcmF3U3RyaW5nIChTdHJpbmcgc3RyaW5nLCBpbnQgeCwgaW50IHkpIHsKIAlkcmF3U3RyaW5nKHN0cmluZywgeCwgeSwgZmFsc2UpOwogfQorCiAvKiogCiAgKiBEcmF3cyB0aGUgZ2l2ZW4gc3RyaW5nLCB1c2luZyB0aGUgcmVjZWl2ZXIncyBjdXJyZW50IGZvbnQgYW5kCiAgKiBmb3JlZ3JvdW5kIGNvbG9yLiBObyB0YWIgZXhwYW5zaW9uIG9yIGNhcnJpYWdlIHJldHVybiBwcm9jZXNzaW5nCkBAIC03MjAsNDQgKzcwNiwyNiBAQAogICogICAgPGxpPkVSUk9SX0dSQVBISUNfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgogICogPC91bD4KICAqLwotcHVibGljIHZvaWQgZHJhd1N0cmluZyAoU3RyaW5nIHN0cmluZywgaW50IHgsIGludCB5LCBib29sZWFuIGlzVHJhbnNwYXJlbnQpIHsKK3B1YmxpYyB2b2lkIGRyYXdTdHJpbmcoU3RyaW5nIHN0cmluZywgaW50IHgsIGludCB5LCBib29sZWFuIGlzVHJhbnNwYXJlbnQpIHsKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7CiAJaWYgKHN0cmluZyA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCS8qIEFXCi0JYnl0ZSBbXSBidWZmZXIgPSBDb252ZXJ0ZXIud2NzVG9NYmNzIChnZXRDb2RlUGFnZSAoKSwgc3RyaW5nLCB0cnVlKTsKLQlpbnQgeG1TdHJpbmcgPSBPUy5YbVN0cmluZ0NyZWF0ZSAoYnVmZmVyLCBPUy5YbUZPTlRMSVNUX0RFRkFVTFRfVEFHKTsKLQlpZiAoaXNUcmFuc3BhcmVudCkgewotCQlPUy5YbVN0cmluZ0RyYXcgKGRhdGEuZGlzcGxheSwgZGF0YS5kcmF3YWJsZSwgZGF0YS5mb250TGlzdCwgeG1TdHJpbmcsIGhhbmRsZSwgeCwgeSwgMHg3RkZGRkZGRiwgT1MuWG1BTElHTk1FTlRfQkVHSU5OSU5HLCAwLCBudWxsKTsKLQl9IGVsc2UgewotCQlPUy5YbVN0cmluZ0RyYXdJbWFnZSAoZGF0YS5kaXNwbGF5LCBkYXRhLmRyYXdhYmxlLCBkYXRhLmZvbnRMaXN0LCB4bVN0cmluZywgaGFuZGxlLCB4LCB5LCAweDdGRkZGRkZGLCBPUy5YbUFMSUdOTUVOVF9CRUdJTk5JTkcsIDAsIG51bGwpOwotCX0JCQkKLS8vCU9TLlhtU3RyaW5nRHJhd1VuZGVybGluZSAoZGlzcGxheSwgZHJhd2FibGUsIGZvbnRMaXN0LCB4bVN0cmluZywgaGFuZGxlLCB4LCB5LCAweDdGRkZGRkZGLCBPUy5YbUFMSUdOTUVOVF9CRUdJTk5JTkcsIDAsIG51bGwsIDApOwotCU9TLlhtU3RyaW5nRnJlZSAoeG1TdHJpbmcpOwotCSovCi0JdHJ5IHsKLQkJaWYgKGZvY3VzKHRydWUsIG51bGwpKSB7Ci0JCQlpbnN0YWxsRm9udCgpOwotCQkJTWFjVXRpbC5SR0JGb3JlQ29sb3IoZGF0YS5mb3JlZ3JvdW5kKTsKLQkJCWlmIChpc1RyYW5zcGFyZW50KSB7Ci0JCQkJT1MuVGV4dE1vZGUoT1Muc3JjT3IpOwotCQkJfSBlbHNlIHsKLQkJCQlpZiAoKGRhdGEuYmFja2dyb3VuZCAmIDB4ZmYwMDAwMDApID09IDApIHsKLQkJCQkJTWFjVXRpbC5SR0JCYWNrQ29sb3IoZGF0YS5iYWNrZ3JvdW5kKTsKLQkJCQkJT1MuVGV4dE1vZGUoT1Muc3JjQ29weSk7Ci0JCQkJfSBlbHNlIHsKLQkJCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIkdDLmRyYXdTdHJpbmc6ICIgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKGRhdGEuYmFja2dyb3VuZCkpOwotCQkJCQlPUy5UZXh0TW9kZShPUy5zcmNPcik7Ci0JCQkJfQotCQkJfQotCQkJc2hvcnRbXSBmb250SW5mbz0gbmV3IHNob3J0WzRdOwotCQkJT1MuR2V0Rm9udEluZm8oZm9udEluZm8pOwkvLyBGb250SW5mbwotCQkJT1MuTW92ZVRvKChzaG9ydCl4LCAoc2hvcnQpKHkrZm9udEluZm9bMF0pKTsKLQkJCU9TLkRyYXdUZXh0KHN0cmluZywgZGF0YS5mb250LmZJRCwgZGF0YS5mb250LmZTaXplLCBkYXRhLmZvbnQuZkZhY2UpOwotCQl9Ci0JfSBmaW5hbGx5IHsKLQkJdW5mb2N1cyh0cnVlKTsKLQl9CisJaW50IGxlbmd0aCA9IHN0cmluZy5sZW5ndGgoKTsKKwlpZiAobGVuZ3RoID09IDApIHJldHVybjsKKwlPUy5DR0NvbnRleHRTYXZlR1N0YXRlKGhhbmRsZSk7CisJT1MuQ0dDb250ZXh0U2NhbGVDVE0oaGFuZGxlLCAxLCAtMSk7CisJT1MuQ0dDb250ZXh0VHJhbnNsYXRlQ1RNKGhhbmRsZSwgMCwgLWRhdGEuZm9udEFzY2VudCk7CisJT1MuQ0dDb250ZXh0U2V0RmlsbENvbG9yKGhhbmRsZSwgZGF0YS5mb3JlZ3JvdW5kKTsKKwljaGFyW10gYnVmZmVyID0gbmV3IGNoYXJbbGVuZ3RoXTsKKwlzdHJpbmcuZ2V0Q2hhcnMoMCwgbGVuZ3RoLCBidWZmZXIsIDApOworCWludCBwdHIgPSBPUy5OZXdQdHIobGVuZ3RoICogMik7CisJT1MubWVtY3B5KHB0ciwgYnVmZmVyLCBsZW5ndGggKiAyKTsKKwlPUy5BVFNVU2V0VGV4dFBvaW50ZXJMb2NhdGlvbihkYXRhLmxheW91dCwgcHRyLCAwLCBsZW5ndGgsIGxlbmd0aCk7CisJT1MuQVRTVVNldFJ1blN0eWxlKGRhdGEubGF5b3V0LCBkYXRhLnN0eWxlLCAwLCBsZW5ndGgpOworCU9TLkFUU1VEcmF3VGV4dChkYXRhLmxheW91dCwgMCwgbGVuZ3RoLCB4IDw8IDE2LCAteSA8PCAxNik7CisJT1MuRGlzcG9zZVB0cihwdHIpOworCU9TLkNHQ29udGV4dFJlc3RvcmVHU3RhdGUoaGFuZGxlKTsKIH0KKwogLyoqIAogICogRHJhd3MgdGhlIGdpdmVuIHN0cmluZywgdXNpbmcgdGhlIHJlY2VpdmVyJ3MgY3VycmVudCBmb250IGFuZAogICogZm9yZWdyb3VuZCBjb2xvci4gVGFiIGV4cGFuc2lvbiBhbmQgY2FycmlhZ2UgcmV0dXJuIHByb2Nlc3NpbmcKQEAgLTc3Niw5ICs3NDQsMTAgQEAKICAqICAgIDxsaT5FUlJPUl9HUkFQSElDX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KICAqIDwvdWw+CiAgKi8KLXB1YmxpYyB2b2lkIGRyYXdUZXh0IChTdHJpbmcgc3RyaW5nLCBpbnQgeCwgaW50IHkpIHsKK3B1YmxpYyB2b2lkIGRyYXdUZXh0KFN0cmluZyBzdHJpbmcsIGludCB4LCBpbnQgeSkgewogCWRyYXdUZXh0KHN0cmluZywgeCwgeSwgU1dULkRSQVdfREVMSU1JVEVSIHwgU1dULkRSQVdfVEFCKTsKIH0KKwogLyoqIAogICogRHJhd3MgdGhlIGdpdmVuIHN0cmluZywgdXNpbmcgdGhlIHJlY2VpdmVyJ3MgY3VycmVudCBmb250IGFuZAogICogZm9yZWdyb3VuZCBjb2xvci4gVGFiIGV4cGFuc2lvbiBhbmQgY2FycmlhZ2UgcmV0dXJuIHByb2Nlc3NpbmcKQEAgLTc5OSwxMSArNzY4LDEyIEBACiAgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgdm9pZCBkcmF3VGV4dCAoU3RyaW5nIHN0cmluZywgaW50IHgsIGludCB5LCBib29sZWFuIGlzVHJhbnNwYXJlbnQpIHsKK3B1YmxpYyB2b2lkIGRyYXdUZXh0KFN0cmluZyBzdHJpbmcsIGludCB4LCBpbnQgeSwgYm9vbGVhbiBpc1RyYW5zcGFyZW50KSB7CiAJaW50IGZsYWdzID0gU1dULkRSQVdfREVMSU1JVEVSIHwgU1dULkRSQVdfVEFCOwogCWlmIChpc1RyYW5zcGFyZW50KSBmbGFncyB8PSBTV1QuRFJBV19UUkFOU1BBUkVOVDsKIAlkcmF3VGV4dChzdHJpbmcsIHgsIHksIGZsYWdzKTsKIH0KKwogLyoqIAogICogRHJhd3MgdGhlIGdpdmVuIHN0cmluZywgdXNpbmcgdGhlIHJlY2VpdmVyJ3MgY3VycmVudCBmb250IGFuZAogICogZm9yZWdyb3VuZCBjb2xvci4gVGFiIGV4cGFuc2lvbiwgbGluZSBkZWxpbWl0ZXIgYW5kIG1uZW1vbmljCkBAIC04NDEsNjEgKzgxMSw4IEBACiBwdWJsaWMgdm9pZCBkcmF3VGV4dCAoU3RyaW5nIHN0cmluZywgaW50IHgsIGludCB5LCBpbnQgZmxhZ3MpIHsKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7CiAJaWYgKHN0cmluZyA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCQotCS8qIEFXCi0JaWYgKGRhdGEucmVuZGVyVGFibGUgPT0gMCkgY3JlYXRlUmVuZGVyVGFibGUoKTsKLQlpbnQgcmVuZGVyVGFibGUgPSBkYXRhLnJlbmRlclRhYmxlOwotCi0JY2hhciBtbmVtb25pYz0wOwotCWludCB0YWJsZUxlbmd0aCA9IDA7Ci0JRGV2aWNlIGRldmljZSA9IGRhdGEuZGV2aWNlOwotCWludFtdIHBhcnNlVGFibGUgPSBuZXcgaW50WzJdOwotCWNoYXJbXSB0ZXh0ID0gbmV3IGNoYXJbc3RyaW5nLmxlbmd0aCgpXTsKLQlzdHJpbmcuZ2V0Q2hhcnMoMCwgdGV4dC5sZW5ndGgsIHRleHQsIDApOwotCWlmICgoZmxhZ3MgJiBTV1QuRFJBV19ERUxJTUlURVIpICE9IDApIHBhcnNlVGFibGVbdGFibGVMZW5ndGgrK10gPSBkZXZpY2UuY3JNYXBwaW5nOwotCWlmICgoZmxhZ3MgJiBTV1QuRFJBV19UQUIpICE9IDApIHBhcnNlVGFibGVbdGFibGVMZW5ndGgrK10gPSBkZXZpY2UudGFiTWFwcGluZzsKLQlpZiAoKGZsYWdzICYgU1dULkRSQVdfTU5FTU9OSUMpICE9IDApIG1uZW1vbmljID0gc3RyaXBNbmVtb25pYyh0ZXh0KTsKLQkKLQlTdHJpbmcgY29kZVBhZ2UgPSBnZXRDb2RlUGFnZSgpOwotCWJ5dGVbXSBidWZmZXIgPSBDb252ZXJ0ZXIud2NzVG9NYmNzKGNvZGVQYWdlLCB0ZXh0LCB0cnVlKTsKLQlpbnQgeG1TdHJpbmcgPSBPUy5YbVN0cmluZ1BhcnNlVGV4dChidWZmZXIsIDAsIE9TLlhtRk9OVExJU1RfREVGQVVMVF9UQUcsIE9TLlhtQ0hBUlNFVF9URVhULCBwYXJzZVRhYmxlLCB0YWJsZUxlbmd0aCwgMCk7Ci0JaWYgKG1uZW1vbmljICE9IDApIHsKLQkJYnl0ZSBbXSBidWZmZXIxID0gQ29udmVydGVyLndjc1RvTWJjcyhjb2RlUGFnZSwgbmV3IGNoYXJbXXttbmVtb25pY30sIHRydWUpOwotCQlpbnQgeG1TdHJpbmdVbmRlcmxpbmUgPSBPUy5YbVN0cmluZ0NyZWF0ZSAoYnVmZmVyMSwgT1MuWG1GT05UTElTVF9ERUZBVUxUX1RBRyk7Ci0JCU9TLlhtU3RyaW5nRHJhd1VuZGVybGluZShkYXRhLmRpc3BsYXksIGRhdGEuZHJhd2FibGUsIHJlbmRlclRhYmxlLCB4bVN0cmluZywgaGFuZGxlLCB4LCB5LCAweDdGRkZGRkZGLCBPUy5YbUFMSUdOTUVOVF9CRUdJTk5JTkcsIDAsIG51bGwsIHhtU3RyaW5nVW5kZXJsaW5lKTsKLQkJT1MuWG1TdHJpbmdGcmVlKHhtU3RyaW5nVW5kZXJsaW5lKTsKLQl9IGVsc2UgewotCQlpZiAoKGZsYWdzICYgU1dULkRSQVdfVFJBTlNQQVJFTlQpICE9IDApIHsKLQkJCU9TLlhtU3RyaW5nRHJhdyhkYXRhLmRpc3BsYXksIGRhdGEuZHJhd2FibGUsIHJlbmRlclRhYmxlLCB4bVN0cmluZywgaGFuZGxlLCB4LCB5LCAweDdGRkZGRkZGLCBPUy5YbUFMSUdOTUVOVF9CRUdJTk5JTkcsIDAsIG51bGwpOwotCQl9IGVsc2UgewotCQkJT1MuWG1TdHJpbmdEcmF3SW1hZ2UoZGF0YS5kaXNwbGF5LCBkYXRhLmRyYXdhYmxlLCByZW5kZXJUYWJsZSwgeG1TdHJpbmcsIGhhbmRsZSwgeCwgeSwgMHg3RkZGRkZGRiwgT1MuWG1BTElHTk1FTlRfQkVHSU5OSU5HLCAwLCBudWxsKTsKLQkJfQotCX0KLQlPUy5YbVN0cmluZ0ZyZWUoeG1TdHJpbmcpOwotCSovCi0JdHJ5IHsKLQkJaWYgKGZvY3VzKHRydWUsIG51bGwpKSB7Ci0JCQlpbnN0YWxsRm9udCgpOwotCQkJTWFjVXRpbC5SR0JGb3JlQ29sb3IoZGF0YS5mb3JlZ3JvdW5kKTsKLQkJCWlmICgoZmxhZ3MgJiBTV1QuRFJBV19UUkFOU1BBUkVOVCkgIT0gMCkgewotCQkJCU9TLlRleHRNb2RlKE9TLnNyY09yKTsKLQkJCX0gZWxzZSB7Ci0JCQkJaWYgKChkYXRhLmJhY2tncm91bmQgJiAweGZmMDAwMDAwKSA9PSAwKSB7Ci0JCQkJCU1hY1V0aWwuUkdCQmFja0NvbG9yKGRhdGEuYmFja2dyb3VuZCk7Ci0JCQkJCU9TLlRleHRNb2RlKE9TLnNyY0NvcHkpOwotCQkJCX0gZWxzZSB7Ci0JCQkJCS8vU3lzdGVtLm91dC5wcmludGxuKCJHQy5kcmF3VGV4dDogIiArIEludGVnZXIudG9IZXhTdHJpbmcoZGF0YS5iYWNrZ3JvdW5kKSk7Ci0JCQkJCU9TLlRleHRNb2RlKE9TLnNyY09yKTsKLQkJCQl9Ci0JCQl9Ci0JCQlzaG9ydFtdIGZvbnRJbmZvPSBuZXcgc2hvcnRbNF07Ci0JCQlPUy5HZXRGb250SW5mbyhmb250SW5mbyk7CS8vIEZvbnRJbmZvCi0JCQlPUy5Nb3ZlVG8oKHNob3J0KXgsIChzaG9ydCkoeStmb250SW5mb1swXSkpOwotCQkJT1MuRHJhd1RleHQoc3RyaW5nLCBkYXRhLmZvbnQuZklELCBkYXRhLmZvbnQuZlNpemUsIGRhdGEuZm9udC5mRmFjZSk7Ci0JCX0KLQl9IGZpbmFsbHkgewotCQl1bmZvY3VzKHRydWUpOwotCX0KKwkvL05PVCBET05FCisJZHJhd1N0cmluZyhzdHJpbmcsIHgsIHkpOwogfQogCiAvKioKQEAgLTkwOCwxMSArODI1LDEyIEBACiAgKgogICogQHNlZSAjaGFzaENvZGUKICAqLwotcHVibGljIGJvb2xlYW4gZXF1YWxzIChPYmplY3Qgb2JqZWN0KSB7CitwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgewogCWlmIChvYmplY3QgPT0gdGhpcykgcmV0dXJuIHRydWU7CiAJaWYgKCEob2JqZWN0IGluc3RhbmNlb2YgR0MpKSByZXR1cm4gZmFsc2U7CiAJcmV0dXJuIGhhbmRsZSA9PSAoKEdDKW9iamVjdCkuaGFuZGxlOwogfQorCiAvKioKICAqIEZpbGxzIHRoZSBpbnRlcmlvciBvZiBhIGNpcmN1bGFyIG9yIGVsbGlwdGljYWwgYXJjIHdpdGhpbgogICogdGhlIHNwZWNpZmllZCByZWN0YW5ndWxhciBhcmVhLCB3aXRoIHRoZSByZWNlaXZlcidzIGJhY2tncm91bmQKQEAgLTk2MSwxNCArODc5LDE1IEBACiAJaWYgKHdpZHRoID09IDAgfHwgaGVpZ2h0ID09IDAgfHwgZW5kQW5nbGUgPT0gMCkgewogCQlTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwogCX0KLQkvKiBBVwotCVhHQ1ZhbHVlcyB2YWx1ZXMgPSBuZXcgWEdDVmFsdWVzICgpOwotCU9TLlhHZXRHQ1ZhbHVlcyAoeERpc3BsYXksIGhhbmRsZSwgT1MuR0NGb3JlZ3JvdW5kIHwgT1MuR0NCYWNrZ3JvdW5kLCB2YWx1ZXMpOwotCU9TLlhTZXRGb3JlZ3JvdW5kICh4RGlzcGxheSwgaGFuZGxlLCB2YWx1ZXMuYmFja2dyb3VuZCk7Ci0JT1MuWEZpbGxBcmMoeERpc3BsYXksZGF0YS5kcmF3YWJsZSxoYW5kbGUseCx5LHdpZHRoLGhlaWdodCxzdGFydEFuZ2xlICogNjQgLGVuZEFuZ2xlICogNjQpOwotCU9TLlhTZXRGb3JlZ3JvdW5kICh4RGlzcGxheSwgaGFuZGxlLCB2YWx1ZXMuZm9yZWdyb3VuZCk7Ci0JKi8KLQlTeXN0ZW0ub3V0LnByaW50bG4oIkdDLmZpbGxBcmMiKTsKKwlPUy5DR0NvbnRleHRCZWdpblBhdGgoaGFuZGxlKTsKKyAgICBPUy5DR0NvbnRleHRTYXZlR1N0YXRlKGhhbmRsZSk7CisgICAgT1MuQ0dDb250ZXh0VHJhbnNsYXRlQ1RNKGhhbmRsZSwgeCArIHdpZHRoIC8gMmYsIHkgKyBoZWlnaHQgLyAyZik7CisgICAgT1MuQ0dDb250ZXh0U2NhbGVDVE0oaGFuZGxlLCB3aWR0aCAvIDJmLCBoZWlnaHQgLyAyZik7CisgICAgT1MuQ0dDb250ZXh0TW92ZVRvUG9pbnQoaGFuZGxlLCAwLCAwKTsKKyAgICBPUy5DR0NvbnRleHRBZGRBcmMoaGFuZGxlLCAwLCAwLCAxLCAtc3RhcnRBbmdsZSAqIChmbG9hdClNYXRoLlBJIC8gMTgwLCAgLWVuZEFuZ2xlICogKGZsb2F0KU1hdGguUEkgLyAxODAsIHRydWUpOworICAgIE9TLkNHQ29udGV4dENsb3NlUGF0aChoYW5kbGUpOworICAgIE9TLkNHQ29udGV4dFJlc3RvcmVHU3RhdGUoaGFuZGxlKTsKKwlPUy5DR0NvbnRleHRGaWxsUGF0aChoYW5kbGUpOwogfQogCiAvKioKQEAgLTk5NSwxMTAgKzkxNCwzNSBAQAogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKIAlpZiAoKHdpZHRoID09IDApIHx8IChoZWlnaHQgPT0gMCkpIHJldHVybjsKIAkKLQl0cnkgewotCQlpZiAoISBmb2N1cyh0cnVlLCBudWxsKSkKLQkJCXJldHVybjsKLQkJCi0JCS8qIEFXCi0JCWludCB4RGlzcGxheSA9IGRhdGEuZGlzcGxheTsKLQkJaW50IHhTY3JlZW5OdW0gPSBPUy5YRGVmYXVsdFNjcmVlbih4RGlzcGxheSk7Ci0JCVhHQ1ZhbHVlcyB2YWx1ZXMgPSBuZXcgWEdDVmFsdWVzKCk7Ci0JCSovCi0JCWludCBmcm9tQ29sb3IsIHRvQ29sb3I7Ci0JCS8qIEFXCi0JCU9TLlhHZXRHQ1ZhbHVlcyh4RGlzcGxheSwgaGFuZGxlLCBPUy5HQ0ZvcmVncm91bmQgfCBPUy5HQ0JhY2tncm91bmQsIHZhbHVlcyk7Ci0JCWZyb21Db2xvciA9IHZhbHVlcy5mb3JlZ3JvdW5kOwotCQl0b0NvbG9yID0gdmFsdWVzLmJhY2tncm91bmQ7Ci0JCSovCi0JCWZyb21Db2xvciA9IGRhdGEuZm9yZWdyb3VuZDsKLQkJdG9Db2xvciA9IGRhdGEuYmFja2dyb3VuZDsKLQkJCi0JCWJvb2xlYW4gc3dhcENvbG9ycyA9IGZhbHNlOwotCQlpZiAod2lkdGggPCAwKSB7Ci0JCQl4ICs9IHdpZHRoOyB3aWR0aCA9IC13aWR0aDsKLQkJCWlmICghIHZlcnRpY2FsKSBzd2FwQ29sb3JzID0gdHJ1ZTsKLQkJfQotCQlpZiAoaGVpZ2h0IDwgMCkgewotCQkJeSArPSBoZWlnaHQ7IGhlaWdodCA9IC1oZWlnaHQ7Ci0JCQlpZiAodmVydGljYWwpIHN3YXBDb2xvcnMgPSB0cnVlOwotCQl9Ci0JCWlmIChzd2FwQ29sb3JzKSB7Ci0JCQlmaW5hbCBpbnQgdCA9IGZyb21Db2xvcjsKLQkJCWZyb21Db2xvciA9IHRvQ29sb3I7Ci0JCQl0b0NvbG9yID0gdDsKLQkJfQotCQkKLQkJaWYgKGZyb21Db2xvciA9PSB0b0NvbG9yKSB7Ci0JCQkvKiBBVwotCQkJT1MuWEZpbGxSZWN0YW5nbGUoeERpc3BsYXksIGRhdGEuZHJhd2FibGUsIGhhbmRsZSwgeCwgeSwgd2lkdGgsIGhlaWdodCk7Ci0JCQkqLwotCQkJTWFjVXRpbC5SR0JGb3JlQ29sb3IoZGF0YS5mb3JlZ3JvdW5kKTsKLQkJCWZSZWN0LnNldCh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKLQkJCU9TLlBhaW50UmVjdChmUmVjdC5nZXREYXRhKCkpOwotCQkJcmV0dXJuOwotCQl9Ci0JCS8qIFggV2luZG93IGRlYWxzIHdpdGggYSB2aXJ0dWFsbHkgbGltaXRsZXNzIGFycmF5IG9mIGNvbG9yIGZvcm1hdHMKLQkJICogYnV0IHdlIG9ubHkgZGlzdGluZ3Vpc2ggYmV0d2VlbiBwYWxldHRlZCBhbmQgZGlyZWN0IG1vZGVzCi0JCSAqLwkKLQkJLyogQVcKLQkJZmluYWwgaW50IHhTY3JlZW4gPSBPUy5YRGVmYXVsdFNjcmVlbk9mRGlzcGxheSh4RGlzcGxheSk7Ci0JCWZpbmFsIGludCB4VmlzdWFsID0gT1MuWERlZmF1bHRWaXN1YWwoeERpc3BsYXksIHhTY3JlZW5OdW0pOwotCQlWaXN1YWwgdmlzdWFsID0gbmV3IFZpc3VhbCgpOwotCQlPUy5tZW1tb3ZlKHZpc3VhbCwgeFZpc3VhbCwgdmlzdWFsLnNpemVvZik7Ci0JCWZpbmFsIGludCBkZXB0aCA9IE9TLlhEZWZhdWx0RGVwdGhPZlNjcmVlbih4U2NyZWVuKTsKLQkJKi8KLQkJCi0JCWludCBkZXB0aD0gZ2V0Q3VycmVudFNjcmVlbkRlcHRoKCk7Ci0JCWZpbmFsIGJvb2xlYW4gZGlyZWN0Q29sb3IgPSAoZGVwdGggPiA4KTsKLQkKLQkJLy8gVGhpcyBjb2RlIGlzIGludGVudGlvbmFsbHkgY29tbWVudGVkIHNpbmNlIGVsc2V3aGVyZSBpbiBTV1Qgd2UKLQkJLy8gYXNzdW1lIHRoYXQgZGVwdGggPD0gOCBtZWFucyB3ZSBhcmUgaW4gYSBwYWxldHRlZCBtb2RlIHRob3VnaAotCQkvLyB0aGlzIGlzIG5vdCBhbHdheXMgdGhlIGNhc2UuCi0JCS8vZmluYWwgYm9vbGVhbiBkaXJlY3RDb2xvciA9ICh2aXN1YWwuY19jbGFzcyA9PSBPUy5UcnVlQ29sb3IpIHx8ICh2aXN1YWwuY19jbGFzcyA9PSBPUy5EaXJlY3RDb2xvcik7Ci0JCi0JCS8qIEFXCi0JCVhDb2xvciB4Q29sb3IgPSBuZXcgWENvbG9yKCk7Ci0JCXhDb2xvci5waXhlbCA9IGZyb21Db2xvcjsKLQkJT1MuWFF1ZXJ5Q29sb3IoeERpc3BsYXksIGRhdGEuY29sb3JtYXAsIHhDb2xvcik7Ci0JCWZpbmFsIFJHQiBmcm9tUkdCID0gbmV3IFJHQigoeENvbG9yLnJlZCAmIDB4ZmZmZikgPj4+IDgsICh4Q29sb3IuZ3JlZW4gJiAweGZmZmYpID4+PiA4LCAoeENvbG9yLmJsdWUgJiAweGZmZmYpID4+PiA4KTsKLQkJeENvbG9yLnBpeGVsID0gdG9Db2xvcjsKLQkJT1MuWFF1ZXJ5Q29sb3IoeERpc3BsYXksIGRhdGEuY29sb3JtYXAsIHhDb2xvcik7Ci0JCWZpbmFsIFJHQiB0b1JHQiA9IG5ldyBSR0IoKHhDb2xvci5yZWQgJiAweGZmZmYpID4+PiA4LCAoeENvbG9yLmdyZWVuICYgMHhmZmZmKSA+Pj4gOCwgKHhDb2xvci5ibHVlICYgMHhmZmZmKSA+Pj4gOCk7Ci0JCSovCi0JCQotCQlSR0IgZnJvbVJHQiA9IENvbG9yLmNhcmJvbl9uZXcoZGF0YS5kZXZpY2UsIGZyb21Db2xvciwgZmFsc2UpLmdldFJHQigpOwotCQlSR0IgdG9SR0IgPSBDb2xvci5jYXJib25fbmV3KGRhdGEuZGV2aWNlLCB0b0NvbG9yLCBmYWxzZSkuZ2V0UkdCKCk7Ci0JCi0JCWZpbmFsIGludCByZWRCaXRzLCBncmVlbkJpdHMsIGJsdWVCaXRzOwotCQlpZiAoZGlyZWN0Q29sb3IpIHsKLQkJCS8vIFJHQiBtYXBwZWQgZGlzcGxheQotCQkJcmVkQml0cyA9IGdldENoYW5uZWxXaWR0aCgweDAwZmYwMDAwIC8qIEFXIHZpc3VhbC5yZWRfbWFzayAqLyk7Ci0JCQlncmVlbkJpdHMgPSBnZXRDaGFubmVsV2lkdGgoMHgwMDAwZmYwMCAvKiBBVyB2aXN1YWwuZ3JlZW5fbWFzayAqLyk7Ci0JCQlibHVlQml0cyA9IGdldENoYW5uZWxXaWR0aCgweDAwMDAwMGZmIC8qIEFXIHZpc3VhbC5ibHVlX21hc2sgKi8pOwotCQl9IGVsc2UgewotCQkJLy8gSW5kZXggZGlzcGxheQotCQkJcmVkQml0cyA9IGdyZWVuQml0cyA9IGJsdWVCaXRzID0gMDsKLQkJfQotCQotCQlJbWFnZURhdGEuZmlsbEdyYWRpZW50UmVjdGFuZ2xlKHRoaXMsIGRhdGEuZGV2aWNlLAotCQkJeCwgeSwgd2lkdGgsIGhlaWdodCwgdmVydGljYWwsIGZyb21SR0IsIHRvUkdCLAotCQkJcmVkQml0cywgZ3JlZW5CaXRzLCBibHVlQml0cyk7Ci0JCQkKLQl9IGZpbmFsbHkgewotCQl1bmZvY3VzKHRydWUpOwotCX0KLX0KKwkvKiBSZXdyaXRlIHRoaXMgdG8gdXNlIEdka1BpeGJ1ZiAqLwogCi0vKioKLSAqIENvbXB1dGVzIHRoZSByZXF1aXJlZCBjaGFubmVsIHdpZHRoIChkZXB0aCkgZnJvbSBhIG1hc2suCi0gKi8KLXN0YXRpYyBpbnQgZ2V0Q2hhbm5lbFdpZHRoKGludCBtYXNrKSB7Ci0JaW50IHdpZHRoID0gMDsKLQl3aGlsZSAobWFzayAhPSAwKSB7Ci0JCXdpZHRoICs9IChtYXNrICYgMSk7Ci0JCW1hc2sgPj4+PSAxOworCVJHQiBiYWNrZ3JvdW5kUkdCLCBmb3JlZ3JvdW5kUkdCOworCWJhY2tncm91bmRSR0IgPSBnZXRCYWNrZ3JvdW5kKCkuZ2V0UkdCKCk7CisJZm9yZWdyb3VuZFJHQiA9IGdldEZvcmVncm91bmQoKS5nZXRSR0IoKTsKKworCVJHQiBmcm9tUkdCLCB0b1JHQjsKKwlmcm9tUkdCID0gZm9yZWdyb3VuZFJHQjsKKwl0b1JHQiAgID0gYmFja2dyb3VuZFJHQjsKKwlib29sZWFuIHN3YXBDb2xvcnMgPSBmYWxzZTsKKwlpZiAod2lkdGggPCAwKSB7CisJCXggKz0gd2lkdGg7IHdpZHRoID0gLXdpZHRoOworCQlpZiAoISB2ZXJ0aWNhbCkgc3dhcENvbG9ycyA9IHRydWU7CiAJfQotCXJldHVybiB3aWR0aDsKKwlpZiAoaGVpZ2h0IDwgMCkgeworCQl5ICs9IGhlaWdodDsgaGVpZ2h0ID0gLWhlaWdodDsKKwkJaWYgKHZlcnRpY2FsKSBzd2FwQ29sb3JzID0gdHJ1ZTsKKwl9CisJaWYgKHN3YXBDb2xvcnMpIHsKKwkJZnJvbVJHQiA9IGJhY2tncm91bmRSR0I7CisJCXRvUkdCICAgPSBmb3JlZ3JvdW5kUkdCOworCX0KKwlpZiAoZnJvbVJHQiA9PSB0b1JHQikgeworCQlmaWxsUmVjdGFuZ2xlKHgsIHksIHdpZHRoLCBoZWlnaHQpOworCQlyZXR1cm47CisJfQorCUltYWdlRGF0YS5maWxsR3JhZGllbnRSZWN0YW5nbGUodGhpcywgZGF0YS5kZXZpY2UsCisJCXgsIHksIHdpZHRoLCBoZWlnaHQsIHZlcnRpY2FsLCBmcm9tUkdCLCB0b1JHQiwKKwkJOCwgOCwgOCk7CiB9CiAKIC8qKiAKQEAgLTExMTcsNyArOTYxLDcgQEAKICAqCiAgKiBAc2VlICNkcmF3T3ZhbAogICovCi1wdWJsaWMgdm9pZCBmaWxsT3ZhbCAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKK3B1YmxpYyB2b2lkIGZpbGxPdmFsKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CiAJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwogCWlmICh3aWR0aCA8IDApIHsKIAkJeCA9IHggKyB3aWR0aDsKQEAgLTExMjcsMjAgKzk3MSwxNyBAQAogCQl5ID0geSArIGhlaWdodDsKIAkJaGVpZ2h0ID0gLWhlaWdodDsKIAl9Ci0JdHJ5IHsKLQkJaWYgKGZvY3VzKHRydWUsIG51bGwpKSB7Ci0JCQlpZiAoKGRhdGEuYmFja2dyb3VuZCAmIDB4ZmYwMDAwMDApID09IDApIHsKLQkJCQlNYWNVdGlsLlJHQkZvcmVDb2xvcihkYXRhLmJhY2tncm91bmQpOwotCQkJCWZSZWN0LnNldCh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKLQkJCQlPUy5QYWludE92YWwoZlJlY3QuZ2V0RGF0YSgpKTsKLQkJCX0gZWxzZSB7Ci0JCQkJLy8JU3lzdGVtLm91dC5wcmludGxuKCJHQy5maWxsT3ZhbDogIiArIEludGVnZXIudG9IZXhTdHJpbmcoZGF0YS5iYWNrZ3JvdW5kKSk7Ci0JCQl9Ci0JCX0KLQl9IGZpbmFsbHkgewotCQl1bmZvY3VzKHRydWUpOwotCX0KKwlPUy5DR0NvbnRleHRCZWdpblBhdGgoaGFuZGxlKTsKKyAgICBPUy5DR0NvbnRleHRTYXZlR1N0YXRlKGhhbmRsZSk7CisgICAgT1MuQ0dDb250ZXh0VHJhbnNsYXRlQ1RNKGhhbmRsZSwgeCArIHdpZHRoIC8gMmYsIHkgKyBoZWlnaHQgLyAyZik7CisgICAgT1MuQ0dDb250ZXh0U2NhbGVDVE0oaGFuZGxlLCB3aWR0aCAvIDJmLCBoZWlnaHQgLyAyZik7CisgICAgT1MuQ0dDb250ZXh0TW92ZVRvUG9pbnQoaGFuZGxlLCAxLCAwKTsKKyAgICBPUy5DR0NvbnRleHRBZGRBcmMoaGFuZGxlLCAwLCAwLCAxLCAwLCAgKGZsb2F0KShNYXRoLlBJICogMiksIGZhbHNlKTsKKyAgICBPUy5DR0NvbnRleHRDbG9zZVBhdGgoaGFuZGxlKTsKKyAgICBPUy5DR0NvbnRleHRSZXN0b3JlR1N0YXRlKGhhbmRsZSk7CisJT1MuQ0dDb250ZXh0RmlsbFBhdGgoaGFuZGxlKTsKIH0KKwogLyoqIAogICogRmlsbHMgdGhlIGludGVyaW9yIG9mIHRoZSBjbG9zZWQgcG9seWdvbiB3aGljaCBpcyBkZWZpbmVkIGJ5IHRoZQogICogc3BlY2lmaWVkIGFycmF5IG9mIGludGVnZXIgY29vcmRpbmF0ZXMsIHVzaW5nIHRoZSByZWNlaXZlcidzCkBAIC0xMTYzLDM3ICsxMDA0LDE2IEBACiBwdWJsaWMgdm9pZCBmaWxsUG9seWdvbihpbnRbXSBwb2ludEFycmF5KSB7CiAJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwogCWlmIChwb2ludEFycmF5ID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0KLQkvKiBBVwotCXNob3J0W10geFBvaW50cyA9IG5ldyBzaG9ydFtwb2ludEFycmF5Lmxlbmd0aF07Ci0JZm9yIChpbnQgaSA9IDA7IGk8cG9pbnRBcnJheS5sZW5ndGg7aSsrKSB7Ci0JCXhQb2ludHNbaV0gPSAoc2hvcnQpIHBvaW50QXJyYXlbaV07CisJZmxvYXRbXSBwb2ludHMgPSBuZXcgZmxvYXRbcG9pbnRBcnJheS5sZW5ndGhdOworCWZvciAoaW50IGk9MDsgaTxwb2ludHMubGVuZ3RoOyBpKyspIHsKKwkJcG9pbnRzW2ldID0gcG9pbnRBcnJheVtpXTsKIAl9Ci0JaW50IHhEaXNwbGF5ID0gZGF0YS5kaXNwbGF5OwotCVhHQ1ZhbHVlcyB2YWx1ZXMgPSBuZXcgWEdDVmFsdWVzICgpOwotCU9TLlhHZXRHQ1ZhbHVlcyAoeERpc3BsYXksIGhhbmRsZSwgT1MuR0NGb3JlZ3JvdW5kIHwgT1MuR0NCYWNrZ3JvdW5kLCB2YWx1ZXMpOwotCU9TLlhTZXRGb3JlZ3JvdW5kICh4RGlzcGxheSwgaGFuZGxlLCB2YWx1ZXMuYmFja2dyb3VuZCk7Ci0JT1MuWEZpbGxQb2x5Z29uKHhEaXNwbGF5LCBkYXRhLmRyYXdhYmxlLCBoYW5kbGUseFBvaW50cywgeFBvaW50cy5sZW5ndGggLyAyLCBPUy5Db21wbGV4LCBPUy5Db29yZE1vZGVPcmlnaW4pOwotCU9TLlhTZXRGb3JlZ3JvdW5kICh4RGlzcGxheSwgaGFuZGxlLCB2YWx1ZXMuZm9yZWdyb3VuZCk7Ci0JKi8KLQlpbnQgcG9seT0gMDsKLQl0cnkgewotCQlpZiAoZm9jdXModHJ1ZSwgbnVsbCkpIHsKLQkJCXBvbHk9IE9TLk9wZW5Qb2x5KCk7Ci0JCQlPUy5Nb3ZlVG8oKHNob3J0KXBvaW50QXJyYXlbMF0sIChzaG9ydClwb2ludEFycmF5WzFdKTsKLQkJCWZvciAoaW50IGk9IDI7IGkgPCBwb2ludEFycmF5Lmxlbmd0aDsgaSs9IDIpCi0JCQkJT1MuTGluZVRvKChzaG9ydClwb2ludEFycmF5W2ldLCAoc2hvcnQpcG9pbnRBcnJheVtpKzFdKTsKLQkJCU9TLkNsb3NlUG9seSgpOwotCQkJCi0JCQlNYWNVdGlsLlJHQkZvcmVDb2xvcihkYXRhLmJhY2tncm91bmQpOwotCQkJT1MuUGFpbnRQb2x5KHBvbHkpOwotCQl9Ci0JfSBmaW5hbGx5IHsKLQkJdW5mb2N1cyh0cnVlKTsKLQl9Ci0JaWYgKHBvbHkgIT0gMCkKLQkJT1MuS2lsbFBvbHkocG9seSk7CisJT1MuQ0dDb250ZXh0QmVnaW5QYXRoKGhhbmRsZSk7CisJT1MuQ0dDb250ZXh0QWRkTGluZXMoaGFuZGxlLCBwb2ludHMsIHBvaW50cy5sZW5ndGggLyAyKTsKKwlPUy5DR0NvbnRleHRDbG9zZVBhdGgoaGFuZGxlKTsKKwlPUy5DR0NvbnRleHRGaWxsUGF0aChoYW5kbGUpOwogfQorCiAvKiogCiAgKiBGaWxscyB0aGUgaW50ZXJpb3Igb2YgdGhlIHJlY3RhbmdsZSBzcGVjaWZpZWQgYnkgdGhlIGFyZ3VtZW50cywKICAqIHVzaW5nIHRoZSByZWNlaXZlcidzIGJhY2tncm91bmQgY29sb3IuIApAQCAtMTIwOSw3ICsxMDI5LDcgQEAKICAqCiAgKiBAc2VlICNkcmF3UmVjdGFuZ2xlCiAgKi8KLXB1YmxpYyB2b2lkIGZpbGxSZWN0YW5nbGUgKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CitwdWJsaWMgdm9pZCBmaWxsUmVjdGFuZ2xlKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CiAJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwogCWlmICh3aWR0aCA8IDApIHsKIAkJeCA9IHggKyB3aWR0aDsKQEAgLTEyMTksMjcgKzEwMzksMTQgQEAKIAkJeSA9IHkgKyBoZWlnaHQ7CiAJCWhlaWdodCA9IC1oZWlnaHQ7CiAJfQotCXRyeSB7Ci0JCWlmIChmb2N1cyh0cnVlLCBudWxsKSkgewotCQkJZlJlY3Quc2V0KHgsIHksIHdpZHRoLCBoZWlnaHQpOwotCQkJaWYgKChkYXRhLmJhY2tncm91bmQgJiAweEZGMDAwMDAwKSA9PSAwKSB7Ci0JCQkJTWFjVXRpbC5SR0JGb3JlQ29sb3IoZGF0YS5iYWNrZ3JvdW5kKTsKLQkJCQlPUy5QYWludFJlY3QoZlJlY3QuZ2V0RGF0YSgpKTsKLQkJCX0gZWxzZSB7Ci0JCQkJc2hvcnQgZGVwdGg9IGdldEN1cnJlbnRTY3JlZW5EZXB0aCgpOwotCQkJCWludFtdIHN0YXRlPSBuZXcgaW50WzFdOwotCQkJCU9TLkdldFRoZW1lRHJhd2luZ1N0YXRlKHN0YXRlKTsKLQkJCQkvL09TLlNldFRoZW1lQmFja2dyb3VuZChPUy5rVGhlbWVCcnVzaERpYWxvZ0JhY2tncm91bmRBY3RpdmUsIGRlcHRoLCB0cnVlKTsKLQkJCQlpZiAoZGF0YS5jb250cm9sSGFuZGxlICE9IDApCi0JCQkJCU9TLlNldFVwQ29udHJvbEJhY2tncm91bmQoZGF0YS5jb250cm9sSGFuZGxlLCBkZXB0aCwgdHJ1ZSk7Ci0JCQkJT1MuRXJhc2VSZWN0KGZSZWN0LmdldERhdGEoKSk7Ci0JCQkJT1MuU2V0VGhlbWVEcmF3aW5nU3RhdGUoc3RhdGVbMF0sIHRydWUpOwotCQkJfQotCQl9Ci0JfSBmaW5hbGx5IHsKLQkJdW5mb2N1cyh0cnVlKTsKLQl9CisJQ0dSZWN0IHJlY3QgPSBuZXcgQ0dSZWN0KCk7CisJcmVjdC54ID0geDsKKwlyZWN0LnkgPSB5OworCXJlY3Qud2lkdGggPSB3aWR0aDsKKwlyZWN0LmhlaWdodCA9IGhlaWdodDsKKwlPUy5DR0NvbnRleHRGaWxsUmVjdChoYW5kbGUsIHJlY3QpOwogfQorCiAvKiogCiAgKiBGaWxscyB0aGUgaW50ZXJpb3Igb2YgdGhlIHNwZWNpZmllZCByZWN0YW5nbGUsIHVzaW5nIHRoZSByZWNlaXZlcidzCiAgKiBiYWNrZ3JvdW5kIGNvbG9yLiAKQEAgLTEyNTUsMTAgKzEwNjIsMTIgQEAKICAqCiAgKiBAc2VlICNkcmF3UmVjdGFuZ2xlCiAgKi8KLXB1YmxpYyB2b2lkIGZpbGxSZWN0YW5nbGUgKFJlY3RhbmdsZSByZWN0KSB7CitwdWJsaWMgdm9pZCBmaWxsUmVjdGFuZ2xlKFJlY3RhbmdsZSByZWN0KSB7CisJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwogCWlmIChyZWN0ID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJZmlsbFJlY3RhbmdsZShyZWN0LngsIHJlY3QueSwgcmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpOwogfQorCiAvKiogCiAgKiBGaWxscyB0aGUgaW50ZXJpb3Igb2YgdGhlIHJvdW5kLWNvcm5lcmVkIHJlY3RhbmdsZSBzcGVjaWZpZWQgYnkgCiAgKiB0aGUgYXJndW1lbnRzLCB1c2luZyB0aGUgcmVjZWl2ZXIncyBiYWNrZ3JvdW5kIGNvbG9yLiAKQEAgLTEyNzYsMjIgKzEwODUsMjggQEAKICAqCiAgKiBAc2VlICNkcmF3Um91bmRSZWN0YW5nbGUKICAqLwotcHVibGljIHZvaWQgZmlsbFJvdW5kUmVjdGFuZ2xlIChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGFyY1dpZHRoLCBpbnQgYXJjSGVpZ2h0KSB7CitwdWJsaWMgdm9pZCBmaWxsUm91bmRSZWN0YW5nbGUoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBhcmNXaWR0aCwgaW50IGFyY0hlaWdodCkgewogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQl0cnkgewotCQlpZiAoZm9jdXModHJ1ZSwgbnVsbCkpIHsKLQkJCWlmICgoZGF0YS5iYWNrZ3JvdW5kICYgMHhmZjAwMDAwMCkgPT0gMCkgewotCQkJCU1hY1V0aWwuUkdCRm9yZUNvbG9yKGRhdGEuYmFja2dyb3VuZCk7Ci0JCQkJZlJlY3Quc2V0KHgsIHksIHdpZHRoLCBoZWlnaHQpOwotCQkJCU9TLlBhaW50Um91bmRSZWN0KGZSZWN0LmdldERhdGEoKSwgKHNob3J0KWFyY1dpZHRoLCAoc2hvcnQpYXJjSGVpZ2h0KTsKLQkJCX0gZWxzZSB7Ci0JCQkJLy8JU3lzdGVtLm91dC5wcmludGxuKCJHQy5maWxsUm91bmRSZWN0YW5nbGU6ICIgKyBJbnRlZ2VyLnRvSGV4U3RyaW5nKGRhdGEuYmFja2dyb3VuZCkpOwotCQkJfQotCQl9Ci0JfSBmaW5hbGx5IHsKLQkJdW5mb2N1cyh0cnVlKTsKKwlpZiAoYXJjV2lkdGggPT0gMCB8fCBhcmNIZWlnaHQgPT0gMCkgeworCQlmaWxsUmVjdGFuZ2xlKHgsIHksIHdpZHRoLCBoZWlnaHQpOworICAgIAlyZXR1cm47CiAJfQorCU9TLkNHQ29udGV4dEJlZ2luUGF0aChoYW5kbGUpOworCU9TLkNHQ29udGV4dFNhdmVHU3RhdGUoaGFuZGxlKTsKKwlPUy5DR0NvbnRleHRUcmFuc2xhdGVDVE0oaGFuZGxlLCB4LCB5KTsKKwlPUy5DR0NvbnRleHRTY2FsZUNUTShoYW5kbGUsIGFyY1dpZHRoLCBhcmNIZWlnaHQpOworICAgIGZsb2F0IGZ3ID0gd2lkdGggLyAoZmxvYXQpYXJjV2lkdGg7CisJZmxvYXQgZmggPSBoZWlnaHQgLyAoZmxvYXQpYXJjSGVpZ2h0OworCU9TLkNHQ29udGV4dE1vdmVUb1BvaW50KGhhbmRsZSwgZncsIGZoLzIpOworCU9TLkNHQ29udGV4dEFkZEFyY1RvUG9pbnQoaGFuZGxlLCBmdywgZmgsIGZ3LzIsIGZoLCAxKTsKKwlPUy5DR0NvbnRleHRBZGRBcmNUb1BvaW50KGhhbmRsZSwgMCwgZmgsIDAsIGZoLzIsIDEpOworCU9TLkNHQ29udGV4dEFkZEFyY1RvUG9pbnQoaGFuZGxlLCAwLCAwLCBmdy8yLCAwLCAxKTsKKwlPUy5DR0NvbnRleHRBZGRBcmNUb1BvaW50KGhhbmRsZSwgZncsIDAsIGZ3LCBmaC8yLCAxKTsKKwlPUy5DR0NvbnRleHRDbG9zZVBhdGgoaGFuZGxlKTsKKwlPUy5DR0NvbnRleHRSZXN0b3JlR1N0YXRlKGhhbmRsZSk7CisJT1MuQ0dDb250ZXh0RmlsbFBhdGgoaGFuZGxlKTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIHRoZSA8ZW0+YWR2YW5jZSB3aWR0aDwvZW0+IG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGluCiAgKiB0aGUgZm9udCB3aGljaCBpcyBjdXJyZW50bHkgc2VsZWN0ZWQgaW50byB0aGUgcmVjZWl2ZXIuCkBAIC0xMzA3LDE2ICsxMTIyLDEyIEBACiAgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgaW50IGdldEFkdmFuY2VXaWR0aChjaGFyIGNoKSB7CitwdWJsaWMgaW50IGdldEFkdmFuY2VXaWR0aChjaGFyIGNoKSB7CQogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQl0cnkgewotCQlmb2N1cyhmYWxzZSwgbnVsbCk7Ci0JCWluc3RhbGxGb250KCk7Ci0JCXJldHVybiBPUy5DaGFyV2lkdGgoKGJ5dGUpIGNoKTsKLQl9IGZpbmFsbHkgewotCQl1bmZvY3VzKGZhbHNlKTsKLQl9CisJLy9OT1QgRE9ORQorCXJldHVybiBzdHJpbmdFeHRlbnQobmV3IFN0cmluZyhuZXcgY2hhcltde2NofSkpLng7CiB9CisKIC8qKiAKICAqIFJldHVybnMgdGhlIGJhY2tncm91bmQgY29sb3IuCiAgKgpAQCAtMTMyOCwxNiArMTEzOSw5IEBACiAgKi8KIHB1YmxpYyBDb2xvciBnZXRCYWNrZ3JvdW5kKCkgewogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQkvKiBBVwotCWludCB4RGlzcGxheSA9IGRhdGEuZGlzcGxheTsKLQlYR0NWYWx1ZXMgdmFsdWVzID0gbmV3IFhHQ1ZhbHVlcygpOwotCU9TLlhHZXRHQ1ZhbHVlcyh4RGlzcGxheSwgaGFuZGxlLCBPUy5HQ0JhY2tncm91bmQsIHZhbHVlcyk7Ci0JWENvbG9yIHhDb2xvciA9IG5ldyBYQ29sb3IoKTsKLQl4Q29sb3IucGl4ZWwgPSB2YWx1ZXMuYmFja2dyb3VuZDsKLQlPUy5YUXVlcnlDb2xvcih4RGlzcGxheSxkYXRhLmNvbG9ybWFwLHhDb2xvcik7Ci0JKi8KLQlyZXR1cm4gQ29sb3IuY2FyYm9uX25ldyhkYXRhLmRldmljZSwgZGF0YS5iYWNrZ3JvdW5kLCBmYWxzZSk7CisJcmV0dXJuIENvbG9yLmNhcmJvbl9uZXcgKGRhdGEuZGV2aWNlLCBkYXRhLmJhY2tncm91bmQpOwogfQorCiAvKioKICAqIFJldHVybnMgdGhlIHdpZHRoIG9mIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGluIHRoZSBmb250CiAgKiBzZWxlY3RlZCBpbnRvIHRoZSByZWNlaXZlci4gCkBAIC0xMzU2LDkgKzExNjAsMTAgQEAKICAqLwogcHVibGljIGludCBnZXRDaGFyV2lkdGgoY2hhciBjaCkgewogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQlTeXN0ZW0ub3V0LnByaW50bG4oIkdDLmdldENoYXJXaWR0aCIpOwotCXJldHVybiAwOworCS8vTk9UIERPTkUKKwlyZXR1cm4gc3RyaW5nRXh0ZW50KG5ldyBTdHJpbmcobmV3IGNoYXJbXXtjaH0pKS54OwogfQorCiAvKiogCiAgKiBSZXR1cm5zIHRoZSBib3VuZGluZyByZWN0YW5nbGUgb2YgdGhlIHJlY2VpdmVyJ3MgY2xpcHBpbmcKICAqIHJlZ2lvbi4gSWYgbm8gY2xpcHBpbmcgcmVnaW9uIGlzIHNldCwgdGhlIHJldHVybiB2YWx1ZQpAQCAtMTM3MywzMyArMTE3OCwyOCBAQAogICovCiBwdWJsaWMgUmVjdGFuZ2xlIGdldENsaXBwaW5nKCkgewogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQkvKiBBVwotCWludCBjbGlwUmduID0gZGF0YS5jbGlwUmduOwotCWlmIChjbGlwUmduID09IDApIHsKLQkJaW50W10gd2lkdGggPSBuZXcgaW50WzFdOyBpbnRbXSBoZWlnaHQgPSBuZXcgaW50WzFdOwotCQlpbnRbXSB1bnVzZWQgPSBuZXcgaW50WzFdOwotCQlPUy5YR2V0R2VvbWV0cnkoZGF0YS5kaXNwbGF5LCBkYXRhLmRyYXdhYmxlLCB1bnVzZWQsIHVudXNlZCwgdW51c2VkLCB3aWR0aCwgaGVpZ2h0LCB1bnVzZWQsIHVudXNlZCk7Ci0JCXJldHVybiBuZXcgUmVjdGFuZ2xlKDAsIDAsIHdpZHRoWzBdLCBoZWlnaHRbMF0pOwotCX0KLQlYUmVjdGFuZ2xlIHJlY3QgPSBuZXcgWFJlY3RhbmdsZSgpOwotCU9TLlhDbGlwQm94KGNsaXBSZ24sIHJlY3QpOwotCXJldHVybiBuZXcgUmVjdGFuZ2xlKHJlY3QueCwgcmVjdC55LCByZWN0LndpZHRoLCByZWN0LmhlaWdodCk7Ci0JKi8KLQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKIAlpZiAoZGF0YS5jbGlwUmduID09IDApIHsKLQkJaWYgKGRhdGEuY29udHJvbEhhbmRsZSAhPSAwKSB7Ci0JCQlPUy5HZXRDb250cm9sQm91bmRzKGRhdGEuY29udHJvbEhhbmRsZSwgYm91bmRzLmdldERhdGEoKSk7Ci0JCQlyZXR1cm4gbmV3IFJlY3RhbmdsZSgwLCAwLCBib3VuZHMuZ2V0V2lkdGgoKSwgYm91bmRzLmdldEhlaWdodCgpKTsKKwkJaW50IHdpZHRoID0gMCwgaGVpZ2h0ID0gMDsKKwkJaWYgKGRhdGEuY29udHJvbCAhPSAwKSB7CisJCQlSZWN0IGJvdW5kcyA9IG5ldyBSZWN0KCk7CisJCQlPUy5HZXRDb250cm9sQm91bmRzKGRhdGEuY29udHJvbCwgYm91bmRzKTsKKwkJCXdpZHRoID0gYm91bmRzLnJpZ2h0IC0gYm91bmRzLmxlZnQ7CisJCQloZWlnaHQgPSBib3VuZHMuYm90dG9tIC0gYm91bmRzLnRvcDsKIAkJfQogCQlpZiAoZGF0YS5pbWFnZSAhPSBudWxsKSB7Ci0JCQlyZXR1cm4gZGF0YS5pbWFnZS5nZXRCb3VuZHMoKTsKLQkJfQkKLQkJU3lzdGVtLm91dC5wcmludGxuKCJHQy5nZXRDbGlwcGluZygpOiBzaG91bGQgbm90IGhhcHBlbiIpOwotCQlyZXR1cm4gbmV3IFJlY3RhbmdsZSgwLCAwLCAxMDAsIDEwMCk7CisJCQlpbnQgaW1hZ2UgPSBkYXRhLmltYWdlLmhhbmRsZTsKKwkJCXdpZHRoID0gT1MuQ0dJbWFnZUdldFdpZHRoKGltYWdlKTsKKwkJCWhlaWdodCA9IE9TLkNHSW1hZ2VHZXRIZWlnaHQoaW1hZ2UpOworCQl9CisJCXJldHVybiBuZXcgUmVjdGFuZ2xlKDAsIDAsIHdpZHRoLCBoZWlnaHQpOwogCX0KLQlPUy5HZXRSZWdpb25Cb3VuZHMoZGF0YS5jbGlwUmduLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQlyZXR1cm4gYm91bmRzLnRvUmVjdGFuZ2xlKCk7CisJUmVjdCBib3VuZHMgPSBuZXcgUmVjdCgpOworCU9TLkdldFJlZ2lvbkJvdW5kcyhkYXRhLmNsaXBSZ24sIGJvdW5kcyk7CisJaW50IHdpZHRoID0gYm91bmRzLnJpZ2h0IC0gYm91bmRzLmxlZnQ7CisJaW50IGhlaWdodCA9IGJvdW5kcy5ib3R0b20gLSBib3VuZHMudG9wOworCXJldHVybiBuZXcgUmVjdGFuZ2xlKGJvdW5kcy5sZWZ0LCBib3VuZHMudG9wLCB3aWR0aCwgaGVpZ2h0KTsKIH0KKwogLyoqIAogICogU2V0cyB0aGUgcmVnaW9uIG1hbmFnZWQgYnkgdGhlIGFyZ3VtZW50IHRvIHRoZSBjdXJyZW50CiAgKiBjbGlwcGluZyByZWdpb24gb2YgdGhlIHJlY2VpdmVyLgpAQCAtMTQxMywzOCArMTIxMywyOCBAQAogICogICAgPGxpPkVSUk9SX0dSQVBISUNfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgogICogPC91bD4KICAqLwotcHVibGljIHZvaWQgZ2V0Q2xpcHBpbmcoUmVnaW9uIHJlZ2lvbikgeworcHVibGljIHZvaWQgZ2V0Q2xpcHBpbmcoUmVnaW9uIHJlZ2lvbikgewkKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7CiAJaWYgKHJlZ2lvbiA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCQotCWlmIChyZWdpb24uaGFuZGxlID09IDApCi0JCXJlZ2lvbi5oYW5kbGU9IE9TLk5ld1JnbigpOwotCQkKIAlpZiAoZGF0YS5jbGlwUmduID09IDApIHsKLQkJaWYgKGRhdGEuY29udHJvbEhhbmRsZSAhPSAwKSB7Ci0JCQlPUy5HZXRDb250cm9sUmVnaW9uKGRhdGEuY29udHJvbEhhbmRsZSwgT1Mua1dpbmRvd0NvbnRlbnRSZ24sIHJlZ2lvbi5oYW5kbGUpOwotCQl9IGVsc2UKLQkJCVN5c3RlbS5vdXQucHJpbnRsbigiR0MuZ2V0Q2xpcHBpbmcoUmVnaW9uKTogbnlpIik7Ci0JfSBlbHNlIHsKLQkJT1MuQ29weVJnbihkYXRhLmNsaXBSZ24sIHJlZ2lvbi5oYW5kbGUpOwotCX0KLQkKLQkvKiBBVwotCWlmIChjbGlwUmduID09IDApIHsKLQkJaW50W10gd2lkdGggPSBuZXcgaW50WzFdOyBpbnRbXSBoZWlnaHQgPSBuZXcgaW50WzFdOwotCQlpbnRbXSB1bnVzZWQgPSBuZXcgaW50WzFdOwotCQlPUy5YR2V0R2VvbWV0cnkoZGF0YS5kaXNwbGF5LCBkYXRhLmRyYXdhYmxlLCB1bnVzZWQsIHVudXNlZCwgdW51c2VkLCB3aWR0aCwgaGVpZ2h0LCB1bnVzZWQsIHVudXNlZCk7Ci0JCU9TLlhTdWJ0cmFjdFJlZ2lvbiAoaFJlZ2lvbiwgaFJlZ2lvbiwgaFJlZ2lvbik7Ci0JCVhSZWN0YW5nbGUgcmVjdCA9IG5ldyBYUmVjdGFuZ2xlKCk7Ci0JCXJlY3QueCA9IDA7IHJlY3QueSA9IDA7Ci0JCXJlY3Qud2lkdGggPSAoc2hvcnQpd2lkdGhbMF07IHJlY3QuaGVpZ2h0ID0gKHNob3J0KWhlaWdodFswXTsKLQkJT1MuWFVuaW9uUmVjdFdpdGhSZWdpb24ocmVjdCwgaFJlZ2lvbiwgaFJlZ2lvbik7CisJCWludCB3aWR0aCA9IDAsIGhlaWdodCA9IDA7CisJCWlmIChkYXRhLmNvbnRyb2wgIT0gMCkgeworCQkJUmVjdCBib3VuZHMgPSBuZXcgUmVjdCgpOworCQkJT1MuR2V0Q29udHJvbEJvdW5kcyhkYXRhLmNvbnRyb2wsIGJvdW5kcyk7CisJCQl3aWR0aCA9IGJvdW5kcy5yaWdodCAtIGJvdW5kcy5sZWZ0OworCQkJaGVpZ2h0ID0gYm91bmRzLmJvdHRvbSAtIGJvdW5kcy50b3A7CisJCX0KKwkJaWYgKGRhdGEuaW1hZ2UgIT0gbnVsbCkgeworCQkJaW50IGltYWdlID0gZGF0YS5pbWFnZS5oYW5kbGU7CisJCQl3aWR0aCA9IE9TLkNHSW1hZ2VHZXRXaWR0aChpbWFnZSk7CisJCQloZWlnaHQgPSBPUy5DR0ltYWdlR2V0SGVpZ2h0KGltYWdlKTsKKwkJfQorCQlPUy5TZXRSZWN0UmduKHJlZ2lvbi5oYW5kbGUsIChzaG9ydCkgMCwgKHNob3J0KSAwLCAoc2hvcnQpIHdpZHRoLCAoc2hvcnQpIGhlaWdodCk7CiAJCXJldHVybjsKIAl9Ci0JT1MuWFN1YnRyYWN0UmVnaW9uIChoUmVnaW9uLCBoUmVnaW9uLCBoUmVnaW9uKTsKLQlPUy5YVW5pb25SZWdpb24gKGNsaXBSZ24sIGhSZWdpb24sIGhSZWdpb24pOwotCSovCisJT1MuQ29weVJnbihkYXRhLmNsaXBSZ24sIHJlZ2lvbi5oYW5kbGUpOwogfQorCiAvKiogCiAgKiBSZXR1cm5zIHRoZSBmb250IGN1cnJlbnRseSBiZWluZyB1c2VkIGJ5IHRoZSByZWNlaXZlcgogICogdG8gZHJhdyBhbmQgbWVhc3VyZSB0ZXh0LgpAQCAtMTQ1NSwyMSArMTI0NSwxMSBAQAogICogICAgPGxpPkVSUk9SX0dSQVBISUNfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgogICogPC91bD4KICAqLwotcHVibGljIEZvbnQgZ2V0Rm9udCAoKSB7CitwdWJsaWMgRm9udCBnZXRGb250KCkgewogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQlyZXR1cm4gRm9udC5jYXJib25fbmV3KGRhdGEuZGV2aWNlLCBkYXRhLmZvbnQpOworCXJldHVybiBkYXRhLmZvbnQ7CiB9Ci1pbnQgZ2V0Rm9udEhlaWdodCAoKSB7Ci0JdHJ5IHsKLQkJZm9jdXMoZmFsc2UsIG51bGwpOwotCQlpbnN0YWxsRm9udCgpOwotCQlzaG9ydFtdIGZvbnRJbmZvPSBuZXcgc2hvcnRbNF07Ci0JCU9TLkdldEZvbnRJbmZvKGZvbnRJbmZvKTsJLy8gRm9udEluZm8KLQkJcmV0dXJuIGZvbnRJbmZvWzBdICsgZm9udEluZm9bMV07Ci0JfSBmaW5hbGx5IHsKLQkJdW5mb2N1cyhmYWxzZSk7Ci0JfQotfQorCiAvKioKICAqIFJldHVybnMgYSBGb250TWV0cmljcyB3aGljaCBjb250YWlucyBpbmZvcm1hdGlvbgogICogYWJvdXQgdGhlIGZvbnQgY3VycmVudGx5IGJlaW5nIHVzZWQgYnkgdGhlIHJlY2VpdmVyCkBAIC0xNDgzLDE5ICsxMjYzLDIxIEBACiAgKi8KIHB1YmxpYyBGb250TWV0cmljcyBnZXRGb250TWV0cmljcygpIHsKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JCi0JdHJ5IHsKLQkJZm9jdXMoZmFsc2UsIG51bGwpOwotCQlpbnN0YWxsRm9udCgpOwotCQlzaG9ydFtdIGZvbnRJbmZvPSBuZXcgc2hvcnRbNF07Ci0JCU9TLkdldEZvbnRJbmZvKGZvbnRJbmZvKTsJLy8gRm9udEluZm8KLQkJU3RyaW5nIHM9ICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiI7Ci0JCWludCB3aWR0aD0gT1MuVGV4dFdpZHRoKHMsIGRhdGEuZm9udC5mSUQsIGRhdGEuZm9udC5mU2l6ZSwgZGF0YS5mb250LmZGYWNlKSAvIDI2OwotCQlyZXR1cm4gRm9udE1ldHJpY3MuY2FyYm9uX25ldyhmb250SW5mb1swXSwgZm9udEluZm9bMV0sIHdpZHRoLCBmb250SW5mb1szXSwgZm9udEluZm9bMF0rZm9udEluZm9bMV0pOwotCX0gZmluYWxseSB7Ci0JCXVuZm9jdXMoZmFsc2UpOwkKLQl9CisJRm9udCBmb250ID0gZGF0YS5mb250OworCUZvbnRJbmZvIGluZm8gPSBuZXcgRm9udEluZm8oKTsKKwlPUy5GZXRjaEZvbnRJbmZvKGZvbnQuaWQsIGZvbnQuc2l6ZSwgZm9udC5zdHlsZSwgaW5mbyk7CisJRm9udE1ldHJpY3MgZm0gPSBuZXcgRm9udE1ldHJpY3MoKTsKKwlmbS5hc2NlbnQgPSBpbmZvLmFzY2VudDsKKwlmbS5kZXNjZW50ID0gaW5mby5kZXNjZW50OworCWZtLmxlYWRpbmcgPSBpbmZvLmxlYWRpbmc7CisJLyogVGhpcyBjb2RlIGlzIGludGVudGlvbmFseSBjb21tZW50LiBOb3QgcmlnaHQgZm9yIGZpeGVkIHdpZHRoIGZvbnRzLiAqLworCS8vZm0uYXZlcmFnZUNoYXJXaWR0aCA9IGluZm8ud2lkTWF4IC8gMzsKKwlTdHJpbmcgcyA9ICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ekFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQ1Njc4OSI7IAorCWZtLmF2ZXJhZ2VDaGFyV2lkdGggPSBzdHJpbmdFeHRlbnQocykueCAvIHMubGVuZ3RoKCk7CisJZm0uaGVpZ2h0ID0gZm0uYXNjZW50ICsgZm0uZGVzY2VudDsKKwlyZXR1cm4gZm07CiB9CisKIC8qKiAKICAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3MgZm9yZWdyb3VuZCBjb2xvci4KICAqCkBAIC0xNTA1LDE5ICsxMjg3LDExIEBACiAgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgQ29sb3IgZ2V0Rm9yZWdyb3VuZCgpIHsKLQlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JLyogQVcKLQlpbnQgeERpc3BsYXkgPSBkYXRhLmRpc3BsYXk7Ci0JWEdDVmFsdWVzIHZhbHVlcyA9IG5ldyBYR0NWYWx1ZXMoKTsKLQlPUy5YR2V0R0NWYWx1ZXMoeERpc3BsYXksIGhhbmRsZSwgT1MuR0NGb3JlZ3JvdW5kLCB2YWx1ZXMpOwotCVhDb2xvciB4Q29sb3IgPSBuZXcgWENvbG9yKCk7Ci0JeENvbG9yLnBpeGVsID0gdmFsdWVzLmZvcmVncm91bmQ7Ci0JT1MuWFF1ZXJ5Q29sb3IoeERpc3BsYXksZGF0YS5jb2xvcm1hcCx4Q29sb3IpOwotCXJldHVybiBDb2xvci5tb3RpZl9uZXcoZGF0YS5kZXZpY2UsIHhDb2xvcik7Ci0JKi8KLQlyZXR1cm4gQ29sb3IuY2FyYm9uX25ldyhkYXRhLmRldmljZSwgZGF0YS5mb3JlZ3JvdW5kLCBmYWxzZSk7CitwdWJsaWMgQ29sb3IgZ2V0Rm9yZWdyb3VuZCgpIHsJCisJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX1dJREdFVF9ESVNQT1NFRCk7CisJcmV0dXJuIENvbG9yLmNhcmJvbl9uZXcoZGF0YS5kZXZpY2UsIGRhdGEuZm9yZWdyb3VuZCk7CQogfQorCiAvKiogCiAgKiBSZXR1cm5zIHRoZSByZWNlaXZlcidzIGxpbmUgc3R5bGUsIHdoaWNoIHdpbGwgYmUgb25lCiAgKiBvZiB0aGUgY29uc3RhbnRzIDxjb2RlPlNXVC5MSU5FX1NPTElEPC9jb2RlPiwgPGNvZGU+U1dULkxJTkVfREFTSDwvY29kZT4sCkBAIC0xNTM0LDYgKzEzMDgsNyBAQAogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKIAlyZXR1cm4gZGF0YS5saW5lU3R5bGU7CiB9CisKIC8qKiAKICAqIFJldHVybnMgdGhlIHdpZHRoIHRoYXQgd2lsbCBiZSB1c2VkIHdoZW4gZHJhd2luZyBsaW5lcwogICogZm9yIGFsbCBvZiB0aGUgZmlndXJlIGRyYXdpbmcgb3BlcmF0aW9ucyAodGhhdCBpcywKQEAgLTE1NDgsMTMgKzEzMjMsOSBAQAogICovCiBwdWJsaWMgaW50IGdldExpbmVXaWR0aCgpIHsKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JLyogQVcKLQlYR0NWYWx1ZXMgdmFsdWVzID0gbmV3IFhHQ1ZhbHVlcygpOwotCU9TLlhHZXRHQ1ZhbHVlcyhkYXRhLmRpc3BsYXksIGhhbmRsZSwgT1MuR0NMaW5lV2lkdGgsIHZhbHVlcyk7Ci0JcmV0dXJuIHZhbHVlcy5saW5lX3dpZHRoOwotCSovCi0JcmV0dXJuIGZMaW5lV2lkdGg7CisJcmV0dXJuIGRhdGEubGluZVdpZHRoOwogfQorCiAvKiogCiAgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoaXMgR0MgaXMgZHJhd2luZyBpbiB0aGUgbW9kZQogICogd2hlcmUgdGhlIHJlc3VsdGluZyBjb2xvciBpbiB0aGUgZGVzdGluYXRpb24gaXMgdGhlCkBAIC0xNTcxLDEzICsxMzQyLDkgQEAKICAqLwogcHVibGljIGJvb2xlYW4gZ2V0WE9STW9kZSgpIHsKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JLyogQVcKLQlYR0NWYWx1ZXMgdmFsdWVzID0gbmV3IFhHQ1ZhbHVlcyAoKTsKLQlPUy5YR2V0R0NWYWx1ZXMgKGRhdGEuZGlzcGxheSwgaGFuZGxlLCBPUy5HQ0Z1bmN0aW9uLCB2YWx1ZXMpOwotCXJldHVybiB2YWx1ZXMuZnVuY3Rpb24gPT0gT1MuR1h4b3I7Ci0JKi8KLQlyZXR1cm4gZlhvck1vZGU7CisJcmV0dXJuIGRhdGEueG9yTW9kZTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGUgcmVjZWl2ZXIuIEFueSB0d28gCiAgKiBvYmplY3RzIHdoaWNoIHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHBhc3NlZCB0byAKQEAgLTE1OTIsMTcgKzEzNTksMzYgQEAKICAqCiAgKiBAc2VlICNlcXVhbHMKICAqLwotcHVibGljIGludCBoYXNoQ29kZSAoKSB7CitwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogCXJldHVybiBoYW5kbGU7CiB9Ci12b2lkIGluaXQoRHJhd2FibGUgZHJhd2FibGUsIEdDRGF0YSBkYXRhLCBpbnQgeEdDKSB7Ci0JLyogQVcKLQlpbnQgeERpc3BsYXkgPSBkYXRhLmRpc3BsYXk7Ci0JaW50IGZvcmVncm91bmQgPSBkYXRhLmZvcmVncm91bmQ7Ci0JaWYgKGZvcmVncm91bmQgIT0gLTEpIE9TLlhTZXRGb3JlZ3JvdW5kICh4RGlzcGxheSwgeEdDLCBmb3JlZ3JvdW5kKTsKLQlpbnQgYmFja2dyb3VuZCA9IGRhdGEuYmFja2dyb3VuZDsKLQlpZiAoYmFja2dyb3VuZCAhPSAtMSkgT1MuWFNldEJhY2tncm91bmQgKHhEaXNwbGF5LCB4R0MsIGJhY2tncm91bmQpOwotCSovCisKK3ZvaWQgaW5pdChEcmF3YWJsZSBkcmF3YWJsZSwgR0NEYXRhIGRhdGEsIGludCBjb250ZXh0KSB7CisJaW50IGNvbG9yc3BhY2UgPSBkYXRhLmRldmljZS5jb2xvcnNwYWNlOworCU9TLkNHQ29udGV4dFNldFN0cm9rZUNvbG9yU3BhY2UoY29udGV4dCwgY29sb3JzcGFjZSk7CisJT1MuQ0dDb250ZXh0U2V0RmlsbENvbG9yU3BhY2UoY29udGV4dCwgY29sb3JzcGFjZSk7CisJZmxvYXRbXSBmb3JlZ3JvdW5kID0gZGF0YS5mb3JlZ3JvdW5kOworCWlmIChmb3JlZ3JvdW5kICE9IG51bGwpIE9TLkNHQ29udGV4dFNldFN0cm9rZUNvbG9yKGNvbnRleHQsIGZvcmVncm91bmQpOworCWZsb2F0W10gYmFja2dyb3VuZCA9IGRhdGEuYmFja2dyb3VuZDsKKwlpZiAoYmFja2dyb3VuZCAhPSBudWxsKSBPUy5DR0NvbnRleHRTZXRGaWxsQ29sb3IoY29udGV4dCwgYmFja2dyb3VuZCk7CisKKwlpbnRbXSBidWZmZXIgPSBuZXcgaW50WzFdOworCU9TLkFUU1VDcmVhdGVUZXh0TGF5b3V0KGJ1ZmZlcik7CisJaWYgKGJ1ZmZlclswXSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCWRhdGEubGF5b3V0ID0gYnVmZmVyWzBdOworCU9TLkFUU1VDcmVhdGVTdHlsZShidWZmZXIpOworCWlmIChidWZmZXJbMF0gPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwlkYXRhLnN0eWxlID0gYnVmZmVyWzBdOworCQorCWludCBwdHIgPSBPUy5OZXdQdHIoNCk7CisJYnVmZmVyWzBdID0gY29udGV4dDsKKwlPUy5tZW1jcHkocHRyLCBidWZmZXIsIDQpOworCWludFtdIHRhZ3MgPSBuZXcgaW50W117T1Mua0FUU1VDR0NvbnRleHRUYWd9OworCWludFtdIHNpemVzID0gbmV3IGludFtdezR9OworCWludFtdIHZhbHVlcyA9IG5ldyBpbnRbXXtwdHJ9OworCU9TLkFUU1VTZXRMYXlvdXRDb250cm9scyhkYXRhLmxheW91dCwgdGFncy5sZW5ndGgsIHRhZ3MsIHNpemVzLCB2YWx1ZXMpOworCU9TLkRpc3Bvc2VQdHIocHRyKTsKKwogCUltYWdlIGltYWdlID0gZGF0YS5pbWFnZTsKIAlpZiAoaW1hZ2UgIT0gbnVsbCkgewogCQlpbWFnZS5tZW1HQyA9IHRoaXM7CkBAIC0xNjExLDE0ICsxMzk3LDE2IEBACiAJCSAqIHRoZSBpbWFnZS4gIERlc3Ryb3kgaXQgc28gdGhhdCBpdCBpcyByZWdlbmVyYXRlZCB3aGVuCiAJCSAqIG5lY2Vzc2FyeS4KIAkJICovCi0JCWlmIChpbWFnZS50cmFuc3BhcmVudFBpeGVsICE9IC0xKSBpbWFnZS5kZXN0cm95TWFzaygpOworLy8JCWlmIChpbWFnZS50cmFuc3BhcmVudFBpeGVsICE9IC0xKSBpbWFnZS5kZXN0cm95TWFzaygpOwogCX0KIAl0aGlzLmRyYXdhYmxlID0gZHJhd2FibGU7CiAJdGhpcy5kYXRhID0gZGF0YTsKLQlpZiAoeEdDID09IDApCi0JCVNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JaGFuZGxlID0geEdDOworCWhhbmRsZSA9IGNvbnRleHQ7CisKKwlGb250IGZvbnQgPSBkYXRhLmZvbnQ7CisJaWYgKGZvbnQgIT0gbnVsbCkgc2V0Rm9udChmb250KTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSByZWNlaXZlciBoYXMgYSBjbGlwcGluZwogICogcmVnaW9uIHNldCBpbnRvIGl0LCBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KQEAgLTE2MzUsOSArMTQyMyw5IEBACiAgKi8KIHB1YmxpYyBib29sZWFuIGlzQ2xpcHBlZCgpIHsKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JU3lzdGVtLm91dC5wcmludGxuKCJHQy5pc0NsaXBwZWQ6IG55aSIpOwogCXJldHVybiBkYXRhLmNsaXBSZ24gIT0gMDsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBHQyBoYXMgYmVlbiBkaXNwb3NlZCwKICAqIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgpAQCAtMTY1MSwxMiArMTQzOSw3IEBACiBwdWJsaWMgYm9vbGVhbiBpc0Rpc3Bvc2VkKCkgewogCXJldHVybiBoYW5kbGUgPT0gMDsKIH0KLXB1YmxpYyBzdGF0aWMgR0MgbWFjb3N4X25ldyhEcmF3YWJsZSBkcmF3YWJsZSwgR0NEYXRhIGRhdGEpIHsKLQlHQyBnYyA9IG5ldyBHQygpOwotCWludCB4R0MgPSBkcmF3YWJsZS5pbnRlcm5hbF9uZXdfR0MoZGF0YSk7Ci0JZ2MuaW5pdChkcmF3YWJsZSwgZGF0YSwgeEdDKTsKLQlyZXR1cm4gZ2M7Ci19CisKIC8qKgogICogU2V0cyB0aGUgYmFja2dyb3VuZCBjb2xvci4gVGhlIGJhY2tncm91bmQgY29sb3IgaXMgdXNlZAogICogZm9yIGZpbGwgb3BlcmF0aW9ucyBhbmQgYXMgdGhlIGJhY2tncm91bmQgY29sb3Igd2hlbiB0ZXh0CkBAIC0xNjcyLDEyICsxNDU1LDE0IEBACiAgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgdm9pZCBzZXRCYWNrZ3JvdW5kIChDb2xvciBjb2xvcikgeworcHVibGljIHZvaWQgc2V0QmFja2dyb3VuZChDb2xvciBjb2xvcikgewogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKIAlpZiAoY29sb3IgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlpZiAoY29sb3IuaXNEaXNwb3NlZCgpKSBTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwotCWRhdGEuYmFja2dyb3VuZD0gY29sb3IuaGFuZGxlOworCWRhdGEuYmFja2dyb3VuZCA9IGNvbG9yLmhhbmRsZTsKKwlPUy5DR0NvbnRleHRTZXRGaWxsQ29sb3IoaGFuZGxlLCBjb2xvci5oYW5kbGUpOwogfQorCiAvKioKICAqIFNldHMgdGhlIGFyZWEgb2YgdGhlIHJlY2VpdmVyIHdoaWNoIGNhbiBiZSBjaGFuZ2VkCiAgKiBieSBkcmF3aW5nIG9wZXJhdGlvbnMgdG8gdGhlIHJlY3Rhbmd1bGFyIGFyZWEgc3BlY2lmaWVkCkBAIC0xNjkyLDEzICsxNDc3LDEzIEBACiAgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgdm9pZCBzZXRDbGlwcGluZyAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKK3B1YmxpYyB2b2lkIHNldENsaXBwaW5nKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CiAJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwotCWlmIChkYXRhLmNsaXBSZ24gPT0gMCkKLQkJZGF0YS5jbGlwUmduID0gT1MuTmV3UmduICgpOwotCU9TLlNldFJlY3RSZ24oZGF0YS5jbGlwUmduLCAoc2hvcnQpIHgsIChzaG9ydCkgeSwgKHNob3J0KSAoeCt3aWR0aCksIChzaG9ydCkgKHkraGVpZ2h0KSk7Ci0JZlBlbmRpbmdDbGlwPSB0cnVlOworCWlmIChkYXRhLmNsaXBSZ24gPT0gMCkgZGF0YS5jbGlwUmduID0gT1MuTmV3UmduKCk7CisJT1MuU2V0UmVjdFJnbihkYXRhLmNsaXBSZ24sIChzaG9ydCl4LCAoc2hvcnQpeSwgKHNob3J0KSh4ICsgd2lkdGgpLCAoc2hvcnQpKHkgKyBoZWlnaHQpKTsKKwlzZXRDR0NsaXBwaW5nKCk7CiB9CisKIC8qKgogICogU2V0cyB0aGUgYXJlYSBvZiB0aGUgcmVjZWl2ZXIgd2hpY2ggY2FuIGJlIGNoYW5nZWQKICAqIGJ5IGRyYXdpbmcgb3BlcmF0aW9ucyB0byB0aGUgcmVjdGFuZ3VsYXIgYXJlYSBzcGVjaWZpZWQKQEAgLTE3MTAsMTggKzE0OTUsMjIgQEAKICAqICAgIDxsaT5FUlJPUl9HUkFQSElDX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KICAqIDwvdWw+CiAgKi8KLXB1YmxpYyB2b2lkIHNldENsaXBwaW5nIChSZWN0YW5nbGUgcmVjdCkgeworcHVibGljIHZvaWQgc2V0Q2xpcHBpbmcoUmVjdGFuZ2xlIHIpIHsKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JaWYgKHJlY3QgPT0gbnVsbCkgeworCWlmIChyID09IG51bGwpIHsKIAkJaWYgKGRhdGEuY2xpcFJnbiAhPSAwKSB7CiAJCQlPUy5EaXNwb3NlUmduKGRhdGEuY2xpcFJnbik7Ci0JCQlkYXRhLmNsaXBSZ249IDA7CisJCQlkYXRhLmNsaXBSZ24gPSAwOworCQl9IGVsc2UgeworCQkJcmV0dXJuOwogCQl9Ci0JCWZQZW5kaW5nQ2xpcD0gdHJ1ZTsKLQkJcmV0dXJuOworCX0gZWxzZSB7CisJCWlmIChkYXRhLmNsaXBSZ24gPT0gMCkgZGF0YS5jbGlwUmduID0gT1MuTmV3UmduKCk7CisJCU9TLlNldFJlY3RSZ24oZGF0YS5jbGlwUmduLCAoc2hvcnQpci54LCAoc2hvcnQpci55LCAoc2hvcnQpKHIueCArIHIud2lkdGgpLCAoc2hvcnQpKHIueSArIHIuaGVpZ2h0KSk7CiAJfQotCXNldENsaXBwaW5nIChyZWN0LngsIHJlY3QueSwgcmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpOworCXNldENHQ2xpcHBpbmcoKTsKIH0KKwogLyoqCiAgKiBTZXRzIHRoZSBhcmVhIG9mIHRoZSByZWNlaXZlciB3aGljaCBjYW4gYmUgY2hhbmdlZAogICogYnkgZHJhd2luZyBvcGVyYXRpb25zIHRvIHRoZSByZWdpb24gc3BlY2lmaWVkCkBAIC0xNzMzLDIwICsxNTIyLDU5IEBACiAgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgdm9pZCBzZXRDbGlwcGluZyAoUmVnaW9uIHJlZ2lvbikgeworcHVibGljIHZvaWQgc2V0Q2xpcHBpbmcoUmVnaW9uIHJlZ2lvbikgewogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKIAlpZiAocmVnaW9uID09IG51bGwpIHsKIAkJaWYgKGRhdGEuY2xpcFJnbiAhPSAwKSB7Ci0JCQlPUy5EaXNwb3NlUmduIChkYXRhLmNsaXBSZ24pOworCQkJT1MuRGlzcG9zZVJnbihkYXRhLmNsaXBSZ24pOwogCQkJZGF0YS5jbGlwUmduID0gMDsKKwkJfSBlbHNlIHsKKwkJCXJldHVybjsKIAkJfQogCX0gZWxzZSB7Ci0JCWlmIChkYXRhLmNsaXBSZ24gPT0gMCkKLQkJCWRhdGEuY2xpcFJnbiA9IE9TLk5ld1JnbigpOworCQlpZiAoZGF0YS5jbGlwUmduID09IDApIGRhdGEuY2xpcFJnbiA9IE9TLk5ld1JnbigpOwogCQlPUy5Db3B5UmduKHJlZ2lvbi5oYW5kbGUsIGRhdGEuY2xpcFJnbik7CiAJfQotCWZQZW5kaW5nQ2xpcD0gdHJ1ZTsKKwlzZXRDR0NsaXBwaW5nKCk7CiB9CisKK3ZvaWQgc2V0Q0dDbGlwcGluZyAoKSB7CisJaWYgKGRhdGEuY29udHJvbCA9PSAwKSB7CisJCU9TLkNHQ29udGV4dFNjYWxlQ1RNKGhhbmRsZSwgMSwgLTEpOworCQlpZiAoZGF0YS5jbGlwUmduICE9IDApIHsKKwkJCU9TLkNsaXBDR0NvbnRleHRUb1JlZ2lvbihoYW5kbGUsIG5ldyBSZWN0KCksIGRhdGEuY2xpcFJnbik7CisJCX0gZWxzZSB7CisJCQlpbnQgcmduID0gT1MuTmV3UmduKCk7CisJCQlPUy5TZXRSZWN0UmduKHJnbiwgKHNob3J0KS0zMjc2OCwgKHNob3J0KS0zMjc2OCwgKHNob3J0KTMyNzY3LCAoc2hvcnQpMzI3NjcpOworCQkJT1MuQ2xpcENHQ29udGV4dFRvUmVnaW9uKGhhbmRsZSwgbmV3IFJlY3QoKSwgcmduKTsKKwkJCU9TLkRpc3Bvc2VSZ24ocmduKTsKKwkJfQorCQlPUy5DR0NvbnRleHRTY2FsZUNUTShoYW5kbGUsIDEsIC0xKTsKKwkJcmV0dXJuOworCX0KKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyKGRhdGEuY29udHJvbCk7CisJaW50IHBvcnQgPSBPUy5HZXRXaW5kb3dQb3J0KHdpbmRvdyk7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzKGRhdGEuY29udHJvbCwgcmVjdCk7CisJUmVjdCBwb3J0UmVjdCA9IG5ldyBSZWN0KCk7CisJT1MuR2V0UG9ydEJvdW5kcyhwb3J0LCBwb3J0UmVjdCk7CisJaW50IHBvcnRIZWlnaHQgPSBwb3J0UmVjdC5ib3R0b20gLSBwb3J0UmVjdC50b3A7CisJT1MuQ0dDb250ZXh0VHJhbnNsYXRlQ1RNKGhhbmRsZSwgLXJlY3QubGVmdCwgcG9ydEhlaWdodCAtIHJlY3QudG9wKTsKKwlPUy5DR0NvbnRleHRTY2FsZUNUTShoYW5kbGUsIDEsIC0xKTsKKwlpZiAoZGF0YS5jbGlwUmduICE9IDApIHsgCisJCWludCByZ24gPSBPUy5OZXdSZ24oKTsKKwkJT1MuQ29weVJnbihkYXRhLmNsaXBSZ24sIHJnbik7CisJCU9TLk9mZnNldFJnbihyZ24sIHJlY3QubGVmdCwgcmVjdC50b3ApOworCQlPUy5TZWN0UmduKGRhdGEudmlzaWJsZVJnbiwgcmduLCByZ24pOworCQlPUy5DbGlwQ0dDb250ZXh0VG9SZWdpb24oaGFuZGxlLCBwb3J0UmVjdCwgcmduKTsKKwkJT1MuRGlzcG9zZVJnbihyZ24pOworCX0gZWxzZSB7CisJCU9TLkNsaXBDR0NvbnRleHRUb1JlZ2lvbihoYW5kbGUsIHBvcnRSZWN0LCBkYXRhLnZpc2libGVSZ24pOworCX0KKwlPUy5DR0NvbnRleHRTY2FsZUNUTShoYW5kbGUsIDEsIC0xKTsKKwlPUy5DR0NvbnRleHRUcmFuc2xhdGVDVE0oaGFuZGxlLCByZWN0LmxlZnQsIC1wb3J0SGVpZ2h0ICsgcmVjdC50b3ApOworfQorCiAvKiogCiAgKiBTZXRzIHRoZSBmb250IHdoaWNoIHdpbGwgYmUgdXNlZCBieSB0aGUgcmVjZWl2ZXIKICAqIHRvIGRyYXcgYW5kIG1lYXN1cmUgdGV4dCB0byB0aGUgYXJndW1lbnQuIElmIHRoZQpAQCAtMTc2MiwxNSArMTU5MCwyNyBAQAogICogICAgPGxpPkVSUk9SX0dSQVBISUNfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgogICogPC91bD4KICAqLwotcHVibGljIHZvaWQgc2V0Rm9udCAoRm9udCBmb250KSB7CitwdWJsaWMgdm9pZCBzZXRGb250KEZvbnQgZm9udCkgewogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQlpZiAoZm9udCA9PSBudWxsKSB7Ci0JCWRhdGEuZm9udCA9IGRhdGEuZGV2aWNlLnN5c3RlbUZvbnQ7Ci0JfSBlbHNlIHsKLQkJaWYgKGZvbnQuaXNEaXNwb3NlZCgpKSBTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwotCQlkYXRhLmZvbnQgPSBmb250LmhhbmRsZTsKLQl9CisJaWYgKGZvbnQgPT0gbnVsbCkgZm9udCA9IGRhdGEuZGV2aWNlLnN5c3RlbUZvbnQ7CisJaWYgKGZvbnQuaXNEaXNwb3NlZCgpKSBTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCWRhdGEuZm9udCA9IGZvbnQ7CisJaW50IHB0ciA9IE9TLk5ld1B0cigxNik7CisJT1MubWVtY3B5KHB0ciwgbmV3IGludFtde2ZvbnQuaGFuZGxlfSwgNCk7IAorCU9TLm1lbWNweShwdHIgKyA0LCBuZXcgaW50W117Zm9udC5zaXplIDw8IDE2fSwgNCk7IAorCU9TLm1lbWNweShwdHIgKyA4LCBuZXcgYnl0ZVtdeyhmb250LnN0eWxlICYgT1MuYm9sZCkgIT0gMCA/IChieXRlKTEgOiAwfSwgMSk7IAorCU9TLm1lbWNweShwdHIgKyA5LCBuZXcgYnl0ZVtdeyhmb250LnN0eWxlICYgT1MuaXRhbGljKSAhPSAwID8gKGJ5dGUpMSA6IDB9LCAxKTsgCisJaW50W10gdGFncyA9IG5ldyBpbnRbXXtPUy5rQVRTVUZvbnRUYWcsIE9TLmtBVFNVU2l6ZVRhZywgT1Mua0FUU1VRREJvbGRmYWNlVGFnLCBPUy5rQVRTVVFESXRhbGljVGFnfTsKKwlpbnRbXSBzaXplcyA9IG5ldyBpbnRbXXs0LCA0LCAxLCAxfTsKKwlpbnRbXSB2YWx1ZXMgPSBuZXcgaW50W117cHRyLCBwdHIgKyA0LCBwdHIgKyA4LCBwdHIgKyA5fTsKKwlPUy5BVFNVU2V0QXR0cmlidXRlcyhkYXRhLnN0eWxlLCB0YWdzLmxlbmd0aCwgdGFncywgc2l6ZXMsIHZhbHVlcyk7CisJT1MuRGlzcG9zZVB0cihwdHIpOworCUZvbnRJbmZvIGluZm8gPSBuZXcgRm9udEluZm8oKTsKKwlPUy5GZXRjaEZvbnRJbmZvKGZvbnQuaWQsIGZvbnQuc2l6ZSwgZm9udC5zdHlsZSwgaW5mbyk7CisJZGF0YS5mb250QXNjZW50ID0gaW5mby5hc2NlbnQ7CisJZGF0YS5mb250RGVzY2VudCA9IGluZm8uZGVzY2VudDsKIH0KKwogLyoqCiAgKiBTZXRzIHRoZSBmb3JlZ3JvdW5kIGNvbG9yLiBUaGUgZm9yZWdyb3VuZCBjb2xvciBpcyB1c2VkCiAgKiBmb3IgZHJhd2luZyBvcGVyYXRpb25zIGluY2x1ZGluZyB3aGVuIHRleHQgaXMgZHJhd24uCkBAIC0xNzg1LDEyICsxNjI1LDE0IEBACiAgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgdm9pZCBzZXRGb3JlZ3JvdW5kIChDb2xvciBjb2xvcikgeworcHVibGljIHZvaWQgc2V0Rm9yZWdyb3VuZChDb2xvciBjb2xvcikgewkKIAlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7CiAJaWYgKGNvbG9yID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaWYgKGNvbG9yLmlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKLQlkYXRhLmZvcmVncm91bmQ9IGNvbG9yLmhhbmRsZTsKKwlkYXRhLmZvcmVncm91bmQgPSBjb2xvci5oYW5kbGU7CisJT1MuQ0dDb250ZXh0U2V0U3Ryb2tlQ29sb3IoaGFuZGxlLCBjb2xvci5oYW5kbGUpOwogfQorCiAvKiogCiAgKiBTZXRzIHRoZSByZWNlaXZlcidzIGxpbmUgc3R5bGUgdG8gdGhlIGFyZ3VtZW50LCB3aGljaCBtdXN0IGJlIG9uZQogICogb2YgdGhlIGNvbnN0YW50cyA8Y29kZT5TV1QuTElORV9TT0xJRDwvY29kZT4sIDxjb2RlPlNXVC5MSU5FX0RBU0g8L2NvZGU+LApAQCAtMTgwNSwzMiArMTY0NywyOCBAQAogICovCiBwdWJsaWMgdm9pZCBzZXRMaW5lU3R5bGUoaW50IGxpbmVTdHlsZSkgewogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQkvKiBBVwotCWludCB4RGlzcGxheSA9IGRhdGEuZGlzcGxheTsKIAlzd2l0Y2ggKGxpbmVTdHlsZSkgewogCQljYXNlIFNXVC5MSU5FX1NPTElEOgotCQkJZGF0YS5saW5lU3R5bGUgPSBsaW5lU3R5bGU7Ci0JCQlPUy5YU2V0TGluZUF0dHJpYnV0ZXMoeERpc3BsYXksIGhhbmRsZSwgMCwgT1MuTGluZVNvbGlkLCBPUy5DYXBCdXR0LCBPUy5Kb2luTWl0ZXIpOwotCQkJcmV0dXJuOworCQkJT1MuQ0dDb250ZXh0U2V0TGluZURhc2goaGFuZGxlLCAwLCBudWxsLCAwKTsKKwkJCWJyZWFrOwogCQljYXNlIFNXVC5MSU5FX0RBU0g6Ci0JCQlPUy5YU2V0RGFzaGVzKHhEaXNwbGF5LGhhbmRsZSwwLCBuZXcgYnl0ZVtdIHs2LCAyfSwyKTsKKwkJCU9TLkNHQ29udGV4dFNldExpbmVEYXNoKGhhbmRsZSwgMCwgbmV3IGZsb2F0W117MTgsIDZ9LCAyKTsKIAkJCWJyZWFrOwogCQljYXNlIFNXVC5MSU5FX0RPVDoKLQkJCU9TLlhTZXREYXNoZXMoeERpc3BsYXksaGFuZGxlLDAsIG5ldyBieXRlW10gezMsIDF9LDIpOworCQkJT1MuQ0dDb250ZXh0U2V0TGluZURhc2goaGFuZGxlLCAwLCBuZXcgZmxvYXRbXXszLCAzfSwgMik7CiAJCQlicmVhazsKIAkJY2FzZSBTV1QuTElORV9EQVNIRE9UOgotCQkJT1MuWFNldERhc2hlcyh4RGlzcGxheSxoYW5kbGUsMCwgbmV3IGJ5dGVbXSB7NiwgMiwgMywgMX0sNCk7CisJCQlPUy5DR0NvbnRleHRTZXRMaW5lRGFzaChoYW5kbGUsIDAsIG5ldyBmbG9hdFtdezksIDYsIDMsIDZ9LCA0KTsKIAkJCWJyZWFrOwogCQljYXNlIFNXVC5MSU5FX0RBU0hET1RET1Q6Ci0JCQlPUy5YU2V0RGFzaGVzKHhEaXNwbGF5LGhhbmRsZSwwLCBuZXcgYnl0ZVtdIHs2LCAyLCAzLCAxLCAzLCAxfSw2KTsKKwkJCU9TLkNHQ29udGV4dFNldExpbmVEYXNoKGhhbmRsZSwgMCwgbmV3IGZsb2F0W117OSwgMywgMywgMywgMywgM30sIDYpOwogCQkJYnJlYWs7CiAJCWRlZmF1bHQ6CiAJCQlTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwogCX0KIAlkYXRhLmxpbmVTdHlsZSA9IGxpbmVTdHlsZTsKLQlPUy5YU2V0TGluZUF0dHJpYnV0ZXMoeERpc3BsYXksIGhhbmRsZSwgMCwgT1MuTGluZURvdWJsZURhc2gsIE9TLkNhcEJ1dHQsIE9TLkpvaW5NaXRlcik7Ci0JKi8KIH0KKwogLyoqIAogICogU2V0cyB0aGUgd2lkdGggdGhhdCB3aWxsIGJlIHVzZWQgd2hlbiBkcmF3aW5nIGxpbmVzCiAgKiBmb3IgYWxsIG9mIHRoZSBmaWd1cmUgZHJhd2luZyBvcGVyYXRpb25zICh0aGF0IGlzLApAQCAtMTg0NSwxNyArMTY4MywxMCBAQAogICovCiBwdWJsaWMgdm9pZCBzZXRMaW5lV2lkdGgoaW50IHdpZHRoKSB7CiAJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwotCWlmIChkYXRhLmxpbmVTdHlsZSA9PSBTV1QuTElORV9TT0xJRCkgewotCQkvKiBBVwotCQlPUy5YU2V0TGluZUF0dHJpYnV0ZXMoZGF0YS5kaXNwbGF5LCBoYW5kbGUsIHdpZHRoLCBPUy5MaW5lU29saWQsIE9TLkNhcEJ1dHQsIE9TLkpvaW5NaXRlcik7Ci0JCSovCi0JfSBlbHNlIHsKLQkJLyogQVcKLQkJT1MuWFNldExpbmVBdHRyaWJ1dGVzKGRhdGEuZGlzcGxheSwgaGFuZGxlLCB3aWR0aCwgT1MuTGluZURvdWJsZURhc2gsIE9TLkNhcEJ1dHQsIE9TLkpvaW5NaXRlcik7Ci0JCSovCi0JfQotCWZMaW5lV2lkdGg9IHdpZHRoOworCWRhdGEubGluZVdpZHRoID0gd2lkdGg7CisJT1MuQ0dDb250ZXh0U2V0TGluZVdpZHRoKGhhbmRsZSwgd2lkdGgpOwogfQorCiAvKiogCiAgKiBJZiB0aGUgYXJndW1lbnQgaXMgPGNvZGU+dHJ1ZTwvY29kZT4sIHB1dHMgdGhlIHJlY2VpdmVyCiAgKiBpbiBhIGRyYXdpbmcgbW9kZSB3aGVyZSB0aGUgcmVzdWx0aW5nIGNvbG9yIGluIHRoZSBkZXN0aW5hdGlvbgpAQCAtMTg3MiwxNCArMTcwMywxMCBAQAogICovCiBwdWJsaWMgdm9pZCBzZXRYT1JNb2RlKGJvb2xlYW4geG9yKSB7CiAJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwotCS8qIEFXCi0JaWYgKHhvcikKLQkJT1MuWFNldEZ1bmN0aW9uKGRhdGEuZGlzcGxheSwgaGFuZGxlLCBPUy5HWHhvcik7Ci0JZWxzZQotCQlPUy5YU2V0RnVuY3Rpb24oZGF0YS5kaXNwbGF5LCBoYW5kbGUsIE9TLkdYY29weSk7Ci0JKi8KLQlmWG9yTW9kZT0geG9yOworCS8vTk9UIERPTkUKKwlkYXRhLnhvck1vZGUgPSB4b3I7CiB9CisKIC8qKgogICogUmV0dXJucyB0aGUgZXh0ZW50IG9mIHRoZSBnaXZlbiBzdHJpbmcuIE5vIHRhYgogICogZXhwYW5zaW9uIG9yIGNhcnJpYWdlIHJldHVybiBwcm9jZXNzaW5nIHdpbGwgYmUgcGVyZm9ybWVkLgpAQCAtMTg5OSwyOSArMTcyNiwyOCBAQAogICogICAgPGxpPkVSUk9SX0dSQVBISUNfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgogICogPC91bD4KICAqLwotcHVibGljIFBvaW50IHN0cmluZ0V4dGVudChTdHJpbmcgc3RyaW5nKSB7CitwdWJsaWMgUG9pbnQgc3RyaW5nRXh0ZW50KFN0cmluZyBzdHJpbmcpIHsJCiAJaWYgKGhhbmRsZSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwogCWlmIChzdHJpbmcgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQlpZiAoc3RyaW5nLmxlbmd0aCAoKSA9PSAwKSByZXR1cm4gbmV3IFBvaW50KDAsIGdldEZvbnRIZWlnaHQoKSk7Ci0JLyogQVcKLQlieXRlW10gYnVmZmVyID0gQ29udmVydGVyLndjc1RvTWJjcyhnZXRDb2RlUGFnZSAoKSwgc3RyaW5nLCB0cnVlKTsKLQlpbnQgeG1TdHJpbmcgPSBPUy5YbVN0cmluZ0NyZWF0ZShidWZmZXIsIE9TLlhtRk9OVExJU1RfREVGQVVMVF9UQUcpOwotCWludCBmb250TGlzdCA9IGRhdGEuZm9udExpc3Q7Ci0JaW50IHdpZHRoID0gT1MuWG1TdHJpbmdXaWR0aChmb250TGlzdCwgeG1TdHJpbmcpOwotCWludCBoZWlnaHQgPSBPUy5YbVN0cmluZ0hlaWdodChmb250TGlzdCwgeG1TdHJpbmcpOwotCU9TLlhtU3RyaW5nRnJlZSh4bVN0cmluZyk7Ci0JKi8KLQl0cnkgewotCQlmb2N1cyhmYWxzZSwgbnVsbCk7Ci0JCWluc3RhbGxGb250KCk7Ci0JCWludCB3aWR0aD0gT1MuVGV4dFdpZHRoKHN0cmluZywgZGF0YS5mb250LmZJRCwgZGF0YS5mb250LmZTaXplLCBkYXRhLmZvbnQuZkZhY2UpOwotCQlzaG9ydFtdIGZvbnRJbmZvPSBuZXcgc2hvcnRbNF07Ci0JCU9TLkdldEZvbnRJbmZvKGZvbnRJbmZvKTsJLy8gRm9udEluZm8KLQkJcmV0dXJuIG5ldyBQb2ludCh3aWR0aCwgZm9udEluZm9bMF0gKyBmb250SW5mb1sxXSk7Ci0JfSBmaW5hbGx5IHsKLQkJdW5mb2N1cyhmYWxzZSk7Ci0JfQorCWludCBsZW5ndGggPSBzdHJpbmcubGVuZ3RoKCk7CisJaWYgKGxlbmd0aCA9PSAwKSByZXR1cm4gbmV3IFBvaW50KDAsIGRhdGEuZm9udEFzY2VudCArIGRhdGEuZm9udERlc2NlbnQpOworCWNoYXJbXSBidWZmZXIgPSBuZXcgY2hhcltsZW5ndGhdOworCXN0cmluZy5nZXRDaGFycygwLCBsZW5ndGgsIGJ1ZmZlciwgMCk7CisJaW50IHB0cjEgPSBPUy5OZXdQdHIobGVuZ3RoICogMik7CisJT1MubWVtY3B5KHB0cjEsIGJ1ZmZlciwgbGVuZ3RoICogMik7CisJT1MuQVRTVVNldFRleHRQb2ludGVyTG9jYXRpb24oZGF0YS5sYXlvdXQsIHB0cjEsIDAsIGxlbmd0aCwgbGVuZ3RoKTsKKwlPUy5BVFNVU2V0UnVuU3R5bGUoZGF0YS5sYXlvdXQsIGRhdGEuc3R5bGUsIDAsIGxlbmd0aCk7CisJaW50IHB0cjIgPSBPUy5OZXdQdHIoQVRTVHJhcGV6b2lkLnNpemVvZik7CisJT1MuQVRTVUdldEdseXBoQm91bmRzKGRhdGEubGF5b3V0LCAwLCAwLCAwLCBsZW5ndGgsIChzaG9ydClPUy5rQVRTVXNlRGV2aWNlT3JpZ2lucywgMSwgcHRyMiwgbnVsbCk7CisJT1MuRGlzcG9zZVB0cihwdHIxKTsKKwlBVFNUcmFwZXpvaWQgdHJhcGV6b2lkID0gbmV3IEFUU1RyYXBlem9pZCgpOworCU9TLm1lbWNweSh0cmFwZXpvaWQsIHB0cjIsIEFUU1RyYXBlem9pZC5zaXplb2YpOworCU9TLkRpc3Bvc2VQdHIocHRyMik7CisJaW50IHdpZHRoID0gKHRyYXBlem9pZC51cHBlclJpZ2h0X3ggPj4gMTYpIC0gKHRyYXBlem9pZC51cHBlckxlZnRfeCA+PiAxNik7CisJaW50IGhlaWdodCA9ICh0cmFwZXpvaWQubG93ZXJSaWdodF95ID4+IDE2KSAtICh0cmFwZXpvaWQudXBwZXJSaWdodF95ID4+IDE2KTsKKwlyZXR1cm4gbmV3IFBvaW50KHdpZHRoLCBoZWlnaHQpOwogfQorCiAvKioKICAqIFJldHVybnMgdGhlIGV4dGVudCBvZiB0aGUgZ2l2ZW4gc3RyaW5nLiBUYWIgZXhwYW5zaW9uIGFuZAogICogY2FycmlhZ2UgcmV0dXJuIHByb2Nlc3NpbmcgYXJlIHBlcmZvcm1lZC4KQEAgLTE5NDQsNiArMTc3MCw3IEBACiBwdWJsaWMgUG9pbnQgdGV4dEV4dGVudChTdHJpbmcgc3RyaW5nKSB7CiAJcmV0dXJuIHRleHRFeHRlbnQoc3RyaW5nLCBTV1QuRFJBV19ERUxJTUlURVIgfCBTV1QuRFJBV19UQUIpOwogfQorCiAvKioKICAqIFJldHVybnMgdGhlIGV4dGVudCBvZiB0aGUgZ2l2ZW4gc3RyaW5nLiBUYWIgZXhwYW5zaW9uLCBsaW5lCiAgKiBkZWxpbWl0ZXIgYW5kIG1uZW1vbmljIHByb2Nlc3NpbmcgYXJlIHBlcmZvcm1lZCBhY2NvcmRpbmcgdG8KQEAgLTE5NzgsMzkgKzE4MDUsMTAgQEAKIHB1YmxpYyBQb2ludCB0ZXh0RXh0ZW50KFN0cmluZyBzdHJpbmcsIGludCBmbGFncykgewogCWlmIChoYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKIAlpZiAoc3RyaW5nID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0JaWYgKHN0cmluZy5sZW5ndGggKCkgPT0gMCkgcmV0dXJuIG5ldyBQb2ludCgwLCBnZXRGb250SGVpZ2h0KCkpOwotCQotCS8qIEFXCi0JaWYgKGRhdGEucmVuZGVyVGFibGUgPT0gMCkgY3JlYXRlUmVuZGVyVGFibGUoKTsKLQlpbnQgcmVuZGVyVGFibGUgPSBkYXRhLnJlbmRlclRhYmxlOwotCi0JaW50IHRhYmxlTGVuZ3RoID0gMDsKLQlEZXZpY2UgZGV2aWNlID0gZGF0YS5kZXZpY2U7Ci0JaW50W10gcGFyc2VUYWJsZSA9IG5ldyBpbnRbMl07Ci0JY2hhcltdIHRleHQgPSBuZXcgY2hhcltzdHJpbmcubGVuZ3RoKCldOwotCXN0cmluZy5nZXRDaGFycygwLCB0ZXh0Lmxlbmd0aCwgdGV4dCwgMCk7CQotCWlmICgoZmxhZ3MgJiBTV1QuRFJBV19ERUxJTUlURVIpICE9IDApIHBhcnNlVGFibGVbdGFibGVMZW5ndGgrK10gPSBkZXZpY2UuY3JNYXBwaW5nOwotCWlmICgoZmxhZ3MgJiBTV1QuRFJBV19UQUIpICE9IDApIHBhcnNlVGFibGVbdGFibGVMZW5ndGgrK10gPSBkZXZpY2UudGFiTWFwcGluZzsKLQlpZiAoKGZsYWdzICYgU1dULkRSQVdfTU5FTU9OSUMpICE9IDApIHN0cmlwTW5lbW9uaWModGV4dCk7CQotCi0JYnl0ZVtdIGJ1ZmZlciA9IENvbnZlcnRlci53Y3NUb01iY3MoZ2V0Q29kZVBhZ2UoKSwgdGV4dCwgdHJ1ZSk7Ci0JaW50IHhtU3RyaW5nID0gT1MuWG1TdHJpbmdQYXJzZVRleHQoYnVmZmVyLCAwLCBPUy5YbUZPTlRMSVNUX0RFRkFVTFRfVEFHLCBPUy5YbUNIQVJTRVRfVEVYVCwgcGFyc2VUYWJsZSwgdGFibGVMZW5ndGgsIDApOwotCWludCB3aWR0aCA9IE9TLlhtU3RyaW5nV2lkdGgocmVuZGVyVGFibGUsIHhtU3RyaW5nKTsKLQlpbnQgaGVpZ2h0ID0gIE9TLlhtU3RyaW5nSGVpZ2h0KHJlbmRlclRhYmxlLCB4bVN0cmluZyk7Ci0JT1MuWG1TdHJpbmdGcmVlKHhtU3RyaW5nKTsKLQlyZXR1cm4gbmV3IFBvaW50KHdpZHRoLCBoZWlnaHQpOwotCSovCi0JdHJ5IHsKLQkJZm9jdXMoZmFsc2UsIG51bGwpOwotCQlpbnN0YWxsRm9udCgpOwotCQlpbnQgd2lkdGg9IE9TLlRleHRXaWR0aChzdHJpbmcsIGRhdGEuZm9udC5mSUQsIGRhdGEuZm9udC5mU2l6ZSwgZGF0YS5mb250LmZGYWNlKTsKLQkJc2hvcnRbXSBmb250SW5mbz0gbmV3IHNob3J0WzRdOwotCQlPUy5HZXRGb250SW5mbyhmb250SW5mbyk7CS8vIEZvbnRJbmZvCi0JCXJldHVybiBuZXcgUG9pbnQod2lkdGgsIGZvbnRJbmZvWzBdICsgZm9udEluZm9bMV0pOwotCX0gZmluYWxseSB7Ci0JCXVuZm9jdXMoZmFsc2UpOwotCX0KKwkvL05PVCBET05FCisJcmV0dXJuIHN0cmluZ0V4dGVudChzdHJpbmcpOwogfQorCiAvKioKICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlCiAgKiBkZXNjcmlwdGlvbiBvZiB0aGUgcmVjZWl2ZXIuCkBAIC0yMDIyLDE0NiArMTgyMCw0IEBACiAJcmV0dXJuICJHQyB7IiArIGhhbmRsZSArICJ9IjsKIH0KIAotLy8tLS0tIE1hYyBTdHVmZgotCi0JcHVibGljIHZvaWQgaW5zdGFsbEZvbnQoKSB7Ci0JCWlmIChkYXRhICE9IG51bGwgJiYgZGF0YS5mb250ICE9IG51bGwpCi0JCQlkYXRhLmZvbnQuaW5zdGFsbEluR3JhZlBvcnQoKTsKLQl9Ci0KLQlwcml2YXRlIGJvb2xlYW4gZm9jdXMoYm9vbGVhbiBkb0NsaXAsIE1hY1JlY3QgYm91bmRzKSB7Ci0JCQotCQlpZiAoZklzRm9jdXNlZCAmJiAhZlBlbmRpbmdDbGlwKSB7Ci0JCQlyZXR1cm4gdHJ1ZTsKLQkJfQotCi0JCS8vIHNhdmUgZ2xvYmFsIHN0YXRlCi0JCU9TLkdldEdXb3JsZChmU2F2ZVBvcnQsIGZTYXZlR1dvcmxkKTsJCQotCQlPUy5TZXRHV29ybGQoaGFuZGxlLCBmU2F2ZUdXb3JsZFswXSk7Ci0JCQotCQlpZiAoIWRvQ2xpcCkKLQkJCXJldHVybiB0cnVlOwotCQkKLQkJaW50IGR4PSAwLCBkeT0gMDsKLQotCQkvLyBzZXQgb3JpZ2luIG9mIHBvcnQgdXNpbmcgZHJhd2FibGUgYm91bmRzCi0JCWlmIChkYXRhLmNvbnRyb2xIYW5kbGUgIT0gMCkgewotCQkJT1MuR2V0Q29udHJvbEJvdW5kcyhkYXRhLmNvbnRyb2xIYW5kbGUsIGZSZWN0LmdldERhdGEoKSk7Ci0JCQlkeD0gZlJlY3QuZ2V0WCgpOwotCQkJZHk9IGZSZWN0LmdldFkoKTsKLQkJCU9TLlNldE9yaWdpbigoc2hvcnQpLWR4LCAoc2hvcnQpLWR5KTsKLQkJCU1hY1BvaW50IHA9IG5ldyBNYWNQb2ludCgtZHgsIC1keSk7Ci0JCQlPUy5RRFNldFBhdHRlcm5PcmlnaW4ocC5nZXREYXRhKCkpOwotCQl9Ci0JCS8vIHNhdmUgY2xpcCByZWdpb24KLQkJT1MuR2V0Q2xpcChmU2F2ZUNsaXApOwotCQkKLQkJLy8gY2FsY3VsYXRlIG5ldyBjbGlwIGJhc2VkIG9uIHRoZSBjb250cm9scyBib3VuZCBhbmQgR0MgY2xpcHBpbmcgcmVnaW9uCi0JCWlmIChkYXRhLmNvbnRyb2xIYW5kbGUgIT0gMCkgewotCQkJCi0JCQlpbnQgcmVzdWx0PSBPUy5OZXdSZ24oKTsKLQkJCU1hY1V0aWwuZ2V0VmlzaWJsZVJlZ2lvbihkYXRhLmNvbnRyb2xIYW5kbGUsIHJlc3VsdCwgdHJ1ZSk7Ci0JCQlPUy5PZmZzZXRSZ24ocmVzdWx0LCAoc2hvcnQpLWR4LCAoc2hvcnQpLWR5KTsKLQotCQkJLy8gY2xpcCBhZ2FpbnN0IGRhbWFnZSAKLQkJCWlmIChmRGFtYWdlUmduICE9IDApIHsKLQkJCQlpbnQgZFJnbj0gT1MuTmV3UmduKCk7Ci0JCQkJT1MuQ29weVJnbihmRGFtYWdlUmduLCBkUmduKTsKLQkJCQlPUy5PZmZzZXRSZ24oZFJnbiwgKHNob3J0KS1keCwgKHNob3J0KS1keSk7Ci0JCQkJT1MuU2VjdFJnbihyZXN1bHQsIGRSZ24sIHJlc3VsdCk7Ci0JCQl9Ci0JCQkKLQkJCS8vIGNsaXAgYWdhaW5zdCBHQyBjbGlwcGluZyByZWdpb24KLQkJCWlmIChkYXRhLmNsaXBSZ24gIT0gMCkgewotCQkJCU9TLlNlY3RSZ24ocmVzdWx0LCBkYXRhLmNsaXBSZ24sIHJlc3VsdCk7Ci0JCQl9Ci0JCQkJCi0JCQlPUy5TZXRDbGlwKHJlc3VsdCk7Ci0JCQlpZiAoYm91bmRzICE9IG51bGwpCi0JCQkJT1MuR2V0UmVnaW9uQm91bmRzKHJlc3VsdCwgYm91bmRzLmdldERhdGEoKSk7Ci0JCQlPUy5EaXNwb3NlUmduKHJlc3VsdCk7Ci0JCQkKLQkJfSBlbHNlIHsKLQkJCS8vIGNsaXAgYWdhaW5zdCBHQyBjbGlwcGluZyByZWdpb24KLQkJCWlmIChkYXRhLmNsaXBSZ24gIT0gMCkgewotCQkJCU9TLlNldENsaXAoZGF0YS5jbGlwUmduKTsKLQkJCQlpZiAoYm91bmRzICE9IG51bGwpCi0JCQkJCU9TLkdldFJlZ2lvbkJvdW5kcyhkYXRhLmNsaXBSZ24sIGJvdW5kcy5nZXREYXRhKCkpOwotCQkJfSBlbHNlIHsKLQkJCQlpZiAoYm91bmRzICE9IG51bGwpCi0JCQkJCWJvdW5kcy5zZXQoMCwgMCwgMHg4ZmZmLCAweDhmZmYpOwotCQkJfQotCQl9Ci0JCWZQZW5kaW5nQ2xpcD0gZmFsc2U7Ci0JCQotCQlyZXR1cm4gdHJ1ZTsKLQl9Ci0KLQlwcml2YXRlIHZvaWQgdW5mb2N1cyhib29sZWFuIGRvQ2xpcCkgewotCQkKLQkJaWYgKGZJc0ZvY3VzZWQpCi0JCQlyZXR1cm47Ci0JCQotCQlpZiAoZG9DbGlwKSB7Ci0JCQkvLyByZXN0b3JlIGNsaXBwaW5nIGFuZCBvcmlnaW4gb2YgcG9ydAotCQkJT1MuU2V0Q2xpcChmU2F2ZUNsaXApOwotCQkJT1MuU2V0T3JpZ2luKChzaG9ydCkwLCAoc2hvcnQpMCk7Ci0JCX0KLQkJCi0JCS8vIHJlc3RvcmUgZ2xvYmFscwotCQlPUy5TZXRHV29ybGQoZlNhdmVQb3J0WzBdLCBmU2F2ZUdXb3JsZFswXSk7Ci0JfQotCQotCXB1YmxpYyBSZWN0YW5nbGUgY2FyYm9uX2ZvY3VzKGludCBkYW1hZ2VSZ24pIHsKLQkJT1MuTG9ja1BvcnRCaXRzKGhhbmRsZSk7Ci0JCWZEYW1hZ2VSZ249IGRhbWFnZVJnbjsKLQkJTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JCWZvY3VzKHRydWUsIGJvdW5kcyk7Ci0JCWZJc0ZvY3VzZWQ9IHRydWU7Ci0JCXJldHVybiBib3VuZHMudG9SZWN0YW5nbGUoKTsKLQl9Ci0JCi0JcHVibGljIHZvaWQgY2FyYm9uX3VuZm9jdXMoKSB7Ci0JCWZJc0ZvY3VzZWQ9IGZhbHNlOwotCQl1bmZvY3VzKHRydWUpOwotCQlmRGFtYWdlUmduPSAwOwotCQlPUy5VbmxvY2tQb3J0Qml0cyhoYW5kbGUpOwotCX0KLQkJCi0JcHJpdmF0ZSBzaG9ydCBnZXRDdXJyZW50U2NyZWVuRGVwdGgoKSB7Ci0JCWludCBnZD0gT1MuR2V0R0RldmljZSgpOwotCQlpZiAoZ2QgIT0gMCkgewotCQkJaW50IHBtPSBPUy5nZXRnZFBNYXAoZ2QpOwotCQkJaWYgKHBtICE9IDApCi0JCQkJcmV0dXJuIE9TLkdldFBpeERlcHRoKHBtKTsKLQkJfQotCQlyZXR1cm4gMzI7Ci0JfQotCQkKLQkvLyBuZXcgQ29yZSBHcmFwaGljIHN0dWZmCi0JCi0JcHVibGljIGludCBjYXJib25fQ0dfZm9jdXMoKSB7Ci0JCQotCQlpZiAoT1MuUURCZWdpbkNHQ29udGV4dChoYW5kbGUsIGZDb250ZXh0KSAhPSBPUy5rTm9FcnIpCi0JCQlyZXR1cm4gMDsKLQkJCQotCQlpbnQgY29udGV4dD0gZkNvbnRleHRbMF07Ci0JCQotCQlNYWNSZWN0IGI9IG5ldyBNYWNSZWN0KCk7Ci0JCU9TLkdldFBvcnRCb3VuZHMoaGFuZGxlLCBiLmdldERhdGEoKSk7IAotCQkKLQkJaW50IGNsaXA9IE9TLk5ld1JnbigpOwotCQlPUy5HZXRQb3J0Q2xpcFJlZ2lvbihoYW5kbGUsIGNsaXApOwotCQlPUy5DbGlwQ0dDb250ZXh0VG9SZWdpb24oY29udGV4dCwgYi5nZXREYXRhKCksIGNsaXApOwotCQlPUy5EaXNwb3NlUmduKGNsaXApOwotCSAgICAgICAgICAgICAgCQkKLQkJT1MuQ0dDb250ZXh0VHJhbnNsYXRlQ1RNKGNvbnRleHQsIDAsIGIuZ2V0SGVpZ2h0KCkpOwotCQlPUy5DR0NvbnRleHRTY2FsZUNUTShjb250ZXh0LCAxLCAtMSk7Ci0JCXJldHVybiBjb250ZXh0OwotCX0KLQotCXB1YmxpYyB2b2lkIGNhcmJvbl9DR191bmZvY3VzKCkgewotCQlPUy5RREVuZENHQ29udGV4dChoYW5kbGUsIGZDb250ZXh0KTsJCQkJCQkJCi0JfQotCiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0dDRGF0YS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9HQ0RhdGEuamF2YQppbmRleCA3YTU1ZTYzLi5mZmIxMTRhIDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0dDRGF0YS5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZ3JhcGhpY3MvR0NEYXRhLmphdmEKQEAgLTgsOCArOCw3IEBACiAgKi8KIAogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwotCi1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5NYWNGb250OworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUmVjdDsKIAogLyoqCiAgKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBhcmUgZGVzY3JpcHRpb25zIG9mIEdDcyBpbiB0ZXJtcwpAQCAtMjYsMTIgKzI1LDIwIEBACiBwdWJsaWMgZmluYWwgY2xhc3MgR0NEYXRhIHsKIAlwdWJsaWMgRGV2aWNlIGRldmljZTsKIAlwdWJsaWMgSW1hZ2UgaW1hZ2U7Ci0JcHVibGljIGludCBmb3JlZ3JvdW5kID0gLTE7Ci0JcHVibGljIGludCBiYWNrZ3JvdW5kID0gLTE7Ci0JcHVibGljIE1hY0ZvbnQgZm9udDsKKwlwdWJsaWMgZmxvYXRbXSBmb3JlZ3JvdW5kOworCXB1YmxpYyBmbG9hdFtdIGJhY2tncm91bmQ7CiAJcHVibGljIGludCBjbGlwUmduOworCXB1YmxpYyBpbnQgbGluZVdpZHRoID0gMTsKIAlwdWJsaWMgaW50IGxpbmVTdHlsZSA9IFNXVC5MSU5FX1NPTElEOwotCS8vIEFXCi0JcHVibGljIGludCBjb250cm9sSGFuZGxlOwotCS8vIEFXCisJcHVibGljIGJvb2xlYW4geG9yTW9kZTsKKwkKKwlwdWJsaWMgRm9udCBmb250OworCXB1YmxpYyBpbnQgZm9udEFzY2VudDsKKwlwdWJsaWMgaW50IGZvbnREZXNjZW50OworCXB1YmxpYyBpbnQgbGF5b3V0OworCXB1YmxpYyBpbnQgc3R5bGU7CisJCisJcHVibGljIGludCBwYWludEV2ZW50OworCXB1YmxpYyBpbnQgdmlzaWJsZVJnbjsKKwlwdWJsaWMgaW50IGNvbnRyb2w7CiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0ltYWdlLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL0ltYWdlLmphdmEKaW5kZXggNWJlY2E3YS4uY2ZkNmM4ZiAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9JbWFnZS5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZ3JhcGhpY3MvSW1hZ2UuamF2YQpAQCAtNiwxMSArNiwxMSBAQAogICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAgKi8KLQorIAogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKIGltcG9ydCBqYXZhLmlvLio7Ci0KKyAKIC8qKgogICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgYXJlIGdyYXBoaWNzIHdoaWNoIGhhdmUgYmVlbiBwcmVwYXJlZAogICogZm9yIGRpc3BsYXkgb24gYSBzcGVjaWZpYyBkZXZpY2UuIFRoYXQgaXMsIHRoZXkgYXJlIHJlYWR5CkBAIC01OCwzNyArNTgsMzcgQEAKICAqIEBzZWUgSW1hZ2VEYXRhCiAgKiBAc2VlIEltYWdlTG9hZGVyCiAgKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBJbWFnZSBpbXBsZW1lbnRzIERyYXdhYmxlIHsKLQkKK3B1YmxpYyBmaW5hbCBjbGFzcyBJbWFnZSBpbXBsZW1lbnRzIERyYXdhYmxleworCiAJLyoqCiAJICogc3BlY2lmaWVzIHdoZXRoZXIgdGhlIHJlY2VpdmVyIGlzIGEgYml0bWFwIG9yIGFuIGljb24KIAkgKiAob25lIG9mIDxjb2RlPlNXVC5CSVRNQVA8L2NvZGU+LCA8Y29kZT5TV1QuSUNPTjwvY29kZT4pCiAJICovCiAJcHVibGljIGludCB0eXBlOwotCisJCiAJLyoqCi0JICogVGhlIGhhbmRsZSB0byB0aGUgT1MgcGl4bWFwIHJlc291cmNlLgorCSAqIFRoZSBoYW5kbGUgdG8gdGhlIE9TIGltYWdlIHJlc291cmNlLgogCSAqIFdhcm5pbmc6IFRoaXMgZmllbGQgaXMgcGxhdGZvcm0gZGVwZW5kZW50LgogCSAqLwotCXB1YmxpYyBpbnQgcGl4bWFwOworCXB1YmxpYyBpbnQgaGFuZGxlOwogCiAJLyoqCi0JICogVGhlIGhhbmRsZSB0byB0aGUgT1MgbWFzayByZXNvdXJjZS4KKwkgKiBUaGUgZGF0YSB0byB0aGUgT1MgaW1hZ2UgcmVzb3VyY2UuCiAJICogV2FybmluZzogVGhpcyBmaWVsZCBpcyBwbGF0Zm9ybSBkZXBlbmRlbnQuCiAJICovCi0JcHVibGljIGludCBtYXNrOworCXB1YmxpYyBpbnQgZGF0YTsKIAogCS8qKgogCSAqIFRoZSBkZXZpY2Ugd2hlcmUgdGhpcyBpbWFnZSB3YXMgY3JlYXRlZC4KIAkgKi8KIAlEZXZpY2UgZGV2aWNlOwotCisJCiAJLyoqCiAJICogc3BlY2lmaWVzIHRoZSB0cmFuc3BhcmVudCBwaXhlbAogCSAqIChXYXJuaW5nOiBUaGlzIGZpZWxkIGlzIHBsYXRmb3JtIGRlcGVuZGVudCkKIAkgKi8KIAlpbnQgdHJhbnNwYXJlbnRQaXhlbCA9IC0xOwotCisJCiAJLyoqCiAJICogVGhlIEdDIHRoZSBpbWFnZSBpcyBjdXJyZW50bHkgc2VsZWN0ZWQgaW4uCiAJICogV2FybmluZzogVGhpcyBmaWVsZCBpcyBwbGF0Zm9ybSBkZXBlbmRlbnQuCkBAIC0xMDAsMTMgKzEwMCwxMyBAQAogCSAqIFdhcm5pbmc6IFRoaXMgZmllbGQgaXMgcGxhdGZvcm0gZGVwZW5kZW50LgogCSAqLwogCWJ5dGVbXSBhbHBoYURhdGE7Ci0KKwkKIAkvKioKIAkgKiBUaGUgZ2xvYmFsIGFscGhhIHZhbHVlIHRvIGJlIHVzZWQgZm9yIGV2ZXJ5IHBpeGVsLgogCSAqIFdhcm5pbmc6IFRoaXMgZmllbGQgaXMgcGxhdGZvcm0gZGVwZW5kZW50LgogCSAqLwogCWludCBhbHBoYSA9IC0xOwotCisJCiAJLyoqCiAJICogU3BlY2lmaWVzIHRoZSBkZWZhdWx0IHNjYW5saW5lIHBhZGRpbmcuCiAJICogV2FybmluZzogVGhpcyBmaWVsZCBpcyBwbGF0Zm9ybSBkZXBlbmRlbnQuCkBAIC0xMTUsNiArMTE1LDcgQEAKIAogSW1hZ2UoKSB7CiB9CisKIC8qKgogICogQ29uc3RydWN0cyBhbiBlbXB0eSBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIHdpdGggdGhlCiAgKiBzcGVjaWZpZWQgd2lkdGggYW5kIGhlaWdodC4gVGhlIHJlc3VsdCBtYXkgYmUgZHJhd24gdXBvbgpAQCAtMTQ1LDkgKzE0NiwxMiBAQAogICogICAgPGxpPkVSUk9SX05PX0hBTkRMRVMgaWYgYSBoYW5kbGUgY291bGQgbm90IGJlIG9idGFpbmVkIGZvciBpbWFnZSBjcmVhdGlvbjwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgSW1hZ2UoRGV2aWNlIGRldmljZSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CitwdWJsaWMgSW1hZ2UoRGV2aWNlIGRpc3BsYXksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworCWlmIChkZXZpY2UgPT0gbnVsbCkgZGV2aWNlID0gRGV2aWNlLmdldERldmljZSgpOworCWlmIChkZXZpY2UgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlpbml0KGRldmljZSwgd2lkdGgsIGhlaWdodCk7CiB9CisKIC8qKgogICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGJhc2VkIG9uIHRoZQogICogcHJvdmlkZWQgaW1hZ2UsIHdpdGggYW4gYXBwZWFyYW5jZSB0aGF0IHZhcmllcyBkZXBlbmRpbmcKQEAgLTE4MiwyNTMgKzE4NiwxMjEgQEAKIHB1YmxpYyBJbWFnZShEZXZpY2UgZGV2aWNlLCBJbWFnZSBzcmNJbWFnZSwgaW50IGZsYWcpIHsKIAlpZiAoZGV2aWNlID09IG51bGwpIGRldmljZSA9IERldmljZS5nZXREZXZpY2UoKTsKIAlpZiAoZGV2aWNlID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0JdGhpcy5kZXZpY2UgPSBkZXZpY2U7CiAJaWYgKHNyY0ltYWdlID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaWYgKHNyY0ltYWdlLmlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKLQkJCQotCXRoaXMudHlwZSA9IHNyY0ltYWdlLnR5cGU7Ci0JdGhpcy5tYXNrID0gMDsKLQkJCi0JTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JT1MuR2V0UGl4Qm91bmRzKHNyY0ltYWdlLnBpeG1hcCwgYm91bmRzLmdldERhdGEoKSk7Ci0gCWludCB3aWR0aCA9IGJvdW5kcy5nZXRXaWR0aCgpOwotIAlpbnQgaGVpZ2h0ID0gYm91bmRzLmdldEhlaWdodCgpOwotCi0JLyogRG9uJ3QgY3JlYXRlIHRoZSBtYXNrIGhlcmUgaWYgZmxhZyBpcyBTV1QuSU1BR0VfR1JBWS4gU2VlIGJlbG93LiovCi0JaWYgKGZsYWcgIT0gU1dULklNQUdFX0dSQVkgJiYgc3JjSW1hZ2UubWFzayAhPSAwKSB7Ci0JCS8qIEdlbmVyYXRlIHRoZSBtYXNrIGlmIG5lY2Vzc2FyeS4gKi8KLQkJaWYgKHNyY0ltYWdlLnRyYW5zcGFyZW50UGl4ZWwgIT0gLTEpIHNyY0ltYWdlLmNyZWF0ZU1hc2soKTsKLQkJdGhpcy5tYXNrID0gZHVwbGljYXRlKHNyY0ltYWdlLm1hc2spOwotCQkvKiBEZXN0cm95IHRoZSBpbWFnZSBtYXNrIGlmIHRoZSB0aGVyZSBpcyBhIEdDIGNyZWF0ZWQgb24gdGhlIGltYWdlICovCi0JCWlmIChzcmNJbWFnZS50cmFuc3BhcmVudFBpeGVsICE9IC0xICYmIHNyY0ltYWdlLm1lbUdDICE9IG51bGwpIHNyY0ltYWdlLmRlc3Ryb3lNYXNrKCk7Ci0JfQotCQogCXN3aXRjaCAoZmxhZykgewotCQkKLQljYXNlIFNXVC5JTUFHRV9DT1BZOgotCQl0aGlzLnBpeG1hcCA9IGR1cGxpY2F0ZShzcmNJbWFnZS5waXhtYXApOworCQljYXNlIFNXVC5JTUFHRV9DT1BZOgorCQljYXNlIFNXVC5JTUFHRV9ESVNBQkxFOgorCQljYXNlIFNXVC5JTUFHRV9HUkFZOgorCQkJYnJlYWs7CisJCWRlZmF1bHQ6CisJCQlTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCX0KKwl0aGlzLmRldmljZSA9IGRldmljZTsKKwl0aGlzLnR5cGUgPSBzcmNJbWFnZS50eXBlOworCisJLyogR2V0IHNvdXJjZSBpbWFnZSBzaXplICovCisgCWludCB3aWR0aCA9IE9TLkNHSW1hZ2VHZXRXaWR0aChzcmNJbWFnZS5oYW5kbGUpOworIAlpbnQgaGVpZ2h0ID0gT1MuQ0dJbWFnZUdldEhlaWdodChzcmNJbWFnZS5oYW5kbGUpOworIAlpbnQgYnByID0gT1MuQ0dJbWFnZUdldEJ5dGVzUGVyUm93KHNyY0ltYWdlLmhhbmRsZSk7CisgCWludCBicGMgPSBPUy5DR0ltYWdlR2V0Qml0c1BlckNvbXBvbmVudChzcmNJbWFnZS5oYW5kbGUpOworIAlpbnQgYnBwID0gT1MuQ0dJbWFnZUdldEJpdHNQZXJQaXhlbChzcmNJbWFnZS5oYW5kbGUpOworCWludCBjb2xvcnNwYWNlID0gT1MuQ0dJbWFnZUdldENvbG9yU3BhY2Uoc3JjSW1hZ2UuaGFuZGxlKTsKKwlpbnQgYWxwaGFJbmZvID0gT1Mua0NHSW1hZ2VBbHBoYU5vbmVTa2lwRmlyc3Q7CisgCQorCS8qIENvcHkgdHJhbnNwYXJlbnQgcGl4ZWwgYW5kIGFscGhhIGRhdGEgd2hlbiBuZWNlc3NhcnkgKi8KKwlpZiAoZmxhZyAhPSBTV1QuSU1BR0VfRElTQUJMRSkgeworCQlhbHBoYUluZm8gPSBPUy5DR0ltYWdlR2V0QWxwaGFJbmZvKHNyY0ltYWdlLmhhbmRsZSk7CiAJCXRyYW5zcGFyZW50UGl4ZWwgPSBzcmNJbWFnZS50cmFuc3BhcmVudFBpeGVsOwogCQlhbHBoYSA9IHNyY0ltYWdlLmFscGhhOwogCQlpZiAoc3JjSW1hZ2UuYWxwaGFEYXRhICE9IG51bGwpIHsKIAkJCWFscGhhRGF0YSA9IG5ldyBieXRlW3NyY0ltYWdlLmFscGhhRGF0YS5sZW5ndGhdOwogCQkJU3lzdGVtLmFycmF5Y29weShzcmNJbWFnZS5hbHBoYURhdGEsIDAsIGFscGhhRGF0YSwgMCwgYWxwaGFEYXRhLmxlbmd0aCk7CiAJCX0KLQkJcmV0dXJuOwotCQkKLQljYXNlIFNXVC5JTUFHRV9ESVNBQkxFOgotCQkvKiBHZXQgc3JjIGltYWdlIGRhdGEgKi8KLQkJaW50IHNyY0RlcHRoPSBnZXREZXB0aChzcmNJbWFnZS5waXhtYXApOwotCQlpbnQgc3JjQml0c1BlclBpeGVsPSBzcmNEZXB0aDsKLQkJCi0JCWlmIChzcmNCaXRzUGVyUGl4ZWwgPT0gMSkgewotCQkJLyoKLQkJCSAqIE5vdGhpbmcgd2UgY2FuIHJlYXNvbmFibHkgZG8gaGVyZSBleGNlcHQgY29weQotCQkJICogdGhlIGJpdG1hcDsgd2UgY2FuJ3QgbWFrZSBpdCBhIGhpZ2hlciBjb2xvciBkZXB0aC4KLQkJCSAqIFNob3J0LWNpcmN1aXQgdGhlIHJlc3Qgb2YgdGhlIGNvZGUgYW5kIHJldHVybi4KLQkJCSAqLwotCQkJcGl4bWFwID0gZHVwbGljYXRlKHNyY0ltYWdlLnBpeG1hcCk7Ci0JCQlyZXR1cm47Ci0JCX0KLQkJCi0JCWludCBzcmNSb3dCeXRlcz0gcm93Qnl0ZXMod2lkdGgsIHNyY0RlcHRoKTsKLQkJYnl0ZVtdIHNyY0RhdGEgPSBuZXcgYnl0ZVtzcmNSb3dCeXRlcyAqIGhlaWdodF07Ci0JCWNvcHlQaXhNYXBEYXRhKHNyY0ltYWdlLnBpeG1hcCwgc3JjRGF0YSk7CisJfQogCi0JCS8qIENyZWF0ZSBkZXN0aW5hdGlvbiBpbWFnZSAqLwotCQlpbnQgZGVzdFBpeG1hcCA9IGNyZWF0ZVBpeE1hcCh3aWR0aCwgaGVpZ2h0LCBzcmNEZXB0aCk7Ci0JCWludCBkZXN0Qml0c1BlclBpeGVsPSBzcmNEZXB0aDsKLQkJYnl0ZVtdIGRlc3REYXRhID0gbmV3IGJ5dGVbc3JjUm93Qnl0ZXMgKiBoZWlnaHRdOwotCQkKLQkJLyogRmluZCB0aGUgY29sb3JzIHRvIG1hcCB0byAqLwotCQlDb2xvciB6ZXJvQ29sb3IgPSBkZXZpY2UuZ2V0U3lzdGVtQ29sb3IoU1dULkNPTE9SX1dJREdFVF9OT1JNQUxfU0hBRE9XKTsKLQkJQ29sb3Igb25lQ29sb3IgPSBkZXZpY2UuZ2V0U3lzdGVtQ29sb3IoU1dULkNPTE9SX1dJREdFVF9CQUNLR1JPVU5EKTsKLQkJaW50IHplcm9QaXhlbD0gMDsKLQkJaW50IG9uZVBpeGVsPSAxOwotCQlzZXRDb2xvclRhYmxlKGRlc3RQaXhtYXAsIG5ldyBDb2xvcltdIHsgemVyb0NvbG9yLCBvbmVDb2xvciB9KTsKLQotCQlzd2l0Y2ggKHNyY0JpdHNQZXJQaXhlbCkgewotCQljYXNlIDE6Ci0JCQkvLyBzaG91bGQgbm90IGhhcHBlbjsgc2VlIGFib3ZlCi0JCQlyZXR1cm47Ci0JCWNhc2UgNDoKLQkJCS8vU1dULmVycm9yKFNXVC5FUlJPUl9OT1RfSU1QTEVNRU5URUQpOwotCQkJcGl4bWFwID0gZHVwbGljYXRlKHNyY0ltYWdlLnBpeG1hcCk7Ci0JCQlicmVhazsKLQkJY2FzZSA4OgotCQkJaW50IGluZGV4ID0gMDsKLQkJCWludCBzcmNQaXhlbCwgciwgZywgYjsKLQkJCQotCQkJaW50W10gY29sb3JzPSBuZXcgaW50WzI1Nl07Ci0JCQlmb3IgKGludCBpPSAwOyBpIDwgMjU2OyBpKyspCi0JCQkJY29sb3JzW2ldPSAtMTsKLQkJCQkKLQkJCXNob3J0W10gY29sb3JUYWJsZT0gZ2V0Q29sb3JUYWJsZShzcmNJbWFnZS5waXhtYXApOwotCQkJCi0JCQlmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7Ci0JCQkJZm9yIChpbnQgeCA9IDA7IHggPCBzcmNSb3dCeXRlczsgeCsrKSB7Ci0JCQkJCXNyY1BpeGVsID0gc3JjRGF0YVtpbmRleCArIHhdICYgMHhGRjsKLQkJCQkJLyogR2V0IHRoZSBSR0IgdmFsdWVzIG9mIHNyY1BpeGVsICovCi0JCQkJCWludCBjb2xvcj0gY29sb3JzW3NyY1BpeGVsXTsKLQkJCQkJaWYgKGNvbG9yID09IC0xKQkJCQotCQkJCQkJY29sb3JzW3NyY1BpeGVsXT0gY29sb3I9IGdldFJHQihjb2xvclRhYmxlLCBzcmNQaXhlbCk7Ci0JCQkJCXIgPSAoY29sb3IgPj4gMTYpICYgMHhGRjsKLQkJCQkJZyA9IChjb2xvciA+PiA4KSAmIDB4RkY7Ci0JCQkJCWIgPSAoY29sb3IpICYgMHhGRjsKLQkJCQkJLyogU2VlIGlmIHRoZSByZ2IgbWFwcyB0byAwIG9yIDEgKi8KLQkJCQkJaWYgKChyICogciArIGcgKiBnICsgYiAqIGIpIDwgOTgzMDQpIHsKLQkJCQkJCS8qIE1hcCBkb3duIHRvIDAgKi8KLQkJCQkJCWRlc3REYXRhW2luZGV4ICsgeF0gPSAoYnl0ZSl6ZXJvUGl4ZWw7CisJLyogQ3JlYXRlIHRoZSBpbWFnZSAqLworCWludCBkYXRhU2l6ZSA9IGhlaWdodCAqIGJwcjsKKwlkYXRhID0gT1MuTmV3UHRyKGRhdGFTaXplKTsKKwlpZiAoZGF0YSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCWludCBwcm92aWRlciA9IE9TLkNHRGF0YVByb3ZpZGVyQ3JlYXRlV2l0aERhdGEoMCwgZGF0YSwgZGF0YVNpemUsIDApOworCWlmIChwcm92aWRlciA9PSAwKSB7CisJCU9TLkRpc3Bvc2VQdHIoZGF0YSk7CisJCVNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7CisJfQorCWhhbmRsZSA9IE9TLkNHSW1hZ2VDcmVhdGUod2lkdGgsIGhlaWdodCwgYnBjLCBicHAsIGJwciwgY29sb3JzcGFjZSwgYWxwaGFJbmZvLCBwcm92aWRlciwgbnVsbCwgZmFsc2UsIDApOworCU9TLkNHRGF0YVByb3ZpZGVyUmVsZWFzZShwcm92aWRlcik7CisJaWYgKGhhbmRsZSA9PSAwKSB7CisJCU9TLkRpc3Bvc2VQdHIoZGF0YSk7CisJCVNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7CisJfQorCQorCU9TLm1lbWNweShkYXRhLCBzcmNJbWFnZS5kYXRhLCBkYXRhU2l6ZSk7CisJaWYgKGZsYWcgPT0gU1dULklNQUdFX0NPUFkpIHJldHVybjsKKwkKKwkvKiBBcHBseSB0cmFuc2Zvcm1hdGlvbiAqLworCXN3aXRjaCAoZmxhZykgeworCQljYXNlIFNXVC5JTUFHRV9ESVNBQkxFOiB7CisJCQlDb2xvciB6ZXJvQ29sb3IgPSBkZXZpY2UuZ2V0U3lzdGVtQ29sb3IoU1dULkNPTE9SX1dJREdFVF9OT1JNQUxfU0hBRE9XKTsKKwkJCVJHQiB6ZXJvUkdCID0gemVyb0NvbG9yLmdldFJHQigpOworCQkJYnl0ZSB6ZXJvUmVkID0gKGJ5dGUpemVyb1JHQi5yZWQ7CisJCQlieXRlIHplcm9HcmVlbiA9IChieXRlKXplcm9SR0IuZ3JlZW47CisJCQlieXRlIHplcm9CbHVlID0gKGJ5dGUpemVyb1JHQi5ibHVlOworCQkJQ29sb3Igb25lQ29sb3IgPSBkZXZpY2UuZ2V0U3lzdGVtQ29sb3IoU1dULkNPTE9SX1dJREdFVF9CQUNLR1JPVU5EKTsKKwkJCVJHQiBvbmVSR0IgPSBvbmVDb2xvci5nZXRSR0IoKTsKKwkJCWJ5dGUgb25lUmVkID0gKGJ5dGUpb25lUkdCLnJlZDsKKwkJCWJ5dGUgb25lR3JlZW4gPSAoYnl0ZSlvbmVSR0IuZ3JlZW47CisJCQlieXRlIG9uZUJsdWUgPSAoYnl0ZSlvbmVSR0IuYmx1ZTsKKwkJCWJ5dGVbXSBsaW5lID0gbmV3IGJ5dGVbYnByXTsKKwkJCWZvciAoaW50IHk9MDsgeTxoZWlnaHQ7IHkrKykgeworCQkJCU9TLm1lbWNweShsaW5lLCBkYXRhICsgKHkgKiBicHIpLCBicHIpOworCQkJCWludCBvZmZzZXQgPSAwOworCQkJCWZvciAoaW50IHg9MDsgeDx3aWR0aDsgeCsrKSB7CisJCQkJCWludCByZWQgPSBsaW5lW29mZnNldCsxXSAmIDB4RkY7CisJCQkJCWludCBncmVlbiA9IGxpbmVbb2Zmc2V0KzJdICYgMHhGRjsKKwkJCQkJaW50IGJsdWUgPSBsaW5lW29mZnNldCszXSAmIDB4RkY7CisJCQkJCWludCBpbnRlbnNpdHkgPSByZWQgKiByZWQgKyBncmVlbiAqIGdyZWVuICsgYmx1ZSAqIGJsdWU7CisJCQkJCWlmIChpbnRlbnNpdHkgPCA5ODMwNCkgeworCQkJCQkJbGluZVtvZmZzZXQrMV0gPSB6ZXJvUmVkOworCQkJCQkJbGluZVtvZmZzZXQrMl0gPSB6ZXJvR3JlZW47CisJCQkJCQlsaW5lW29mZnNldCszXSA9IHplcm9CbHVlOwogCQkJCQl9IGVsc2UgewotCQkJCQkJLyogTWFwIHVwIHRvIDEgKi8KLQkJCQkJCWRlc3REYXRhW2luZGV4ICsgeF0gPSAoYnl0ZSlvbmVQaXhlbDsKKwkJCQkJCWxpbmVbb2Zmc2V0KzFdID0gb25lUmVkOworCQkJCQkJbGluZVtvZmZzZXQrMl0gPSBvbmVHcmVlbjsKKwkJCQkJCWxpbmVbb2Zmc2V0KzNdID0gb25lQmx1ZTsKIAkJCQkJfQorCQkJCQlvZmZzZXQgKz0gNDsKIAkJCQl9Ci0JCQkJaW5kZXggKz0gc3JjUm93Qnl0ZXM7CisJCQkJT1MubWVtY3B5KGRhdGEgKyAoeSAqIGJwciksIGxpbmUsIGJwcik7CiAJCQl9CiAJCQlicmVhazsKLQkJY2FzZSAxNjoKLQkJCWluZGV4ID0gMDsKLQkJCS8qIEdldCBtYXNrcyAqLwotCQkJaW50IHJlZE1hc2sgPSBnZXRSZWRNYXNrKDE2KTsKLQkJCWludCBncmVlbk1hc2sgPSBnZXRHcmVlbk1hc2soMTYpOwotCQkJaW50IGJsdWVNYXNrID0gZ2V0Qmx1ZU1hc2soMTYpOwkJCQkJCi0JCQkvKiBDYWxjdWxhdGUgbWFzayBzaGlmdHMgKi8KLQkJCWludCByU2hpZnQgPSAyNCAtIGdldE9mZnNldEZvck1hc2soMTYsIHJlZE1hc2ssIHRydWUpOwotCQkJaW50IGdTaGlmdCA9IDI0IC0gZ2V0T2Zmc2V0Rm9yTWFzaygxNiwgZ3JlZW5NYXNrLCB0cnVlKTsKLQkJCWludCBiU2hpZnQgPSAyNCAtIGdldE9mZnNldEZvck1hc2soMTYsIGJsdWVNYXNrLCB0cnVlKTsKLQkJCWJ5dGUgemVyb0xvdyA9IChieXRlKSh6ZXJvUGl4ZWwgJiAweEZGKTsKLQkJCWJ5dGUgemVyb0hpZ2ggPSAoYnl0ZSkoKHplcm9QaXhlbCA+PiA4KSAmIDB4RkYpOwotCQkJYnl0ZSBvbmVMb3cgPSAoYnl0ZSkob25lUGl4ZWwgJiAweEZGKTsKLQkJCWJ5dGUgb25lSGlnaCA9IChieXRlKSgob25lUGl4ZWwgPj4gOCkgJiAweEZGKTsKLQkJCWZvciAoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKLQkJCQlpbnQgeEluZGV4ID0gMDsKLQkJCQlmb3IgKGludCB4ID0gMDsgeCA8IHNyY1Jvd0J5dGVzOyB4ICs9IDIpIHsKLQkJCQkJaW50IGl4PSBpbmRleCArIHhJbmRleDsKLQkJCQkJc3JjUGl4ZWwgPSAoKHNyY0RhdGFbaXggKyAxXSAmIDB4RkYpIDw8IDgpIHwgKHNyY0RhdGFbaXhdICYgMHhGRik7Ci0JCQkJCXIgPSAoc3JjUGl4ZWwgJiByZWRNYXNrKSA8PCByU2hpZnQgPj4gMTY7Ci0JCQkJCWcgPSAoc3JjUGl4ZWwgJiBncmVlbk1hc2spIDw8IGdTaGlmdCA+PiAxNjsKLQkJCQkJYiA9IChzcmNQaXhlbCAmIGJsdWVNYXNrKSA8PCBiU2hpZnQgPj4gMTY7Ci0JCQkJCS8qIFNlZSBpZiB0aGUgcmdiIG1hcHMgdG8gMCBvciAxICovCi0JCQkJCWlmICgociAqIHIgKyBnICogZyArIGIgKiBiKSA8IDk4MzA0KSB7Ci0JCQkJCQkvKiBNYXAgZG93biB0byAwICovCi0JCQkJCQlkZXN0RGF0YVtpeF0gPSB6ZXJvTG93OwotCQkJCQkJZGVzdERhdGFbaXggKyAxXSA9IHplcm9IaWdoOwotCQkJCQl9IGVsc2UgewotCQkJCQkJLyogTWFwIHVwIHRvIDEgKi8KLQkJCQkJCWRlc3REYXRhW2l4XSA9IG9uZUxvdzsKLQkJCQkJCWRlc3REYXRhW2l4ICsgMV0gPSBvbmVIaWdoOwotCQkJCQl9Ci0JCQkJCXhJbmRleCArPSBzcmNCaXRzUGVyUGl4ZWwgLyA4OwotCQkJCX0KLQkJCQlpbmRleCArPSBzcmNSb3dCeXRlczsKLQkJCX0KLQkJCWJyZWFrOwotCQljYXNlIDI0OgotCQljYXNlIDMyOgotCQkJaW5kZXggPSAwOwotCQkJLyogR2V0IG1hc2tzICovCi0JCQlyZWRNYXNrID0gZ2V0UmVkTWFzayhzcmNCaXRzUGVyUGl4ZWwpOwotCQkJZ3JlZW5NYXNrID0gZ2V0R3JlZW5NYXNrKHNyY0JpdHNQZXJQaXhlbCk7Ci0JCQlibHVlTWFzayA9IGdldEJsdWVNYXNrKHNyY0JpdHNQZXJQaXhlbCk7CQkJCQkKLQkJCS8qIENhbGN1bGF0ZSBtYXNrIHNoaWZ0cyAqLwotCQkJclNoaWZ0ID0gZ2V0T2Zmc2V0Rm9yTWFzayhzcmNCaXRzUGVyUGl4ZWwsIHJlZE1hc2ssIHRydWUpOwotCQkJZ1NoaWZ0ID0gZ2V0T2Zmc2V0Rm9yTWFzayhzcmNCaXRzUGVyUGl4ZWwsIGdyZWVuTWFzaywgdHJ1ZSk7Ci0JCQliU2hpZnQgPSBnZXRPZmZzZXRGb3JNYXNrKHNyY0JpdHNQZXJQaXhlbCwgYmx1ZU1hc2ssIHRydWUpOwotCQkJYnl0ZSB6ZXJvUiA9IChieXRlKXplcm9Db2xvci5nZXRSZWQoKTsKLQkJCWJ5dGUgemVyb0cgPSAoYnl0ZSl6ZXJvQ29sb3IuZ2V0R3JlZW4oKTsKLQkJCWJ5dGUgemVyb0IgPSAoYnl0ZSl6ZXJvQ29sb3IuZ2V0Qmx1ZSgpOwotCQkJYnl0ZSBvbmVSID0gKGJ5dGUpb25lQ29sb3IuZ2V0UmVkKCk7Ci0JCQlieXRlIG9uZUcgPSAoYnl0ZSlvbmVDb2xvci5nZXRHcmVlbigpOwotCQkJYnl0ZSBvbmVCID0gKGJ5dGUpb25lQ29sb3IuZ2V0Qmx1ZSgpOwotCQkJZm9yIChpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewotCQkJCWludCB4SW5kZXggPSAwOwotCQkJCWZvciAoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewotCQkJCQlpbnQgaT0gaW5kZXggKyB4SW5kZXg7Ci0JCQkJCXIgPSBzcmNEYXRhW2kgKyByU2hpZnRdICYgMHhGRjsKLQkJCQkJZyA9IHNyY0RhdGFbaSArIGdTaGlmdF0gJiAweEZGOwotCQkJCQliID0gc3JjRGF0YVtpICsgYlNoaWZ0XSAmIDB4RkY7Ci0JCQkJCS8qIFNlZSBpZiB0aGUgcmdiIG1hcHMgdG8gMCBvciAxICovCi0JCQkJCWlmICgociAqIHIgKyBnICogZyArIGIgKiBiKSA8IDk4MzA0KSB7Ci0JCQkJCQkvKiBNYXAgZG93biB0byAwICovCi0JCQkJCQlkZXN0RGF0YVtpICsgclNoaWZ0XSA9IHplcm9SOwotCQkJCQkJZGVzdERhdGFbaSArIGdTaGlmdF0gPSB6ZXJvRzsKLQkJCQkJCWRlc3REYXRhW2kgKyBiU2hpZnRdID0gemVyb0I7Ci0JCQkJCX0gZWxzZSB7Ci0JCQkJCQkvKiBNYXAgdXAgdG8gMSAqLwotCQkJCQkJZGVzdERhdGFbaSArIHJTaGlmdF0gPSBvbmVSOwotCQkJCQkJZGVzdERhdGFbaSArIGdTaGlmdF0gPSBvbmVHOwotCQkJCQkJZGVzdERhdGFbaSArIGJTaGlmdF0gPSBvbmVCOwotCQkJCQl9Ci0JCQkJCXhJbmRleCArPSBkZXN0Qml0c1BlclBpeGVsIC8gODsKLQkJCQl9Ci0JCQkJaW5kZXggKz0gc3JjUm93Qnl0ZXM7Ci0JCQl9Ci0JCQlicmVhazsKLQkJZGVmYXVsdDoKLQkJCVNXVC5lcnJvcihTV1QuRVJST1JfSU5WQUxJRF9JTUFHRSk7CiAJCX0KLQkJc2V0UGl4TWFwRGF0YShkZXN0UGl4bWFwLCBkZXN0RGF0YSk7Ci0JCXRoaXMucGl4bWFwID0gZGVzdFBpeG1hcDsKLQkJcmV0dXJuOwotCi0JY2FzZSBTV1QuSU1BR0VfR1JBWToKLQkJSW1hZ2VEYXRhIGRhdGEgPSBzcmNJbWFnZS5nZXRJbWFnZURhdGEoKTsKLQkJUGFsZXR0ZURhdGEgcGFsZXR0ZSA9IGRhdGEucGFsZXR0ZTsKLQkJSW1hZ2VEYXRhIG5ld0RhdGEgPSBkYXRhOwotCQlpZiAocGFsZXR0ZS5pc0RpcmVjdCkgewotCQkJLyogQ3JlYXRlIGEgOCBiaXQgZGVwdGggaW1hZ2UgZGF0YSB3aXRoIGEgZ3JheSBwYWxldHRlLiAqLwotCQkJUkdCW10gcmdicyA9IG5ldyBSR0JbMjU2XTsKLQkJCWZvciAoaW50IGk9IDA7IGkgPCByZ2JzLmxlbmd0aDsgaSsrKQotCQkJCXJnYnNbaV09IG5ldyBSR0IoaSwgaSwgaSk7Ci0JCQkKLQkJCW5ld0RhdGEgPSBuZXcgSW1hZ2VEYXRhKHdpZHRoLCBoZWlnaHQsIDgsIG5ldyBQYWxldHRlRGF0YShyZ2JzKSk7Ci0JCQluZXdEYXRhLm1hc2tEYXRhID0gZGF0YS5tYXNrRGF0YTsKLQkJCW5ld0RhdGEubWFza1BhZCA9IGRhdGEubWFza1BhZDsKLQkJCS8qIENvbnZlcnQgdGhlIHBpeGVscy4gKi8KLQkJCWludFtdIHNjYW5saW5lID0gbmV3IGludFt3aWR0aF07Ci0JCQlpbnQgcmVkTWFzayA9IHBhbGV0dGUucmVkTWFzazsKLQkJCWludCBncmVlbk1hc2sgPSBwYWxldHRlLmdyZWVuTWFzazsKLQkJCWludCBibHVlTWFzayA9IHBhbGV0dGUuYmx1ZU1hc2s7Ci0JCQlpbnQgcmVkU2hpZnQgPSBwYWxldHRlLnJlZFNoaWZ0OwotCQkJaW50IGdyZWVuU2hpZnQgPSBwYWxldHRlLmdyZWVuU2hpZnQ7Ci0JCQlpbnQgYmx1ZVNoaWZ0ID0gcGFsZXR0ZS5ibHVlU2hpZnQ7Ci0JCQlmb3IgKGludCB5PSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKLQkJCQlpbnQgb2Zmc2V0ID0geSAqIG5ld0RhdGEuYnl0ZXNQZXJMaW5lOwotCQkJCWRhdGEuZ2V0UGl4ZWxzKDAsIHksIHdpZHRoLCBzY2FubGluZSwgMCk7Ci0JCQkJZm9yIChpbnQgeD0gMDsgeCA8IHdpZHRoOyB4KyspIHsKLQkJCQkJaW50IHBpeGVsID0gc2NhbmxpbmVbeF07Ci0JCQkJCWludCByZWQgPSBwaXhlbCAmIHJlZE1hc2s7Ci0JCQkJCXJlZCA9IChyZWRTaGlmdCA8IDApID8gcmVkID4+PiAtcmVkU2hpZnQgOiByZWQgPDwgcmVkU2hpZnQ7Ci0JCQkJCWludCBncmVlbiA9IHBpeGVsICYgZ3JlZW5NYXNrOwotCQkJCQlncmVlbiA9IChncmVlblNoaWZ0IDwgMCkgPyBncmVlbiA+Pj4gLWdyZWVuU2hpZnQgOiBncmVlbiA8PCBncmVlblNoaWZ0OwotCQkJCQlpbnQgYmx1ZSA9IHBpeGVsICYgYmx1ZU1hc2s7Ci0JCQkJCWJsdWUgPSAoYmx1ZVNoaWZ0IDwgMCkgPyBibHVlID4+PiAtYmx1ZVNoaWZ0IDogYmx1ZSA8PCBibHVlU2hpZnQ7Ci0JCQkJCW5ld0RhdGEuZGF0YVtvZmZzZXQrK10gPQotCQkJCQkJKGJ5dGUpKChyZWQrcmVkK2dyZWVuK2dyZWVuK2dyZWVuK2dyZWVuK2dyZWVuK2JsdWUpID4+IDMpOworCQljYXNlIFNXVC5JTUFHRV9HUkFZOiB7CQkJCisJCQlieXRlW10gbGluZSA9IG5ldyBieXRlW2Jwcl07CisJCQlmb3IgKGludCB5PTA7IHk8aGVpZ2h0OyB5KyspIHsKKwkJCQlPUy5tZW1jcHkobGluZSwgZGF0YSArICh5ICogYnByKSwgYnByKTsKKwkJCQlpbnQgb2Zmc2V0ID0gMDsKKwkJCQlmb3IgKGludCB4PTA7IHg8d2lkdGg7IHgrKykgeworCQkJCQlpbnQgcmVkID0gbGluZVtvZmZzZXQrMV0gJiAweEZGOworCQkJCQlpbnQgZ3JlZW4gPSBsaW5lW29mZnNldCsyXSAmIDB4RkY7CisJCQkJCWludCBibHVlID0gbGluZVtvZmZzZXQrM10gJiAweEZGOworCQkJCQlieXRlIGludGVuc2l0eSA9IChieXRlKSgocmVkK3JlZCtncmVlbitncmVlbitncmVlbitncmVlbitncmVlbitibHVlKSA+PiAzKTsKKwkJCQkJbGluZVtvZmZzZXQrMV0gPSBsaW5lW29mZnNldCsyXSA9IGxpbmVbb2Zmc2V0KzNdID0gaW50ZW5zaXR5OworCQkJCQlvZmZzZXQgKz0gNDsKIAkJCQl9CisJCQkJT1MubWVtY3B5KGRhdGEgKyAoeSAqIGJwciksIGxpbmUsIGJwcik7CiAJCQl9Ci0JCX0gZWxzZSB7Ci0JCQkvKiBDb252ZXJ0IHRoZSBwYWxldHRlIGVudHJpZXMgdG8gZ3JheS4gKi8KLQkJCVJHQiBbXSByZ2JzID0gcGFsZXR0ZS5nZXRSR0JzKCk7Ci0JCQlmb3IgKGludCBpPSAwOyBpIDwgcmdicy5sZW5ndGg7IGkrKykgewotCQkJCWlmIChkYXRhLnRyYW5zcGFyZW50UGl4ZWwgIT0gaSkgewotCQkJCQlSR0IgY29sb3IgPSByZ2JzIFtpXTsKLQkJCQkJaW50IHJlZCA9IGNvbG9yLnJlZDsKLQkJCQkJaW50IGdyZWVuID0gY29sb3IuZ3JlZW47Ci0JCQkJCWludCBibHVlID0gY29sb3IuYmx1ZTsKLQkJCQkJaW50IGludGVuc2l0eSA9IChyZWQrcmVkK2dyZWVuK2dyZWVuK2dyZWVuK2dyZWVuK2dyZWVuK2JsdWUpID4+IDM7Ci0JCQkJCWNvbG9yLnJlZCA9IGNvbG9yLmdyZWVuID0gY29sb3IuYmx1ZSA9IGludGVuc2l0eTsKLQkJCQl9CisJCQl0cmFuc3BhcmVudFBpeGVsID0gc3JjSW1hZ2UudHJhbnNwYXJlbnRQaXhlbDsKKwkJCWFscGhhID0gc3JjSW1hZ2UuYWxwaGE7CisJCQlpZiAoc3JjSW1hZ2UuYWxwaGFEYXRhICE9IG51bGwpIHsKKwkJCQlhbHBoYURhdGEgPSBuZXcgYnl0ZVtzcmNJbWFnZS5hbHBoYURhdGEubGVuZ3RoXTsKKwkJCQlTeXN0ZW0uYXJyYXljb3B5KHNyY0ltYWdlLmFscGhhRGF0YSwgMCwgYWxwaGFEYXRhLCAwLCBhbHBoYURhdGEubGVuZ3RoKTsKIAkJCX0KLQkJCW5ld0RhdGEucGFsZXR0ZSA9IG5ldyBQYWxldHRlRGF0YShyZ2JzKTsKKwkJCWJyZWFrOwogCQl9Ci0JCWluaXQgKGRldmljZSwgbmV3RGF0YSk7Ci0JCWJyZWFrOwotCQkKLQlkZWZhdWx0OgotCQlTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwogCX0KIH0KKwogLyoqCiAgKiBDb25zdHJ1Y3RzIGFuIGVtcHR5IGluc3RhbmNlIG9mIHRoaXMgY2xhc3Mgd2l0aCB0aGUKICAqIHdpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIHNwZWNpZmllZCByZWN0YW5nbGUuIFRoZSByZXN1bHQKQEAgLTQ1OSwxMCArMzMxLDEzIEBACiAgKiAgICA8bGk+RVJST1JfTk9fSEFORExFUyBpZiBhIGhhbmRsZSBjb3VsZCBub3QgYmUgb2J0YWluZWQgZm9yIGltYWdlIGNyZWF0aW9uPC9saT4KICAqIDwvdWw+CiAgKi8KLXB1YmxpYyBJbWFnZShEZXZpY2UgZGV2aWNlLCBSZWN0YW5nbGUgYm91bmRzKSB7CitwdWJsaWMgSW1hZ2UoRGV2aWNlIGRpc3BsYXksIFJlY3RhbmdsZSBib3VuZHMpIHsKKwlpZiAoZGV2aWNlID09IG51bGwpIGRldmljZSA9IERldmljZS5nZXREZXZpY2UoKTsKKwlpZiAoZGV2aWNlID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaWYgKGJvdW5kcyA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWluaXQoZGV2aWNlLCBib3VuZHMud2lkdGgsIGJvdW5kcy5oZWlnaHQpOwogfQorCiAvKioKICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIHRoZSBnaXZlbgogICogPGNvZGU+SW1hZ2VEYXRhPC9jb2RlPi4KQEAgLTQ3OCw5ICszNTMsMTIgQEAKICAqICAgIDxsaT5FUlJPUl9OT19IQU5ETEVTIGlmIGEgaGFuZGxlIGNvdWxkIG5vdCBiZSBvYnRhaW5lZCBmb3IgaW1hZ2UgY3JlYXRpb248L2xpPgogICogPC91bD4KICAqLwotcHVibGljIEltYWdlKERldmljZSBkZXZpY2UsIEltYWdlRGF0YSBpbWFnZSkgewotCWluaXQoZGV2aWNlLCBpbWFnZSk7CitwdWJsaWMgSW1hZ2UoRGV2aWNlIGRldmljZSwgSW1hZ2VEYXRhIGRhdGEpIHsKKwlpZiAoZGV2aWNlID09IG51bGwpIGRldmljZSA9IERldmljZS5nZXREZXZpY2UoKTsKKwlpZiAoZGV2aWNlID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJaW5pdChkZXZpY2UsIGRhdGEpOwogfQorCiAvKioKICAqIENvbnN0cnVjdHMgYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcywgd2hvc2UgdHlwZSBpcyAKICAqIDxjb2RlPlNXVC5JQ09OPC9jb2RlPiwgZnJvbSB0aGUgdHdvIGdpdmVuIDxjb2RlPkltYWdlRGF0YTwvY29kZT4KQEAgLTUxMCw3ICszODgsOCBAQAogICogICAgPGxpPkVSUk9SX05PX0hBTkRMRVMgaWYgYSBoYW5kbGUgY291bGQgbm90IGJlIG9idGFpbmVkIGZvciBpbWFnZSBjcmVhdGlvbjwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgSW1hZ2UoRGV2aWNlIGRldmljZSwgSW1hZ2VEYXRhIHNvdXJjZSwgSW1hZ2VEYXRhIG1hc2spIHsKK3B1YmxpYyBJbWFnZShEZXZpY2UgZGlzcGxheSwgSW1hZ2VEYXRhIHNvdXJjZSwgSW1hZ2VEYXRhIG1hc2spIHsKKwlpZiAoZGV2aWNlID09IG51bGwpIGRldmljZSA9IERldmljZS5nZXREZXZpY2UoKTsKIAlpZiAoc291cmNlID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaWYgKG1hc2sgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlpZiAoc291cmNlLndpZHRoICE9IG1hc2sud2lkdGggfHwgc291cmNlLmhlaWdodCAhPSBtYXNrLmhlaWdodCkgewpAQCAtNTIyLDYgKzQwMSw3IEBACiAJaW1hZ2UubWFza0RhdGEgPSBtYXNrLmRhdGE7CiAJaW5pdChkZXZpY2UsIGltYWdlKTsKIH0KKwogLyoqCiAgKiBDb25zdHJ1Y3RzIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYnkgbG9hZGluZyBpdHMgcmVwcmVzZW50YXRpb24KICAqIGZyb20gdGhlIHNwZWNpZmllZCBpbnB1dCBzdHJlYW0uIFRocm93cyBhbiBlcnJvciBpZiBhbiBlcnJvcgpAQCAtNTU1LDggKzQzNSwxMSBAQAogICogPC91bD4KICAqLwogcHVibGljIEltYWdlKERldmljZSBkZXZpY2UsIElucHV0U3RyZWFtIHN0cmVhbSkgeworCWlmIChkZXZpY2UgPT0gbnVsbCkgZGV2aWNlID0gRGV2aWNlLmdldERldmljZSgpOworCWlmIChkZXZpY2UgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlpbml0KGRldmljZSwgbmV3IEltYWdlRGF0YShzdHJlYW0pKTsKIH0KKwogLyoqCiAgKiBDb25zdHJ1Y3RzIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYnkgbG9hZGluZyBpdHMgcmVwcmVzZW50YXRpb24KICAqIGZyb20gdGhlIGZpbGUgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUuIFRocm93cyBhbiBlcnJvciBpZiBhbiBlcnJvcgpAQCAtNTgyLDYwICs0NjUsMjcgQEAKICAqICAgIDxsaT5FUlJPUl9OT19IQU5ETEVTIGlmIGEgaGFuZGxlIGNvdWxkIG5vdCBiZSBvYnRhaW5lZCBmb3IgaW1hZ2UgY3JlYXRpb248L2xpPgogICogPC91bD4KICAqLwotcHVibGljIEltYWdlKERldmljZSBkZXZpY2UsIFN0cmluZyBmaWxlbmFtZSkgeworcHVibGljIEltYWdlKERldmljZSBkaXNwbGF5LCBTdHJpbmcgZmlsZW5hbWUpIHsKKwlpZiAoZGV2aWNlID09IG51bGwpIGRldmljZSA9IERldmljZS5nZXREZXZpY2UoKTsKKwlpZiAoZGV2aWNlID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaW5pdChkZXZpY2UsIG5ldyBJbWFnZURhdGEoZmlsZW5hbWUpKTsKIH0KLS8qKgotICogQ3JlYXRlIHRoZSByZWNlaXZlcidzIG1hc2sgaWYgbmVjZXNzYXJ5LgotICovCi12b2lkIGNyZWF0ZU1hc2soKSB7Ci0JaWYgKG1hc2sgIT0gMCkgcmV0dXJuOwotCW1hc2sgPSBjcmVhdGVNYXNrSW1hZ2UoZ2V0SW1hZ2VEYXRhKCkuZ2V0VHJhbnNwYXJlbmN5TWFzaygpKTsKLX0KLS8qKgotICogQ3JlYXRlcyBhIFF1aWNrZHJhdyBCaXRNYXAgZnJvbSBhIGRldmljZS1pbmRlcGVuZGVudCBpbWFnZSBvZiBkZXB0aCAxLgotICovCi1wcml2YXRlIHN0YXRpYyBpbnQgY3JlYXRlTWFza0ltYWdlKEltYWdlRGF0YSBpbWFnZSkgewotCWlmIChpbWFnZS5kZXB0aCAhPSAxKSByZXR1cm4gMDsKLQkKLQlpbnQgdz0gaW1hZ2Uud2lkdGg7Ci0JaW50IGg9IGltYWdlLmhlaWdodDsKLQlpbnQgYml0bWFwPSBjcmVhdGVCaXRNYXAodywgaCk7Ci0JaW50IHJvd0J5dGVzPSByb3dCeXRlcyh3LCAxKTsKLQlieXRlW10gZGF0YT0gbmV3IGJ5dGVbcm93Qnl0ZXMgKiBoXTsKIAotCUltYWdlRGF0YS5ibGl0KEltYWdlRGF0YS5CTElUX1NSQywKLQkJaW1hZ2UuZGF0YSwgMSwgaW1hZ2UuYnl0ZXNQZXJMaW5lLCBpbWFnZS5nZXRCeXRlT3JkZXIoKSwgMCwgMCwgdywgaCwgbnVsbCwgbnVsbCwgbnVsbCwKLQkJSW1hZ2VEYXRhLkFMUEhBX09QQVFVRSwgbnVsbCwgMCwgMCwgMCwKLQkJZGF0YSwgMSwgcm93Qnl0ZXMsIEltYWdlRGF0YS5NU0JfRklSU1QsIDAsIDAsIHcsIGgsIG51bGwsIG51bGwsIG51bGwsCi0JCWZhbHNlLCBmYWxzZSk7Ci0JCi0Jc2V0UGl4TWFwRGF0YShiaXRtYXAsIGRhdGEpOwotCi0JcmV0dXJuIGJpdG1hcDsKLX0KIC8qKgogICogRGlzcG9zZXMgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0gcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aAogICogdGhlIGltYWdlLiBBcHBsaWNhdGlvbnMgbXVzdCBkaXNwb3NlIG9mIGFsbCBpbWFnZXMgd2hpY2gKICAqIHRoZXkgYWxsb2NhdGUuCiAgKi8KIHB1YmxpYyB2b2lkIGRpc3Bvc2UgKCkgewotCWlmIChwaXhtYXAgPT0gMCkgcmV0dXJuOworCWlmIChoYW5kbGUgPT0gMCkgcmV0dXJuOwogCWlmIChkZXZpY2UuaXNEaXNwb3NlZCgpKSByZXR1cm47Ci0JaWYgKHBpeG1hcCAhPSAwKSBkaXNwb3NlQml0bWFwT3JQaXhtYXAocGl4bWFwKTsKLQlpZiAobWFzayAhPSAwKSBkaXNwb3NlQml0bWFwT3JQaXhtYXAobWFzayk7CisJT1MuQ0dJbWFnZVJlbGVhc2UoaGFuZGxlKTsKKwlPUy5EaXNwb3NlUHRyKGRhdGEpOwogCWRldmljZSA9IG51bGw7CisJZGF0YSA9IGhhbmRsZSA9IDA7CiAJbWVtR0MgPSBudWxsOwotCXBpeG1hcCA9IG1hc2sgPSAwOwogfQotLyoqCi0gKiBEZXN0cm95IHRoZSByZWNlaXZlcidzIG1hc2sgaWYgaXQgZXhpc3RzLgotICovCi12b2lkIGRlc3Ryb3lNYXNrKCkgewotCWlmIChtYXNrID09IDApIHJldHVybjsKLQlkaXNwb3NlQml0bWFwT3JQaXhtYXAobWFzayk7Ci0JbWFzaz0gMDsKLX0KKwogLyoqCiAgKiBDb21wYXJlcyB0aGUgYXJndW1lbnQgdG8gdGhlIHJlY2VpdmVyLCBhbmQgcmV0dXJucyB0cnVlCiAgKiBpZiB0aGV5IHJlcHJlc2VudCB0aGUgPGVtPnNhbWU8L2VtPiBvYmplY3QgdXNpbmcgYSBjbGFzcwpAQCAtNjUwLDEwICs1MDAsMTAgQEAKIAlpZiAob2JqZWN0ID09IHRoaXMpIHJldHVybiB0cnVlOwogCWlmICghKG9iamVjdCBpbnN0YW5jZW9mIEltYWdlKSkgcmV0dXJuIGZhbHNlOwogCUltYWdlIGltYWdlID0gKEltYWdlKW9iamVjdDsKLQlyZXR1cm4gZGV2aWNlID09IGltYWdlLmRldmljZSAmJiBwaXhtYXAgPT0gaW1hZ2UucGl4bWFwICYmCi0JCQl0cmFuc3BhcmVudFBpeGVsID09IGltYWdlLnRyYW5zcGFyZW50UGl4ZWwgJiYKLQkJCQkJbWFzayA9PSBpbWFnZS5tYXNrOworCXJldHVybiBkZXZpY2UgPT0gaW1hZ2UuZGV2aWNlICYmIGhhbmRsZSA9PSBpbWFnZS5oYW5kbGUgJiYKKwkJdHJhbnNwYXJlbnRQaXhlbCA9PSBpbWFnZS50cmFuc3BhcmVudFBpeGVsOwogfQorCiAvKioKICAqIFJldHVybnMgdGhlIGNvbG9yIHRvIHdoaWNoIHRvIG1hcCB0aGUgdHJhbnNwYXJlbnQgcGl4ZWwsIG9yIG51bGwgaWYKICAqIHRoZSByZWNlaXZlciBoYXMgbm8gdHJhbnNwYXJlbnQgcGl4ZWwuCkBAIC02NzUsMTcgKzUyNSwxMCBAQAogcHVibGljIENvbG9yIGdldEJhY2tncm91bmQoKSB7CiAJaWYgKGlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKIAlpZiAodHJhbnNwYXJlbnRQaXhlbCA9PSAtMSkgcmV0dXJuIG51bGw7Ci0gICAgLyogQVcKLQlYQ29sb3IgeENvbG9yID0gbmV3IFhDb2xvcigpOwotCXhDb2xvci5waXhlbCA9IHRyYW5zcGFyZW50UGl4ZWw7Ci0JaW50IHhEaXNwbGF5ID0gZGV2aWNlLnhEaXNwbGF5OwotCWludCBjb2xvcm1hcCA9IE9TLlhEZWZhdWx0Q29sb3JtYXAoeERpc3BsYXksIE9TLlhEZWZhdWx0U2NyZWVuKHhEaXNwbGF5KSk7Ci0JT1MuWFF1ZXJ5Q29sb3IoeERpc3BsYXksIGNvbG9ybWFwLCB4Q29sb3IpOwotCXJldHVybiBDb2xvci5tb3RpZl9uZXcoZGV2aWNlLCB4Q29sb3IpOwotICAgICovCi0gICAgU3lzdGVtLm91dC5wcmludGxuKCJJbWFnZS5nZXRCYWNrZ3JvdW5kOiBueWkiKTsKLSAgICByZXR1cm4gbnVsbDsKKwkvL05PVCBET05FCisJcmV0dXJuIG51bGw7CiB9CisKIC8qKgogICogUmV0dXJucyB0aGUgYm91bmRzIG9mIHRoZSByZWNlaXZlci4gVGhlIHJlY3RhbmdsZSB3aWxsIGFsd2F5cwogICogaGF2ZSB4IGFuZCB5IHZhbHVlcyBvZiAwLCBhbmQgdGhlIHdpZHRoIGFuZCBoZWlnaHQgb2YgdGhlCkBAIC02OTgsMTIgKzU0MSwxMSBAQAogICogICAgPGxpPkVSUk9SX0lOVkFMSURfSU1BR0UgLSBpZiB0aGUgaW1hZ2UgaXMgbm90IGEgYml0bWFwIG9yIGFuIGljb248L2xpPgogICogPC91bD4KICAqLwotcHVibGljIFJlY3RhbmdsZSBnZXRCb3VuZHMgKCkgeworcHVibGljIFJlY3RhbmdsZSBnZXRCb3VuZHMoKSB7CiAJaWYgKGlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsJCQotCU9TLkdldFBpeEJvdW5kcyhwaXhtYXAsIGJvdW5kcy5nZXREYXRhKCkpOwotCXJldHVybiBib3VuZHMudG9SZWN0YW5nbGUoKTsKKwlyZXR1cm4gbmV3IFJlY3RhbmdsZSgwLCAwLCBPUy5DR0ltYWdlR2V0V2lkdGgoaGFuZGxlKSwgT1MuQ0dJbWFnZUdldEhlaWdodChoYW5kbGUpKTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIGFuIDxjb2RlPkltYWdlRGF0YTwvY29kZT4gYmFzZWQgb24gdGhlIHJlY2VpdmVyCiAgKiBNb2RpZmljYXRpb25zIG1hZGUgdG8gdGhpcyA8Y29kZT5JbWFnZURhdGE8L2NvZGU+IHdpbGwgbm90CkBAIC03MjAsMTE3ICs1NjIsNDAgQEAKICAqLwogcHVibGljIEltYWdlRGF0YSBnZXRJbWFnZURhdGEoKSB7CiAJaWYgKGlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQlSZWN0YW5nbGUgc3JjQm91bmRzID0gZ2V0Qm91bmRzKCk7Ci0JaW50IHdpZHRoID0gc3JjQm91bmRzLndpZHRoOwotCWludCBoZWlnaHQgPSBzcmNCb3VuZHMuaGVpZ2h0OwotICAgIGludCBzcmNEZXB0aD0gZ2V0RGVwdGgocGl4bWFwKTsKIAotCS8qIEdldCB0aGUgZGF0YSBmb3IgdGhlIHNvdXJjZSBpbWFnZS4gKi8KLSAgICBpbnQgc3JjUm93Qnl0ZXM9IHJvd0J5dGVzKHdpZHRoLCBzcmNEZXB0aCk7Ci0gICAgaW50IHNyY0JpdHNQZXJQaXhlbD0gc3JjRGVwdGg7Ci0JYnl0ZVtdIHNyY0RhdGEgPSBuZXcgYnl0ZVtzcmNSb3dCeXRlcyAqIGhlaWdodF07Ci0gCWNvcHlQaXhNYXBEYXRhKHBpeG1hcCwgc3JjRGF0YSk7Ci0KLQkvKiBCdWlsZCB0aGUgcGFsZXR0ZSAqLwotCVBhbGV0dGVEYXRhIHBhbGV0dGUgPSBudWxsOwotCXN3aXRjaCAoc3JjRGVwdGgpIHsKLQljYXNlIDE6Ci0JCXBhbGV0dGUgPSBuZXcgUGFsZXR0ZURhdGEobmV3IFJHQltdIHsKLQkJCW5ldyBSR0IoMCwgMCwgMCksCi0JCQluZXcgUkdCKDI1NSwgMjU1LCAyNTUpCi0JCX0pOwotCQlicmVhazsKLQljYXNlIDQ6Ci0JCXNob3J0W10gY29sb3JUYWJsZTQ9IGdldENvbG9yVGFibGUocGl4bWFwKTsKLQkJUkdCW10gcmdiczQgPSBuZXcgUkdCWyBjb2xvclRhYmxlNC5sZW5ndGgvNCBdOwotCQlmb3IgKGludCBpID0gMDsgaSA8IHJnYnM0Lmxlbmd0aDsgaSsrKSB7Ci0JCQlpbnQgcGFja2VkPSBnZXRSR0IoY29sb3JUYWJsZTQsIGkpOwotCQkJcmdiczRbaV0gPSBuZXcgUkdCKChwYWNrZWQgPj4gMTYpICYgMHhGRiwgKHBhY2tlZCA+PiA4KSAmIDB4RkYsIChwYWNrZWQgPj4gMCkgJiAweEZGKTsKLQkJfQotCQlwYWxldHRlID0gbmV3IFBhbGV0dGVEYXRhKHJnYnM0KTsKLQkJYnJlYWs7Ci0JY2FzZSA4OgotCQkvKiBOb3JtYWxpemUgdGhlIHBpeGVscyBpbiB0aGUgc291cmNlIGltYWdlIGRhdGEgKGJ5IG1ha2luZyB0aGUKLQkJICogcGl4ZWwgdmFsdWVzIHNlcXVlbnRpYWwgc3RhcnRpbmcgYXQgcGl4ZWwgMCkuIFJlc2VydmUgbm9ybWFsaXplZAotCQkgKiBwaXhlbCAwIHNvIHRoYXQgaXQgbWFwcyB0byByZWFsIHBpeGVsIDAuIFRoaXMgYXNzdW1lcyBwaXhlbCAwIGlzCi0JCSAqIGFsd2F5cyB1c2VkIGluIHRoZSBpbWFnZS4KLQkJICovCi0JCWJ5dGVbXSBub3JtUGl4ZWwgPSBuZXcgYnl0ZVsgMjU2IF07Ci0JCWZvciAoaW50IGluZGV4ID0gMDsgaW5kZXggPCBub3JtUGl4ZWwubGVuZ3RoOyBpbmRleCsrKSB7Ci0JCQlub3JtUGl4ZWxbIGluZGV4IF0gPSAwOwotCQl9Ci0JCWludCBudW1QaXhlbHMgPSAxOwotCQlpbnQgaW5kZXggPSAwOwotCQlmb3IgKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7Ci0JCQlmb3IgKGludCB4ID0gMDsgeCA8IHNyY1Jvd0J5dGVzOyB4KyspIHsKLQkJCQlpbnQgc3JjUGl4ZWwgPSBzcmNEYXRhWyBpbmRleCArIHggXSAmIDB4RkY7Ci0JCQkJaWYgKHNyY1BpeGVsICE9IDAgJiYgbm9ybVBpeGVsWyBzcmNQaXhlbCBdID09IDApIHsKLQkJCQkJbm9ybVBpeGVsWyBzcmNQaXhlbCBdID0gKGJ5dGUpbnVtUGl4ZWxzKys7Ci0JCQkJfQotCQkJCXNyY0RhdGFbIGluZGV4ICsgeCBdID0gbm9ybVBpeGVsWyBzcmNQaXhlbCBdOwotCQkJfQotCQkJaW5kZXggKz0gc3JjUm93Qnl0ZXM7Ci0JCX0KLQkJCi0JCXNob3J0W10gY29sb3JUYWJsZT0gZ2V0Q29sb3JUYWJsZShwaXhtYXApOwotCi0JCS8qIENyZWF0ZSBhIHBhbGV0dGUgd2l0aCBvbmx5IHRoZSBSR0IgdmFsdWVzIHVzZWQgaW4gdGhlIGltYWdlLiAqLwotCQlSR0JbXSByZ2JzID0gbmV3IFJHQlsgbnVtUGl4ZWxzIF07Ci0JCWZvciAoaW50IHNyY1BpeGVsID0gMDsgc3JjUGl4ZWwgPCBub3JtUGl4ZWwubGVuZ3RoOyBzcmNQaXhlbCsrKSB7Ci0JCQkvLyBJZiB0aGUgcGl4ZWwgdmFsdWUgd2FzIHVzZWQgaW4gdGhlIGltYWdlLCBnZXQgaXRzIFJHQiB2YWx1ZXMuCi0JCQlpZiAoc3JjUGl4ZWwgPT0gMCB8fCBub3JtUGl4ZWxbIHNyY1BpeGVsIF0gIT0gMCkgewotCQkJCWludCBwYWNrZWQ9IGdldFJHQihjb2xvclRhYmxlLCBzcmNQaXhlbCk7Ci0JCQkJaW50IHJnYkluZGV4ID0gbm9ybVBpeGVsWyBzcmNQaXhlbCBdICYgMHhGRjsKLQkJCQlyZ2JzWyByZ2JJbmRleCBdID0gbmV3IFJHQigocGFja2VkID4+IDE2KSAmIDB4RkYsIChwYWNrZWQgPj4gOCkgJiAweEZGLCAocGFja2VkID4+IDApICYgMHhGRik7CQkJCQkKLQkJCX0KLQkJfQotCQlwYWxldHRlID0gbmV3IFBhbGV0dGVEYXRhKHJnYnMpOwotCQlicmVhazsKLQljYXNlIDE2OgotCWNhc2UgMjQ6Ci0JY2FzZSAzMjoKLQkJcGFsZXR0ZSA9IG5ldyBQYWxldHRlRGF0YShnZXRSZWRNYXNrKHNyY0RlcHRoKSwgZ2V0R3JlZW5NYXNrKHNyY0RlcHRoKSwgZ2V0Qmx1ZU1hc2soc3JjRGVwdGgpKTsKLQkJYnJlYWs7Ci0JZGVmYXVsdDoKLQkJU1dULmVycm9yKFNXVC5FUlJPUl9VTlNVUFBPUlRFRF9ERVBUSCk7Ci0JfQorCWludCB3aWR0aCA9IE9TLkNHSW1hZ2VHZXRXaWR0aChoYW5kbGUpOworCWludCBoZWlnaHQgPSBPUy5DR0ltYWdlR2V0SGVpZ2h0KGhhbmRsZSk7CisJaW50IGJwciA9IE9TLkNHSW1hZ2VHZXRCeXRlc1BlclJvdyhoYW5kbGUpOworCWludCBicHAgPSBPUy5DR0ltYWdlR2V0Qml0c1BlclBpeGVsKGhhbmRsZSk7CQorCWludCBkYXRhU2l6ZSA9IGhlaWdodCAqIGJwcjsKKwlieXRlW10gc3JjRGF0YSA9IG5ldyBieXRlW2RhdGFTaXplXTsKKwlPUy5tZW1jcHkoc3JjRGF0YSwgZGF0YSwgZGF0YVNpemUpOwogCQotCQotCUltYWdlRGF0YSBkYXRhID0gbmV3IEltYWdlRGF0YSh3aWR0aCwgaGVpZ2h0LCBzcmNEZXB0aCwgcGFsZXR0ZSk7CisJUGFsZXR0ZURhdGEgcGFsZXR0ZSA9IG5ldyBQYWxldHRlRGF0YSgweEZGMDAwMCwgMHhGRjAwLCAweEZGKTsKKwlJbWFnZURhdGEgZGF0YSA9IG5ldyBJbWFnZURhdGEod2lkdGgsIGhlaWdodCwgYnBwLCBwYWxldHRlKTsKIAlkYXRhLmRhdGEgPSBzcmNEYXRhOwotCWlmIChmYWxzZSAmJiBzcmNCaXRzUGVyUGl4ZWwgPT0gMzIpIHsKLQkJLyoKLQkJICogSWYgYml0cyBwZXIgcGl4ZWwgaXMgMzIsIHNjYWxlIHRoZSBkYXRhIGRvd24gdG8gMjQsIHNpbmNlIHdlIGRvIG5vdAotCQkgKiBzdXBwb3J0IDMyLWJpdCBpbWFnZXMKLQkJICovCi0JCWJ5dGVbXSBvbGREYXRhID0gZGF0YS5kYXRhOwotCQlpbnQgYnl0ZXNQZXJMaW5lID0gKHdpZHRoICogc3JjRGVwdGggKyA3KSAvIDg7Ci0JCWJ5dGVzUGVyTGluZSA9IChieXRlc1BlckxpbmUgKyAzKSAvIDQgKiA0OwotCQlieXRlW10gbmV3RGF0YSA9IG5ldyBieXRlW2J5dGVzUGVyTGluZSAqIGhlaWdodF07Ci0JCWludCBkZXN0SW5kZXggPSAwOwotCQlpbnQgc3JjSW5kZXggPSAwOwotCQkKLQkJZm9yIChpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewotCQkJZGVzdEluZGV4ID0geSAqIGJ5dGVzUGVyTGluZTsKLQkJCXNyY0luZGV4ID0geSAqIHNyY1Jvd0J5dGVzOwotCQkJZm9yIChpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7Ci0JCQkJbmV3RGF0YVtkZXN0SW5kZXhdID0gb2xkRGF0YVtzcmNJbmRleCArIDFdOwotCQkJCW5ld0RhdGFbZGVzdEluZGV4ICsgMV0gPSBvbGREYXRhW3NyY0luZGV4ICsgMl07Ci0JCQkJbmV3RGF0YVtkZXN0SW5kZXggKyAyXSA9IG9sZERhdGFbc3JjSW5kZXggKyAzXTsKLQkJCQlzcmNJbmRleCArPSA0OwotCQkJCWRlc3RJbmRleCArPSAzOwotCQkJfQotCQl9Ci0JCWRhdGEuZGF0YSA9IG5ld0RhdGE7Ci0JfQotCWlmICh0cmFuc3BhcmVudFBpeGVsID09IC0xICYmIHR5cGUgPT0gU1dULklDT04gJiYgbWFzayAhPSAwKSB7Ci0JCS8qIEdldCB0aGUgaWNvbiBkYXRhICovCi0JCWRhdGEubWFza1BhZCA9IDQ7Ci0JCWludCBtYXNrUm93Qnl0ZXM9IHJvd0J5dGVzKHdpZHRoLCBnZXREZXB0aChtYXNrKSk7Ci0JCWRhdGEubWFza0RhdGEgPSBuZXcgYnl0ZVttYXNrUm93Qnl0ZXMgKiBoZWlnaHRdOwotCQljb3B5UGl4TWFwRGF0YShtYXNrLCBkYXRhLm1hc2tEYXRhKTsKLQl9CisJZGF0YS5ieXRlc1BlckxpbmUgPSBicHI7CisKIAlkYXRhLnRyYW5zcGFyZW50UGl4ZWwgPSB0cmFuc3BhcmVudFBpeGVsOworCWlmICh0cmFuc3BhcmVudFBpeGVsID09IC0xICYmIHR5cGUgPT0gU1dULklDT04pIHsKKwkJLyogR2V0IHRoZSBpY29uIG1hc2sgZGF0YSAqLworCQlpbnQgbWFza0JwbCA9ICgoKHdpZHRoICsgNykgLyA4KSArIDMpIC8gNCAqIDQ7CisJCWJ5dGVbXSBtYXNrRGF0YSA9IG5ldyBieXRlW2hlaWdodCAqIG1hc2tCcGxdOworCQlpbnQgb2Zmc2V0ID0gMCwgbWFza09mZnNldCA9IDA7CisJCWZvciAoaW50IHkgPSAwOyB5PGhlaWdodDsgeSsrKSB7CisJCQlmb3IgKGludCB4ID0gMDsgeDx3aWR0aDsgeCsrKSB7CisJCQkJaWYgKHNyY0RhdGFbb2Zmc2V0XSAhPSAwKSB7CisJCQkJCW1hc2tEYXRhW21hc2tPZmZzZXQgKyAoeCA+PiAzKV0gfD0gKDEgPDwgKDcgLSAoeCAmIDB4NykpKTsKKwkJCQl9IGVsc2UgeworCQkJCQltYXNrRGF0YVttYXNrT2Zmc2V0ICsgKHggPj4gMyldICY9IH4oMSA8PCAoNyAtICh4ICYgMHg3KSkpOworCQkJCX0KKwkJCQlvZmZzZXQgKz0gNDsKKwkJCX0KKwkJCW1hc2tPZmZzZXQgKz0gbWFza0JwbDsKKwkJfQorCQlkYXRhLm1hc2tEYXRhID0gbWFza0RhdGE7CisJCWRhdGEubWFza1BhZCA9IDQ7CisJfQogCWRhdGEuYWxwaGEgPSBhbHBoYTsKIAlpZiAoYWxwaGEgPT0gLTEgJiYgYWxwaGFEYXRhICE9IG51bGwpIHsKIAkJZGF0YS5hbHBoYURhdGEgPSBuZXcgYnl0ZVthbHBoYURhdGEubGVuZ3RoXTsKQEAgLTgzOCw3MyArNjAzLDM0IEBACiAJfQogCXJldHVybiBkYXRhOwogfQotLyoqCi0gKiBHZXQgdGhlIG9mZnNldCBmb3IgdGhlIGdpdmVuIG1hc2suCisKKy8qKgkgCisgKiBJbnZva2VzIHBsYXRmb3JtIHNwZWNpZmljIGZ1bmN0aW9uYWxpdHkgdG8gYWxsb2NhdGUgYSBuZXcgaW1hZ2UuCisgKiA8cD4KKyAqIDxiPklNUE9SVEFOVDo8L2I+IFRoaXMgbWV0aG9kIGlzIDxlbT5ub3Q8L2VtPiBwYXJ0IG9mIHRoZSBwdWJsaWMKKyAqIEFQSSBmb3IgPGNvZGU+SW1hZ2U8L2NvZGU+LiBJdCBpcyBtYXJrZWQgcHVibGljIG9ubHkgc28gdGhhdCBpdAorICogY2FuIGJlIHNoYXJlZCB3aXRoaW4gdGhlIHBhY2thZ2VzIHByb3ZpZGVkIGJ5IFNXVC4gSXQgaXMgbm90CisgKiBhdmFpbGFibGUgb24gYWxsIHBsYXRmb3JtcywgYW5kIHNob3VsZCBuZXZlciBiZSBjYWxsZWQgZnJvbQorICogYXBwbGljYXRpb24gY29kZS4KKyAqIDwvcD4KICAqCi0gKiBGb3IgMjQgYW5kIDMyLWJpdCBtYXNrcywgdGhlIG9mZnNldCBpbmRpY2F0ZXMgd2hpY2ggYnl0ZSBob2xkcyB0aGUKLSAqICBkYXRhIGZvciB0aGUgZ2l2ZW4gbWFzayAoaW5kZXhlZCBmcm9tIDApLgotICogIEZvciBleGFtcGxlLCBpbiAweDAwMDBGRjAwLCB0aGUgYnl0ZSBvZmZzZXQgaXMgMS4KKyAqIEBwYXJhbSBkZXZpY2UgdGhlIGRldmljZSBvbiB3aGljaCB0byBhbGxvY2F0ZSB0aGUgY29sb3IKKyAqIEBwYXJhbSB0eXBlIHRoZSB0eXBlIG9mIHRoZSBpbWFnZSAoPGNvZGU+U1dULkJJVE1BUDwvY29kZT4gb3IgPGNvZGU+U1dULklDT048L2NvZGU+KQorICogQHBhcmFtIGhhbmRsZSB0aGUgT1MgaGFuZGxlIGZvciB0aGUgaW1hZ2UKKyAqIEBwYXJhbSBkYXRhIHRoZSBPUyBkYXRhIGZvciB0aGUgaW1hZ2UKICAqCi0gKiBGb3IgMTYtYml0IG1hc2tzLCB0aGUgb2Zmc2V0IGluZGljYXRlcyB3aGljaCBiaXQgaG9sZHMgdGhlIG1vc3Qgc2lnbmlmaWNhbnQKLSAqICBkYXRhIGZvciB0aGUgZ2l2ZW4gbWFzayAoaW5kZXhlZCBmcm9tIDEpLgotICogIEZvciBleGFtcGxlLCBpbiAweDdFMCwgdGhlIGJpdCBvZmZzZXQgaXMgMTEuCi0gKgotICogVGhlIGRpZmZlcmVudCBzZW1hbnRpY3MgYXJlIG5lY2Vzc2FyeSBiZWNhdXNlIDI0LSBhbmQgMzItYml0IGltYWdlcwotICogaGF2ZSB0aGVpciBjb2xvciBjb21wb25lbnRzIGFsaWduZWQgb24gYnl0ZSBib3VuZGFyaWVzLCBhbmQgMTYtYml0IGltYWdlcwotICogZG8gbm90LgorICogQHByaXZhdGUKICAqLwotc3RhdGljIGludCBnZXRPZmZzZXRGb3JNYXNrKGludCBiaXRzcHAsIGludCBtYXNrLCBib29sZWFuIG1zYkZpcnN0KSB7Ci0JaWYgKGJpdHNwcCAlIDggIT0gMCkgewotCQlTeXN0ZW0uZXJyLnByaW50bG4oIkltYWdlLmdldE9mZnNldEZvck1hc2s6IGVycm9yIDEiKTsKLQkJcmV0dXJuIDA7Ci0JfQotCWludCBwb2ZmPSAwOwotCXN3aXRjaCAobWFzaykgewotCS8qIDI0LWJpdCBhbmQgMzItYml0IG1hc2tzICovCi0JY2FzZSAweDAwMDAwMEZGOgotCQlwb2ZmID0gMDsKLQkJYnJlYWs7Ci0JY2FzZSAweDAwMDBGRjAwOgotCQlwb2ZmID0gMTsKLQkJYnJlYWs7Ci0JY2FzZSAweDAwRkYwMDAwOgotCQlwb2ZmID0gMjsKLQkJYnJlYWs7Ci0JY2FzZSAweEZGMDAwMDAwOgotCQlwb2ZmID0gMzsKLQkJYnJlYWs7Ci0JLyogMTYtYml0IG1hc2tzICovCi0JY2FzZSAweDAwMUY6Ci0JCXBvZmYgPSA1OwotCQlicmVhazsKLQljYXNlIDB4MDNFMDoKLQkJcG9mZiA9IDEwOwotCQlicmVhazsKLQljYXNlIDB4MDdFMDoKLQkJcG9mZiA9IDExOwotCQlicmVhazsKLQljYXNlIDB4N0MwMDoKLQkJcG9mZiA9IDE1OwotCQlicmVhazsKLQljYXNlIDB4RjgwMDoKLQkJcG9mZiA9IDE2OwotCQlicmVhazsKLQlkZWZhdWx0OgotCQlTeXN0ZW0uZXJyLnByaW50bG4oIkltYWdlLmdldE9mZnNldEZvck1hc2s6IGVycm9yIDIiKTsKLQkJcmV0dXJuIDA7Ci0JfQotCWlmIChiaXRzcHAgPT0gMTYpIHsKLQkJcmV0dXJuIHBvZmY7Ci0JfQotCWlmIChwb2ZmID49IGJpdHNwcCAvIDgpIHsKLQkJU3lzdGVtLmVyci5wcmludGxuKCJJbWFnZS5nZXRPZmZzZXRGb3JNYXNrOiBlcnJvciAzIik7Ci0JCXJldHVybiAwOwotCX0KLQlpZiAobXNiRmlyc3QpIHsKLQkJcG9mZiA9IChiaXRzcHAvOCAtIDEpIC0gcG9mZjsKLQl9Ci0JcmV0dXJuIHBvZmY7CitwdWJsaWMgc3RhdGljIEltYWdlIGNhcmJvbl9uZXcoRGV2aWNlIGRldmljZSwgaW50IHR5cGUsIGludCBoYW5kbGUsIGludCBkYXRhKSB7CisJaWYgKGRldmljZSA9PSBudWxsKSBkZXZpY2UgPSBEZXZpY2UuZ2V0RGV2aWNlKCk7CisJSW1hZ2UgaW1hZ2UgPSBuZXcgSW1hZ2UoKTsKKwlpbWFnZS50eXBlID0gdHlwZTsKKwlpbWFnZS5oYW5kbGUgPSBoYW5kbGU7CisJaW1hZ2UuZGF0YSA9IGRhdGE7CisJaW1hZ2UuZGV2aWNlID0gZGV2aWNlOworCXJldHVybiBpbWFnZTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGUgcmVjZWl2ZXIuIEFueSB0d28gCiAgKiBvYmplY3RzIHdoaWNoIHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHBhc3NlZCB0byAKQEAgLTkxNiw3NCArNjQyLDE0MCBAQAogICogQHNlZSAjZXF1YWxzCiAgKi8KIHB1YmxpYyBpbnQgaGFzaENvZGUgKCkgewotCXJldHVybiBwaXhtYXA7CisJcmV0dXJuIGhhbmRsZTsKIH0KKwogdm9pZCBpbml0KERldmljZSBkZXZpY2UsIGludCB3aWR0aCwgaW50IGhlaWdodCkgewotCWlmIChkZXZpY2UgPT0gbnVsbCkgZGV2aWNlID0gRGV2aWNlLmdldERldmljZSgpOwotCWlmIChkZXZpY2UgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQl0aGlzLmRldmljZSA9IGRldmljZTsKLQkvKiBDcmVhdGUgdGhlIHBpeG1hcCAqLwotCWlmICh3aWR0aCA8PSAwIHwgaGVpZ2h0IDw9IDApCi0JCVNXVC5lcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7Ci0KLQl0aGlzLnR5cGUgPSBTV1QuQklUTUFQOwotCXRoaXMucGl4bWFwID0gY3JlYXRlUGl4TWFwKHdpZHRoLCBoZWlnaHQsIGRldmljZS5mU2NyZWVuRGVwdGgpOwotCi0JLyogRmlsbCB0aGUgYml0bWFwIHdpdGggd2hpdGUgKi8KLSAgICBpbnRbXSBvZmZzY3JlZW5HV29ybGQ9IG5ldyBpbnRbMV07Ci0JT1MuTmV3R1dvcmxkRnJvbVB0cihvZmZzY3JlZW5HV29ybGQsIHBpeG1hcCk7Ci0JaW50IGd3PSBvZmZzY3JlZW5HV29ybGRbMF07Ci0JaWYgKGd3ID09IDApIFNXVC5lcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOwotCi0JaW50W10gc2F2ZVBvcnQ9IG5ldyBpbnRbMV07Ci0JaW50W10gc2F2ZUdXb3JsZD0gbmV3IGludFsxXTsKLQlPUy5HZXRHV29ybGQoc2F2ZVBvcnQsIHNhdmVHV29ybGQpOwotCU9TLlNldEdXb3JsZChndywgMCk7Ci0JT1MuRXJhc2VSZWN0KG5ldyBzaG9ydFtdIHsgMCwgMCwgKHNob3J0KWhlaWdodCwgKHNob3J0KXdpZHRoIH0gKTsKLQlPUy5TZXRHV29ybGQoc2F2ZVBvcnRbMF0sIHNhdmVHV29ybGRbMF0pOwotCQotCU9TLkRpc3Bvc2VHV29ybGQoZ3cpOwotfQotdm9pZCBpbml0KERldmljZSBkZXZpY2UsIEltYWdlRGF0YSBpbWFnZSkgewotCWlmIChkZXZpY2UgPT0gbnVsbCkgZGV2aWNlID0gRGV2aWNlLmdldERldmljZSgpOwotCWlmIChkZXZpY2UgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQl0aGlzLmRldmljZSA9IGRldmljZTsKLQlpZiAoaW1hZ2UgPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQotCWludCBwaXhtYXA9IGNyZWF0ZVBpeE1hcChpbWFnZS53aWR0aCwgaW1hZ2UuaGVpZ2h0LCBpbWFnZS5kZXB0aCk7Ci0KLQlpbnRbXSB0cmFuc1BpeGVsPSBudWxsOwotCWlmIChpbWFnZS50cmFuc3BhcmVudFBpeGVsICE9IC0xKSB0cmFuc1BpeGVsPSBuZXcgaW50W117IGltYWdlLnRyYW5zcGFyZW50UGl4ZWwgfTsKLQkKLQlpbnQgZXJyb3I9IHB1dEltYWdlKGltYWdlLCB0cmFuc1BpeGVsLCBwaXhtYXApOwotCWlmIChlcnJvciAhPSAwKSB7Ci0JCWRpc3Bvc2VCaXRtYXBPclBpeG1hcChwaXhtYXApOwotCQlTV1QuZXJyb3IoZXJyb3IpOworCWlmICh3aWR0aCA8PSAwIHx8IGhlaWdodCA8PSAwKSB7CisJCVNXVC5lcnJvciAoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwogCX0KLQlpZiAoaW1hZ2UuZ2V0VHJhbnNwYXJlbmN5VHlwZSgpID09IFNXVC5UUkFOU1BBUkVOQ1lfTUFTSyB8fCBpbWFnZS50cmFuc3BhcmVudFBpeGVsICE9IC0xKSB7Ci0JCWlmIChpbWFnZS50cmFuc3BhcmVudFBpeGVsICE9IC0xKSB0cmFuc3BhcmVudFBpeGVsID0gdHJhbnNQaXhlbFswXTsKLQkJaW50IG1hc2s9IGNyZWF0ZU1hc2tJbWFnZShpbWFnZS5nZXRUcmFuc3BhcmVuY3lNYXNrKCkpOwotCQlpZiAobWFzayA9PSAwKSB7Ci0JCQlkaXNwb3NlQml0bWFwT3JQaXhtYXAocGl4bWFwKTsKLQkJCVNXVC5lcnJvcihlcnJvcik7CisJdGhpcy5kZXZpY2UgPSBkZXZpY2U7CisJdGhpcy50eXBlID0gU1dULkJJVE1BUDsKKworCS8qIENyZWF0ZSB0aGUgaW1hZ2UgKi8KKwlpbnQgYnByID0gd2lkdGggKiA0OworCWludCBkYXRhU2l6ZSA9IGhlaWdodCAqIGJwcjsKKwlkYXRhID0gT1MuTmV3UHRyKGRhdGFTaXplKTsKKwlpZiAoZGF0YSA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCWludCBwcm92aWRlciA9IE9TLkNHRGF0YVByb3ZpZGVyQ3JlYXRlV2l0aERhdGEoMCwgZGF0YSwgZGF0YVNpemUsIDApOworCWlmIChwcm92aWRlciA9PSAwKSB7CisJCU9TLkRpc3Bvc2VQdHIoZGF0YSk7CisJCVNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7CisJfQorCWludCBjb2xvcnNwYWNlID0gZGV2aWNlLmNvbG9yc3BhY2U7CisJaGFuZGxlID0gT1MuQ0dJbWFnZUNyZWF0ZSh3aWR0aCwgaGVpZ2h0LCA4LCAzMiwgYnByLCBjb2xvcnNwYWNlLCBPUy5rQ0dJbWFnZUFscGhhTm9uZVNraXBGaXJzdCwgcHJvdmlkZXIsIG51bGwsIGZhbHNlLCAwKTsKKwlPUy5DR0RhdGFQcm92aWRlclJlbGVhc2UocHJvdmlkZXIpOworCWlmIChoYW5kbGUgPT0gMCkgeworCQlPUy5EaXNwb3NlUHRyKGRhdGEpOworCQlTV1QuZXJyb3IoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCX0KKwkJCisJLyogRmlsbCB0aGUgaW1hZ2Ugd2l0aCB3aGl0ZSAqLworCWludCBicGMgPSBPUy5DR0ltYWdlR2V0Qml0c1BlckNvbXBvbmVudChoYW5kbGUpOworCWludCBjb250ZXh0ID0gT1MuQ0dCaXRtYXBDb250ZXh0Q3JlYXRlKHRoaXMuZGF0YSwgd2lkdGgsIGhlaWdodCwgYnBjLCBicHIsIGNvbG9yc3BhY2UsIE9TLmtDR0ltYWdlQWxwaGFOb25lU2tpcEZpcnN0KTsKKwlDR1JlY3QgcmVjdCA9IG5ldyBDR1JlY3QoKTsKKwlyZWN0LndpZHRoID0gd2lkdGg7IHJlY3QuaGVpZ2h0ID0gaGVpZ2h0OworCU9TLkNHQ29udGV4dFNldFJHQkZpbGxDb2xvcihjb250ZXh0LCAxLCAxLCAxLCAxKTsKKwlPUy5DR0NvbnRleHRGaWxsUmVjdChjb250ZXh0LCByZWN0KTsKKwlPUy5DR0NvbnRleHRSZWxlYXNlKGNvbnRleHQpOworfQorCit2b2lkIGluaXQoRGV2aWNlIGRldmljZSwgSW1hZ2VEYXRhIGltYWdlKSB7CisJaWYgKGltYWdlID09IG51bGwpIFNXVC5lcnJvcihTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJdGhpcy5kZXZpY2UgPSBkZXZpY2U7CisJaW50IHdpZHRoID0gaW1hZ2Uud2lkdGg7CisJaW50IGhlaWdodCA9IGltYWdlLmhlaWdodDsKKwkKKwkvKiBDcmVhdGUgdGhlIGltYWdlICovCisJaW50IGRhdGFTaXplID0gd2lkdGggKiBoZWlnaHQgKiA0OworCWRhdGEgPSBPUy5OZXdQdHIoZGF0YVNpemUpOworCWlmIChkYXRhID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7CisJaW50IHByb3ZpZGVyID0gT1MuQ0dEYXRhUHJvdmlkZXJDcmVhdGVXaXRoRGF0YSgwLCBkYXRhLCBkYXRhU2l6ZSwgMCk7CisJaWYgKHByb3ZpZGVyID09IDApIHsKKwkJT1MuRGlzcG9zZVB0cihkYXRhKTsKKwkJU1dULmVycm9yKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwl9CisJaW50IGNvbG9yc3BhY2UgPSBkZXZpY2UuY29sb3JzcGFjZTsKKwlpbnQgdHJhbnNwYXJlbmN5ID0gaW1hZ2UuZ2V0VHJhbnNwYXJlbmN5VHlwZSgpOyAKKwlpbnQgYWxwaGFJbmZvID0gdHJhbnNwYXJlbmN5ID09IFNXVC5UUkFOU1BBUkVOQ1lfTk9ORSA/IE9TLmtDR0ltYWdlQWxwaGFOb25lU2tpcEZpcnN0IDogT1Mua0NHSW1hZ2VBbHBoYUZpcnN0OworCWhhbmRsZSA9IE9TLkNHSW1hZ2VDcmVhdGUod2lkdGgsIGhlaWdodCwgOCwgMzIsIHdpZHRoICogNCwgY29sb3JzcGFjZSwgYWxwaGFJbmZvLCBwcm92aWRlciwgbnVsbCwgZmFsc2UsIDApOworCU9TLkNHRGF0YVByb3ZpZGVyUmVsZWFzZShwcm92aWRlcik7CisJaWYgKGhhbmRsZSA9PSAwKSB7CisJCU9TLkRpc3Bvc2VQdHIoZGF0YSk7CisJCVNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7CisJfQorCQorCS8qIEluaXRpYWxpemUgZGF0YSAqLworCWludCBicHIgPSB3aWR0aCAqIDQ7CisJUGFsZXR0ZURhdGEgcGFsZXR0ZSA9IGltYWdlLnBhbGV0dGU7CisJUGFsZXR0ZURhdGEgbmV3UGFsZXR0ZSA9IG5ldyBQYWxldHRlRGF0YSgweEZGMDAwMCwgMHhGRjAwLCAweEZGKTsKKwlieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbZGF0YVNpemVdOworCWlmIChwYWxldHRlLmlzRGlyZWN0KSB7CisJCUltYWdlRGF0YS5ibGl0KEltYWdlRGF0YS5CTElUX1NSQywKKwkJCWltYWdlLmRhdGEsIGltYWdlLmRlcHRoLCBpbWFnZS5ieXRlc1BlckxpbmUsIGltYWdlLmdldEJ5dGVPcmRlcigpLCAwLCAwLCB3aWR0aCwgaGVpZ2h0LCBwYWxldHRlLnJlZE1hc2ssIHBhbGV0dGUuZ3JlZW5NYXNrLCBwYWxldHRlLmJsdWVNYXNrLAorCQkJSW1hZ2VEYXRhLkFMUEhBX09QQVFVRSwgbnVsbCwgMCwgMCwgMCwgCisJCQlidWZmZXIsIDMyLCBicHIsIEltYWdlRGF0YS5NU0JfRklSU1QsIDAsIDAsIHdpZHRoLCBoZWlnaHQsIDB4RkYwMDAwLCAweEZGMDAsIDB4RkYsCisJCQlmYWxzZSwgZmFsc2UpOworCX0gZWxzZSB7CisJCVJHQltdIHJnYnMgPSBwYWxldHRlLmdldFJHQnMoKTsKKwkJaW50IGxlbmd0aCA9IHJnYnMubGVuZ3RoOworCQlieXRlW10gc3JjUmVkcyA9IG5ldyBieXRlW2xlbmd0aF07CisJCWJ5dGVbXSBzcmNHcmVlbnMgPSBuZXcgYnl0ZVtsZW5ndGhdOworCQlieXRlW10gc3JjQmx1ZXMgPSBuZXcgYnl0ZVtsZW5ndGhdOworCQlmb3IgKGludCBpID0gMDsgaSA8IHJnYnMubGVuZ3RoOyBpKyspIHsKKwkJCVJHQiByZ2IgPSByZ2JzW2ldOworCQkJaWYgKHJnYiA9PSBudWxsKSBjb250aW51ZTsKKwkJCXNyY1JlZHNbaV0gPSAoYnl0ZSlyZ2IucmVkOworCQkJc3JjR3JlZW5zW2ldID0gKGJ5dGUpcmdiLmdyZWVuOworCQkJc3JjQmx1ZXNbaV0gPSAoYnl0ZSlyZ2IuYmx1ZTsKIAkJfQotCQl0aGlzLm1hc2sgPSBtYXNrOwotCQlpZiAoaW1hZ2UuZ2V0VHJhbnNwYXJlbmN5VHlwZSgpID09IFNXVC5UUkFOU1BBUkVOQ1lfTUFTSykgewotCQkJdGhpcy50eXBlID0gU1dULklDT047Ci0JCX0gZWxzZSB7Ci0JCQl0aGlzLnR5cGUgPSBTV1QuQklUTUFQOworCQlJbWFnZURhdGEuYmxpdChJbWFnZURhdGEuQkxJVF9TUkMsCisJCQlpbWFnZS5kYXRhLCBpbWFnZS5kZXB0aCwgaW1hZ2UuYnl0ZXNQZXJMaW5lLCBpbWFnZS5nZXRCeXRlT3JkZXIoKSwgMCwgMCwgd2lkdGgsIGhlaWdodCwgc3JjUmVkcywgc3JjR3JlZW5zLCBzcmNCbHVlcywKKwkJCUltYWdlRGF0YS5BTFBIQV9PUEFRVUUsIG51bGwsIDAsIDAsIDAsCisJCQlidWZmZXIsIDMyLCBicHIsIEltYWdlRGF0YS5NU0JfRklSU1QsIDAsIDAsIHdpZHRoLCBoZWlnaHQsIG5ld1BhbGV0dGUucmVkTWFzaywgbmV3UGFsZXR0ZS5ncmVlbk1hc2ssIG5ld1BhbGV0dGUuYmx1ZU1hc2ssCisJCQlmYWxzZSwgZmFsc2UpOworCX0KKwkKKwkvKiBJbml0aWFsaXplIHRyYW5zcGFyZW5jeSAqLworCWlmICh0cmFuc3BhcmVuY3kgPT0gU1dULlRSQU5TUEFSRU5DWV9NQVNLIHx8IGltYWdlLnRyYW5zcGFyZW50UGl4ZWwgIT0gLTEpIHsKKwkJdGhpcy50eXBlID0gaW1hZ2UudHJhbnNwYXJlbnRQaXhlbCAhPSAtMSA/IFNXVC5CSVRNQVAgOiBTV1QuSUNPTjsKKwkJaWYgKGltYWdlLnRyYW5zcGFyZW50UGl4ZWwgIT0gLTEpIHt9CisJCUltYWdlRGF0YSBtYXNrSW1hZ2UgPSBpbWFnZS5nZXRUcmFuc3BhcmVuY3lNYXNrKCk7CisJCWJ5dGVbXSBtYXNrRGF0YSA9IG1hc2tJbWFnZS5kYXRhOworCQlpbnQgbWFza0JwbCA9IG1hc2tJbWFnZS5ieXRlc1BlckxpbmU7CisJCWludCBvZmZzZXQgPSAwLCBtYXNrT2Zmc2V0ID0gMDsKKwkJZm9yIChpbnQgeSA9IDA7IHk8aGVpZ2h0OyB5KyspIHsKKwkJCWZvciAoaW50IHggPSAwOyB4PHdpZHRoOyB4KyspIHsKKwkJCQlidWZmZXJbb2Zmc2V0XSA9ICgobWFza0RhdGFbbWFza09mZnNldCArICh4ID4+IDMpXSkgJiAoMSA8PCAoNyAtICh4ICYgMHg3KSkpKSAhPSAwID8gKGJ5dGUpMHhmZiA6IDA7CisJCQkJb2Zmc2V0ICs9IDQ7CisJCQl9CisJCQltYXNrT2Zmc2V0ICs9IG1hc2tCcGw7CiAJCX0KIAl9IGVsc2UgewogCQl0aGlzLnR5cGUgPSBTV1QuQklUTUFQOwotCQl0aGlzLm1hc2sgPSAwOwotCQl0aGlzLmFscGhhID0gaW1hZ2UuYWxwaGE7Ci0JCWlmIChpbWFnZS5hbHBoYSA9PSAtMSAmJiBpbWFnZS5hbHBoYURhdGEgIT0gbnVsbCkgeworCQlpZiAoaW1hZ2UuYWxwaGEgIT0gLTEpIHsKKwkJCXRoaXMuYWxwaGEgPSBpbWFnZS5hbHBoYTsKKwkJCWJ5dGUgYSA9IChieXRlKXRoaXMuYWxwaGE7CisJCQlmb3IgKGludCBkYXRhSW5kZXg9MDsgZGF0YUluZGV4PGJ1ZmZlci5sZW5ndGg7IGRhdGFJbmRleCs9NCkgeworCQkJCWJ1ZmZlcltkYXRhSW5kZXhdID0gYTsJCQkJCisJCQl9CisJCX0gZWxzZSBpZiAoaW1hZ2UuYWxwaGFEYXRhICE9IG51bGwpIHsKIAkJCXRoaXMuYWxwaGFEYXRhID0gbmV3IGJ5dGVbaW1hZ2UuYWxwaGFEYXRhLmxlbmd0aF07CiAJCQlTeXN0ZW0uYXJyYXljb3B5KGltYWdlLmFscGhhRGF0YSwgMCwgdGhpcy5hbHBoYURhdGEsIDAsIGFscGhhRGF0YS5sZW5ndGgpOworCQkJaW50IG9mZnNldCA9IDAsIGFscGhhT2Zmc2V0ID0gMDsKKwkJCWZvciAoaW50IHkgPSAwOyB5PGhlaWdodDsgeSsrKSB7CisJCQkJZm9yIChpbnQgeCA9IDA7IHg8d2lkdGg7IHgrKykgeworCQkJCQlidWZmZXJbb2Zmc2V0XSA9IGFscGhhRGF0YVthbHBoYU9mZnNldF07CisJCQkJCW9mZnNldCArPSA0OworCQkJCQlhbHBoYU9mZnNldCArPSAxOworCQkJCX0KKwkJCX0KIAkJfQogCX0KLQl0aGlzLnBpeG1hcCA9IHBpeG1hcDsKKwkKKwlPUy5tZW1jcHkoZGF0YSwgYnVmZmVyLCBkYXRhU2l6ZSk7CiB9CisKIC8qKgkgCiAgKiBJbnZva2VzIHBsYXRmb3JtIHNwZWNpZmljIGZ1bmN0aW9uYWxpdHkgdG8gYWxsb2NhdGUgYSBuZXcgR0MgaGFuZGxlLgogICogPHA+CkBAIC0xMDAwLDIzICs3OTIsMjkgQEAKICAqIEBwcml2YXRlCiAgKi8KIHB1YmxpYyBpbnQgaW50ZXJuYWxfbmV3X0dDIChHQ0RhdGEgZGF0YSkgewotCWlmIChwaXhtYXAgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKKwlpZiAoaGFuZGxlID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7CiAJaWYgKHR5cGUgIT0gU1dULkJJVE1BUCB8fCBtZW1HQyAhPSBudWxsKSB7CiAJCVNXVC5lcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CiAJfQotCWludFtdIG9mZnNjcmVlbkdXb3JsZCA9IG5ldyBpbnRbMV07Ci0JT1MuTmV3R1dvcmxkRnJvbVB0cihvZmZzY3JlZW5HV29ybGQsIHBpeG1hcCk7Ci0JaW50IHhHQyA9IG9mZnNjcmVlbkdXb3JsZFswXTsKLQlpZiAoeEdDID09IDApIFNXVC5lcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCWludCB3aWR0aCA9IE9TLkNHSW1hZ2VHZXRXaWR0aChoYW5kbGUpOworCWludCBoZWlnaHQgPSBPUy5DR0ltYWdlR2V0SGVpZ2h0KGhhbmRsZSk7CisJaW50IGJwYyA9IE9TLkNHSW1hZ2VHZXRCaXRzUGVyQ29tcG9uZW50KGhhbmRsZSk7CisJaW50IGJwciA9IE9TLkNHSW1hZ2VHZXRCeXRlc1BlclJvdyhoYW5kbGUpOworCWludCBjb2xvcnNwYWNlID0gT1MuQ0dJbWFnZUdldENvbG9yU3BhY2UoaGFuZGxlKTsKKwlpbnQgY29udGV4dCA9IE9TLkNHQml0bWFwQ29udGV4dENyZWF0ZSh0aGlzLmRhdGEsIHdpZHRoLCBoZWlnaHQsIGJwYywgYnByLCBjb2xvcnNwYWNlLCBPUy5rQ0dJbWFnZUFscGhhTm9uZVNraXBGaXJzdCk7CisJaWYgKGNvbnRleHQgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwlPUy5DR0NvbnRleHRTY2FsZUNUTShjb250ZXh0LCAxLCAtMSk7CisJT1MuQ0dDb250ZXh0VHJhbnNsYXRlQ1RNKGNvbnRleHQsIDAsIC1oZWlnaHQpOwogCWlmIChkYXRhICE9IG51bGwpIHsKIAkJZGF0YS5kZXZpY2UgPSBkZXZpY2U7Ci0JCWRhdGEuaW1hZ2UgPSB0aGlzOworCQlkYXRhLmJhY2tncm91bmQgPSBkZXZpY2UuQ09MT1JfV0hJVEUuaGFuZGxlOworCQlkYXRhLmZvcmVncm91bmQgPSBkZXZpY2UuQ09MT1JfQkxBQ0suaGFuZGxlOwogCQlkYXRhLmZvbnQgPSBkZXZpY2Uuc3lzdGVtRm9udDsKLQkJZGF0YS5mb3JlZ3JvdW5kID0gMHgwMDAwMDAwMDsJLy8gYmxhY2sKLQkJZGF0YS5iYWNrZ3JvdW5kID0gMHgwMGZmZmZmZjsJLy8gd2hpdGUKKwkJZGF0YS5pbWFnZSA9IHRoaXM7CiAJfQotCXJldHVybiB4R0M7CisJcmV0dXJuIGNvbnRleHQ7CiB9CisKIC8qKgkgCiAgKiBJbnZva2VzIHBsYXRmb3JtIHNwZWNpZmljIGZ1bmN0aW9uYWxpdHkgdG8gZGlzcG9zZSBhIEdDIGhhbmRsZS4KICAqIDxwPgpAQCAtMTAzMiwxMCArODMwLDEwIEBACiAgKgogICogQHByaXZhdGUKICAqLwotcHVibGljIHZvaWQgaW50ZXJuYWxfZGlzcG9zZV9HQyAoaW50IGdjLCBHQ0RhdGEgZGF0YSkgewotCWlmIChnYyAhPSAwKQotCQlPUy5EaXNwb3NlR1dvcmxkKGdjKTsKK3B1YmxpYyB2b2lkIGludGVybmFsX2Rpc3Bvc2VfR0MgKGludCBjb250ZXh0LCBHQ0RhdGEgZGF0YSkgeworCU9TLkNHQ29udGV4dFJlbGVhc2UoY29udGV4dCk7CiB9CisKIC8qKgogICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgaW1hZ2UgaGFzIGJlZW4gZGlzcG9zZWQsCiAgKiBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KQEAgLTEwNDcsMTM0ICs4NDUsOSBAQAogICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHRoZSBpbWFnZSBpcyBkaXNwb3NlZCBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZQogICovCiBwdWJsaWMgYm9vbGVhbiBpc0Rpc3Bvc2VkKCkgewotCXJldHVybiBwaXhtYXAgPT0gMDsKKwlyZXR1cm4gaGFuZGxlID09IDA7CiB9Ci0vKioKLSAqIFB1dCBhIGRldmljZS1pbmRlcGVuZGVudCBpbWFnZSBvZiBhbnkgZGVwdGggaW50byBhIGRyYXdhYmxlIG9mIGFueSBkZXB0aCwKLSAqLwotc3RhdGljIGludCBwdXRJbWFnZShJbWFnZURhdGEgaW1hZ2UsIGludFtdIHRyYW5zcGFyZW50UGl4ZWwsIGludCBkcmF3YWJsZSkgewotCQotCWludCBzcmNYPSAwLCBzcmNZPSAwOwotCWludCBzcmNXaWR0aD0gaW1hZ2Uud2lkdGgsIHNyY0hlaWdodD0gaW1hZ2UuaGVpZ2h0OwotCWludCBkZXN0WD0gc3JjWCwgZGVzdFk9IHNyY1ksIGRlc3RXaWR0aD0gc3JjV2lkdGgsIGRlc3RIZWlnaHQ9IHNyY0hlaWdodDsKLQkJCQotCVBhbGV0dGVEYXRhIHBhbGV0dGUgPSBpbWFnZS5wYWxldHRlOwotCWlmICghKCgoaW1hZ2UuZGVwdGggPT0gMSB8fCBpbWFnZS5kZXB0aCA9PSAyIHx8IGltYWdlLmRlcHRoID09IDQgfHwgaW1hZ2UuZGVwdGggPT0gOCkgJiYgIXBhbGV0dGUuaXNEaXJlY3QpIHx8Ci0JCSgoaW1hZ2UuZGVwdGggPT0gOCkgfHwgKGltYWdlLmRlcHRoID09IDE2IHx8IGltYWdlLmRlcHRoID09IDI0IHx8IGltYWdlLmRlcHRoID09IDMyKSAmJiBwYWxldHRlLmlzRGlyZWN0KSkpCi0JCQlyZXR1cm4gU1dULkVSUk9SX1VOU1VQUE9SVEVEX0RFUFRIOwotCQkJCi0JYm9vbGVhbiBmbGlwWCA9IGRlc3RXaWR0aCA8IDA7Ci0JYm9vbGVhbiBmbGlwWSA9IGRlc3RIZWlnaHQgPCAwOwotCWlmIChmbGlwWCkgewotCQlkZXN0V2lkdGggPSAtZGVzdFdpZHRoOwotCQlkZXN0WCA9IGRlc3RYIC0gZGVzdFdpZHRoOwotCX0KLQlpZiAoZmxpcFkpIHsKLQkJZGVzdEhlaWdodCA9IC1kZXN0SGVpZ2h0OwotCQlkZXN0WSA9IGRlc3RZIC0gZGVzdEhlaWdodDsKLQl9Ci0JCi0JYnl0ZVtdIHNyY1JlZHMgPSBudWxsLCBzcmNHcmVlbnMgPSBudWxsLCBzcmNCbHVlcyA9IG51bGw7Ci0JaWYgKCFwYWxldHRlLmlzRGlyZWN0KSB7Ci0JCVJHQltdIHJnYnMgPSBwYWxldHRlLmdldFJHQnMoKTsKLQkJaW50IGxlbmd0aCA9IHJnYnMubGVuZ3RoOwotCQlzcmNSZWRzID0gbmV3IGJ5dGVbbGVuZ3RoXTsKLQkJc3JjR3JlZW5zID0gbmV3IGJ5dGVbbGVuZ3RoXTsKLQkJc3JjQmx1ZXMgPSBuZXcgYnl0ZVtsZW5ndGhdOwotCQlmb3IgKGludCBpID0gMDsgaSA8IHJnYnMubGVuZ3RoOyBpKyspIHsKLQkJCVJHQiByZ2IgPSByZ2JzW2ldOwotCQkJaWYgKHJnYiA9PSBudWxsKSBjb250aW51ZTsKLQkJCXNyY1JlZHNbaV0gPSAoYnl0ZSlyZ2IucmVkOwotCQkJc3JjR3JlZW5zW2ldID0gKGJ5dGUpcmdiLmdyZWVuOwotCQkJc3JjQmx1ZXNbaV0gPSAoYnl0ZSlyZ2IuYmx1ZTsKLQkJfQotCX0KLQkKLQlieXRlW10gZGVzdFJlZHMgPSBudWxsLCBkZXN0R3JlZW5zID0gbnVsbCwgZGVzdEJsdWVzID0gbnVsbDsKLQlpbnQgZGVzdFJlZE1hc2sgPSAwLCBkZXN0R3JlZW5NYXNrID0gMCwgZGVzdEJsdWVNYXNrID0gMDsKLQlmaW5hbCBib29sZWFuIHNjcmVlbkRpcmVjdDsKLQlpbnQgZGVzdERlcHRoPSBPUy5HZXRQaXhEZXB0aChkcmF3YWJsZSk7Ci0JaWYgKGRlc3REZXB0aCA8PSA4KSB7Ci0JCWRlc3RSZWRzID0gbmV3IGJ5dGVbc3JjUmVkcy5sZW5ndGhdOwotCQlkZXN0R3JlZW5zID0gbmV3IGJ5dGVbc3JjR3JlZW5zLmxlbmd0aF07Ci0JCWRlc3RCbHVlcyA9IG5ldyBieXRlW3NyY0JsdWVzLmxlbmd0aF07Ci0JCWZvciAoaW50IGkgPSAwOyBpIDwgc3JjUmVkcy5sZW5ndGg7IGkrKykgewotCQkJZGVzdFJlZHNbaV0gPSBzcmNSZWRzW2ldOwotCQkJZGVzdEdyZWVuc1tpXSA9IHNyY0dyZWVuc1tpXTsKLQkJCWRlc3RCbHVlc1tpXSA9IHNyY0JsdWVzW2ldOwotCQl9Ci0JCXNldENvbG9yVGFibGUoZHJhd2FibGUsIGRlc3RSZWRzLCBkZXN0R3JlZW5zLCBkZXN0Qmx1ZXMpOwotCQlzY3JlZW5EaXJlY3QgPSBmYWxzZTsKLQl9IGVsc2UgewotCQlkZXN0UmVkTWFzayA9IGdldFJlZE1hc2soZGVzdERlcHRoKTsKLQkJZGVzdEdyZWVuTWFzayA9IGdldEdyZWVuTWFzayhkZXN0RGVwdGgpOwotCQlkZXN0Qmx1ZU1hc2sgPSBnZXRCbHVlTWFzayhkZXN0RGVwdGgpOwotCQlzY3JlZW5EaXJlY3QgPSB0cnVlOwotCX0KLQlpZiAodHJhbnNwYXJlbnRQaXhlbCAhPSBudWxsKSB7Ci0JCWludCB0cmFuc1JlZCA9IDAsIHRyYW5zR3JlZW4gPSAwLCB0cmFuc0JsdWUgPSAwOwotCQlpZiAocGFsZXR0ZS5pc0RpcmVjdCkgewotCQkJUkdCIHJnYiA9IHBhbGV0dGUuZ2V0UkdCKHRyYW5zcGFyZW50UGl4ZWxbMF0pOwotCQkJdHJhbnNSZWQgPSByZ2IucmVkOwotCQkJdHJhbnNHcmVlbiA9IHJnYi5ncmVlbjsKLQkJCXRyYW5zQmx1ZSA9IHJnYi5ibHVlOwotCQl9IGVsc2UgewotCQkJUkdCW10gcmdicyA9IHBhbGV0dGUuZ2V0UkdCcygpOwotCQkJaWYgKHRyYW5zcGFyZW50UGl4ZWxbMF0gPCByZ2JzLmxlbmd0aCkgewotCQkJCVJHQiByZ2IgPSByZ2JzW3RyYW5zcGFyZW50UGl4ZWxbMF1dOwotCQkJCXRyYW5zUmVkID0gcmdiLnJlZDsKLQkJCQl0cmFuc0dyZWVuID0gcmdiLmdyZWVuOwotCQkJCXRyYW5zQmx1ZSA9IHJnYi5ibHVlOwotCQkJfQotCQl9Ci0JCXRyYW5zcGFyZW50UGl4ZWxbMF0gPSBJbWFnZURhdGEuY2xvc2VzdE1hdGNoKGRlc3REZXB0aCwgKGJ5dGUpdHJhbnNSZWQsIChieXRlKXRyYW5zR3JlZW4sIChieXRlKXRyYW5zQmx1ZSwKLQkJCWRlc3RSZWRNYXNrLCBkZXN0R3JlZW5NYXNrLCBkZXN0Qmx1ZU1hc2ssIGRlc3RSZWRzLCBkZXN0R3JlZW5zLCBkZXN0Qmx1ZXMpOwotCX0KLQkKLQlpbnQgZGVzdEJpdHNQZXJQaXhlbD0gZGVzdERlcHRoOwotCQotCWludCBkZXN0X3JlZF9tYXNrPSBnZXRSZWRNYXNrKGRlc3RCaXRzUGVyUGl4ZWwpOwotCWludCBkZXN0X2dyZWVuX21hc2s9IGdldEdyZWVuTWFzayhkZXN0Qml0c1BlclBpeGVsKTsKLQlpbnQgZGVzdF9ibHVlX21hc2s9IGdldEJsdWVNYXNrKGRlc3RCaXRzUGVyUGl4ZWwpOwotCQotCWludCBkZXN0Um93Qnl0ZXM9IHJvd0J5dGVzKGRlc3RXaWR0aCwgZGVzdERlcHRoKTsKLQlpbnQgYnVmU2l6ZSA9IGRlc3RSb3dCeXRlcyAqIGRlc3RIZWlnaHQ7Ci0JYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlW2J1ZlNpemVdOwogCi0JaW50IHNyY09yZGVyID0gaW1hZ2UuZ2V0Qnl0ZU9yZGVyKCk7Ci0JCi0JaWYgKHBhbGV0dGUuaXNEaXJlY3QpIHsKLQkJaWYgKHNjcmVlbkRpcmVjdCkgewotCQkJSW1hZ2VEYXRhLmJsaXQoSW1hZ2VEYXRhLkJMSVRfU1JDLAotCQkJCWltYWdlLmRhdGEsIGltYWdlLmRlcHRoLCBpbWFnZS5ieXRlc1BlckxpbmUsIHNyY09yZGVyLCBzcmNYLCBzcmNZLCBzcmNXaWR0aCwgc3JjSGVpZ2h0LCBwYWxldHRlLnJlZE1hc2ssIHBhbGV0dGUuZ3JlZW5NYXNrLCBwYWxldHRlLmJsdWVNYXNrLAotCQkJCUltYWdlRGF0YS5BTFBIQV9PUEFRVUUsIG51bGwsIDAsIHNyY1gsIHNyY1ksIAotCQkJCWJ1ZiwgZGVzdEJpdHNQZXJQaXhlbCwgZGVzdFJvd0J5dGVzLCBJbWFnZURhdGEuTVNCX0ZJUlNULCAwLCAwLCBkZXN0V2lkdGgsIGRlc3RIZWlnaHQsIGRlc3RfcmVkX21hc2ssIGRlc3RfZ3JlZW5fbWFzaywgZGVzdF9ibHVlX21hc2ssCi0JCQkJZmxpcFgsIGZsaXBZKTsKLQkJfSBlbHNlIHsKLQkJCUltYWdlRGF0YS5ibGl0KEltYWdlRGF0YS5CTElUX1NSQywKLQkJCQlpbWFnZS5kYXRhLCBpbWFnZS5kZXB0aCwgaW1hZ2UuYnl0ZXNQZXJMaW5lLCBzcmNPcmRlciwgc3JjWCwgc3JjWSwgc3JjV2lkdGgsIHNyY0hlaWdodCwgcGFsZXR0ZS5yZWRNYXNrLCBwYWxldHRlLmdyZWVuTWFzaywgcGFsZXR0ZS5ibHVlTWFzaywKLQkJCQlJbWFnZURhdGEuQUxQSEFfT1BBUVVFLCBudWxsLCAwLCBzcmNYLCBzcmNZLAotCQkJCWJ1ZiwgZGVzdEJpdHNQZXJQaXhlbCwgZGVzdFJvd0J5dGVzLCBJbWFnZURhdGEuTVNCX0ZJUlNULCAwLCAwLCBkZXN0V2lkdGgsIGRlc3RIZWlnaHQsIGRlc3RSZWRzLCBkZXN0R3JlZW5zLCBkZXN0Qmx1ZXMsCi0JCQkJZmxpcFgsIGZsaXBZKTsKLQkJfQotCX0gZWxzZSB7Ci0JCWlmIChzY3JlZW5EaXJlY3QpIHsKLQkJCUltYWdlRGF0YS5ibGl0KEltYWdlRGF0YS5CTElUX1NSQywKLQkJCQlpbWFnZS5kYXRhLCBpbWFnZS5kZXB0aCwgaW1hZ2UuYnl0ZXNQZXJMaW5lLCBzcmNPcmRlciwgc3JjWCwgc3JjWSwgc3JjV2lkdGgsIHNyY0hlaWdodCwgc3JjUmVkcywgc3JjR3JlZW5zLCBzcmNCbHVlcywKLQkJCQlJbWFnZURhdGEuQUxQSEFfT1BBUVVFLCBudWxsLCAwLCBzcmNYLCBzcmNZLAotCQkJCWJ1ZiwgZGVzdEJpdHNQZXJQaXhlbCwgZGVzdFJvd0J5dGVzLCBJbWFnZURhdGEuTVNCX0ZJUlNULCAwLCAwLCBkZXN0V2lkdGgsIGRlc3RIZWlnaHQsIGRlc3RfcmVkX21hc2ssIGRlc3RfZ3JlZW5fbWFzaywgZGVzdF9ibHVlX21hc2ssCi0JCQkJZmxpcFgsIGZsaXBZKTsKLQkJfSBlbHNlIHsKLQkJCUltYWdlRGF0YS5ibGl0KEltYWdlRGF0YS5CTElUX1NSQywKLQkJCQlpbWFnZS5kYXRhLCBpbWFnZS5kZXB0aCwgaW1hZ2UuYnl0ZXNQZXJMaW5lLCBzcmNPcmRlciwgc3JjWCwgc3JjWSwgc3JjV2lkdGgsIHNyY0hlaWdodCwgc3JjUmVkcywgc3JjR3JlZW5zLCBzcmNCbHVlcywKLQkJCQlJbWFnZURhdGEuQUxQSEFfT1BBUVVFLCBudWxsLCAwLCBzcmNYLCBzcmNZLAotCQkJCWJ1ZiwgZGVzdEJpdHNQZXJQaXhlbCwgZGVzdFJvd0J5dGVzLCBJbWFnZURhdGEuTVNCX0ZJUlNULCAwLCAwLCBkZXN0V2lkdGgsIGRlc3RIZWlnaHQsIGRlc3RSZWRzLCBkZXN0R3JlZW5zLCBkZXN0Qmx1ZXMsCi0JCQkJZmxpcFgsIGZsaXBZKTsKLQkJfQotCX0KLQlzZXRQaXhNYXBEYXRhKGRyYXdhYmxlLCBidWYpOwotCXJldHVybiAwOwotfQogLyoqCiAgKiBTZXRzIHRoZSBjb2xvciB0byB3aGljaCB0byBtYXAgdGhlIHRyYW5zcGFyZW50IHBpeGVsLgogICogPHA+CkBAIC0xMjE0LDI5ICs4ODcsOSBAQAogCWlmIChjb2xvciA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWlmIChjb2xvci5pc0Rpc3Bvc2VkKCkpIFNXVC5lcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CiAJaWYgKHRyYW5zcGFyZW50UGl4ZWwgPT0gLTEpIHJldHVybjsKLQkvKiBHZW5lcmF0ZSB0aGUgbWFzayBpZiBuZWNlc3NhcnkuICovCi0JaWYgKG1hc2sgPT0gMCkgY3JlYXRlTWFzaygpOwotICAgIC8qIEFXCi0JUmVjdGFuZ2xlIGJvdW5kcyA9IGdldEJvdW5kcygpOwotCWludFtdIHVudXNlZCA9IG5ldyBpbnRbMV07Ci0JaW50W10gZGVwdGggPSBuZXcgaW50WzFdOwotCWludCB4RGlzcGxheSA9IGRldmljZS54RGlzcGxheTsKLSAJT1MuWEdldEdlb21ldHJ5KHhEaXNwbGF5LCBwaXhtYXAsIHVudXNlZCwgdW51c2VkLCB1bnVzZWQsIHVudXNlZCwgdW51c2VkLCB1bnVzZWQsIGRlcHRoKTsKLQlpbnQgZHJhd2FibGUgPSBPUy5YRGVmYXVsdFJvb3RXaW5kb3coeERpc3BsYXkpOwotCWludCB0ZW1wUGl4bWFwID0gT1MuWENyZWF0ZVBpeG1hcCh4RGlzcGxheSwgZHJhd2FibGUsIGJvdW5kcy53aWR0aCwgYm91bmRzLmhlaWdodCwgZGVwdGhbMF0pOwotCWludCB4R0MgPSBPUy5YQ3JlYXRlR0MoeERpc3BsYXksIHRlbXBQaXhtYXAsIDAsIG51bGwpOwotCU9TLlhTZXRGb3JlZ3JvdW5kKHhEaXNwbGF5LCB4R0MsIGNvbG9yLmhhbmRsZS5waXhlbCk7Ci0JT1MuWEZpbGxSZWN0YW5nbGUoeERpc3BsYXksIHRlbXBQaXhtYXAsIHhHQywgMCwgMCwgYm91bmRzLndpZHRoLCBib3VuZHMuaGVpZ2h0KTsKLQlPUy5YU2V0Q2xpcE1hc2soeERpc3BsYXksIHhHQywgbWFzayk7Ci0JT1MuWENvcHlBcmVhKHhEaXNwbGF5LCBwaXhtYXAsIHRlbXBQaXhtYXAsIHhHQywgMCwgMCwgYm91bmRzLndpZHRoLCBib3VuZHMuaGVpZ2h0LCAwLCAwKTsKLQlPUy5YU2V0Q2xpcE1hc2soeERpc3BsYXksIHhHQywgT1MuTm9uZSk7Ci0JT1MuWENvcHlBcmVhKHhEaXNwbGF5LCB0ZW1wUGl4bWFwLCBwaXhtYXAsIHhHQywgMCwgMCwgYm91bmRzLndpZHRoLCBib3VuZHMuaGVpZ2h0LCAwLCAwKTsKLQlPUy5YRnJlZVBpeG1hcCh4RGlzcGxheSwgdGVtcFBpeG1hcCk7Ci0JT1MuWEZyZWVHQyh4RGlzcGxheSwgeEdDKTsKLSAgICAqLwotCS8qIERlc3Ryb3kgdGhlIHJlY2VpdmVyJ3MgbWFzayBpZiB0aGUgdGhlcmUgaXMgYSBHQyBjcmVhdGVkIG9uIGl0ICovCi0JaWYgKG1lbUdDICE9IG51bGwpIGRlc3Ryb3lNYXNrKCk7CisJLy9OT1QgRE9ORQogfQorCiAvKioKICAqIFJldHVybnMgYSBzdHJpbmcgY29udGFpbmluZyBhIGNvbmNpc2UsIGh1bWFuLXJlYWRhYmxlCiAgKiBkZXNjcmlwdGlvbiBvZiB0aGUgcmVjZWl2ZXIuCkBAIC0xMjQ1LDM2MCArODk4LDcgQEAKICAqLwogcHVibGljIFN0cmluZyB0b1N0cmluZyAoKSB7CiAJaWYgKGlzRGlzcG9zZWQoKSkgcmV0dXJuICJJbWFnZSB7KkRJU1BPU0VEKn0iOwotCXJldHVybiAiSW1hZ2UgeyIgKyBwaXhtYXAgKyAifSI7CisJcmV0dXJuICJJbWFnZSB7IiArIGhhbmRsZSArICJ9IjsKIH0KIAotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLS8vIE1hYyBzdHVmZgotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCXByaXZhdGUgc3RhdGljIGludCByb3dCeXRlcyhpbnQgd2lkdGgsIGludCBkZXB0aCkgewotCQlpZiAoZGVwdGggPT0gMjQpCi0JCQlkZXB0aD0gMzI7Ci0JCXJldHVybiAoKCh3aWR0aCpkZXB0aC0xKS8oOCpERUZBVUxUX1NDQU5MSU5FX1BBRCkpKzEpKkRFRkFVTFRfU0NBTkxJTkVfUEFEOwotCX0KLQotCXByaXZhdGUgc3RhdGljIGludCBjcmVhdGVCaXRNYXAoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7Ci0JCWludCByb3dCeXRlcz0gcm93Qnl0ZXMod2lkdGgsIDEpOwotCQlpZiAocm93Qnl0ZXMgPiAweDNmZmYpIHsKLQkJCVN5c3RlbS5vdXQucHJpbnRsbigiSW1hZ2UuY3JlYXRlQml0TWFwOiByb3dCeXRlcyA+PSAweDQwMDAiKTsKLQkJCXJldHVybiAwOwotCQl9Ci0JCWludCBiaXRtYXA9IG5ld0JpdE1hcCh3aWR0aCwgaGVpZ2h0LCByb3dCeXRlcyk7Ci0JCWlmIChiaXRtYXAgPT0gMCkKLQkJCVNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JCQkKLQkJaW5pdFBpeE1hcERhdGEoYml0bWFwLCByb3dCeXRlcyAqIGhlaWdodCwgMCk7Ci0JCQotCQlyZXR1cm4gYml0bWFwOwotCX0KLQkKLQlwcml2YXRlIHN0YXRpYyBpbnQgY3JlYXRlUGl4TWFwKGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGRlcHRoKSB7Ci0JCWludCByb3dCeXRlcz0gcm93Qnl0ZXMod2lkdGgsIGRlcHRoKTsKLQkJaWYgKHJvd0J5dGVzID4gMHgzZmZmKSB7Ci0JCQlTeXN0ZW0ub3V0LnByaW50bG4oIkltYWdlLmNyZWF0ZVBpeE1hcDogcm93Qnl0ZXMgPj0gMHg0MDAwIik7Ci0JCQlyZXR1cm4gMDsKLQkJfQotCQlpbnQgcGl4bWFwPSBOZXdQaXhNYXAod2lkdGgsIGhlaWdodCwgZGVwdGgsIHJvd0J5dGVzKTsKLQkJaWYgKHBpeG1hcCA9PSAwKQotCQkJU1dULmVycm9yKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKLQkJCQotCQlpbml0UGl4TWFwRGF0YShwaXhtYXAsIHJvd0J5dGVzICogaGVpZ2h0LCAwKTsKLQotCQlyZXR1cm4gcGl4bWFwOwotCX0KLQkKLQlwcml2YXRlIHN0YXRpYyBpbnQgTmV3UGl4TWFwKGludCB3LCBpbnQgaCwgaW50IGRlcHRoLCBpbnQgcm93Qnl0ZXMpIHsKLQkJCi0JCWludCBwaXhlbFR5cGU9IDAsIHBpeGVsU2l6ZT0gMCwgY21wU2l6ZT0gMCwgY21wQ291bnQ9IDAsIHBpeGVsRm9ybWF0PSAwOwotCQkKLQkJaWYgKGRlcHRoID09IDI0KQotCQkJZGVwdGg9IDMyOwotCQkKLQkJcGl4ZWxGb3JtYXQ9IGRlcHRoOwotCQlwaXhlbFNpemU9IGRlcHRoOwotCQkKLQkJc3dpdGNoIChkZXB0aCkgewotCQljYXNlIDE6Ci0JCWNhc2UgMjoKLQkJY2FzZSA0OgotCQljYXNlIDg6Ci0JCQlwaXhlbFR5cGU9IE9TLkluZGV4ZWQ7Ci0JCQljbXBTaXplPSBkZXB0aDsKLQkJCWNtcENvdW50PSAxOwotCQkJYnJlYWs7Ci0JCQotCQljYXNlIDE2OgotCQkJcGl4ZWxUeXBlPSBPUy5SR0JEaXJlY3Q7Ci0JCQljbXBTaXplPSA1OwotCQkJY21wQ291bnQ9IDM7Ci0JCQlicmVhazsKLQkJCQkJCQotCQljYXNlIDMyOgotCQkJcGl4ZWxUeXBlPSBPUy5SR0JEaXJlY3Q7Ci0JCQljbXBTaXplPSA4OwotCQkJY21wQ291bnQ9IDM7Ci0JCQlicmVhazsKLQkJCQotCQlkZWZhdWx0OgotCQkJYnJlYWs7Ci0JCX0KLQkJCi0JCXJldHVybiBPUy5OZXdQaXhNYXAoKHNob3J0KXcsIChzaG9ydCloLCAoc2hvcnQpcm93Qnl0ZXMsCi0JCQkJKHNob3J0KXBpeGVsVHlwZSwgKHNob3J0KXBpeGVsU2l6ZSwKLQkJCQkoc2hvcnQpY21wU2l6ZSwgKHNob3J0KWNtcENvdW50LCAoc2hvcnQpcGl4ZWxGb3JtYXQpOwotCX0KLQkKLQlwdWJsaWMgc3RhdGljIHZvaWQgZGlzcG9zZUJpdG1hcE9yUGl4bWFwKGludCBoYW5kbGUpIHsKLQotCQlpZiAoaGFuZGxlID09IDApCi0JCQlyZXR1cm47Ci0JCWlmICgoT1MuZ2V0Um93Qnl0ZXMoaGFuZGxlKSAmIDB4ODAwMCkgIT0gMCkgewkvLyBQaXhtYXAKLQkJCU9TLkRpc3Bvc2VQaXhNYXAoaGFuZGxlKTsKLQkJCXJldHVybjsKLQkJfQotCQkKLQkJaW50IGJhc2VBZGRyPSBPUy5nZXRCYXNlQWRkcihoYW5kbGUpOwotCQlpZiAoYmFzZUFkZHIgIT0gMCkgewotCQkJT1MuRGlzcG9zZVB0cihiYXNlQWRkcik7Ci0JCQlPUy5zZXRCYXNlQWRkcihoYW5kbGUsIDApOwotCQl9Ci0JCQotCQlPUy5EaXNwb3NlSGFuZGxlKGhhbmRsZSk7Ci0JfQotCQotCS8vcHJpdmF0ZSBzdGF0aWMgaW50IGZnSWNvbkNvdW50OwotCQotCXB1YmxpYyBzdGF0aWMgaW50IGNhcmJvbl9jcmVhdGVDSWNvbihJbWFnZSBpbWFnZSkgewotCQkKLQkJaWYgKGltYWdlID09IG51bGwpCi0JCQlyZXR1cm4gMDsKLQkJCi0JCVJlY3RhbmdsZSByPSBpbWFnZS5nZXRCb3VuZHMoKTsKLQkJc2hvcnQgdz0gKHNob3J0KXIud2lkdGg7Ci0JCXNob3J0IGg9IChzaG9ydClyLmhlaWdodDsKLQotCi0JCWludCBtYXNrPSBpbWFnZS5tYXNrOwotCQlpZiAobWFzayA9PSAwKSB7Ci0JCQkvL1N5c3RlbS5vdXQucHJpbnRsbigiLS0tPiBDSWNvbjogY3JlYXRpbmcgZHVtbXkgbWFzayIpOwotCQkJaW50IHJvd0J5dGVzPSByb3dCeXRlcyh3LCAxKTsKLQkJCW1hc2s9IG5ld0JpdE1hcCh3LCBoLCByb3dCeXRlcyk7Ci0JCQlpbml0UGl4TWFwRGF0YShtYXNrLCByb3dCeXRlcypoLCAweGZmKTsKLQkJfQotCQkKLQkJaW50IHBtPSBpbWFnZS5waXhtYXA7Ci0JCWlmIChwbSAhPSAwICYmIGdldERlcHRoKHBtKSA+IDgpIHsKLQkJCQotCQkJSW1hZ2VEYXRhIGlkPSBpbWFnZS5nZXRJbWFnZURhdGEoKTsKLQkJCQkJCQkJCQotCQkJaW50IGRlcHRoPSA4OwotCQkJaW50IGJ5dGVzUGVyUm93PSByb3dCeXRlcyh3LCBkZXB0aCk7Ci0JCQlieXRlW10gZGF0YT0gbmV3IGJ5dGVbYnl0ZXNQZXJSb3cqaF07Ci0JCQotCQkJYnl0ZVtdIHJlZHM9IG5ldyBieXRlWzI1Nl07Ci0JCQlieXRlW10gZ3JlZW5zPSBuZXcgYnl0ZVsyNTZdOwotCQkJYnl0ZVtdIGJsdWVzPSBuZXcgYnl0ZVsyNTZdOwotCQkJCi0JCQlpbnRbXSB2YWx1ZXM9IG5ldyBpbnRbMjU2XTsKLQkJCWludCBpLCBmaWxsPSAwOwotCQkJCi0JCQlib29sZWFuIGQxNj0gaWQuZGVwdGggPT0gMTY7Ci0JCQkKLQkJCWZvciAoaW50IHk9IDA7IHkgPCBoOyB5KyspIHsKLQkJCQlmb3IgKGludCB4PSAwOyB4IDwgdzsgeCsrKSB7Ci0JCQkJCWludCBpbmRleD0gLTE7Ci0JCQkJCWludCB2YWx1ZT0gaWQuZ2V0UGl4ZWwoeCwgeSk7Ci0JCQkJCWZvciAoaT0gMDsgaSA8IGZpbGw7IGkrKykgewotCQkJCQkJaWYgKHZhbHVlID09IHZhbHVlc1tpXSkgewotCQkJCQkJCWluZGV4PSBpOwotCQkJCQkJCWJyZWFrOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJCWlmIChpID49IGZpbGwpIHsKLQkJCQkJCWluZGV4PSBmaWxsKys7Ci0JCQkJCQl2YWx1ZXNbaW5kZXhdPSB2YWx1ZTsKLQkJCQkJCWlmICghZDE2KSB7Ci0JCQkJCQkJcmVkc1tpbmRleF09IChieXRlKSgodmFsdWUgPj4gMTYpICYgMHhGRik7Ci0JCQkJCQkJZ3JlZW5zW2luZGV4XT0gKGJ5dGUpKCh2YWx1ZSA+PiA4KSAmIDB4RkYpOyAKLQkJCQkJCQlibHVlc1tpbmRleF09IChieXRlKSgodmFsdWUpICYgMHhGRik7Ci0JCQkJCQl9IGVsc2UgewotCQkJCQkJCXJlZHNbaW5kZXhdPSAoYnl0ZSkoKCh2YWx1ZSA+PiAxMCkgJiAweDFGKSA8PCAzKTsKLQkJCQkJCQlncmVlbnNbaW5kZXhdPSAoYnl0ZSkoKCh2YWx1ZSA+PiA1KSAmIDB4MUYpIDw8IDMpOyAKLQkJCQkJCQlibHVlc1tpbmRleF09IChieXRlKSgoKHZhbHVlKSAmIDB4MUYpIDw8IDMpOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJCWlmIChpbmRleCA+PSAwKQotCQkJCQkJZGF0YVt5KmJ5dGVzUGVyUm93K3hdPSAoYnl0ZSlpbmRleDsKLQkJCQl9Ci0JCQl9Ci0JCQlwbT0gTmV3UGl4TWFwKHcsIGgsIGRlcHRoLCBieXRlc1BlclJvdyk7Ci0JCQlzZXRDb2xvclRhYmxlKHBtLCByZWRzLCBncmVlbnMsIGJsdWVzKTsKLQkJCXNldFBpeE1hcERhdGEocG0sIGRhdGEpOwotCQl9IGVsc2UgewotCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIi0tLT4gQ0ljb246IGNhbiB1c2UgcGl4bWFwIik7Ci0JCX0KLQkJCi0JCWludCBpY29uPSAwOwotCQlpZiAocG0gIT0gMCAmJiBtYXNrICE9IDApIHsJCQotCQkJaWNvbj0gT1MuTmV3Q0ljb24ocG0sIG1hc2spOwotCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIkNJY29uczogIiArIGZnSWNvbkNvdW50KyspOwotCQl9Ci0JCQotCQlpZiAobWFzayAhPSBpbWFnZS5tYXNrKQotCQkJZGlzcG9zZUJpdG1hcE9yUGl4bWFwKG1hc2spOwotCQlpZiAocG0gIT0gaW1hZ2UucGl4bWFwKQotCQkJZGlzcG9zZUJpdG1hcE9yUGl4bWFwKHBtKTsKLQkJCQkKLQkJcmV0dXJuIGljb247IAotCX0KLQkKLQlwdWJsaWMgc3RhdGljIHZvaWQgZGlzcG9zZUNJY29uKGludCBpY29uSGFuZGxlKSB7Ci0JCWludCBpY29uRGF0YT0gT1MuZ2V0Q0ljb25JY29uRGF0YShpY29uSGFuZGxlKTsKLQkJaWYgKGljb25EYXRhICE9IDApCi0JCQlPUy5EaXNwb3NlSGFuZGxlKGljb25EYXRhKTsKLQkJCQotCQlpbnQgY29sb3JUYWJsZT0gT1MuZ2V0Q0ljb25Db2xvclRhYmxlKGljb25IYW5kbGUpOwotCQlpZiAoY29sb3JUYWJsZSAhPSAwKQotCQkJT1MuRGlzcG9zZUhhbmRsZShjb2xvclRhYmxlKTsKLQkJCQkKLQkJT1MuRGlzcG9zZUhhbmRsZShpY29uSGFuZGxlKTsKLQkJLy9mZ0ljb25Db3VudC0tOwotCX0KLQkKLQlwcml2YXRlIHN0YXRpYyB2b2lkIHNldENvbG9yVGFibGUoaW50IHBpeG1hcEhhbmRsZSwgYnl0ZVtdIHJlZCwgYnl0ZVtdIGdyZWVuLCBieXRlW10gYmx1ZSkgewotCQlpbnQgbj0gTWF0aC5tYXgoTWF0aC5tYXgocmVkLmxlbmd0aCwgZ3JlZW4ubGVuZ3RoKSwgYmx1ZS5sZW5ndGgpOwotCQlzaG9ydFtdIGNvbG9yU3BlYz0gbmV3IHNob3J0W24qNF07Ci0JCWludCBqPSAwOwotCQlmb3IgKGludCBpPSAwOyBpIDwgbjsgaSsrKSB7Ci0JCQljb2xvclNwZWNbaisrXT0gKHNob3J0KSBpOwotCQkJY29sb3JTcGVjW2orK109IChzaG9ydCkgKHJlZFtpXSoyNTcpOwotCQkJY29sb3JTcGVjW2orK109IChzaG9ydCkgKGdyZWVuW2ldKjI1Nyk7Ci0JCQljb2xvclNwZWNbaisrXT0gKHNob3J0KSAoYmx1ZVtpXSoyNTcpOwotCQl9Ci0JCU9TLnNldENvbG9yVGFibGUocGl4bWFwSGFuZGxlLCBjb2xvclNwZWMpOwotCX0KLQkKLQlwcml2YXRlIHN0YXRpYyB2b2lkIHNldENvbG9yVGFibGUoaW50IHBpeG1hcEhhbmRsZSwgQ29sb3JbXSB0YWJsZSkgewotCQlpbnQgbj0gdGFibGUubGVuZ3RoOwotCQlzaG9ydFtdIGNvbG9yU3BlYz0gbmV3IHNob3J0W24qNF07Ci0JCWludCBqPSAwOwotCQlmb3IgKGludCBpPSAwOyBpIDwgbjsgaSsrKSB7Ci0JCQljb2xvclNwZWNbaisrXT0gKHNob3J0KSBpOwotCQkJY29sb3JTcGVjW2orK109IChzaG9ydCkgKHRhYmxlW2ldLmdldFJlZCgpICogMjU3KTsKLQkJCWNvbG9yU3BlY1tqKytdPSAoc2hvcnQpICh0YWJsZVtpXS5nZXRHcmVlbigpICogMjU3KTsKLQkJCWNvbG9yU3BlY1tqKytdPSAoc2hvcnQpICh0YWJsZVtpXS5nZXRCbHVlKCkgKiAyNTcpOwotCQl9Ci0JCU9TLnNldENvbG9yVGFibGUocGl4bWFwSGFuZGxlLCBjb2xvclNwZWMpOwotCX0KLQkKLQlwcml2YXRlIHN0YXRpYyBpbnQgZ2V0RGVwdGgoaW50IGJpdG1hcEhhbmRsZSkgewotCQlpZiAoKE9TLmdldFJvd0J5dGVzKGJpdG1hcEhhbmRsZSkgJiAweDgwMDApICE9IDApCS8vIFBpeG1hcAotCQkJcmV0dXJuIE9TLkdldFBpeERlcHRoKGJpdG1hcEhhbmRsZSk7Ci0JCXJldHVybiAxOwotCX0KLQkKLQlwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzQml0TWFwKGludCBoYW5kbGUpIHsKLQkJcmV0dXJuIChPUy5nZXRSb3dCeXRlcyhoYW5kbGUpICYgMHg4MDAwKSA9PSAwOwotCX0KLQkKLQlwcml2YXRlIHN0YXRpYyBpbnQgZHVwbGljYXRlKGludCBoYW5kbGUpIHsKLQkJaW50IHJvd0J5dGVzPSBPUy5nZXRSb3dCeXRlcyhoYW5kbGUpOwotCQlpZiAoKHJvd0J5dGVzICYgMHg4MDAwKSA9PSAwKSB7Ci0JCQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQkJCU9TLkdldFBpeEJvdW5kcyhoYW5kbGUsIGJvdW5kcy5nZXREYXRhKCkpOwotCQkJaW50IGNvcHk9IG5ld0JpdE1hcChib3VuZHMuZ2V0V2lkdGgoKSwgYm91bmRzLmdldEhlaWdodCgpLCByb3dCeXRlcyk7Ci0JCQlpbnQgYmFzZUFkZHI9IE9TLmdldEJhc2VBZGRyKGhhbmRsZSk7Ci0JCQlpZiAoYmFzZUFkZHIgIT0gMCkgewotCQkJCWludCBzaXplPSBPUy5HZXRQdHJTaXplKGJhc2VBZGRyKTsKLQkJCQlpbnQgZGF0YT0gT1MuTmV3UHRyKHNpemUpOwotCQkJCU9TLm1lbWNweShkYXRhLCBiYXNlQWRkciwgc2l6ZSk7Ci0JCQkJT1Muc2V0QmFzZUFkZHIoY29weSwgZGF0YSk7Ci0JCQl9Ci0JCQlyZXR1cm4gY29weTsKLQkJfQotCQlyZXR1cm4gT1MuZHVwbGljYXRlUGl4TWFwKGhhbmRsZSk7Ci0JfQotCQotCXByaXZhdGUgc3RhdGljIGludCBnZXRSZWRNYXNrKGludCBkZXB0aCkgewotCQlzd2l0Y2ggKGRlcHRoKSB7Ci0JCWNhc2UgMTU6Ci0JCWNhc2UgMTY6Ci0JCQlyZXR1cm4gMHg3QzAwOwotCQljYXNlIDI0OgotCQljYXNlIDMyOgotCQkJcmV0dXJuIDB4ZmYwMDAwOwotCQl9Ci0JCXJldHVybiAtMTsKLQl9Ci0JCi0JcHJpdmF0ZSBzdGF0aWMgaW50IGdldEdyZWVuTWFzayhpbnQgZGVwdGgpIHsKLQkJc3dpdGNoIChkZXB0aCkgewotCQljYXNlIDE1OgotCQljYXNlIDE2OgotCQkJcmV0dXJuIDB4MDNFMDsKLQkJY2FzZSAyNDoKLQkJY2FzZSAzMjoKLQkJCXJldHVybiAweDAwZmYwMDsKLQkJfQotCQlyZXR1cm4gLTE7Ci0JfQotCQotCXByaXZhdGUgc3RhdGljIGludCBnZXRCbHVlTWFzayhpbnQgZGVwdGgpIHsKLQkJc3dpdGNoIChkZXB0aCkgewotCQljYXNlIDE1OgotCQljYXNlIDE2OgotCQkJcmV0dXJuIDB4MDAxRjsKLQkJY2FzZSAyNDoKLQkJY2FzZSAzMjoKLQkJCXJldHVybiAweDAwMDBmZjsKLQkJfQotCQlyZXR1cm4gLTE7Ci0JfQotCQotCXByaXZhdGUgc3RhdGljIHZvaWQgc2V0UGl4TWFwRGF0YShpbnQgZGVzdFBpeE1hcCwgYnl0ZVtdIGRhdGEpIHsKLQkJaW50IGFkZHI9IE9TLmdldEJhc2VBZGRyKGRlc3RQaXhNYXApOwotCQlpZiAoYWRkciAhPSAwKSB7Ci0JCQlPUy5EaXNwb3NlUHRyKGFkZHIpOwotCQl9Ci0JCWFkZHI9IE9TLk5ld1B0cihkYXRhLmxlbmd0aCk7Ci0JCU9TLm1lbWNweShhZGRyLCBkYXRhLCBkYXRhLmxlbmd0aCk7Ci0JCU9TLnNldEJhc2VBZGRyKGRlc3RQaXhNYXAsIGFkZHIpOwotCX0KLQkKLQlwcml2YXRlIHN0YXRpYyB2b2lkIGluaXRQaXhNYXBEYXRhKGludCBkZXN0UGl4TWFwLCBpbnQgc2l6ZSwgaW50IHZhbHVlKSB7Ci0JCWludCBhZGRyPSBPUy5nZXRCYXNlQWRkcihkZXN0UGl4TWFwKTsKLQkJaWYgKGFkZHIgIT0gMCkgewotCQkJT1MuRGlzcG9zZVB0cihhZGRyKTsKLQkJfQotCQlpZiAodmFsdWUgIT0gMCkgewotCQkJYWRkcj0gT1MuTmV3UHRyKHNpemUpOwotCQkJT1MubWVtc2V0KGFkZHIsIHZhbHVlLCBzaXplKTsKLQkJfSBlbHNlIHsKLQkJCWFkZHI9IE9TLk5ld1B0ckNsZWFyKHNpemUpOwotCQl9Ci0JCU9TLnNldEJhc2VBZGRyKGRlc3RQaXhNYXAsIGFkZHIpOwotCX0KLQkKLQlwcml2YXRlIHN0YXRpYyB2b2lkIGNvcHlQaXhNYXBEYXRhKGludCBzcmNQaXhNYXAsIGJ5dGVbXSBkYXRhKSB7Ci0JCWludCBiYXNlQWRkcj0gT1MuZ2V0QmFzZUFkZHIoc3JjUGl4TWFwKTsKLQkJaWYgKGJhc2VBZGRyICE9IDApIHsKLQkJCWludCBsPSBPUy5HZXRQdHJTaXplKGJhc2VBZGRyKTsKLQkJCWlmIChsID09IGRhdGEubGVuZ3RoKSB7Ci0gIAkJCQlPUy5tZW1jcHkoZGF0YSwgYmFzZUFkZHIsIGRhdGEubGVuZ3RoKTsKLSAgIAkJCX0gZWxzZSB7Ci0gICAJCQkJU3lzdGVtLmVyci5wcmludGxuKCJJbWFnZS5jb3B5UGl4bWFwRGF0YTogd3JvbmcgbGVuZ3RoczogIiArIGwgKyAiICIgKyBkYXRhLmxlbmd0aCk7Ci0JCQl9Ci0JCX0KLQl9Ci0JCi0JcHJpdmF0ZSBzdGF0aWMgaW50IG5ld0JpdE1hcChpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCByb3dCeXRlcykgewotCQlpbnQgYm1oPSBPUy5OZXdIYW5kbGVDbGVhcigvKiBzaXplb2YoQml0TWFwKSAqLyAxNCk7Ci0JCU9TLnNldFJvd0J5dGVzKGJtaCwgKHNob3J0KSByb3dCeXRlcyk7Ci0JCU9TLnNldFBpeEJvdW5kcyhibWgsIChzaG9ydCkwLCAoc2hvcnQpMCwgKHNob3J0KWhlaWdodCwgKHNob3J0KXdpZHRoKTsKLQkJcmV0dXJuIGJtaDsKLQl9Ci0JCi0JcHJpdmF0ZSBzdGF0aWMgc2hvcnRbXSBnZXRDb2xvclRhYmxlKGludCBwaXhtYXBIYW5kbGUpIHsKLQkJaW50IG49IE9TLmdldENvbG9yVGFibGVTaXplKHBpeG1hcEhhbmRsZSk7Ci0JCWlmIChuIDwgMSkKLQkJCXJldHVybiBudWxsOwotCQlzaG9ydFtdIGRhdGE9IG5ldyBzaG9ydFtuKjRdOwotCQlPUy5nZXRDb2xvclRhYmxlKHBpeG1hcEhhbmRsZSwgZGF0YSk7Ci0JCXJldHVybiBkYXRhOwotCX0KLQkKLQlwcml2YXRlIHN0YXRpYyBpbnQgZ2V0UkdCKHNob3J0W10gY29sb3JUYWJsZSwgaW50IHBpeGVsKSB7Ci0JCWlmIChjb2xvclRhYmxlID09IG51bGwpCi0JCQlyZXR1cm4gMDsKLQkJaW50IGJhc2U9IHBpeGVsKjQ7Ci0JCWlmIChiYXNlICsgMyA+PSBjb2xvclRhYmxlLmxlbmd0aCkgewotCQkJU3lzdGVtLm91dC5wcmludGxuKCJJbWFnZS5nZXRSR0I6IG91dCBvZiBib3VuZHMiKTsKLQkJCXJldHVybiAwOwotCQl9Ci0JCWludCByZWQ9IGNvbG9yVGFibGVbYmFzZSsxXSA+PiA4OwotCQlpbnQgZ3JlZW49IGNvbG9yVGFibGVbYmFzZSsyXSA+PiA4OwotCQlpbnQgYmx1ZT0gY29sb3JUYWJsZVtiYXNlKzNdID4+IDg7Ci0JCXJldHVybiAocmVkIDw8IDE2KSArIChncmVlbiA8PCA4KSArIGJsdWU7Ci0JfQogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9SZWdpb24uamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3QvZ3JhcGhpY3MvUmVnaW9uLmphdmEKaW5kZXggYTYyOWNiZi4uM2VlZjlmZiAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC9ncmFwaGljcy9SZWdpb24uamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L2dyYXBoaWNzL1JlZ2lvbi5qYXZhCkBAIC02LDEwICs2LDEwIEBACiAgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKICAqLwotIAorCiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwotIAorCiAvKioKICAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIHJlcHJlc2VudCBhcmVhcyBvZiBhbiB4LXkgY29vcmRpbmF0ZQogICogc3lzdGVtIHRoYXQgYXJlIGFnZ3JlZ2F0ZXMgb2YgdGhlIGFyZWFzIGNvdmVyZWQgYnkgYSBudW1iZXIKQEAgLTI2LDYgKzI2LDcgQEAKIAkgKiAoV2FybmluZzogVGhpcyBmaWVsZCBpcyBwbGF0Zm9ybSBkZXBlbmRlbnQpCiAJICovCiAJcHVibGljIGludCBoYW5kbGU7CisKIC8qKgogICogQ29uc3RydWN0cyBhIG5ldyBlbXB0eSByZWdpb24uCiAgKiAKQEAgLTMzLDEyICszNCwxNCBAQAogICogICAgPGxpPkVSUk9SX05PX0hBTkRMRVMgaWYgYSBoYW5kbGUgY291bGQgbm90IGJlIG9idGFpbmVkIGZvciByZWdpb24gY3JlYXRpb248L2xpPgogICogPC91bD4KICAqLwotcHVibGljIFJlZ2lvbiAoKSB7Ci0JaGFuZGxlPSBPUy5OZXdSZ24oKTsKK3B1YmxpYyBSZWdpb24oKSB7CisJaGFuZGxlID0gT1MuTmV3UmduKCk7CiB9Ci1SZWdpb24gKGludCBoYW5kbGUpIHsKKworUmVnaW9uKGludCBoYW5kbGUpIHsKIAl0aGlzLmhhbmRsZSA9IGhhbmRsZTsKIH0KKwogLyoqCiAgKiBBZGRzIHRoZSBnaXZlbiByZWN0YW5nbGUgdG8gdGhlIGNvbGxlY3Rpb24gb2YgcmVjdGFuZ2xlcwogICogdGhlIHJlY2VpdmVyIG1haW50YWlucyB0byBkZXNjcmliZSBpdHMgYXJlYS4KQEAgLTUzLDE1ICs1NiwxOCBAQAogICogICAgPGxpPkVSUk9SX0dSQVBISUNfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgogICogPC91bD4KICAqLwotcHVibGljIHZvaWQgYWRkIChSZWN0YW5nbGUgcmVjdCkgeworcHVibGljIHZvaWQgYWRkKFJlY3RhbmdsZSByZWN0KSB7CiAJaWYgKGlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKIAlpZiAocmVjdCA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWlmIChyZWN0LndpZHRoIDwgMCB8fCByZWN0LmhlaWdodCA8IDApIFNXVC5lcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7Ci0JaW50IHJlY3RSZ249IE9TLk5ld1JnbigpOwotCU9TLlJlY3RSZ24ocmVjdFJnbiwgbmV3IE1hY1JlY3QocmVjdCkuZ2V0RGF0YSgpKTsKKwlpbnQgcmVjdFJnbiA9IE9TLk5ld1JnbigpOworCVJlY3QgciA9IG5ldyBSZWN0KCk7CisJT1MuU2V0UmVjdChyLCAoc2hvcnQpcmVjdC54LCAoc2hvcnQpcmVjdC55LCAoc2hvcnQpKHJlY3QueCArIHJlY3Qud2lkdGgpLChzaG9ydCkocmVjdC55ICsgcmVjdC5oZWlnaHQpKTsKKwlPUy5SZWN0UmduKHJlY3RSZ24sIHIpOwogCU9TLlVuaW9uUmduKHJlY3RSZ24sIGhhbmRsZSwgaGFuZGxlKTsKIAlPUy5EaXNwb3NlUmduKHJlY3RSZ24pOwogfQorCiAvKioKICAqIEFkZHMgYWxsIG9mIHRoZSByZWN0YW5nbGVzIHdoaWNoIG1ha2UgdXAgdGhlIGFyZWEgY292ZXJlZAogICogYnkgdGhlIGFyZ3VtZW50IHRvIHRoZSBjb2xsZWN0aW9uIG9mIHJlY3RhbmdsZXMgdGhlIHJlY2VpdmVyCkBAIC03NywxMiArODMsMTMgQEAKICAqICAgIDxsaT5FUlJPUl9HUkFQSElDX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KICAqIDwvdWw+CiAgKi8KLXB1YmxpYyB2b2lkIGFkZCAoUmVnaW9uIHJlZ2lvbikgeworcHVibGljIHZvaWQgYWRkKFJlZ2lvbiByZWdpb24pIHsKIAlpZiAoaXNEaXNwb3NlZCgpKSBTV1QuZXJyb3IoU1dULkVSUk9SX0dSQVBISUNfRElTUE9TRUQpOwogCWlmIChyZWdpb24gPT0gbnVsbCkgU1dULmVycm9yKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlpZiAocmVnaW9uLmlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKLQlPUy5VbmlvblJnbihoYW5kbGUsIHJlZ2lvbi5oYW5kbGUsIGhhbmRsZSk7CisJT1MuVW5pb25SZ24ocmVnaW9uLmhhbmRsZSwgaGFuZGxlLCBoYW5kbGUpOwogfQorCiAvKioKICAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHBvaW50IHNwZWNpZmllZCBieSB0aGUKICAqIGFyZ3VtZW50cyBpcyBpbnNpZGUgdGhlIGFyZWEgc3BlY2lmaWVkIGJ5IHRoZSByZWNlaXZlciwKQEAgLTk2LDEwICsxMDMsMTMgQEAKICAqICAgIDxsaT5FUlJPUl9HUkFQSElDX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KICAqIDwvdWw+CiAgKi8KLXB1YmxpYyBib29sZWFuIGNvbnRhaW5zIChpbnQgeCwgaW50IHkpIHsKK3B1YmxpYyBib29sZWFuIGNvbnRhaW5zKGludCB4LCBpbnQgeSkgewogCWlmIChpc0Rpc3Bvc2VkKCkpIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JcmV0dXJuIE9TLlB0SW5SZ24obmV3IE1hY1BvaW50KHgsIHkpLmdldERhdGEoKSwgaGFuZGxlKTsKKwlvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBvaW50IHBvaW50ID0gbmV3IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQoKTsKKwlPUy5TZXRQdChwb2ludCwgKHNob3J0KXgsIChzaG9ydCl5KTsKKwlyZXR1cm4gT1MuUHRJblJnbihwb2ludCwgaGFuZGxlKTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBnaXZlbiBwb2ludCBpcyBpbnNpZGUgdGhlCiAgKiBhcmVhIHNwZWNpZmllZCBieSB0aGUgcmVjZWl2ZXIsIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4KQEAgLTExNSw3ICsxMjUsNyBAQAogICogICAgPGxpPkVSUk9SX0dSQVBISUNfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgogICogPC91bD4KICAqLwotcHVibGljIGJvb2xlYW4gY29udGFpbnMgKFBvaW50IHB0KSB7CitwdWJsaWMgYm9vbGVhbiBjb250YWlucyhQb2ludCBwdCkgewogCWlmIChwdCA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCXJldHVybiBjb250YWlucyhwdC54LCBwdC55KTsKIH0KQEAgLTEyNCwxMCArMTM0LDExIEBACiAgKiB0aGUgcmVnaW9uLiBBcHBsaWNhdGlvbnMgbXVzdCBkaXNwb3NlIG9mIGFsbCByZWdpb25zIHdoaWNoCiAgKiB0aGV5IGFsbG9jYXRlLgogICovCi1wdWJsaWMgdm9pZCBkaXNwb3NlICgpIHsKK3B1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CiAJaWYgKGhhbmRsZSAhPSAwKSBPUy5EaXNwb3NlUmduKGhhbmRsZSk7CiAJaGFuZGxlID0gMDsKIH0KKwogLyoqCiAgKiBDb21wYXJlcyB0aGUgYXJndW1lbnQgdG8gdGhlIHJlY2VpdmVyLCBhbmQgcmV0dXJucyB0cnVlCiAgKiBpZiB0aGV5IHJlcHJlc2VudCB0aGUgPGVtPnNhbWU8L2VtPiBvYmplY3QgdXNpbmcgYSBjbGFzcwpAQCAtMTM4LDEyICsxNDksMTMgQEAKICAqCiAgKiBAc2VlICNoYXNoQ29kZQogICovCi1wdWJsaWMgYm9vbGVhbiBlcXVhbHMgKE9iamVjdCBvYmplY3QpIHsKK3B1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CiAJaWYgKHRoaXMgPT0gb2JqZWN0KSByZXR1cm4gdHJ1ZTsKIAlpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBSZWdpb24pKSByZXR1cm4gZmFsc2U7CiAJUmVnaW9uIHJlZ2lvbiA9IChSZWdpb24pb2JqZWN0OwogCXJldHVybiBoYW5kbGUgPT0gcmVnaW9uLmhhbmRsZTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIGEgcmVjdGFuZ2xlIHdoaWNoIHJlcHJlc2VudHMgdGhlIHJlY3Rhbmd1bGFyCiAgKiB1bmlvbiBvZiB0aGUgY29sbGVjdGlvbiBvZiByZWN0YW5nbGVzIHRoZSByZWNlaXZlcgpAQCAtMTU5LDEwICsxNzEsMTcgQEAKICAqLwogcHVibGljIFJlY3RhbmdsZSBnZXRCb3VuZHMoKSB7CiAJaWYgKGlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKLQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQlPUy5HZXRSZWdpb25Cb3VuZHMoaGFuZGxlLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQlyZXR1cm4gYm91bmRzLnRvUmVjdGFuZ2xlKCk7CisJUmVjdCBib3VuZHMgPSBuZXcgUmVjdCgpOworCU9TLkdldFJlZ2lvbkJvdW5kcyhoYW5kbGUsIGJvdW5kcyk7CisJaW50IHdpZHRoID0gYm91bmRzLnJpZ2h0IC0gYm91bmRzLmxlZnQ7CisJaW50IGhlaWdodCA9IGJvdW5kcy5ib3R0b20gLSBib3VuZHMudG9wOworCXJldHVybiBuZXcgUmVjdGFuZ2xlKGJvdW5kcy5sZWZ0LCBib3VuZHMudG9wLCB3aWR0aCwgaGVpZ2h0KTsKIH0KKworcHVibGljIHN0YXRpYyBSZWdpb24gY2FyYm9uX25ldyhpbnQgaGFuZGxlKSB7CisJcmV0dXJuIG5ldyBSZWdpb24oaGFuZGxlKTsKK30KKwogLyoqCiAgKiBSZXR1cm5zIGFuIGludGVnZXIgaGFzaCBjb2RlIGZvciB0aGUgcmVjZWl2ZXIuIEFueSB0d28gCiAgKiBvYmplY3RzIHdoaWNoIHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHBhc3NlZCB0byAKQEAgLTE3Myw5ICsxOTIsMTAgQEAKICAqCiAgKiBAc2VlICNlcXVhbHMKICAqLwotcHVibGljIGludCBoYXNoQ29kZSAoKSB7CitwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogCXJldHVybiBoYW5kbGU7CiB9CisKIC8qKgogICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVjdGFuZ2xlIGRlc2NyaWJlZCBieSB0aGUKICAqIGFyZ3VtZW50cyBpbnRlcnNlY3RzIHdpdGggYW55IG9mIHRoZSByZWN0YW5nbGVzIHRoZSByZWNlaXZlcgpAQCAtMTk1LDggKzIxNSwxMSBAQAogICovCiBwdWJsaWMgYm9vbGVhbiBpbnRlcnNlY3RzIChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgewogCWlmIChpc0Rpc3Bvc2VkKCkpIFNXVC5lcnJvcihTV1QuRVJST1JfR1JBUEhJQ19ESVNQT1NFRCk7Ci0JcmV0dXJuIE9TLlJlY3RJblJnbihuZXcgTWFjUmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0KS5nZXREYXRhKCksIGhhbmRsZSk7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QoKTsKKwlPUy5TZXRSZWN0KHJlY3QsIChzaG9ydCl4LCAoc2hvcnQpeSwgKHNob3J0KSh4ICsgd2lkdGgpLChzaG9ydCkoeSArIGhlaWdodCkpOworCXJldHVybiBPUy5SZWN0SW5SZ24ocmVjdCwgaGFuZGxlKTsKIH0KKwogLyoqCiAgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBnaXZlbiByZWN0YW5nbGUgaW50ZXJzZWN0cwogICogd2l0aCBhbnkgb2YgdGhlIHJlY3RhbmdsZXMgdGhlIHJlY2VpdmVyIG1haW5haW5zIHRvIGRlc2NyaWJlCkBAIC0yMTQsMTAgKzIzNywxMSBAQAogICoKICAqIEBzZWUgUmVjdGFuZ2xlI2ludGVyc2VjdHMKICAqLwotcHVibGljIGJvb2xlYW4gaW50ZXJzZWN0cyAoUmVjdGFuZ2xlIHJlY3QpIHsKK3B1YmxpYyBib29sZWFuIGludGVyc2VjdHMoUmVjdGFuZ2xlIHJlY3QpIHsKIAlpZiAocmVjdCA9PSBudWxsKSBTV1QuZXJyb3IoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCXJldHVybiBpbnRlcnNlY3RzKHJlY3QueCwgcmVjdC55LCByZWN0LndpZHRoLCByZWN0LmhlaWdodCk7CiB9CisKIC8qKgogICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVnaW9uIGhhcyBiZWVuIGRpc3Bvc2VkLAogICogYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCkBAIC0yMzEsNiArMjU1LDcgQEAKIHB1YmxpYyBib29sZWFuIGlzRGlzcG9zZWQoKSB7CiAJcmV0dXJuIGhhbmRsZSA9PSAwOwogfQorCiAvKioKICAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGRvZXMgbm90IGNvdmVyIGFueQogICogYXJlYSBpbiB0aGUgKHgsIHkpIGNvb3JkaW5hdGUgcGxhbmUsIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gaWYKQEAgLTI0MiwxMyArMjY3LDExIEBACiAgKiAgICA8bGk+RVJST1JfR1JBUEhJQ19ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+CiAgKiA8L3VsPgogICovCi1wdWJsaWMgYm9vbGVhbiBpc0VtcHR5ICgpIHsKK3B1YmxpYyBib29sZWFuIGlzRW1wdHkoKSB7CiAJaWYgKGlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9HUkFQSElDX0RJU1BPU0VEKTsKIAlyZXR1cm4gT1MuRW1wdHlSZ24oaGFuZGxlKTsKIH0KLXB1YmxpYyBzdGF0aWMgUmVnaW9uIG1hY29zeF9uZXcoaW50IHJnbkhhbmRsZSkgewotCXJldHVybiBuZXcgUmVnaW9uKHJnbkhhbmRsZSk7Ci19CisKIC8qKgogICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUKICAqIGRlc2NyaXB0aW9uIG9mIHRoZSByZWNlaXZlci4KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9CdXR0b24uamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9CdXR0b24uamF2YQppbmRleCA0NTNkY2UzLi5jODkwZTY5IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvQnV0dG9uLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0J1dHRvbi5qYXZhCkBAIC03LDExMyArNywyNiBAQAogICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKICAqLwogCi1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLk9TOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uQ29udHJvbEZvbnRTdHlsZVJlYzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkNvbnRyb2xCdXR0b25Db250ZW50SW5mbzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkNGUmFuZ2U7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5SZWN0OwogCi0vKioKLSAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIHJlcHJlc2VudCBhIHNlbGVjdGFibGUgdXNlciBpbnRlcmZhY2Ugb2JqZWN0IHRoYXQKLSAqIGlzc3VlcyBub3RpZmljYXRpb24gd2hlbiBwcmVzc2VkIGFuZCByZWxlYXNlZC4gCi0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPkFSUk9XLCBDSEVDSywgUFVTSCwgUkFESU8sIFRPR0dMRSwgRkxBVDwvZGQ+Ci0gKiA8ZGQ+VVAsIERPV04sIExFRlQsIFJJR0hULCBDRU5URVI8L2RkPgotICogPGR0PjxiPkV2ZW50czo8L2I+PC9kdD4KLSAqIDxkZD5TZWxlY3Rpb248L2RkPgotICogPC9kbD4KLSAqIDxwPgotICogTm90ZTogT25seSBvbmUgb2YgdGhlIHN0eWxlcyBBUlJPVywgQ0hFQ0ssIFBVU0gsIFJBRElPLCBhbmQgVE9HR0xFIAotICogbWF5IGJlIHNwZWNpZmllZC4KLSAqIDwvcD48cD4KLSAqIE5vdGU6IE9ubHkgb25lIG9mIHRoZSBzdHlsZXMgTEVGVCwgUklHSFQsIGFuZCBDRU5URVIgbWF5IGJlIHNwZWNpZmllZC4KLSAqIDwvcD48cD4KLSAqIE5vdGU6IE9ubHkgb25lIG9mIHRoZSBzdHlsZXMgVVAsIERPV04sIExFRlQsIGFuZCBSSUdIVCBtYXkgYmUgc3BlY2lmaWVkCi0gKiB3aGVuIHRoZSBBUlJPVyBzdHlsZSBpcyBzcGVjaWZpZWQuCi0gKiA8L3A+PHA+Ci0gKiBJTVBPUlRBTlQ6IFRoaXMgY2xhc3MgaXMgaW50ZW5kZWQgdG8gYmUgc3ViY2xhc3NlZCA8ZW0+b25seTwvZW0+Ci0gKiB3aXRoaW4gdGhlIFNXVCBpbXBsZW1lbnRhdGlvbi4KLSAqIDwvcD4KLSAqLwotcHVibGljIC8qZmluYWwqLyBjbGFzcyBCdXR0b24gZXh0ZW5kcyBDb250cm9sIHsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7CisKK3B1YmxpYyBjbGFzcyBCdXR0b24gZXh0ZW5kcyBDb250cm9sIHsKKwlTdHJpbmcgdGV4dCA9ICIiOwogCUltYWdlIGltYWdlOworCWludCBjSWNvbjsKKwlib29sZWFuIGlzSW1hZ2U7CiAJCi0JLy8gQVcKLQlwcml2YXRlIGJvb2xlYW4gZkltYWdlTW9kZTsKLQlwcml2YXRlIGludCBmQWxpZ25tZW50OwotCXByaXZhdGUgaW50IGZDSWNvbkhhbmRsZTsKLQlwcml2YXRlIGludCBmVG9wTWFyZ2luOwotCXByaXZhdGUgaW50IGZCb3R0b21NYXJnaW47Ci0JCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BUkdJTj0gMzsJLy8gY29ycmVjdCB2YWx1ZSB3b3VsZCBiZSA2OyBob3dldmVyIHRoZSBzaGFkb3cgaXMgb25seSAyCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNQQUNFPSA5OwkvLyBtaW4gaXMgOCBvciBtYXkgYmUgOQotCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUT1BfTUFSR0lOPSAwOwkvLyAKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQk9UVE9NX01BUkdJTj0gNTsJLy8gCi0JLy8gQVcKLQkKLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIGl0cyBwYXJlbnQKLSAqIGFuZCBhIHN0eWxlIHZhbHVlIGRlc2NyaWJpbmcgaXRzIGJlaGF2aW9yIGFuZCBhcHBlYXJhbmNlLgotICogPHA+Ci0gKiBUaGUgc3R5bGUgdmFsdWUgaXMgZWl0aGVyIG9uZSBvZiB0aGUgc3R5bGUgY29uc3RhbnRzIGRlZmluZWQgaW4KLSAqIGNsYXNzIDxjb2RlPlNXVDwvY29kZT4gd2hpY2ggaXMgYXBwbGljYWJsZSB0byBpbnN0YW5jZXMgb2YgdGhpcwotICogY2xhc3MsIG9yIG11c3QgYmUgYnVpbHQgYnkgPGVtPmJpdHdpc2UgT1I8L2VtPidpbmcgdG9nZXRoZXIgCi0gKiAodGhhdCBpcywgdXNpbmcgdGhlIDxjb2RlPmludDwvY29kZT4gInwiIG9wZXJhdG9yKSB0d28gb3IgbW9yZQotICogb2YgdGhvc2UgPGNvZGU+U1dUPC9jb2RlPiBzdHlsZSBjb25zdGFudHMuIFRoZSBjbGFzcyBkZXNjcmlwdGlvbgotICogbGlzdHMgdGhlIHN0eWxlIGNvbnN0YW50cyB0aGF0IGFyZSBhcHBsaWNhYmxlIHRvIHRoZSBjbGFzcy4KLSAqIFN0eWxlIGJpdHMgYXJlIGFsc28gaW5oZXJpdGVkIGZyb20gc3VwZXJjbGFzc2VzLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBjb21wb3NpdGUgY29udHJvbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZSAoY2Fubm90IGJlIG51bGwpCi0gKiBAcGFyYW0gc3R5bGUgdGhlIHN0eWxlIG9mIGNvbnRyb2wgdG8gY29uc3RydWN0Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcGFyZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHBhcmVudDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNXVCNBUlJPVwotICogQHNlZSBTV1QjQ0hFQ0sKLSAqIEBzZWUgU1dUI1BVU0gKLSAqIEBzZWUgU1dUI1JBRElPCi0gKiBAc2VlIFNXVCNUT0dHTEUKLSAqIEBzZWUgU1dUI0ZMQVQKLSAqIEBzZWUgU1dUI0xFRlQKLSAqIEBzZWUgU1dUI1JJR0hUCi0gKiBAc2VlIFNXVCNDRU5URVIKLSAqIEBzZWUgV2lkZ2V0I2NoZWNrU3ViY2xhc3MKLSAqIEBzZWUgV2lkZ2V0I2dldFN0eWxlCi0gKi8KIHB1YmxpYyBCdXR0b24gKENvbXBvc2l0ZSBwYXJlbnQsIGludCBzdHlsZSkgewogCXN1cGVyIChwYXJlbnQsIGNoZWNrU3R5bGUgKHN0eWxlKSk7CiB9Ci0vKioKLSAqIEFkZHMgdGhlIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgY29udHJvbCBpcyBzZWxlY3RlZCwgYnkgc2VuZGluZwotICogaXQgb25lIG9mIHRoZSBtZXNzYWdlcyBkZWZpbmVkIGluIHRoZSA8Y29kZT5TZWxlY3Rpb25MaXN0ZW5lcjwvY29kZT4KLSAqIGludGVyZmFjZS4KLSAqIDxwPgotICogPGNvZGU+d2lkZ2V0U2VsZWN0ZWQ8L2NvZGU+IGlzIGNhbGxlZCB3aGVuIHRoZSBjb250cm9sIGlzIHNlbGVjdGVkLgotICogPGNvZGU+d2lkZ2V0RGVmYXVsdFNlbGVjdGVkPC9jb2RlPiBpcyBub3QgY2FsbGVkLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU2VsZWN0aW9uTGlzdGVuZXIKLSAqIEBzZWUgI3JlbW92ZVNlbGVjdGlvbkxpc3RlbmVyCi0gKiBAc2VlIFNlbGVjdGlvbkV2ZW50Ci0gKi8KKwogcHVibGljIHZvaWQgYWRkU2VsZWN0aW9uTGlzdGVuZXIoU2VsZWN0aW9uTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwpAQCAtMTIxLDYgKzM0LDcgQEAKIAlhZGRMaXN0ZW5lcihTV1QuU2VsZWN0aW9uLHR5cGVkTGlzdGVuZXIpOwogCWFkZExpc3RlbmVyKFNXVC5EZWZhdWx0U2VsZWN0aW9uLHR5cGVkTGlzdGVuZXIpOwogfQorCiBzdGF0aWMgaW50IGNoZWNrU3R5bGUgKGludCBzdHlsZSkgewogCXN0eWxlID0gY2hlY2tCaXRzIChzdHlsZSwgU1dULlBVU0gsIFNXVC5BUlJPVywgU1dULkNIRUNLLCBTV1QuUkFESU8sIFNXVC5UT0dHTEUsIDApOwogCWlmICgoc3R5bGUgJiBTV1QuUFVTSCkgIT0gMCkgewpAQCAtMTM0LDI2MCArNDgsMTkwIEBACiAJfQogCXJldHVybiBzdHlsZTsKIH0KLXZvaWQgY2xpY2sgKCkgewotCXNob3J0IHBhcnQ9IDEwOwotCWlmICgoc3R5bGUgJiBTV1QuQ0hFQ0spICE9IDAgfHwgKHN0eWxlICYgU1dULlJBRElPKSAhPSAwKQotCQlwYXJ0PSAxMTsKLSAgICBPUy5ISVZpZXdTaW11bGF0ZUNsaWNrKGhhbmRsZSwgcGFydCwgMCwgbmV3IHNob3J0WzFdKTsKLX0KKwogcHVibGljIFBvaW50IGNvbXB1dGVTaXplIChpbnQgd0hpbnQsIGludCBoSGludCwgYm9vbGVhbiBjaGFuZ2VkKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpbnQgYm9yZGVyID0gZ2V0Qm9yZGVyV2lkdGggKCk7Ci0JaW50IHdpZHRoID0gYm9yZGVyICogMiwgaGVpZ2h0ID0gYm9yZGVyICogMjsKKwkvLyBORUVEUyBXT1JLIC0gZW1wdHkgc3RyaW5nCiAJaWYgKChzdHlsZSAmIFNXVC5BUlJPVykgIT0gMCkgewotCQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOwotCQl3aWR0aCArPSBkaXNwbGF5LnNjcm9sbGVkTWFyZ2luWDsKLQkJaGVpZ2h0ICs9IGRpc3BsYXkuc2Nyb2xsZWRNYXJnaW5ZOwotCQlpZiAod0hpbnQgIT0gU1dULkRFRkFVTFQpIHdpZHRoID0gd0hpbnQgKyAoYm9yZGVyICogMik7Ci0JCWlmIChoSGludCAhPSBTV1QuREVGQVVMVCkgaGVpZ2h0ID0gaEhpbnQgKyAoYm9yZGVyICogMik7CisJCWludCBbXSBvdXRNZXRyaWMgPSBuZXcgaW50IFsxXTsKKwkJT1MuR2V0VGhlbWVNZXRyaWMgKE9TLmtUaGVtZU1ldHJpY0Rpc2Nsb3N1cmVUcmlhbmdsZUhlaWdodCwgb3V0TWV0cmljKTsKKwkJaW50IHdpZHRoID0gb3V0TWV0cmljIFswXSwgaGVpZ2h0ID0gb3V0TWV0cmljIFswXTsKKwkJaWYgKHdIaW50ICE9IFNXVC5ERUZBVUxUKSB3aWR0aCA9IHdIaW50OworCQlpZiAoaEhpbnQgIT0gU1dULkRFRkFVTFQpIGhlaWdodCA9IGhIaW50OwogCQlyZXR1cm4gbmV3IFBvaW50ICh3aWR0aCwgaGVpZ2h0KTsKIAl9Ci0gICAgLyogQVcKLQlYdFdpZGdldEdlb21ldHJ5IHJlc3VsdCA9IG5ldyBYdFdpZGdldEdlb21ldHJ5ICgpOwotCXJlc3VsdC5yZXF1ZXN0X21vZGUgPSBPUy5DV1dpZHRoIHwgT1MuQ1dIZWlnaHQ7Ci0JaW50IFtdIGFyZ0xpc3QyID0ge09TLlhtTnJlY29tcHV0ZVNpemUsIDF9OwotCU9TLlh0U2V0VmFsdWVzKGhhbmRsZSwgYXJnTGlzdDIsIGFyZ0xpc3QyLmxlbmd0aCAvIDIpOwotCU9TLlh0UXVlcnlHZW9tZXRyeSAoaGFuZGxlLCBudWxsLCByZXN1bHQpOwotCWludCBbXSBhcmdMaXN0MyA9IHtPUy5YbU5yZWNvbXB1dGVTaXplLCAwfTsKLQlPUy5YdFNldFZhbHVlcyhoYW5kbGUsIGFyZ0xpc3QzLCBhcmdMaXN0My5sZW5ndGggLyAyKTsKLQkqLwotCVBvaW50IHJlc3VsdD0gTWFjVXRpbC5jb21wdXRlU2l6ZShoYW5kbGUpOwotCWlmICgoc3R5bGUgJiBTV1QuUFVTSCkgIT0gMCkgewotCQlpZiAoaW1hZ2UgIT0gbnVsbCkgewkvLyBpcyBhIEJldmVsIGJ1dHRvbiEKLQkJCVJlY3RhbmdsZSBib3VuZHM9IGltYWdlLmdldEJvdW5kcygpOwotCQkJcmVzdWx0Lng9IDQgKyBib3VuZHMud2lkdGggKyA0OwotCQkJcmVzdWx0Lnk9IDQgKyBib3VuZHMuaGVpZ2h0ICsgNDsKLQkJfSBlbHNlIHsKLQkJCVN0cmluZyBzPSBnZXRUZXh0KCk7Ci0JCQlpZiAocyAhPSBudWxsICYmIHMubGVuZ3RoKCkgPiAwKSB7Ci0JCQkJcmVzdWx0Lng9IHJlc3VsdC54IC0gMipTUEFDRSArIDIqTUFSR0lOOwotCQkJCXJlc3VsdC55PSByZXN1bHQueSArIFRPUF9NQVJHSU4gKyBCT1RUT01fTUFSR0lOOworCisJaW50IHdpZHRoID0gMCwgaGVpZ2h0ID0gMDsKKworCWlmIChpc0ltYWdlICYmIGltYWdlICE9IG51bGwpIHsKKwkJUmVjdGFuZ2xlIGJvdW5kcyA9IGltYWdlLmdldEJvdW5kcygpOworCQl3aWR0aCA9IGJvdW5kcy53aWR0aDsKKwkJaGVpZ2h0ID0gYm91bmRzLmhlaWdodDsKKwl9IGVsc2UgeworCQlpbnQgW10gcHRyID0gbmV3IGludCBbMV07CisJCU9TLkNvcHlDb250cm9sVGl0bGVBc0NGU3RyaW5nKGhhbmRsZSwgcHRyKTsKKwkJaWYgKHB0ciBbMF0gIT0gMCkgeworCQkJaWYgKGZvbnQgPT0gbnVsbCkgeworCQkJCW9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgaW9Cb3VuZHMgPSBuZXcgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCAoKTsKKwkJCQlzaG9ydCBbXSBiYXNlTGluZSA9IG5ldyBzaG9ydCBbMV07CisJCQkJT1MuR2V0VGhlbWVUZXh0RGltZW5zaW9ucyhwdHIgWzBdLCAoc2hvcnQpT1Mua1RoZW1lUHVzaEJ1dHRvbkZvbnQsIE9TLmtUaGVtZVN0YXRlQWN0aXZlLCBmYWxzZSwgaW9Cb3VuZHMsIGJhc2VMaW5lKTsKKwkJCQl3aWR0aCA9IGlvQm91bmRzLmg7CisJCQkJaGVpZ2h0ID0gaW9Cb3VuZHMudjsKKwkJCX0gZWxzZSB7CisJCQkJLy8gTkVFRFMgV09SSyAtIGFsdGVybmF0aXZlbHkgd2UgY291bGQgdXNlIEdldFRoZW1lVGV4dERpbWVuc2lvbnMgd2l0aCBPUy5rVGhlbWVDdXJyZW50UG9ydEZvbnQKKwkJCQlpbnQgbGVuZ3RoID0gT1MuQ0ZTdHJpbmdHZXRMZW5ndGggKHB0ciBbMF0pOworCQkJCWNoYXIgW10gYnVmZmVyID0gbmV3IGNoYXIgW2xlbmd0aF07CisJCQkJQ0ZSYW5nZSByYW5nZSA9IG5ldyBDRlJhbmdlICgpOworCQkJCXJhbmdlLmxlbmd0aCA9IGxlbmd0aDsKKwkJCQlPUy5DRlN0cmluZ0dldENoYXJhY3RlcnMgKHB0ciBbMF0sIHJhbmdlLCBidWZmZXIpOworCQkJCVN0cmluZyBzdHJpbmcgPSBuZXcgU3RyaW5nIChidWZmZXIpOworCQkJCUdDIGdjID0gbmV3IEdDICh0aGlzKTsKKwkJCQlQb2ludCBleHRlbnQgPSBnYy5zdHJpbmdFeHRlbnQgKHN0cmluZyk7CisJCQkJZ2MuZGlzcG9zZSAoKTsKKwkJCQl3aWR0aCA9IGV4dGVudC54OworCQkJCWhlaWdodCA9IGV4dGVudC55OwogCQkJfQorCQkJT1MuQ0ZSZWxlYXNlIChwdHIgWzBdKTsKKwkJfSBlbHNlIHsKKwkJCXdpZHRoID0gREVGQVVMVF9XSURUSDsKKwkJCWhlaWdodCA9IERFRkFVTFRfSEVJR0hUOwogCQl9CiAJfQotCXdpZHRoICs9IHJlc3VsdC54OwotCWhlaWdodCArPSByZXN1bHQueTsKLQkvKgotCSAqIEZlYXR1cmUgaW4gTW90aWYuIElmIGEgYnV0dG9uJ3MgbGFiZWxUeXBlIGlzIFhtU1RSSU5HIGJ1dCBpdAotCSAqIGhhcyBubyBsYWJlbCBzZXQgaW50byBpdCB5ZXQsIHJlY29tcHV0aW5nIHRoZSBzaXplIHdpbGwKLQkgKiBub3QgdGFrZSBpbnRvIGFjY291bnQgdGhlIGhlaWdodCBvZiB0aGUgZm9udCwgYXMgd2Ugd291bGQKLQkgKiBsaWtlIGl0IHRvLiBUYWtlIGNhcmUgb2YgdGhpcyBjYXNlLgotCSAqLwotICAgIC8qIEFXCi0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1ObGFiZWxUeXBlLCAwfTsKLQlPUy5YdEdldFZhbHVlcyAoaGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCWlmIChhcmdMaXN0IFsxXSA9PSBPUy5YbVNUUklORykgewotCQlpbnQgW10gYXJnTGlzdDEgPSB7T1MuWG1ObGFiZWxTdHJpbmcsIDB9OwotCQlPUy5YdEdldFZhbHVlcyAoaGFuZGxlLCBhcmdMaXN0MSwgYXJnTGlzdDEubGVuZ3RoIC8gMik7Ci0JCWludCB4bVN0cmluZyA9IGFyZ0xpc3QxIFsxXTsKLQkJaWYgKE9TLlhtU3RyaW5nRW1wdHkgKHhtU3RyaW5nKSkgaGVpZ2h0ICs9IGdldEZvbnRIZWlnaHQgKCk7Ci0JfQotCSovCi0JaWYgKHdIaW50ICE9IFNXVC5ERUZBVUxUIHx8IGhIaW50ICE9IFNXVC5ERUZBVUxUKSB7Ci0JCS8qIEFXCi0JCWludCBbXSBhcmdMaXN0NCA9IG5ldyBpbnQgW10ge09TLlhtTm1hcmdpbkxlZnQsIDAsIE9TLlhtTm1hcmdpblJpZ2h0LCAwLCBPUy5YbU5tYXJnaW5Ub3AsIDAsIE9TLlhtTm1hcmdpbkJvdHRvbSwgMH07Ci0JCU9TLlh0R2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3Q0LCBhcmdMaXN0NC5sZW5ndGggLyAyKTsKLQkJaWYgKHdIaW50ICE9IFNXVC5ERUZBVUxUKSB3aWR0aCA9IHdIaW50ICsgYXJnTGlzdDQgWzFdICsgYXJnTGlzdDQgWzNdICsgKGJvcmRlciAqIDIpOwotCQlpZiAoaEhpbnQgIT0gU1dULkRFRkFVTFQpIGhlaWdodCA9IGhIaW50ICsgYXJnTGlzdDQgWzVdICsgYXJnTGlzdDQgWzddICsgKGJvcmRlciAqIDIpOwotCQkqLwotCQlpbnQgbGVmdD0gMDsKLQkJaW50IHJpZ2h0PSAwOwotCQlpbnQgdG9wPSAwOwotCQlpbnQgYm90dG9tPSAwOwotCQkKLQkJaWYgKHdIaW50ICE9IFNXVC5ERUZBVUxUKSB3aWR0aCA9IHdIaW50ICsgbGVmdCArIHJpZ2h0OwotCQlpZiAoaEhpbnQgIT0gU1dULkRFRkFVTFQpIGhlaWdodCA9IGhIaW50ICsgdG9wICsgYm90dG9tOwotCX0KLQkJCi0JcmV0dXJuIG5ldyBQb2ludCh3aWR0aCwgaGVpZ2h0KTsKLX0KLXZvaWQgY3JlYXRlSGFuZGxlIChpbnQgaW5kZXgpIHsKLQlzdGF0ZSB8PSBIQU5ETEU7Ci0JLyogQVcKLQlpbnQgYm9yZGVyV2lkdGggPSAoc3R5bGUgJiBTV1QuQk9SREVSKSAhPSAwID8gMSA6IDA7Ci0JKi8KLQlpbnQgcGFyZW50SGFuZGxlID0gcGFyZW50LmhhbmRsZTsKIAotCS8qIEFSUk9XIGJ1dHRvbiAqLworCWlmICgoc3R5bGUgJiAoU1dULkNIRUNLIHwgU1dULlJBRElPKSkgIT0gMCkgeworCQlpbnQgW10gb3V0TWV0cmljID0gbmV3IGludCBbMV07CisJCWludCBtZXRyaWMgPSAoKHN0eWxlICYgU1dULkNIRUNLKSAhPSAwKSA/IE9TLmtUaGVtZU1ldHJpY0NoZWNrQm94V2lkdGggOiBPUy5rVGhlbWVNZXRyaWNSYWRpb0J1dHRvbldpZHRoOworCQlPUy5HZXRUaGVtZU1ldHJpYyAobWV0cmljLCBvdXRNZXRyaWMpOwkKKyAJCXdpZHRoICs9IG91dE1ldHJpYyBbMF0gKyAzOyAvLyArMyBmb3IgZ2FwIGJldHdlZW4gYnV0dG9uIGFuZCB0ZXh0L2ltYWdlCisJCWhlaWdodCA9IE1hdGgubWF4KG91dE1ldHJpYyBbMF0sIGhlaWdodCk7CisJfSBlbHNlIHsKKwkJaWYgKChzdHlsZSAmIFNXVC5GTEFUKSAhPSAwIHx8IChzdHlsZSAmIFNXVC5UT0dHTEUpICE9IDApIHsKKwkJCXdpZHRoICs9IDEwOworCQkJaGVpZ2h0ICs9IDEwOworCQl9IGVsc2UgeworCQkJd2lkdGggKz0gMjg7CisJCQloZWlnaHQgKz0gODsKKwkJfQorCX0KKwkKKwlSZWN0IGluc2V0ID0gZ2V0SW5zZXQgKCk7CisJd2lkdGggKz0gaW5zZXQubGVmdCArIGluc2V0LnJpZ2h0OworCWhlaWdodCArPSBpbnNldC50b3AgKyBpbnNldC5ib3R0b207CisJCisJLyoKKwkgKiBGZWF0dXJlIGluIE1hYyBPUyBYLiBTZXR0aW5nIHRoZSB3aWR0aCBvZiBhIGJldmVsIGJ1dHRvbgorCSAqIHdpZGdldCB0byBsZXNzIHRoYW4gMjAgd2lsbCBmYWlsLiAgVGhpcyBtZWFucyB5b3UgY2FuIG5vdCAKKwkgKiBtYWtlIGEgYnV0dG9uIHZlcnkgc21hbGwuICBCeSBmb3JjaW5nIHRoZSB3aWR0aCB0byBiZSBncmVhdGVyCisJICogdGhhbiBvciBlcXVhbCB0byAyMCwgdGhlIGhlaWdodCBvZiB0aGUgYnV0dG9uIGNhbiBiZSBtYWRlCisJICogdmVyeSBzbWFsbCwgZXZlbiAwLgorCSAqLworCXdpZHRoID0gTWF0aC5tYXgoMjAsIHdpZHRoKTsKKwlpbnQgYm9yZGVyID0gKHN0eWxlICYgU1dULlBVU0gpICE9IDAgPyAyIDogMDsKKwlpZiAod0hpbnQgIT0gU1dULkRFRkFVTFQpIHdpZHRoID0gd0hpbnQgKyAoYm9yZGVyICogMik7CisJaWYgKGhIaW50ICE9IFNXVC5ERUZBVUxUKSBoZWlnaHQgPSBoSGludCArIChib3JkZXIgKiAyKTsKKwlyZXR1cm4gbmV3IFBvaW50ICh3aWR0aCwgaGVpZ2h0KTsKK30KKwordm9pZCBjcmVhdGVIYW5kbGUgKCkgeworCWludCBbXSBvdXRDb250cm9sID0gbmV3IGludCBbMV07CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAocGFyZW50LmhhbmRsZSk7CisJCQkJCiAJaWYgKChzdHlsZSAmIFNXVC5BUlJPVykgIT0gMCkgewotICAgICAgICAvKgotCQlpbnQgYWxpZ25tZW50ID0gT1MuWG1BUlJPV19VUDsKLQkJaWYgKChzdHlsZSAmIFNXVC5VUCkgIT0gMCkgYWxpZ25tZW50ID0gT1MuWG1BUlJPV19VUDsKLQkJaWYgKChzdHlsZSAmIFNXVC5ET1dOKSAhPSAwKSBhbGlnbm1lbnQgPSBPUy5YbUFSUk9XX0RPV047Ci0JCWlmICgoc3R5bGUgJiBTV1QuTEVGVCkgIT0gMCkgYWxpZ25tZW50ID0gT1MuWG1BUlJPV19MRUZUOwotCQlpZiAoKHN0eWxlICYgU1dULlJJR0hUKSAhPSAwKSBhbGlnbm1lbnQgPSBPUy5YbUFSUk9XX1JJR0hUOwotCQlpbnQgW10gYXJnTGlzdCA9IHsKLQkJCU9TLlhtTnRyYXZlcnNhbE9uLCAwLAotCQkJT1MuWG1OYXJyb3dEaXJlY3Rpb24sIGFsaWdubWVudCwKLQkJCU9TLlhtTmJvcmRlcldpZHRoLCBib3JkZXJXaWR0aCwKLQkJCU9TLlhtTmFuY2VzdG9yU2Vuc2l0aXZlLCAxLAotCQl9OwotCQloYW5kbGUgPSBPUy5YbUNyZWF0ZUFycm93QnV0dG9uIChwYXJlbnRIYW5kbGUsIG51bGwsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0gICAgICAgICovCi0gICAgICAgIGhhbmRsZT0gTWFjVXRpbC5uZXdDb250cm9sKHBhcmVudEhhbmRsZSwgKHNob3J0KU9TLmtDb250cm9sQmV2ZWxCdXR0b25Ob3JtYWxCZXZlbFByb2MpOwotCQlpZiAoaGFuZGxlID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JCWludCBrVGhlbWVEaXNjbG9zdXJlUmlnaHQgPSAwOwotICAJCWludCBrVGhlbWVEaXNjbG9zdXJlRG93biA9IDE7Ci0gIAkJaW50IGtUaGVtZURpc2Nsb3N1cmVMZWZ0ID0gMjsKLSAgCQlpbnQga1RoZW1lRGlzY2xvc3VyZUJ1dHRvbiA9IDY7Ci0gIAkJaW50IGtDb250cm9sQmV2ZWxCdXR0b25LaW5kVGFnID0gKCdiJzw8MjQpICsgKCdlJzw8MTYpICsgKCdiJzw8OCkgKyAnayc7Ci0JCWludCBvcmllbnRhdGlvbiA9IGtUaGVtZURpc2Nsb3N1cmVSaWdodDsKLQkJaWYgKChzdHlsZSAmIFNXVC5VUCkgIT0gMCkgb3JpZW50YXRpb24gPSBrVGhlbWVEaXNjbG9zdXJlUmlnaHQ7IC8vIE5FRURTIFdPUksKLQkJaWYgKChzdHlsZSAmIFNXVC5ET1dOKSAhPSAwKSBvcmllbnRhdGlvbiA9IGtUaGVtZURpc2Nsb3N1cmVEb3duOwotCQlpZiAoKHN0eWxlICYgU1dULkxFRlQpICE9IDApIG9yaWVudGF0aW9uID0ga1RoZW1lRGlzY2xvc3VyZUxlZnQ7Ci0JCU9TLlNldENvbnRyb2xEYXRhIChoYW5kbGUsIE9TLmtDb250cm9sRW50aXJlQ29udHJvbCwga0NvbnRyb2xCZXZlbEJ1dHRvbktpbmRUYWcsIG5ldyBzaG9ydCBbXSB7KHNob3J0KShrVGhlbWVEaXNjbG9zdXJlQnV0dG9uKX0pOworCQlpbnQgb3JpZW50YXRpb24gPSBPUy5rVGhlbWVEaXNjbG9zdXJlUmlnaHQ7CisJCWlmICgoc3R5bGUgJiBTV1QuVVApICE9IDApIG9yaWVudGF0aW9uID0gT1Mua1RoZW1lRGlzY2xvc3VyZVJpZ2h0OyAvLyBORUVEUyBXT1JLCisJCWlmICgoc3R5bGUgJiBTV1QuRE9XTikgIT0gMCkgb3JpZW50YXRpb24gPSBPUy5rVGhlbWVEaXNjbG9zdXJlRG93bjsKKwkJaWYgKChzdHlsZSAmIFNXVC5MRUZUKSAhPSAwKSBvcmllbnRhdGlvbiA9IE9TLmtUaGVtZURpc2Nsb3N1cmVMZWZ0OworCQlPUy5DcmVhdGVCZXZlbEJ1dHRvbkNvbnRyb2wod2luZG93LCBudWxsLCAwLCAoc2hvcnQpMCwgKHNob3J0KU9TLmtDb250cm9sQmVoYXZpb3JQdXNoYnV0dG9uLCAwLCAoc2hvcnQpMCwgKHNob3J0KTAsIChzaG9ydCkwLCBvdXRDb250cm9sKTsKKwkJaWYgKG91dENvbnRyb2wgWzBdID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7CisJCWhhbmRsZSA9IG91dENvbnRyb2wgWzBdOworCQlPUy5TZXRDb250cm9sRGF0YSAoaGFuZGxlLCBPUy5rQ29udHJvbEVudGlyZUNvbnRyb2wsIE9TLmtDb250cm9sQmV2ZWxCdXR0b25LaW5kVGFnLCAyLCBuZXcgc2hvcnQgW10geyhzaG9ydCkoT1Mua1RoZW1lRGlzY2xvc3VyZUJ1dHRvbil9KTsKIAkJT1MuU2V0Q29udHJvbDMyQml0TWF4aW11bSAoaGFuZGxlLCAyKTsKIAkJT1MuU2V0Q29udHJvbDMyQml0VmFsdWUgKGhhbmRsZSwgb3JpZW50YXRpb24pOwotICAgICAgICAvKiBBVwotCQlpZiAoKHN0eWxlICYgU1dULkZMQVQpICE9IDApIHsKLQkJCWludCBbXSBhcmdMaXN0MSA9IHtPUy5YbU5zaGFkb3dUaGlja25lc3MsIDF9OwotCQkJT1MuWHRTZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdDEsIGFyZ0xpc3QxLmxlbmd0aCAvIDIpOwotCQl9Ci0gICAgICAgICovCi0JCXJldHVybjsKIAl9Ci0KLQkvKiBDb21wdXRlIGFsaWdubWVudCAqLwotICAgIC8qIEFXCi0JaW50IGFsaWdubWVudCA9IE9TLlhtQUxJR05NRU5UX0JFR0lOTklORzsKLQlpZiAoKHN0eWxlICYgU1dULkNFTlRFUikgIT0gMCkgYWxpZ25tZW50ID0gT1MuWG1BTElHTk1FTlRfQ0VOVEVSOwotCWlmICgoc3R5bGUgJiBTV1QuUklHSFQpICE9IDApIGFsaWdubWVudCA9IE9TLlhtQUxJR05NRU5UX0VORDsKLSAgICAqLwotCi0JLyogVE9HR0xFIGJ1dHRvbiAqLworCQorCWlmICgoc3R5bGUgJiBTV1QuQ0hFQ0spICE9IDApIHsKKwkJLy9PUy5DcmVhdGVDaGVja0JveENvbnRyb2wgKHdpbmRvdywgbnVsbCwgMCwgMCAvKmluaXRpYWxseSBvZmYqLywgdHJ1ZSwgb3V0Q29udHJvbCk7CisJCU9TLkNyZWF0ZUJldmVsQnV0dG9uQ29udHJvbCh3aW5kb3csIG51bGwsIDAsIChzaG9ydCkwLCAoc2hvcnQpT1Mua0NvbnRyb2xCZWhhdmlvclRvZ2dsZXMsIDAsIChzaG9ydCkwLCAoc2hvcnQpMCwgKHNob3J0KTAsIG91dENvbnRyb2wpOworCQlpZiAob3V0Q29udHJvbCBbMF0gPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwkJaGFuZGxlID0gb3V0Q29udHJvbCBbMF07CisJCU9TLlNldENvbnRyb2xEYXRhIChoYW5kbGUsIE9TLmtDb250cm9sRW50aXJlQ29udHJvbCwgT1Mua0NvbnRyb2xCZXZlbEJ1dHRvbktpbmRUYWcsIDIsIG5ldyBzaG9ydCBbXSB7KHNob3J0KU9TLmtUaGVtZUNoZWNrQm94fSk7CisJfQorCQorCWlmICgoc3R5bGUgJiBTV1QuUkFESU8pICE9IDApIHsKKwkJLy9PUy5DcmVhdGVSYWRpb0J1dHRvbkNvbnRyb2wod2luZG93LCBudWxsLCAwLCAwIC8qaW5pdGlhbGx5IG9mZiovLCB0cnVlLCBvdXRDb250cm9sKTsKKwkJT1MuQ3JlYXRlQmV2ZWxCdXR0b25Db250cm9sKHdpbmRvdywgbnVsbCwgMCwgKHNob3J0KTAsIChzaG9ydClPUy5rQ29udHJvbEJlaGF2aW9yVG9nZ2xlcywgMCwgKHNob3J0KTAsIChzaG9ydCkwLCAoc2hvcnQpMCwgb3V0Q29udHJvbCk7CisJCWlmIChvdXRDb250cm9sIFswXSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCQloYW5kbGUgPSBvdXRDb250cm9sIFswXTsKKwkJT1MuU2V0Q29udHJvbERhdGEgKGhhbmRsZSwgT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbEJldmVsQnV0dG9uS2luZFRhZywgMiwgbmV3IHNob3J0IFtdIHsoc2hvcnQpT1Mua1RoZW1lUmFkaW9CdXR0b259KTsKKwl9CisJCiAJaWYgKChzdHlsZSAmIFNXVC5UT0dHTEUpICE9IDApIHsKLQkJLyoKLQkJKiBCdWcgaW4gTW90aWYuICBXaGVuIFhtTmluZGljYXRvck9uIGlzIHNldCB0byBmYWxzZSwKLQkJKiBNb3RpZiBkb2Vzbid0IHJlc2V0IHRoZSBzaGFkb3cgdGhpY2tuZXNzIHRvIGdpdmUgYQotCQkqIHB1c2ggYnV0dG9uIGxvb2suICBUaGUgZml4IGlzIHRvIHNldCB0aGUgc2hhZG93Ci0JCSogdGhpY2tuZXNzIHdoZW4gZXZlciB0aGlzIHJlc291cmNlIGlzIGNoYW5nZWQuCi0JCSovCi0gICAgICAgIC8qIEFXCi0JCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7Ci0JCWludCB0aGlja25lc3MgPSBkaXNwbGF5LmJ1dHRvblNoYWRvd1RoaWNrbmVzczsKLQkJaW50IFtdIGFyZ0xpc3QgPSB7Ci0JCQlPUy5YbU5hbmNlc3RvclNlbnNpdGl2ZSwgMSwKLQkJCU9TLlhtTnJlY29tcHV0ZVNpemUsIDAsCi0JCQlPUy5YbU5pbmRpY2F0b3JPbiwgMCwKLQkJCU9TLlhtTnNoYWRvd1RoaWNrbmVzcywgKHN0eWxlICYgU1dULkZMQVQpICE9IDAgPyAxIDogdGhpY2tuZXNzLAotCQkJT1MuWG1OYWxpZ25tZW50LCBhbGlnbm1lbnQsCi0JCQlPUy5YbU5ib3JkZXJXaWR0aCwgYm9yZGVyV2lkdGgsCi0JCX07Ci0JCWhhbmRsZSA9IE9TLlhtQ3JlYXRlVG9nZ2xlQnV0dG9uIChwYXJlbnRIYW5kbGUsIG51bGwsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0gICAgICAgICovCi0JCWhhbmRsZT0gTWFjVXRpbC5uZXdDb250cm9sKHBhcmVudEhhbmRsZSwgKHNob3J0KTAsIE9TLmtDb250cm9sQmVoYXZpb3JUb2dnbGVzLCAoc2hvcnQpMCwgT1Mua0NvbnRyb2xCZXZlbEJ1dHRvbk5vcm1hbEJldmVsUHJvYyk7Ci0JCWlmIChoYW5kbGUgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKLQkJc2V0Rm9udChkZWZhdWx0Rm9udCgpKTsKLQkJcmV0dXJuOworCQlPUy5DcmVhdGVCZXZlbEJ1dHRvbkNvbnRyb2wod2luZG93LCBudWxsLCAwLCAoc2hvcnQpT1Mua0NvbnRyb2xCZXZlbEJ1dHRvbk5vcm1hbEJldmVsLCAoc2hvcnQpT1Mua0NvbnRyb2xCZWhhdmlvclRvZ2dsZXMsIDAsIChzaG9ydCkwLCAoc2hvcnQpMCwgKHNob3J0KTAsIG91dENvbnRyb2wpOworCQlpZiAob3V0Q29udHJvbCBbMF0gPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwkJaGFuZGxlID0gb3V0Q29udHJvbCBbMF07CisJCWlmICgoc3R5bGUgJiBTV1QuRkxBVCkgPT0gMCApIHsKKwkJCU9TLlNldENvbnRyb2xEYXRhIChoYW5kbGUsIE9TLmtDb250cm9sRW50aXJlQ29udHJvbCwgT1Mua0NvbnRyb2xCZXZlbEJ1dHRvbktpbmRUYWcsIDIsIG5ldyBzaG9ydCBbXSB7KHNob3J0KU9TLmtUaGVtZVJvdW5kZWRCZXZlbEJ1dHRvbn0pOworCQl9CisJfQorCQorCWlmICgoc3R5bGUgJiBTV1QuUFVTSCkgIT0gMCkgeworCQlpZiAoKHN0eWxlICYgU1dULkZMQVQpICE9IDApIHsKKwkJCU9TLkNyZWF0ZUJldmVsQnV0dG9uQ29udHJvbCh3aW5kb3csIG51bGwsIDAsIChzaG9ydCkyLCAoc2hvcnQpT1Mua0NvbnRyb2xCZWhhdmlvclB1c2hidXR0b24sIDAsIChzaG9ydCkwLCAoc2hvcnQpMCwgKHNob3J0KTAsIG91dENvbnRyb2wpOworCQl9IGVsc2UgeworCQkJT1MuQ3JlYXRlUHVzaEJ1dHRvbkNvbnRyb2wgKHdpbmRvdywgbnVsbCwgMCwgb3V0Q29udHJvbCk7CisJCQkvL09TLkNyZWF0ZUJldmVsQnV0dG9uQ29udHJvbCh3aW5kb3csIG51bGwsIDAsIChzaG9ydCkyLCAoc2hvcnQpT1Mua0NvbnRyb2xCZWhhdmlvclB1c2hidXR0b24sIDAsIChzaG9ydCkwLCAoc2hvcnQpMCwgKHNob3J0KTAsIG91dENvbnRyb2wpOworCQl9CisJCWlmIChvdXRDb250cm9sIFswXSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCQloYW5kbGUgPSBvdXRDb250cm9sIFswXTsKKwkJaWYgKChzdHlsZSAmIFNXVC5GTEFUKSA9PSAwICkgeworCQkJT1MuU2V0Q29udHJvbERhdGEgKGhhbmRsZSwgT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbEJldmVsQnV0dG9uS2luZFRhZywgMiwgbmV3IHNob3J0IFtdIHsoc2hvcnQpT1Mua1RoZW1lUHVzaEJ1dHRvbn0pOworCQl9CiAJfQogCi0JLyogQ0hFQ0sgb3IgUkFESU8gYnV0dG9uICovCi0JaWYgKChzdHlsZSAmIChTV1QuQ0hFQ0sgfCBTV1QuUkFESU8pKSAhPSAwKSB7Ci0JCS8qCi0JCSogQnVnIGluIE1vdGlmLiAgRm9yIHNvbWUgcmVhc29uLCBhIHRvZ2dsZSBidXR0b24KLQkJKiB3aXRoIFhtTmluZGljYXRvclR5cGUgWG1PTkVfT0ZfTUFOWSBtdXN0IGhhdmUgdGhpcwotCQkqIHZhbHVlIHNldCBhdCBjcmVhdGlvbiBvciB0aGUgaGlnaGxpZ2h0IGNvbG9yIHdpbGwKLQkJKiBub3QgYmUgY29ycmVjdC4gIFRoZSBmaXggaXMgdG8gc2V0IHRoZXNlIHZhbHVlcwotCQkqIG9uIGNyZWF0ZS4KLQkJKi8KLSAgICAgICAgLyogQVcKLQkJaW50IGluZGljYXRvclR5cGUgPSBPUy5YbU9ORV9PRl9NQU5ZOwotCQlpZiAoKHN0eWxlICYgU1dULkNIRUNLKSAhPSAwKSBpbmRpY2F0b3JUeXBlID0gT1MuWG1OX09GX01BTlk7Ci0JCWludCBbXSBhcmdMaXN0ID0gewotCQkJT1MuWG1OYW5jZXN0b3JTZW5zaXRpdmUsIDEsCi0JCQlPUy5YbU5yZWNvbXB1dGVTaXplLCAwLAotCQkJT1MuWG1OaW5kaWNhdG9yVHlwZSwgaW5kaWNhdG9yVHlwZSwKLQkJCU9TLlhtTmFsaWdubWVudCwgYWxpZ25tZW50LAotCQkJT1MuWG1OYm9yZGVyV2lkdGgsIGJvcmRlcldpZHRoLAotCQl9OwotCQloYW5kbGUgPSBPUy5YbUNyZWF0ZVRvZ2dsZUJ1dHRvbiAocGFyZW50SGFuZGxlLCBudWxsLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotICAgICAgICAqLwotCQlzaG9ydCB0eXBlPSAoc3R5bGUgJiBTV1QuQ0hFQ0spICE9IDAKLQkJCQkJPyBPUy5rQ29udHJvbENoZWNrQm94QXV0b1RvZ2dsZVByb2MKLQkJCQkJOiBPUy5rQ29udHJvbFJhZGlvQnV0dG9uQXV0b1RvZ2dsZVByb2M7Ci0JCWhhbmRsZT0gTWFjVXRpbC5uZXdDb250cm9sKHBhcmVudEhhbmRsZSwgKHNob3J0KTAsIChzaG9ydCkwLCAoc2hvcnQpMTAwLCB0eXBlKTsKLQkJaWYgKGhhbmRsZSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOwotCQlzZXRGb250KGRlZmF1bHRGb250KCkpOwotCQlyZXR1cm47CisJQ29udHJvbEZvbnRTdHlsZVJlYyBmb250UmVjID0gbmV3IENvbnRyb2xGb250U3R5bGVSZWMoKTsKKwlmb250UmVjLmZsYWdzID0gKHNob3J0KSBPUy5rQ29udHJvbFVzZVRoZW1lRm9udElETWFzazsKKwlmb250UmVjLmZvbnQgPSAoc2hvcnQpIGRlZmF1bHRUaGVtZUZvbnQgKCk7CisJT1MuU2V0Q29udHJvbEZvbnRTdHlsZSAoaGFuZGxlLCBmb250UmVjKTsKKwkKKwlpZiAoKHN0eWxlICYgKFNXVC5MRUZUIHwgU1dULlJJR0hUIHwgU1dULkNFTlRFUikpICE9IDApIHsKKwkJaW50IHRleHRBbGlnbm1lbnQgPSAwOworCQlpbnQgZ3JhcGhpY0FsaWdubWVudCA9IDA7CisJCWlmICgoc3R5bGUgJiBTV1QuTEVGVCkgIT0gMCkgeworCQkJdGV4dEFsaWdubWVudCA9IE9TLmtDb250cm9sQmV2ZWxCdXR0b25BbGlnblRleHRGbHVzaExlZnQ7CisJCQlncmFwaGljQWxpZ25tZW50ID0gT1Mua0NvbnRyb2xCZXZlbEJ1dHRvbkFsaWduTGVmdDsKKwkJfQorCQlpZiAoKHN0eWxlICYgU1dULkNFTlRFUikgIT0gMCkgeworCQkJdGV4dEFsaWdubWVudCA9IE9TLmtDb250cm9sQmV2ZWxCdXR0b25BbGlnblRleHRDZW50ZXI7CisJCQlncmFwaGljQWxpZ25tZW50ID0gT1Mua0NvbnRyb2xCZXZlbEJ1dHRvbkFsaWduQ2VudGVyOworCQl9CisJCWlmICgoc3R5bGUgJiBTV1QuUklHSFQpICE9IDApIHsKKwkJCXRleHRBbGlnbm1lbnQgPSBPUy5rQ29udHJvbEJldmVsQnV0dG9uQWxpZ25UZXh0Rmx1c2hSaWdodDsKKwkJCWdyYXBoaWNBbGlnbm1lbnQgPSBPUy5rQ29udHJvbEJldmVsQnV0dG9uQWxpZ25SaWdodDsKKwkJfQorCQlPUy5TZXRDb250cm9sRGF0YSAoaGFuZGxlLCBPUy5rQ29udHJvbEVudGlyZUNvbnRyb2wsIE9TLmtDb250cm9sQmV2ZWxCdXR0b25UZXh0QWxpZ25UYWcsIDIsIG5ldyBzaG9ydCBbXSB7KHNob3J0KXRleHRBbGlnbm1lbnR9KTsKKwkJT1MuU2V0Q29udHJvbERhdGEgKGhhbmRsZSwgT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbEJldmVsQnV0dG9uR3JhcGhpY0FsaWduVGFnLCAyLCBuZXcgc2hvcnQgW10geyhzaG9ydClncmFwaGljQWxpZ25tZW50fSk7CiAJfQorfQogCi0JLyogUFVTSCBidXR0b24gKi8KLSAgICAvKiBBVwotCWludCBbXSBhcmdMaXN0ID0gewotCQlPUy5YbU5hbmNlc3RvclNlbnNpdGl2ZSwgMSwKLQkJT1MuWG1OcmVjb21wdXRlU2l6ZSwgMCwKLQkJT1MuWG1OYWxpZ25tZW50LCBhbGlnbm1lbnQsCi0JCU9TLlhtTmJvcmRlcldpZHRoLCBib3JkZXJXaWR0aCwKLSAgICAqLwotCXNob3J0IHR5cGU9IChzdHlsZSAmIFNXVC5GTEFUKSAhPSAwCi0JCQkJCT8gT1Mua0NvbnRyb2xCZXZlbEJ1dHRvbk5vcm1hbEJldmVsUHJvYwotCQkJCQk6IE9TLmtDb250cm9sUHVzaEJ1dHRvblByb2M7Ci0gICAgaGFuZGxlPSBNYWNVdGlsLm5ld0NvbnRyb2wocGFyZW50SGFuZGxlLCB0eXBlKTsKLQlpZiAoaGFuZGxlID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0Jc2V0Rm9udChkZWZhdWx0Rm9udCgpKTsKLQkvKiBBVwotCWlmICgoc3R5bGUgJiBTV1QuRkxBVCkgIT0gMCkgewotCQlpbnQgW10gYXJnTGlzdDEgPSB7T1MuWG1Oc2hhZG93VGhpY2tuZXNzLCAxfTsKLQkJT1MuWHRTZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdDEsIGFyZ0xpc3QxLmxlbmd0aCAvIDIpOwotCX0KLQkqLworaW50IGRlZmF1bHRUaGVtZUZvbnQgKCkgewkKKwlyZXR1cm4gT1Mua1RoZW1lUHVzaEJ1dHRvbkZvbnQ7CiB9Ci1pbnQgZGVmYXVsdEJhY2tncm91bmQgKCkgewotCXJldHVybiBnZXREaXNwbGF5ICgpLmJ1dHRvbkJhY2tncm91bmQ7Ci19Ci1Gb250IGRlZmF1bHRGb250ICgpIHsKLQlyZXR1cm4gZ2V0RGlzcGxheSAoKS5idXR0b25Gb250OwotfQotaW50IGRlZmF1bHRGb3JlZ3JvdW5kICgpIHsKLQlyZXR1cm4gZ2V0RGlzcGxheSAoKS5idXR0b25Gb3JlZ3JvdW5kOwotfQotLyoqCi0gKiBSZXR1cm5zIGEgdmFsdWUgd2hpY2ggZGVzY3JpYmVzIHRoZSBwb3NpdGlvbiBvZiB0aGUKLSAqIHRleHQgb3IgaW1hZ2UgaW4gdGhlIHJlY2VpdmVyLiBUaGUgdmFsdWUgd2lsbCBiZSBvbmUgb2YKLSAqIDxjb2RlPkxFRlQ8L2NvZGU+LCA8Y29kZT5SSUdIVDwvY29kZT4gb3IgPGNvZGU+Q0VOVEVSPC9jb2RlPgotICogdW5sZXNzIHRoZSByZWNlaXZlciBpcyBhbiA8Y29kZT5BUlJPVzwvY29kZT4gYnV0dG9uLCBpbiAKLSAqIHdoaWNoIGNhc2UsIHRoZSBhbGlnbm1lbnQgd2lsbCBpbmRpY2F0ZSB0aGUgZGlyZWN0aW9uIG9mCi0gKiB0aGUgYXJyb3cgKG9uZSBvZiA8Y29kZT5MRUZUPC9jb2RlPiwgPGNvZGU+UklHSFQ8L2NvZGU+LCAKLSAqIDxjb2RlPlVQPC9jb2RlPiBvciA8Y29kZT5ET1dOPC9jb2RlPikuCi0gKgotICogQHJldHVybiB0aGUgYWxpZ25tZW50IAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldEFsaWdubWVudCAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLSAgICByZXR1cm4gZkFsaWdubWVudDsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAoKHN0eWxlICYgU1dULkFSUk9XKSAhPSAwKSB7CisJCWlmICgoc3R5bGUgJiBTV1QuVVApICE9IDApIHJldHVybiBTV1QuVVA7CisJCWlmICgoc3R5bGUgJiBTV1QuRE9XTikgIT0gMCkgcmV0dXJuIFNXVC5ET1dOOworCQlpZiAoKHN0eWxlICYgU1dULkxFRlQpICE9IDApIHJldHVybiBTV1QuTEVGVDsKKwkJaWYgKChzdHlsZSAmIFNXVC5SSUdIVCkgIT0gMCkgcmV0dXJuIFNXVC5SSUdIVDsKKwkJcmV0dXJuIFNXVC5VUDsKKwl9CisJaWYgKChzdHlsZSAmIFNXVC5MRUZUKSAhPSAwKSByZXR1cm4gU1dULkxFRlQ7CisJaWYgKChzdHlsZSAmIFNXVC5DRU5URVIpICE9IDApIHJldHVybiBTV1QuQ0VOVEVSOworCWlmICgoc3R5bGUgJiBTV1QuUklHSFQpICE9IDApIHJldHVybiBTV1QuUklHSFQ7CisJcmV0dXJuIFNXVC5MRUZUOwogfQotYm9vbGVhbiBnZXREZWZhdWx0ICgpIHsKLQlpZiAoKHN0eWxlICYgU1dULlBVU0gpID09IDApIHJldHVybiBmYWxzZTsKLSAgICBpbnRbXSBjb250cm9sPSBuZXcgaW50WzFdOwotCU9TLkdldFdpbmRvd0RlZmF1bHRCdXR0b24oT1MuR2V0Q29udHJvbE93bmVyKGhhbmRsZSksIGNvbnRyb2wpOwotCXJldHVybiBjb250cm9sWzBdID09IGhhbmRsZTsKLX0KLS8qKgotICogUmV0dXJucyB0aGUgcmVjZWl2ZXIncyBpbWFnZSBpZiBpdCBoYXMgb25lLCBvciBudWxsCi0gKiBpZiBpdCBkb2VzIG5vdC4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGltYWdlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBJbWFnZSBnZXRJbWFnZSAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlyZXR1cm4gaW1hZ2U7CkBAIC0zOTUsMTI4ICsyMzksNzMgQEAKIFN0cmluZyBnZXROYW1lVGV4dCAoKSB7CiAJcmV0dXJuIGdldFRleHQgKCk7CiB9Ci0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGlzIHNlbGVjdGVkLAotICogYW5kIGZhbHNlIG90aGVyd2lzZS4KLSAqIDxwPgotICogV2hlbiB0aGUgcmVjZWl2ZXIgaXMgb2YgdHlwZSA8Y29kZT5DSEVDSzwvY29kZT4gb3IgPGNvZGU+UkFESU88L2NvZGU+LAotICogaXQgaXMgc2VsZWN0ZWQgd2hlbiBpdCBpcyBjaGVja2VkLiBXaGVuIGl0IGlzIG9mIHR5cGUgPGNvZGU+VE9HR0xFPC9jb2RlPiwKLSAqIGl0IGlzIHNlbGVjdGVkIHdoZW4gaXQgaXMgcHVzaGVkIGluLiBJZiB0aGUgcmVjZWl2ZXIgaXMgb2YgYW55IG90aGVyIHR5cGUsCi0gKiB0aGlzIG1ldGhvZCByZXR1cm5zIGZhbHNlLgotICoKLSAqIEByZXR1cm4gdGhlIHNlbGVjdGlvbiBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgYm9vbGVhbiBnZXRTZWxlY3Rpb24gKCkgewotCWNoZWNrV2lkZ2V0KCk7CisJY2hlY2tXaWRnZXQgKCk7CiAJaWYgKChzdHlsZSAmIChTV1QuQ0hFQ0sgfCBTV1QuUkFESU8gfCBTV1QuVE9HR0xFKSkgPT0gMCkgcmV0dXJuIGZhbHNlOwogICAgIHJldHVybiBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUpICE9IDA7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3MgdGV4dCwgd2hpY2ggd2lsbCBiZSBhbiBlbXB0eQotICogc3RyaW5nIGlmIGl0IGhhcyBuZXZlciBiZWVuIHNldC4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIHRleHQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIFN0cmluZyBnZXRUZXh0ICgpIHsKLQljaGVja1dpZGdldCgpOwotCWlmICgoc3R5bGUgJiBTV1QuQVJST1cpICE9IDApIHJldHVybiAiIjsKLQlpbnQgc0hhbmRsZVtdPSBuZXcgaW50WzFdOwotICAgIE9TLkdldENvbnRyb2xUaXRsZUFzQ0ZTdHJpbmcoaGFuZGxlLCBzSGFuZGxlKTsKLQlyZXR1cm4gTWFjVXRpbC5nZXRTdHJpbmdBbmRSZWxlYXNlKHNIYW5kbGVbMF0pOworCWNoZWNrV2lkZ2V0ICgpOworCXJldHVybiB0ZXh0OwogfQotdm9pZCBob29rRXZlbnRzICgpIHsKLQlzdXBlci5ob29rRXZlbnRzICgpOwotCS8qIEFXCi0JaW50IGNhbGxiYWNrID0gT1MuWG1OYWN0aXZhdGVDYWxsYmFjazsKLQlpbnQgd2luZG93UHJvYyA9IGdldERpc3BsYXkgKCkud2luZG93UHJvYzsKLQlpZiAoKHN0eWxlICYgKFNXVC5DSEVDSyB8IFNXVC5SQURJTyB8IFNXVC5UT0dHTEUpKSAhPSAwKSBjYWxsYmFjayA9IE9TLlhtTnZhbHVlQ2hhbmdlZENhbGxiYWNrOwotCU9TLlh0QWRkQ2FsbGJhY2sgKGhhbmRsZSwgY2FsbGJhY2ssIHdpbmRvd1Byb2MsIFNXVC5TZWxlY3Rpb24pOwotCSovCi0JaWYgKE1hY1V0aWwuSElWSUVXKSB7Ci0JCURpc3BsYXkgZGlzcGxheT0gZ2V0RGlzcGxheSgpOwotCQlPUy5TZXRDb250cm9sQWN0aW9uKGhhbmRsZSwgZGlzcGxheS5mQ29udHJvbEFjdGlvblByb2MpOworCitSZWN0IGdldEluc2V0ICgpIHsKKwlpZiAoKHN0eWxlICYgU1dULlBVU0gpID09IDApIHJldHVybiBzdXBlci5nZXRJbnNldCgpOworCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisJcmV0dXJuIGRpc3BsYXkuYnV0dG9uSW5zZXQ7Cit9CisKK2ludCBrRXZlbnRDb250cm9sRHJhdyAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWludCByZXN1bHQgPSBzdXBlci5rRXZlbnRDb250cm9sRHJhdyAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKGlzSW1hZ2UgJiYgaW1hZ2UgIT0gbnVsbCAmJiAoc3R5bGUgJiBTV1QuUFVTSCkgIT0gMCAmJiAoc3R5bGUgJiBTV1QuRkxBVCkgPT0gMCkgeworCQlSZWN0IHJlY3QgPSBuZXcgUmVjdCgpOworCQlPUy5HZXRDb250cm9sQm91bmRzIChoYW5kbGUsIHJlY3QpOworCQlpbnQgd2lkdGggPSBPUy5DR0ltYWdlR2V0V2lkdGggKGltYWdlLmhhbmRsZSk7CisJCWludCBoZWlnaHQgPSBPUy5DR0ltYWdlR2V0SGVpZ2h0IChpbWFnZS5oYW5kbGUpOworCQlpbnQgeCA9IE1hdGgubWF4ICgwLCAocmVjdC5yaWdodCAtIHJlY3QubGVmdCAtIHdpZHRoKSAvIDIpOworCQlpbnQgeSA9IE1hdGgubWF4ICgwLCAocmVjdC5ib3R0b20gLSByZWN0LnRvcCAtIGhlaWdodCkgLyAyKTsKKwkJR0NEYXRhIGRhdGEgPSBuZXcgR0NEYXRhICgpOworCQlkYXRhLnBhaW50RXZlbnQgPSB0aGVFdmVudDsKKwkJR0MgZ2MgPSBHQy5jYXJib25fbmV3ICh0aGlzLCBkYXRhKTsKKwkJZ2MuZHJhd0ltYWdlIChpbWFnZSwgeCwgeSk7CisJCWdjLmRpc3Bvc2UgKCk7CisJCXJldHVybiBPUy5ub0VycjsKIAl9CisJcmV0dXJuIHJlc3VsdDsKIH0KLWJvb2xlYW4gbW5lbW9uaWNIaXQgKGNoYXIga2V5KSB7Ci0JaWYgKCFzZXRGb2N1cyAoKSkgcmV0dXJuIGZhbHNlOwotCWNsaWNrICgpOwotCXJldHVybiB0cnVlOwotfQotLyogQVcKLWJvb2xlYW4gbW5lbW9uaWNNYXRjaCAoY2hhciBrZXkpIHsKLQljaGFyIG1uZW1vbmljID0gZmluZE1uZW1vbmljIChnZXRUZXh0ICgpKTsKLQlpZiAobW5lbW9uaWMgPT0gJ1wwJykgcmV0dXJuIGZhbHNlOwotCXJldHVybiBDaGFyYWN0ZXIudG9VcHBlckNhc2UgKGtleSkgPT0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlIChtbmVtb25pYyk7Ci19Ci0qLwotaW50IHByb2Nlc3NGb2N1c0luICgpIHsKLQlzdXBlci5wcm9jZXNzRm9jdXNJbiAoKTsKLQkvLyB3aWRnZXQgY291bGQgYmUgZGlzcG9zZWQgYXQgdGhpcyBwb2ludAotCWlmIChoYW5kbGUgPT0gMCkgcmV0dXJuIDA7Ci0JaWYgKChzdHlsZSAmIFNXVC5QVVNIKSA9PSAwKSByZXR1cm4gMDsKLQlnZXRTaGVsbCAoKS5zZXREZWZhdWx0QnV0dG9uICh0aGlzLCBmYWxzZSk7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc0ZvY3VzT3V0ICgpIHsKLQlzdXBlci5wcm9jZXNzRm9jdXNPdXQgKCk7Ci0JLy8gd2lkZ2V0IGNvdWxkIGJlIGRpc3Bvc2VkIGF0IHRoaXMgcG9pbnQKLQlpZiAoaGFuZGxlID09IDApIHJldHVybiAwOwotCWlmICgoc3R5bGUgJiBTV1QuUFVTSCkgPT0gMCkgcmV0dXJuIDA7Ci0JaWYgKGdldERlZmF1bHQgKCkpIHsKLQkJZ2V0U2hlbGwgKCkuc2V0RGVmYXVsdEJ1dHRvbiAobnVsbCwgZmFsc2UpOwotCX0KLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzU2VsZWN0aW9uIChPYmplY3QgY2FsbERhdGEpIHsKKworaW50IGtFdmVudENvbnRyb2xIaXQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpbnQgcmVzdWx0ID0gc3VwZXIua0V2ZW50Q29udHJvbEhpdCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKHJlc3VsdCA9PSBPUy5ub0VycikgcmV0dXJuIHJlc3VsdDsKIAlpZiAoKHN0eWxlICYgU1dULlJBRElPKSAhPSAwKSB7Ci0JCWlmICgocGFyZW50LmdldFN0eWxlICgpICYgU1dULk5PX1JBRElPX0dST1VQKSA9PSAwKSBzZWxlY3RSYWRpbyAoKTsKKwkJaWYgKChwYXJlbnQuZ2V0U3R5bGUgKCkgJiBTV1QuTk9fUkFESU9fR1JPVVApID09IDApIHsKKwkJCXNlbGVjdFJhZGlvICgpOworCQl9CiAJfQotCXJldHVybiBzdXBlci5wcm9jZXNzU2VsZWN0aW9uIChjYWxsRGF0YSk7CisJcG9zdEV2ZW50IChTV1QuU2VsZWN0aW9uKTsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOwogfQorCitpbnQga0V2ZW50Q29udHJvbFNldEZvY3VzUGFydCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWludCByZXN1bHQgPSBzdXBlci5rRXZlbnRDb250cm9sU2V0Rm9jdXNQYXJ0IChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwlpZiAoKHN0eWxlICYgU1dULlBVU0gpICE9IDApIHsKKwkJc2hvcnQgW10gcGFydCA9IG5ldyBzaG9ydCBbMV07CisJCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1Db250cm9sUGFydCwgT1MudHlwZUNvbnRyb2xQYXJ0Q29kZSwgbnVsbCwgMiwgbnVsbCwgcGFydCk7CisJCW1lbnVTaGVsbCAoKS5zZXREZWZhdWx0QnV0dG9uICgocGFydCBbMF0gIT0gMCkgPyB0aGlzIDogbnVsbCwgZmFsc2UpOwkKKwl9CisJcmV0dXJuIHJlc3VsdDsKK30KKwogdm9pZCByZWxlYXNlV2lkZ2V0ICgpIHsKIAlzdXBlci5yZWxlYXNlV2lkZ2V0ICgpOwotICAgIC8qCi0JaW50IFtdIGFyZ0xpc3QgPSB7Ci0JCU9TLlhtTmxhYmVsUGl4bWFwLCBPUy5YbVVOU1BFQ0lGSUVEX1BJWE1BUCwKLQkJT1MuWG1ObGFiZWxJbnNlbnNpdGl2ZVBpeG1hcCwgT1MuWG1VTlNQRUNJRklFRF9QSVhNQVAsCi0JfTsKLQlPUy5YdFNldFZhbHVlcyAoaGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotICAgICovCi0gICAgaWYgKGZDSWNvbkhhbmRsZSAhPSAwKSB7Ci0gICAgCWlmIChoYW5kbGUgIT0gMCkKLSAgICAJCU9TLlNldEJldmVsQnV0dG9uQ29udGVudEluZm8oaGFuZGxlLCAoc2hvcnQpMCwgMCk7Ci0JCUltYWdlLmRpc3Bvc2VDSWNvbihmQ0ljb25IYW5kbGUpOwotCQlmQ0ljb25IYW5kbGU9IDA7Ci0gICAgfQotCWltYWdlID0gbnVsbDsKKwlpZiAoY0ljb24gIT0gMCkgeworCQlkZXN0cm95Q0ljb24gKGNJY29uKTsKKwkJY0ljb24gPSAwOworCX0KIH0KLS8qKgotICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGNvbnRyb2wgaXMgc2VsZWN0ZWQuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTZWxlY3Rpb25MaXN0ZW5lcgotICogQHNlZSAjYWRkU2VsZWN0aW9uTGlzdGVuZXIKLSAqLworCiBwdWJsaWMgdm9pZCByZW1vdmVTZWxlY3Rpb25MaXN0ZW5lcihTZWxlY3Rpb25MaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC01MjQsMjE3ICszMTMsMTU4IEBACiAJZXZlbnRUYWJsZS51bmhvb2soU1dULlNlbGVjdGlvbiwgbGlzdGVuZXIpOwogCWV2ZW50VGFibGUudW5ob29rKFNXVC5EZWZhdWx0U2VsZWN0aW9uLGxpc3RlbmVyKTsKIH0KKwogdm9pZCBzZWxlY3RSYWRpbyAoKSB7CisJLyoKKwkqIFRoaXMgY29kZSBpcyBpbnRlbnRpb25hbGx5IGNvbW1lbnRlZC4gIFdoZW4gdHdvIGdyb3VwcworCSogb2YgcmFkaW8gYnV0dG9ucyB3aXRoIHRoZSBzYW1lIHBhcmVudCBhcmUgc2VwYXJhdGVkIGJ5CisJKiBhbm90aGVyIGNvbnRyb2wsIHRoZSBjb3JyZWN0IGJlaGF2aW9yIHNob3VsZCBiZSB0aGF0CisJKiB0aGUgdHdvIGdyb3VwcyBhY3QgaW5kZXBlbmRlbnRseS4gIFRoaXMgaXMgY29uc2lzdGVudAorCSogd2l0aCByYWRpbyB0b29sIGFuZCBtZW51IGl0ZW1zLiAgVGhlIGNvbW1lbnRlZCBjb2RlCisJKiBpbXBsZW1lbnRzIHRoaXMgYmVoYXZpb3IuCisJKi8KKy8vCWludCBpbmRleCA9IDA7CisvLwlDb250cm9sIFtdIGNoaWxkcmVuID0gcGFyZW50Ll9nZXRDaGlsZHJlbiAoKTsKKy8vCXdoaWxlIChpbmRleCA8IGNoaWxkcmVuLmxlbmd0aCAmJiBjaGlsZHJlbiBbaW5kZXhdICE9IHRoaXMpIGluZGV4Kys7CisvLwlpbnQgaSA9IGluZGV4IC0gMTsKKy8vCXdoaWxlIChpID49IDAgJiYgY2hpbGRyZW4gW2ldLnNldFJhZGlvU2VsZWN0aW9uIChmYWxzZSkpIC0taTsKKy8vCWludCBqID0gaW5kZXggKyAxOworLy8Jd2hpbGUgKGogPCBjaGlsZHJlbi5sZW5ndGggJiYgY2hpbGRyZW4gW2pdLnNldFJhZGlvU2VsZWN0aW9uIChmYWxzZSkpIGorKzsKKy8vCXNldFNlbGVjdGlvbiAodHJ1ZSk7CiAJQ29udHJvbCBbXSBjaGlsZHJlbiA9IHBhcmVudC5fZ2V0Q2hpbGRyZW4gKCk7CiAJZm9yIChpbnQgaT0wOyBpPGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAJCUNvbnRyb2wgY2hpbGQgPSBjaGlsZHJlbiBbaV07Ci0JCWlmICh0aGlzICE9IGNoaWxkICYmIGNoaWxkIGluc3RhbmNlb2YgQnV0dG9uKSB7Ci0JCQlCdXR0b24gYnV0dG9uID0gKEJ1dHRvbikgY2hpbGQ7Ci0JCQlpZiAoKGJ1dHRvbi5nZXRTdHlsZSAoKSAmIFNXVC5SQURJTykgIT0gMCkgewotCQkJCWlmIChidXR0b24uZ2V0U2VsZWN0aW9uICgpKSB7Ci0JCQkJCWJ1dHRvbi5zZXRTZWxlY3Rpb24gKGZhbHNlKTsKLQkJCQkJYnV0dG9uLnBvc3RFdmVudCAoU1dULlNlbGVjdGlvbik7Ci0JCQkJfQotCQkJfQotCQl9CisJCWlmICh0aGlzICE9IGNoaWxkKSBjaGlsZC5zZXRSYWRpb1NlbGVjdGlvbiAoZmFsc2UpOwogCX0KIAlzZXRTZWxlY3Rpb24gKHRydWUpOwogfQotLyoqCi0gKiBDb250cm9scyBob3cgdGV4dCwgaW1hZ2VzIGFuZCBhcnJvd3Mgd2lsbCBiZSBkaXNwbGF5ZWQKLSAqIGluIHRoZSByZWNlaXZlci4gVGhlIGFyZ3VtZW50IHNob3VsZCBiZSBvbmUgb2YKLSAqIDxjb2RlPkxFRlQ8L2NvZGU+LCA8Y29kZT5SSUdIVDwvY29kZT4gb3IgPGNvZGU+Q0VOVEVSPC9jb2RlPgotICogdW5sZXNzIHRoZSByZWNlaXZlciBpcyBhbiA8Y29kZT5BUlJPVzwvY29kZT4gYnV0dG9uLCBpbiAKLSAqIHdoaWNoIGNhc2UsIHRoZSBhcmd1bWVudCBpbmRpY2F0ZXMgdGhlIGRpcmVjdGlvbiBvZgotICogdGhlIGFycm93IChvbmUgb2YgPGNvZGU+TEVGVDwvY29kZT4sIDxjb2RlPlJJR0hUPC9jb2RlPiwgCi0gKiA8Y29kZT5VUDwvY29kZT4gb3IgPGNvZGU+RE9XTjwvY29kZT4pLgotICoKLSAqIEBwYXJhbSBhbGlnbm1lbnQgdGhlIG5ldyBhbGlnbm1lbnQgCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldEFsaWdubWVudCAoaW50IGFsaWdubWVudCkgewotCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKChzdHlsZSAmIFNXVC5BUlJPVykgIT0gMCkgewotCQlmQWxpZ25tZW50PSBhbGlnbm1lbnQ7Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigiQnV0dG9uLnNldEFsaWdubWVudDogbnlpIik7CisJCWlmICgoc3R5bGUgJiAoU1dULlVQIHwgU1dULkRPV04gfCBTV1QuTEVGVCB8IFNXVC5SSUdIVCkpID09IDApIHJldHVybjsgCisJCXN0eWxlICY9IH4oU1dULlVQIHwgU1dULkRPV04gfCBTV1QuTEVGVCB8IFNXVC5SSUdIVCk7CisJCXN0eWxlIHw9IGFsaWdubWVudCAmIChTV1QuVVAgfCBTV1QuRE9XTiB8IFNXVC5MRUZUIHwgU1dULlJJR0hUKTsKKwkJaW50IG9yaWVudGF0aW9uID0gT1Mua1RoZW1lRGlzY2xvc3VyZVJpZ2h0OworCQlpZiAoKHN0eWxlICYgU1dULlVQKSAhPSAwKSBvcmllbnRhdGlvbiA9IE9TLmtUaGVtZURpc2Nsb3N1cmVSaWdodDsgLy8gTkVFRFMgV09SSworCQlpZiAoKHN0eWxlICYgU1dULkRPV04pICE9IDApIG9yaWVudGF0aW9uID0gT1Mua1RoZW1lRGlzY2xvc3VyZURvd247CisJCWlmICgoc3R5bGUgJiBTV1QuTEVGVCkgIT0gMCkgb3JpZW50YXRpb24gPSBPUy5rVGhlbWVEaXNjbG9zdXJlTGVmdDsKKwkJT1MuU2V0Q29udHJvbDMyQml0VmFsdWUgKGhhbmRsZSwgb3JpZW50YXRpb24pOwogCQlyZXR1cm47CiAJfQogCWlmICgoYWxpZ25tZW50ICYgKFNXVC5MRUZUIHwgU1dULlJJR0hUIHwgU1dULkNFTlRFUikpID09IDApIHJldHVybjsKLQlmQWxpZ25tZW50PSBhbGlnbm1lbnQ7Ci0JU3lzdGVtLm91dC5wcmludGxuKCJCdXR0b24uc2V0QWxpZ25tZW50OiBueWkiKTsKKwlzdHlsZSAmPSB+KFNXVC5MRUZUIHwgU1dULlJJR0hUIHwgU1dULkNFTlRFUik7CisJc3R5bGUgfD0gYWxpZ25tZW50ICYgKFNXVC5MRUZUIHwgU1dULlJJR0hUIHwgU1dULkNFTlRFUik7CisJaW50IHRleHRBbGlnbm1lbnQgPSAwOworCWludCBncmFwaGljQWxpZ25tZW50ID0gMDsKKwlpZiAoKHN0eWxlICYgU1dULkxFRlQpICE9IDApIHsKKwkJdGV4dEFsaWdubWVudCA9IE9TLmtDb250cm9sQmV2ZWxCdXR0b25BbGlnblRleHRGbHVzaExlZnQ7CisJCWdyYXBoaWNBbGlnbm1lbnQgPSBPUy5rQ29udHJvbEJldmVsQnV0dG9uQWxpZ25MZWZ0OworCX0KKwlpZiAoKHN0eWxlICYgU1dULkNFTlRFUikgIT0gMCkgeworCQl0ZXh0QWxpZ25tZW50ID0gT1Mua0NvbnRyb2xCZXZlbEJ1dHRvbkFsaWduVGV4dENlbnRlcjsKKwkJZ3JhcGhpY0FsaWdubWVudCA9IE9TLmtDb250cm9sQmV2ZWxCdXR0b25BbGlnbkNlbnRlcjsKKwl9CisJaWYgKChzdHlsZSAmIFNXVC5SSUdIVCkgIT0gMCkgeworCQl0ZXh0QWxpZ25tZW50ID0gT1Mua0NvbnRyb2xCZXZlbEJ1dHRvbkFsaWduVGV4dEZsdXNoUmlnaHQ7CisJCWdyYXBoaWNBbGlnbm1lbnQgPSBPUy5rQ29udHJvbEJldmVsQnV0dG9uQWxpZ25SaWdodDsKKwl9CisJT1MuU2V0Q29udHJvbERhdGEgKGhhbmRsZSwgT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbEJldmVsQnV0dG9uVGV4dEFsaWduVGFnLCAyLCBuZXcgc2hvcnQgW10geyhzaG9ydCl0ZXh0QWxpZ25tZW50fSk7CisJT1MuU2V0Q29udHJvbERhdGEgKGhhbmRsZSwgT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbEJldmVsQnV0dG9uR3JhcGhpY0FsaWduVGFnLCAyLCBuZXcgc2hvcnQgW10geyhzaG9ydClncmFwaGljQWxpZ25tZW50fSk7CisJcmVkcmF3ICgpOwogfQorCitwdWJsaWMgdm9pZCBzZXRCb3VuZHMgKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisJY2hlY2tXaWRnZXQgKCk7CisJLyogQnVnIGluIE1hY09TIFguIFdoZW4gc2V0dGluZyB0aGUgaGVpZ2h0IG9mIGEgYmV2ZWwgYnV0dG9uIAorCSAqIHRvIGEgdmFsdWUgbGVzcyB0aGFuIDIwLCB0aGUgYnV0dG9uIGlzIGRyYXduIGluY29ycmVjdGx5LgorCSAqIFRoZSBmaXggaXMgdG8gZm9yY2UgdGhlIGhlaWdodCB0byBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMjAuCisJICovCisJaWYgKChzdHlsZSAmIFNXVC5BUlJPVykgPT0gMCkgeworCQloZWlnaHQgPSBNYXRoLm1heCAoMjAsIGhlaWdodCk7CisJfQorCXN1cGVyLnNldEJvdW5kcyAoeCwgeSwgd2lkdGgsIGhlaWdodCk7Cit9CisKIHZvaWQgc2V0RGVmYXVsdCAoYm9vbGVhbiB2YWx1ZSkgewogCWlmICgoc3R5bGUgJiBTV1QuUFVTSCkgPT0gMCkgcmV0dXJuOwotCWlmIChnZXRTaGVsbCAoKS5wYXJlbnQgPT0gbnVsbCkgcmV0dXJuOwotCU9TLlNldFdpbmRvd0RlZmF1bHRCdXR0b24oT1MuR2V0Q29udHJvbE93bmVyKGhhbmRsZSksIHZhbHVlID8gaGFuZGxlIDogMCk7CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAoaGFuZGxlKTsKKwlPUy5TZXRXaW5kb3dEZWZhdWx0QnV0dG9uICh3aW5kb3csIHZhbHVlID8gaGFuZGxlIDogMCk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgaW1hZ2UgdG8gdGhlIGFyZ3VtZW50LCB3aGljaCBtYXkgYmUKLSAqIG51bGwgaW5kaWNhdGluZyB0aGF0IG5vIGltYWdlIHNob3VsZCBiZSBkaXNwbGF5ZWQuCi0gKgotICogQHBhcmFtIGltYWdlIHRoZSBpbWFnZSB0byBkaXNwbGF5IG9uIHRoZSByZWNlaXZlciAobWF5IGJlIG51bGwpCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfQVJHVU1FTlQgLSBpZiB0aGUgaW1hZ2UgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogPC91bD4gCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0SW1hZ2UgKEltYWdlIGltYWdlKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQkKLQl0aGlzLmltYWdlID0gaW1hZ2U7Ci0JCi0JaWYgKGZDSWNvbkhhbmRsZSAhPSAwKSB7Ci0JCUltYWdlLmRpc3Bvc2VDSWNvbihmQ0ljb25IYW5kbGUpOwotCQlmQ0ljb25IYW5kbGU9IDA7CisJaWYgKChzdHlsZSAmIFNXVC5BUlJPVykgIT0gMCkgcmV0dXJuOworCWlmIChjSWNvbiAhPSAwKSB7CisJCWRlc3Ryb3lDSWNvbihjSWNvbik7CisJCWNJY29uID0gMDsKIAl9CisJdGhpcy5pbWFnZSA9IGltYWdlOworCWlzSW1hZ2UgPSB0cnVlOwogCQotCWlmIChpbWFnZSAhPSBudWxsKSB7Ci0JCWlmIChpbWFnZS5pc0Rpc3Bvc2VkKCkpIGVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKLQkJZkNJY29uSGFuZGxlPSBJbWFnZS5jYXJib25fY3JlYXRlQ0ljb24oaW1hZ2UpOwotCQlpZiAoZkNJY29uSGFuZGxlICE9IDApCi0JCQlzZXRNb2RlKGZDSWNvbkhhbmRsZSk7Ci0JfSBlbHNlIAotCQlzZXRNb2RlKDApOworCWlmIChpbWFnZSA9PSBudWxsKSB7CisJCXNldFRleHQgKHRleHQpOworCQlyZXR1cm47CisJfQorCisJaWYgKHRleHQubGVuZ3RoICgpID4gMCkgeworCQljaGFyIFtdIGJ1ZmZlciA9IG5ldyBjaGFyIFtdIHsnICd9OworCQlpbnQgcHRyID0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgYnVmZmVyLCBidWZmZXIubGVuZ3RoKTsKKwkJaWYgKHB0ciA9PSAwKSBlcnJvciAoU1dULkVSUk9SX0NBTk5PVF9TRVRfVEVYVCk7CisJCU9TLlNldENvbnRyb2xUaXRsZVdpdGhDRlN0cmluZyAoaGFuZGxlLCBwdHIpOworCQlPUy5DRlJlbGVhc2UgKHB0cik7CisJfQorCisJY0ljb24gPSBjcmVhdGVDSWNvbiAoaW1hZ2UpOworCUNvbnRyb2xCdXR0b25Db250ZW50SW5mbyBpbkNvbnRlbnQgPSBuZXcgQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvICgpOworCWluQ29udGVudC5jb250ZW50VHlwZSA9IChzaG9ydClPUy5rQ29udHJvbENvbnRlbnRDSWNvbkhhbmRsZTsKKwlpbkNvbnRlbnQuaWNvblJlZiA9IGNJY29uOworCU9TLlNldEJldmVsQnV0dG9uQ29udGVudEluZm8gKGhhbmRsZSwgaW5Db250ZW50KTsKKwlyZWRyYXcgKCk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHNlbGVjdGlvbiBzdGF0ZSBvZiB0aGUgcmVjZWl2ZXIsIGlmIGl0IGlzIG9mIHR5cGUgPGNvZGU+Q0hFQ0s8L2NvZGU+LCAKLSAqIDxjb2RlPlJBRElPPC9jb2RlPiwgb3IgPGNvZGU+VE9HR0xFPC9jb2RlPi4KLSAqCi0gKiA8cD4KLSAqIFdoZW4gdGhlIHJlY2VpdmVyIGlzIG9mIHR5cGUgPGNvZGU+Q0hFQ0s8L2NvZGU+IG9yIDxjb2RlPlJBRElPPC9jb2RlPiwKLSAqIGl0IGlzIHNlbGVjdGVkIHdoZW4gaXQgaXMgY2hlY2tlZC4gV2hlbiBpdCBpcyBvZiB0eXBlIDxjb2RlPlRPR0dMRTwvY29kZT4sCi0gKiBpdCBpcyBzZWxlY3RlZCB3aGVuIGl0IGlzIHB1c2hlZCBpbi4KLSAqCi0gKiBAcGFyYW0gc2VsZWN0ZWQgdGhlIG5ldyBzZWxlY3Rpb24gc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKworYm9vbGVhbiBzZXRSYWRpb1NlbGVjdGlvbiAoYm9vbGVhbiB2YWx1ZSl7CisJaWYgKChzdHlsZSAmIFNXVC5SQURJTykgPT0gMCkgcmV0dXJuIGZhbHNlOworCWlmIChnZXRTZWxlY3Rpb24gKCkgIT0gdmFsdWUpIHsKKwkJc2V0U2VsZWN0aW9uICh2YWx1ZSk7CisJCXBvc3RFdmVudCAoU1dULlNlbGVjdGlvbik7CisJfQorCXJldHVybiB0cnVlOworfQorCiBwdWJsaWMgdm9pZCBzZXRTZWxlY3Rpb24gKGJvb2xlYW4gc2VsZWN0ZWQpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICgoc3R5bGUgJiAoU1dULkNIRUNLIHwgU1dULlJBRElPIHwgU1dULlRPR0dMRSkpID09IDApIHJldHVybjsKLQlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUsIHNlbGVjdGVkID8gMSA6IDApOworCU9TLlNldENvbnRyb2wzMkJpdFZhbHVlIChoYW5kbGUsIHNlbGVjdGVkID8gMSA6IDApOwogfQotLyoqCi0gKiBTZXRzIHRoZSByZWNlaXZlcidzIHRleHQuCi0gKiA8cD4KLSAqIFRoaXMgbWV0aG9kIHNldHMgdGhlIGJ1dHRvbiBsYWJlbC4gIFRoZSBsYWJlbCBtYXkgaW5jbHVkZQotICogdGhlIG1uZW1vbmljIGNoYXJhY3RlciBidXQgbXVzdCBub3QgY29udGFpbiBsaW5lIGRlbGltaXRlcnMuCi0gKiA8L3A+Ci0gKiAKLSAqIEBwYXJhbSBzdHJpbmcgdGhlIG5ldyB0ZXh0Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgdGV4dCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0VGV4dCAoU3RyaW5nIHN0cmluZykgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHN0cmluZyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWlmICgoc3R5bGUgJiBTV1QuQVJST1cpICE9IDApIHJldHVybjsKLQkKLQlpbnQgc0hhbmRsZT0gMDsKLQl0cnkgewotCQlzSGFuZGxlPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzKE1hY1V0aWwucmVtb3ZlTW5lbW9uaWNzKHN0cmluZykpOwotCQlpZiAoT1MuU2V0Q29udHJvbFRpdGxlV2l0aENGU3RyaW5nKGhhbmRsZSwgc0hhbmRsZSkgIT0gT1Mua05vRXJyKQotCQkJZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfU0VUX1RFWFQpOwotCX0gZmluYWxseSB7Ci0JCWlmIChzSGFuZGxlICE9IDApCi0JCQlPUy5DRlJlbGVhc2Uoc0hhbmRsZSk7CisJdGV4dCA9IHN0cmluZzsKKwlpZiAoaXNJbWFnZSkgeworCQlDb250cm9sQnV0dG9uQ29udGVudEluZm8gaW5Db250ZW50ID0gbmV3IENvbnRyb2xCdXR0b25Db250ZW50SW5mbygpOworCQlpbkNvbnRlbnQuY29udGVudFR5cGUgPSAoc2hvcnQpT1Mua0NvbnRyb2xDb250ZW50VGV4dE9ubHk7CisJCU9TLlNldEJldmVsQnV0dG9uQ29udGVudEluZm8oaGFuZGxlLCBpbkNvbnRlbnQpOwogCX0KLX0KLQotaW50IHRyYXZlcnNhbENvZGUgKCkgewotCWludCBjb2RlID0gc3VwZXIudHJhdmVyc2FsQ29kZSAoKTsKLQlpZiAoKHN0eWxlICYgU1dULlBVU0gpICE9IDApIHJldHVybiBjb2RlOwotCXJldHVybiBjb2RlIHwgU1dULlRSQVZFUlNFX0FSUk9XX05FWFQgfCBTV1QuVFJBVkVSU0VfQVJST1dfUFJFVklPVVM7Ci19Ci0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0vLyBNYWMgc3R1ZmYKLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLXByaXZhdGUgdm9pZCBzZXRNb2RlKGludCBpY29uKSB7Ci0JCi0JaWYgKChzdHlsZSAmIFNXVC5GTEFUKSAhPSAwIHx8IGZJbWFnZU1vZGUpIHsKLQkJT1MuU2V0QmV2ZWxCdXR0b25Db250ZW50SW5mbyhoYW5kbGUsIE9TLmtDb250cm9sQ29udGVudENJY29uSGFuZGxlLCBpY29uKTsKLQkJcmVkcmF3KCk7Ci0JCXJldHVybjsKKwlpc0ltYWdlID0gZmFsc2U7CisJaW50IGxlbmd0aCA9IHRleHQubGVuZ3RoICgpOworCVN0cmluZyBzID0gKGxlbmd0aCA9PSAwKSA/ICIgIjogdGV4dDsKKwljaGFyIFtdIGJ1ZmZlciA9IG5ldyBjaGFyIFtsZW5ndGhdOworCXMuZ2V0Q2hhcnMgKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlciwgMCk7CisJaW50IGk9MCwgaj0wOworCXdoaWxlIChpIDwgYnVmZmVyLmxlbmd0aCkgeworCQlpZiAoKGJ1ZmZlciBbaisrXSA9IGJ1ZmZlciBbaSsrXSkgPT0gTW5lbW9uaWMpIHsKKwkJCWlmIChpID09IGJ1ZmZlci5sZW5ndGgpIHtjb250aW51ZTt9CisJCQlpZiAoYnVmZmVyIFtpXSA9PSBNbmVtb25pYykge2krKzsgY29udGludWU7fQorCQkJai0tOworCQl9CiAJfQotCi0JaWYgKChzdHlsZSAmIFNXVC5QVVNIKSA9PSAwKQotCQlyZXR1cm47CS8vIHdlIG9ubHkgdHJhbnNtb2dyaWZ5IHB1c2ggYnV0dG9ucwotCQotCWZJbWFnZU1vZGU9IHRydWU7Ci0JCi0JaW50W10gcGg9IG5ldyBpbnRbMV07Ci0JaW50IHJjPSBPUy5HZXRTdXBlckNvbnRyb2woaGFuZGxlLCBwaCk7Ci0JaWYgKHJjICE9IE9TLmtOb0VycikKLQkJU3lzdGVtLm91dC5wcmludGxuKCJCdXR0b24uc2V0TW9kZTogIiArIHJjKTsKLQlpbnQgcGFyZW50SGFuZGxlPSBwaFswXTsKLQkKLQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQlPUy5HZXRDb250cm9sQm91bmRzKGhhbmRsZSwgYm91bmRzLmdldERhdGEoKSk7Ci0JCi0JaW50IGluZGV4PSBNYWNVdGlsLmluZGV4T2YocGFyZW50SGFuZGxlLCBoYW5kbGUpOwotCWlmIChpbmRleCA8IDApCi0JCVN5c3RlbS5vdXQucHJpbnRsbigiQnV0dG9uLnNldE1vZGU6IGNhbid0IGZpbmQgaGFuZGxlIik7Ci0JV2lkZ2V0IHc9IFdpZGdldFRhYmxlLmdldChoYW5kbGUpOwotCVdpZGdldFRhYmxlLnJlbW92ZShoYW5kbGUpOwotCU9TLkRpc3Bvc2VDb250cm9sKGhhbmRsZSk7Ci0JCi0Jc2hvcnQgdHlwZT0gaWNvbiAhPSAwID8gT1Mua0NvbnRyb2xCZXZlbEJ1dHRvbk5vcm1hbEJldmVsUHJvYyA6IE9TLmtDb250cm9sUHVzaEJ1dHRvblByb2M7Ci0JCQotICAgIGhhbmRsZT0gTWFjVXRpbC5uZXdDb250cm9sKHBhcmVudEhhbmRsZSwgaW5kZXgsIChzaG9ydCkwLCAoc2hvcnQpMCwgKHNob3J0KTAsIHR5cGUpOwotCWlmIChoYW5kbGUgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKLQlXaWRnZXRUYWJsZS5wdXQoaGFuZGxlLCB3KTsKLQkKLQlPUy5TZXRDb250cm9sQm91bmRzKGhhbmRsZSwgYm91bmRzLmdldERhdGEoKSk7Ci0JT1MuU2V0QmV2ZWxCdXR0b25Db250ZW50SW5mbyhoYW5kbGUsIE9TLmtDb250cm9sQ29udGVudENJY29uSGFuZGxlLCBpY29uKTsKLX0KLQotLyoqCi0gKiBPdmVycmlkZGVuIGZyb20gQ29udHJvbC4KLSAqIHggYW5kIHkgYXJlIHJlbGF0aXZlIHRvIHdpbmRvdyEKLSAqLwotdm9pZCBoYW5kbGVSZXNpemUoaW50IGhuZGwsIE1hY1JlY3QgYm91bmRzKSB7Ci0JZlRvcE1hcmdpbj0gZkJvdHRvbU1hcmdpbj0gMDsKLQlpZiAoKHN0eWxlICYgU1dULlBVU0gpICE9IDAgJiYgaW1hZ2UgPT0gbnVsbCkgewkvLyBmb3IgcHVzaCBidXR0b25zCi0JCVBvaW50IHJlc3VsdD0gTWFjVXRpbC5jb21wdXRlU2l6ZShobmRsKTsKLQkJaW50IGRpZmY9IGJvdW5kcy5nZXRIZWlnaHQoKS1yZXN1bHQueTsKLQkJZlRvcE1hcmdpbj0gZGlmZi8yOwotCQlmQm90dG9tTWFyZ2luPSBkaWZmLWZUb3BNYXJnaW47Ci0JCWJvdW5kcy5pbnNldChNQVJHSU4sIGZUb3BNYXJnaW4sIE1BUkdJTiwgZkJvdHRvbU1hcmdpbik7Ci0JfQotCXN1cGVyLmhhbmRsZVJlc2l6ZShobmRsLCBib3VuZHMpOwotfQotCi12b2lkIGludGVybmFsR2V0Q29udHJvbEJvdW5kcyhpbnQgaG5kbCwgTWFjUmVjdCBib3VuZHMpIHsKLQlzdXBlci5pbnRlcm5hbEdldENvbnRyb2xCb3VuZHMoaG5kbCwgYm91bmRzKTsKLQlpZiAoKHN0eWxlICYgU1dULlBVU0gpICE9IDAgJiYgaW1hZ2UgPT0gbnVsbCkKLQkJYm91bmRzLmluc2V0KC1NQVJHSU4sIC1mVG9wTWFyZ2luLCAtTUFSR0lOLCAtZkJvdHRvbU1hcmdpbik7Ci19Ci0KLXB1YmxpYyB2b2lkIHNldEZvbnQgKEZvbnQgZm9udCkgewotCXN1cGVyLnNldEZvbnQobnVsbCk7Ci19Ci0KLWludCBzZW5kS2V5RXZlbnQoaW50IHR5cGUsIE1hY0V2ZW50IG1FdmVudCwgRXZlbnQgZXZlbnQpIHsKLQlyZXR1cm4gT1MuQ2FsbE5leHRFdmVudEhhbmRsZXIobUV2ZW50LmdldE5leHRIYW5kbGVyKCksIG1FdmVudC5nZXRFdmVudFJlZigpKTsKKwlpbnQgcHRyID0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgYnVmZmVyLCBqKTsKKwlpZiAocHRyID09IDApIGVycm9yIChTV1QuRVJST1JfQ0FOTk9UX1NFVF9URVhUKTsKKwlPUy5TZXRDb250cm9sVGl0bGVXaXRoQ0ZTdHJpbmcgKGhhbmRsZSwgcHRyKTsKKwlPUy5DRlJlbGVhc2UgKHB0cik7CisJcmVkcmF3ICgpOwogfQogCiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvQ2FudmFzLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvQ2FudmFzLmphdmEKaW5kZXggMDUyYjM3Yy4uOTU0MGExNCAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0NhbnZhcy5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9DYW52YXMuamF2YQpAQCAtNywyMDAgKzcsNzAgQEAKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAgKi8KIAoraW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKKwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOwogCi0vKioKLSAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIHByb3ZpZGUgYSBzdXJmYWNlIGZvciBkcmF3aW5nCi0gKiBhcmJpdHJhcnkgZ3JhcGhpY3MuCi0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPihub25lKTwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPihub25lKTwvZGQ+Ci0gKiA8L2RsPgotICogPHA+Ci0gKiBUaGlzIGNsYXNzIG1heSBiZSBzdWJjbGFzc2VkIGJ5IGN1c3RvbSBjb250cm9sIGltcGxlbWVudG9ycwotICogd2hvIGFyZSBidWlsZGluZyBjb250cm9scyB0aGF0IGFyZSA8ZW0+bm90PC9lbT4gY29uc3RydWN0ZWQKLSAqIGZyb20gYWdncmVnYXRlcyBvZiBvdGhlciBjb250cm9scy4gVGhhdCBpcywgdGhleSBhcmUgZWl0aGVyCi0gKiBwYWludGVkIHVzaW5nIFNXVCBncmFwaGljcyBjYWxscyBvciBhcmUgaGFuZGxlZCBieSBuYXRpdmUKLSAqIG1ldGhvZHMuCi0gKiA8L3A+Ci0gKgotICogQHNlZSBDb21wb3NpdGUKLSAqLwogcHVibGljIGNsYXNzIENhbnZhcyBleHRlbmRzIENvbXBvc2l0ZSB7CiAJQ2FyZXQgY2FyZXQ7CiAKIENhbnZhcyAoKSB7CiAJLyogRG8gbm90aGluZyAqLwogfQotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gaXRzIHBhcmVudAotICogYW5kIGEgc3R5bGUgdmFsdWUgZGVzY3JpYmluZyBpdHMgYmVoYXZpb3IgYW5kIGFwcGVhcmFuY2UuCi0gKiA8cD4KLSAqIFRoZSBzdHlsZSB2YWx1ZSBpcyBlaXRoZXIgb25lIG9mIHRoZSBzdHlsZSBjb25zdGFudHMgZGVmaW5lZCBpbgotICogY2xhc3MgPGNvZGU+U1dUPC9jb2RlPiB3aGljaCBpcyBhcHBsaWNhYmxlIHRvIGluc3RhbmNlcyBvZiB0aGlzCi0gKiBjbGFzcywgb3IgbXVzdCBiZSBidWlsdCBieSA8ZW0+Yml0d2lzZSBPUjwvZW0+J2luZyB0b2dldGhlciAKLSAqICh0aGF0IGlzLCB1c2luZyB0aGUgPGNvZGU+aW50PC9jb2RlPiAifCIgb3BlcmF0b3IpIHR3byBvciBtb3JlCi0gKiBvZiB0aG9zZSA8Y29kZT5TV1Q8L2NvZGU+IHN0eWxlIGNvbnN0YW50cy4gVGhlIGNsYXNzIGRlc2NyaXB0aW9uCi0gKiBsaXN0cyB0aGUgc3R5bGUgY29uc3RhbnRzIHRoYXQgYXJlIGFwcGxpY2FibGUgdG8gdGhlIGNsYXNzLgotICogU3R5bGUgYml0cyBhcmUgYWxzbyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIGNvbXBvc2l0ZSBjb250cm9sIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqIEBwYXJhbSBzdHlsZSB0aGUgc3R5bGUgb2YgY29udHJvbCB0byBjb25zdHJ1Y3QKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU1dUCi0gKiBAc2VlIFdpZGdldCNjaGVja1N1YmNsYXNzCi0gKiBAc2VlIFdpZGdldCNnZXRTdHlsZQotICovCisKIHB1YmxpYyBDYW52YXMgKENvbXBvc2l0ZSBwYXJlbnQsIGludCBzdHlsZSkgewogCXN1cGVyIChwYXJlbnQsIHN0eWxlKTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgY2FyZXQuCi0gKiA8cD4KLSAqIFRoZSBjYXJldCBmb3IgdGhlIGNvbnRyb2wgaXMgYXV0b21hdGljYWxseSBoaWRkZW4KLSAqIGFuZCBzaG93biB3aGVuIHRoZSBjb250cm9sIGlzIHBhaW50ZWQgb3IgcmVzaXplZCwKLSAqIHdoZW4gZm9jdXMgaXMgZ2FpbmVkIG9yIGxvc3QgYW5kIHdoZW4gYW4gdGhlIGNvbnRyb2wKLSAqIGlzIHNjcm9sbGVkLiAgVG8gYXZvaWQgZHJhd2luZyBvbiB0b3Agb2YgdGhlIGNhcmV0LAotICogdGhlIHByb2dyYW1tZXIgbXVzdCBoaWRlIGFuZCBzaG93IHRoZSBjYXJldCB3aGVuCi0gKiBkcmF3aW5nIGluIHRoZSB3aW5kb3cgYW55IG90aGVyIHRpbWUuCi0gKiA8L3A+Ci0gKgotICogQHJldHVybiB0aGUgY2FyZXQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIENhcmV0IGdldENhcmV0ICgpIHsKIAljaGVja1dpZGdldCgpOwogICAgIHJldHVybiBjYXJldDsKIH0KLS8qIEFXCi1zaG9ydCBbXSBnZXRJTUVDYXJldFBvcyAoKSB7Ci0JaWYgKGNhcmV0ID09IG51bGwpIHJldHVybiBzdXBlci5nZXRJTUVDYXJldFBvcyAoKTsKLQlpbnQgd2lkdGggPSBjYXJldC53aWR0aDsKLQlpZiAod2lkdGggPD0gMCkgd2lkdGggPSAyOwotCXJldHVybiBuZXcgc2hvcnRbXXsoc2hvcnQpIChjYXJldC54ICsgd2lkdGgpLCAoc2hvcnQpIChjYXJldC55ICsgY2FyZXQuaGVpZ2h0KX07Ci19Ci0qLwotaW50IHByb2Nlc3NGb2N1c0luICgpIHsKLQlpbnQgcmVzdWx0ID0gc3VwZXIucHJvY2Vzc0ZvY3VzSW4gKCk7Ci0JaWYgKGNhcmV0ICE9IG51bGwpIGNhcmV0LnNldEZvY3VzICgpOwotCXJldHVybiByZXN1bHQ7Ci19Ci1pbnQgcHJvY2Vzc0ZvY3VzT3V0ICgpIHsKLQlpbnQgcmVzdWx0ID0gc3VwZXIucHJvY2Vzc0ZvY3VzT3V0ICgpOwotCWlmIChjYXJldCAhPSBudWxsKSBjYXJldC5raWxsRm9jdXMgKCk7Ci0JcmV0dXJuIHJlc3VsdDsKLX0KIAotaW50IHByb2Nlc3NQYWludCAoT2JqZWN0IGNhbGxEYXRhKSB7CitpbnQga0V2ZW50Q29udHJvbERyYXcgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKIAlib29sZWFuIGlzRm9jdXMgPSBjYXJldCAhPSBudWxsICYmIGNhcmV0LmlzRm9jdXNDYXJldCAoKTsKIAlpZiAoaXNGb2N1cykgY2FyZXQua2lsbEZvY3VzICgpOwotCWludCByZXN1bHQgPSBzdXBlci5wcm9jZXNzUGFpbnQgKGNhbGxEYXRhKTsKKwlpbnQgcmVzdWx0ID0gc3VwZXIua0V2ZW50Q29udHJvbERyYXcgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOwogCWlmIChpc0ZvY3VzKSBjYXJldC5zZXRGb2N1cyAoKTsKIAlyZXR1cm4gcmVzdWx0OwogfQogCi12b2lkIHJlZHJhd1dpZGdldCAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGJvb2xlYW4gYWxsKSB7Ci0JYm9vbGVhbiBpc0ZvY3VzID0gY2FyZXQgIT0gbnVsbCAmJiBjYXJldC5pc0ZvY3VzQ2FyZXQgKCk7Ci0JaWYgKGlzRm9jdXMpIGNhcmV0LmtpbGxGb2N1cyAoKTsKLQlzdXBlci5yZWRyYXdXaWRnZXQgKHgsIHksIHdpZHRoLCBoZWlnaHQsIGFsbCk7Ci0JaWYgKGlzRm9jdXMpIGNhcmV0LnNldEZvY3VzICgpOworaW50IGtFdmVudENvbnRyb2xTZXRGb2N1c1BhcnQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpbnQgcmVzdWx0ID0gc3VwZXIua0V2ZW50Q29udHJvbFNldEZvY3VzUGFydCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKGNhcmV0ICE9IG51bGwpIHsKKwkJc2hvcnQgW10gcGFydCA9IG5ldyBzaG9ydCBbMV07CisJCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1Db250cm9sUGFydCwgT1MudHlwZUNvbnRyb2xQYXJ0Q29kZSwgbnVsbCwgMiwgbnVsbCwgcGFydCk7CisJCWlmIChwYXJ0IFswXSAhPSAwKSB7CisJCQljYXJldC5zZXRGb2N1cyAoKTsKKwkJfSBlbHNlIHsKKwkJCWNhcmV0LmtpbGxGb2N1cyAoKTsKKwkJfQorCX0KKwlyZXR1cm4gcmVzdWx0OwogfQogCiB2b2lkIHJlbGVhc2VXaWRnZXQgKCkgewotCWlmIChjYXJldCAhPSBudWxsKSB7Ci0JCWNhcmV0LnJlbGVhc2VXaWRnZXQgKCk7Ci0JCWNhcmV0LnJlbGVhc2VIYW5kbGUgKCk7Ci0JfQorCWlmIChjYXJldCAhPSBudWxsKSBjYXJldC5yZWxlYXNlUmVzb3VyY2VzICgpOwogCWNhcmV0ID0gbnVsbDsKLQlzdXBlci5yZWxlYXNlV2lkZ2V0KCk7CisJc3VwZXIucmVsZWFzZVdpZGdldCAoKTsKIH0KIAotLyoqCi0gKiBTY3JvbGxzIGEgcmVjdGFuZ3VsYXIgYXJlYSBvZiB0aGUgcmVjZWl2ZXIgYnkgZmlyc3QgY29weWluZyAKLSAqIHRoZSBzb3VyY2UgYXJlYSB0byB0aGUgZGVzdGluYXRpb24gYW5kIHRoZW4gY2F1c2luZyB0aGUgYXJlYQotICogb2YgdGhlIHNvdXJjZSB3aGljaCBpcyBub3QgY292ZXJlZCBieSB0aGUgZGVzdGluYXRpb24gdG8KLSAqIGJlIHJlcGFpbnRlZC4gQ2hpbGRyZW4gdGhhdCBpbnRlcnNlY3QgdGhlIHJlY3RhbmdsZSBhcmUKLSAqIG9wdGlvbmFsbHkgbW92ZWQgZHVyaW5nIHRoZSBvcGVyYXRpb24uIEluIGFkZGl0aW9uLCBvdXRzdGFuZGluZwotICogcGFpbnQgZXZlbnRzIGFyZSBmbHVzaGVkIGJlZm9yZSB0aGUgc291cmNlIGFyZWEgaXMgY29waWVkIHRvCi0gKiBlbnN1cmUgdGhhdCB0aGUgY29udGVudHMgb2YgdGhlIGNhbnZhcyBhcmUgZHJhd24gY29ycmVjdGx5LgotICoKLSAqIEBwYXJhbSBkZXN0WCB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBkZXN0aW5hdGlvbgotICogQHBhcmFtIGRlc3RZIHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGRlc3RpbmF0aW9uCi0gKiBAcGFyYW0geCB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBzb3VyY2UKLSAqIEBwYXJhbSB5IHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHNvdXJjZQotICogQHBhcmFtIHdpZHRoIHRoZSB3aWR0aCBvZiB0aGUgYXJlYQotICogQHBhcmFtIGhlaWdodCB0aGUgaGVpZ2h0IG9mIHRoZSBhcmVhCi0gKiBAcGFyYW0gYWxsIDxjb2RlPnRydWU8L2NvZGU+aWYgY2hpbGRyZW4gc2hvdWxkIGJlIHNjcm9sbGVkLCBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIHZvaWQgc2Nyb2xsIChpbnQgZGVzdFgsIGludCBkZXN0WSwgaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGJvb2xlYW4gYWxsKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAod2lkdGggPD0gMCB8fCBoZWlnaHQgPD0gMCkgcmV0dXJuOwogCWludCBkZWx0YVggPSBkZXN0WCAtIHgsIGRlbHRhWSA9IGRlc3RZIC0geTsKIAlpZiAoZGVsdGFYID09IDAgJiYgZGVsdGFZID09IDApIHJldHVybjsKIAlpZiAoIWlzVmlzaWJsZSAoKSkgcmV0dXJuOwotCi0JLyogSGlkZSB0aGUgY2FyZXQgKi8KIAlib29sZWFuIGlzRm9jdXMgPSBjYXJldCAhPSBudWxsICYmIGNhcmV0LmlzRm9jdXNDYXJldCAoKTsKIAlpZiAoaXNGb2N1cykgY2FyZXQua2lsbEZvY3VzICgpOwotCi0JLyogRmx1c2ggb3V0c3RhbmRpbmcgZXhwb3NlcyAqLwotCWdldERpc3BsYXkoKS51cGRhdGUgKCk7Ci0KLSAgICBHQyBnYz0gbmV3IEdDKHRoaXMpOwotICAgIGdjLmNvcHlBcmVhKHgsIHksIHdpZHRoLCBoZWlnaHQsIGRlc3RYLCBkZXN0WSk7Ci0gICAgZ2MuZGlzcG9zZSgpOwotCQotCS8qIFNob3cgdGhlIGNhcmV0ICovCisJdXBkYXRlICgpOworICAgIEdDIGdjID0gbmV3IEdDICh0aGlzKTsKKyAgICBnYy5jb3B5QXJlYSAoeCwgeSwgd2lkdGgsIGhlaWdodCwgZGVzdFgsIGRlc3RZKTsKKyAgICBnYy5kaXNwb3NlICgpOwogCWlmIChpc0ZvY3VzKSBjYXJldC5zZXRGb2N1cyAoKTsKIH0KLXB1YmxpYyB2b2lkIHNldEJvdW5kcyAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKLQljaGVja1dpZGdldCgpOwotCWJvb2xlYW4gaXNGb2N1cyA9IGNhcmV0ICE9IG51bGwgJiYgY2FyZXQuaXNGb2N1c0NhcmV0ICgpOwotCWlmIChpc0ZvY3VzKSBjYXJldC5raWxsRm9jdXMgKCk7Ci0Jc3VwZXIuc2V0Qm91bmRzICh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKLQlpZiAoaXNGb2N1cykgY2FyZXQuc2V0Rm9jdXMgKCk7Ci19Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgY2FyZXQuCi0gKiA8cD4KLSAqIFRoZSBjYXJldCBmb3IgdGhlIGNvbnRyb2wgaXMgYXV0b21hdGljYWxseSBoaWRkZW4KLSAqIGFuZCBzaG93biB3aGVuIHRoZSBjb250cm9sIGlzIHBhaW50ZWQgb3IgcmVzaXplZCwKLSAqIHdoZW4gZm9jdXMgaXMgZ2FpbmVkIG9yIGxvc3QgYW5kIHdoZW4gYW4gdGhlIGNvbnRyb2wKLSAqIGlzIHNjcm9sbGVkLiAgVG8gYXZvaWQgZHJhd2luZyBvbiB0b3Agb2YgdGhlIGNhcmV0LAotICogdGhlIHByb2dyYW1tZXIgbXVzdCBoaWRlIGFuZCBzaG93IHRoZSBjYXJldCB3aGVuCi0gKiBkcmF3aW5nIGluIHRoZSB3aW5kb3cgYW55IG90aGVyIHRpbWUuCi0gKiA8L3A+Ci0gKiBAcGFyYW0gY2FyZXQgdGhlIG5ldyBjYXJldCBmb3IgdGhlIHJlY2VpdmVyLCBtYXkgYmUgbnVsbAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX0FSR1VNRU5UIC0gaWYgdGhlIGNhcmV0IGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0Q2FyZXQgKENhcmV0IGNhcmV0KSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlDYXJldCBuZXdDYXJldCA9IGNhcmV0OwpAQCAtMjE1LDM2ICs4NSw0IEBACiAJfQogfQogCi1wdWJsaWMgdm9pZCBzZXRGb250IChGb250IGZvbnQpIHsKLQljaGVja1dpZGdldCgpOwotCXN1cGVyLnNldEZvbnQgKGZvbnQpOwotCWlmIChjYXJldCAhPSBudWxsKSBjYXJldC5zZXRGb250IChmb250KTsKLX0KLQkKLXB1YmxpYyB2b2lkIHNldExvY2F0aW9uIChpbnQgeCwgaW50IHkpIHsKLQljaGVja1dpZGdldCgpOwotCWJvb2xlYW4gaXNGb2N1cyA9IGNhcmV0ICE9IG51bGwgJiYgY2FyZXQuaXNGb2N1c0NhcmV0ICgpOwotCWlmIChpc0ZvY3VzKSBjYXJldC5raWxsRm9jdXMgKCk7Ci0Jc3VwZXIuc2V0TG9jYXRpb24gKHgsIHkpOwotCWlmIChpc0ZvY3VzKSBjYXJldC5zZXRGb2N1cyAoKTsKLX0KLXB1YmxpYyB2b2lkIHNldFNpemUgKGludCB3aWR0aCwgaW50IGhlaWdodCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0JYm9vbGVhbiBpc0ZvY3VzID0gY2FyZXQgIT0gbnVsbCAmJiBjYXJldC5pc0ZvY3VzQ2FyZXQgKCk7Ci0JaWYgKGlzRm9jdXMpIGNhcmV0LmtpbGxGb2N1cyAoKTsKLQlzdXBlci5zZXRTaXplICh3aWR0aCwgaGVpZ2h0KTsKLQlpZiAoaXNGb2N1cykgY2FyZXQuc2V0Rm9jdXMgKCk7Ci19Ci12b2lkIHVwZGF0ZUNhcmV0ICgpIHsKLQlpZiAoY2FyZXQgPT0gbnVsbCkgcmV0dXJuOwotICAgIC8qIEFXCi0JaWYgKCFJc0RCTG9jYWxlKSByZXR1cm47Ci0Jc2hvcnQgW10gcG9pbnQgPSBnZXRJTUVDYXJldFBvcyAoKTsKLQlpbnQgcHRyID0gT1MuWHRNYWxsb2MgKDQpOwotCU9TLm1lbW1vdmUgKHB0ciwgcG9pbnQsIDQpOwotCWludFtdIGFyZ0xpc3QgPSB7T1MuWG1Oc3BvdExvY2F0aW9uLCBwdHJ9OwotCU9TLlhtSW1TZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlpZiAocHRyICE9IDApIE9TLlh0RnJlZSAocHRyKTsKLSAgICAqLwotfQotfQorfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9DYXJldC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0NhcmV0LmphdmEKaW5kZXggZTRkZDczYy4uN2YxM2NiMSAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0NhcmV0LmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0NhcmV0LmphdmEKQEAgLTcsODMgKzcsNDYgQEAKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAgKi8KIAotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLk9TOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUkdCQ29sb3I7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5SZWN0OworCiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7CiAKLS8qKgotICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgcHJvdmlkZSBhbiBpLWJlYW0gdGhhdCBpcyB0eXBpY2FsbHkgdXNlZAotICogYXMgdGhlIGluc2VydGlvbiBwb2ludCBmb3IgdGV4dC4KLSAqIDxkbD4KLSAqIDxkdD48Yj5TdHlsZXM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+KG5vbmUpPC9kZD4KLSAqIDxkdD48Yj5FdmVudHM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+KG5vbmUpPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cD4KLSAqIElNUE9SVEFOVDogVGhpcyBjbGFzcyBpcyBpbnRlbmRlZCB0byBiZSBzdWJjbGFzc2VkIDxlbT5vbmx5PC9lbT4KLSAqIHdpdGhpbiB0aGUgU1dUIGltcGxlbWVudGF0aW9uLgotICogPC9wPgotICovCi1wdWJsaWMgLypmaW5hbCovIGNsYXNzIENhcmV0IGV4dGVuZHMgV2lkZ2V0IHsKK3B1YmxpYyBjbGFzcyBDYXJldCBleHRlbmRzIFdpZGdldCB7CiAJQ2FudmFzIHBhcmVudDsKLQlJbWFnZSBpbWFnZTsKIAlpbnQgeCwgeSwgd2lkdGgsIGhlaWdodDsKLQlib29sZWFuIG1vdmVkLCByZXNpemVkOwogCWJvb2xlYW4gaXNWaXNpYmxlLCBpc1Nob3dpbmc7Ci0JaW50IGJsaW5rUmF0ZSA9IChPUy5HZXRDYXJldFRpbWUoKSAqIDEwMDApIC8gNjA7Ci0JRm9udCBmb250OworCWludCBibGlua1JhdGU7CisJSW1hZ2UgaW1hZ2U7CiAKLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIGl0cyBwYXJlbnQKLSAqIGFuZCBhIHN0eWxlIHZhbHVlIGRlc2NyaWJpbmcgaXRzIGJlaGF2aW9yIGFuZCBhcHBlYXJhbmNlLgotICogPHA+Ci0gKiBUaGUgc3R5bGUgdmFsdWUgaXMgZWl0aGVyIG9uZSBvZiB0aGUgc3R5bGUgY29uc3RhbnRzIGRlZmluZWQgaW4KLSAqIGNsYXNzIDxjb2RlPlNXVDwvY29kZT4gd2hpY2ggaXMgYXBwbGljYWJsZSB0byBpbnN0YW5jZXMgb2YgdGhpcwotICogY2xhc3MsIG9yIG11c3QgYmUgYnVpbHQgYnkgPGVtPmJpdHdpc2UgT1I8L2VtPidpbmcgdG9nZXRoZXIgCi0gKiAodGhhdCBpcywgdXNpbmcgdGhlIDxjb2RlPmludDwvY29kZT4gInwiIG9wZXJhdG9yKSB0d28gb3IgbW9yZQotICogb2YgdGhvc2UgPGNvZGU+U1dUPC9jb2RlPiBzdHlsZSBjb25zdGFudHMuIFRoZSBjbGFzcyBkZXNjcmlwdGlvbgotICogbGlzdHMgdGhlIHN0eWxlIGNvbnN0YW50cyB0aGF0IGFyZSBhcHBsaWNhYmxlIHRvIHRoZSBjbGFzcy4KLSAqIFN0eWxlIGJpdHMgYXJlIGFsc28gaW5oZXJpdGVkIGZyb20gc3VwZXJjbGFzc2VzLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBjb21wb3NpdGUgY29udHJvbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZSAoY2Fubm90IGJlIG51bGwpCi0gKiBAcGFyYW0gc3R5bGUgdGhlIHN0eWxlIG9mIGNvbnRyb2wgdG8gY29uc3RydWN0Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcGFyZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHBhcmVudDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNXVAotICogQHNlZSBXaWRnZXQjY2hlY2tTdWJjbGFzcwotICogQHNlZSBXaWRnZXQjZ2V0U3R5bGUKLSAqLwogcHVibGljIENhcmV0IChDYW52YXMgcGFyZW50LCBpbnQgc3R5bGUpIHsKIAlzdXBlciAocGFyZW50LCBzdHlsZSk7CiAJdGhpcy5wYXJlbnQgPSBwYXJlbnQ7Ci0JY3JlYXRlV2lkZ2V0ICgwKTsKKwljcmVhdGVXaWRnZXQgKCk7CiB9CisKIGJvb2xlYW4gYmxpbmtDYXJldCAoKSB7CiAJaWYgKCFpc1Zpc2libGUpIHJldHVybiB0cnVlOwogCWlmICghaXNTaG93aW5nKSByZXR1cm4gc2hvd0NhcmV0ICgpOwogCWlmIChibGlua1JhdGUgPT0gMCkgcmV0dXJuIHRydWU7CiAJcmV0dXJuIGhpZGVDYXJldCAoKTsKIH0KLXZvaWQgY3JlYXRlV2lkZ2V0IChpbnQgaW5kZXgpIHsKLQlzdXBlci5jcmVhdGVXaWRnZXQgKGluZGV4KTsKKwordm9pZCBjcmVhdGVXaWRnZXQgKCkgeworCXN1cGVyLmNyZWF0ZVdpZGdldCAoKTsKKwlEaXNwbGF5IGRpc3BsYXkgPSBwYXJlbnQuZ2V0RGlzcGxheSAoKTsKKwlibGlua1JhdGUgPSBkaXNwbGF5LmdldENhcmV0QmxpbmtUaW1lICgpOwogCWlzVmlzaWJsZSA9IHRydWU7CiAJaWYgKHBhcmVudC5nZXRDYXJldCAoKSA9PSBudWxsKSB7CiAJCXBhcmVudC5zZXRDYXJldCAodGhpcyk7CiAJfQogfQorCiBib29sZWFuIGRyYXdDYXJldCAoKSB7CiAJaWYgKHBhcmVudCA9PSBudWxsKSByZXR1cm4gZmFsc2U7CiAJaWYgKHBhcmVudC5pc0Rpc3Bvc2VkICgpKSByZXR1cm4gZmFsc2U7Ci0JaW50IGhhbmRsZSA9IHBhcmVudC5oYW5kbGU7CiAJaW50IG5XaWR0aCA9IHdpZHRoLCBuSGVpZ2h0ID0gaGVpZ2h0OwogCWlmIChpbWFnZSAhPSBudWxsKSB7CiAJCVJlY3RhbmdsZSByZWN0ID0gaW1hZ2UuZ2V0Qm91bmRzICgpOwpAQCAtOTEsMTI3ICs1NCw3MCBAQAogCQluSGVpZ2h0ID0gcmVjdC5oZWlnaHQ7CiAJfQogCWlmIChuV2lkdGggPD0gMCkgbldpZHRoID0gMjsKLQkKLQlpbnQgY2xpcFJnbj0gT1MuTmV3UmduKCk7Ci0JTWFjVXRpbC5nZXRWaXNpYmxlUmVnaW9uKHBhcmVudC5oYW5kbGUsIGNsaXBSZ24sIHRydWUpOwotCi0JTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JT1MuR2V0Q29udHJvbEJvdW5kcyhwYXJlbnQuaGFuZGxlLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQlib3VuZHM9IG5ldyBNYWNSZWN0KHgrYm91bmRzLmdldFgoKSwgeStib3VuZHMuZ2V0WSgpLCBuV2lkdGgsIG5IZWlnaHQpOwotCQotCWludCBjYXJldFJnbj0gT1MuTmV3UmduKCk7Ci0JT1MuUmVjdFJnbihjYXJldFJnbiwgYm91bmRzLmdldERhdGEoKSk7Ci0JT1MuU2VjdFJnbihjYXJldFJnbiwgY2xpcFJnbiwgY2FyZXRSZ24pOwotCQotCWlmICghT1MuRW1wdHlSZ24oY2FyZXRSZ24pKSB7Ci0JCWludCBwb3J0PSBPUy5HZXRQb3J0KCk7Ci0JCU9TLlNldFBvcnRXaW5kb3dQb3J0KE9TLkdldENvbnRyb2xPd25lcihoYW5kbGUpKTsJCi0JCU9TLkludmVydFJnbihjYXJldFJnbik7Ci0JCU9TLlNldFBvcnQocG9ydCk7Ci0JfQotCQotCU9TLkRpc3Bvc2VSZ24oY2xpcFJnbik7Ci0JT1MuRGlzcG9zZVJnbihjYXJldFJnbik7Ci0KKwlpbnQgcGFyZW50SGFuZGxlID0gcGFyZW50LmhhbmRsZTsKKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChwYXJlbnRIYW5kbGUpOworCWludCBwb3J0ID0gT1MuR2V0V2luZG93UG9ydCAod2luZG93KTsKKwlpbnQgW10gY3VycmVudFBvcnQgPSBuZXcgaW50IFsxXTsKKwlPUy5HZXRQb3J0IChjdXJyZW50UG9ydCk7CisJT1MuU2V0UG9ydCAocG9ydCk7CisJaW50IG9sZENsaXAgPSBPUy5OZXdSZ24gKCk7CisJaW50IHZpc2libGVSZ24gPSBnZXRWaXNpYmxlUmVnaW9uIChwYXJlbnRIYW5kbGUpOworCU9TLkdldENsaXAgKG9sZENsaXApOworCU9TLlNldENsaXAgKHZpc2libGVSZ24pOworCVJlY3QgcmVjdCA9IG5ldyBSZWN0ICgpOworCU9TLkdldENvbnRyb2xCb3VuZHMgKHBhcmVudEhhbmRsZSwgcmVjdCk7CisJaW50IGxlZnQgPSByZWN0LmxlZnQgKyB4OworCWludCB0b3AgPSByZWN0LnRvcCArIHk7CisJT1MuU2V0UmVjdChyZWN0LCAoc2hvcnQpIGxlZnQsIChzaG9ydCkgdG9wLCAoc2hvcnQpIChsZWZ0ICsgbldpZHRoKSwgKHNob3J0KSAodG9wICsgbkhlaWdodCkpOworCVJHQkNvbG9yIGNvbG9yID0gbmV3IFJHQkNvbG9yICgpOworCWNvbG9yLnJlZCA9IChzaG9ydCkgMHhGRkZGOworCWNvbG9yLmdyZWVuID0gKHNob3J0KSAweEZGRkY7CisJY29sb3IuYmx1ZSA9IChzaG9ydCkgMHhGRkZGOworCU9TLlJHQkJhY2tDb2xvciAoY29sb3IpOworCU9TLkludmVydFJlY3QgKHJlY3QpOwkKKwlPUy5TZXRDbGlwIChvbGRDbGlwKTsKKwlPUy5EaXNwb3NlUmduICh2aXNpYmxlUmduKTsKKwlPUy5EaXNwb3NlUmduIChvbGRDbGlwKTsKKwlPUy5TZXRQb3J0IChjdXJyZW50UG9ydCBbMF0pOwogCXJldHVybiB0cnVlOwogfQotLyoqCi0gKiBSZXR1cm5zIGEgcmVjdGFuZ2xlIGRlc2NyaWJpbmcgdGhlIHJlY2VpdmVyJ3Mgc2l6ZSBhbmQgbG9jYXRpb24KLSAqIHJlbGF0aXZlIHRvIGl0cyBwYXJlbnQgKG9yIGl0cyBkaXNwbGF5IGlmIGl0cyBwYXJlbnQgaXMgbnVsbCkuCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBib3VuZGluZyByZWN0YW5nbGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIFJlY3RhbmdsZSBnZXRCb3VuZHMgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGltYWdlICE9IG51bGwpIHsKIAkJUmVjdGFuZ2xlIHJlY3QgPSBpbWFnZS5nZXRCb3VuZHMgKCk7Ci0JCXJlY3QueD0geDsKLQkJcmVjdC55PSB5OwotCQlyZXR1cm4gcmVjdDsKKwkJcmV0dXJuIG5ldyBSZWN0YW5nbGUgKHgsIHksIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTsKIAl9CiAJcmV0dXJuIG5ldyBSZWN0YW5nbGUgKHgsIHksIHdpZHRoLCBoZWlnaHQpOwogfQotLyoqCi0qIEdldHMgdGhlIERpc3BsYXkuCi0qLworCiBwdWJsaWMgRGlzcGxheSBnZXREaXNwbGF5ICgpIHsKIAlDb21wb3NpdGUgcGFyZW50ID0gdGhpcy5wYXJlbnQ7CiAJaWYgKHBhcmVudCA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX1dJREdFVF9ESVNQT1NFRCk7CiAJcmV0dXJuIHBhcmVudC5nZXREaXNwbGF5ICgpOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBmb250IHRoYXQgdGhlIHJlY2VpdmVyIHdpbGwgdXNlIHRvIHBhaW50IHRleHR1YWwgaW5mb3JtYXRpb24uCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBmb250Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBGb250IGdldEZvbnQgKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKGZvbnQgIT0gbnVsbCkgcmV0dXJuIGZvbnQ7CiAJcmV0dXJuIHBhcmVudC5nZXRGb250ICgpOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBpbWFnZSB0aGF0IHRoZSByZWNlaXZlciB3aWxsIHVzZSB0byBwYWludCB0aGUgY2FyZXQuCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBpbWFnZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCisKIHB1YmxpYyBJbWFnZSBnZXRJbWFnZSAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlyZXR1cm4gaW1hZ2U7CiB9Ci0vKioKLSAqIFJldHVybnMgYSBwb2ludCBkZXNjcmliaW5nIHRoZSByZWNlaXZlcidzIGxvY2F0aW9uIHJlbGF0aXZlCi0gKiB0byBpdHMgcGFyZW50IChvciBpdHMgZGlzcGxheSBpZiBpdHMgcGFyZW50IGlzIG51bGwpLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgbG9jYXRpb24KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIFBvaW50IGdldExvY2F0aW9uICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBuZXcgUG9pbnQgKHgsIHkpOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSByZWNlaXZlcidzIHBhcmVudCwgd2hpY2ggbXVzdCBiZSBhIDxjb2RlPkNhbnZhczwvY29kZT4uCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBwYXJlbnQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIENhbnZhcyBnZXRQYXJlbnQgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIHBhcmVudDsKIH0KLS8qKgotICogUmV0dXJucyBhIHBvaW50IGRlc2NyaWJpbmcgdGhlIHJlY2VpdmVyJ3Mgc2l6ZS4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIHNpemUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIFBvaW50IGdldFNpemUgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGltYWdlICE9IG51bGwpIHsKQEAgLTIyMCwyODQgKzEyNiwxMzEgQEAKIAl9CiAJcmV0dXJuIG5ldyBQb2ludCAod2lkdGgsIGhlaWdodCk7CiB9Ci0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGlzIHZpc2libGUsIGFuZAotICogPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAqIDxwPgotICogSWYgb25lIG9mIHRoZSByZWNlaXZlcidzIGFuY2VzdG9ycyBpcyBub3QgdmlzaWJsZSBvciBzb21lCi0gKiBvdGhlciBjb25kaXRpb24gbWFrZXMgdGhlIHJlY2VpdmVyIG5vdCB2aXNpYmxlLCB0aGlzIG1ldGhvZAotICogbWF5IHN0aWxsIGluZGljYXRlIHRoYXQgaXQgaXMgY29uc2lkZXJlZCB2aXNpYmxlIGV2ZW4gdGhvdWdoCi0gKiBpdCBtYXkgbm90IGFjdHVhbGx5IGJlIHNob3dpbmcuCi0gKiA8L3A+Ci0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyB2aXNpYmlsaXR5IHN0YXRlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBib29sZWFuIGdldFZpc2libGUgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIGlzVmlzaWJsZTsKIH0KKwogYm9vbGVhbiBoaWRlQ2FyZXQgKCkgewotCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7Ci0JaWYgKGRpc3BsYXkuY3VycmVudENhcmV0ICE9IHRoaXMpIHJldHVybiBmYWxzZTsKIAlpZiAoIWlzU2hvd2luZykgcmV0dXJuIHRydWU7CiAJaXNTaG93aW5nID0gZmFsc2U7CiAJcmV0dXJuIGRyYXdDYXJldCAoKTsKIH0KLS8qKgotICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVjZWl2ZXIgaXMgdmlzaWJsZSBhbmQgYWxsCi0gKiBvZiB0aGUgcmVjZWl2ZXIncyBhbmNlc3RvcnMgYXJlIHZpc2libGUgYW5kIDxjb2RlPmZhbHNlPC9jb2RlPgotICogb3RoZXJ3aXNlLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgdmlzaWJpbGl0eSBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNnZXRWaXNpYmxlCi0gKi8KKwogcHVibGljIGJvb2xlYW4gaXNWaXNpYmxlICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBpc1Zpc2libGUgJiYgcGFyZW50LmlzVmlzaWJsZSAoKSAmJiBwYXJlbnQuaGFzRm9jdXMgKCk7CiB9CisKIGJvb2xlYW4gaXNGb2N1c0NhcmV0ICgpIHsKIAlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOwogCXJldHVybiB0aGlzID09IGRpc3BsYXkuY3VycmVudENhcmV0OwogfQorCiB2b2lkIGtpbGxGb2N1cyAoKSB7CiAJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKIAlpZiAoZGlzcGxheS5jdXJyZW50Q2FyZXQgIT0gdGhpcykgcmV0dXJuOwotCWlmIChpc1Zpc2libGUpIGhpZGVDYXJldCAoKTsKIAlkaXNwbGF5LnNldEN1cnJlbnRDYXJldCAobnVsbCk7CisJaWYgKGlzVmlzaWJsZSkgaGlkZUNhcmV0ICgpOwogfQorCiB2b2lkIHJlbGVhc2VDaGlsZCAoKSB7CiAJc3VwZXIucmVsZWFzZUNoaWxkICgpOwogCWlmICh0aGlzID09IHBhcmVudC5nZXRDYXJldCAoKSkgcGFyZW50LnNldENhcmV0IChudWxsKTsKIH0KKwogdm9pZCByZWxlYXNlV2lkZ2V0ICgpIHsKIAlzdXBlci5yZWxlYXNlV2lkZ2V0ICgpOwogCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CiAJaWYgKGRpc3BsYXkuY3VycmVudENhcmV0ID09IHRoaXMpIHsKLQkJaWYgKGlzVmlzaWJsZSkgaGlkZUNhcmV0ICgpOworCQloaWRlQ2FyZXQgKCk7CiAJCWRpc3BsYXkuc2V0Q3VycmVudENhcmV0IChudWxsKTsKIAl9CiAJcGFyZW50ID0gbnVsbDsKIAlpbWFnZSA9IG51bGw7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3Mgc2l6ZSBhbmQgbG9jYXRpb24gdG8gdGhlIHJlY3Rhbmd1bGFyCi0gKiBhcmVhIHNwZWNpZmllZCBieSB0aGUgYXJndW1lbnRzLiBUaGUgPGNvZGU+eDwvY29kZT4gYW5kIAotICogPGNvZGU+eTwvY29kZT4gYXJndW1lbnRzIGFyZSByZWxhdGl2ZSB0byB0aGUgcmVjZWl2ZXIncwotICogcGFyZW50IChvciBpdHMgZGlzcGxheSBpZiBpdHMgcGFyZW50IGlzIG51bGwpLgotICoKLSAqIEBwYXJhbSB4IHRoZSBuZXcgeCBjb29yZGluYXRlIGZvciB0aGUgcmVjZWl2ZXIKLSAqIEBwYXJhbSB5IHRoZSBuZXcgeSBjb29yZGluYXRlIGZvciB0aGUgcmVjZWl2ZXIKLSAqIEBwYXJhbSB3aWR0aCB0aGUgbmV3IHdpZHRoIGZvciB0aGUgcmVjZWl2ZXIKLSAqIEBwYXJhbSBoZWlnaHQgdGhlIG5ldyBoZWlnaHQgZm9yIHRoZSByZWNlaXZlcgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRCb3VuZHMgKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlib29sZWFuIHNhbWVQb3NpdGlvbiwgc2FtZUV4dGVudDsKLQlzYW1lUG9zaXRpb24gPSAodGhpcy54ID09IHgpICYmICh0aGlzLnkgPT0geSk7Ci0Jc2FtZUV4dGVudCA9ICh0aGlzLndpZHRoID09IHdpZHRoKSAmJiAodGhpcy5oZWlnaHQgPT0gaGVpZ2h0KTsKLQlpZiAoKHNhbWVQb3NpdGlvbikgJiYgKHNhbWVFeHRlbnQpKSByZXR1cm47Ci0JaWYgKGlzU2hvd2luZykgaGlkZUNhcmV0ICgpOworCWlmICh0aGlzLnggPT0geCAmJiB0aGlzLnkgPT0geSAmJiB0aGlzLndpZHRoID09IHdpZHRoICYmIHRoaXMuaGVpZ2h0ID09IGhlaWdodCkgcmV0dXJuOworCWJvb2xlYW4gaXNGb2N1cyA9IGlzRm9jdXNDYXJldCAoKTsKKwlpZiAoaXNGb2N1cykgaGlkZUNhcmV0ICgpOwogCXRoaXMueCA9IHg7IHRoaXMueSA9IHk7CiAJdGhpcy53aWR0aCA9IHdpZHRoOyB0aGlzLmhlaWdodCA9IGhlaWdodDsKLQlpZiAoc2FtZUV4dGVudCkgewotCQltb3ZlZCA9IHRydWU7Ci0JCWlmIChpc1Zpc2libGUgKCkpIHsKLQkJCW1vdmVkID0gZmFsc2U7Ci0JCQlwYXJlbnQudXBkYXRlQ2FyZXQgKCk7Ci0JCX0KLQl9IGVsc2UgewotCQlyZXNpemVkID0gdHJ1ZTsKLQkJaWYgKGlzVmlzaWJsZSAoKSkgewotCQkJbW92ZWQgPSBmYWxzZTsKLQkJCXBhcmVudC51cGRhdGVDYXJldCAoKTsKLQkJCXJlc2l6ZWQgPSBmYWxzZTsKLQkJfQotCX0KLQlpZiAoaXNTaG93aW5nKSBzaG93Q2FyZXQgKCk7CisvLwlwYXJlbnQudXBkYXRlQ2FyZXQgKCk7CisJaWYgKGlzRm9jdXMpIHNob3dDYXJldCAoKTsKIH0KLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBzaXplIGFuZCBsb2NhdGlvbiB0byB0aGUgcmVjdGFuZ3VsYXIKLSAqIGFyZWEgc3BlY2lmaWVkIGJ5IHRoZSBhcmd1bWVudC4gVGhlIDxjb2RlPng8L2NvZGU+IGFuZCAKLSAqIDxjb2RlPnk8L2NvZGU+IGZpZWxkcyBvZiB0aGUgcmVjdGFuZ2xlIGFyZSByZWxhdGl2ZSB0bwotICogdGhlIHJlY2VpdmVyJ3MgcGFyZW50IChvciBpdHMgZGlzcGxheSBpZiBpdHMgcGFyZW50IGlzIG51bGwpLgotICoKLSAqIEBwYXJhbSByZWN0IHRoZSBuZXcgYm91bmRzIGZvciB0aGUgcmVjZWl2ZXIKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0Qm91bmRzIChSZWN0YW5nbGUgcmVjdCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHJlY3QgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlzZXRCb3VuZHMgKHJlY3QueCwgcmVjdC55LCByZWN0LndpZHRoLCByZWN0LmhlaWdodCk7CiB9CisKIHZvaWQgc2V0Rm9jdXMgKCkgewogCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CiAJaWYgKGRpc3BsYXkuY3VycmVudENhcmV0ID09IHRoaXMpIHJldHVybjsKIAlkaXNwbGF5LnNldEN1cnJlbnRDYXJldCAodGhpcyk7CiAJaWYgKGlzVmlzaWJsZSkgc2hvd0NhcmV0ICgpOwogfQotLyoqCi0gKiBTZXRzIHRoZSBmb250IHRoYXQgdGhlIHJlY2VpdmVyIHdpbGwgdXNlIHRvIHBhaW50IHRleHR1YWwgaW5mb3JtYXRpb24KLSAqIHRvIHRoZSBmb250IHNwZWNpZmllZCBieSB0aGUgYXJndW1lbnQsIG9yIHRvIHRoZSBkZWZhdWx0IGZvbnQgZm9yIHRoYXQKLSAqIGtpbmQgb2YgY29udHJvbCBpZiB0aGUgYXJndW1lbnQgaXMgbnVsbC4KLSAqCi0gKiBAcGFyYW0gZm9udCB0aGUgbmV3IGZvbnQgKG9yIG51bGwpCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfQVJHVU1FTlQgLSBpZiB0aGUgZm9udCBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiA8L3VsPiAKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRGb250IChGb250IGZvbnQpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChmb250ICE9IG51bGwgJiYgZm9udC5pc0Rpc3Bvc2VkICgpKSB7CiAJCWVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CiAJfQotCXRoaXMuZm9udCA9IGZvbnQ7CiB9Ci0vKioKLSAqIFNldHMgdGhlIGltYWdlIHRoYXQgdGhlIHJlY2VpdmVyIHdpbGwgdXNlIHRvIHBhaW50IHRoZSBjYXJldAotICogdG8gdGhlIGltYWdlIHNwZWNpZmllZCBieSB0aGUgYXJndW1lbnQsIG9yIHRvIHRoZSBkZWZhdWx0Ci0gKiB3aGljaCBpcyBhIGZpbGxlZCByZWN0YW5nbGUgaWYgdGhlIGFyZ3VtZW50IGlzIG51bGwKLSAqCi0gKiBAcGFyYW0gZm9udCB0aGUgbmV3IGZvbnQgKG9yIG51bGwpCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfQVJHVU1FTlQgLSBpZiB0aGUgaW1hZ2UgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogPC91bD4gCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0SW1hZ2UgKEltYWdlIGltYWdlKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoaW1hZ2UgIT0gbnVsbCAmJiBpbWFnZS5pc0Rpc3Bvc2VkICgpKSB7CiAJCWVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CiAJfQotCWlmIChpc1Nob3dpbmcpIGhpZGVDYXJldCAoKTsKKwlib29sZWFuIGlzRm9jdXMgPSBpc0ZvY3VzQ2FyZXQgKCk7CisJaWYgKGlzRm9jdXMpIGhpZGVDYXJldCAoKTsKIAl0aGlzLmltYWdlID0gaW1hZ2U7Ci0JaWYgKGlzU2hvd2luZykgc2hvd0NhcmV0ICgpOworCWlmIChpc0ZvY3VzKSBzaG93Q2FyZXQgKCk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgbG9jYXRpb24gdG8gdGhlIHBvaW50IHNwZWNpZmllZCBieQotICogdGhlIGFyZ3VtZW50cyB3aGljaCBhcmUgcmVsYXRpdmUgdG8gdGhlIHJlY2VpdmVyJ3MKLSAqIHBhcmVudCAob3IgaXRzIGRpc3BsYXkgaWYgaXRzIHBhcmVudCBpcyBudWxsKS4KLSAqCi0gKiBAcGFyYW0geCB0aGUgbmV3IHggY29vcmRpbmF0ZSBmb3IgdGhlIHJlY2VpdmVyCi0gKiBAcGFyYW0geSB0aGUgbmV3IHkgY29vcmRpbmF0ZSBmb3IgdGhlIHJlY2VpdmVyCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldExvY2F0aW9uIChpbnQgeCwgaW50IHkpIHsKIAljaGVja1dpZGdldCgpOwogCXNldEJvdW5kcyAoeCwgeSwgd2lkdGgsIGhlaWdodCk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgbG9jYXRpb24gdG8gdGhlIHBvaW50IHNwZWNpZmllZCBieQotICogdGhlIGFyZ3VtZW50IHdoaWNoIGlzIHJlbGF0aXZlIHRvIHRoZSByZWNlaXZlcidzCi0gKiBwYXJlbnQgKG9yIGl0cyBkaXNwbGF5IGlmIGl0cyBwYXJlbnQgaXMgbnVsbCkuCi0gKgotICogQHBhcmFtIGxvY2F0aW9uIHRoZSBuZXcgbG9jYXRpb24gZm9yIHRoZSByZWNlaXZlcgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbiAoUG9pbnQgbG9jYXRpb24pIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsb2NhdGlvbiA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCXNldExvY2F0aW9uIChsb2NhdGlvbi54LCBsb2NhdGlvbi55KTsKIH0KLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBzaXplIHRvIHRoZSBwb2ludCBzcGVjaWZpZWQgYnkgdGhlIGFyZ3VtZW50cy4KLSAqCi0gKiBAcGFyYW0gd2lkdGggdGhlIG5ldyB3aWR0aCBmb3IgdGhlIHJlY2VpdmVyCi0gKiBAcGFyYW0gaGVpZ2h0IHRoZSBuZXcgaGVpZ2h0IGZvciB0aGUgcmVjZWl2ZXIKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0U2l6ZSAoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlzZXRCb3VuZHMgKHgsIHksIHdpZHRoLCBoZWlnaHQpOwogfQotLyoqCi0gKiBTZXRzIHRoZSByZWNlaXZlcidzIHNpemUgdG8gdGhlIHBvaW50IHNwZWNpZmllZCBieSB0aGUgYXJndW1lbnQuCi0gKgotICogQHBhcmFtIHNpemUgdGhlIG5ldyBleHRlbnQgZm9yIHRoZSByZWNlaXZlcgotICogQHBhcmFtIGhlaWdodCB0aGUgbmV3IGhlaWdodCBmb3IgdGhlIHJlY2VpdmVyCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcG9pbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldFNpemUgKFBvaW50IHNpemUpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChzaXplID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJc2V0U2l6ZSAoc2l6ZS54LCBzaXplLnkpOwogfQotLyoqCi0gKiBNYXJrcyB0aGUgcmVjZWl2ZXIgYXMgdmlzaWJsZSBpZiB0aGUgYXJndW1lbnQgaXMgPGNvZGU+dHJ1ZTwvY29kZT4sCi0gKiBhbmQgbWFya3MgaXQgaW52aXNpYmxlIG90aGVyd2lzZS4gCi0gKiA8cD4KLSAqIElmIG9uZSBvZiB0aGUgcmVjZWl2ZXIncyBhbmNlc3RvcnMgaXMgbm90IHZpc2libGUgb3Igc29tZQotICogb3RoZXIgY29uZGl0aW9uIG1ha2VzIHRoZSByZWNlaXZlciBub3QgdmlzaWJsZSwgbWFya2luZwotICogaXQgdmlzaWJsZSBtYXkgbm90IGFjdHVhbGx5IGNhdXNlIGl0IHRvIGJlIGRpc3BsYXllZC4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gdmlzaWJsZSB0aGUgbmV3IHZpc2liaWxpdHkgc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0VmlzaWJsZSAoYm9vbGVhbiB2aXNpYmxlKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAodmlzaWJsZSA9PSBpc1Zpc2libGUpIHJldHVybjsKLQlpZiAoaXNWaXNpYmxlID0gdmlzaWJsZSkgeworCWlzVmlzaWJsZSA9IHZpc2libGU7CisJaWYgKCFpc0ZvY3VzQ2FyZXQgKCkpIHJldHVybjsKKwlpZiAoaXNWaXNpYmxlKSB7CiAJCXNob3dDYXJldCAoKTsKIAl9IGVsc2UgewogCQloaWRlQ2FyZXQgKCk7CiAJfQogfQorCiBib29sZWFuIHNob3dDYXJldCAoKSB7Ci0JaWYgKGdldERpc3BsYXkgKCkuY3VycmVudENhcmV0ICE9IHRoaXMpIHJldHVybiBmYWxzZTsKIAlpZiAoaXNTaG93aW5nKSByZXR1cm4gdHJ1ZTsKIAlpc1Nob3dpbmcgPSB0cnVlOwogCXJldHVybiBkcmF3Q2FyZXQgKCk7CiB9CisKIH0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Db2xvckRpYWxvZy5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0NvbG9yRGlhbG9nLmphdmEKaW5kZXggYWQxMDllMC4uNGE2ZWE2MyAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0NvbG9yRGlhbG9nLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0NvbG9yRGlhbG9nLmphdmEKQEAgLTEyLDEzNCArMTIsNjEgQEAKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLlJHQjsKIAotLyoqCi0gKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBhbGxvdyB0aGUgdXNlciB0byBzZWxlY3QgYSBjb2xvcgotICogZnJvbSBhIHByZWRlZmluZWQgc2V0IG9mIGF2YWlsYWJsZSBjb2xvcnMuCi0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPihub25lKTwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPihub25lKTwvZGQ+Ci0gKiA8L2RsPgotICogPHA+Ci0gKiBJTVBPUlRBTlQ6IFRoaXMgY2xhc3MgaXMgaW50ZW5kZWQgdG8gYmUgc3ViY2xhc3NlZCA8ZW0+b25seTwvZW0+Ci0gKiB3aXRoaW4gdGhlIFNXVCBpbXBsZW1lbnRhdGlvbi4KLSAqIDwvcD4KLSAqLwotcHVibGljIC8qZmluYWwqLyBjbGFzcyBDb2xvckRpYWxvZyBleHRlbmRzIERpYWxvZyB7Ci0KLQlwcml2YXRlIFJHQiByZ2I7Ci0JcHJpdmF0ZSBzaG9ydFtdIGZDb2xvcj0gbmV3IHNob3J0WzNdOworcHVibGljIGNsYXNzIENvbG9yRGlhbG9nIGV4dGVuZHMgRGlhbG9nIHsKKwlSR0IgcmdiOwogCQotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gb25seSBpdHMgcGFyZW50LgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBjb21wb3NpdGUgY29udHJvbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZSAoY2Fubm90IGJlIG51bGwpCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcGFyZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHBhcmVudDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNXVAotICogQHNlZSBXaWRnZXQjY2hlY2tTdWJjbGFzcwotICogQHNlZSBXaWRnZXQjZ2V0U3R5bGUKLSAqLwogcHVibGljIENvbG9yRGlhbG9nKFNoZWxsIHBhcmVudCkgewotCXRoaXMocGFyZW50LCBTV1QuTlVMTCk7Ci19Ci0vKioKLSAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50Ci0gKiBhbmQgYSBzdHlsZSB2YWx1ZSBkZXNjcmliaW5nIGl0cyBiZWhhdmlvciBhbmQgYXBwZWFyYW5jZS4KLSAqIDxwPgotICogVGhlIHN0eWxlIHZhbHVlIGlzIGVpdGhlciBvbmUgb2YgdGhlIHN0eWxlIGNvbnN0YW50cyBkZWZpbmVkIGluCi0gKiBjbGFzcyA8Y29kZT5TV1Q8L2NvZGU+IHdoaWNoIGlzIGFwcGxpY2FibGUgdG8gaW5zdGFuY2VzIG9mIHRoaXMKLSAqIGNsYXNzLCBvciBtdXN0IGJlIGJ1aWx0IGJ5IDxlbT5iaXR3aXNlIE9SPC9lbT4naW5nIHRvZ2V0aGVyIAotICogKHRoYXQgaXMsIHVzaW5nIHRoZSA8Y29kZT5pbnQ8L2NvZGU+ICJ8IiBvcGVyYXRvcikgdHdvIG9yIG1vcmUKLSAqIG9mIHRob3NlIDxjb2RlPlNXVDwvY29kZT4gc3R5bGUgY29uc3RhbnRzLiBUaGUgY2xhc3MgZGVzY3JpcHRpb24KLSAqIGxpc3RzIHRoZSBzdHlsZSBjb25zdGFudHMgdGhhdCBhcmUgYXBwbGljYWJsZSB0byB0aGUgY2xhc3MuCi0gKiBTdHlsZSBiaXRzIGFyZSBhbHNvIGluaGVyaXRlZCBmcm9tIHN1cGVyY2xhc3Nlcy4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gcGFyZW50IGEgY29tcG9zaXRlIGNvbnRyb2wgd2hpY2ggd2lsbCBiZSB0aGUgcGFyZW50IG9mIHRoZSBuZXcgaW5zdGFuY2UgKGNhbm5vdCBiZSBudWxsKQotICogQHBhcmFtIHN0eWxlIHRoZSBzdHlsZSBvZiBjb250cm9sIHRvIGNvbnN0cnVjdAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTV1QKLSAqIEBzZWUgV2lkZ2V0I2NoZWNrU3ViY2xhc3MKLSAqIEBzZWUgV2lkZ2V0I2dldFN0eWxlCi0gKi8KLXB1YmxpYyBDb2xvckRpYWxvZyhTaGVsbCBwYXJlbnQsIGludCBzdHlsZSkgewotCXN1cGVyKHBhcmVudCwgc3R5bGUgfCBTV1QuVElUTEUgfCBTV1QuQk9SREVSIHwgU1dULkFQUExJQ0FUSU9OX01PREFMKTsKKwl0aGlzKHBhcmVudCwgU1dULkFQUExJQ0FUSU9OX01PREFMKTsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgY29sb3IgaW4gdGhlIHJlY2VpdmVyLgotICoKLSAqIEByZXR1cm4gdGhlIFJHQiB2YWx1ZSBmb3IgdGhlIHNlbGVjdGVkIGNvbG9yLCBtYXkgYmUgbnVsbAotICoKLSAqIEBzZWUgUGFsZXR0ZURhdGEjZ2V0UkdCcwotICovCitwdWJsaWMgQ29sb3JEaWFsb2coU2hlbGwgcGFyZW50LCBpbnQgc3R5bGUpIHsKKwlzdXBlcihwYXJlbnQsIHN0eWxlKTsKKwljaGVja1N1YmNsYXNzICgpOworfQorCiBwdWJsaWMgUkdCIGdldFJHQigpIHsKIAlyZXR1cm4gcmdiOwogfQotLyoqCi0gKiBNYWtlcyB0aGUgcmVjZWl2ZXIgdmlzaWJsZSBhbmQgYnJpbmdzIGl0IHRvIHRoZSBmcm9udAotICogb2YgdGhlIGRpc3BsYXkuCi0gKgotICogQHJldHVybiB0aGUgc2VsZWN0ZWQgY29sb3IsIG9yIG51bGwgaWYgdGhlIGRpYWxvZyB3YXMKLSAqICAgICAgICAgY2FuY2VsbGVkLCBubyBjb2xvciB3YXMgc2VsZWN0ZWQsIG9yIGFuIGVycm9yCi0gKiAgICAgICAgIG9jY3VycmVkCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCi1wdWJsaWMgUkdCIG9wZW4oKSB7CiAKLQlNYWNQb2ludCBtcD0gbmV3IE1hY1BvaW50KCk7Ci0JT1MuR2V0R2xvYmFsTW91c2UobXAuZ2V0RGF0YSgpKTsKLQkKLQlib29sZWFuW10gc3VjY2Vzcz0gbmV3IGJvb2xlYW5bMV07Ci0JaWYgKE9TLlBpY2tDb2xvcihmQ29sb3IsIG1wLmdldERhdGEoKSwgTWFjVXRpbC5TdHIyNTUodGl0bGUpLCBzdWNjZXNzKSA9PSBPUy5rTm9FcnIpIHsKLQkJaWYgKHN1Y2Nlc3NbMF0pIHsKLQkJCWlmIChyZ2IgPT0gbnVsbCkKLQkJCQlyZ2I9IG5ldyBSR0IoMCwgMCwgMCk7Ci0JCQlyZ2IucmVkPQkoZkNvbG9yWzBdID4+IDgpICYgMHhmZjsKLQkJCXJnYi5ncmVlbj0JKGZDb2xvclsxXSA+PiA4KSAmIDB4ZmY7Ci0JCQlyZ2IuYmx1ZT0JKGZDb2xvclsyXSA+PiA4KSAmIDB4ZmY7Ci0JCX0gZWxzZQotCQkJcmdiPSBudWxsOwotCX0gZWxzZQotCQlyZ2I9IG51bGw7Ci0JCitwdWJsaWMgUkdCIG9wZW4oKSB7CQorCUNvbG9yUGlja2VySW5mbyBpbmZvID0gbmV3IENvbG9yUGlja2VySW5mbyAoKTsKKwlpZiAocmdiICE9IG51bGwpIHsKKwkJaW5mby5yZWQgPSAoc2hvcnQpKHJnYi5yZWQgKiAyNTcpOworCQlpbmZvLmdyZWVuID0gKHNob3J0KShyZ2IuZ3JlZW4gKiAyNTcpOworCQlpbmZvLmJsdWUgPSAoc2hvcnQpKHJnYi5ibHVlICogMjU3KTsKKwl9IGVsc2UgeworCQlpbmZvLnJlZCA9IChzaG9ydCkoMjU1ICogMjU3KTsKKwkJaW5mby5ncmVlbiA9IChzaG9ydCkoMjU1ICogMjU3KTsKKwkJaW5mby5ibHVlID0gKHNob3J0KSgyNTUgKiAyNTcpOwkJCisJfQorCWluZm8uZmxhZ3MgPSBPUy5rQ29sb3JQaWNrZXJEaWFsb2dJc01vdmVhYmxlIHwgT1Mua0NvbG9yUGlja2VyRGlhbG9nSXNNb2RhbDsKKwkvLyBORUVEUyBXT1JLIC0gc2hvdWxkbid0IGJlIGF0IG1vdXNlIGxvY2F0aW9uCisJaW5mby5wbGFjZVdoZXJlID0gKHNob3J0KU9TLmtBdFNwZWNpZmllZE9yaWdpbjsKKwlvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBvaW50IG1wID0gbmV3IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgKCk7CisJT1MuR2V0R2xvYmFsTW91c2UgKG1wKTsKKwlpbmZvLnYgPSBtcC52OworCWluZm8uaCA9IG1wLmg7CisJaWYgKHRpdGxlICE9IG51bGwpIHsKKwkJLy8gTkVFRFMgV09SSyAtIG5vIHRpdGxlIGRpc3BsYXllZAkJCisJCWluZm8ucHJvbXB0ID0gbmV3IGJ5dGVbMjU2XTsKKwkJaW50IGxlbmd0aCA9IHRpdGxlLmxlbmd0aCgpOworCQlpZiAobGVuZ3RoID4gMjU1KSBsZW5ndGggPSAyNTU7CisJCWluZm8ucHJvbXB0IFswXSA9IChieXRlKWxlbmd0aDsKKwkJZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSB7CisJCQlpbmZvLnByb21wdCBbaSsxXSA9IChieXRlKXRpdGxlLmNoYXJBdCAoaSk7CisJCX0KKwl9CisJcmdiID0gbnVsbDsKKwlpZiAoT1MuUGlja0NvbG9yIChpbmZvKSA9PSBPUy5ub0VyciAmJiBpbmZvLm5ld0NvbG9yQ2hvc2VuKSB7CisJCWludCByZWQgPSAoaW5mby5yZWQgPj4gOCkgJiAweEZGOworCQlpbnQgZ3JlZW4gPSAoaW5mby5ncmVlbiA+PiA4KSAmIDB4RkY7CisJCWludCBibHVlID0JKGluZm8uYmx1ZSA+PiA4KSAmIDB4RkY7CisJCXJnYiA9IG5ldyBSR0IocmVkLCBncmVlbiwgYmx1ZSk7CisJfQogCXJldHVybiByZ2I7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3Mgc2VsZWN0ZWQgY29sb3IgdG8gYmUgdGhlIGFyZ3VtZW50LgotICoKLSAqIEBwYXJhbSByZ2IgdGhlIG5ldyBSR0IgdmFsdWUgZm9yIHRoZSBzZWxlY3RlZCBjb2xvciwgbWF5IGJlCi0gKiAgICAgICAgbnVsbCB0byBsZXQgdGhlIHBsYXRmb3JtIHRvIHNlbGVjdCBhIGRlZmF1bHQgd2hlbgotICogICAgICAgIG9wZW4oKSBpcyBjYWxsZWQKLSAqCi0gKiBAc2VlIFBhbGV0dGVEYXRhI2dldFJHQnMKLSAqLworCiBwdWJsaWMgdm9pZCBzZXRSR0IoUkdCIHJnYikgewogCXRoaXMucmdiID0gcmdiOwotCWZDb2xvclswXT0gKHNob3J0KSAocmdiLnJlZCAqIDI1Nyk7Ci0JZkNvbG9yWzFdPSAoc2hvcnQpIChyZ2IuZ3JlZW4gKiAyNTcpOwotCWZDb2xvclsyXT0gKHNob3J0KSAocmdiLmJsdWUgKiAyNTcpOwotCiB9CiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvQ29tYm8uamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Db21iby5qYXZhCmluZGV4IDMxOTJhOWEuLjRhZTVjYTggMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Db21iby5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Db21iby5qYXZhCkBAIC04LDYwICs4LDIwIEBACiAgKi8KIAogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZG5kLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uT1M7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5DRlJhbmdlOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uQ0dSZWN0OworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUmVjdDsKIAotLyoqCi0gKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBhcmUgY29udHJvbHMgdGhhdCBhbGxvdyB0aGUgdXNlcgotICogdG8gY2hvb3NlIGFuIGl0ZW0gZnJvbSBhIGxpc3Qgb2YgaXRlbXMsIG9yIG9wdGlvbmFsbHkgCi0gKiBlbnRlciBhIG5ldyB2YWx1ZSBieSB0eXBpbmcgaXQgaW50byBhbiBlZGl0YWJsZSB0ZXh0Ci0gKiBmaWVsZC4gT2Z0ZW4sIDxjb2RlPkNvbWJvPC9jb2RlPnMgYXJlIHVzZWQgaW4gdGhlIHNhbWUgcGxhY2UKLSAqIHdoZXJlIGEgc2luZ2xlIHNlbGVjdGlvbiA8Y29kZT5MaXN0PC9jb2RlPiB3aWRnZXQgY291bGQKLSAqIGJlIHVzZWQgYnV0IHNwYWNlIGlzIGxpbWl0ZWQuIEEgPGNvZGU+Q29tYm88L2NvZGU+IHRha2VzCi0gKiBsZXNzIHNwYWNlIHRoYW4gYSA8Y29kZT5MaXN0PC9jb2RlPiB3aWRnZXQgYW5kIHNob3dzCi0gKiBzaW1pbGFyIGluZm9ybWF0aW9uLgotICogPHA+Ci0gKiBOb3RlOiBTaW5jZSA8Y29kZT5Db21ibzwvY29kZT5zIGNhbiBjb250YWluIGJvdGggYSBsaXN0Ci0gKiBhbmQgYW4gZWRpdGFibGUgdGV4dCBmaWVsZCwgaXQgaXMgcG9zc2libGUgdG8gY29uZnVzZSBtZXRob2RzCi0gKiB3aGljaCBhY2Nlc3Mgb25lIHZlcnN1cyB0aGUgb3RoZXIgKGNvbXBhcmUgZm9yIGV4YW1wbGUsCi0gKiA8Y29kZT5jbGVhclNlbGVjdGlvbigpPC9jb2RlPiBhbmQgPGNvZGU+ZGVzZWxlY3RBbGwoKTwvY29kZT4pLgotICogVGhlIEFQSSBkb2N1bWVudGF0aW9uIGlzIGNhcmVmdWwgdG8gaW5kaWNhdGUgZWl0aGVyICJ0aGUKLSAqIHJlY2VpdmVyJ3MgbGlzdCIgb3IgdGhlICJ0aGUgcmVjZWl2ZXIncyB0ZXh0IGZpZWxkIiB0byAKLSAqIGRpc3Rpbmd1aXNoIGJldHdlZW4gdGhlIHR3byBjYXNlcy4KLSAqIDwvcD48cD4KLSAqIE5vdGUgdGhhdCBhbHRob3VnaCB0aGlzIGNsYXNzIGlzIGEgc3ViY2xhc3Mgb2YgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiwKLSAqIGl0IGRvZXMgbm90IG1ha2Ugc2Vuc2UgdG8gYWRkIGNoaWxkcmVuIHRvIGl0LCBvciBzZXQgYSBsYXlvdXQgb24gaXQuCi0gKiA8L3A+Ci0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPkRST1BfRE9XTiwgUkVBRF9PTkxZLCBTSU1QTEU8L2RkPgotICogPGR0PjxiPkV2ZW50czo8L2I+PC9kdD4KLSAqIDxkZD5EZWZhdWx0U2VsZWN0aW9uLCBNb2RpZnksIFNlbGVjdGlvbjwvZGQ+Ci0gKiA8L2RsPgotICogPHA+Ci0gKiBOb3RlOiBPbmx5IG9uZSBvZiB0aGUgc3R5bGVzIERST1BfRE9XTiBhbmQgU0lNUExFIAotICogbWF5IGJlIHNwZWNpZmllZC4KLSAqIDwvcD48cD4KLSAqIElNUE9SVEFOVDogVGhpcyBjbGFzcyBpcyA8ZW0+bm90PC9lbT4gaW50ZW5kZWQgdG8gYmUgc3ViY2xhc3NlZC4KLSAqIDwvcD4KLSAqCi0gKiBAc2VlIExpc3QKLSAqLwotcHVibGljIC8qZmluYWwqLyBjbGFzcyBDb21ibyBleHRlbmRzIENvbXBvc2l0ZSB7CitwdWJsaWMgY2xhc3MgQ29tYm8gZXh0ZW5kcyBDb21wb3NpdGUgewogCiAJLyoqCiAJICogdGhlIG9wZXJhdGluZyBzeXN0ZW0gbGltaXQgZm9yIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycwogCSAqIHRoYXQgdGhlIHRleHQgZmllbGQgaW4gYW4gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBjYW4gaG9sZAogCSAqLwogCXB1YmxpYyBzdGF0aWMgaW50IExJTUlUOwotCXByaXZhdGUgc3RhdGljIGludCBmZ0NvbW1hbmRJRD0gNjAwMDsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRk9DVVNfQk9SREVSPSAzOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVJHSU49IDI7Ci0KLQlwcml2YXRlIGludCBtZW51SGFuZGxlOwotCXByaXZhdGUgaW50IHRleHRMaW1pdD0gTElNSVQ7CiAJCiAJLyoKIAkqIFRoZXNlIHZhbHVlcyBjYW4gYmUgZGlmZmVyZW50IG9uIGRpZmZlcmVudCBwbGF0Zm9ybXMuCkBAIC03MSwxNzMgKzMxLDU5IEBACiAJc3RhdGljIHsKIAkJTElNSVQgPSAweDdGRkZGRkZGOwogCX0KKwkKKwkvLyBORUVEUyBXT1JLIC0gaXMgdGhpcyBoYW5kbGUgYmVpbmcgbGVha2VkPworCWludCBtZW51SGFuZGxlOwogCi0vKioKLSAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50Ci0gKiBhbmQgYSBzdHlsZSB2YWx1ZSBkZXNjcmliaW5nIGl0cyBiZWhhdmlvciBhbmQgYXBwZWFyYW5jZS4KLSAqIDxwPgotICogVGhlIHN0eWxlIHZhbHVlIGlzIGVpdGhlciBvbmUgb2YgdGhlIHN0eWxlIGNvbnN0YW50cyBkZWZpbmVkIGluCi0gKiBjbGFzcyA8Y29kZT5TV1Q8L2NvZGU+IHdoaWNoIGlzIGFwcGxpY2FibGUgdG8gaW5zdGFuY2VzIG9mIHRoaXMKLSAqIGNsYXNzLCBvciBtdXN0IGJlIGJ1aWx0IGJ5IDxlbT5iaXR3aXNlIE9SPC9lbT4naW5nIHRvZ2V0aGVyIAotICogKHRoYXQgaXMsIHVzaW5nIHRoZSA8Y29kZT5pbnQ8L2NvZGU+ICJ8IiBvcGVyYXRvcikgdHdvIG9yIG1vcmUKLSAqIG9mIHRob3NlIDxjb2RlPlNXVDwvY29kZT4gc3R5bGUgY29uc3RhbnRzLiBUaGUgY2xhc3MgZGVzY3JpcHRpb24KLSAqIGxpc3RzIHRoZSBzdHlsZSBjb25zdGFudHMgdGhhdCBhcmUgYXBwbGljYWJsZSB0byB0aGUgY2xhc3MuCi0gKiBTdHlsZSBiaXRzIGFyZSBhbHNvIGluaGVyaXRlZCBmcm9tIHN1cGVyY2xhc3Nlcy4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gcGFyZW50IGEgY29tcG9zaXRlIGNvbnRyb2wgd2hpY2ggd2lsbCBiZSB0aGUgcGFyZW50IG9mIHRoZSBuZXcgaW5zdGFuY2UgKGNhbm5vdCBiZSBudWxsKQotICogQHBhcmFtIHN0eWxlIHRoZSBzdHlsZSBvZiBjb250cm9sIHRvIGNvbnN0cnVjdAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTV1QjRFJPUF9ET1dOCi0gKiBAc2VlIFNXVCNSRUFEX09OTFkKLSAqIEBzZWUgU1dUI1NJTVBMRQotICogQHNlZSBXaWRnZXQjY2hlY2tTdWJjbGFzcwotICogQHNlZSBXaWRnZXQjZ2V0U3R5bGUKLSAqLwogcHVibGljIENvbWJvIChDb21wb3NpdGUgcGFyZW50LCBpbnQgc3R5bGUpIHsKIAlzdXBlciAocGFyZW50LCBjaGVja1N0eWxlIChzdHlsZSkpOwogfQotLyoqCi0gKiBBZGRzIHRoZSBhcmd1bWVudCB0byB0aGUgZW5kIG9mIHRoZSByZWNlaXZlcidzIGxpc3QuCi0gKgotICogQHBhcmFtIHN0cmluZyB0aGUgbmV3IGl0ZW0KLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBzdHJpbmcgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSVRFTV9OT1RfQURERUQgLSBpZiB0aGUgb3BlcmF0aW9uIGZhaWxzIGJlY2F1c2Ugb2YgYW4gb3BlcmF0aW5nIHN5c3RlbSBmYWlsdXJlPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjYWRkKFN0cmluZyxpbnQpCi0gKi8KLXB1YmxpYyB2b2lkIGFkZCAoU3RyaW5nIHN0cmluZykgewotCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKHN0cmluZyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCQotCWludCBzSGFuZGxlPSAwOwotCXRyeSB7Ci0JCXNIYW5kbGU9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMoc3RyaW5nKTsKLQkJaWYgKG1lbnVIYW5kbGUgIT0gMCkgewotCQkJaWYgKE9TLkFwcGVuZE1lbnVJdGVtVGV4dFdpdGhDRlN0cmluZyhtZW51SGFuZGxlLCBzSGFuZGxlLCAwLCBmZ0NvbW1hbmRJRCsrLCBudWxsKSAhPSBPUy5rTm9FcnIpCi0JCQkJZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9BRERFRCk7Ci0JCQlPUy5TZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSwgT1MuQ291bnRNZW51SXRlbXMobWVudUhhbmRsZSkpOwkKLQkJfSBlbHNlIHsKLQkJCWlmIChPUy5ISUNvbWJvQm94QXBwZW5kVGV4dEl0ZW0oaGFuZGxlLCBzSGFuZGxlKSAhPSBPUy5rTm9FcnIpCi0JCQkJZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9BRERFRCk7Ci0JCX0KLQl9IGZpbmFsbHkgewotCQlpZiAoc0hhbmRsZSAhPSAwKQotCQkJT1MuQ0ZSZWxlYXNlKHNIYW5kbGUpOwotCX0KLX0KLS8qKgotICogQWRkcyB0aGUgYXJndW1lbnQgdG8gdGhlIHJlY2VpdmVyJ3MgbGlzdCBhdCB0aGUgZ2l2ZW4KLSAqIHplcm8tcmVsYXRpdmUgaW5kZXguCi0gKiA8cD4KLSAqIE5vdGU6IFRvIGFkZCBhbiBpdGVtIGF0IHRoZSBlbmQgb2YgdGhlIGxpc3QsIHVzZSB0aGUKLSAqIHJlc3VsdCBvZiBjYWxsaW5nIDxjb2RlPmdldEl0ZW1Db3VudCgpPC9jb2RlPiBhcyB0aGUKLSAqIGluZGV4IG9yIHVzZSA8Y29kZT5hZGQoU3RyaW5nKTwvY29kZT4uCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHN0cmluZyB0aGUgbmV3IGl0ZW0KLSAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggZm9yIHRoZSBpdGVtCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgc3RyaW5nIGlzIG51bGw8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfUkFOR0UgLSBpZiB0aGUgaW5kZXggaXMgbm90IGJldHdlZW4gMCBhbmQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgbGlzdCAoaW5jbHVzaXZlKTwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSVRFTV9OT1RfQURERUQgLSBpZiB0aGUgb3BlcmF0aW9uIGZhaWxzIGJlY2F1c2Ugb2YgYW4gb3BlcmF0aW5nIHN5c3RlbSBmYWlsdXJlPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjYWRkKFN0cmluZykKLSAqLwotcHVibGljIHZvaWQgYWRkIChTdHJpbmcgc3RyaW5nLCBpbnQgaW5kZXgpIHsKLQljaGVja1dpZGdldCgpOwotCWlmIChzdHJpbmcgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQlpZiAoaW5kZXggPT0gLTEpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7CiAKLQlpbnQgc0hhbmRsZT0gMDsKLQl0cnkgewotCQlzSGFuZGxlPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzKHN0cmluZyk7Ci0JCWlmIChtZW51SGFuZGxlICE9IDApIHsKLQkJCWlmIChPUy5JbnNlcnRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcobWVudUhhbmRsZSwgc0hhbmRsZSwgKHNob3J0KWluZGV4LCAwLCBmZ0NvbW1hbmRJRCsrKSAhPSBPUy5rTm9FcnIpCi0JCQkJZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9BRERFRCk7Ci0JCQlPUy5TZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSwgT1MuQ291bnRNZW51SXRlbXMobWVudUhhbmRsZSkpOwkKLQkJfSBlbHNlIHsKLQkJCU9TLkhJQ29tYm9Cb3hJbnNlcnRUZXh0SXRlbUF0SW5kZXgoaGFuZGxlLCBpbmRleCwgc0hhbmRsZSk7Ci0JCX0KLQl9IGZpbmFsbHkgewotCQlpZiAoc0hhbmRsZSAhPSAwKQotCQkJT1MuQ0ZSZWxlYXNlKHNIYW5kbGUpOworcHVibGljIHZvaWQgYWRkIChTdHJpbmcgc3RyaW5nKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKHN0cmluZyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwkKKwkKKwljaGFyIFtdIGJ1ZmZlciA9IG5ldyBjaGFyIFtzdHJpbmcubGVuZ3RoICgpXTsKKwlzdHJpbmcuZ2V0Q2hhcnMgKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlciwgMCk7CisJaW50IHB0ciA9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMgKE9TLmtDRkFsbG9jYXRvckRlZmF1bHQsIGJ1ZmZlciwgYnVmZmVyLmxlbmd0aCk7CisJaWYgKHB0ciA9PSAwKSBlcnJvciAoU1dULkVSUk9SX0lURU1fTk9UX0FEREVEKTsKKwlpbnQgcmVzdWx0OworCWlmICgoc3R5bGUgJiBTV1QuUkVBRF9PTkxZKSAhPSAwKSB7CisJCXJlc3VsdCA9IE9TLkFwcGVuZE1lbnVJdGVtVGV4dFdpdGhDRlN0cmluZyAobWVudUhhbmRsZSwgcHRyLCAwLCAwLCBudWxsKTsKKwl9IGVsc2UgeworCQlyZXN1bHQgPSBPUy5ISUNvbWJvQm94QXBwZW5kVGV4dEl0ZW0gKGhhbmRsZSwgcHRyLCBudWxsKTsKIAl9CisJT1MuQ0ZSZWxlYXNlIChwdHIpOworCWlmIChyZXN1bHQgIT0gT1Mubm9FcnIpIGVycm9yIChTV1QuRVJST1JfSVRFTV9OT1RfQURERUQpOwogfQotLyoqCi0gKiBBZGRzIHRoZSBsaXN0ZW5lciB0byB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIHJlY2VpdmVyJ3MgdGV4dCBpcyBtb2RpZmllZCwgYnkgc2VuZGluZwotICogaXQgb25lIG9mIHRoZSBtZXNzYWdlcyBkZWZpbmVkIGluIHRoZSA8Y29kZT5Nb2RpZnlMaXN0ZW5lcjwvY29kZT4KLSAqIGludGVyZmFjZS4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIE1vZGlmeUxpc3RlbmVyCi0gKiBAc2VlICNyZW1vdmVNb2RpZnlMaXN0ZW5lcgotICovCisKK3B1YmxpYyB2b2lkIGFkZCAoU3RyaW5nIHN0cmluZywgaW50IGluZGV4KSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKHN0cmluZyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWludCBjb3VudCA9IGdldEl0ZW1Db3VudCAoKTsKKwlpZiAoMCA+IGluZGV4IHx8IGluZGV4ID4gY291bnQpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7CisJCisJY2hhciBbXSBidWZmZXIgPSBuZXcgY2hhciBbc3RyaW5nLmxlbmd0aCAoKV07CisJc3RyaW5nLmdldENoYXJzICgwLCBidWZmZXIubGVuZ3RoLCBidWZmZXIsIDApOworCWludCBwdHIgPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzIChPUy5rQ0ZBbGxvY2F0b3JEZWZhdWx0LCBidWZmZXIsIGJ1ZmZlci5sZW5ndGgpOworCWlmIChwdHIgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9BRERFRCk7CisJaW50IHJlc3VsdDsKKwlpZiAoKHN0eWxlICYgU1dULlJFQURfT05MWSkgIT0gMCkgeworCQlyZXN1bHQgPSBPUy5JbnNlcnRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcgKG1lbnVIYW5kbGUsIHB0ciwgKHNob3J0KWluZGV4LCAwLCAwKTsKKwl9IGVsc2UgeworCQlyZXN1bHQgPSBPUy5ISUNvbWJvQm94SW5zZXJ0VGV4dEl0ZW1BdEluZGV4IChoYW5kbGUsIGluZGV4LCBwdHIpOworCX0KKwlPUy5DRlJlbGVhc2UgKHB0cik7CisJaWYgKHJlc3VsdCAhPSBPUy5ub0VycikgZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9BRERFRCk7Cit9CisKIHB1YmxpYyB2b2lkIGFkZE1vZGlmeUxpc3RlbmVyIChNb2RpZnlMaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJVHlwZWRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IFR5cGVkTGlzdGVuZXIgKGxpc3RlbmVyKTsKIAlhZGRMaXN0ZW5lciAoU1dULk1vZGlmeSwgdHlwZWRMaXN0ZW5lcik7CiB9Ci0vKioKLSAqIEFkZHMgdGhlIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgcmVjZWl2ZXIncyBzZWxlY3Rpb24gY2hhbmdlcywgYnkgc2VuZGluZwotICogaXQgb25lIG9mIHRoZSBtZXNzYWdlcyBkZWZpbmVkIGluIHRoZSA8Y29kZT5TZWxlY3Rpb25MaXN0ZW5lcjwvY29kZT4KLSAqIGludGVyZmFjZS4KLSAqIDxwPgotICogPGNvZGU+d2lkZ2V0U2VsZWN0ZWQ8L2NvZGU+IGlzIGNhbGxlZCB3aGVuIHRoZSBjb21ibydzIGxpc3Qgc2VsZWN0aW9uIGNoYW5nZXMuCi0gKiA8Y29kZT53aWRnZXREZWZhdWx0U2VsZWN0ZWQ8L2NvZGU+IGlzIHR5cGljYWxseSBjYWxsZWQgd2hlbiBFTlRFUiBpcyBwcmVzc2VkIHRoZSBjb21ibydzIHRleHQgYXJlYS4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNlbGVjdGlvbkxpc3RlbmVyCi0gKiBAc2VlICNyZW1vdmVTZWxlY3Rpb25MaXN0ZW5lcgotICogQHNlZSBTZWxlY3Rpb25FdmVudAotICovCisKIHB1YmxpYyB2b2lkIGFkZFNlbGVjdGlvbkxpc3RlbmVyKFNlbGVjdGlvbkxpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTI0NSwxMyArOTEsOCBAQAogCWFkZExpc3RlbmVyIChTV1QuU2VsZWN0aW9uLHR5cGVkTGlzdGVuZXIpOwogCWFkZExpc3RlbmVyIChTV1QuRGVmYXVsdFNlbGVjdGlvbix0eXBlZExpc3RlbmVyKTsKIH0KLXN0YXRpYyBpbnQgY2hlY2tTdHlsZSAoaW50IHN0eWxlKSB7CiAKLQkvLyBBVyBvbmx5IFJFQURfT05MWSBpcyBpbXBsZW1lbnRlZAotCXN0eWxlICY9IH5TV1QuRFJPUF9ET1dOOwotCXN0eWxlICY9IH5TV1QuU0lNUExFOwotCS8vIEFXCi0JCitzdGF0aWMgaW50IGNoZWNrU3R5bGUgKGludCBzdHlsZSkgewogCS8qCiAJKiBGZWF0dXJlIGluIFdpbmRvd3MuICBJdCBpcyBub3QgcG9zc2libGUgdG8gY3JlYXRlCiAJKiBhIGNvbWJvIGJveCB0aGF0IGhhcyBhIGJvcmRlciB1c2luZyBXaW5kb3dzIHN0eWxlCkBAIC0yNzgsNzA1ICsxMTksNDUzIEBACiAJaWYgKChzdHlsZSAmIFNXVC5TSU1QTEUpICE9IDApIHJldHVybiBzdHlsZSAmIH5TV1QuUkVBRF9PTkxZOwogCXJldHVybiBzdHlsZTsKIH0KKwogcHJvdGVjdGVkIHZvaWQgY2hlY2tTdWJjbGFzcyAoKSB7CiAJaWYgKCFpc1ZhbGlkU3ViY2xhc3MgKCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9TVUJDTEFTUyk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHNlbGVjdGlvbiBpbiB0aGUgcmVjZWl2ZXIncyB0ZXh0IGZpZWxkIHRvIGFuIGVtcHR5Ci0gKiBzZWxlY3Rpb24gc3RhcnRpbmcganVzdCBiZWZvcmUgdGhlIGZpcnN0IGNoYXJhY3Rlci4gSWYgdGhlCi0gKiB0ZXh0IGZpZWxkIGlzIGVkaXRhYmxlLCB0aGlzIGhhcyB0aGUgZWZmZWN0IG9mIHBsYWNpbmcgdGhlCi0gKiBpLWJlYW0gYXQgdGhlIHN0YXJ0IG9mIHRoZSB0ZXh0LgotICogPHA+Ci0gKiBOb3RlOiBUbyBjbGVhciB0aGUgc2VsZWN0ZWQgaXRlbXMgaW4gdGhlIHJlY2VpdmVyJ3MgbGlzdCwgCi0gKiB1c2UgPGNvZGU+ZGVzZWxlY3RBbGwoKTwvY29kZT4uCi0gKiA8L3A+Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI2Rlc2VsZWN0QWxsCi0gKi8KKwogcHVibGljIHZvaWQgY2xlYXJTZWxlY3Rpb24gKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKG1lbnVIYW5kbGUgPT0gMCkKLQkJT1MuU2V0Q29udHJvbERhdGEoaGFuZGxlLCBPUy5rSElDb21ib0JveEVkaXRUZXh0UGFydCwgT1Mua0NvbnRyb2xFZGl0VGV4dFNlbGVjdGlvblRhZywgbmV3IHNob3J0W10geyAwLCAwIH0pOwotfQotcHVibGljIFBvaW50IGNvbXB1dGVTaXplIChpbnQgd0hpbnQsIGludCBoSGludCwgYm9vbGVhbiBjaGFuZ2VkKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLSAgICAvKiBBVwotCWludCBbXSBhcmdMaXN0ID0gewotCQlPUy5YbU5saXN0LCAwLAotCQlPUy5YbU50ZXh0RmllbGQsIDAsCi0JCU9TLlhtTml0ZW1Db3VudCwgMCwKLQkJT1MuWG1ObWFyZ2luV2lkdGgsIDAsCi0JCU9TLlhtTnNoYWRvd1RoaWNrbmVzcywgMCwKLQkJT1MuWG1OaGlnaGxpZ2h0VGhpY2tuZXNzLCAwLAotCQlPUy5YbU5hcnJvd1NpemUsIDAsCi0JCU9TLlhtTmFycm93U3BhY2luZywgMCwKLQl9OwotCU9TLlh0R2V0VmFsdWVzKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlYdFdpZGdldEdlb21ldHJ5IHJlc3VsdCA9IG5ldyBYdFdpZGdldEdlb21ldHJ5ICgpOwotCXJlc3VsdC5yZXF1ZXN0X21vZGUgPSBPUy5DV1dpZHRoOwotCU9TLlh0UXVlcnlHZW9tZXRyeSAoYXJnTGlzdFsxXSwgbnVsbCwgcmVzdWx0KTsKLQlpbnQgd2lkdGggPSByZXN1bHQud2lkdGgsIGhlaWdodCA9IGdldFRleHRIZWlnaHQoKTsKLQlpbnRbXSBhcmdMaXN0MiA9IHtPUy5YbU5tYXJnaW5XaWR0aCwgMCwgT1MuWG1Oc2hhZG93VGhpY2tuZXNzLCAwfTsKLQlPUy5YdEdldFZhbHVlcyhhcmdMaXN0WzNdLCBhcmdMaXN0MiwgYXJnTGlzdDIubGVuZ3RoIC8gMik7Ci0JaWYgKChzdHlsZSAmIFNXVC5SRUFEX09OTFkpID09IDApIHdpZHRoICs9ICgyICogYXJnTGlzdFs3XSk7Ci0JaWYgKChzdHlsZSAmIFNXVC5EUk9QX0RPV04pICE9IDApIHsKLQkJd2lkdGggKz0gYXJnTGlzdFsxM10gKyBhcmdMaXN0WzE1XTsKKwlpZiAoKHN0eWxlICYgU1dULlJFQURfT05MWSkgIT0gMCkgeworCQlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZSAoaGFuZGxlLCAwKTsKIAl9IGVsc2UgewotCQlpbnQgaXRlbUNvdW50ID0gKGFyZ0xpc3RbNV0gPT0gMCkgPyA1IDogYXJnTGlzdFs1XTsKLQkJaGVpZ2h0ICs9IChnZXRJdGVtSGVpZ2h0ICgpICogaXRlbUNvdW50KTsKKwkJY2hhciBbXSBidWZmZXIgPSBuZXcgY2hhciBbMF07CisJCWludCBwdHIgPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzIChPUy5rQ0ZBbGxvY2F0b3JEZWZhdWx0LCBidWZmZXIsIGJ1ZmZlci5sZW5ndGgpOworCQlpZiAocHRyID09IDApIHJldHVybjsJCisJCU9TLlNldENvbnRyb2xEYXRhIChoYW5kbGUsIE9TLmtISUNvbWJvQm94RWRpdFRleHRQYXJ0LCBPUy5rQ29udHJvbEVkaXRUZXh0Q0ZTdHJpbmdUYWcsIDQsIG5ldyBpbnRbXSB7cHRyfSk7CisJCU9TLkNGUmVsZWFzZSAocHRyKTsKIAl9Ci0Jd2lkdGggKz0gKDIgKiBhcmdMaXN0WzldKQotCQkrICgyICogYXJnTGlzdFsxMV0pCi0JCSsgKDIgKiBhcmdMaXN0MlsxXSkKLQkJKyAoMiAqIGFyZ0xpc3QyWzNdKTsKLQlpZiAoYXJnTGlzdFs1XSA9PSAwKSB3aWR0aCA9IERFRkFVTFRfV0lEVEg7Ci0JaWYgKGhIaW50ICE9IFNXVC5ERUZBVUxUKSBoZWlnaHQgPSBoSGludDsKK30KKworcHVibGljIFBvaW50IGNvbXB1dGVTaXplIChpbnQgd0hpbnQsIGludCBoSGludCwgYm9vbGVhbiBjaGFuZ2VkKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJLy8gTkVFRFMgV09SSworCWludCB3aWR0aCA9IDEwMDsKKwlpbnQgaGVpZ2h0ID0gMzA7CisJUmVjdCBpbnNldCA9IGdldEluc2V0ICgpOworCXdpZHRoICs9IGluc2V0LmxlZnQgKyBpbnNldC5yaWdodDsKKwloZWlnaHQgKz0gaW5zZXQudG9wICsgaW5zZXQuYm90dG9tOwogCWlmICh3SGludCAhPSBTV1QuREVGQVVMVCkgd2lkdGggPSB3SGludDsKLSAgICAqLwotCQkKLQlpbnQgd2lkdGggPSB3SGludDsKLQlpbnQgaGVpZ2h0ID0gaEhpbnQ7Ci0JCi0JaWYgKHdIaW50ID09IFNXVC5ERUZBVUxUIHx8IGhIaW50ID09IFNXVC5ERUZBVUxUKSB7Ci0JCQotCQlQb2ludCBlPSBNYWNVdGlsLmNvbXB1dGVTaXplKGhhbmRsZSk7Ci0JCWlmICh3SGludCA9PSBTV1QuREVGQVVMVCkKLQkJCXdpZHRoPSBlLng7Ci0JCWlmIChoSGludCA9PSBTV1QuREVGQVVMVCkKLQkJCWhlaWdodD0gZS55OwotCX0KLQkKLQl3aWR0aD0gMTUwOwotCWhlaWdodC0tOwotCQotLy8Jd2lkdGggKz0gMipNQVJHSU47Ci0vLwloZWlnaHQgKz0gMipNQVJHSU47Ci0vLwlpZiAoKHN0eWxlICYgU1dULkJPUkRFUikgIT0gMCkgewotCQl3aWR0aCArPSAyKkZPQ1VTX0JPUkRFUjsKLQkJaGVpZ2h0ICs9IDIqRk9DVVNfQk9SREVSOwotLy8JfQotCQorCWlmIChoSGludCAhPSBTV1QuREVGQVVMVCkgaGVpZ2h0ID0gaEhpbnQ7CiAJcmV0dXJuIG5ldyBQb2ludCAod2lkdGgsIGhlaWdodCk7CiB9Ci0vKioKLSAqIENvcGllcyB0aGUgc2VsZWN0ZWQgdGV4dC4KLSAqIDxwPgotICogVGhlIGN1cnJlbnQgc2VsZWN0aW9uIGlzIGNvcGllZCB0byB0aGUgY2xpcGJvYXJkLgotICogPC9wPgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqIAotICogQHNpbmNlIDIuMQotICovCisKIHB1YmxpYyB2b2lkIGNvcHkgKCkgewogCWNoZWNrV2lkZ2V0ICgpOwotCXNlbGVjdGlvblRvQ2xpcGJvYXJkKCk7Ci19Ci12b2lkIGNyZWF0ZUhhbmRsZSAoaW50IGluZGV4KSB7Ci0Jc3RhdGUgfD0gSEFORExFOworCWludCBbXSBzdHIgPSBuZXcgaW50IFsxXTsKKwlzaG9ydCBzdGFydCwgZW5kOwogCWlmICgoc3R5bGUgJiBTV1QuUkVBRF9PTkxZKSAhPSAwKSB7Ci0JCWhhbmRsZT0gTWFjVXRpbC5uZXdDb250cm9sKHBhcmVudC5oYW5kbGUsIChzaG9ydCkwLCAoc2hvcnQpLTEyMzQ1LCAoc2hvcnQpLTEsIChzaG9ydCkoT1Mua0NvbnRyb2xQb3B1cEJ1dHRvblByb2MrMSkpOwotCQlpZiAoaGFuZGxlID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JCWludFtdIG1lbnVSZWY9IG5ldyBpbnRbMV07Ci0JCU9TLkNyZWF0ZU5ld01lbnUoMjAwMDAsIDAsIG1lbnVSZWYpOwotCQltZW51SGFuZGxlPSBtZW51UmVmWzBdOwotCQlpZiAobWVudUhhbmRsZSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOwotCQlPUy5TZXRDb250cm9sUG9wdXBNZW51SGFuZGxlKGhhbmRsZSwgbWVudUhhbmRsZSk7CisJCS8vIE5FRURTIFdPUksgLSBnZXR0aW5nIHdob2xlIHRleHQsIG5vdCBqdXN0IHNlbGVjdGlvbgorCQlpbnQgaW5kZXggPSBPUy5HZXRDb250cm9sVmFsdWUgKGhhbmRsZSk7CisJCWlmIChPUy5Db3B5TWVudUl0ZW1UZXh0QXNDRlN0cmluZyhtZW51SGFuZGxlLCAoc2hvcnQpaW5kZXgsIHN0cikgIT0gT1Mubm9FcnIpIHJldHVybjsKKwkJc3RhcnQgPSAwOyBlbmQgPSAoc2hvcnQpT1MuQ0ZTdHJpbmdHZXRMZW5ndGggKHN0ciBbMF0pOworCQlpZiAoc3RhcnQgPj0gZW5kKSB7CisJCQlPUy5DRlJlbGVhc2UgKHN0ciBbMF0pOworCQkJcmV0dXJuOworCQl9CiAJfSBlbHNlIHsKLQkgICAgaW50W10gb3V0Q29tYm9Cb3g9IG5ldyBpbnRbMV07Ci0JCU9TLkhJQ29tYm9Cb3hDcmVhdGUob3V0Q29tYm9Cb3gsIE9TLmtISUNvbWJvQm94QXV0b1NpemVMaXN0QXR0cmlidXRlKTsKLQkJaGFuZGxlPSBvdXRDb21ib0JveFswXTsKLQkJaWYgKGhhbmRsZSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOwotCQlNYWNVdGlsLmFkZENvbnRyb2woaGFuZGxlLCBwYXJlbnQuaGFuZGxlKTsKLQkJT1MuSElWaWV3U2V0VmlzaWJsZShoYW5kbGUsIHRydWUpOworCQlzaG9ydCBbXSBzID0gbmV3IHNob3J0IFsyXTsKKwkJT1MuR2V0Q29udHJvbERhdGEgKGhhbmRsZSwgKHNob3J0KU9TLmtISUNvbWJvQm94RWRpdFRleHRQYXJ0LCBPUy5rQ29udHJvbEVkaXRUZXh0U2VsZWN0aW9uVGFnLCA0LCBzLCBudWxsKTsKKwkJaWYgKHMgWzBdID49IHMgWzFdKSByZXR1cm47CisJCXN0YXJ0ID0gcyBbMF07IGVuZCA9IHMgWzFdOworCQlpZiAoT1MuR2V0Q29udHJvbERhdGEgKGhhbmRsZSwgKHNob3J0KU9TLmtISUNvbWJvQm94RWRpdFRleHRQYXJ0LCBPUy5rQ29udHJvbEVkaXRUZXh0Q0ZTdHJpbmdUYWcsIDQsIHN0ciwgbnVsbCkgIT0gT1Mubm9FcnIpIHJldHVybjsKKwl9CisJQ0ZSYW5nZSByYW5nZSA9IG5ldyBDRlJhbmdlICgpOworCXJhbmdlLmxvY2F0aW9uID0gc3RhcnQ7CisJcmFuZ2UubGVuZ3RoID0gZW5kIC0gc3RhcnQ7CisJaW50IGVuY29kaW5nID0gT1MuQ0ZTdHJpbmdHZXRTeXN0ZW1FbmNvZGluZyAoKTsKKwlpbnQgW10gc2l6ZSA9IG5ldyBpbnQgWzFdOworCU9TLkNGU3RyaW5nR2V0Qnl0ZXMgKHN0ciBbMF0sIHJhbmdlLCBlbmNvZGluZywgKGJ5dGUpJz8nLCB0cnVlLCBudWxsLCAwLCBzaXplKTsKKwlieXRlIFtdIGJ1ZmZlciA9IG5ldyBieXRlIFtzaXplIFswXV07CisJT1MuQ0ZTdHJpbmdHZXRCeXRlcyAoc3RyIFswXSwgcmFuZ2UsIGVuY29kaW5nLCAoYnl0ZSknPycsIHRydWUsIGJ1ZmZlciwgc2l6ZSBbMF0sIHNpemUpOworCU9TLkNGUmVsZWFzZSAoc3RyIFswXSk7CisJCisJT1MuQ2xlYXJDdXJyZW50U2NyYXAoKTsKKwlpbnRbXSBzY3JhcCA9IG5ldyBpbnQgWzFdOworCU9TLkdldEN1cnJlbnRTY3JhcCAoc2NyYXApOworCU9TLlB1dFNjcmFwRmxhdm9yKHNjcmFwIFswXSwgT1Mua1NjcmFwRmxhdm9yVHlwZVRleHQsIDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlcik7Cit9CisKK3ZvaWQgY3JlYXRlSGFuZGxlICgpIHsKKwkvLyBORUVEUyBXT1JLIC0gU0lNUExFCisJaWYgKChzdHlsZSAmIFNXVC5SRUFEX09OTFkpICE9IDApIHsKKwkJaW50IFtdIG91dENvbnRyb2wgPSBuZXcgaW50IFsxXTsKKwkJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAocGFyZW50LmhhbmRsZSk7CisJCS8qIEZyb20gQ29udHJvbERlZmluaXRpb25zLmg6CisJCSAqIAorCQkgKiBQYXNzaW5nIGluIGEgbWVudSBJRCBvZiAtMTIzNDUgY2F1c2VzIHRoZSBwb3B1cCBub3QgdG8gdHJ5IGFuZCBnZXQgdGhlIG1lbnUgZnJvbSBhCisJCSAqIHJlc291cmNlLiBJbnN0ZWFkLCB5b3UgY2FuIGJ1aWxkIHRoZSBtZW51IGFuZCBsYXRlciBzdHVmZiB0aGUgTWVudVJlZiBmaWVsZCBpbgorCQkgKiB0aGUgcG9wdXAgZGF0YSBpbmZvcm1hdGlvbi4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisJCSAqLworCQlPUy5DcmVhdGVQb3B1cEJ1dHRvbkNvbnRyb2wod2luZG93LCBudWxsLCAwLCAoc2hvcnQpLTEyMzQ1LCBmYWxzZSwgKHNob3J0KTAsIChzaG9ydCkwLCAwLCBvdXRDb250cm9sKTsKKwkJaWYgKG91dENvbnRyb2wgWzBdID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7CisJCWhhbmRsZSA9IG91dENvbnRyb2wgWzBdOworCQlpbnRbXSBtZW51UmVmPSBuZXcgaW50WzFdOworCQlPUy5DcmVhdGVOZXdNZW51ICgoc2hvcnQpMCwgMCwgbWVudVJlZik7CisJCWlmIChtZW51UmVmIFswXSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCQltZW51SGFuZGxlID0gbWVudVJlZlswXTsKKwkJT1MuU2V0Q29udHJvbFBvcHVwTWVudUhhbmRsZShoYW5kbGUsIG1lbnVIYW5kbGUpOworCQlPUy5TZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSwgMHg3RkZGKTsKKwl9IGVsc2UgeworCQlpbnQgW10gb3V0Q29udHJvbCA9IG5ldyBpbnQgWzFdOworCQlDR1JlY3QgcmVjdCA9IG5ldyBDR1JlY3QgKCk7CisJCWludCBpbkF0dHJpYnV0ZXMgPSBPUy5rSElDb21ib0JveEF1dG9Db21wbGV0aW9uQXR0cmlidXRlIHwgT1Mua0hJQ29tYm9Cb3hBdXRvU2l6ZUxpc3RBdHRyaWJ1dGU7CisJCU9TLkhJQ29tYm9Cb3hDcmVhdGUocmVjdCwgMCwgbnVsbCwgMCwgaW5BdHRyaWJ1dGVzLCBvdXRDb250cm9sKTsKKwkJaWYgKG91dENvbnRyb2wgWzBdID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7CisJCWhhbmRsZSA9IG91dENvbnRyb2wgWzBdOworCQlPUy5ISVZpZXdTZXRWaXNpYmxlIChoYW5kbGUsIHRydWUpOwogCX0KIH0KLS8qKgotICogQ3V0cyB0aGUgc2VsZWN0ZWQgdGV4dC4KLSAqIDxwPgotICogVGhlIGN1cnJlbnQgc2VsZWN0aW9uIGlzIGZpcnN0IGNvcGllZCB0byB0aGUKLSAqIGNsaXBib2FyZCBhbmQgdGhlbiBkZWxldGVkIGZyb20gdGhlIHdpZGdldC4KLSAqIDwvcD4KLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiAKLSAqIEBzaW5jZSAyLjEKLSAqLworCiBwdWJsaWMgdm9pZCBjdXQgKCkgewogCWNoZWNrV2lkZ2V0ICgpOwotCXNlbGVjdGlvblRvQ2xpcGJvYXJkKCk7Ci0JX3JlcGxhY2VUZXh0U2VsZWN0aW9uKCIiKTsKLX0KLS8qIEFXCi12b2lkIGVuYWJsZVdpZGdldCAoYm9vbGVhbiBlbmFibGVkKSB7Ci0Jc3VwZXIuZW5hYmxlV2lkZ2V0IChlbmFibGVkKTsKLQlpbnQgW10gYXJnTGlzdCA9IHsKLQkJT1MuWG1ObGlzdCwgMCwKLQkJT1MuWG1OdGV4dEZpZWxkLCAwLAotCX07Ci0JT1MuWHRHZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQllbmFibGVIYW5kbGUgKGVuYWJsZWQsIGFyZ0xpc3QgWzFdKTsKLQllbmFibGVIYW5kbGUgKGVuYWJsZWQsIGFyZ0xpc3QgWzNdKTsKLX0KLSovCi0vKioKLSAqIERlc2VsZWN0cyB0aGUgaXRlbSBhdCB0aGUgZ2l2ZW4gemVyby1yZWxhdGl2ZSBpbmRleCBpbiB0aGUgcmVjZWl2ZXIncyAKLSAqIGxpc3QuICBJZiB0aGUgaXRlbSBhdCB0aGUgaW5kZXggd2FzIGFscmVhZHkgZGVzZWxlY3RlZCwgaXQgcmVtYWlucwotICogZGVzZWxlY3RlZC4gSW5kaWNlcyB0aGF0IGFyZSBvdXQgb2YgcmFuZ2UgYXJlIGlnbm9yZWQuCi0gKgotICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgaXRlbSB0byBkZXNlbGVjdAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwotcHVibGljIHZvaWQgZGVzZWxlY3QgKGludCBpbmRleCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKGluZGV4ID09IC0xKSByZXR1cm47Ci0gICAgLyogQVcKLQlpbnQgW10gYXJnTGlzdCA9IHtPUy5YbU50ZXh0RmllbGQsIDAsIE9TLlhtTmxpc3QsIDB9OwotCU9TLlh0R2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0KLQlpZiAoT1MuWG1MaXN0UG9zU2VsZWN0ZWQgKGFyZ0xpc3RbM10sIGluZGV4ICsgMSkpIHsKLQkJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKLQkJYm9vbGVhbiB3YXJuaW5ncyA9IGRpc3BsYXkuZ2V0V2FybmluZ3MgKCk7Ci0JCWRpc3BsYXkuc2V0V2FybmluZ3MgKGZhbHNlKTsKLQkJT1MuWG1UZXh0U2V0U3RyaW5nIChhcmdMaXN0WzFdLCBuZXcgYnl0ZVsxXSk7Ci0JCU9TLlhtVGV4dFNldEluc2VydGlvblBvc2l0aW9uIChhcmdMaXN0WzFdLCAwKTsKLQkJZGlzcGxheS5zZXRXYXJuaW5ncyAod2FybmluZ3MpOwotCQlPUy5YbUxpc3REZXNlbGVjdEFsbEl0ZW1zIChhcmdMaXN0WzNdKTsKKwlpbnQgW10gc3RyID0gbmV3IGludCBbMV07CisJc2hvcnQgc3RhcnQsIGVuZDsKKwlpZiAoKHN0eWxlICYgU1dULlJFQURfT05MWSkgIT0gMCkgeworCQkvLyBORUVEUyBXT1JLIC0gZ2V0dGluZyB3aG9sZSB0ZXh0LCBub3QganVzdCBzZWxlY3Rpb24KKwkJaW50IGluZGV4ID0gT1MuR2V0Q29udHJvbFZhbHVlIChoYW5kbGUpOworCQlpZiAoT1MuQ29weU1lbnVJdGVtVGV4dEFzQ0ZTdHJpbmcobWVudUhhbmRsZSwgKHNob3J0KWluZGV4LCBzdHIpICE9IE9TLm5vRXJyKSByZXR1cm47CisJCXN0YXJ0ID0gMDsgZW5kID0gKHNob3J0KU9TLkNGU3RyaW5nR2V0TGVuZ3RoIChzdHIgWzBdKTsKKwkJaWYgKHN0YXJ0ID49IGVuZCkgeworCQkJT1MuQ0ZSZWxlYXNlIChzdHIgWzBdKTsKKwkJCXJldHVybjsKKwkJfQorCX0gZWxzZSB7CisJCXNob3J0IFtdIHMgPSBuZXcgc2hvcnQgWzJdOworCQlPUy5HZXRDb250cm9sRGF0YSAoaGFuZGxlLCAoc2hvcnQpT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRTZWxlY3Rpb25UYWcsIDQsIHMsIG51bGwpOworCQlpZiAocyBbMF0gPj0gcyBbMV0pIHJldHVybjsKKwkJc3RhcnQgPSBzIFswXTsgZW5kID0gcyBbMV07CisJCWlmIChPUy5HZXRDb250cm9sRGF0YSAoaGFuZGxlLCAoc2hvcnQpT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRDRlN0cmluZ1RhZywgNCwgc3RyLCBudWxsKSAhPSBPUy5ub0VycikgcmV0dXJuOwogCX0KLSAgICAqLwotCVN5c3RlbS5vdXQucHJpbnRsbigiQ29tYm8uZGVzZWxlY3Q6IG55aSIpOworCUNGUmFuZ2UgcmFuZ2UgPSBuZXcgQ0ZSYW5nZSAoKTsKKwlyYW5nZS5sb2NhdGlvbiA9IHN0YXJ0OworCXJhbmdlLmxlbmd0aCA9IGVuZCAtIHN0YXJ0OworCWludCBlbmNvZGluZyA9IE9TLkNGU3RyaW5nR2V0U3lzdGVtRW5jb2RpbmcgKCk7CisJaW50IFtdIHNpemUgPSBuZXcgaW50IFsxXTsKKwlPUy5DRlN0cmluZ0dldEJ5dGVzIChzdHIgWzBdLCByYW5nZSwgZW5jb2RpbmcsIChieXRlKSc/JywgdHJ1ZSwgbnVsbCwgMCwgc2l6ZSk7CisJYnl0ZSBbXSBidWZmZXIgPSBuZXcgYnl0ZSBbc2l6ZSBbMF1dOworCU9TLkNGU3RyaW5nR2V0Qnl0ZXMgKHN0ciBbMF0sIHJhbmdlLCBlbmNvZGluZywgKGJ5dGUpJz8nLCB0cnVlLCBidWZmZXIsIHNpemUgWzBdLCBzaXplKTsKKworCU9TLkNsZWFyQ3VycmVudFNjcmFwKCk7CisJaW50W10gc2NyYXAgPSBuZXcgaW50IFsxXTsKKwlPUy5HZXRDdXJyZW50U2NyYXAgKHNjcmFwKTsKKwlPUy5QdXRTY3JhcEZsYXZvciAoc2NyYXAgWzBdLCBPUy5rU2NyYXBGbGF2b3JUeXBlVGV4dCwgMCwgYnVmZmVyLmxlbmd0aCwgYnVmZmVyKTsKKwkKKwkvLyBkZWxldGUgc2VsZWN0aW9uCisJaWYgKChzdHlsZSAmIFNXVC5SRUFEX09OTFkpICE9IDApIHsKKwkJLy8gTkVFRFMgV09SSworCX0gZWxzZSB7CisJCWJ5dGUgW10gbmV3QnVmZmVyOworCQlyYW5nZS5sb2NhdGlvbiA9IDA7CisJCXJhbmdlLmxlbmd0aCA9IHN0YXJ0OworCQlzaXplID0gbmV3IGludCBbMV07CisJCU9TLkNGU3RyaW5nR2V0Qnl0ZXMgKHN0ciBbMF0sIHJhbmdlLCBlbmNvZGluZywgKGJ5dGUpJz8nLCB0cnVlLCBudWxsLCAwLCBzaXplKTsKKwkJYnl0ZSBbXSBwcmVCdWZmZXIgPSBuZXcgYnl0ZSBbc2l6ZSBbMF1dOworCQlPUy5DRlN0cmluZ0dldEJ5dGVzKHN0ciBbMF0sIHJhbmdlLCBlbmNvZGluZywgKGJ5dGUpJz8nLCB0cnVlLCBwcmVCdWZmZXIsIHNpemUgWzBdLCBzaXplKTsKKwkJcmFuZ2UubG9jYXRpb24gPSBlbmQ7CisJCXJhbmdlLmxlbmd0aCA9IE9TLkNGU3RyaW5nR2V0TGVuZ3RoIChzdHIgWzBdKSAtIGVuZDsKKwkJc2l6ZSA9IG5ldyBpbnQgWzFdOworCQlPUy5DRlN0cmluZ0dldEJ5dGVzIChzdHIgWzBdLCByYW5nZSwgZW5jb2RpbmcsIChieXRlKSc/JywgdHJ1ZSwgbnVsbCwgMCwgc2l6ZSk7CisJCWJ5dGUgW10gcG9zdEJ1ZmZlciA9IG5ldyBieXRlIFtzaXplIFswXV07CisJCU9TLkNGU3RyaW5nR2V0Qnl0ZXMgKHN0ciBbMF0sIHJhbmdlLCBlbmNvZGluZywgKGJ5dGUpJz8nLCB0cnVlLCBwb3N0QnVmZmVyLCBzaXplIFswXSwgc2l6ZSk7CisJCW5ld0J1ZmZlciA9IG5ldyBieXRlIFtwcmVCdWZmZXIubGVuZ3RoICsgcG9zdEJ1ZmZlci5sZW5ndGhdOworCQlTeXN0ZW0uYXJyYXljb3B5KHByZUJ1ZmZlciwgMCwgbmV3QnVmZmVyLCAwLCBwcmVCdWZmZXIubGVuZ3RoKTsKKwkJU3lzdGVtLmFycmF5Y29weShwb3N0QnVmZmVyLCAwLCBuZXdCdWZmZXIsIHByZUJ1ZmZlci5sZW5ndGgsIHBvc3RCdWZmZXIubGVuZ3RoKTsKKwkJaW50IHB0ciA9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aEJ5dGVzIChPUy5rQ0ZBbGxvY2F0b3JEZWZhdWx0LCBuZXdCdWZmZXIsIG5ld0J1ZmZlci5sZW5ndGgsIGVuY29kaW5nLCB0cnVlKTsKKwkJT1MuU2V0Q29udHJvbERhdGEgKGhhbmRsZSwgT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRDRlN0cmluZ1RhZywgNCwgbmV3IGludFtdIHtwdHJ9KTsKKwkJT1MuQ0ZSZWxlYXNlIChwdHIpOworCX0KKwkKKwlPUy5DRlJlbGVhc2UgKHN0ciBbMF0pOwogfQotLyoqCi0gKiBEZXNlbGVjdHMgYWxsIHNlbGVjdGVkIGl0ZW1zIGluIHRoZSByZWNlaXZlcidzIGxpc3QuCi0gKiA8cD4KLSAqIE5vdGU6IFRvIGNsZWFyIHRoZSBzZWxlY3Rpb24gaW4gdGhlIHJlY2VpdmVyJ3MgdGV4dCBmaWVsZCwKLSAqIHVzZSA8Y29kZT5jbGVhclNlbGVjdGlvbigpPC9jb2RlPi4KLSAqIDwvcD4KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjY2xlYXJTZWxlY3Rpb24KLSAqLworCitwdWJsaWMgdm9pZCBkZXNlbGVjdCAoaW50IGluZGV4KSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKGluZGV4ID09IC0xKSByZXR1cm47CisJLy8gTkVFRFMgV09SSworfQorCiBwdWJsaWMgdm9pZCBkZXNlbGVjdEFsbCAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLSAgICAvKiBBVwotCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTnRleHRGaWVsZCwgMCwgT1MuWG1ObGlzdCwgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOwotCWJvb2xlYW4gd2FybmluZ3MgPSBkaXNwbGF5LmdldFdhcm5pbmdzICgpOwotCWRpc3BsYXkuc2V0V2FybmluZ3MgKGZhbHNlKTsKLQlPUy5YbVRleHRTZXRTdHJpbmcgKGFyZ0xpc3RbMV0sIG5ldyBieXRlWzFdKTsKLQlPUy5YbVRleHRTZXRJbnNlcnRpb25Qb3NpdGlvbiAoYXJnTGlzdFsxXSwgMCk7Ci0JZGlzcGxheS5zZXRXYXJuaW5ncyh3YXJuaW5ncyk7Ci0JT1MuWG1MaXN0RGVzZWxlY3RBbGxJdGVtcyAoYXJnTGlzdFszXSk7Ci0gICAgKi8KLQlTeXN0ZW0ub3V0LnByaW50bG4oIkNvbWJvLmRlc2VsZWN0QWxsOiBueWkiKTsKKwljaGVja1dpZGdldCAoKTsKKwkvLyBORUVEUyBXT1JLCiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIGl0ZW0gYXQgdGhlIGdpdmVuLCB6ZXJvLXJlbGF0aXZlIGluZGV4IGluIHRoZQotICogcmVjZWl2ZXIncyBsaXN0LiBUaHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZSBpbmRleCBpcyBvdXQKLSAqIG9mIHJhbmdlLgotICoKLSAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIGl0ZW0gdG8gcmV0dXJuCi0gKiBAcmV0dXJuIHRoZSBpdGVtIGF0IHRoZSBnaXZlbiBpbmRleAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1JBTkdFIC0gaWYgdGhlIGluZGV4IGlzIG5vdCBiZXR3ZWVuIDAgYW5kIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGxpc3QgbWludXMgMSAoaW5jbHVzaXZlKTwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfQ0FOTk9UX0dFVF9JVEVNIC0gaWYgdGhlIG9wZXJhdGlvbiBmYWlscyBiZWNhdXNlIG9mIGFuIG9wZXJhdGluZyBzeXN0ZW0gZmFpbHVyZTwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBTdHJpbmcgZ2V0SXRlbSAoaW50IGluZGV4KSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlyZXR1cm4gX2dldEl0ZW0oaW5kZXgpOworCWNoZWNrV2lkZ2V0ICgpOworCWludCBjb3VudCA9IGdldEl0ZW1Db3VudCAoKTsKKwlpZiAoMCA+IGluZGV4IHx8IGluZGV4ID49IGNvdW50KSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOworCWludFtdIHB0ciA9IG5ldyBpbnRbMV07CisJaW50IHJlc3VsdDsKKwlpZiAoKHN0eWxlICYgU1dULlJFQURfT05MWSkgIT0gMCkgeworCQlyZXN1bHQgPSBPUy5Db3B5TWVudUl0ZW1UZXh0QXNDRlN0cmluZyhtZW51SGFuZGxlLCAoc2hvcnQpKGluZGV4KzEpLCBwdHIpOworCX0gZWxzZSB7CisJCXJlc3VsdCA9IE9TLkhJQ29tYm9Cb3hDb3B5VGV4dEl0ZW1BdEluZGV4IChoYW5kbGUsIGluZGV4LCBwdHIpOworCX0KKwlpZiAocmVzdWx0ICE9IE9TLm5vRXJyKSBlcnJvcihTV1QuRVJST1JfQ0FOTk9UX0dFVF9JVEVNKTsKKwlpbnQgbGVuZ3RoID0gT1MuQ0ZTdHJpbmdHZXRMZW5ndGggKHB0ciBbMF0pOworCWNoYXIgW10gYnVmZmVyPSBuZXcgY2hhciBbbGVuZ3RoXTsKKwlDRlJhbmdlIHJhbmdlID0gbmV3IENGUmFuZ2UgKCk7CisJcmFuZ2UubGVuZ3RoID0gbGVuZ3RoOworCU9TLkNGU3RyaW5nR2V0Q2hhcmFjdGVycyAocHRyIFswXSwgcmFuZ2UsIGJ1ZmZlcik7CisJT1MuQ0ZSZWxlYXNlIChwdHIgWzBdKTsKKwlyZXR1cm4gbmV3IFN0cmluZyAoYnVmZmVyKTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGl0ZW1zIGNvbnRhaW5lZCBpbiB0aGUgcmVjZWl2ZXIncyBsaXN0LgotICoKLSAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBpdGVtcwotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXJyb3IgPHVsPgotICogICAgPGxpPkVSUk9SX0NBTk5PVF9HRVRfQ09VTlQgLSBpZiB0aGUgb3BlcmF0aW9uIGZhaWxzIGJlY2F1c2Ugb2YgYW4gb3BlcmF0aW5nIHN5c3RlbSBmYWlsdXJlPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGludCBnZXRJdGVtQ291bnQgKCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0JcmV0dXJuIF9nZXRJdGVtQ291bnQoKTsKKwljaGVja1dpZGdldCAoKTsKKwlpbnQgY291bnQ7CisJaWYgKChzdHlsZSAmIFNXVC5SRUFEX09OTFkpICE9IDApIHsKKwkJY291bnQgPSBPUy5Db3VudE1lbnVJdGVtcyAobWVudUhhbmRsZSk7CisJfSBlbHNlIHsKKwkJY291bnQgPSBPUy5ISUNvbWJvQm94R2V0SXRlbUNvdW50IChoYW5kbGUpOworCX0KKwlyZXR1cm4gY291bnQ7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIGhlaWdodCBvZiB0aGUgYXJlYSB3aGljaCB3b3VsZCBiZSB1c2VkIHRvCi0gKiBkaXNwbGF5IDxlbT5vbmU8L2VtPiBvZiB0aGUgaXRlbXMgaW4gdGhlIHJlY2VpdmVyJ3MgbGlzdC4KLSAqCi0gKiBAcmV0dXJuIHRoZSBoZWlnaHQgb2Ygb25lIGl0ZW0KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEVycm9yIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9DQU5OT1RfR0VUX0lURU1fSEVJR0hUIC0gaWYgdGhlIG9wZXJhdGlvbiBmYWlscyBiZWNhdXNlIG9mIGFuIG9wZXJhdGluZyBzeXN0ZW0gZmFpbHVyZTwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBpbnQgZ2V0SXRlbUhlaWdodCAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLSAgICAvKiBBVwotCWludCBbXSBsaXN0SGFuZGxlQXJncyA9IHtPUy5YbU5saXN0LCAwfTsKLQlPUy5YdEdldFZhbHVlcyAoaGFuZGxlLCBsaXN0SGFuZGxlQXJncywgbGlzdEhhbmRsZUFyZ3MubGVuZ3RoIC8gMik7Ci0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1ObGlzdFNwYWNpbmcsIDAsIE9TLlhtTmhpZ2hsaWdodFRoaWNrbmVzcywgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKGxpc3RIYW5kbGVBcmdzWzFdLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCWludCBzcGFjaW5nID0gYXJnTGlzdCBbMV0sIGhpZ2hsaWdodCA9IGFyZ0xpc3QgWzNdOwotICAgICovCi0JLyogUmVzdWx0IGlzIGZyb20gZW1waXJpY2FsIGFuYWx5c2lzIG9uIExpbnV4IGFuZCBBSVggKi8KLSAgICAvKiBBVwotCXJldHVybiBnZXRGb250SGVpZ2h0ICgpICsgc3BhY2luZyArICgyICogaGlnaGxpZ2h0KTsKLSAgICAqLwotICAgIHJldHVybiBNYWNVdGlsLmNvbXB1dGVTaXplKGhhbmRsZSkueTsKKwljaGVja1dpZGdldCAoKTsKKwlyZXR1cm4gMjY7IC8vIE5FRURTIFdPUksKIH0KLS8qKgotICogUmV0dXJucyBhbiBhcnJheSBvZiA8Y29kZT5TdHJpbmc8L2NvZGU+cyB3aGljaCBhcmUgdGhlIGl0ZW1zCi0gKiBpbiB0aGUgcmVjZWl2ZXIncyBsaXN0LiAKLSAqIDxwPgotICogTm90ZTogVGhpcyBpcyBub3QgdGhlIGFjdHVhbCBzdHJ1Y3R1cmUgdXNlZCBieSB0aGUgcmVjZWl2ZXIKLSAqIHRvIG1haW50YWluIGl0cyBsaXN0IG9mIGl0ZW1zLCBzbyBtb2RpZnlpbmcgdGhlIGFycmF5IHdpbGwKLSAqIG5vdCBhZmZlY3QgdGhlIHJlY2VpdmVyLiAKLSAqIDwvcD4KLSAqCi0gKiBAcmV0dXJuIHRoZSBpdGVtcyBpbiB0aGUgcmVjZWl2ZXIncyBsaXN0Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfQ0FOTk9UX0dFVF9JVEVNIC0gaWYgdGhlIG9wZXJhdGlvbiBmYWlscyBiZWNhdXNlIG9mIGFuIG9wZXJhdGluZyBzeXN0ZW0gZmFpbHVyZTwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBTdHJpbmcgW10gZ2V0SXRlbXMgKCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0JaW50IGl0ZW1Db3VudD0gX2dldEl0ZW1Db3VudCgpOwotCVN0cmluZ1tdIHJlc3VsdD0gbmV3IFN0cmluZyBbaXRlbUNvdW50XTsKLQlmb3IgKGludCBpPSAwOyBpIDwgaXRlbUNvdW50OyBpKyspCi0JCXJlc3VsdFtpXT0gX2dldEl0ZW0oaSk7CisJY2hlY2tXaWRnZXQgKCk7CisJaW50IGNvdW50ID0gZ2V0SXRlbUNvdW50ICgpOworCVN0cmluZyBbXSByZXN1bHQgPSBuZXcgU3RyaW5nIFtjb3VudF07CisJZm9yIChpbnQgaT0wOyBpPGNvdW50OyBpKyspIHJlc3VsdCBbaV0gPSBnZXRJdGVtIChpKTsKIAlyZXR1cm4gcmVzdWx0OwogfQotLyoqCi0gKiBSZXR1cm5zIGEgPGNvZGU+UG9pbnQ8L2NvZGU+IHdob3NlIHggY29vcmRpbmF0ZSBpcyB0aGUgc3RhcnQKLSAqIG9mIHRoZSBzZWxlY3Rpb24gaW4gdGhlIHJlY2VpdmVyJ3MgdGV4dCBmaWVsZCwgYW5kIHdob3NlIHkKLSAqIGNvb3JkaW5hdGUgaXMgdGhlIGVuZCBvZiB0aGUgc2VsZWN0aW9uLiBUaGUgcmV0dXJuZWQgdmFsdWVzCi0gKiBhcmUgemVyby1yZWxhdGl2ZS4gQW4gImVtcHR5IiBzZWxlY3Rpb24gYXMgaW5kaWNhdGVkIGJ5Ci0gKiB0aGUgdGhlIHggYW5kIHkgY29vcmRpbmF0ZXMgaGF2aW5nIHRoZSBzYW1lIHZhbHVlLgotICoKLSAqIEByZXR1cm4gYSBwb2ludCByZXByZXNlbnRpbmcgdGhlIHNlbGVjdGlvbiBzdGFydCBhbmQgZW5kCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBQb2ludCBnZXRTZWxlY3Rpb24gKCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0gCVBvaW50IHNlbGVjdGlvbj0gbmV3IFBvaW50KDAsIDApOwotCWlmIChtZW51SGFuZGxlID09IDApIHsKLQkJc2hvcnRbXSBzPSBuZXcgc2hvcnRbMl07Ci0JCU9TLkdldENvbnRyb2xEYXRhKGhhbmRsZSwgT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRTZWxlY3Rpb25UYWcsIHMpOwotCQlzZWxlY3Rpb24ueD0gKHNob3J0KSBzWzBdOwotCQlzZWxlY3Rpb24ueT0gKHNob3J0KSBzWzFdOworCWNoZWNrV2lkZ2V0ICgpOworCVBvaW50IHNlbGVjdGlvbjsKKwlpZiAoKHN0eWxlICYgU1dULlJFQURfT05MWSkgIT0gMCkgeworCQkvLyBORUVEUyBXT1JLCisJCXNlbGVjdGlvbiA9IG5ldyBQb2ludCgwLCAwKTsKKwl9IGVsc2UgeworCQlzaG9ydCBbXSBzID0gbmV3IHNob3J0IFsyXTsKKwkJT1MuR2V0Q29udHJvbERhdGEgKGhhbmRsZSwgKHNob3J0KU9TLmtISUNvbWJvQm94RWRpdFRleHRQYXJ0LCBPUy5rQ29udHJvbEVkaXRUZXh0U2VsZWN0aW9uVGFnLCA0LCBzLCBudWxsKTsKKwkJc2VsZWN0aW9uID0gbmV3IFBvaW50IChzWzBdLCBzWzFdKTsKIAl9CiAJcmV0dXJuIHNlbGVjdGlvbjsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgemVyby1yZWxhdGl2ZSBpbmRleCBvZiB0aGUgaXRlbSB3aGljaCBpcyBjdXJyZW50bHkKLSAqIHNlbGVjdGVkIGluIHRoZSByZWNlaXZlcidzIGxpc3QsIG9yIC0xIGlmIG5vIGl0ZW0gaXMgc2VsZWN0ZWQuCi0gKgotICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIHNlbGVjdGVkIGl0ZW0KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGludCBnZXRTZWxlY3Rpb25JbmRleCAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlpZiAobWVudUhhbmRsZSAhPSAwKQotICAgIAlyZXR1cm4gT1MuR2V0Q29udHJvbFZhbHVlKGhhbmRsZSktMTsKLSAgICByZXR1cm4gaW5kZXhPZihnZXRUZXh0KCkpOwotfQotLyoqCi0gKiBSZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgYSBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUKLSAqIHJlY2VpdmVyJ3MgdGV4dCBmaWVsZC4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIHRleHQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KLXB1YmxpYyBTdHJpbmcgZ2V0VGV4dCAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlpZiAobWVudUhhbmRsZSAhPSAwKSB7Ci0JCWludCBpbmRleD0gZ2V0U2VsZWN0aW9uSW5kZXgoKTsKLQkJaWYgKGluZGV4ID49IDApCi0JCQlyZXR1cm4gX2dldEl0ZW0oaW5kZXgpOwotCQlyZXR1cm4gIiI7CisJY2hlY2tXaWRnZXQgKCk7CisJaW50IGluZGV4OworCWlmICgoc3R5bGUgJiBTV1QuUkVBRF9PTkxZKSAhPSAwKSB7CisJCWluZGV4ID0gT1MuR2V0Q29udHJvbFZhbHVlIChoYW5kbGUpIC0gMTsKKwl9IGVsc2UgeworCQkvLyBORUVEUyBXT1JLCisgICAgCWluZGV4ID0gaW5kZXhPZihnZXRUZXh0ICgpKTsKIAl9Ci0JaW50W10gdD0gbmV3IGludFsxXTsKLQlPUy5HZXRDb250cm9sRGF0YShoYW5kbGUsIE9TLmtISUNvbWJvQm94RWRpdFRleHRQYXJ0LCBPUy5rQ29udHJvbEVkaXRUZXh0Q0ZTdHJpbmdUYWcsIHQpOwotCXJldHVybiBNYWNVdGlsLmdldFN0cmluZ0FuZFJlbGVhc2UodFswXSk7CisJcmV0dXJuIGluZGV4OwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBoZWlnaHQgb2YgdGhlIHJlY2VpdmVycydzIHRleHQgZmllbGQuCi0gKgotICogQHJldHVybiB0aGUgdGV4dCBoZWlnaHQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEVycm9yIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9DQU5OT1RfR0VUX0lURU1fSEVJR0hUIC0gaWYgdGhlIG9wZXJhdGlvbiBmYWlscyBiZWNhdXNlIG9mIGFuIG9wZXJhdGluZyBzeXN0ZW0gZmFpbHVyZTwvbGk+Ci0gKiA8L3VsPgotICovCisKK3B1YmxpYyBTdHJpbmcgZ2V0VGV4dCAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaW50IFtdIHB0ciA9IG5ldyBpbnQgWzFdOworCWludCByZXN1bHQ7CisJaWYgKChzdHlsZSAmIFNXVC5SRUFEX09OTFkpICE9IDApIHsKKwkJaW50IGluZGV4ID0gT1MuR2V0Q29udHJvbFZhbHVlIChoYW5kbGUpIC0gMTsKKwkJcmVzdWx0ID0gT1MuQ29weU1lbnVJdGVtVGV4dEFzQ0ZTdHJpbmcobWVudUhhbmRsZSwgKHNob3J0KShpbmRleCsxKSwgcHRyKTsKKwl9IGVsc2UgeworCQlpbnQgW10gYWN0dWFsU2l6ZSA9IG5ldyBpbnQgWzFdOworCQlyZXN1bHQgPSBPUy5HZXRDb250cm9sRGF0YSAoaGFuZGxlLCAoc2hvcnQpT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRDRlN0cmluZ1RhZywgNCwgcHRyLCBhY3R1YWxTaXplKTsKKwl9CisJaWYgKHJlc3VsdCAhPSBPUy5ub0VycikgcmV0dXJuICIiOworCWludCBsZW5ndGggPSBPUy5DRlN0cmluZ0dldExlbmd0aCAocHRyIFswXSk7CisJY2hhciBbXSBidWZmZXI9IG5ldyBjaGFyIFtsZW5ndGhdOworCUNGUmFuZ2UgcmFuZ2UgPSBuZXcgQ0ZSYW5nZSAoKTsKKwlyYW5nZS5sZW5ndGggPSBsZW5ndGg7CisJT1MuQ0ZTdHJpbmdHZXRDaGFyYWN0ZXJzIChwdHIgWzBdLCByYW5nZSwgYnVmZmVyKTsKKwlPUy5DRlJlbGVhc2UgKHB0ciBbMF0pOworCXJldHVybiBuZXcgU3RyaW5nIChidWZmZXIpOworfQorCiBwdWJsaWMgaW50IGdldFRleHRIZWlnaHQgKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKChzdHlsZSAmIFNXVC5EUk9QX0RPV04pICE9IDApIHsKLQkJLyoKLQkJKiBCdWcgaW4gTU9USUYuICBGb3Igc29tZSByZWFzb24sIFh0UXVlcnlHZW9tZXRyeSAoKQotCQkqIHJldHVybnMgdGhlIHdyb25nIGhlaWdodCB3aGVuIHRoZSBjb21ibyBpcyBub3QgcmVhbGl6ZWQuCi0JCSogVGhlIGZpeCBpcyB0byBmb3JjZSB0aGUgY29tYm8gdG8gYmUgcmVhbGl6ZWQgYnkgZm9yY2luZwotCQkqIHRoZSBzaGVsbCB0byBiZSByZWFsaXplZC4KLQkJKi8KLSAgICAgICAgLyogQVcKLQkJaWYgKCFPUy5YdElzUmVhbGl6ZWQgKGhhbmRsZSkpIGdldFNoZWxsICgpLnJlYWxpemVXaWRnZXQgKCk7Ci0JCVh0V2lkZ2V0R2VvbWV0cnkgcmVzdWx0ID0gbmV3IFh0V2lkZ2V0R2VvbWV0cnkgKCk7Ci0JCXJlc3VsdC5yZXF1ZXN0X21vZGUgPSBPUy5DV0hlaWdodDsKLQkJT1MuWHRRdWVyeUdlb21ldHJ5IChoYW5kbGUsIG51bGwsIHJlc3VsdCk7Ci0JCXJldHVybiByZXN1bHQuaGVpZ2h0OwotICAgICAgICAqLwotICAgICAgICByZXR1cm4gMjY7Ci0JfSBlbHNlIHsKLQkJLyogQ2FsY3VsYXRlIHRleHQgZmllbGQgaGVpZ2h0LiAqLwotICAgICAgICAvKiBBVwotCQlpbnQgW10gYXJnTGlzdCA9IHtPUy5YbU50ZXh0RmllbGQsIDB9OwotCQlPUy5YdEdldFZhbHVlcyAoaGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCQlpbnQgW10gYXJnTGlzdDIgPSB7T1MuWG1ObWFyZ2luSGVpZ2h0LCAwfTsKLQkJT1MuWHRHZXRWYWx1ZXMgKGFyZ0xpc3RbMV0sIGFyZ0xpc3QyLCBhcmdMaXN0Mi5sZW5ndGggLyAyKTsKLQkJaW50IGhlaWdodCA9IGdldEZvbnRIZWlnaHQgKCk7Ci0JCVhSZWN0YW5nbGUgcmVjdCA9IG5ldyBYUmVjdGFuZ2xlICgpOwotCQlPUy5YbVdpZGdldEdldERpc3BsYXlSZWN0IChhcmdMaXN0WzFdLCByZWN0KTsKLQkJaGVpZ2h0ICs9IChyZWN0LnkgKiAyKSArICgyICogYXJnTGlzdDJbMV0pOwotICAgICAgICAqLwotCi0JCS8qIEFkZCBpbiBjb21ibyBib3ggbWFyZ2lucy4gKi8KLSAgICAgICAgLyogQVcKLQkJaW50IFtdIGFyZ0xpc3QzID0ge09TLlhtTm1hcmdpbkhlaWdodCwgMCwgT1MuWG1Oc2hhZG93VGhpY2tuZXNzLCAwLCBPUy5YbU5oaWdobGlnaHRUaGlja25lc3MsIDB9OwotCQlPUy5YdEdldFZhbHVlcyhoYW5kbGUsIGFyZ0xpc3QzLCBhcmdMaXN0My5sZW5ndGggLyAyKTsKLQkJaGVpZ2h0ICs9ICgyICogYXJnTGlzdDNbMV0pICsgKDIgKiBhcmdMaXN0M1szXSkgKyAoMiAqIGFyZ0xpc3QzWzVdKTsKLQotCQlyZXR1cm4gaGVpZ2h0OwotICAgICAgICAqLwotICAgICAgICByZXR1cm4gMjY7Ci0JfQorCXJldHVybiAyNjsgLy8gTkVFRFMgV09SSwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRoYXQgdGhlIHJlY2VpdmVyJ3MKLSAqIHRleHQgZmllbGQgaXMgY2FwYWJsZSBvZiBob2xkaW5nLiBJZiB0aGlzIGhhcyBub3QgYmVlbiBjaGFuZ2VkCi0gKiBieSA8Y29kZT5zZXRUZXh0TGltaXQoKTwvY29kZT4sIGl0IHdpbGwgYmUgdGhlIGNvbnN0YW50Ci0gKiA8Y29kZT5Db21iby5MSU1JVDwvY29kZT4uCi0gKiAKLSAqIEByZXR1cm4gdGhlIHRleHQgbGltaXQKLSAqIAotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBpbnQgZ2V0VGV4dExpbWl0ICgpIHsKIAljaGVja1dpZGdldCgpOwotICAgIHJldHVybiB0ZXh0TGltaXQ7CisgICAgcmV0dXJuIExJTUlUOyAvLyBORUVEUyBXT1JLCiB9CisKIHZvaWQgaG9va0V2ZW50cyAoKSB7CiAJc3VwZXIuaG9va0V2ZW50cyAoKTsKLSAgICAvKiBBVwotCWludCB3aW5kb3dQcm9jID0gZ2V0RGlzcGxheSAoKS53aW5kb3dQcm9jOwotCU9TLlh0QWRkQ2FsbGJhY2sgKGhhbmRsZSwgT1MuWG1Oc2VsZWN0aW9uQ2FsbGJhY2ssIHdpbmRvd1Byb2MsIFNXVC5TZWxlY3Rpb24pOwotCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTnRleHRGaWVsZCwgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlPUy5YdEFkZENhbGxiYWNrIChhcmdMaXN0WzFdLCBPUy5YbU5hY3RpdmF0ZUNhbGxiYWNrLCB3aW5kb3dQcm9jLCBTV1QuRGVmYXVsdFNlbGVjdGlvbik7Ci0JT1MuWHRBZGRDYWxsYmFjayAoYXJnTGlzdFsxXSwgT1MuWG1OdmFsdWVDaGFuZ2VkQ2FsbGJhY2ssIHdpbmRvd1Byb2MsIFNXVC5Nb2RpZnkpOwotICAgICovCi19Ci0vKioKLSAqIFNlYXJjaGVzIHRoZSByZWNlaXZlcidzIGxpc3Qgc3RhcnRpbmcgYXQgdGhlIGZpcnN0IGl0ZW0KLSAqIChpbmRleCAwKSB1bnRpbCBhbiBpdGVtIGlzIGZvdW5kIHRoYXQgaXMgZXF1YWwgdG8gdGhlIAotICogYXJndW1lbnQsIGFuZCByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGF0IGl0ZW0uIElmIG5vIGl0ZW0KLSAqIGlzIGZvdW5kLCByZXR1cm5zIC0xLgotICoKLSAqIEBwYXJhbSBzdHJpbmcgdGhlIHNlYXJjaCBpdGVtCi0gKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgaXRlbQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHN0cmluZyBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KLXB1YmxpYyBpbnQgaW5kZXhPZiAoU3RyaW5nIHN0cmluZykgewotCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKHN0cmluZyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCWludCBpdGVtQ291bnQ9IF9nZXRJdGVtQ291bnQoKTsKLQlmb3IgKGludCBpPSAwOyBpIDwgaXRlbUNvdW50OyBpKyspIHsKLQkJU3RyaW5nIHM9IF9nZXRJdGVtKGkpOwotCQlpZiAocyAhPSBudWxsICYmIHN0cmluZy5lcXVhbHMocykpCi0JCQlyZXR1cm4gaTsKKwlpZiAoKHN0eWxlICYgU1dULlJFQURfT05MWSkgIT0gMCkgeworCQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCQlpbnQgY29tbWFuZFByb2MgPSBkaXNwbGF5LmNvbW1hbmRQcm9jOworCQlpbnQgW10gbWFzayA9IG5ldyBpbnQgW10geworCQkJT1Mua0V2ZW50Q2xhc3NDb21tYW5kLCBPUy5rRXZlbnRQcm9jZXNzQ29tbWFuZCwKKwkJfTsKKwkJaW50IG1lbnVUYXJnZXQgPSBPUy5HZXRNZW51RXZlbnRUYXJnZXQgKG1lbnVIYW5kbGUpOworCQlPUy5JbnN0YWxsRXZlbnRIYW5kbGVyIChtZW51VGFyZ2V0LCBjb21tYW5kUHJvYywgbWFzay5sZW5ndGggLyAyLCBtYXNrLCBoYW5kbGUsIG51bGwpOwkJCiAJfQotCXJldHVybiAtMTsKIH0KLS8qKgotICogU2VhcmNoZXMgdGhlIHJlY2VpdmVyJ3MgbGlzdCBzdGFydGluZyBhdCB0aGUgZ2l2ZW4sIAotICogemVyby1yZWxhdGl2ZSBpbmRleCB1bnRpbCBhbiBpdGVtIGlzIGZvdW5kIHRoYXQgaXMgZXF1YWwKLSAqIHRvIHRoZSBhcmd1bWVudCwgYW5kIHJldHVybnMgdGhlIGluZGV4IG9mIHRoYXQgaXRlbS4gSWYKLSAqIG5vIGl0ZW0gaXMgZm91bmQgb3IgdGhlIHN0YXJ0aW5nIGluZGV4IGlzIG91dCBvZiByYW5nZSwKLSAqIHJldHVybnMgLTEuCi0gKgotICogQHBhcmFtIHN0cmluZyB0aGUgc2VhcmNoIGl0ZW0KLSAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBpdGVtCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgc3RyaW5nIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCQorcHVibGljIGludCBpbmRleE9mIChTdHJpbmcgc3RyaW5nKSB7CisJcmV0dXJuIGluZGV4T2YgKHN0cmluZywgMCk7Cit9CisKIHB1YmxpYyBpbnQgaW5kZXhPZiAoU3RyaW5nIHN0cmluZywgaW50IHN0YXJ0KSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoc3RyaW5nID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0JaW50IGl0ZW1Db3VudD0gX2dldEl0ZW1Db3VudCgpOwotCWlmICghKCgwIDw9IHN0YXJ0KSAmJiAoc3RhcnQgPCBpdGVtQ291bnQpKSkgcmV0dXJuIC0xOwotCWZvciAoaW50IGk9IHN0YXJ0OyBpIDwgaXRlbUNvdW50OyBpKyspIHsKLQkJU3RyaW5nIHM9IF9nZXRJdGVtKGkpOwotCQlpZiAoc3RyaW5nLmVxdWFscyhzKSkKKwlpbnQgY291bnQgPSBnZXRJdGVtQ291bnQgKCk7CisJZm9yIChpbnQgaT1zdGFydDsgaTxjb3VudDsgaSsrKSB7CisJCWlmIChzdHJpbmcuZXF1YWxzIChnZXRJdGVtIChpKSkpIHsKIAkJCXJldHVybiBpOworCQl9CiAJfQogCXJldHVybiAtMTsKIH0KLS8qKgotICogUGFzdGVzIHRleHQgZnJvbSBjbGlwYm9hcmQuCi0gKiA8cD4KLSAqIFRoZSBzZWxlY3RlZCB0ZXh0IGlzIGRlbGV0ZWQgZnJvbSB0aGUgd2lkZ2V0Ci0gKiBhbmQgbmV3IHRleHQgaW5zZXJ0ZWQgZnJvbSB0aGUgY2xpcGJvYXJkLgotICogPC9wPgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqIAotICogQHNpbmNlIDIuMQotICovCisKK1JlY3QgZ2V0SW5zZXQgKCkgeworCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisJcmV0dXJuIGRpc3BsYXkuY29tYm9JbnNldDsKK30KKwkKK2ludCBrRXZlbnRQcm9jZXNzQ29tbWFuZCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWludCByZXN1bHQgPSBzdXBlci5rRXZlbnRQcm9jZXNzQ29tbWFuZCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKHJlc3VsdCA9PSBPUy5ub0VycikgcmV0dXJuIHJlc3VsdDsKKwkvKgorCSogSXQgaXMgcG9zc2libGUgKGJ1dCB1bmxpa2VseSksIHRoYXQgYXBwbGljYXRpb24KKwkqIGNvZGUgY291bGQgaGF2ZSBkaXNwb3NlZCB0aGUgd2lkZ2V0IGluIHRoZSBtb2RpZnkKKwkqIGV2ZW50LiAgSWYgdGhpcyBoYXBwZW5zLCBlbmQgdGhlIHByb2Nlc3Npbmcgb2YgdGhlCisJKiBXaW5kb3dzIG1lc3NhZ2UgYnkgcmV0dXJuaW5nIHplcm8gYXMgdGhlIHJlc3VsdCBvZgorCSogdGhlIHdpbmRvdyBwcm9jLgorCSovCisJc2VuZEV2ZW50IChTV1QuTW9kaWZ5KTsKKwlpZiAoaXNEaXNwb3NlZCAoKSkgcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKKwlwb3N0RXZlbnQgKFNXVC5TZWxlY3Rpb24pOworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRSYXdLZXlEb3duIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IHJlc3VsdCA9IHN1cGVyLmtFdmVudFJhd0tleURvd24gKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCWlmIChyZXN1bHQgPT0gT1Mubm9FcnIpIHJldHVybiByZXN1bHQ7CisJaW50IFtdIGtleUNvZGUgPSBuZXcgaW50IFsxXTsKKwlPUy5HZXRFdmVudFBhcmFtZXRlciAodGhlRXZlbnQsIE9TLmtFdmVudFBhcmFtS2V5Q29kZSwgT1MudHlwZVVJbnQzMiwgbnVsbCwga2V5Q29kZS5sZW5ndGggKiA0LCBudWxsLCBrZXlDb2RlKTsKKwlpZiAoa2V5Q29kZSBbMF0gPT0gMzYpIHsgLy9DUgorCQlzZW5kRXZlbnQgKFNXVC5EZWZhdWx0U2VsZWN0aW9uKTsKKwkJcmV0dXJuIE9TLm5vRXJyOworCX0KKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCQkKIHB1YmxpYyB2b2lkIHBhc3RlICgpIHsKIAljaGVja1dpZGdldCAoKTsKLQlpZiAobWVudUhhbmRsZSA9PSAwKSB7Ci0JCUNsaXBib2FyZCBjbGlwYm9hcmQ9IG5ldyBDbGlwYm9hcmQoZ2V0RGlzcGxheSgpKTsKLQkJVGV4dFRyYW5zZmVyIHRleHRUcmFuc2Zlcj0gVGV4dFRyYW5zZmVyLmdldEluc3RhbmNlKCk7Ci0JCVN0cmluZyBjbGlwQm9hcmQ9IChTdHJpbmcpY2xpcGJvYXJkLmdldENvbnRlbnRzKHRleHRUcmFuc2Zlcik7Ci0JCWNsaXBib2FyZC5kaXNwb3NlKCk7Ci0JCV9yZXBsYWNlVGV4dFNlbGVjdGlvbihjbGlwQm9hcmQpOworCWludFtdIHNjcmFwID0gbmV3IGludCBbMV07CisJT1MuR2V0Q3VycmVudFNjcmFwIChzY3JhcCk7CisJaW50IFtdIHNpemUgPSBuZXcgaW50IFsxXTsKKwlpZiAoT1MuR2V0U2NyYXBGbGF2b3JTaXplIChzY3JhcCBbMF0sIE9TLmtTY3JhcEZsYXZvclR5cGVUZXh0LCBzaXplKSAhPSBPUy5ub0VyciB8fCBzaXplIFswXSA9PSAwKSByZXR1cm47CisJYnl0ZSBbXSBidWZmZXIgPSBuZXcgYnl0ZVtzaXplIFswXV07CisJaWYgKE9TLkdldFNjcmFwRmxhdm9yRGF0YSAoc2NyYXAgWzBdLCBPUy5rU2NyYXBGbGF2b3JUeXBlVGV4dCwgc2l6ZSwgYnVmZmVyKSAhPSBPUy5ub0VycikgcmV0dXJuOworCWlmICgoc3R5bGUgJiBTV1QuUkVBRF9PTkxZKSAhPSAwKSB7CisJCVN0cmluZyBzdHJpbmcgPSBuZXcgU3RyaW5nIChidWZmZXIpOyAvLz8/CisJCWludCBpbmRleCA9IGluZGV4T2YgKHN0cmluZyk7CisJCWlmIChpbmRleCAhPSAtMSkgc2VsZWN0KGluZGV4KTsKKwl9IGVsc2UgeworCQlieXRlIFtdIG5ld0J1ZmZlcjsKKwkJaW50IGVuY29kaW5nID0gT1MuQ0ZTdHJpbmdHZXRTeXN0ZW1FbmNvZGluZyAoKTsKKwkJaW50W10gcHRyT2xkID0gbmV3IGludCBbMV07CisJCWlmIChPUy5HZXRDb250cm9sRGF0YSAoaGFuZGxlLCAoc2hvcnQpT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRDRlN0cmluZ1RhZywgNCwgcHRyT2xkLCBudWxsKSA9PSBPUy5ub0VycikgeworCQkJc2hvcnQgW10gcyA9IG5ldyBzaG9ydCBbMl07CisJCQlPUy5HZXRDb250cm9sRGF0YSAoaGFuZGxlLCAoc2hvcnQpT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRTZWxlY3Rpb25UYWcsIDQsIHMsIG51bGwpOworCQkJQ0ZSYW5nZSByYW5nZSA9IG5ldyBDRlJhbmdlICgpOworCQkJcmFuZ2UubG9jYXRpb24gPSAwOworCQkJcmFuZ2UubGVuZ3RoID0gcyBbMF07CisJCQlzaXplID0gbmV3IGludCBbMV07CisJCQlPUy5DRlN0cmluZ0dldEJ5dGVzIChwdHJPbGQgWzBdLCByYW5nZSwgZW5jb2RpbmcsIChieXRlKSc/JywgdHJ1ZSwgbnVsbCwgMCwgc2l6ZSk7CisJCQlieXRlIFtdIHByZUJ1ZmZlciA9IG5ldyBieXRlIFtzaXplIFswXV07CisJCQlPUy5DRlN0cmluZ0dldEJ5dGVzKHB0ck9sZCBbMF0sIHJhbmdlLCBlbmNvZGluZywgKGJ5dGUpJz8nLCB0cnVlLCBwcmVCdWZmZXIsIHNpemUgWzBdLCBzaXplKTsKKwkJCXJhbmdlLmxvY2F0aW9uID0gcyBbMV07CisJCQlyYW5nZS5sZW5ndGggPSBPUy5DRlN0cmluZ0dldExlbmd0aCAocHRyT2xkIFswXSkgLSBzIFsxXTsKKwkJCXNpemUgPSBuZXcgaW50IFsxXTsKKwkJCU9TLkNGU3RyaW5nR2V0Qnl0ZXMgKHB0ck9sZCBbMF0sIHJhbmdlLCBlbmNvZGluZywgKGJ5dGUpJz8nLCB0cnVlLCBudWxsLCAwLCBzaXplKTsKKwkJCWJ5dGUgW10gcG9zdEJ1ZmZlciA9IG5ldyBieXRlIFtzaXplIFswXV07CisJCQlPUy5DRlN0cmluZ0dldEJ5dGVzKHB0ck9sZCBbMF0sIHJhbmdlLCBlbmNvZGluZywgKGJ5dGUpJz8nLCB0cnVlLCBwb3N0QnVmZmVyLCBzaXplIFswXSwgc2l6ZSk7CisJCQluZXdCdWZmZXIgPSBuZXcgYnl0ZSBbcHJlQnVmZmVyLmxlbmd0aCArIGJ1ZmZlci5sZW5ndGggKyBwb3N0QnVmZmVyLmxlbmd0aF07CisJCQlTeXN0ZW0uYXJyYXljb3B5KHByZUJ1ZmZlciwgMCwgbmV3QnVmZmVyLCAwLCBwcmVCdWZmZXIubGVuZ3RoKTsKKwkJCVN5c3RlbS5hcnJheWNvcHkoYnVmZmVyLCAwLCBuZXdCdWZmZXIsIHByZUJ1ZmZlci5sZW5ndGgsIGJ1ZmZlci5sZW5ndGgpOworCQkJU3lzdGVtLmFycmF5Y29weShwb3N0QnVmZmVyLCAwLCBuZXdCdWZmZXIsIHByZUJ1ZmZlci5sZW5ndGggKyBidWZmZXIubGVuZ3RoLCBwb3N0QnVmZmVyLmxlbmd0aCk7CisJCQlPUy5DRlJlbGVhc2UgKHB0ck9sZCBbMF0pOworCQl9IGVsc2UgeworCQkJbmV3QnVmZmVyID0gYnVmZmVyOworCQl9CisJCWludCBwdHIgPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhCeXRlcyAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgbmV3QnVmZmVyLCBuZXdCdWZmZXIubGVuZ3RoLCBlbmNvZGluZywgdHJ1ZSk7CisJCU9TLlNldENvbnRyb2xEYXRhIChoYW5kbGUsIE9TLmtISUNvbWJvQm94RWRpdFRleHRQYXJ0LCBPUy5rQ29udHJvbEVkaXRUZXh0Q0ZTdHJpbmdUYWcsIDQsIG5ldyBpbnRbXSB7cHRyfSk7CisJCU9TLkNGUmVsZWFzZSAocHRyKTsKIAl9CiB9Ci0vKioKLSAqIFJlbW92ZXMgdGhlIGl0ZW0gZnJvbSB0aGUgcmVjZWl2ZXIncyBsaXN0IGF0IHRoZSBnaXZlbgotICogemVyby1yZWxhdGl2ZSBpbmRleC4KLSAqCi0gKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IGZvciB0aGUgaXRlbQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1JBTkdFIC0gaWYgdGhlIGluZGV4IGlzIG5vdCBiZXR3ZWVuIDAgYW5kIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGxpc3QgbWludXMgMSAoaW5jbHVzaXZlKTwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSVRFTV9OT1RfUkVNT1ZFRCAtIGlmIHRoZSBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCByZW1vdmUgKGludCBpbmRleCkgewotCWNoZWNrV2lkZ2V0KCk7CisJY2hlY2tXaWRnZXQgKCk7CiAJaWYgKGluZGV4ID09IC0xKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOwotCWludCBpdGVtQ291bnQ9IF9nZXRJdGVtQ291bnQoKTsKLQlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbUNvdW50KSkgewotCQllcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOworCWludCBjb3VudCA9IGdldEl0ZW1Db3VudCAoKTsKKwlpZiAoMCA+IGluZGV4IHx8IGluZGV4ID49IGNvdW50KSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOworCWlmICgoc3R5bGUgJiBTV1QuUkVBRF9PTkxZKSAhPSAwKSB7CisJCU9TLkRlbGV0ZU1lbnVJdGVtcyAobWVudUhhbmRsZSwgKHNob3J0KShpbmRleCsxKSwgMSk7CisJfSBlbHNlIHsKKwkJT1MuSElDb21ib0JveFJlbW92ZUl0ZW1BdEluZGV4IChoYW5kbGUsIGluZGV4KTsKIAl9Ci0gICAJaWYgKG1lbnVIYW5kbGUgIT0gMCkgewotCQlPUy5EZWxldGVNZW51SXRlbXMobWVudUhhbmRsZSwgKHNob3J0KShpbmRleCsxKSwgMSk7Ci0JCU9TLlNldENvbnRyb2wzMkJpdE1heGltdW0oaGFuZGxlLCBPUy5Db3VudE1lbnVJdGVtcyhtZW51SGFuZGxlKSk7Ci0gICAJfSBlbHNlIHsKLSAgIAkJT1MuSElDb21ib0JveFJlbW92ZUl0ZW1BdEluZGV4KGhhbmRsZSwgaW5kZXgpOwotICAgCX0KIH0KLS8qKgotICogUmVtb3ZlcyB0aGUgaXRlbXMgZnJvbSB0aGUgcmVjZWl2ZXIncyBsaXN0IHdoaWNoIGFyZQotICogYmV0d2VlbiB0aGUgZ2l2ZW4gemVyby1yZWxhdGl2ZSBzdGFydCBhbmQgZW5kIAotICogaW5kaWNlcyAoaW5jbHVzaXZlKS4KLSAqCi0gKiBAcGFyYW0gc3RhcnQgdGhlIHN0YXJ0IG9mIHRoZSByYW5nZQotICogQHBhcmFtIGVuZCB0aGUgZW5kIG9mIHRoZSByYW5nZQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1JBTkdFIC0gaWYgZWl0aGVyIHRoZSBzdGFydCBvciBlbmQgYXJlIG5vdCBiZXR3ZWVuIDAgYW5kIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGxpc3QgbWludXMgMSAoaW5jbHVzaXZlKTwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSVRFTV9OT1RfUkVNT1ZFRCAtIGlmIHRoZSBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCByZW1vdmUgKGludCBzdGFydCwgaW50IGVuZCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHN0YXJ0ID4gZW5kKSByZXR1cm47Ci0JaW50IGl0ZW1Db3VudD0gX2dldEl0ZW1Db3VudCgpOwotCWlmICghKDAgPD0gc3RhcnQgJiYgc3RhcnQgPCBpdGVtQ291bnQpKSB7Ci0JCWVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7Ci0JfQotCWludCBuZXdFbmQgPSBNYXRoLm1pbiAoZW5kLCBpdGVtQ291bnQgLSAxKTsKLQlpZiAobWVudUhhbmRsZSAhPSAwKSB7Ci0JCU9TLkRlbGV0ZU1lbnVJdGVtcyhtZW51SGFuZGxlLCAoc2hvcnQpKHN0YXJ0KzEpLCBuZXdFbmQtc3RhcnQrMSk7Ci0JCU9TLlNldENvbnRyb2wzMkJpdE1heGltdW0oaGFuZGxlLCBPUy5Db3VudE1lbnVJdGVtcyhtZW51SGFuZGxlKSk7CisJaW50IGNvdW50ID0gZ2V0SXRlbUNvdW50ICgpOworCWlmICgwID4gc3RhcnQgfHwgc3RhcnQgPj0gY291bnQpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7CisJaW50IG5ld0VuZCA9IE1hdGgubWluIChlbmQsIGNvdW50IC0gMSk7CisJaWYgKChzdHlsZSAmIFNXVC5SRUFEX09OTFkpICE9IDApIHsKKwkJT1MuRGVsZXRlTWVudUl0ZW1zIChtZW51SGFuZGxlLCAoc2hvcnQpKHN0YXJ0KzEpLCBuZXdFbmQtc3RhcnQrMSk7CisJCU9TLlNldENvbnRyb2wzMkJpdE1heGltdW0gKGhhbmRsZSwgT1MuQ291bnRNZW51SXRlbXMgKG1lbnVIYW5kbGUpKTsKIAl9IGVsc2UgewotCQlmb3IgKGludCBpPSBlbmQ7IGkgPj0gc3RhcnQ7IGktLSkKLSAgCQkJT1MuSElDb21ib0JveFJlbW92ZUl0ZW1BdEluZGV4KGhhbmRsZSwgaSk7CisJCS8vIE5FRURTIFdPUksKKwkJZm9yIChpbnQgaT1uZXdFbmQ7IGk+PXN0YXJ0OyBpLS0pIHsKKwkJCU9TLkhJQ29tYm9Cb3hSZW1vdmVJdGVtQXRJbmRleChoYW5kbGUsIGkpOworCQl9CiAJfQogfQotLyoqCi0gKiBTZWFyY2hlcyB0aGUgcmVjZWl2ZXIncyBsaXN0IHN0YXJ0aW5nIGF0IHRoZSBmaXJzdCBpdGVtCi0gKiB1bnRpbCBhbiBpdGVtIGlzIGZvdW5kIHRoYXQgaXMgZXF1YWwgdG8gdGhlIGFyZ3VtZW50LCAKLSAqIGFuZCByZW1vdmVzIHRoYXQgaXRlbSBmcm9tIHRoZSBsaXN0LgotICoKLSAqIEBwYXJhbSBzdHJpbmcgdGhlIGl0ZW0gdG8gcmVtb3ZlCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgc3RyaW5nIGlzIG51bGw8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfQVJHVU1FTlQgLSBpZiB0aGUgc3RyaW5nIGlzIG5vdCBmb3VuZCBpbiB0aGUgbGlzdDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSVRFTV9OT1RfUkVNT1ZFRCAtIGlmIHRoZSBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCByZW1vdmUgKFN0cmluZyBzdHJpbmcpIHsKLQljaGVja1dpZGdldCgpOworCWNoZWNrV2lkZ2V0ICgpOwogCWlmIChzdHJpbmcgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQlpbnQgaXRlbUNvdW50PSBfZ2V0SXRlbUNvdW50KCk7Ci0JZm9yIChpbnQgaT0gMDsgaSA8IGl0ZW1Db3VudDsgaSsrKSB7Ci0JCVN0cmluZyBzPSBfZ2V0SXRlbShpKTsKLQkJaWYgKHMgIT0gbnVsbCAmJiBzdHJpbmcuZXF1YWxzKHMpKSB7Ci0JCQlyZW1vdmUoaSk7CisJLy8gTkVFRFMgV09SSworCWludCBjb3VudCA9IGdldEl0ZW1Db3VudCAoKTsKKwlmb3IgKGludCBpPTA7IGk8Y291bnQ7IGkrKykgeworCQlTdHJpbmcgcyA9IGdldEl0ZW0gKGkpOworCQlpZiAoc3RyaW5nLmVxdWFscyAocykpIHsKKwkJCXJlbW92ZSAoaSk7CiAJCQlyZXR1cm47CiAJCX0KIAl9CiAJZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKIH0KLS8qKgotICogUmVtb3ZlcyBhbGwgb2YgdGhlIGl0ZW1zIGZyb20gdGhlIHJlY2VpdmVyJ3MgbGlzdC4KLSAqIDxwPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHJlbW92ZUFsbCAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlpbnQgaXRlbUNvdW50PSBfZ2V0SXRlbUNvdW50KCk7Ci0JaWYgKGl0ZW1Db3VudCA+IDApIHsKLQkJaWYgKG1lbnVIYW5kbGUgIT0gMCkgewotCQkJT1MuRGVsZXRlTWVudUl0ZW1zKG1lbnVIYW5kbGUsIChzaG9ydCkxLCBpdGVtQ291bnQpOwotCQkJT1MuU2V0Q29udHJvbDMyQml0TWF4aW11bShoYW5kbGUsIE9TLkNvdW50TWVudUl0ZW1zKG1lbnVIYW5kbGUpKTsKLQkJfSBlbHNlIHsKLQkJCWZvciAoaW50IGk9IGl0ZW1Db3VudC0xOyBpID49IDA7IGktLSkKLSAgCQkJCU9TLkhJQ29tYm9Cb3hSZW1vdmVJdGVtQXRJbmRleChoYW5kbGUsIGkpOworCWNoZWNrV2lkZ2V0ICgpOworCWludCBjb3VudCA9IGdldEl0ZW1Db3VudCAoKTsKKwlpZiAoKHN0eWxlICYgU1dULlJFQURfT05MWSkgIT0gMCkgeworCQlPUy5EZWxldGVNZW51SXRlbXMgKG1lbnVIYW5kbGUsIChzaG9ydCkxLCBjb3VudCk7CisJfSBlbHNlIHsKKwkJLy8gTkVFRFMgV09SSworCQlpZiAoY291bnQgPiAwKSB7CisJCQlmb3IgKGludCBpPWNvdW50LTE7IGk+PTA7IGktLSkgeworICAJCQkJT1MuSElDb21ib0JveFJlbW92ZUl0ZW1BdEluZGV4IChoYW5kbGUsIGkpOworCQkJfQogCQl9CiAJfQogfQotLyoqCi0gKiBSZW1vdmVzIHRoZSBsaXN0ZW5lciBmcm9tIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgcmVjZWl2ZXIncyB0ZXh0IGlzIG1vZGlmaWVkLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIG5vIGxvbmdlciBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIE1vZGlmeUxpc3RlbmVyCi0gKiBAc2VlICNhZGRNb2RpZnlMaXN0ZW5lcgotICovCisKIHB1YmxpYyB2b2lkIHJlbW92ZU1vZGlmeUxpc3RlbmVyIChNb2RpZnlMaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaWYgKGV2ZW50VGFibGUgPT0gbnVsbCkgcmV0dXJuOwogCWV2ZW50VGFibGUudW5ob29rIChTV1QuTW9kaWZ5LCBsaXN0ZW5lcik7CiB9Ci0vKioKLSAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSByZWNlaXZlcidzIHNlbGVjdGlvbiBjaGFuZ2VzLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIG5vIGxvbmdlciBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNlbGVjdGlvbkxpc3RlbmVyCi0gKiBAc2VlICNhZGRTZWxlY3Rpb25MaXN0ZW5lcgotICovCisKIHB1YmxpYyB2b2lkIHJlbW92ZVNlbGVjdGlvbkxpc3RlbmVyIChTZWxlY3Rpb25MaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC05ODQsNDQwICs1NzMsOTYgQEAKIAlldmVudFRhYmxlLnVuaG9vayAoU1dULlNlbGVjdGlvbiwgbGlzdGVuZXIpOwogCWV2ZW50VGFibGUudW5ob29rIChTV1QuRGVmYXVsdFNlbGVjdGlvbixsaXN0ZW5lcik7CiB9Ci0vKioKLSAqIFNlbGVjdHMgdGhlIGl0ZW0gYXQgdGhlIGdpdmVuIHplcm8tcmVsYXRpdmUgaW5kZXggaW4gdGhlIHJlY2VpdmVyJ3MgCi0gKiBsaXN0LiAgSWYgdGhlIGl0ZW0gYXQgdGhlIGluZGV4IHdhcyBhbHJlYWR5IHNlbGVjdGVkLCBpdCByZW1haW5zCi0gKiBzZWxlY3RlZC4gSW5kaWNlcyB0aGF0IGFyZSBvdXQgb2YgcmFuZ2UgYXJlIGlnbm9yZWQuCi0gKgotICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgaXRlbSB0byBzZWxlY3QKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2VsZWN0IChpbnQgaW5kZXgpIHsKLQljaGVja1dpZGdldCgpOwotCQotCWludCBpdGVtQ291bnQ9IF9nZXRJdGVtQ291bnQoKTsKLQlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbUNvdW50KSkgewotCQllcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOwotCX0KLQkKLQlpZiAobWVudUhhbmRsZSAhPSAwKSB7Ci0JCWludCBzZWxlY3RlZD0gT1MuR2V0Q29udHJvbFZhbHVlKGhhbmRsZSktMTsKLQkJaWYgKGluZGV4ICE9IHNlbGVjdGVkKQl7Ci0JCQlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUsIGluZGV4KzEpOwotCQkJc2VuZEV2ZW50KFNXVC5Nb2RpZnkpOwotCQl9CisJY2hlY2tXaWRnZXQgKCk7CisJaW50IGNvdW50ID0gZ2V0SXRlbUNvdW50ICgpOworCWlmICgwID4gaW5kZXggfHwgaW5kZXggPj0gY291bnQpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7CisJaWYgKChzdHlsZSAmIFNXVC5SRUFEX09OTFkpICE9IDApIHsKKwkJT1MuU2V0Q29udHJvbDMyQml0VmFsdWUgKGhhbmRsZSwgaW5kZXgrMSk7CiAJfSBlbHNlIHsKLQkJU3RyaW5nIHN0cmluZz0gX2dldEl0ZW0oaW5kZXgpOwotCQlfc2V0VGV4dChzdHJpbmcpOwotCQlfc2VsZWN0QWxsKCk7CisJCWludFtdIHB0ciA9IG5ldyBpbnRbMV07CisJCWlmIChPUy5ISUNvbWJvQm94Q29weVRleHRJdGVtQXRJbmRleCAoaGFuZGxlLCBpbmRleCwgcHRyKSAhPSBPUy5ub0VycikgcmV0dXJuOworCQlPUy5TZXRDb250cm9sRGF0YSAoaGFuZGxlLCAoc2hvcnQpT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRDRlN0cmluZ1RhZywgNCwgcHRyKTsKKwkJT1MuQ0ZSZWxlYXNlIChwdHIgWzBdKTsJCQogCX0KIH0KLS8qKgotKiBTZXRzIHRoZSB3aWRnZXQgYm91bmRzLgotKi8KLXB1YmxpYyB2b2lkIHNldEJvdW5kcyAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKLQljaGVja1dpZGdldCgpOwotCWludCBuZXdIZWlnaHQgPSAoKHN0eWxlICYgU1dULkRST1BfRE9XTikgIT0gMCkgPyBnZXRUZXh0SGVpZ2h0KCkgOiBoZWlnaHQ7Ci0Jc3VwZXIuc2V0Qm91bmRzICh4LCB5LCB3aWR0aCwgbmV3SGVpZ2h0KTsKLX0KLS8qKgotICogU2V0cyB0aGUgdGV4dCBvZiB0aGUgaXRlbSBpbiB0aGUgcmVjZWl2ZXIncyBsaXN0IGF0IHRoZSBnaXZlbgotICogemVyby1yZWxhdGl2ZSBpbmRleCB0byB0aGUgc3RyaW5nIGFyZ3VtZW50LiBUaGlzIGlzIGVxdWl2YWxlbnQKLSAqIHRvIDxjb2RlPnJlbW92ZTwvY29kZT4naW5nIHRoZSBvbGQgaXRlbSBhdCB0aGUgaW5kZXgsIGFuZCB0aGVuCi0gKiA8Y29kZT5hZGQ8L2NvZGU+J2luZyB0aGUgbmV3IGl0ZW0gYXQgdGhhdCBpbmRleC4KLSAqCi0gKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IGZvciB0aGUgaXRlbQotICogQHBhcmFtIHN0cmluZyB0aGUgbmV3IHRleHQgZm9yIHRoZSBpdGVtCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfUkFOR0UgLSBpZiB0aGUgaW5kZXggaXMgbm90IGJldHdlZW4gMCBhbmQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgbGlzdCBtaW51cyAxIChpbmNsdXNpdmUpPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEVycm9yIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JVEVNX05PVF9SRU1PVkVEIC0gaWYgdGhlIHJlbW92ZSBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogICAgPGxpPkVSUk9SX0lURU1fTk9UX0FEREVEIC0gaWYgdGhlIGFkZCBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRJdGVtIChpbnQgaW5kZXgsIFN0cmluZyBzdHJpbmcpIHsKLQljaGVja1dpZGdldCgpOworCWNoZWNrV2lkZ2V0ICgpOwogCWlmIChzdHJpbmcgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQlpZiAoaW5kZXggPT0gLTEpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7Ci0gICAgLyogQVcKLQlpbnQgW10gYXJnTGlzdCA9IHtPUy5YbU5saXN0LCAwLCBPUy5YbU5pdGVtQ291bnQsIDB9OwotCU9TLlh0R2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JaWYgKCEoMCA8PSBpbmRleCAmJiBpbmRleCA8IGFyZ0xpc3QgWzNdKSkgewotCQllcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOworCWludCBjb3VudCA9IGdldEl0ZW1Db3VudCAoKTsKKwlpZiAoMCA+IGluZGV4IHx8IGluZGV4ID49IGNvdW50KSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOworCWNoYXIgW10gYnVmZmVyID0gbmV3IGNoYXIgW3N0cmluZy5sZW5ndGggKCldOworCXN0cmluZy5nZXRDaGFycyAoMCwgYnVmZmVyLmxlbmd0aCwgYnVmZmVyLCAwKTsKKwlpbnQgcHRyID0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgYnVmZmVyLCBidWZmZXIubGVuZ3RoKTsKKwlpZiAocHRyID09IDApIGVycm9yIChTV1QuRVJST1JfSVRFTV9OT1RfQURERUQpOworCWludCByZXN1bHQ7CisJaWYgKChzdHlsZSAmIFNXVC5SRUFEX09OTFkpICE9IDApIHsKKwkJcmVzdWx0ID0gT1MuU2V0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nIChtZW51SGFuZGxlLCAoc2hvcnQpKGluZGV4KzEpLCBwdHIpOworCX0gZWxzZSB7CisJCXJlc3VsdCA9IE9TLkhJQ29tYm9Cb3hJbnNlcnRUZXh0SXRlbUF0SW5kZXggKGhhbmRsZSwgaW5kZXgsIHB0cik7CisJCU9TLkhJQ29tYm9Cb3hSZW1vdmVJdGVtQXRJbmRleCAoaGFuZGxlLCBpbmRleCsxKTsKIAl9Ci0JYnl0ZSBbXSBidWZmZXIgPSBDb252ZXJ0ZXIud2NzVG9NYmNzIChnZXRDb2RlUGFnZSAoKSwgZW5jb2RlU3RyaW5nKHN0cmluZyksIHRydWUpOwotCWludCB4bVN0cmluZyA9IE9TLlhtU3RyaW5nQ3JlYXRlTG9jYWxpemVkIChidWZmZXIpOwotCWlmICh4bVN0cmluZyA9PSAwKSBlcnJvciAoU1dULkVSUk9SX0lURU1fTk9UX0FEREVEKTsKLQlib29sZWFuIGlzU2VsZWN0ZWQgPSBPUy5YbUxpc3RQb3NTZWxlY3RlZCAoYXJnTGlzdFsxXSwgaW5kZXggKyAxKTsKLQlPUy5YbUxpc3RSZXBsYWNlSXRlbXNQb3NVbnNlbGVjdGVkIChhcmdMaXN0WzFdLCBuZXcgaW50IFtdIHt4bVN0cmluZ30sIDEsIGluZGV4ICsgMSk7Ci0JaWYgKGlzU2VsZWN0ZWQpIE9TLlhtTGlzdFNlbGVjdFBvcyAoYXJnTGlzdFsxXSwgaW5kZXggKyAxLCBmYWxzZSk7Ci0JT1MuWG1TdHJpbmdGcmVlICh4bVN0cmluZyk7Ci0gICAgKi8KLQlpbnQgc0hhbmRsZT0gMDsKLQl0cnkgewotCQlzSGFuZGxlPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzKHN0cmluZyk7Ci0JCWlmIChtZW51SGFuZGxlICE9IDApIHsKLQkJCWlmIChPUy5TZXRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcobWVudUhhbmRsZSwgKHNob3J0KShpbmRleCsxKSwgc0hhbmRsZSkgIT0gT1Mua05vRXJyKQotCQkJCWVycm9yIChTV1QuRVJST1JfSVRFTV9OT1RfQURERUQpOwotCQl9IGVsc2UgewotCQkJT1MuSElDb21ib0JveEluc2VydFRleHRJdGVtQXRJbmRleChoYW5kbGUsIGluZGV4LCBzSGFuZGxlKTsKLQkJCU9TLkhJQ29tYm9Cb3hSZW1vdmVJdGVtQXRJbmRleChoYW5kbGUsIGluZGV4KzEpOwotCQl9Ci0JfSBmaW5hbGx5IHsKLQkJaWYgKHNIYW5kbGUgIT0gMCkKLQkJCU9TLkNGUmVsZWFzZShzSGFuZGxlKTsKLQl9CisJT1MuQ0ZSZWxlYXNlKHB0cik7CisJaWYgKHJlc3VsdCAhPSBPUy5ub0VycikgZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9BRERFRCk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgbGlzdCB0byBiZSB0aGUgZ2l2ZW4gYXJyYXkgb2YgaXRlbXMuCi0gKgotICogQHBhcmFtIGl0ZW1zIHRoZSBhcnJheSBvZiBpdGVtcwotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXJyb3IgPHVsPgotICogICAgPGxpPkVSUk9SX0lURU1fTk9UX0FEREVEIC0gaWYgdGhlIG9wZXJhdGlvbiBmYWlscyBiZWNhdXNlIG9mIGFuIG9wZXJhdGluZyBzeXN0ZW0gZmFpbHVyZTwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldEl0ZW1zIChTdHJpbmcgW10gaXRlbXMpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChpdGVtcyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCi0JaWYgKGl0ZW1zLmxlbmd0aCA9PSAwKSB7Ci0JCXJlbW92ZUFsbCgpOwotCQlyZXR1cm47Ci0JfQotCi0gICAgLyogQVcKLQlpbnQgaW5kZXggPSAwOwotCWludCBbXSB0YWJsZSA9IG5ldyBpbnQgW2l0ZW1zLmxlbmd0aF07Ci0JU3RyaW5nIGNvZGVQYWdlID0gZ2V0Q29kZVBhZ2UgKCk7Ci0Jd2hpbGUgKGluZGV4IDwgaXRlbXMubGVuZ3RoKSB7Ci0JCVN0cmluZyBzdHJpbmcgPSBpdGVtcyBbaW5kZXhdOwotCQlpZiAoc3RyaW5nID09IG51bGwpIGJyZWFrOwotCQlieXRlIFtdIGJ1ZmZlciA9IENvbnZlcnRlci53Y3NUb01iY3MgKGNvZGVQYWdlLCBlbmNvZGVTdHJpbmcoc3RyaW5nKSwgdHJ1ZSk7Ci0JCWludCB4bVN0cmluZyA9IE9TLlhtU3RyaW5nQ3JlYXRlTG9jYWxpemVkIChidWZmZXIpOwotCQlpZiAoeG1TdHJpbmcgPT0gMCkgYnJlYWs7Ci0JCXRhYmxlIFtpbmRleCsrXSA9IHhtU3RyaW5nOwotCX0KLQlpbnQgcHRyID0gT1MuWHRNYWxsb2MgKGluZGV4ICogNCk7Ci0JT1MubWVtbW92ZSAocHRyLCB0YWJsZSwgaW5kZXggKiA0KTsKLQlpbnQgW10gYXJnTGlzdCA9IHtPUy5YbU5pdGVtcywgcHRyLCBPUy5YbU5pdGVtQ291bnQsIGluZGV4fTsKLQlPUy5YdFNldFZhbHVlcyAoaGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCWZvciAoaW50IGk9MDsgaTxpbmRleDsgaSsrKSBPUy5YbVN0cmluZ0ZyZWUgKHRhYmxlIFtpXSk7Ci0JT1MuWHRGcmVlIChwdHIpOwotCWlmIChpbmRleCA8IGl0ZW1zLmxlbmd0aCkgZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9BRERFRCk7Ci0gICAgKi8KLQkKLQlpZiAobWVudUhhbmRsZSAhPSAwKSB7Ci0JCWZvciAoaW50IGk9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykgewotCQkJU3RyaW5nIHN0cmluZz0gaXRlbXNbaV07Ci0JCQlpZiAoc3RyaW5nID09IG51bGwpCi0JCQkJYnJlYWs7Ci0JCQlpbnQgc0hhbmRsZT0gMDsKLQkJCXRyeSB7Ci0JCQkJc0hhbmRsZT0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyhzdHJpbmcpOwotCQkJCWlmIChPUy5BcHBlbmRNZW51SXRlbVRleHRXaXRoQ0ZTdHJpbmcobWVudUhhbmRsZSwgc0hhbmRsZSwgMCwgZmdDb21tYW5kSUQrKywgbnVsbCkgIT0gT1Mua05vRXJyKQotCQkJCQllcnJvciAoU1dULkVSUk9SX0lURU1fTk9UX0FEREVEKTsKLQkJCX0gZmluYWxseSB7Ci0JCQkJaWYgKHNIYW5kbGUgIT0gMCkKLQkJCQkJT1MuQ0ZSZWxlYXNlKHNIYW5kbGUpOwotCQkJfQorCXJlbW92ZUFsbCgpOworCWlmIChpdGVtcy5sZW5ndGggPT0gMCkgcmV0dXJuOworCWZvciAoaW50IGk9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykgeworCQlTdHJpbmcgc3RyaW5nID0gaXRlbXNbaV07CisJCWlmIChzdHJpbmcgPT0gbnVsbCkgY29udGludWU7CisJCWNoYXIgW10gYnVmZmVyID0gbmV3IGNoYXIgW3N0cmluZy5sZW5ndGggKCldOworCQlzdHJpbmcuZ2V0Q2hhcnMgKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlciwgMCk7CisJCWludCBwdHIgPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzIChPUy5rQ0ZBbGxvY2F0b3JEZWZhdWx0LCBidWZmZXIsIGJ1ZmZlci5sZW5ndGgpOworCQlpZiAocHRyID09IDApIGVycm9yIChTV1QuRVJST1JfSVRFTV9OT1RfQURERUQpOworCQlpbnQgcmVzdWx0OworCQlpZiAoKHN0eWxlICYgU1dULlJFQURfT05MWSkgIT0gMCkgeworCQkJcmVzdWx0ID0gT1MuQXBwZW5kTWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nIChtZW51SGFuZGxlLCBwdHIsIDAsIDAsIG51bGwpOworCQl9IGVsc2UgeworCQkJaW50IFtdIG91dEluZGV4ID0gbmV3IGludFsxXTsKKwkJCXJlc3VsdCA9IE9TLkhJQ29tYm9Cb3hBcHBlbmRUZXh0SXRlbSAoaGFuZGxlLCBwdHIsIG91dEluZGV4KTsKIAkJfQotCQlPUy5TZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSwgaXRlbXMubGVuZ3RoKTsKLQl9IGVsc2UgewotCQlyZW1vdmVBbGwoKTsKLQkJZm9yIChpbnQgaT0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgaSsrKSB7Ci0JCQlTdHJpbmcgc3RyaW5nPSBpdGVtc1tpXTsKLQkJCWlmIChzdHJpbmcgPT0gbnVsbCkKLQkJCQlicmVhazsKLQkJCWludCBzSGFuZGxlPSAwOwotCQkJdHJ5IHsKLQkJCQlzSGFuZGxlPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzKHN0cmluZyk7Ci0JCQkJaWYgKE9TLkhJQ29tYm9Cb3hBcHBlbmRUZXh0SXRlbShoYW5kbGUsIHNIYW5kbGUpICE9IE9TLmtOb0VycikKLQkJCQkJZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9BRERFRCk7Ci0JCQl9IGZpbmFsbHkgewotCQkJCWlmIChzSGFuZGxlICE9IDApCi0JCQkJCU9TLkNGUmVsZWFzZShzSGFuZGxlKTsKLQkJCX0KLQkJfQorCQlPUy5DRlJlbGVhc2UocHRyKTsKKwkJaWYgKHJlc3VsdCAhPSBPUy5ub0VycikgZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9BRERFRCk7CiAJfQogfQotLyoqCi0gKiBTZXRzIHRoZSBzZWxlY3Rpb24gaW4gdGhlIHJlY2VpdmVyJ3MgdGV4dCBmaWVsZCB0byB0aGUKLSAqIHJhbmdlIHNwZWNpZmllZCBieSB0aGUgYXJndW1lbnQgd2hvc2UgeCBjb29yZGluYXRlIGlzIHRoZQotICogc3RhcnQgb2YgdGhlIHNlbGVjdGlvbiBhbmQgd2hvc2UgeSBjb29yZGluYXRlIGlzIHRoZSBlbmQKLSAqIG9mIHRoZSBzZWxlY3Rpb24uIAotICoKLSAqIEBwYXJhbSBhIHBvaW50IHJlcHJlc2VudGluZyB0aGUgbmV3IHNlbGVjdGlvbiBzdGFydCBhbmQgZW5kCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcG9pbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldFNlbGVjdGlvbiAoUG9pbnQgc2VsZWN0aW9uKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlpZiAobWVudUhhbmRsZSA9PSAwKSB7Ci0JCXNob3J0W10gcz0gbmV3IHNob3J0W10geyAoc2hvcnQpc2VsZWN0aW9uLngsIChzaG9ydClzZWxlY3Rpb24ueSB9OwotCQlPUy5TZXRDb250cm9sRGF0YShoYW5kbGUsIE9TLmtISUNvbWJvQm94RWRpdFRleHRQYXJ0LCBPUy5rQ29udHJvbEVkaXRUZXh0U2VsZWN0aW9uVGFnLCBzKTsKLQl9Ci19Ci0vKioKLSogU2V0cyB0aGUgd2lkZ2V0IHNpemUuCi0qLwotcHVibGljIHZvaWQgc2V0U2l6ZSAoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlpbnQgbmV3SGVpZ2h0ID0gKChzdHlsZSAmIFNXVC5EUk9QX0RPV04pICE9IDApID8gZ2V0VGV4dEhlaWdodCAoKSA6IGhlaWdodDsKLQlzdXBlci5zZXRTaXplICh3aWR0aCwgbmV3SGVpZ2h0KTsKLX0KLS8qKgotICogU2V0cyB0aGUgY29udGVudHMgb2YgdGhlIHJlY2VpdmVyJ3MgdGV4dCBmaWVsZCB0byB0aGUKLSAqIGdpdmVuIHN0cmluZy4KLSAqIDxwPgotICogTm90ZTogVGhlIHRleHQgZmllbGQgaW4gYSA8Y29kZT5Db21ibzwvY29kZT4gaXMgdHlwaWNhbGx5Ci0gKiBvbmx5IGNhcGFibGUgb2YgZGlzcGxheWluZyBhIHNpbmdsZSBsaW5lIG9mIHRleHQuIFRodXMsCi0gKiBzZXR0aW5nIHRoZSB0ZXh0IHRvIGEgc3RyaW5nIGNvbnRhaW5pbmcgbGluZSBicmVha3Mgb3IKLSAqIG90aGVyIHNwZWNpYWwgY2hhcmFjdGVycyB3aWxsIHByb2JhYmx5IGNhdXNlIGl0IHRvIAotICogZGlzcGxheSBpbmNvcnJlY3RseS4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gdGV4dCB0aGUgbmV3IHRleHQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBzdHJpbmcgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCi1wdWJsaWMgdm9pZCBzZXRUZXh0IChTdHJpbmcgc3RyaW5nKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlpZiAoc3RyaW5nID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0KLQlpbnQgaW5kZXg9IGluZGV4T2YgKHN0cmluZyk7Ci0JaWYgKGluZGV4ICE9IC0xKSB7Ci0JCXNlbGVjdChpbmRleCk7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKHNlbGVjdGlvbiA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWlmICgoc3R5bGUgJiBTV1QuUkVBRF9PTkxZKSAhPSAwKSB7CisJCS8vIE5FRURTIFdPUksKIAl9IGVsc2UgewotCQlpZiAoKHN0eWxlICYgU1dULlJFQURfT05MWSkgPT0gMCkgewotCQkJaW50IHNIYW5kbGU9IDA7Ci0JCQl0cnkgewotCQkJCXNIYW5kbGU9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMoc3RyaW5nKTsKLQkJCQlPUy5TZXRDb250cm9sRGF0YShoYW5kbGUsIE9TLmtISUNvbWJvQm94RWRpdFRleHRQYXJ0LCBPUy5rQ29udHJvbEVkaXRUZXh0Q0ZTdHJpbmdUYWcsIHNIYW5kbGUpOwotCQkJfSBmaW5hbGx5IHsKLQkJCQlpZiAoc0hhbmRsZSAhPSAwKQotCQkJCQlPUy5DRlJlbGVhc2Uoc0hhbmRsZSk7Ci0JCQl9Ci0JCQlzZW5kRXZlbnQoU1dULk1vZGlmeSk7Ci0JCX0KKwkJc2hvcnQgW10gcyA9IG5ldyBzaG9ydCBbXSB7KHNob3J0KXNlbGVjdGlvbi54LCAoc2hvcnQpc2VsZWN0aW9uLnkgfTsKKwkJT1MuU2V0Q29udHJvbERhdGEgKGhhbmRsZSwgT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRTZWxlY3Rpb25UYWcsIDQsIHMpOwogCX0KIH0KLS8qKgotICogU2V0cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0aGF0IHRoZSByZWNlaXZlcidzCi0gKiB0ZXh0IGZpZWxkIGlzIGNhcGFibGUgb2YgaG9sZGluZyB0byBiZSB0aGUgYXJndW1lbnQuCi0gKgotICogQHBhcmFtIGxpbWl0IG5ldyB0ZXh0IGxpbWl0Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0NBTk5PVF9CRV9aRVJPIC0gaWYgdGhlIGxpbWl0IGlzIHplcm88L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCitwdWJsaWMgdm9pZCBzZXRUZXh0IChTdHJpbmcgc3RyaW5nKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKHN0cmluZyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWlmICgoc3R5bGUgJiBTV1QuUkVBRF9PTkxZKSAhPSAwKSB7CisJCWludCBpbmRleCA9IGluZGV4T2YgKHN0cmluZyk7CisJCWlmIChpbmRleCAhPSAtMSkgc2VsZWN0KGluZGV4KTsKKwl9IGVsc2UgeworCQljaGFyIFtdIGJ1ZmZlciA9IG5ldyBjaGFyIFtzdHJpbmcubGVuZ3RoICgpXTsKKwkJc3RyaW5nLmdldENoYXJzICgwLCBidWZmZXIubGVuZ3RoLCBidWZmZXIsIDApOworCQlpbnQgcHRyID0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgYnVmZmVyLCBidWZmZXIubGVuZ3RoKTsKKwkJaWYgKHB0ciA9PSAwKSByZXR1cm47CQorCQlPUy5TZXRDb250cm9sRGF0YSAoaGFuZGxlLCBPUy5rSElDb21ib0JveEVkaXRUZXh0UGFydCwgT1Mua0NvbnRyb2xFZGl0VGV4dENGU3RyaW5nVGFnLCA0LCBuZXcgaW50W10ge3B0cn0pOworCQlPUy5DRlJlbGVhc2UgKHB0cik7CisJfQorfQorCiBwdWJsaWMgdm9pZCBzZXRUZXh0TGltaXQgKGludCBsaW1pdCkgewotCWNoZWNrV2lkZ2V0KCk7CisJY2hlY2tXaWRnZXQgKCk7CiAJaWYgKGxpbWl0ID09IDApIGVycm9yIChTV1QuRVJST1JfQ0FOTk9UX0JFX1pFUk8pOwotCXRleHRMaW1pdD0gbGltaXQ7CisJLy8gTkVFRFMgV09SSwogfQogCi0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotLy8gTWFjIHN0dWZmCi0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0JcHJpdmF0ZSB2b2lkIF9zZXRUZXh0IChTdHJpbmcgc3RyaW5nKSB7Ci0JCWlmICgoc3R5bGUgJiBTV1QuUkVBRF9PTkxZKSA9PSAwKSB7Ci0JCQlpbnQgc0hhbmRsZT0gMDsKLQkJCXRyeSB7Ci0JCQkJc0hhbmRsZT0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyhzdHJpbmcpOwotCQkJCU9TLlNldENvbnRyb2xEYXRhKGhhbmRsZSwgT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRDRlN0cmluZ1RhZywgc0hhbmRsZSk7Ci0JCQl9IGZpbmFsbHkgewotCQkJCWlmIChzSGFuZGxlICE9IDApCi0JCQkJCU9TLkNGUmVsZWFzZShzSGFuZGxlKTsKLQkJCX0KLQkJCXNlbmRFdmVudChTV1QuTW9kaWZ5KTsKLQkJfQotCX0KLQotCXByaXZhdGUgaW50IF9nZXRJdGVtQ291bnQgKCkgewotCQlpZiAobWVudUhhbmRsZSAhPSAwKQotCQkJcmV0dXJuIE9TLkNvdW50TWVudUl0ZW1zKG1lbnVIYW5kbGUpOwotCQlyZXR1cm4gT1MuSElDb21ib0JveEdldEl0ZW1Db3VudChoYW5kbGUpOwotCX0KLQkKLQlwcml2YXRlIFN0cmluZyBfZ2V0SXRlbSAoaW50IGluZGV4KSB7Ci0JCWludCBpdGVtQ291bnQ9IF9nZXRJdGVtQ291bnQoKTsKLQkJaWYgKCEoMCA8PSBpbmRleCAmJiBpbmRleCA8IGl0ZW1Db3VudCkpIHsKLQkJCWVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7Ci0JCX0KLQkJaW50W10gc0hhbmRsZT0gbmV3IGludFsxXTsKLQkJaW50IHJjOwotCQlpZiAobWVudUhhbmRsZSAhPSAwKQotCQkJcmM9IE9TLkNvcHlNZW51SXRlbVRleHRBc0NGU3RyaW5nKG1lbnVIYW5kbGUsIChzaG9ydCkoaW5kZXgrMSksIHNIYW5kbGUpOwotCQllbHNlCi0JCQlyYz0gT1MuSElDb21ib0JveENvcHlUZXh0SXRlbUF0SW5kZXgoaGFuZGxlLCBpbmRleCwgc0hhbmRsZSk7Ci0JCWlmIChyYyAhPSBPUy5rTm9FcnIpCi0JCQllcnJvcihTV1QuRVJST1JfQ0FOTk9UX0dFVF9JVEVNKTsKLQkJcmV0dXJuIE1hY1V0aWwuZ2V0U3RyaW5nQW5kUmVsZWFzZShzSGFuZGxlWzBdKTsKLQl9Ci0KLQkvKioKLQkgKiBPdmVycmlkZGVuIGZyb20gQ29udHJvbC4KLQkgKiB4IGFuZCB5IGFyZSByZWxhdGl2ZSB0byB3aW5kb3chCi0JICovCi0Jdm9pZCBoYW5kbGVSZXNpemUoaW50IGhuZGwsIE1hY1JlY3QgYm91bmRzKSB7Ci0JCWJvdW5kcy5pbnNldChGT0NVU19CT1JERVIsIEZPQ1VTX0JPUkRFUiwgRk9DVVNfQk9SREVSLCBGT0NVU19CT1JERVIpOwotCQlzdXBlci5oYW5kbGVSZXNpemUoaG5kbCwgYm91bmRzKTsKLQl9Ci0JCi0Jdm9pZCBpbnRlcm5hbEdldENvbnRyb2xCb3VuZHMoaW50IGhuZGwsIE1hY1JlY3QgYm91bmRzKSB7Ci0JCXN1cGVyLmludGVybmFsR2V0Q29udHJvbEJvdW5kcyhobmRsLCBib3VuZHMpOwotCQlib3VuZHMuaW5zZXQoLUZPQ1VTX0JPUkRFUiwgLUZPQ1VTX0JPUkRFUiwgLUZPQ1VTX0JPUkRFUiwgLUZPQ1VTX0JPUkRFUik7Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIF9zZWxlY3RBbGwoKSB7Ci0JCVN0cmluZyBzPSBnZXRUZXh0KCk7Ci0JCXNob3J0W10gc2VsZWN0aW9uPSBuZXcgc2hvcnRbXSB7IDAsIChzaG9ydCkgcy5sZW5ndGgoKSB9OwotCQlPUy5TZXRDb250cm9sRGF0YShoYW5kbGUsIE9TLmtISUNvbWJvQm94RWRpdFRleHRQYXJ0LCBPUy5rQ29udHJvbEVkaXRUZXh0U2VsZWN0aW9uVGFnLCBzZWxlY3Rpb24pOwotCX0KLQkKLQlpbnQgc2VuZEtleUV2ZW50IChpbnQgdHlwZSwgTWFjRXZlbnQgbUV2ZW50LCBFdmVudCBldmVudCkgewotCQkKLQkJLyogQVc6IG90aGVyIHBsYXRmb3JtcyBjYWxsIHN1cGVyCi0JCUxSRVNVTFQgcmVzdWx0ID0gc3VwZXIuV01fQ0hBUiAod1BhcmFtLCBsUGFyYW0pOwotCQlpZiAocmVzdWx0ICE9IG51bGwpIHJldHVybiByZXN1bHQ7Ci0JCSovCi0JCQotLy8JCWlmICh0cmFuc2xhdGVUcmF2ZXJzYWwobUV2ZW50KSkKLS8vCQkJcmV0dXJuIDA7Ci0JCQkKLQkJaW50IGtpbmQ9IG1FdmVudC5nZXRLaW5kKCk7Ci0JCWludCBtY2M9IG1FdmVudC5nZXRNYWNDaGFyQ29kZXMoKTsKLQkJaW50IGNvZGU9IG1FdmVudC5nZXRLZXlDb2RlKCk7Ci0KLQkJLy8gcmV0dXJuIGtleSAtPiBEZWZhdWx0U2VsZWN0aW9uCi0JCWlmIChtY2MgPT0gU1dULkNSKSB7Ci0JCQlpZiAoa2luZCA9PSBPUy5rRXZlbnRSYXdLZXlEb3duKQotCQkJCXBvc3RFdmVudCAoU1dULkRlZmF1bHRTZWxlY3Rpb24pOwotCQkJcmV0dXJuIE9TLmtOb0VycjsKLQkJfQotCQkJCQotCQlpZiAoKG1FdmVudC5nZXRNb2RpZmllcnMoKSAmIE9TLmNtZEtleSkgIT0gMCkgewotCQkJc3dpdGNoIChjb2RlKSB7Ci0JCQljYXNlIDA6CS8vIHNlbGVjdCBhbGwKLQkJCQlpZiAoa2luZCA9PSBPUy5rRXZlbnRSYXdLZXlEb3duKQotCQkJCQlfc2VsZWN0QWxsKCk7Ci0JCQkJcmV0dXJuIE9TLmtOb0VycjsKLQkJCWNhc2UgNzoKLQkJCQlpZiAoa2luZCA9PSBPUy5rRXZlbnRSYXdLZXlEb3duKQotCQkJCQljdXQoKTsKLQkJCQlyZXR1cm4gT1Mua05vRXJyOwotCQkJY2FzZSA4OgotCQkJCWlmIChraW5kID09IE9TLmtFdmVudFJhd0tleURvd24pCi0JCQkJCWNvcHkoKTsKLQkJCQlyZXR1cm4gT1Mua05vRXJyOwotCQkJY2FzZSA5OgotCQkJCWlmIChraW5kID09IE9TLmtFdmVudFJhd0tleURvd24gfHwga2luZCA9PSBPUy5rRXZlbnRSYXdLZXlSZXBlYXQpCi0JCQkJCXBhc3RlKCk7Ci0JCQkJcmV0dXJuIE9TLmtOb0VycjsKLQkJCWRlZmF1bHQ6Ci0JCQkJYnJlYWs7Ci0JCQl9Ci0JCX0KLQotCQlTdHJpbmcgb2xkVGV4dD0gZ2V0VGV4dCgpOwotCi0JCWludCBzdGF0dXM9IE9TLkNhbGxOZXh0RXZlbnRIYW5kbGVyKG1FdmVudC5nZXROZXh0SGFuZGxlcigpLCBtRXZlbnQuZ2V0RXZlbnRSZWYoKSk7Ci0JCQotCQlpZiAoa2luZCA9PSBPUy5rRXZlbnRSYXdLZXlEb3duKSB7Ci0JCQlTdHJpbmcgbmV3VGV4dD0gZ2V0VGV4dCgpOwotCQkJaWYgKCFvbGRUZXh0LmVxdWFscyhuZXdUZXh0KSkKLQkJCQlzZW5kRXZlbnQgKFNXVC5Nb2RpZnkpOwotCQl9Ci0JCQotCQlyZXR1cm4gc3RhdHVzOwotCX0KLQkKLQlwcml2YXRlIHZvaWQgc2VsZWN0aW9uVG9DbGlwYm9hcmQoKSB7Ci0JCXNob3J0W10gcz0gbmV3IHNob3J0WzJdOwotCQlPUy5HZXRDb250cm9sRGF0YShoYW5kbGUsIE9TLmtISUNvbWJvQm94RWRpdFRleHRQYXJ0LCBPUy5rQ29udHJvbEVkaXRUZXh0U2VsZWN0aW9uVGFnLCBzKTsKLQkJaWYgKHNbMF0gIT0gc1sxXSkgewotCQkJaW50W10gdD0gbmV3IGludFsxXTsKLQkJCU9TLkdldENvbnRyb2xEYXRhKGhhbmRsZSwgT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRDRlN0cmluZ1RhZywgdCk7Ci0JCQlTdHJpbmcgdHh0PSBNYWNVdGlsLmdldFN0cmluZ0FuZFJlbGVhc2UodFswXSk7Ci0JCQl0eHQ9IHR4dC5zdWJzdHJpbmcoc1swXSwgc1sxXSk7Ci0JCi0JCQlDbGlwYm9hcmQgY2xpcGJvYXJkPSBuZXcgQ2xpcGJvYXJkKGdldERpc3BsYXkoKSk7Ci0JCQljbGlwYm9hcmQuc2V0Q29udGVudHMobmV3IE9iamVjdFtdIHsgdHh0IH0sIG5ldyBUcmFuc2ZlcltdeyBUZXh0VHJhbnNmZXIuZ2V0SW5zdGFuY2UoKSB9KTsKLQkJCWNsaXBib2FyZC5kaXNwb3NlKCk7Ci0JCX0KLQl9Ci0JCi0JLyoqCi0JICogUmVwbGFjZSBjdXJyZW50IHRleHQgc2VsZWN0aW9uIHdpdGggZ2l2ZW4gc3RyaW5nLgotCSAqIElmIHNlbGVjdGlvbiBpcyBlbXB0eSwgaW5zZXJ0cyBzdHJpbmcuCi0JICogSWYgc3RyaW5nIGlzIGVtcHR5LCBzZWxlY3Rpb24gaXMgZGVsZXRlZC4KLQkgKi8KLQlwcml2YXRlIHZvaWQgX3JlcGxhY2VUZXh0U2VsZWN0aW9uKFN0cmluZyBuZXdUZXh0KSB7Ci0JCQotCQlzaG9ydFtdIHM9IG5ldyBzaG9ydFsyXTsKLQkJT1MuR2V0Q29udHJvbERhdGEoaGFuZGxlLCBPUy5rSElDb21ib0JveEVkaXRUZXh0UGFydCwgT1Mua0NvbnRyb2xFZGl0VGV4dFNlbGVjdGlvblRhZywgcyk7Ci0JCQotCQlib29sZWFuIHNlbEVtcHR5PSBzWzBdID09IHNbMV07Ci0JCWlmIChuZXdUZXh0Lmxlbmd0aCgpID09IDAgJiYgc2VsRW1wdHkpCi0JCQlyZXR1cm47Ci0JCQotCQlpbnRbXSB0PSBuZXcgaW50WzFdOwotCQlPUy5HZXRDb250cm9sRGF0YShoYW5kbGUsIE9TLmtISUNvbWJvQm94RWRpdFRleHRQYXJ0LCBPUy5rQ29udHJvbEVkaXRUZXh0Q0ZTdHJpbmdUYWcsIHQpOwotCQlTdHJpbmcgdHh0PSBNYWNVdGlsLmdldFN0cmluZ0FuZFJlbGVhc2UodFswXSk7Ci0JCQotCQlTdHJpbmcgcHJlPSAiIjsKLQkJaWYgKHNlbEVtcHR5KQotCQkJcHJlPSB0eHQuc3Vic3RyaW5nKDAsIHNbMF0pOwotCQllbHNlIGlmIChzWzBdID4gMCkKLQkJCXByZT0gdHh0LnN1YnN0cmluZygwLCBzWzBdLTEpOwotCQkJCi0JCVN0cmluZyBwb3N0PSB0eHQuc3Vic3RyaW5nKHNbMV0pOwotCQkKLQkJaW50IHNIYW5kbGU9IDA7Ci0JCXRyeSB7Ci0JCQlzSGFuZGxlPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzKHByZSArIG5ld1RleHQgKyBwb3N0KTsKLQkJCU9TLlNldENvbnRyb2xEYXRhKGhhbmRsZSwgT1Mua0hJQ29tYm9Cb3hFZGl0VGV4dFBhcnQsIE9TLmtDb250cm9sRWRpdFRleHRDRlN0cmluZ1RhZywgc0hhbmRsZSk7Ci0JCX0gZmluYWxseSB7Ci0JCQlpZiAoc0hhbmRsZSAhPSAwKQotCQkJCU9TLkNGUmVsZWFzZShzSGFuZGxlKTsKLQkJfQotCQkKLQkJc1swXT0gc1sxXT0gKHNob3J0KShwcmUubGVuZ3RoKCkgKyBuZXdUZXh0Lmxlbmd0aCgpKTsKLQkJT1MuU2V0Q29udHJvbERhdGEoaGFuZGxlLCBPUy5rSElDb21ib0JveEVkaXRUZXh0UGFydCwgT1Mua0NvbnRyb2xFZGl0VGV4dFNlbGVjdGlvblRhZywgcyk7Ci0JCi0JCXNlbmRFdmVudChTV1QuTW9kaWZ5KTsKLQl9CiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvQ29tcG9zaXRlLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvQ29tcG9zaXRlLmphdmEKaW5kZXggNDI3Yzc5ZC4uYzVlMmYxYyAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0NvbXBvc2l0ZS5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Db21wb3NpdGUuamF2YQpAQCAtNywzMyArNywxMyBAQAogICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKICAqLwogCi1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uT1M7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5SR0JDb2xvcjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlJlY3Q7CisKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuKjsKIAotLyoqCi0gKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBhcmUgY29udHJvbHMgd2hpY2ggYXJlIGNhcGFibGUKLSAqIG9mIGNvbnRhaW5pbmcgb3RoZXIgY29udHJvbHMuCi0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPk5PX0JBQ0tHUk9VTkQsIE5PX0ZPQ1VTLCBOT19NRVJHRV9QQUlOVFMsIE5PX1JFRFJBV19SRVNJWkUsIE5PX1JBRElPX0dST1VQPC9kZD4KLSAqIDxkdD48Yj5FdmVudHM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+KG5vbmUpPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cD4KLSAqIE5vdGU6IFRoZSA8Y29kZT5OT19CQUNLR1JPVU5EPC9jb2RlPiwgPGNvZGU+Tk9fRk9DVVM8L2NvZGU+LCA8Y29kZT5OT19NRVJHRV9QQUlOVFM8L2NvZGU+LAotICogYW5kIDxjb2RlPk5PX1JFRFJBV19SRVNJWkU8L2NvZGU+IHN0eWxlcyBhcmUgaW50ZW5kZWQgZm9yIHVzZSB3aXRoIDxjb2RlPkNhbnZhczwvY29kZT4uCi0gKiBUaGV5IGNhbiBiZSB1c2VkIHdpdGggPGNvZGU+Q29tcG9zaXRlPC9jb2RlPiBpZiB5b3UgYXJlIGRyYXdpbmcgeW91ciBvd24sIGJ1dCB0aGVpcgotICogYmVoYXZpb3IgaXMgdW5kZWZpbmVkIGlmIHRoZXkgYXJlIHVzZWQgd2l0aCBzdWJjbGFzc2VzIG9mIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gb3RoZXIKLSAqIHRoYW4gPGNvZGU+Q2FudmFzPC9jb2RlPi4KLSAqIDwvcD48cD4KLSAqIFRoaXMgY2xhc3MgbWF5IGJlIHN1YmNsYXNzZWQgYnkgY3VzdG9tIGNvbnRyb2wgaW1wbGVtZW50b3JzCi0gKiB3aG8gYXJlIGJ1aWxkaW5nIGNvbnRyb2xzIHRoYXQgYXJlIGNvbnN0cnVjdGVkIGZyb20gYWdncmVnYXRlcwotICogb2Ygb3RoZXIgY29udHJvbHMuCi0gKiA8L3A+Ci0gKgotICogQHNlZSBDYW52YXMKLSAqLwogcHVibGljIGNsYXNzIENvbXBvc2l0ZSBleHRlbmRzIFNjcm9sbGFibGUgewogCUxheW91dCBsYXlvdXQ7CiAJQ29udHJvbFtdIHRhYkxpc3Q7CkBAIC00MSw1MyArMjEsMjIgQEAKIENvbXBvc2l0ZSAoKSB7CiAJLyogRG8gbm90aGluZyAqLwogfQotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gaXRzIHBhcmVudAotICogYW5kIGEgc3R5bGUgdmFsdWUgZGVzY3JpYmluZyBpdHMgYmVoYXZpb3IgYW5kIGFwcGVhcmFuY2UuCi0gKiA8cD4KLSAqIFRoZSBzdHlsZSB2YWx1ZSBpcyBlaXRoZXIgb25lIG9mIHRoZSBzdHlsZSBjb25zdGFudHMgZGVmaW5lZCBpbgotICogY2xhc3MgPGNvZGU+U1dUPC9jb2RlPiB3aGljaCBpcyBhcHBsaWNhYmxlIHRvIGluc3RhbmNlcyBvZiB0aGlzCi0gKiBjbGFzcywgb3IgbXVzdCBiZSBidWlsdCBieSA8ZW0+Yml0d2lzZSBPUjwvZW0+J2luZyB0b2dldGhlciAKLSAqICh0aGF0IGlzLCB1c2luZyB0aGUgPGNvZGU+aW50PC9jb2RlPiAifCIgb3BlcmF0b3IpIHR3byBvciBtb3JlCi0gKiBvZiB0aG9zZSA8Y29kZT5TV1Q8L2NvZGU+IHN0eWxlIGNvbnN0YW50cy4gVGhlIGNsYXNzIGRlc2NyaXB0aW9uCi0gKiBsaXN0cyB0aGUgc3R5bGUgY29uc3RhbnRzIHRoYXQgYXJlIGFwcGxpY2FibGUgdG8gdGhlIGNsYXNzLgotICogU3R5bGUgYml0cyBhcmUgYWxzbyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIHdpZGdldCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZSAoY2Fubm90IGJlIG51bGwpCi0gKiBAcGFyYW0gc3R5bGUgdGhlIHN0eWxlIG9mIHdpZGdldCB0byBjb25zdHJ1Y3QKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTV1QjTk9fQkFDS0dST1VORAotICogQHNlZSBTV1QjTk9fRk9DVVMKLSAqIEBzZWUgU1dUI05PX01FUkdFX1BBSU5UUwotICogQHNlZSBTV1QjTk9fUkVEUkFXX1JFU0laRQotICogQHNlZSBTV1QjTk9fUkFESU9fR1JPVVAKLSAqIEBzZWUgV2lkZ2V0I2dldFN0eWxlCi0gKi8KKwogcHVibGljIENvbXBvc2l0ZSAoQ29tcG9zaXRlIHBhcmVudCwgaW50IHN0eWxlKSB7CiAJc3VwZXIgKHBhcmVudCwgc3R5bGUpOwogfQorCiBDb250cm9sIFtdIF9nZXRDaGlsZHJlbiAoKSB7Ci0Jc2hvcnRbXSBjbnQ9IG5ldyBzaG9ydFsxXTsKLQlPUy5Db3VudFN1YkNvbnRyb2xzKGhhbmRsZSwgY250KTsKLQlpbnQgY291bnQ9IGNudFswXTsKLQlpZiAoY291bnQgPT0gMCkgcmV0dXJuIG5ldyBDb250cm9sIFswXTsKLQlpbnRbXSBvdXRDb250cm9sPSBuZXcgaW50WzFdOwotCUNvbnRyb2wgW10gY2hpbGRyZW4gPSBuZXcgQ29udHJvbCBbY291bnRdOworCXNob3J0IFtdIGNvdW50ID0gbmV3IHNob3J0IFsxXTsKKwlPUy5Db3VudFN1YkNvbnRyb2xzIChoYW5kbGUsIGNvdW50KTsKKwlpZiAoY291bnQgWzBdID09IDApIHJldHVybiBuZXcgQ29udHJvbCBbMF07CisJQ29udHJvbCBbXSBjaGlsZHJlbiA9IG5ldyBDb250cm9sIFtjb3VudCBbMF1dOworCWludCBbXSBvdXRDb250cm9sPSBuZXcgaW50IFsxXTsKIAlpbnQgaSA9IDAsIGogPSAwOwotCXdoaWxlIChpIDwgY291bnQpIHsKLQkJaWYgKE1hY1V0aWwuZ2V0Q2hpbGQoaGFuZGxlLCBvdXRDb250cm9sLCBjb3VudCwgaSkgIT0gT1Mua05vRXJyKQotCQkJZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfR0VUX0lURU0pOwotCQlpbnQgaGFuZGxlID0gb3V0Q29udHJvbCBbMF07Ci0JCWlmIChoYW5kbGUgIT0gMCkgewotCQkJV2lkZ2V0IHdpZGdldCA9IFdpZGdldFRhYmxlLmdldCAoaGFuZGxlKTsKKwl3aGlsZSAoaSA8IGNvdW50IFswXSkgeworCQlpbnQgc3RhdHVzID0gT1MuR2V0SW5kZXhlZFN1YkNvbnRyb2wgKGhhbmRsZSwgKHNob3J0KShpKzEpLCBvdXRDb250cm9sKTsKKwkJaWYgKHN0YXR1cyA9PSBPUy5ub0VycikgeworCQkJV2lkZ2V0IHdpZGdldCA9IFdpZGdldFRhYmxlLmdldCAob3V0Q29udHJvbCBbMF0pOwogCQkJaWYgKHdpZGdldCAhPSBudWxsICYmIHdpZGdldCAhPSB0aGlzKSB7CiAJCQkJaWYgKHdpZGdldCBpbnN0YW5jZW9mIENvbnRyb2wpIHsKIAkJCQkJY2hpbGRyZW4gW2orK10gPSAoQ29udHJvbCkgd2lkZ2V0OwpAQCAtOTYsMjQgKzQ1LDE5IEBACiAJCX0KIAkJaSsrOwogCX0KLQlpZiAoaSA9PSBqKSByZXR1cm4gY2hpbGRyZW47CisJaWYgKGogPT0gY291bnQgWzBdKSByZXR1cm4gY2hpbGRyZW47CiAJQ29udHJvbCBbXSBuZXdDaGlsZHJlbiA9IG5ldyBDb250cm9sIFtqXTsKIAlTeXN0ZW0uYXJyYXljb3B5IChjaGlsZHJlbiwgMCwgbmV3Q2hpbGRyZW4sIDAsIGopOwogCXJldHVybiBuZXdDaGlsZHJlbjsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIHRhYkxpc3Qgb3IgbnVsbAotICovCiBDb250cm9sIFtdIF9nZXRUYWJMaXN0ICgpIHsKIAlpZiAodGFiTGlzdCA9PSBudWxsKSByZXR1cm4gbnVsbDsKLQkvLyBlbnN1cmUgdG8gcmV0dXJuIG9ubHkgbm9uLWRpc3Bvc2VkIGNvbnRyb2xzCiAJaW50IGNvdW50ID0gMDsKIAlmb3IgKGludCBpPTA7IGk8dGFiTGlzdC5sZW5ndGg7IGkrKykgewogCQlpZiAoIXRhYkxpc3QgW2ldLmlzRGlzcG9zZWQgKCkpIGNvdW50Kys7CiAJfQogCWlmIChjb3VudCA9PSB0YWJMaXN0Lmxlbmd0aCkgcmV0dXJuIHRhYkxpc3Q7Ci0JLy8gY29weSBvbmx5IG5vbi1kaXNwb3NlZCBjb250cm9scwogCUNvbnRyb2wgW10gbmV3TGlzdCA9IG5ldyBDb250cm9sIFtjb3VudF07CiAJaW50IGluZGV4ID0gMDsKIAlmb3IgKGludCBpPTA7IGk8dGFiTGlzdC5sZW5ndGg7IGkrKykgewpAQCAtMTQ0LDYgKzg4LDcgQEAKIAlSZWN0YW5nbGUgdHJpbSA9IGNvbXB1dGVUcmltICgwLCAwLCBzaXplLngsIHNpemUueSk7CiAJcmV0dXJuIG5ldyBQb2ludCAodHJpbS53aWR0aCwgdHJpbS5oZWlnaHQpOwogfQorCiBwcm90ZWN0ZWQgdm9pZCBjaGVja1N1YmNsYXNzICgpIHsKIAkvKiBEbyBub3RoaW5nIC0gU3ViY2xhc3NpbmcgaXMgYWxsb3dlZCAqLwogfQpAQCAtMTY1LDE2OCArMTEwLDg4IEBACiAJcmV0dXJuIHJlc3VsdDsKIH0KIAotdm9pZCBjcmVhdGVIYW5kbGUgKGludCBpbmRleCkgewotCXN0YXRlIHw9IEhBTkRMRSB8IENBTlZBUzsKLQlpZiAoKHN0eWxlICYgKFNXVC5IX1NDUk9MTCB8IFNXVC5WX1NDUk9MTCkpID09IDApIHsgLy8gbm8gc2Nyb2xsYmFycwotCQlpbnQgYm9yZGVyID0gKHN0eWxlICYgU1dULkJPUkRFUikgIT0gMCA/IDEgOiAwOwotICAgICAgICAvKiBBVwotCQlpbnQgW10gYXJnTGlzdCA9IHsKLQkJCU9TLlhtTmFuY2VzdG9yU2Vuc2l0aXZlLCAxLAotCQkJT1MuWG1OYm9yZGVyV2lkdGgsIGJvcmRlciwKLQkJCU9TLlhtTm1hcmdpbldpZHRoLCAwLAotCQkJT1MuWG1ObWFyZ2luSGVpZ2h0LCAwLAotCQkJT1MuWG1OcmVzaXplUG9saWN5LCBPUy5YbVJFU0laRV9OT05FLAotCQkJT1MuWG1OdHJhdmVyc2FsT24sIChzdHlsZSAmIFNXVC5OT19GT0NVUykgIT0gMCA/IDAgOiAxLAotCQl9OwotICAgICAgICAqLwotCQlpbnQgcGFyZW50SGFuZGxlID0gcGFyZW50LmhhbmRsZTsKLSAgICAgICAgaGFuZGxlPSBNYWNVdGlsLmNyZWF0ZURyYXdpbmdBcmVhIChwYXJlbnRIYW5kbGUsIC0xLCB0cnVlLCAwLCAwLCBib3JkZXIpOwotCi0JCWlmIChoYW5kbGUgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKLSAgICAgICAgLyogQVcKLQkJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKLQkJT1MuWHRPdmVycmlkZVRyYW5zbGF0aW9ucyAoaGFuZGxlLCBkaXNwbGF5LnRhYlRyYW5zbGF0aW9ucyk7Ci0JCU9TLlh0T3ZlcnJpZGVUcmFuc2xhdGlvbnMgKGhhbmRsZSwgZGlzcGxheS5hcnJvd1RyYW5zbGF0aW9ucyk7Ci0gICAgICAgICovCi0JfSBlbHNlIHsKK3ZvaWQgY3JlYXRlSGFuZGxlICgpIHsKKwlzdGF0ZSB8PSBDQU5WQVMgfCBHUkFCOworCWlmICgoc3R5bGUgJiAoU1dULkJPUkRFUiB8IFNXVC5IX1NDUk9MTCB8IFNXVC5WX1NDUk9MTCkpICE9IDApIHsKIAkJY3JlYXRlU2Nyb2xsZWRIYW5kbGUgKHBhcmVudC5oYW5kbGUpOwotCX0KLX0KLXZvaWQgY3JlYXRlU2Nyb2xsZWRIYW5kbGUgKGludCB0b3BIYW5kbGUpIHsKLQotICAgIC8qIEFXCi0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1OYW5jZXN0b3JTZW5zaXRpdmUsIDF9OwotCXNjcm9sbGVkSGFuZGxlID0gT1MuWG1DcmVhdGVNYWluV2luZG93ICh0b3BIYW5kbGUsIG51bGwsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0gICAgKi8KLSAgICBzY3JvbGxlZEhhbmRsZT0gY3JlYXRlU2Nyb2xsVmlldyh0b3BIYW5kbGUsIHN0eWxlKTsKLQlpZiAoc2Nyb2xsZWRIYW5kbGUgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKLQotCWlmICgoc3R5bGUgJiAoU1dULkhfU0NST0xMIHwgU1dULlZfU0NST0xMKSkgIT0gMCkgewotICAgICAgICAvKiBBVwotCQlpbnQgdGhpY2tuZXNzID0gZGlzcGxheS5idXR0b25TaGFkb3dUaGlja25lc3M7Ci0JCWludCBbXSBhcmdMaXN0MSA9IHsKLQkJCU9TLlhtTm1hcmdpbldpZHRoLCAzLAotCQkJT1MuWG1ObWFyZ2luSGVpZ2h0LCAzLAotCQkJT1MuWG1OcmVzaXplUG9saWN5LCBPUy5YbVJFU0laRV9OT05FLAotCQkJT1MuWG1Oc2hhZG93VHlwZSwgT1MuWG1TSEFET1dfSU4sCi0JCQlPUy5YbU5zaGFkb3dUaGlja25lc3MsIHRoaWNrbmVzcywKLQkJfTsKLQkJZm9ybUhhbmRsZSA9IE9TLlhtQ3JlYXRlRm9ybSAoc2Nyb2xsZWRIYW5kbGUsIG51bGwsIGFyZ0xpc3QxLCBhcmdMaXN0MS5sZW5ndGggLyAyKTsKLQkJaWYgKGZvcm1IYW5kbGUgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKLQkJaW50IFtdIGFyZ0xpc3QyID0gewotCQkJT1MuWG1ObWFyZ2luV2lkdGgsIDAsCi0JCQlPUy5YbU5tYXJnaW5IZWlnaHQsIDAsCi0JCQlPUy5YbU5yZXNpemVQb2xpY3ksIE9TLlhtUkVTSVpFX05PTkUsCi0JCQlPUy5YbU50b3BBdHRhY2htZW50LCBPUy5YbUFUVEFDSF9GT1JNLAotCQkJT1MuWG1OYm90dG9tQXR0YWNobWVudCwgT1MuWG1BVFRBQ0hfRk9STSwKLQkJCU9TLlhtTmxlZnRBdHRhY2htZW50LCBPUy5YbUFUVEFDSF9GT1JNLAotCQkJT1MuWG1OcmlnaHRBdHRhY2htZW50LCBPUy5YbUFUVEFDSF9GT1JNLAotCQkJT1MuWG1OcmVzaXphYmxlLCAwLAotCQkJT1MuWG1OdHJhdmVyc2FsT24sIChzdHlsZSAmIFNXVC5OT19GT0NVUykgIT0gMCA/IDAgOiAxLAotCQl9OwotCQloYW5kbGUgPSBPUy5YbUNyZWF0ZURyYXdpbmdBcmVhIChmb3JtSGFuZGxlLCBudWxsLCBhcmdMaXN0MiwgYXJnTGlzdDIubGVuZ3RoIC8gMik7Ci0gICAgICAgICovCi0gICAgICAgIGhhbmRsZT0gTWFjVXRpbC5jcmVhdGVEcmF3aW5nQXJlYSAoc2Nyb2xsZWRIYW5kbGUsIC0xLCB0cnVlLCAwLCAwLCAwKTsKIAl9IGVsc2UgewotICAgICAgICAvKiBBVwotCQlpbnQgW10gYXJnTGlzdDMgPSB7Ci0JCQlPUy5YbU5tYXJnaW5XaWR0aCwgMCwKLQkJCU9TLlhtTm1hcmdpbkhlaWdodCwgMCwKLQkJCU9TLlhtTnJlc2l6ZVBvbGljeSwgT1MuWG1SRVNJWkVfTk9ORSwKLQkJCU9TLlhtTnRyYXZlcnNhbE9uLCAoc3R5bGUgJiBTV1QuTk9fRk9DVVMpICE9IDAgPyAwIDogMSwKLQkJfTsKLQkJaGFuZGxlID0gT1MuWG1DcmVhdGVEcmF3aW5nQXJlYSAoc2Nyb2xsZWRIYW5kbGUsIG51bGwsIGFyZ0xpc3QzLCBhcmdMaXN0My5sZW5ndGggLyAyKTsKLSAgICAgICAgKi8KLSAgICAgICAgaGFuZGxlID0gTWFjVXRpbC5jcmVhdGVEcmF3aW5nQXJlYSAoc2Nyb2xsZWRIYW5kbGUsIC0xLCB0cnVlLCAwLCAwLCAwKTsKKwkJY3JlYXRlSGFuZGxlIChwYXJlbnQuaGFuZGxlKTsKIAl9Ci0JaWYgKGhhbmRsZSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOwotICAgIC8qIEFXCi0JT1MuWHRPdmVycmlkZVRyYW5zbGF0aW9ucyAoaGFuZGxlLCBkaXNwbGF5LnRhYlRyYW5zbGF0aW9ucyk7Ci0JT1MuWHRPdmVycmlkZVRyYW5zbGF0aW9ucyAoaGFuZGxlLCBkaXNwbGF5LmFycm93VHJhbnNsYXRpb25zKTsKLSAgICAqLwogfQotaW50IGRlZmF1bHRCYWNrZ3JvdW5kICgpIHsKLQlyZXR1cm4gZ2V0RGlzcGxheSAoKS5jb21wb3NpdGVCYWNrZ3JvdW5kOworCit2b2lkIGNyZWF0ZUhhbmRsZSAoaW50IHBhcmVudEhhbmRsZSkgeworCWludCBmZWF0dXJlcyA9IE9TLmtDb250cm9sU3VwcG9ydHNFbWJlZGRpbmcgfCBPUy5rQ29udHJvbFN1cHBvcnRzRm9jdXMgfCBPUy5rQ29udHJvbEdldHNGb2N1c09uQ2xpY2s7CisJaW50IFtdIG91dENvbnRyb2wgPSBuZXcgaW50IFsxXTsKKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChwYXJlbnRIYW5kbGUpOworCU9TLkNyZWF0ZVVzZXJQYW5lQ29udHJvbCAod2luZG93LCBudWxsLCBmZWF0dXJlcywgb3V0Q29udHJvbCk7CisJaWYgKG91dENvbnRyb2wgWzBdID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7CisJaGFuZGxlID0gb3V0Q29udHJvbCBbMF07CiB9Ci1pbnQgZGVmYXVsdEZvcmVncm91bmQgKCkgewotCXJldHVybiBnZXREaXNwbGF5ICgpLmNvbXBvc2l0ZUZvcmVncm91bmQ7CisKK3ZvaWQgY3JlYXRlU2Nyb2xsZWRIYW5kbGUgKGludCBwYXJlbnRIYW5kbGUpIHsKKwlpbnQgZmVhdHVyZXMgPSBPUy5rQ29udHJvbFN1cHBvcnRzRW1iZWRkaW5nOworCWludCBbXSBvdXRDb250cm9sID0gbmV3IGludCBbMV07CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAocGFyZW50SGFuZGxlKTsKKwlPUy5DcmVhdGVVc2VyUGFuZUNvbnRyb2wgKHdpbmRvdywgbnVsbCwgZmVhdHVyZXMsIG91dENvbnRyb2wpOworCWlmIChvdXRDb250cm9sIFswXSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCXNjcm9sbGVkSGFuZGxlID0gb3V0Q29udHJvbCBbMF07CisJb3V0Q29udHJvbCBbMF0gPSAwOworCWZlYXR1cmVzIHw9IE9TLmtDb250cm9sU3VwcG9ydHNGb2N1cyB8IE9TLmtDb250cm9sR2V0c0ZvY3VzT25DbGljazsKKwlPUy5DcmVhdGVVc2VyUGFuZUNvbnRyb2wgKHdpbmRvdywgbnVsbCwgZmVhdHVyZXMsIG91dENvbnRyb2wpOworCWlmIChvdXRDb250cm9sIFswXSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCWhhbmRsZSA9IG91dENvbnRyb2wgWzBdOwogfQotLyogQVcKLXB1YmxpYyBib29sZWFuIGZvcmNlRm9jdXMgKCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0JQ29udHJvbCBbXSBjaGlsZHJlbiA9IF9nZXRDaGlsZHJlbiAoKTsKLQlpbnQgW10gdHJhdmVyc2FscyA9IG5ldyBpbnQgW2NoaWxkcmVuLmxlbmd0aF07Ci0JaW50IFtdIGFyZ0xpc3QgPSBuZXcgaW50IFtdIHtPUy5YbU50cmF2ZXJzYWxPbiwgMH07Ci0JZm9yIChpbnQgaT0wOyBpPGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7Ci0JCU9TLlh0R2V0VmFsdWVzIChjaGlsZHJlbiBbaV0uaGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCQl0cmF2ZXJzYWxzIFtpXSA9IGFyZ0xpc3QgWzFdOwotCQlhcmdMaXN0IFsxXSA9IDA7Ci0JCU9TLlh0U2V0VmFsdWVzIChjaGlsZHJlbiBbaV0uaGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOworCit2b2lkIGRyYXdXaWRnZXQgKGludCBjb250cm9sKSB7CisJaWYgKChzdGF0ZSAmIENBTlZBUykgIT0gMCkgeworCQlpZiAoY29udHJvbCA9PSBzY3JvbGxlZEhhbmRsZSkgeworCQkJZHJhd0JhY2tncm91bmQgKGNvbnRyb2wsIGJhY2tncm91bmQpOworCQkJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisJCQlPUy5HZXRDb250cm9sQm91bmRzIChzY3JvbGxlZEhhbmRsZSwgcmVjdCk7CisJCQlSZWN0IGluc2V0ID0gaW5zZXQgKCk7CisJCQlyZWN0LmxlZnQgKz0gaW5zZXQubGVmdDsKKwkJCXJlY3QudG9wICs9IGluc2V0LnRvcDsKKwkJCXJlY3QucmlnaHQgLT0gaW5zZXQucmlnaHQ7CisJCQlyZWN0LmJvdHRvbSAtPSBpbnNldC5ib3R0b207CisJCQlib29sZWFuIGRyYXdGb2N1cyA9IChzdHlsZSAmIFNXVC5OT19GT0NVUykgPT0gMCAmJiBob29rc0tleXMgKCk7CisJCQlib29sZWFuIGRyYXdCb3JkZXIgPSBoYXNCb3JkZXIgKCk7CisJCQlpbnQgc3RhdGUgPSBPUy5Jc0NvbnRyb2xBY3RpdmUgKGhhbmRsZSkgPyBPUy5rVGhlbWVTdGF0ZUFjdGl2ZSA6IE9TLmtUaGVtZVN0YXRlSW5hY3RpdmU7CisJCQlpZiAoaGFzRm9jdXMgKCkpIHsKKwkJCQlpZiAoZHJhd0JvcmRlcikgT1MuRHJhd1RoZW1lRWRpdFRleHRGcmFtZSAocmVjdCwgc3RhdGUpOworCQkJCWlmIChkcmF3Rm9jdXMpIE9TLkRyYXdUaGVtZUZvY3VzUmVjdCAocmVjdCwgdHJ1ZSk7CisJCQl9IGVsc2UgeworCQkJCWlmIChkcmF3Rm9jdXMpIE9TLkRyYXdUaGVtZUZvY3VzUmVjdCAocmVjdCwgZmFsc2UpOworCQkJCWlmIChkcmF3Qm9yZGVyKSBPUy5EcmF3VGhlbWVFZGl0VGV4dEZyYW1lIChyZWN0LCBzdGF0ZSk7CisJCQl9CisJCX0gZWxzZSB7CisJCQlpZiAoKHN0eWxlICYgU1dULk5PX0JBQ0tHUk9VTkQpICE9IDApIHJldHVybjsKKwkJCWRyYXdCYWNrZ3JvdW5kIChjb250cm9sLCBiYWNrZ3JvdW5kKTsKKwkJfQorCX0gZWxzZSB7CisJCXN1cGVyLmRyYXdXaWRnZXQgKGNvbnRyb2wpOwkKIAl9Ci0JYm9vbGVhbiByZXN1bHQgPSBzdXBlci5mb3JjZUZvY3VzICgpOwotCWZvciAoaW50IGk9MDsgaTxjaGlsZHJlbi5sZW5ndGg7IGkrKykgewotCQlhcmdMaXN0IFsxXSA9IHRyYXZlcnNhbHMgW2ldOwotCQlPUy5YdFNldFZhbHVlcyAoY2hpbGRyZW4gW2ldLmhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQl9Ci0JcmV0dXJuIHJlc3VsdDsKIH0KLSovCi0vKioKLSAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyB0aGUgcmVjZWl2ZXIncyBjaGlsZHJlbi4KLSAqIDxwPgotICogTm90ZTogVGhpcyBpcyBub3QgdGhlIGFjdHVhbCBzdHJ1Y3R1cmUgdXNlZCBieSB0aGUgcmVjZWl2ZXIKLSAqIHRvIG1haW50YWluIGl0cyBsaXN0IG9mIGNoaWxkcmVuLCBzbyBtb2RpZnlpbmcgdGhlIGFycmF5IHdpbGwKLSAqIG5vdCBhZmZlY3QgdGhlIHJlY2VpdmVyLiAKLSAqIDwvcD4KLSAqCi0gKiBAcmV0dXJuIGFuIGFycmF5IG9mIGNoaWxkcmVuCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBDb250cm9sIFtdIGdldENoaWxkcmVuICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBfZ2V0Q2hpbGRyZW4gKCk7CiB9CisKIGludCBnZXRDaGlsZHJlbkNvdW50ICgpIHsKIAkvKgogCSogTk9URTogIFRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIHdpbGwgY291bnQKIAkqIG5vbi1yZWdpc3RlcmVkIGNoaWxkcmVuLgogCSovCi0Jc2hvcnRbXSBjbnQ9IG5ldyBzaG9ydFsxXTsKLQlPUy5Db3VudFN1YkNvbnRyb2xzKGhhbmRsZSwgY250KTsKLQlyZXR1cm4gY250WzBdOworCXNob3J0IFtdIGNvdW50ID0gbmV3IHNob3J0IFsxXTsKKwlPUy5Db3VudFN1YkNvbnRyb2xzIChoYW5kbGUsIGNvdW50KTsKKwlyZXR1cm4gY291bnQgWzBdOwogfQotLyoqCi0gKiBSZXR1cm5zIGxheW91dCB3aGljaCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIHJlY2VpdmVyLCBvcgotICogbnVsbCBpZiBvbmUgaGFzIG5vdCBiZWVuIHNldC4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGxheW91dCBvciBudWxsCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBMYXlvdXQgZ2V0TGF5b3V0ICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBsYXlvdXQ7CiB9CiAKLS8qKgotICogR2V0cyB0aGUgbGFzdCBzcGVjaWZpZWQgdGFiYmluZyBvcmRlciBmb3IgdGhlIGNvbnRyb2wuCi0gKgotICogQHJldHVybiB0YWJMaXN0IHRoZSBvcmRlcmVkIGxpc3Qgb2YgY29udHJvbHMgcmVwcmVzZW50aW5nIHRoZSB0YWIgb3JkZXIKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiAKLSAqIEBzZWUgI3NldFRhYkxpc3QKLSAqLwogcHVibGljIENvbnRyb2wgW10gZ2V0VGFiTGlzdCAoKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJQ29udHJvbCBbXSB0YWJMaXN0ID0gX2dldFRhYkxpc3QgKCk7CkBAIC0zNDcsNjQgKzIxMiw0NSBAQAogCXJldHVybiB0YWJMaXN0OwogfQogCi12b2lkIGhvb2tFdmVudHMgKCkgewotCXN1cGVyLmhvb2tFdmVudHMgKCk7Ci0JaWYgKChzdGF0ZSAmIENBTlZBUykgIT0gMCkgewotICAgICAgICAvKiBBVwotCQlpbnQgd2luZG93UHJvYyA9IGdldERpc3BsYXkgKCkud2luZG93UHJvYzsKLQkJT1MuWHRBZGRFdmVudEhhbmRsZXIgKGhhbmRsZSwgMCwgdHJ1ZSwgd2luZG93UHJvYywgLTEpOwotICAgICAgICAqLwotCQlEaXNwbGF5IGRpc3BsYXk9IGdldERpc3BsYXkoKTsJCQotCQlPUy5TZXRDb250cm9sRGF0YShoYW5kbGUsIE9TLmtDb250cm9sRW50aXJlQ29udHJvbCwgT1Mua0NvbnRyb2xVc2VyUGFuZURyYXdQcm9jVGFnLCBkaXNwbGF5LmZVc2VyUGFuZURyYXdQcm9jKTsKLQkJT1MuU2V0Q29udHJvbERhdGEoaGFuZGxlLCBPUy5rQ29udHJvbEVudGlyZUNvbnRyb2wsIE9TLmtDb250cm9sVXNlclBhbmVIaXRUZXN0UHJvY1RhZywgZGlzcGxheS5mVXNlclBhbmVIaXRUZXN0UHJvYyk7Ci0KLQotCQlpZiAoTWFjVXRpbC5ISVZJRVcpIHsKLQkJCS8vIE9TLlNldENvbnRyb2xEYXRhKGhhbmRsZSwgT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbFVzZXJQYW5lVHJhY2tpbmdQcm9jVGFnLCBkaXNwbGF5LmZVc2VyUGFuZVRyYWNraW5nUHJvYyk7Ci0JCQlpbnQgcmVmPSBPUy5HZXRDb250cm9sRXZlbnRUYXJnZXQoaGFuZGxlKTsKLQkJCWludFtdIG1hc2s9IG5ldyBpbnRbXSB7Ci0JCQkJT1Mua0V2ZW50Q2xhc3NNb3VzZSwgT1Mua0V2ZW50TW91c2VEb3duLAotCQkJCU9TLmtFdmVudENsYXNzTW91c2UsIE9TLmtFdmVudE1vdXNlV2hlZWxNb3ZlZCwKLQkJCX07Ci0JCQlPUy5JbnN0YWxsRXZlbnRIYW5kbGVyKHJlZiwgZGlzcGxheS5mTW91c2VQcm9jLCBtYXNrLCBoYW5kbGUpOworaW50IGtFdmVudENvbnRyb2xDbGljayAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWludCByZXN1bHQgPSBzdXBlci5rRXZlbnRDb250cm9sQ2xpY2sgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCWlmIChyZXN1bHQgPT0gT1Mubm9FcnIpIHJldHVybiByZXN1bHQ7CisJaWYgKChzdGF0ZSAmIENBTlZBUykgIT0gMCAmJiAoc3R5bGUgJiBTV1QuTk9fRk9DVVMpID09IDAgJiYgaG9va3NLZXlzICgpKSB7CisJCWludCBbXSB0aGVDb250cm9sID0gbmV3IGludCBbMV07CisJCWludCB3aW5kb3cgPSBPUy5HZXRDb250cm9sT3duZXIgKGhhbmRsZSk7CisJCU9TLkdldEtleWJvYXJkRm9jdXMgKHdpbmRvdywgdGhlQ29udHJvbCk7CisJCWlmIChoYW5kbGUgIT0gdGhlQ29udHJvbCBbMF0pIHsKKwkJCXNob3J0IFtdIGNvdW50ID0gbmV3IHNob3J0IFsxXTsKKwkJCU9TLkNvdW50U3ViQ29udHJvbHMgKGhhbmRsZSwgY291bnQpOworCQkJaWYgKGNvdW50IFswXSA9PSAwKSB7CisJCQkJaWYgKE9TLlNldEtleWJvYXJkRm9jdXMgKHdpbmRvdywgaGFuZGxlLCAoc2hvcnQpIE9TLmtDb250cm9sRm9jdXNOZXh0UGFydCkgPT0gT1Mubm9FcnIpIHsKKwkJCQkJcmV0dXJuIE9TLm5vRXJyOworCQkJCX0KKwkJCX0KIAkJfQogCX0KKwlyZXR1cm4gcmVzdWx0OwogfQogCi0vKioKLSAqIElmIHRoZSByZWNlaXZlciBoYXMgYSBsYXlvdXQsIGFza3MgdGhlIGxheW91dCB0byA8ZW0+bGF5IG91dDwvZW0+Ci0gKiAodGhhdCBpcywgc2V0IHRoZSBzaXplIGFuZCBsb2NhdGlvbiBvZikgdGhlIHJlY2VpdmVyJ3MgY2hpbGRyZW4uIAotICogSWYgdGhlIHJlY2VpdmVyIGRvZXMgbm90IGhhdmUgYSBsYXlvdXQsIGRvIG5vdGhpbmcuCi0gKiA8cD4KLSAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byBjYWxsaW5nIDxjb2RlPmxheW91dCh0cnVlKTwvY29kZT4uCi0gKiA8L3A+Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCitpbnQga0V2ZW50Q29udHJvbFNldEZvY3VzUGFydCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWludCByZXN1bHQgPSBzdXBlci5rRXZlbnRDb250cm9sU2V0Rm9jdXNQYXJ0IChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwlpZiAocmVzdWx0ID09IE9TLm5vRXJyKSByZXR1cm4gcmVzdWx0OworCWlmICgoKHN0YXRlICYgQ0FOVkFTKSAhPSAwICYmIChzdHlsZSAmIFNXVC5OT19GT0NVUykgPT0gMCAmJiBob29rc0tleXMgKCkpKSB7CisJCWlmIChzY3JvbGxlZEhhbmRsZSAhPSAwKSByZWRyYXdXaWRnZXQgKHNjcm9sbGVkSGFuZGxlKTsKKwkJcmV0dXJuIE9TLm5vRXJyOworCX0KKwlyZXR1cm4gcmVzdWx0OworfQorCitib29sZWFuIGhvb2tzS2V5cyAoKSB7CisJcmV0dXJuIGhvb2tzIChTV1QuS2V5RG93bikgfHwgaG9va3MgKFNXVC5LZXlVcCkgfHwgaG9va3MgKFNXVC5UcmF2ZXJzZSk7Cit9CisKIHB1YmxpYyB2b2lkIGxheW91dCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlsYXlvdXQgKHRydWUpOwogfQotLyoqCi0gKiBJZiB0aGUgcmVjZWl2ZXIgaGFzIGEgbGF5b3V0LCBhc2tzIHRoZSBsYXlvdXQgdG8gPGVtPmxheSBvdXQ8L2VtPgotICogKHRoYXQgaXMsIHNldCB0aGUgc2l6ZSBhbmQgbG9jYXRpb24gb2YpIHRoZSByZWNlaXZlcidzIGNoaWxkcmVuLiAKLSAqIElmIHRoZSB0aGUgYXJndW1lbnQgaXMgPGNvZGU+dHJ1ZTwvY29kZT4gdGhlIGxheW91dCBtdXN0IG5vdCByZWx5Ci0gKiBvbiBhbnkgY2FjaGVkIGluZm9ybWF0aW9uIGl0IGlzIGtlZXBpbmcgYWJvdXQgdGhlIGNoaWxkcmVuLiBJZiBpdAotICogaXMgPGNvZGU+ZmFsc2U8L2NvZGU+IHRoZSBsYXlvdXQgbWF5IChwb3RlbnRpYWxseSkgc2ltcGxpZnkgdGhlCi0gKiB3b3JrIGl0IGlzIGRvaW5nIGJ5IGFzc3VtaW5nIHRoYXQgdGhlIHN0YXRlIG9mIHRoZSBub25lIG9mIHRoZQotICogcmVjZWl2ZXIncyBjaGlsZHJlbiBoYXMgY2hhbmdlZCBzaW5jZSB0aGUgbGFzdCBsYXlvdXQuCi0gKiBJZiB0aGUgcmVjZWl2ZXIgZG9lcyBub3QgaGF2ZSBhIGxheW91dCwgZG8gbm90aGluZy4KLSAqCi0gKiBAcGFyYW0gY2hhbmdlZCA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbGF5b3V0IG11c3QgZmx1c2ggaXRzIGNhY2hlcywgYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgbGF5b3V0IChib29sZWFuIGNoYW5nZWQpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsYXlvdXQgPT0gbnVsbCkgcmV0dXJuOwpAQCAtNDEyLDYgKzI1OCw3IEBACiAJaWYgKGNvdW50ID09IDApIHJldHVybjsKIAlsYXlvdXQubGF5b3V0ICh0aGlzLCBjaGFuZ2VkKTsKIH0KKwogUG9pbnQgbWluaW11bVNpemUgKCkgewogCUNvbnRyb2wgW10gY2hpbGRyZW4gPSBfZ2V0Q2hpbGRyZW4gKCk7CiAJaW50IHdpZHRoID0gMCwgaGVpZ2h0ID0gMDsKQEAgLTQyMiwyMDcgKzI2OSw0MyBAQAogCX0KIAlyZXR1cm4gbmV3IFBvaW50ICh3aWR0aCwgaGVpZ2h0KTsKIH0KLS8qIEFXCi12b2lkIG1vdmVBYm92ZSAoaW50IGhhbmRsZTEsIGludCBoYW5kbGUyKSB7Ci0JaWYgKGhhbmRsZTEgPT0gaGFuZGxlMikgcmV0dXJuOwotCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTmNoaWxkcmVuLCAwLCBPUy5YbU5udW1DaGlsZHJlbiwgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlpbnQgcHRyID0gYXJnTGlzdCBbMV0sIGNvdW50ID0gYXJnTGlzdCBbM107Ci0JaWYgKGNvdW50ID09IDAgfHwgcHRyID09IDApIHJldHVybjsKLQlpbnQgW10gaGFuZGxlcyA9IG5ldyBpbnQgW2NvdW50XTsKLQlPUy5tZW1tb3ZlIChoYW5kbGVzLCBwdHIsIGNvdW50ICogNCk7Ci0JaWYgKGhhbmRsZTIgPT0gMCkgaGFuZGxlMiA9IGhhbmRsZXMgWzBdOwotCWludCBpID0gMCwgaW5kZXgxID0gLTEsIGluZGV4MiA9IC0xOwotCXdoaWxlIChpIDwgY291bnQpIHsKLQkJaW50IGhhbmRsZSA9IGhhbmRsZXMgW2ldOwotCQlpZiAoaGFuZGxlID09IGhhbmRsZTEpIGluZGV4MSA9IGk7Ci0JCWlmIChoYW5kbGUgPT0gaGFuZGxlMikgaW5kZXgyID0gaTsKLQkJaWYgKGluZGV4MSAhPSAtMSAmJiBpbmRleDIgIT0gLTEpIGJyZWFrOwotCQlpKys7Ci0JfQotCWlmIChpbmRleDEgPT0gLTEgfHwgaW5kZXgyID09IC0xKSByZXR1cm47Ci0JaWYgKGluZGV4MSA9PSBpbmRleDIpIHJldHVybjsKLQlpZiAoaW5kZXgxIDwgaW5kZXgyKSB7Ci0JCVN5c3RlbS5hcnJheWNvcHkgKGhhbmRsZXMsIGluZGV4MSArIDEsIGhhbmRsZXMsIGluZGV4MSwgaW5kZXgyIC0gaW5kZXgxIC0gMSk7Ci0JCWhhbmRsZXMgW2luZGV4MiAtIDFdID0gaGFuZGxlMTsKLQl9IGVsc2UgewotCQlTeXN0ZW0uYXJyYXljb3B5IChoYW5kbGVzLCBpbmRleDIsIGhhbmRsZXMsIGluZGV4MiArIDEsIGluZGV4MSAtIGluZGV4Mik7Ci0JCWhhbmRsZXMgW2luZGV4Ml0gPSBoYW5kbGUxOwotCX0KLQlPUy5tZW1tb3ZlIChwdHIsIGhhbmRsZXMsIGNvdW50ICogNCk7Ci19Ci12b2lkIG1vdmVCZWxvdyAoaW50IGhhbmRsZTEsIGludCBoYW5kbGUyKSB7Ci0JaWYgKGhhbmRsZTEgPT0gaGFuZGxlMikgcmV0dXJuOwotCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTmNoaWxkcmVuLCAwLCBPUy5YbU5udW1DaGlsZHJlbiwgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlpbnQgcHRyID0gYXJnTGlzdCBbMV0sIGNvdW50ID0gYXJnTGlzdCBbM107Ci0JaWYgKGNvdW50ID09IDAgfHwgcHRyID09IDApIHJldHVybjsKLQlpbnQgW10gaGFuZGxlcyA9IG5ldyBpbnQgW2NvdW50XTsKLQlPUy5tZW1tb3ZlIChoYW5kbGVzLCBwdHIsIGNvdW50ICogNCk7Ci0JaWYgKGhhbmRsZTIgPT0gMCkgaGFuZGxlMiA9IGhhbmRsZXMgW2NvdW50IC0gMV07Ci0JaW50IGkgPSAwLCBpbmRleDEgPSAtMSwgaW5kZXgyID0gLTE7Ci0Jd2hpbGUgKGkgPCBjb3VudCkgewotCQlpbnQgaGFuZGxlID0gaGFuZGxlcyBbaV07Ci0JCWlmIChoYW5kbGUgPT0gaGFuZGxlMSkgaW5kZXgxID0gaTsKLQkJaWYgKGhhbmRsZSA9PSBoYW5kbGUyKSBpbmRleDIgPSBpOwotCQlpZiAoaW5kZXgxICE9IC0xICYmIGluZGV4MiAhPSAtMSkgYnJlYWs7Ci0JCWkrKzsKLQl9Ci0JaWYgKGluZGV4MSA9PSAtMSB8fCBpbmRleDIgPT0gLTEpIHJldHVybjsKLQlpZiAoaW5kZXgxID09IGluZGV4MikgcmV0dXJuOwotCWlmIChpbmRleDEgPCBpbmRleDIpIHsKLQkJU3lzdGVtLmFycmF5Y29weSAoaGFuZGxlcywgaW5kZXgxICsgMSwgaGFuZGxlcywgaW5kZXgxLCBpbmRleDIgLSBpbmRleDEpOwotCQloYW5kbGVzIFtpbmRleDJdID0gaGFuZGxlMTsKLQl9IGVsc2UgewotCQlTeXN0ZW0uYXJyYXljb3B5IChoYW5kbGVzLCBpbmRleDIgKyAxLCBoYW5kbGVzLCBpbmRleDIgKyAyLCBpbmRleDEgLSBpbmRleDIgLSAxKTsKLQkJaGFuZGxlcyBbaW5kZXgyICsgMV0gPSBoYW5kbGUxOwotCX0KLQlPUy5tZW1tb3ZlIChwdHIsIGhhbmRsZXMsIGNvdW50ICogNCk7Ci19Ci0qLwotaW50IHByb2Nlc3NOb25NYXNrYWJsZSAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0gICAgLyogQVcKLQlpZiAoKHN0YXRlICYgQ0FOVkFTKSAhPSAwKSB7Ci0JCVhFeHBvc2VFdmVudCB4RXZlbnQgPSBuZXcgWEV4cG9zZUV2ZW50ICgpOwotCQlPUy5tZW1tb3ZlICh4RXZlbnQsIGNhbGxEYXRhLCBYRXhwb3NlRXZlbnQuc2l6ZW9mKTsKLQkJaWYgKHhFdmVudC50eXBlID09IE9TLkdyYXBoaWNzRXhwb3NlKSBwcm9jZXNzUGFpbnQgKGNhbGxEYXRhKTsKLQl9Ci0gICAgKi8KLQlyZXR1cm4gMDsKLX0KLXZvaWQgcHJvcGFnYXRlQ2hpbGRyZW4gKGJvb2xlYW4gZW5hYmxlZCkgewotCXN1cGVyLnByb3BhZ2F0ZUNoaWxkcmVuIChlbmFibGVkKTsKLQlDb250cm9sIFtdIGNoaWxkcmVuID0gX2dldENoaWxkcmVuICgpOwotCWZvciAoaW50IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsKLQkJQ29udHJvbCBjaGlsZCA9IGNoaWxkcmVuIFtpXTsKLQkJaWYgKGNoaWxkLmdldEVuYWJsZWQgKCkpIHsKLQkJCWNoaWxkLnByb3BhZ2F0ZUNoaWxkcmVuIChlbmFibGVkKTsKLQkJfQotCX0KLX0KLXZvaWQgcmVhbGl6ZUNoaWxkcmVuICgpIHsKLSAgICAvKiBBVwotCXN1cGVyLnJlYWxpemVDaGlsZHJlbiAoKTsKLQlDb250cm9sIFtdIGNoaWxkcmVuID0gX2dldENoaWxkcmVuICgpOwotCWZvciAoaW50IGk9MDsgaTxjaGlsZHJlbi5sZW5ndGg7IGkrKykgewotCQljaGlsZHJlbiBbaV0ucmVhbGl6ZUNoaWxkcmVuICgpOwotCX0KLQlpZiAoKHN0YXRlICYgQ0FOVkFTKSAhPSAwKSB7Ci0JCWlmICgoc3R5bGUgJiBTV1QuTk9fQkFDS0dST1VORCkgPT0gMCAmJiAoc3R5bGUgJiBTV1QuTk9fUkVEUkFXX1JFU0laRSkgIT0gMCkgcmV0dXJuOwotCQlpbnQgeERpc3BsYXkgPSBPUy5YdERpc3BsYXkgKGhhbmRsZSk7Ci0JCWlmICh4RGlzcGxheSA9PSAwKSByZXR1cm47Ci0JCWludCB4V2luZG93ID0gT1MuWHRXaW5kb3cgKGhhbmRsZSk7Ci0JCWlmICh4V2luZG93ID09IDApIHJldHVybjsKLQkJaW50IGZsYWdzID0gMDsKLQkJWFNldFdpbmRvd0F0dHJpYnV0ZXMgYXR0cmlidXRlcyA9IG5ldyBYU2V0V2luZG93QXR0cmlidXRlcyAoKTsKLQkJaWYgKChzdHlsZSAmIFNXVC5OT19CQUNLR1JPVU5EKSAhPSAwKSB7Ci0JCQlmbGFncyB8PSBPUy5DV0JhY2tQaXhtYXA7Ci0JCQlhdHRyaWJ1dGVzLmJhY2tncm91bmRfcGl4bWFwID0gT1MuTm9uZTsKLQkJfQotCQlpZiAoKHN0eWxlICYgU1dULk5PX1JFRFJBV19SRVNJWkUpID09IDApIHsKLQkJCWZsYWdzIHw9IE9TLkNXQml0R3Jhdml0eTsKLQkJCWF0dHJpYnV0ZXMuYml0X2dyYXZpdHkgPSBPUy5Gb3JnZXRHcmF2aXR5OwotCQl9Ci0JCWlmIChmbGFncyAhPSAwKSB7Ci0JCQlPUy5YQ2hhbmdlV2luZG93QXR0cmlidXRlcyAoeERpc3BsYXksIHhXaW5kb3csIGZsYWdzLCBhdHRyaWJ1dGVzKTsKLQkJfQotCX0KLSAgICAqLwotfQotdm9pZCByZWRyYXdXaWRnZXQgKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBib29sZWFuIGFsbCkgewotCXN1cGVyLnJlZHJhd1dpZGdldCAoeCwgeSwgd2lkdGgsIGhlaWdodCwgYWxsKTsKLQlpZiAoIWFsbCkgcmV0dXJuOwotCUNvbnRyb2wgW10gY2hpbGRyZW4gPSBfZ2V0Q2hpbGRyZW4gKCk7Ci0JZm9yIChpbnQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykgewotCQlDb250cm9sIGNoaWxkID0gY2hpbGRyZW4gW2ldOwotCQlQb2ludCBsb2NhdGlvbiA9IGNoaWxkLmdldENsaWVudExvY2F0aW9uICgpOwotCQljaGlsZC5yZWRyYXdXaWRnZXQgKHggLSBsb2NhdGlvbi54LCB5IC0gbG9jYXRpb24ueSwgd2lkdGgsIGhlaWdodCwgYWxsKTsKLQl9Ci19CisKIHZvaWQgcmVsZWFzZUNoaWxkcmVuICgpIHsKIAlDb250cm9sIFtdIGNoaWxkcmVuID0gX2dldENoaWxkcmVuICgpOwogCWZvciAoaW50IGk9MDsgaTxjaGlsZHJlbi5sZW5ndGg7IGkrKykgewogCQlDb250cm9sIGNoaWxkID0gY2hpbGRyZW4gW2ldOwotCQlpZiAoIWNoaWxkLmlzRGlzcG9zZWQgKCkpIHsKLQkJCWNoaWxkLnJlbGVhc2VXaWRnZXQgKCk7Ci0JCQljaGlsZC5yZWxlYXNlSGFuZGxlICgpOwotCQl9CisJCWlmICghY2hpbGQuaXNEaXNwb3NlZCAoKSkgY2hpbGQucmVsZWFzZVJlc291cmNlcyAoKTsKIAl9CiB9CisKIHZvaWQgcmVsZWFzZVdpZGdldCAoKSB7CiAJcmVsZWFzZUNoaWxkcmVuICgpOwogCXN1cGVyLnJlbGVhc2VXaWRnZXQgKCk7CiAJbGF5b3V0ID0gbnVsbDsKIAl0YWJMaXN0ID0gbnVsbDsKLSAgICAvKiBBVwotCWlmIChkYW1hZ2VkUmVnaW9uICE9IDApIE9TLlhEZXN0cm95UmVnaW9uIChkYW1hZ2VkUmVnaW9uKTsKLQlkYW1hZ2VkUmVnaW9uID0gMDsKLSAgICAqLwogfQotdm9pZCBzZXRCYWNrZ3JvdW5kUGl4ZWwgKGludCBwaXhlbCkgewotCXN1cGVyLnNldEJhY2tncm91bmRQaXhlbCAocGl4ZWwpOwotCWlmICgoc3RhdGUgJiBDQU5WQVMpICE9IDApIHsKLQkJaWYgKChzdHlsZSAmIFNXVC5OT19CQUNLR1JPVU5EKSAhPSAwKSB7Ci0JCQkvKiBBVwotCQkJaW50IHhEaXNwbGF5ID0gT1MuWHREaXNwbGF5IChoYW5kbGUpOwotCQkJaWYgKHhEaXNwbGF5ID09IDApIHJldHVybjsKLQkJCWludCB4V2luZG93ID0gT1MuWHRXaW5kb3cgKGhhbmRsZSk7Ci0JCQlpZiAoeFdpbmRvdyA9PSAwKSByZXR1cm47Ci0JCQlYU2V0V2luZG93QXR0cmlidXRlcyBhdHRyaWJ1dGVzID0gbmV3IFhTZXRXaW5kb3dBdHRyaWJ1dGVzICgpOwotCQkJYXR0cmlidXRlcy5iYWNrZ3JvdW5kX3BpeG1hcCA9IE9TLk5vbmU7Ci0JCQlPUy5YQ2hhbmdlV2luZG93QXR0cmlidXRlcyAoeERpc3BsYXksIHhXaW5kb3csIE9TLkNXQmFja1BpeG1hcCwgYXR0cmlidXRlcyk7Ci0JCQkqLwotCQl9Ci0JfQorCitpbnQgc2V0Qm91bmRzIChpbnQgY29udHJvbCwgaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGJvb2xlYW4gbW92ZSwgYm9vbGVhbiByZXNpemUsIGJvb2xlYW4gZXZlbnRzKSB7CisJaW50IHJlc3VsdCA9IHN1cGVyLnNldEJvdW5kcyhjb250cm9sLCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCBtb3ZlLCByZXNpemUsIGV2ZW50cyk7CisJaWYgKGxheW91dCAhPSBudWxsICYmIChyZXN1bHQgJiBSRVNJWkVEKSAhPSAwKSBsYXlvdXQubGF5b3V0ICh0aGlzLCBmYWxzZSk7CisJcmV0dXJuIHJlc3VsdDsKIH0KLXB1YmxpYyB2b2lkIHNldEJvdW5kcyAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKLQlzdXBlci5zZXRCb3VuZHMgKHgsIHksIHdpZHRoLCBoZWlnaHQpOwotCWlmIChsYXlvdXQgIT0gbnVsbCkgbGF5b3V0IChmYWxzZSk7Ci19Ci1wdWJsaWMgYm9vbGVhbiBzZXRGb2N1cygpIHsKKworcHVibGljIGJvb2xlYW4gc2V0Rm9jdXMgKCkgewogCWNoZWNrV2lkZ2V0ICgpOwogCWlmICgoc3R5bGUgJiBTV1QuTk9fRk9DVVMpICE9IDApIHJldHVybiBmYWxzZTsKIAlDb250cm9sIFtdIGNoaWxkcmVuID0gX2dldENoaWxkcmVuICgpOwogCWZvciAoaW50IGk9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykgewotCQlDb250cm9sIGNoaWxkID0gY2hpbGRyZW4gW2ldOwotCQlpZiAoY2hpbGQuc2V0Rm9jdXMgKCkpIHJldHVybiB0cnVlOworCQlpZiAoY2hpbGRyZW4gW2ldLnNldEZvY3VzICgpKSByZXR1cm4gdHJ1ZTsKIAl9CiAJcmV0dXJuIHN1cGVyLnNldEZvY3VzICgpOwogfQotLyoqCi0gKiBTZXRzIHRoZSBsYXlvdXQgd2hpY2ggaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSByZWNlaXZlciB0byBiZQotICogdGhlIGFyZ3VtZW50IHdoaWNoIG1heSBiZSBudWxsLgotICoKLSAqIEBwYXJhbSBsYXlvdXQgdGhlIHJlY2VpdmVyJ3MgbmV3IGxheW91dCBvciBudWxsCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldExheW91dCAoTGF5b3V0IGxheW91dCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJdGhpcy5sYXlvdXQgPSBsYXlvdXQ7CiB9Ci1wdWJsaWMgdm9pZCBzZXRTaXplIChpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKLQlzdXBlci5zZXRTaXplICh3aWR0aCwgaGVpZ2h0KTsKLQlpZiAobGF5b3V0ICE9IG51bGwpIGxheW91dCAoZmFsc2UpOwotfQotLyoqCi0gKiBTZXRzIHRoZSB0YWJiaW5nIG9yZGVyIGZvciB0aGUgc3BlY2lmaWVkIGNvbnRyb2xzIHRvCi0gKiBtYXRjaCB0aGUgb3JkZXIgdGhhdCB0aGV5IG9jY3VyIGluIHRoZSBhcmd1bWVudCBsaXN0LgotICoKLSAqIEBwYXJhbSB0YWJMaXN0IHRoZSBvcmRlcmVkIGxpc3Qgb2YgY29udHJvbHMgcmVwcmVzZW50aW5nIHRoZSB0YWIgb3JkZXIgb3IgbnVsbAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX0FSR1VNRU5UIC0gaWYgYSB3aWRnZXQgaW4gdGhlIHRhYkxpc3QgaXMgbnVsbCBvciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+IAotICogICAgPGxpPkVSUk9SX0lOVkFMSURfUEFSRU5UIC0gaWYgd2lkZ2V0IGluIHRoZSB0YWJMaXN0IGlzIG5vdCBpbiB0aGUgc2FtZSB3aWRnZXQgdHJlZTwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldFRhYkxpc3QgKENvbnRyb2wgW10gdGFiTGlzdCkgewogCWNoZWNrV2lkZ2V0ICgpOwogCWlmICh0YWJMaXN0ICE9IG51bGwpIHsKQEAgLTY0OCwyMiArMzMxLDEwIEBACiAJfSAKIAl0aGlzLnRhYkxpc3QgPSB0YWJMaXN0OwogfQotaW50IHRyYXZlcnNhbENvZGUgKCkgewotCWlmICgoc3RhdGUgJiBDQU5WQVMpICE9IDApIHsKLQkJaWYgKChzdHlsZSAmIFNXVC5OT19GT0NVUykgIT0gMCkgcmV0dXJuIDA7Ci0JCWlmIChob29rcyAoU1dULktleURvd24pIHx8IGhvb2tzIChTV1QuS2V5VXApKSByZXR1cm4gMDsKLQl9Ci0JcmV0dXJuIHN1cGVyLnRyYXZlcnNhbENvZGUgKCk7CisKK3ZvaWQgc2V0Wk9yZGVyICgpIHsKKwlzdXBlci5zZXRaT3JkZXIgKCk7CisJaWYgKHNjcm9sbGVkSGFuZGxlICE9IDApIE9TLkhJVmlld0FkZFN1YnZpZXcgKHNjcm9sbGVkSGFuZGxlLCBoYW5kbGUpOwogfQotLyogQVcKLWJvb2xlYW4gdHJhbnNsYXRlTW5lbW9uaWMgKGNoYXIga2V5LCBYS2V5RXZlbnQgeEV2ZW50KSB7Ci0JaWYgKHN1cGVyLnRyYW5zbGF0ZU1uZW1vbmljIChrZXksIHhFdmVudCkpIHJldHVybiB0cnVlOwotCUNvbnRyb2wgW10gY2hpbGRyZW4gPSBfZ2V0Q2hpbGRyZW4gKCk7Ci0JZm9yIChpbnQgaT0wOyBpPGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7Ci0JCUNvbnRyb2wgY2hpbGQgPSBjaGlsZHJlbiBbaV07Ci0JCWlmIChjaGlsZC50cmFuc2xhdGVNbmVtb25pYyAoa2V5LCB4RXZlbnQpKSByZXR1cm4gdHJ1ZTsKLQl9Ci0JcmV0dXJuIGZhbHNlOwotfQotKi8KKwogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0NvbnRyb2wuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Db250cm9sLmphdmEKaW5kZXggYjVjZDE2OC4uZWZmZDk0YSAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0NvbnRyb2wuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvQ29udHJvbC5qYXZhCkBAIC03LDk0ICs3LDQ0IEBACiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCiAKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmFjY2Vzc2liaWxpdHkuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkNHUG9pbnQ7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5DR1JlY3Q7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Db250cm9sRm9udFN0eWxlUmVjOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uSE1IZWxwQ29udGVudFJlYzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlJlY3Q7CiAKLS8qKgotICogQ29udHJvbCBpcyB0aGUgYWJzdHJhY3Qgc3VwZXJjbGFzcyBvZiBhbGwgd2luZG93ZWQgdXNlciBpbnRlcmZhY2UgY2xhc3Nlcy4KLSAqIDxwPgotICogPGRsPgotICogPGR0PjxiPlN0eWxlczo8L2I+Ci0gKiA8ZGQ+Qk9SREVSPC9kZD4KLSAqIDxkdD48Yj5FdmVudHM6PC9iPgotICogPGRkPkZvY3VzSW4sIEZvY3VzT3V0LCBIZWxwLCBLZXlEb3duLCBLZXlVcCwgTW91c2VEb3VibGVDbGljaywgTW91c2VEb3duLCBNb3VzZUVudGVyLAotICogICAgIE1vdXNlRXhpdCwgTW91c2VIb3ZlciwgTW91c2VVcCwgTW91c2VNb3ZlLCBNb3ZlLCBQYWludCwgUmVzaXplPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cD4KLSAqIElNUE9SVEFOVDogVGhpcyBjbGFzcyBpcyBpbnRlbmRlZCB0byBiZSBzdWJjbGFzc2VkIDxlbT5vbmx5PC9lbT4KLSAqIHdpdGhpbiB0aGUgU1dUIGltcGxlbWVudGF0aW9uLgotICogPC9wPgotICovCitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5hY2Nlc3NpYmlsaXR5LkFjY2Vzc2libGU7CisKIHB1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb250cm9sIGV4dGVuZHMgV2lkZ2V0IGltcGxlbWVudHMgRHJhd2FibGUgeworCS8qKgorCSogdGhlIGhhbmRsZSB0byB0aGUgT1MgcmVzb3VyY2UKKwkqIChXYXJuaW5nOiBUaGlzIGZpZWxkIGlzIHBsYXRmb3JtIGRlcGVuZGVudCkKKwkqLworCXB1YmxpYyBpbnQgaGFuZGxlOwogCUNvbXBvc2l0ZSBwYXJlbnQ7Ci0JRm9udCBmb250OwotCWludCBmb3JlZ3JvdW5kLCBiYWNrZ3JvdW5kOwotCU1lbnUgbWVudTsKIAlTdHJpbmcgdG9vbFRpcFRleHQ7CiAJT2JqZWN0IGxheW91dERhdGE7Ci0JQWNjZXNzaWJsZSBhY2Nlc3NpYmxlOwogCWludCBkcmF3Q291bnQ7Ci0JYm9vbGVhbiB2aXNpYmxlPSB0cnVlOworCU1lbnUgbWVudTsKKwlmbG9hdCBbXSBmb3JlZ3JvdW5kLCBiYWNrZ3JvdW5kOworCUZvbnQgZm9udDsKIAlDdXJzb3IgY3Vyc29yOwotCQorCUFjY2Vzc2libGUgYWNjZXNzaWJsZTsKKwogQ29udHJvbCAoKSB7CiAJLyogRG8gbm90aGluZyAqLwogfQotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gaXRzIHBhcmVudAotICogYW5kIGEgc3R5bGUgdmFsdWUgZGVzY3JpYmluZyBpdHMgYmVoYXZpb3IgYW5kIGFwcGVhcmFuY2UuCi0gKiA8cD4KLSAqIFRoZSBzdHlsZSB2YWx1ZSBpcyBlaXRoZXIgb25lIG9mIHRoZSBzdHlsZSBjb25zdGFudHMgZGVmaW5lZCBpbgotICogY2xhc3MgPGNvZGU+U1dUPC9jb2RlPiB3aGljaCBpcyBhcHBsaWNhYmxlIHRvIGluc3RhbmNlcyBvZiB0aGlzCi0gKiBjbGFzcywgb3IgbXVzdCBiZSBidWlsdCBieSA8ZW0+Yml0d2lzZSBPUjwvZW0+J2luZyB0b2dldGhlciAKLSAqICh0aGF0IGlzLCB1c2luZyB0aGUgPGNvZGU+aW50PC9jb2RlPiAifCIgb3BlcmF0b3IpIHR3byBvciBtb3JlCi0gKiBvZiB0aG9zZSA8Y29kZT5TV1Q8L2NvZGU+IHN0eWxlIGNvbnN0YW50cy4gVGhlIGNsYXNzIGRlc2NyaXB0aW9uCi0gKiBsaXN0cyB0aGUgc3R5bGUgY29uc3RhbnRzIHRoYXQgYXJlIGFwcGxpY2FibGUgdG8gdGhlIGNsYXNzLgotICogU3R5bGUgYml0cyBhcmUgYWxzbyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIGNvbXBvc2l0ZSBjb250cm9sIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqIEBwYXJhbSBzdHlsZSB0aGUgc3R5bGUgb2YgY29udHJvbCB0byBjb25zdHJ1Y3QKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU1dUI0JPUkRFUgotICogQHNlZSBXaWRnZXQjY2hlY2tTdWJjbGFzcwotICogQHNlZSBXaWRnZXQjZ2V0U3R5bGUKLSAqLworCiBwdWJsaWMgQ29udHJvbCAoQ29tcG9zaXRlIHBhcmVudCwgaW50IHN0eWxlKSB7CiAJc3VwZXIgKHBhcmVudCwgc3R5bGUpOwogCXRoaXMucGFyZW50ID0gcGFyZW50OwotCWNyZWF0ZVdpZGdldCAoMCk7CisJY3JlYXRlV2lkZ2V0ICgpOwogfQotLyoqCi0gKiBBZGRzIHRoZSBsaXN0ZW5lciB0byB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGNvbnRyb2wgaXMgbW92ZWQgb3IgcmVzaXplZCwgYnkgc2VuZGluZwotICogaXQgb25lIG9mIHRoZSBtZXNzYWdlcyBkZWZpbmVkIGluIHRoZSA8Y29kZT5Db250cm9sTGlzdGVuZXI8L2NvZGU+Ci0gKiBpbnRlcmZhY2UuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBDb250cm9sTGlzdGVuZXIKLSAqIEBzZWUgI3JlbW92ZUNvbnRyb2xMaXN0ZW5lcgotICovCisKIHB1YmxpYyB2b2lkIGFkZENvbnRyb2xMaXN0ZW5lcihDb250cm9sTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwpAQCAtMTAyLDI1ICs1Miw3IEBACiAJYWRkTGlzdGVuZXIgKFNXVC5SZXNpemUsdHlwZWRMaXN0ZW5lcik7CiAJYWRkTGlzdGVuZXIgKFNXVC5Nb3ZlLHR5cGVkTGlzdGVuZXIpOwogfQotLyoqCi0gKiBBZGRzIHRoZSBsaXN0ZW5lciB0byB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGNvbnRyb2wgZ2FpbnMgb3IgbG9zZXMgZm9jdXMsIGJ5IHNlbmRpbmcKLSAqIGl0IG9uZSBvZiB0aGUgbWVzc2FnZXMgZGVmaW5lZCBpbiB0aGUgPGNvZGU+Rm9jdXNMaXN0ZW5lcjwvY29kZT4KLSAqIGludGVyZmFjZS4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIEZvY3VzTGlzdGVuZXIKLSAqIEBzZWUgI3JlbW92ZUZvY3VzTGlzdGVuZXIKLSAqLworCiBwdWJsaWMgdm9pZCBhZGRGb2N1c0xpc3RlbmVyKEZvY3VzTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwpAQCAtMTI4LDUwICs2MCwxNCBAQAogCWFkZExpc3RlbmVyKFNXVC5Gb2N1c0luLHR5cGVkTGlzdGVuZXIpOwogCWFkZExpc3RlbmVyKFNXVC5Gb2N1c091dCx0eXBlZExpc3RlbmVyKTsKIH0KLS8qKgotICogQWRkcyB0aGUgbGlzdGVuZXIgdG8gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIGhlbHAgZXZlbnRzIGFyZSBnZW5lcmF0ZWQgZm9yIHRoZSBjb250cm9sLAotICogYnkgc2VuZGluZyBpdCBvbmUgb2YgdGhlIG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhlCi0gKiA8Y29kZT5IZWxwTGlzdGVuZXI8L2NvZGU+IGludGVyZmFjZS4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIEhlbHBMaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlSGVscExpc3RlbmVyCi0gKi8KKwogcHVibGljIHZvaWQgYWRkSGVscExpc3RlbmVyIChIZWxwTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCVR5cGVkTGlzdGVuZXIgdHlwZWRMaXN0ZW5lciA9IG5ldyBUeXBlZExpc3RlbmVyIChsaXN0ZW5lcik7CiAJYWRkTGlzdGVuZXIgKFNXVC5IZWxwLCB0eXBlZExpc3RlbmVyKTsKIH0KLS8qKgotICogQWRkcyB0aGUgbGlzdGVuZXIgdG8gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIGtleXMgYXJlIHByZXNzZWQgYW5kIHJlbGVhc2VkIG9uIHRoZSBzeXN0ZW0ga2V5Ym9hcmQsIGJ5IHNlbmRpbmcKLSAqIGl0IG9uZSBvZiB0aGUgbWVzc2FnZXMgZGVmaW5lZCBpbiB0aGUgPGNvZGU+S2V5TGlzdGVuZXI8L2NvZGU+Ci0gKiBpbnRlcmZhY2UuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBLZXlMaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlS2V5TGlzdGVuZXIKLSAqLworCiBwdWJsaWMgdm9pZCBhZGRLZXlMaXN0ZW5lcihLZXlMaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC0xNzksMjUgKzc1LDcgQEAKIAlhZGRMaXN0ZW5lcihTV1QuS2V5VXAsdHlwZWRMaXN0ZW5lcik7CiAJYWRkTGlzdGVuZXIoU1dULktleURvd24sdHlwZWRMaXN0ZW5lcik7CiB9Ci0vKioKLSAqIEFkZHMgdGhlIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiBtb3VzZSBidXR0b25zIGFyZSBwcmVzc2VkIGFuZCByZWxlYXNlZCwgYnkgc2VuZGluZwotICogaXQgb25lIG9mIHRoZSBtZXNzYWdlcyBkZWZpbmVkIGluIHRoZSA8Y29kZT5Nb3VzZUxpc3RlbmVyPC9jb2RlPgotICogaW50ZXJmYWNlLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgTW91c2VMaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlTW91c2VMaXN0ZW5lcgotICovCisKIHB1YmxpYyB2b2lkIGFkZE1vdXNlTGlzdGVuZXIoTW91c2VMaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC0yMDYsMjUgKzg0LDcgQEAKIAlhZGRMaXN0ZW5lcihTV1QuTW91c2VVcCx0eXBlZExpc3RlbmVyKTsKIAlhZGRMaXN0ZW5lcihTV1QuTW91c2VEb3VibGVDbGljayx0eXBlZExpc3RlbmVyKTsKIH0KLS8qKgotICogQWRkcyB0aGUgbGlzdGVuZXIgdG8gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSBtb3VzZSBwYXNzZXMgb3IgaG92ZXJzIG92ZXIgY29udHJvbHMsIGJ5IHNlbmRpbmcKLSAqIGl0IG9uZSBvZiB0aGUgbWVzc2FnZXMgZGVmaW5lZCBpbiB0aGUgPGNvZGU+TW91c2VUcmFja0xpc3RlbmVyPC9jb2RlPgotICogaW50ZXJmYWNlLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgTW91c2VUcmFja0xpc3RlbmVyCi0gKiBAc2VlICNyZW1vdmVNb3VzZVRyYWNrTGlzdGVuZXIKLSAqLworCiBwdWJsaWMgdm9pZCBhZGRNb3VzZVRyYWNrTGlzdGVuZXIgKE1vdXNlVHJhY2tMaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC0yMzMsMTQ1ICs5MywzMiBAQAogCWFkZExpc3RlbmVyIChTV1QuTW91c2VFeGl0LHR5cGVkTGlzdGVuZXIpOwogCWFkZExpc3RlbmVyIChTV1QuTW91c2VIb3Zlcix0eXBlZExpc3RlbmVyKTsKIH0KLS8qKgotICogQWRkcyB0aGUgbGlzdGVuZXIgdG8gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSBtb3VzZSBtb3ZlcywgYnkgc2VuZGluZyBpdCBvbmUgb2YgdGhlCi0gKiBtZXNzYWdlcyBkZWZpbmVkIGluIHRoZSA8Y29kZT5Nb3VzZU1vdmVMaXN0ZW5lcjwvY29kZT4KLSAqIGludGVyZmFjZS4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIE1vdXNlTW92ZUxpc3RlbmVyCi0gKiBAc2VlICNyZW1vdmVNb3VzZU1vdmVMaXN0ZW5lcgotICovCisKIHB1YmxpYyB2b2lkIGFkZE1vdXNlTW92ZUxpc3RlbmVyKE1vdXNlTW92ZUxpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlUeXBlZExpc3RlbmVyIHR5cGVkTGlzdGVuZXIgPSBuZXcgVHlwZWRMaXN0ZW5lciAobGlzdGVuZXIpOwogCWFkZExpc3RlbmVyKFNXVC5Nb3VzZU1vdmUsdHlwZWRMaXN0ZW5lcik7CiB9Ci0vKioKLSAqIEFkZHMgdGhlIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgcmVjZWl2ZXIgbmVlZHMgdG8gYmUgcGFpbnRlZCwgYnkgc2VuZGluZyBpdAotICogb25lIG9mIHRoZSBtZXNzYWdlcyBkZWZpbmVkIGluIHRoZSA8Y29kZT5QYWludExpc3RlbmVyPC9jb2RlPgotICogaW50ZXJmYWNlLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgUGFpbnRMaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlUGFpbnRMaXN0ZW5lcgotICovCisKIHB1YmxpYyB2b2lkIGFkZFBhaW50TGlzdGVuZXIoUGFpbnRMaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJVHlwZWRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IFR5cGVkTGlzdGVuZXIgKGxpc3RlbmVyKTsKIAlhZGRMaXN0ZW5lcihTV1QuUGFpbnQsdHlwZWRMaXN0ZW5lcik7CiB9Ci0vKioKLSAqIEFkZHMgdGhlIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0cmF2ZXJzYWwgZXZlbnRzIG9jY3VyLCBieSBzZW5kaW5nIGl0Ci0gKiBvbmUgb2YgdGhlIG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhlIDxjb2RlPlRyYXZlcnNlTGlzdGVuZXI8L2NvZGU+Ci0gKiBpbnRlcmZhY2UuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBUcmF2ZXJzZUxpc3RlbmVyCi0gKiBAc2VlICNyZW1vdmVUcmF2ZXJzZUxpc3RlbmVyCi0gKi8KKwogcHVibGljIHZvaWQgYWRkVHJhdmVyc2VMaXN0ZW5lciAoVHJhdmVyc2VMaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJVHlwZWRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IFR5cGVkTGlzdGVuZXIgKGxpc3RlbmVyKTsKIAlhZGRMaXN0ZW5lciAoU1dULlRyYXZlcnNlLHR5cGVkTGlzdGVuZXIpOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBwcmVmZXJyZWQgc2l6ZSBvZiB0aGUgcmVjZWl2ZXIuCi0gKiA8cD4KLSAqIFRoZSA8ZW0+cHJlZmVycmVkIHNpemU8L2VtPiBvZiBhIGNvbnRyb2wgaXMgdGhlIHNpemUgdGhhdCBpdCB3b3VsZAotICogYmVzdCBiZSBkaXNwbGF5ZWQgYXQuIFRoZSB3aWR0aCBoaW50IGFuZCBoZWlnaHQgaGludCBhcmd1bWVudHMKLSAqIGFsbG93IHRoZSBjYWxsZXIgdG8gYXNrIGEgY29udHJvbCBxdWVzdGlvbnMgc3VjaCBhcyAiR2l2ZW4gYSBwYXJ0aWN1bGFyCi0gKiB3aWR0aCwgaG93IGhpZ2ggZG9lcyB0aGUgY29udHJvbCBuZWVkIHRvIGJlIHRvIHNob3cgYWxsIG9mIHRoZSBjb250ZW50cz8iCi0gKiBUbyBpbmRpY2F0ZSB0aGF0IHRoZSBjYWxsZXIgZG9lcyBub3Qgd2lzaCB0byBjb25zdHJhaW4gYSBwYXJ0aWN1bGFyIAotICogZGltZW5zaW9uLCB0aGUgY29uc3RhbnQgPGNvZGU+U1dULkRFRkFVTFQ8L2NvZGU+IGlzIHBhc3NlZCBmb3IgdGhlIGhpbnQuIAotICogPC9wPgotICoKLSAqIEBwYXJhbSB3SGludCB0aGUgd2lkdGggaGludCAoY2FuIGJlIDxjb2RlPlNXVC5ERUZBVUxUPC9jb2RlPikKLSAqIEBwYXJhbSBoSGludCB0aGUgaGVpZ2h0IGhpbnQgKGNhbiBiZSA8Y29kZT5TV1QuREVGQVVMVDwvY29kZT4pCi0gKiBAcmV0dXJuIHRoZSBwcmVmZXJyZWQgc2l6ZSBvZiB0aGUgY29udHJvbAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIExheW91dAotICogQHNlZSAjZ2V0Qm9yZGVyV2lkdGgKLSAqIEBzZWUgI2dldEJvdW5kcwotICogQHNlZSAjZ2V0U2l6ZQotICogQHNlZSAjcGFjawotICogQHNlZSAiY29tcHV0ZVRyaW0sIGdldENsaWVudEFyZWEgZm9yIGNvbnRyb2xzIHRoYXQgaW1wbGVtZW50IHRoZW0iCi0gKi8KKwogcHVibGljIFBvaW50IGNvbXB1dGVTaXplIChpbnQgd0hpbnQsIGludCBoSGludCkgewogCXJldHVybiBjb21wdXRlU2l6ZSAod0hpbnQsIGhIaW50LCB0cnVlKTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgcHJlZmVycmVkIHNpemUgb2YgdGhlIHJlY2VpdmVyLgotICogPHA+Ci0gKiBUaGUgPGVtPnByZWZlcnJlZCBzaXplPC9lbT4gb2YgYSBjb250cm9sIGlzIHRoZSBzaXplIHRoYXQgaXQgd291bGQKLSAqIGJlc3QgYmUgZGlzcGxheWVkIGF0LiBUaGUgd2lkdGggaGludCBhbmQgaGVpZ2h0IGhpbnQgYXJndW1lbnRzCi0gKiBhbGxvdyB0aGUgY2FsbGVyIHRvIGFzayBhIGNvbnRyb2wgcXVlc3Rpb25zIHN1Y2ggYXMgIkdpdmVuIGEgcGFydGljdWxhcgotICogd2lkdGgsIGhvdyBoaWdoIGRvZXMgdGhlIGNvbnRyb2wgbmVlZCB0byBiZSB0byBzaG93IGFsbCBvZiB0aGUgY29udGVudHM/IgotICogVG8gaW5kaWNhdGUgdGhhdCB0aGUgY2FsbGVyIGRvZXMgbm90IHdpc2ggdG8gY29uc3RyYWluIGEgcGFydGljdWxhciAKLSAqIGRpbWVuc2lvbiwgdGhlIGNvbnN0YW50IDxjb2RlPlNXVC5ERUZBVUxUPC9jb2RlPiBpcyBwYXNzZWQgZm9yIHRoZSBoaW50LiAKLSAqIDwvcD48cD4KLSAqIElmIHRoZSBjaGFuZ2VkIGZsYWcgaXMgPGNvZGU+dHJ1ZTwvY29kZT4sIGl0IGluZGljYXRlcyB0aGF0IHRoZSByZWNlaXZlcidzCi0gKiA8ZW0+Y29udGVudHM8L2VtPiBoYXZlIGNoYW5nZWQsIHRoZXJlZm9yZSBhbnkgY2FjaGVzIHRoYXQgYSBsYXlvdXQgbWFuYWdlcgotICogY29udGFpbmluZyB0aGUgY29udHJvbCBtYXkgaGF2ZSBiZWVuIGtlZXBpbmcgbmVlZCB0byBiZSBmbHVzaGVkLiBXaGVuIHRoZQotICogY29udHJvbCBpcyByZXNpemVkLCB0aGUgY2hhbmdlZCBmbGFnIHdpbGwgYmUgPGNvZGU+ZmFsc2U8L2NvZGU+LCBzbyBsYXlvdXQKLSAqIG1hbmFnZXIgY2FjaGVzIGNhbiBiZSByZXRhaW5lZC4gCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHdIaW50IHRoZSB3aWR0aCBoaW50IChjYW4gYmUgPGNvZGU+U1dULkRFRkFVTFQ8L2NvZGU+KQotICogQHBhcmFtIGhIaW50IHRoZSBoZWlnaHQgaGludCAoY2FuIGJlIDxjb2RlPlNXVC5ERUZBVUxUPC9jb2RlPikKLSAqIEBwYXJhbSBjaGFuZ2VkIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjb250cm9sJ3MgY29udGVudHMgaGF2ZSBjaGFuZ2VkLCBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZQotICogQHJldHVybiB0aGUgcHJlZmVycmVkIHNpemUgb2YgdGhlIGNvbnRyb2wuCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgTGF5b3V0Ci0gKiBAc2VlICNnZXRCb3JkZXJXaWR0aAotICogQHNlZSAjZ2V0Qm91bmRzCi0gKiBAc2VlICNnZXRTaXplCi0gKiBAc2VlICNwYWNrCi0gKiBAc2VlICJjb21wdXRlVHJpbSwgZ2V0Q2xpZW50QXJlYSBmb3IgY29udHJvbHMgdGhhdCBpbXBsZW1lbnQgdGhlbSIKLSAqLworCiBwdWJsaWMgUG9pbnQgY29tcHV0ZVNpemUgKGludCB3SGludCwgaW50IGhIaW50LCBib29sZWFuIGNoYW5nZWQpIHsKIAljaGVja1dpZGdldCgpOwogCWludCB3aWR0aCA9IERFRkFVTFRfV0lEVEg7CkBAIC00MTMsMTM4ICsxNjAsNjAgQEAKIAlyZXR1cm4gcGFyZW50LmNvbXB1dGVUYWJSb290ICgpOwogfQogCi12b2lkIGNyZWF0ZVdpZGdldCAoaW50IGluZGV4KSB7Ci0Jc3VwZXIuY3JlYXRlV2lkZ2V0IChpbmRleCk7Ci0JZm9yZWdyb3VuZCA9IGJhY2tncm91bmQgPSAtMTsKLQotCS8qCi0JKiBGZWF0dXJlIGluIE1vdGlmLiAgV2hlbiB0aGUgWG1OZm9udExpc3QgcmVzb3VyY2UgaXMgc2V0IGZvcgotCSogYSB3aWRnZXQsIE1vdGlmIGNyZWF0ZXMgYSBjb3B5IG9mIHRoZSBmb250TGlzdCBhbmQgZGlzcG9zZXMKLQkqIHRoZSBjb3B5IHdoZW4gdGhlIHdpZGdldCBpcyBkaXNwb3NlZC4gIFRoaXMgbWVhbnMgdGhhdCB3aGVuCi0JKiB0aGUgcHJvZ3JhbW1lciBxdWVyaWVzIHRoZSBmb250LCBub3Qgb25seSB3aWxsIHRoZSBoYW5kbGUgYmUKLQkqIGRpZmZlcmVudCBidXQgdGhlIGZvbnQgd2lsbCBiZSB1bmV4cGVjdGVkbHkgZGlzcG9zZWQgd2hlbgotCSogdGhlIHdpZGdldCBpcyBkaXNwb3NlZC4gIFRoaXMgY2FuIGNhdXNlIEdQJ3Mgd2hlbiB0aGUgZm9udAotCSogaXMgc2V0IGluIGFub3RoZXIgd2lkZ2V0LiAgVGhlIGZpeCBpcyB0byBjYWNoZSB0aGUgZm9udCB0aGUKLQkqIHRoZSBwcm9ncmFtbWVyIHByb3ZpZGVzLiAgVGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIGNhY2hlIGlzCi0JKiB0aGUgZGVmYXVsdCBmb250IGZvciB0aGUgd2lkZ2V0LgotCSovCi0JZm9udCA9IGRlZmF1bHRGb250ICgpOwotCi0JLyoKLQkqIEV4cGxpY2l0bHkgc2V0IHRoZSB0YWIgb3JkZXJpbmcgZm9yIFhtVEFCX0dST1VQIHdpZGdldHMgdG8KLQkqIG92ZXJyaWRlIHRoZSBkZWZhdWx0IHRyYXZlcnNhbC4gIFRoaXMgaXMgZG9uZSBzbyB0aGF0IHRoZQotCSogdHJhdmVyc2FsIG9yZGVyIGNhbiBiZSBjaGFuZ2VkIGFmdGVyIHRoZSB3aWRnZXQgdHJlZSBpcwotCSogY3JlYXRlZC4gIFVubGVzcyBleHBsaWNpdGx5IGNoYW5nZWQsIHRoZSBvdmVycmlkZGVkIHRyYXZlcnNhbAotCSogb3JkZXIgaXMgdGhlIHNhbWUgYXMgdGhlIGRlZmF1bHQuCi0JKi8KLSAgICAvKiBBVwotCWludCBbXSBhcmdMaXN0MSA9IG5ldyBpbnQgW10ge09TLlhtTm5hdmlnYXRpb25UeXBlLCAwfTsKLQlPUy5YdEdldFZhbHVlcyAoaGFuZGxlLCBhcmdMaXN0MSwgYXJnTGlzdDEubGVuZ3RoIC8gMik7Ci0JaWYgKGFyZ0xpc3QxIFsxXSA9PSBPUy5YbVRBQl9HUk9VUCkgewotCQlpbnQgW10gYXJnTGlzdDIgPSBuZXcgaW50IFtdIHtPUy5YbU5uYXZpZ2F0aW9uVHlwZSwgT1MuWG1FWENMVVNJVkVfVEFCX0dST1VQfTsKLQkJT1MuWHRTZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdDIsIGFyZ0xpc3QyLmxlbmd0aCAvIDIpOwotCX0KLSAgICAqLwordm9pZCBjcmVhdGVXaWRnZXQgKCkgeworCXN1cGVyLmNyZWF0ZVdpZGdldCAoKTsKKwlzZXRaT3JkZXIgKCk7CiB9Ci1pbnQgZGVmYXVsdEJhY2tncm91bmQgKCkgewotCXJldHVybiBnZXREaXNwbGF5ICgpLmRlZmF1bHRCYWNrZ3JvdW5kOwotfQorCiBGb250IGRlZmF1bHRGb250ICgpIHsKLQlyZXR1cm4gZ2V0RGlzcGxheSAoKS5kZWZhdWx0Rm9udDsKKwlieXRlIFtdIGZhbWlseSA9IG5ldyBieXRlIFsyNTZdOworCXNob3J0IFtdIHNpemUgPSBuZXcgc2hvcnQgWzFdOworCWJ5dGUgW10gc3R5bGUgPSBuZXcgYnl0ZSBbMV07CisJT1MuR2V0VGhlbWVGb250ICgoc2hvcnQpIGRlZmF1bHRUaGVtZUZvbnQgKCksIChzaG9ydCkgT1Muc21TeXN0ZW1TY3JpcHQsIGZhbWlseSwgc2l6ZSwgc3R5bGUpOworCXNob3J0IGlkID0gT1MuRk1HZXRGb250RmFtaWx5RnJvbU5hbWUgKGZhbWlseSk7CisJaW50IFtdIGZvbnQgPSBuZXcgaW50IFsxXTsgCisJT1MuRk1HZXRGb250RnJvbUZvbnRGYW1pbHlJbnN0YW5jZSAoaWQsIHN0eWxlIFswXSwgZm9udCwgbnVsbCk7CisJcmV0dXJuIEZvbnQuY2FyYm9uX25ldyAoZ2V0RGlzcGxheSAoKSwgZm9udCBbMF0sIGlkLCBzdHlsZSBbMF0sIHNpemUgWzBdKTsKIH0KLWludCBkZWZhdWx0Rm9yZWdyb3VuZCAoKSB7Ci0JcmV0dXJuIGdldERpc3BsYXkgKCkuZGVmYXVsdEZvcmVncm91bmQ7CisKK2ludCBkZWZhdWx0VGhlbWVGb250ICgpIHsJCisJcmV0dXJuIE9TLmtUaGVtZVN5c3RlbUZvbnQ7CiB9Ci12b2lkIGVuYWJsZVdpZGdldCAoYm9vbGVhbiBlbmFibGVkKSB7Ci0JZW5hYmxlSGFuZGxlIChlbmFibGVkLCBoYW5kbGUpOworCit2b2lkIGRlcmVnaXN0ZXIgKCkgeworCXN1cGVyLmRlcmVnaXN0ZXIgKCk7CisJV2lkZ2V0VGFibGUucmVtb3ZlIChoYW5kbGUpOwogfQotY2hhciBmaW5kTW5lbW9uaWMgKFN0cmluZyBzdHJpbmcpIHsKLQlpbnQgaW5kZXggPSAwOwotCWludCBsZW5ndGggPSBzdHJpbmcubGVuZ3RoICgpOwotCWRvIHsKLQkJd2hpbGUgKChpbmRleCA8IGxlbmd0aCkgJiYgKHN0cmluZy5jaGFyQXQgKGluZGV4KSAhPSBNbmVtb25pYykpIGluZGV4Kys7Ci0JCWlmICgrK2luZGV4ID49IGxlbmd0aCkgcmV0dXJuICdcMCc7Ci0JCWlmIChzdHJpbmcuY2hhckF0IChpbmRleCkgIT0gTW5lbW9uaWMpIHJldHVybiBzdHJpbmcuY2hhckF0IChpbmRleCk7Ci0JCWluZGV4Kys7Ci0JfSB3aGlsZSAoaW5kZXggPCBsZW5ndGgpOwotIAlyZXR1cm4gJ1wwJzsKKwordm9pZCBkZXN0cm95V2lkZ2V0ICgpIHsKKwlpbnQgdGhlQ29udHJvbCA9IHRvcEhhbmRsZSAoKTsKKwlyZWxlYXNlSGFuZGxlICgpOworCWlmICh0aGVDb250cm9sICE9IDApIHsKKwkJT1MuRGlzcG9zZUNvbnRyb2wgKHRoZUNvbnRyb2wpOworCX0KIH0KLWludCBmb250SGFuZGxlICgpIHsKLQlyZXR1cm4gaGFuZGxlOworCitDdXJzb3IgZmluZEN1cnNvciAoKSB7CisJaWYgKGN1cnNvciAhPSBudWxsKSByZXR1cm4gY3Vyc29yOworCXJldHVybiBwYXJlbnQuZmluZEN1cnNvciAoKTsKIH0KLS8qKgotICogRm9yY2VzIHRoZSByZWNlaXZlciB0byBoYXZlIHRoZSA8ZW0+a2V5Ym9hcmQgZm9jdXM8L2VtPiwgY2F1c2luZwotICogYWxsIGtleWJvYXJkIGV2ZW50cyB0byBiZSBkZWxpdmVyZWQgdG8gaXQuCi0gKgotICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY29udHJvbCBnb3QgZm9jdXMsIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gaWYgaXQgd2FzIHVuYWJsZSB0by4KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjc2V0Rm9jdXMKLSAqLworCit2b2lkIGZpeEZvY3VzICgpIHsKKwlTaGVsbCBzaGVsbCA9IGdldFNoZWxsICgpOworCUNvbnRyb2wgY29udHJvbCA9IHRoaXM7CisJd2hpbGUgKChjb250cm9sID0gY29udHJvbC5wYXJlbnQpICE9IG51bGwpIHsKKwkJaWYgKGNvbnRyb2wuc2V0Rm9jdXMgKCkgfHwgY29udHJvbCA9PSBzaGVsbCkgcmV0dXJuOworCX0KKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChoYW5kbGUpOworCU9TLkNsZWFyS2V5Ym9hcmRGb2N1cyAod2luZG93KTsKK30KKwogcHVibGljIGJvb2xlYW4gZm9yY2VGb2N1cyAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlEZWNvcmF0aW9ucyBzaGVsbCA9IG1lbnVTaGVsbCAoKTsKLQlzaGVsbC5zZXRTYXZlZEZvY3VzICh0aGlzKTsKLQlpZiAoIWlzRW5hYmxlZCAoKSB8fCAhaXNWaXNpYmxlICgpIC8qIEFXIHx8ICFpc0FjdGl2ZSAoKSAqLykgcmV0dXJuIGZhbHNlOwotCWlmIChpc0ZvY3VzQ29udHJvbCAoKSkgcmV0dXJuIHRydWU7Ci0Jc2hlbGwuYnJpbmdUb1RvcCAoKTsKLQkvKgotCSogVGhpcyBjb2RlIGlzIGludGVudGlvbmFsbHkgY29tbWVudGVkLgotCSoKLQkqIFdoZW4gc2V0dGluZyBmb2N1cyB0byBhIGNvbnRyb2wsIGl0IGlzCi0JKiBwb3NzaWJsZSB0aGF0IGFwcGxpY2F0aW9uIGNvZGUgY2FuIHNldAotCSogdGhlIGZvY3VzIHRvIGFub3RoZXIgY29udHJvbCBpbnNpZGUgb2YKLQkqIFdNX1NFVEZPQ1VTLiAgSW4gdGhpcyBjYXNlLCB0aGUgb3JpZ2luYWwKLQkqIGNvbnRyb2wgd2lsbCBubyBsb25nZXIgaGF2ZSB0aGUgZm9jdXMKLQkqIGFuZCB0aGUgY2FsbCB0byBzZXRGb2N1cygpIHdpbGwgcmV0dXJuCi0JKiBmYWxzZSBpbmRpY2F0aW5nIGZhaWx1cmUuCi0JKiAKLQkqIFdlIGFyZSBzdGlsbCB3b3JraW5nIG9uIGEgc29sdXRpb24gYXQKLQkqIHRoaXMgdGltZS4KLQkqLwotLy8JaWYgKE9TLkdldEZvY3VzICgpICE9IE9TLlNldEZvY3VzIChoYW5kbGUpKSByZXR1cm4gZmFsc2U7Ci0JCQotCS8qIEFXCi0JT1MuU2V0Rm9jdXMgKGhhbmRsZSk7Ci0JKi8KLQkKLQlib29sZWFuIGZvY3VzPSBmYWxzZTsKLQkKLQlpZiAodGhpcyBpbnN0YW5jZW9mIFRleHQgfHwgdGhpcyBpbnN0YW5jZW9mIExpc3QgfHwgdGhpcyBpbnN0YW5jZW9mIENvbWJvIHx8IHRoaXMgaW5zdGFuY2VvZiBDYW52YXMpCi0JCWZvY3VzPSB0cnVlOwotCWlmICghZm9jdXMgJiYgTWFjVXRpbC5GVUxMX0tCRF9OQVYgJiYgdGhpcyBpbnN0YW5jZW9mIEJ1dHRvbikKLQkJZm9jdXM9IHRydWU7Ci0JCi0JaWYgKGZvY3VzKSB7Ci0JCURpc3BsYXkgZGlzcGxheT0gZ2V0RGlzcGxheSgpOwotCQlpZiAoZGlzcGxheSAhPSBudWxsKQotCQkJZGlzcGxheS5zZXRNYWNGb2N1c0hhbmRsZSgoKFNoZWxsKXNoZWxsKS5zaGVsbEhhbmRsZSwgaGFuZGxlKTsKLQl9Ci0KLQlyZXR1cm4gaXNGb2N1c0NvbnRyb2wgKCk7CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAoaGFuZGxlKTsKKwlyZXR1cm4gT1MuU2V0S2V5Ym9hcmRGb2N1cyAod2luZG93LCBoYW5kbGUsIChzaG9ydClPUy5rQ29udHJvbEZvY3VzTmV4dFBhcnQpID09IE9TLm5vRXJyOwogfQogCi0vKioKLSAqIFJldHVybnMgdGhlIGFjY2Vzc2libGUgb2JqZWN0IGZvciB0aGUgcmVjZWl2ZXIuCi0gKiBJZiB0aGlzIGlzIHRoZSBmaXJzdCB0aW1lIHRoaXMgb2JqZWN0IGlzIHJlcXVlc3RlZCwKLSAqIHRoZW4gdGhlIG9iamVjdCBpcyBjcmVhdGVkIGFuZCByZXR1cm5lZC4KLSAqCi0gKiBAcmV0dXJuIHRoZSBhY2Nlc3NpYmxlIG9iamVjdAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqIAotICogQHNlZSBBY2Nlc3NpYmxlI2FkZEFjY2Vzc2libGVMaXN0ZW5lcgotICogQHNlZSBBY2Nlc3NpYmxlI2FkZEFjY2Vzc2libGVDb250cm9sTGlzdGVuZXIKLSAqIAotICogQHNpbmNlIDIuMAotICovCiBwdWJsaWMgQWNjZXNzaWJsZSBnZXRBY2Nlc3NpYmxlICgpIHsKIAljaGVja1dpZGdldCAoKTsKIAlpZiAoYWNjZXNzaWJsZSA9PSBudWxsKSB7CkBAIC01NTIsMjc0ICsyMjEsNjkgQEAKIAl9CiAJcmV0dXJuIGFjY2Vzc2libGU7CiB9Ci0KLS8qKgotICogUmV0dXJucyB0aGUgcmVjZWl2ZXIncyBiYWNrZ3JvdW5kIGNvbG9yLgotICoKLSAqIEByZXR1cm4gdGhlIGJhY2tncm91bmQgY29sb3IKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwkKIHB1YmxpYyBDb2xvciBnZXRCYWNrZ3JvdW5kICgpIHsKIAljaGVja1dpZGdldCgpOwotCXJldHVybiBDb2xvci5jYXJib25fbmV3IChnZXREaXNwbGF5ICgpLCBnZXRCYWNrZ3JvdW5kUGl4ZWwgKCksIGZhbHNlKTsKKwkvL1dST05HCisJaWYgKGJhY2tncm91bmQgPT0gbnVsbCkgcmV0dXJuIGdldERpc3BsYXkgKCkuZ2V0U3lzdGVtQ29sb3IgKFNXVC5DT0xPUl9XSElURSk7CisJcmV0dXJuIENvbG9yLmNhcmJvbl9uZXcgKGdldERpc3BsYXkgKCksIGJhY2tncm91bmQpOwogfQotaW50IGdldEJhY2tncm91bmRQaXhlbCAoKSB7Ci0vKiBBVwotCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTmJhY2tncm91bmQsIDB9OwotCU9TLlh0R2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JcmV0dXJuIGFyZ0xpc3QgWzFdOwotKi8KLQlpZiAoYmFja2dyb3VuZCA9PSAtMSkgcmV0dXJuIGRlZmF1bHRCYWNrZ3JvdW5kICgpOwotCXJldHVybiBiYWNrZ3JvdW5kOwotfQotLyoqCi0gKiBSZXR1cm5zIHRoZSByZWNlaXZlcidzIGJvcmRlciB3aWR0aC4KLSAqCi0gKiBAcmV0dXJuIHRoZSBib3JkZXIgd2lkdGgKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGludCBnZXRCb3JkZXJXaWR0aCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLSAgICAvKiBBVwotCWludCB0b3BIYW5kbGUgPSB0b3BIYW5kbGUgKCk7Ci0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1OYm9yZGVyV2lkdGgsIDB9OwotCU9TLlh0R2V0VmFsdWVzICh0b3BIYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JcmV0dXJuIGFyZ0xpc3QgWzFdOwotICAgICovCiAgICAgcmV0dXJuIDA7CiB9Ci0vKioKLSAqIFJldHVybnMgYSByZWN0YW5nbGUgZGVzY3JpYmluZyB0aGUgcmVjZWl2ZXIncyBzaXplIGFuZCBsb2NhdGlvbgotICogcmVsYXRpdmUgdG8gaXRzIHBhcmVudCAob3IgaXRzIGRpc3BsYXkgaWYgaXRzIHBhcmVudCBpcyBudWxsKS4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGJvdW5kaW5nIHJlY3RhbmdsZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgUmVjdGFuZ2xlIGdldEJvdW5kcyAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpbnQgdG9wSGFuZGxlID0gdG9wSGFuZGxlICgpOwotICAgIC8qIEFXCi0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1OeCwgMCwgT1MuWG1OeSwgMCwgT1MuWG1Od2lkdGgsIDAsIE9TLlhtTmhlaWdodCwgMCwgT1MuWG1OYm9yZGVyV2lkdGgsIDB9OwotCU9TLlh0R2V0VmFsdWVzICh0b3BIYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JaW50IGJvcmRlcnMgPSBhcmdMaXN0IFs5XSAqIDI7Ci0JcmV0dXJuIG5ldyBSZWN0YW5nbGUgKChzaG9ydCkgYXJnTGlzdCBbMV0sIChzaG9ydCkgYXJnTGlzdCBbM10sIGFyZ0xpc3QgWzVdICsgYm9yZGVycywgYXJnTGlzdCBbN10gKyBib3JkZXJzKTsKLSAgICAqLwotICAgIGlmIChNYWNVdGlsLlVTRV9GUkFNRSkgewotCQlNYWNSZWN0IGJyPSBuZXcgTWFjUmVjdCgpOwotCQlpbnRlcm5hbEdldENvbnRyb2xCb3VuZHModG9wSGFuZGxlLCBicik7Ci0JCXJldHVybiBici50b1JlY3RhbmdsZSgpOwotICAgfSBlbHNlIHsKLQkgICAgTWFjUmVjdCBicj0gbmV3IE1hY1JlY3QoKTsKLQkJc2hvcnRbXSBib3VuZHM9IGJyLmdldERhdGEoKTsKLQkJc2hvcnRbXSBwYm91bmRzPSBuZXcgc2hvcnRbNF07Ci0JCWludGVybmFsR2V0Q29udHJvbEJvdW5kcyh0b3BIYW5kbGUsIGJyKTsKLQkJT1MuR2V0Q29udHJvbEJvdW5kcyhwYXJlbnQuaGFuZGxlLCBwYm91bmRzKTsKLQkJcmV0dXJuIG5ldyBSZWN0YW5nbGUoYm91bmRzWzFdLXBib3VuZHNbMV0sIGJvdW5kc1swXS1wYm91bmRzWzBdLCBib3VuZHNbM10tYm91bmRzWzFdLCBib3VuZHNbMl0tYm91bmRzWzBdKTsKLSAgICB9CisJUmVjdCByZWN0ID0gZ2V0Q29udHJvbEJvdW5kcyAodG9wSGFuZGxlICgpKTsKKwlyZXR1cm4gbmV3IFJlY3RhbmdsZSAocmVjdC5sZWZ0LCByZWN0LnRvcCwgcmVjdC5yaWdodCAtIHJlY3QubGVmdCwgcmVjdC5ib3R0b20gLSByZWN0LnRvcCk7CiB9Ci1Qb2ludCBnZXRDbGllbnRMb2NhdGlvbiAoKSB7Ci0gICAgLyogQVcKLQlzaG9ydCBbXSBoYW5kbGVfeCA9IG5ldyBzaG9ydCBbMV0sIGhhbmRsZV95ID0gbmV3IHNob3J0IFsxXTsKLQlPUy5YdFRyYW5zbGF0ZUNvb3JkcyAoaGFuZGxlLCAoc2hvcnQpIDAsIChzaG9ydCkgMCwgaGFuZGxlX3gsIGhhbmRsZV95KTsKLQlzaG9ydCBbXSB0b3BIYW5kbGVfeCA9IG5ldyBzaG9ydCBbMV0sIHRvcEhhbmRsZV95ID0gbmV3IHNob3J0IFsxXTsKLQlPUy5YdFRyYW5zbGF0ZUNvb3JkcyAocGFyZW50LmhhbmRsZSwgKHNob3J0KSAwLCAoc2hvcnQpIDAsIHRvcEhhbmRsZV94LCB0b3BIYW5kbGVfeSk7Ci0JcmV0dXJuIG5ldyBQb2ludCAoaGFuZGxlX3ggWzBdIC0gdG9wSGFuZGxlX3ggWzBdLCBoYW5kbGVfeSBbMF0gLSB0b3BIYW5kbGVfeSBbMF0pOwotICAgICovCi0Jc2hvcnRbXSBib3VuZHM9IG5ldyBzaG9ydFs0XTsKLQlzaG9ydFtdIHBib3VuZHM9IG5ldyBzaG9ydFs0XTsKLQlPUy5HZXRDb250cm9sQm91bmRzKGhhbmRsZSwgYm91bmRzKTsKLQlPUy5HZXRDb250cm9sQm91bmRzKHBhcmVudC5oYW5kbGUsIHBib3VuZHMpOwotCXJldHVybiBuZXcgUG9pbnQoYm91bmRzWzFdLXBib3VuZHNbMV0sIGJvdW5kc1swXS1wYm91bmRzWzBdKTsKLX0KLS8qKgotICogUmV0dXJucyB0aGUgZGlzcGxheSB0aGF0IHRoZSByZWNlaXZlciB3YXMgY3JlYXRlZCBvbi4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGRpc3BsYXkKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIERpc3BsYXkgZ2V0RGlzcGxheSAoKSB7CiAJQ29tcG9zaXRlIHBhcmVudCA9IHRoaXMucGFyZW50OwogCWlmIChwYXJlbnQgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9XSURHRVRfRElTUE9TRUQpOwogCXJldHVybiBwYXJlbnQuZ2V0RGlzcGxheSAoKTsKIH0KLS8qKgotICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVjZWl2ZXIgaXMgZW5hYmxlZCwgYW5kCi0gKiA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLiBBIGRpc2FibGVkIGNvbnRyb2wgaXMgdHlwaWNhbGx5Ci0gKiBub3Qgc2VsZWN0YWJsZSBmcm9tIHRoZSB1c2VyIGludGVyZmFjZSBhbmQgZHJhd3Mgd2l0aCBhbgotICogaW5hY3RpdmUgb3IgImdyYXllZCIgbG9vay4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGVuYWJsZWQgc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGJvb2xlYW4gZ2V0RW5hYmxlZCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpbnQgaD0gdG9wSGFuZGxlKCk7Ci0JaWYgKE9TLklzVmFsaWRDb250cm9sSGFuZGxlKGgpKQotCQlyZXR1cm4gT1MuSXNDb250cm9sRW5hYmxlZChoKTsKLQlTeXN0ZW0ub3V0LnByaW50bG4oIkNvbnRyb2wuZ2V0RW5hYmxlZDogZml4bWUgZm9yICIgKyBnZXRDbGFzcygpLmdldE5hbWUoKSk7Ci0JcmV0dXJuIHRydWU7CisJcmV0dXJuIChzdGF0ZSAmIERJU0FCTEVEKSA9PSAwOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBmb250IHRoYXQgdGhlIHJlY2VpdmVyIHdpbGwgdXNlIHRvIHBhaW50IHRleHR1YWwgaW5mb3JtYXRpb24uCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBmb250Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBGb250IGdldEZvbnQgKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JcmV0dXJuIGZvbnQ7CisJcmV0dXJuIGZvbnQgIT0gbnVsbCA/IGZvbnQgOiBkZWZhdWx0Rm9udCAoKTsKIH0KIAotaW50IGdldEZvbnRBc2NlbnQgKCkgewotCWludCBvbGRQb3J0PSBPUy5HZXRQb3J0KCk7Ci0JT1MuU2V0UG9ydFdpbmRvd1BvcnQoT1MuR2V0Q29udHJvbE93bmVyKGhhbmRsZSkpOwotCWlmIChmb250ICE9IG51bGwgJiYgZm9udC5oYW5kbGUgIT0gbnVsbCkKLQkJZm9udC5oYW5kbGUuaW5zdGFsbEluR3JhZlBvcnQoKTsKLQlzaG9ydFtdIGZvbnRJbmZvPSBuZXcgc2hvcnRbNF07Ci0JT1MuR2V0Rm9udEluZm8oZm9udEluZm8pOwkvLyBGb250SW5mbwotCWludCBoZWlnaHQ9IGZvbnRJbmZvWzBdOwotCU9TLlNldFBvcnQob2xkUG9ydCk7Ci0JcmV0dXJuIGhlaWdodDsKLX0KLQotaW50IGdldEZvbnRIZWlnaHQgKCkgewotCWludCBvbGRQb3J0PSBPUy5HZXRQb3J0KCk7Ci0JT1MuU2V0UG9ydFdpbmRvd1BvcnQoT1MuR2V0Q29udHJvbE93bmVyKGhhbmRsZSkpOwotCWlmIChmb250ICE9IG51bGwgJiYgZm9udC5oYW5kbGUgIT0gbnVsbCkKLQkJZm9udC5oYW5kbGUuaW5zdGFsbEluR3JhZlBvcnQoKTsKLQlzaG9ydFtdIGZvbnRJbmZvPSBuZXcgc2hvcnRbNF07Ci0JT1MuR2V0Rm9udEluZm8oZm9udEluZm8pOwkvLyBGb250SW5mbwotCWludCBoZWlnaHQ9IGZvbnRJbmZvWzBdICsgZm9udEluZm9bMV07Ci0JT1MuU2V0UG9ydChvbGRQb3J0KTsKLQlyZXR1cm4gaGVpZ2h0OwotfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBmb3JlZ3JvdW5kIGNvbG9yIHRoYXQgdGhlIHJlY2VpdmVyIHdpbGwgdXNlIHRvIGRyYXcuCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBmb3JlZ3JvdW5kIGNvbG9yCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCiBwdWJsaWMgQ29sb3IgZ2V0Rm9yZWdyb3VuZCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlyZXR1cm4gQ29sb3IuY2FyYm9uX25ldyAoZ2V0RGlzcGxheSAoKSwgZ2V0Rm9yZWdyb3VuZFBpeGVsICgpLCBmYWxzZSk7CisJLy9XUk9ORworCWlmIChmb3JlZ3JvdW5kID09IG51bGwpIHJldHVybiBnZXREaXNwbGF5ICgpLmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfQkxBQ0spOworCXJldHVybiBDb2xvci5jYXJib25fbmV3IChnZXREaXNwbGF5ICgpLCBmb3JlZ3JvdW5kKTsKIH0KLWludCBnZXRGb3JlZ3JvdW5kUGl4ZWwgKCkgewotCS8qIEFXCi0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1OZm9yZWdyb3VuZCwgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlyZXR1cm4gYXJnTGlzdCBbMV07Ci0JKi8KLQlpZiAoZm9yZWdyb3VuZCA9PSAtMSkgcmV0dXJuIGRlZmF1bHRGb3JlZ3JvdW5kICgpOwotCXJldHVybiBmb3JlZ3JvdW5kOwotfQotLyogQVcKLXNob3J0IFtdIGdldElNRUNhcmV0UG9zICgpIHsKLQlyZXR1cm4gbmV3IHNob3J0W117MCwgMH07Ci19Ci0qLwotLyoqCi0gKiBSZXR1cm5zIGxheW91dCBkYXRhIHdoaWNoIGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVjZWl2ZXIuCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBsYXlvdXQgZGF0YQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgT2JqZWN0IGdldExheW91dERhdGEgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIGxheW91dERhdGE7CiB9Ci0vKioKLSAqIFJldHVybnMgYSBwb2ludCBkZXNjcmliaW5nIHRoZSByZWNlaXZlcidzIGxvY2F0aW9uIHJlbGF0aXZlCi0gKiB0byBpdHMgcGFyZW50IChvciBpdHMgZGlzcGxheSBpZiBpdHMgcGFyZW50IGlzIG51bGwpLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgbG9jYXRpb24KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIFBvaW50IGdldExvY2F0aW9uICgpIHsKIAljaGVja1dpZGdldCgpOwotCWludCB0b3BIYW5kbGU9IHRvcEhhbmRsZSAoKTsKLQlNYWNSZWN0IGJyPSBuZXcgTWFjUmVjdCgpOwotICAgIGlmIChNYWNVdGlsLlVTRV9GUkFNRSkgewotCQlpbnRlcm5hbEdldENvbnRyb2xCb3VuZHModG9wSGFuZGxlLCBicik7Ci0JCXJldHVybiBici5nZXRMb2NhdGlvbigpOwotICAgIH0gZWxzZSB7Ci0JCXNob3J0W10gYm91bmRzPSBici5nZXREYXRhKCk7Ci0JCXNob3J0W10gcGJvdW5kcz0gbmV3IHNob3J0WzRdOwotCQlpbnRlcm5hbEdldENvbnRyb2xCb3VuZHModG9wSGFuZGxlLCBicik7Ci0JCU9TLkdldENvbnRyb2xCb3VuZHMocGFyZW50LmhhbmRsZSwgcGJvdW5kcyk7Ci0JCXJldHVybiBuZXcgUG9pbnQoYm91bmRzWzFdLXBib3VuZHNbMV0sIGJvdW5kc1swXS1wYm91bmRzWzBdKTsKLSAgICB9CisJUmVjdCByZWN0ID0gZ2V0Q29udHJvbEJvdW5kcyAodG9wSGFuZGxlICgpKTsKKwlyZXR1cm4gbmV3IFBvaW50IChyZWN0LmxlZnQsIHJlY3QudG9wKTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgcmVjZWl2ZXIncyBwb3AgdXAgbWVudSBpZiBpdCBoYXMgb25lLCBvciBudWxsCi0gKiBpZiBpdCBkb2VzIG5vdC4gQWxsIGNvbnRyb2xzIG1heSBvcHRpb25hbGx5IGhhdmUgYSBwb3AgdXAKLSAqIG1lbnUgdGhhdCBpcyBkaXNwbGF5ZWQgd2hlbiB0aGUgdXNlciByZXF1ZXN0cyBvbmUgZm9yCi0gKiB0aGUgY29udHJvbC4gVGhlIHNlcXVlbmNlIG9mIGtleSBzdHJva2VzLCBidXR0b24gcHJlc3NlcwotICogYW5kL29yIGJ1dHRvbiByZWxlYXNlcyB0aGF0IGFyZSB1c2VkIHRvIHJlcXVlc3QgYSBwb3AgdXAKLSAqIG1lbnUgaXMgcGxhdGZvcm0gc3BlY2lmaWMuCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBtZW51Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBNZW51IGdldE1lbnUgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIG1lbnU7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3MgcGFyZW50LCB3aGljaCBtdXN0IGJlIGEgPGNvZGU+Q29tcG9zaXRlPC9jb2RlPgotICogb3IgbnVsbCB3aGVuIHRoZSByZWNlaXZlciBpcyBhIHNoZWxsIHRoYXQgd2FzIGNyZWF0ZWQgd2l0aCBudWxsIG9yCi0gKiBhIGRpc3BsYXkgZm9yIGEgcGFyZW50LgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgcGFyZW50Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBDb21wb3NpdGUgZ2V0UGFyZW50ICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBwYXJlbnQ7CiB9CisKIENvbnRyb2wgW10gZ2V0UGF0aCAoKSB7CiAJaW50IGNvdW50ID0gMDsKIAlTaGVsbCBzaGVsbCA9IGdldFNoZWxsICgpOwpAQCAtODM2LDcxMCArMzAwLDQzNiBAQAogCX0KIAlyZXR1cm4gcmVzdWx0OwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSByZWNlaXZlcidzIHNoZWxsLiBGb3IgYWxsIGNvbnRyb2xzIG90aGVyIHRoYW4KLSAqIHNoZWxscywgdGhpcyBzaW1wbHkgcmV0dXJucyB0aGUgY29udHJvbCdzIG5lYXJlc3QgYW5jZXN0b3IKLSAqIHNoZWxsLiBTaGVsbHMgcmV0dXJuIHRoZW1zZWx2ZXMsIGV2ZW4gaWYgdGhleSBhcmUgY2hpbGRyZW4KLSAqIG9mIG90aGVyIHNoZWxscy4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIHNoZWxsCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI2dldFBhcmVudAotICovCisKIHB1YmxpYyBTaGVsbCBnZXRTaGVsbCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlyZXR1cm4gcGFyZW50LmdldFNoZWxsICgpOwogfQotLyoqCi0gKiBSZXR1cm5zIGEgcG9pbnQgZGVzY3JpYmluZyB0aGUgcmVjZWl2ZXIncyBzaXplLiBUaGUKLSAqIHggY29vcmRpbmF0ZSBvZiB0aGUgcmVzdWx0IGlzIHRoZSB3aWR0aCBvZiB0aGUgcmVjZWl2ZXIuCi0gKiBUaGUgeSBjb29yZGluYXRlIG9mIHRoZSByZXN1bHQgaXMgdGhlIGhlaWdodCBvZiB0aGUKLSAqIHJlY2VpdmVyLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3Mgc2l6ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgUG9pbnQgZ2V0U2l6ZSAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpbnQgdG9wSGFuZGxlID0gdG9wSGFuZGxlICgpOwotCS8qCi0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1Od2lkdGgsIDAsIE9TLlhtTmhlaWdodCwgMCwgT1MuWG1OYm9yZGVyV2lkdGgsIDB9OwotCU9TLlh0R2V0VmFsdWVzICh0b3BIYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JaW50IGJvcmRlcnMgPSBhcmdMaXN0IFs1XSAqIDI7Ci0JcmV0dXJuIG5ldyBQb2ludCAoYXJnTGlzdCBbMV0gKyBib3JkZXJzLCBhcmdMaXN0IFszXSArIGJvcmRlcnMpOwotCSovCi0JTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JaW50ZXJuYWxHZXRDb250cm9sQm91bmRzKHRvcEhhbmRsZSwgYm91bmRzKTsKLQlyZXR1cm4gYm91bmRzLmdldFNpemUoKTsKKwlSZWN0IHJlY3QgPSBnZXRDb250cm9sU2l6ZSAodG9wSGFuZGxlICgpKTsKKwlyZXR1cm4gbmV3IFBvaW50IChyZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0LCByZWN0LmJvdHRvbSAtIHJlY3QudG9wKTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgcmVjZWl2ZXIncyB0b29sIHRpcCB0ZXh0LCBvciBudWxsIGlmIGl0IGhhcwotICogbm90IGJlZW4gc2V0LgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgdG9vbCB0aXAgdGV4dAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgU3RyaW5nIGdldFRvb2xUaXBUZXh0ICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiB0b29sVGlwVGV4dDsKIH0KLS8qKgotICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVjZWl2ZXIgaXMgdmlzaWJsZSwgYW5kCi0gKiA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLgotICogPHA+Ci0gKiBJZiBvbmUgb2YgdGhlIHJlY2VpdmVyJ3MgYW5jZXN0b3JzIGlzIG5vdCB2aXNpYmxlIG9yIHNvbWUKLSAqIG90aGVyIGNvbmRpdGlvbiBtYWtlcyB0aGUgcmVjZWl2ZXIgbm90IHZpc2libGUsIHRoaXMgbWV0aG9kCi0gKiBtYXkgc3RpbGwgaW5kaWNhdGUgdGhhdCBpdCBpcyBjb25zaWRlcmVkIHZpc2libGUgZXZlbiB0aG91Z2gKLSAqIGl0IG1heSBub3QgYWN0dWFsbHkgYmUgc2hvd2luZy4KLSAqIDwvcD4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIHZpc2liaWxpdHkgc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGJvb2xlYW4gZ2V0VmlzaWJsZSAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlyZXR1cm4gdmlzaWJsZTsKKwlyZXR1cm4gKHN0YXRlICYgSElEREVOKSA9PSAwOwogfQorCiBib29sZWFuIGhhc0ZvY3VzICgpIHsKLQlyZXR1cm4gKHRoaXMgPT0gZ2V0RGlzcGxheSAoKS5nZXRGb2N1c0NvbnRyb2wgKCkpOworCXJldHVybiB0aGlzID09IGdldERpc3BsYXkgKCkuZ2V0Rm9jdXNDb250cm9sICgpOwogfQorCitpbnQgaGVscFByb2MgKGludCBpbkNvbnRyb2wsIGludCBpbkdsb2JhbE1vdXNlLCBpbnQgaW5SZXF1ZXN0LCBpbnQgb3V0Q29udGVudFByb3ZpZGVkLCBpbnQgaW9IZWxwQ29udGVudCkgeworCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisgICAgc3dpdGNoIChpblJlcXVlc3QpIHsKKwkJY2FzZSBPUy5rSE1TdXBwbHlDb250ZW50OiB7CisJCQlpbnQgW10gY29udGVudFByb3ZpZGVkID0gbmV3IGludCBbXSB7T1Mua0hNQ29udGVudE5vdFByb3ZpZGVkRG9udFByb3BhZ2F0ZX07CisJCQlpZiAodG9vbFRpcFRleHQgIT0gbnVsbCAmJiB0b29sVGlwVGV4dC5sZW5ndGggKCkgIT0gMCkgeworCQkJCWNoYXIgW10gYnVmZmVyID0gbmV3IGNoYXIgW3Rvb2xUaXBUZXh0Lmxlbmd0aCAoKV07CisJCQkJdG9vbFRpcFRleHQuZ2V0Q2hhcnMgKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlciwgMCk7CisJCQkJaW50IGk9MCwgaj0wOworCQkJCXdoaWxlIChpIDwgYnVmZmVyLmxlbmd0aCkgeworCQkJCQlpZiAoKGJ1ZmZlciBbaisrXSA9IGJ1ZmZlciBbaSsrXSkgPT0gTW5lbW9uaWMpIHsKKwkJCQkJCWlmIChpID09IGJ1ZmZlci5sZW5ndGgpIHtjb250aW51ZTt9CisJCQkJCQlpZiAoYnVmZmVyIFtpXSA9PSBNbmVtb25pYykge2krKzsgY29udGludWU7fQorCQkJCQkJai0tOworCQkJCQl9CisJCQkJfQorCQkJCWlmIChkaXNwbGF5LmhlbHBTdHJpbmcgIT0gMCkgT1MuQ0ZSZWxlYXNlIChkaXNwbGF5LmhlbHBTdHJpbmcpOworCQkgICAgCWRpc3BsYXkuaGVscFN0cmluZyA9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMgKE9TLmtDRkFsbG9jYXRvckRlZmF1bHQsIGJ1ZmZlciwgaik7CisJCQkJSE1IZWxwQ29udGVudFJlYyBoZWxwQ29udGVudCA9IG5ldyBITUhlbHBDb250ZW50UmVjICgpOworCQkJCU9TLm1lbWNweSAoaGVscENvbnRlbnQsIGlvSGVscENvbnRlbnQsIEhNSGVscENvbnRlbnRSZWMuc2l6ZW9mKTsKKwkJICAgICAgICBoZWxwQ29udGVudC52ZXJzaW9uID0gT1Mua01hY0hlbHBWZXJzaW9uOworCQkgICAgICAgIAorCQkgICAgICAgIC8qCisJCSAgICAgICAgKiBGZWF0dXJlIGluIHRoZSBNYWNpbnRvc2guICBEZXNwaXRlIHRoZSBmYWN0IHRoYXQgdGhlIE1hYworCQkgICAgICAgICogcHJvdmlkZXMgMjMgZGlmZmVyZW50IHR5cGVzIG9mIGFsaWdubWVudCBmb3IgdGhlIGhlbHAgdGV4dCwKKwkJICAgICAgICAqIGl0IGRvZXMgbm90IGFsbG93IHRoZSB0ZXh0IHRvIGJlIHBvc2l0aW9uZWQgYXQgdGhlIGN1cnJlbnQKKwkJICAgICAgICAqIG1vdXNlIHBvc2l0aW9uLiAgVGhlIGZpeCBpcyB0byBjZW50ZXIgdGhlIHRleHQgaW4gYSByZWN0YW5nbGUKKwkJCQkqIHRoYXQgc3Vycm91bmRzIHRoZSBvcmlnaW5hbCBwb3NpdGlvbiBvZiB0aGUgbW91c2UuICBBcyB0aGUKKwkJCQkqIG1vdXNlIGlzIG1vdmVkLCB0aGlzIHJlY3RhbmdsZSBpcyBncm93biB0byBpbmNsdWRlIHRoZSBuZXcKKwkJCQkqIGxvY2F0aW9uIG9mIHRoZSBtb3VzZS4gIFRoZSBoZWxwIHRleHQgaXMgdGhlbiBjZW50ZXJlZCBieQorCQkJCSogdGhlICBNYWMgaW4gdGhlIG5ldyByZWN0YW5nbGUgdGhhdCB3YXMgY2FyZWZ1bGx5IGNvbnN0cnVjdGVkCisJCQkJKiBzdWNoIHRoYXQgdGhlIGhlbHAgdGV4dCB3aWxsIHN0YXkgaW4gdGhlIHNhbWUgcG9zaXRpb24uCisJCSAgICAgICAgKi8KKwkJICAgICAgICBpbnQgY3Vyc29ySGVpZ2h0ID0gMTY7CisJCSAgICAgICAgaGVscENvbnRlbnQudGFnU2lkZSA9IChzaG9ydCkgT1Mua0hNQWJzb2x1dGVDZW50ZXJBbGlnbmVkOworCQkJCWludCB4ID0gKHNob3J0KSAoaW5HbG9iYWxNb3VzZSAmIDB4RkZGRik7CisJCQkJaW50IHkgPSAoc2hvcnQpIChpbkdsb2JhbE1vdXNlID4+IDE2KTsKKwkJCQlpZiAoZGlzcGxheS5oZWxwQ29udHJvbCAhPSB0aGlzKSB7CisJCQkJCWRpc3BsYXkubGFzdEhlbHBYID0geCArIGN1cnNvckhlaWdodCAvIDI7CisJCQkJCWRpc3BsYXkubGFzdEhlbHBZID0geSArIGN1cnNvckhlaWdodCArIGN1cnNvckhlaWdodCAvIDI7CQkJCisJCQkJfQorCQkJCWludCBqaXR0ZXIgPSA0OworCQkJCWludCBkZWx0YVggPSBNYXRoLmFicyAoZGlzcGxheS5sYXN0SGVscFggLSB4KSArIGppdHRlcjsKKwkJCQlpbnQgZGVsdGFZID0gTWF0aC5hYnMgKGRpc3BsYXkubGFzdEhlbHBZIC0geSkgKyBqaXR0ZXI7CisJCQkJeCA9IGRpc3BsYXkubGFzdEhlbHBYIC0gZGVsdGFYOworCQkJCXkgPSBkaXNwbGF5Lmxhc3RIZWxwWSAtIGRlbHRhWTsKKwkJCQlpbnQgd2lkdGggPSBkZWx0YVggKiAyOworCQkJCWludCBoZWlnaHQgPSBkZWx0YVkgKiAyOworCQkJCWRpc3BsYXkuaGVscENvbnRyb2wgPSB0aGlzOworCQkgICAgICAgIGhlbHBDb250ZW50LmFic0hvdFJlY3RfbGVmdCA9IChzaG9ydCkgeDsKKwkJICAgICAJaGVscENvbnRlbnQuYWJzSG90UmVjdF90b3AgPSAoc2hvcnQpIHk7CisJCSAgICAgICAgaGVscENvbnRlbnQuYWJzSG90UmVjdF9yaWdodCA9IChzaG9ydCkgKHggKyB3aWR0aCk7CisJCSAgICAgICAgaGVscENvbnRlbnQuYWJzSG90UmVjdF9ib3R0b20gPSAoc2hvcnQpICh5ICsgaGVpZ2h0KTsKKwkJICAgICAgICAKKwkJICAgICAgICBoZWxwQ29udGVudC5jb250ZW50MF9jb250ZW50VHlwZSA9IE9TLmtITUNGU3RyaW5nQ29udGVudDsKKwkJICAgICAgICBoZWxwQ29udGVudC5jb250ZW50MF90YWdDRlN0cmluZyA9IGRpc3BsYXkuaGVscFN0cmluZzsKKwkJICAgICAgICBoZWxwQ29udGVudC5jb250ZW50MV9jb250ZW50VHlwZSA9IE9TLmtITUNGU3RyaW5nQ29udGVudDsKKwkJICAgICAgICBoZWxwQ29udGVudC5jb250ZW50MV90YWdDRlN0cmluZyA9IGRpc3BsYXkuaGVscFN0cmluZzsKKwkJCQlPUy5tZW1jcHkgKGlvSGVscENvbnRlbnQsIGhlbHBDb250ZW50LCBITUhlbHBDb250ZW50UmVjLnNpemVvZik7CisJCQkJY29udGVudFByb3ZpZGVkIFswXSA9IE9TLmtITUNvbnRlbnRQcm92aWRlZDsKKwkJCX0KKwkJCU9TLm1lbWNweSAob3V0Q29udGVudFByb3ZpZGVkLCBjb250ZW50UHJvdmlkZWQsIDQpOworCQkJYnJlYWs7CisJCX0KKwkJY2FzZSBPUy5rSE1EaXNwb3NlQ29udGVudDogeworCQkJaWYgKGRpc3BsYXkuaGVscFN0cmluZyAhPSAwKSBPUy5DRlJlbGVhc2UgKGRpc3BsYXkuaGVscFN0cmluZyk7CisJCQlkaXNwbGF5LmhlbHBTdHJpbmcgPSAwOworCQkJYnJlYWs7CisJCX0KKwl9CisJcmV0dXJuIE9TLm5vRXJyOworfQorCiB2b2lkIGhvb2tFdmVudHMgKCkgewotICAgIC8qIEFXCi0JaW50IHdpbmRvd1Byb2MgPSBnZXREaXNwbGF5ICgpLndpbmRvd1Byb2M7Ci0JT1MuWHRBZGRFdmVudEhhbmRsZXIgKGhhbmRsZSwgT1MuS2V5UHJlc3NNYXNrLCBmYWxzZSwgd2luZG93UHJvYywgU1dULktleURvd24pOwotCU9TLlh0QWRkRXZlbnRIYW5kbGVyIChoYW5kbGUsIE9TLktleVJlbGVhc2VNYXNrLCBmYWxzZSwgd2luZG93UHJvYywgU1dULktleVVwKTsKLQlPUy5YdEFkZEV2ZW50SGFuZGxlciAoaGFuZGxlLCBPUy5CdXR0b25QcmVzc01hc2ssIGZhbHNlLCB3aW5kb3dQcm9jLCBTV1QuTW91c2VEb3duKTsKLQlPUy5YdEFkZEV2ZW50SGFuZGxlciAoaGFuZGxlLCBPUy5CdXR0b25SZWxlYXNlTWFzaywgZmFsc2UsIHdpbmRvd1Byb2MsIFNXVC5Nb3VzZVVwKTsKLQlPUy5YdEFkZEV2ZW50SGFuZGxlciAoaGFuZGxlLCBPUy5Qb2ludGVyTW90aW9uTWFzaywgZmFsc2UsIHdpbmRvd1Byb2MsIFNXVC5Nb3VzZU1vdmUpOwotCU9TLlh0QWRkRXZlbnRIYW5kbGVyIChoYW5kbGUsIE9TLkVudGVyV2luZG93TWFzaywgZmFsc2UsIHdpbmRvd1Byb2MsIFNXVC5Nb3VzZUVudGVyKTsKLQlPUy5YdEFkZEV2ZW50SGFuZGxlciAoaGFuZGxlLCBPUy5MZWF2ZVdpbmRvd01hc2ssIGZhbHNlLCB3aW5kb3dQcm9jLCBTV1QuTW91c2VFeGl0KTsKLQlPUy5YdEFkZEV2ZW50SGFuZGxlciAoaGFuZGxlLCBPUy5FeHBvc3VyZU1hc2ssIGZhbHNlLCB3aW5kb3dQcm9jLCBTV1QuUGFpbnQpOwotCU9TLlh0QWRkRXZlbnRIYW5kbGVyIChoYW5kbGUsIE9TLkZvY3VzQ2hhbmdlTWFzaywgZmFsc2UsIHdpbmRvd1Byb2MsIFNXVC5Gb2N1c0luKTsKLQlPUy5YdEFkZENhbGxiYWNrIChoYW5kbGUsIE9TLlhtTmhlbHBDYWxsYmFjaywgd2luZG93UHJvYywgU1dULkhlbHApOwotICAgICovCi0gICAgLy9EaXNwbGF5IGRpc3BsYXk9IGdldERpc3BsYXkoKTsJCQotCS8vT1MuU2V0Q29udHJvbERhdGEoaGFuZGxlLCBPUy5rQ29udHJvbEVudGlyZUNvbnRyb2wsIE9TLmtDb250cm9sVXNlclBhbmVEcmF3UHJvY1RhZywgZGlzcGxheS5mVXNlclBhbmVEcmF3UHJvYyk7CisJc3VwZXIuaG9va0V2ZW50cyAoKTsKKwlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCWludCBjb250cm9sUHJvYyA9IGRpc3BsYXkuY29udHJvbFByb2M7CisJaW50IFtdIG1hc2sgPSBuZXcgaW50IFtdIHsKKwkJT1Mua0V2ZW50Q2xhc3NDb250cm9sLCBPUy5rRXZlbnRDb250cm9sQWN0aXZhdGUsCisJCU9TLmtFdmVudENsYXNzQ29udHJvbCwgT1Mua0V2ZW50Q29udHJvbEJvdW5kc0NoYW5nZWQsCisJCU9TLmtFdmVudENsYXNzQ29udHJvbCwgT1Mua0V2ZW50Q29udHJvbENsaWNrLAorCQlPUy5rRXZlbnRDbGFzc0NvbnRyb2wsIE9TLmtFdmVudENvbnRyb2xDb250ZXh0dWFsTWVudUNsaWNrLAorCQlPUy5rRXZlbnRDbGFzc0NvbnRyb2wsIE9TLmtFdmVudENvbnRyb2xEZWFjdGl2YXRlLAorCQlPUy5rRXZlbnRDbGFzc0NvbnRyb2wsIE9TLmtFdmVudENvbnRyb2xEcmF3LAorCQlPUy5rRXZlbnRDbGFzc0NvbnRyb2wsIE9TLmtFdmVudENvbnRyb2xIaXQsCisJCU9TLmtFdmVudENsYXNzQ29udHJvbCwgT1Mua0V2ZW50Q29udHJvbFNldEN1cnNvciwKKwkJT1Mua0V2ZW50Q2xhc3NDb250cm9sLCBPUy5rRXZlbnRDb250cm9sU2V0Rm9jdXNQYXJ0LAorCX07CisJaW50IGNvbnRyb2xUYXJnZXQgPSBPUy5HZXRDb250cm9sRXZlbnRUYXJnZXQgKGhhbmRsZSk7CisJT1MuSW5zdGFsbEV2ZW50SGFuZGxlciAoY29udHJvbFRhcmdldCwgY29udHJvbFByb2MsIG1hc2subGVuZ3RoIC8gMiwgbWFzaywgaGFuZGxlLCBudWxsKTsKKwlpbnQgaGVscFByb2MgPSBkaXNwbGF5LmhlbHBQcm9jOworCU9TLkhNSW5zdGFsbENvbnRyb2xDb250ZW50Q2FsbGJhY2sgKGhhbmRsZSwgaGVscFByb2MpOwogfQotLyoqCSAKLSAqIEludm9rZXMgcGxhdGZvcm0gc3BlY2lmaWMgZnVuY3Rpb25hbGl0eSB0byBhbGxvY2F0ZSBhIG5ldyBHQyBoYW5kbGUuCi0gKiA8cD4KLSAqIDxiPklNUE9SVEFOVDo8L2I+IFRoaXMgbWV0aG9kIGlzIDxlbT5ub3Q8L2VtPiBwYXJ0IG9mIHRoZSBwdWJsaWMKLSAqIEFQSSBmb3IgPGNvZGU+Q29udHJvbDwvY29kZT4uIEl0IGlzIG1hcmtlZCBwdWJsaWMgb25seSBzbyB0aGF0IGl0Ci0gKiBjYW4gYmUgc2hhcmVkIHdpdGhpbiB0aGUgcGFja2FnZXMgcHJvdmlkZWQgYnkgU1dULiBJdCBpcyBub3QKLSAqIGF2YWlsYWJsZSBvbiBhbGwgcGxhdGZvcm1zLCBhbmQgc2hvdWxkIG5ldmVyIGJlIGNhbGxlZCBmcm9tCi0gKiBhcHBsaWNhdGlvbiBjb2RlLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBkYXRhIHRoZSBwbGF0Zm9ybSBzcGVjaWZpYyBHQyBkYXRhIAotICogQHJldHVybiB0aGUgcGxhdGZvcm0gc3BlY2lmaWMgR0MgaGFuZGxlCi0gKgotICogQHByaXZhdGUKLSAqLworCiBwdWJsaWMgaW50IGludGVybmFsX25ld19HQyAoR0NEYXRhIGRhdGEpIHsKIAljaGVja1dpZGdldCgpOwotICAgIC8qIEFXCi0JaWYgKCFPUy5YdElzUmVhbGl6ZWQgKGhhbmRsZSkpIHsKLQkJU2hlbGwgc2hlbGwgPSBnZXRTaGVsbCAoKTsKLQkJc2hlbGwucmVhbGl6ZVdpZGdldCAoKTsKKwlpbnQgW10gYnVmZmVyID0gbmV3IGludCBbMV07CisJaW50IGNvbnRleHQgPSAwLCBwYWludFJnbiA9IDAsIHZpc2libGVSZ24gPSAwOworCWlmIChkYXRhLnBhaW50RXZlbnQgIT0gMCkgeworCQlpbnQgdGhlRXZlbnQgPSBkYXRhLnBhaW50RXZlbnQ7CisJCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1DR0NvbnRleHRSZWYsIE9TLnR5cGVDR0NvbnRleHRSZWYsIG51bGwsIDQsIG51bGwsIGJ1ZmZlcik7CisJCWNvbnRleHQgPSBidWZmZXIgWzBdOwkKKwkJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbVJnbkhhbmRsZSwgT1MudHlwZVFEUmduSGFuZGxlLCBudWxsLCA0LCBudWxsLCBidWZmZXIpOworCQl2aXNpYmxlUmduID0gcGFpbnRSZ24gPSBidWZmZXIgWzBdOwogCX0KLQlpbnQgeERpc3BsYXkgPSBPUy5YdERpc3BsYXkgKGhhbmRsZSk7Ci0JaWYgKHhEaXNwbGF5ID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JaW50IHhXaW5kb3cgPSBPUy5YdFdpbmRvdyAoaGFuZGxlKTsKLQlpZiAoeFdpbmRvdyA9PSAwKSBTV1QuZXJyb3IoU1dULkVSUk9SX05PX0hBTkRMRVMpOwotCWludCB4R0MgPSBPUy5YQ3JlYXRlR0MgKHhEaXNwbGF5LCB4V2luZG93LCAwLCBudWxsKTsKLQlpZiAoeEdDID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JT1MuWFNldEdyYXBoaWNzRXhwb3N1cmVzICh4RGlzcGxheSwgeEdDLCBmYWxzZSk7Ci0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1OZm9yZWdyb3VuZCwgMCwgT1MuWG1OYmFja2dyb3VuZCwgMCwgT1MuWG1OY29sb3JtYXAsIDB9OwotCU9TLlh0R2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JKi8KKwlpZiAoY29udGV4dCA9PSAwKSB7CisJCWludCB3aW5kb3cgPSBPUy5HZXRDb250cm9sT3duZXIgKGhhbmRsZSk7CisJCWludCBwb3J0ID0gT1MuR2V0V2luZG93UG9ydCAod2luZG93KTsKKwkJT1MuQ3JlYXRlQ0dDb250ZXh0Rm9yUG9ydCAocG9ydCwgYnVmZmVyKTsKKwkJY29udGV4dCA9IGJ1ZmZlciBbMF07CisJCWlmIChjb250ZXh0ICE9IDApIHsKKwkJCVJlY3QgcmVjdCA9IG5ldyBSZWN0ICgpOworCQkJT1MuR2V0Q29udHJvbEJvdW5kcyAoaGFuZGxlLCByZWN0KTsKKwkJCVJlY3QgcG9ydFJlY3QgPSBuZXcgUmVjdCAoKTsKKwkJCU9TLkdldFBvcnRCb3VuZHMgKHBvcnQsIHBvcnRSZWN0KTsKKwkJCXZpc2libGVSZ24gPSBnZXRWaXNpYmxlUmVnaW9uIChoYW5kbGUpOworCQkJaWYgKHBhaW50UmduICE9IDApIE9TLlNlY3RSZ24gKHBhaW50UmduLCB2aXNpYmxlUmduLCB2aXNpYmxlUmduKTsKKwkJCU9TLkNsaXBDR0NvbnRleHRUb1JlZ2lvbiAoY29udGV4dCwgcG9ydFJlY3QsIHZpc2libGVSZ24pOworCQkJaW50IHBvcnRIZWlnaHQgPSBwb3J0UmVjdC5ib3R0b20gLSBwb3J0UmVjdC50b3A7CisJCQlPUy5DR0NvbnRleHRTY2FsZUNUTSAoY29udGV4dCwgMSwgLTEpOworCQkJT1MuQ0dDb250ZXh0VHJhbnNsYXRlQ1RNIChjb250ZXh0LCByZWN0LmxlZnQsIC1wb3J0SGVpZ2h0ICsgcmVjdC50b3ApOworCQl9CisJfQorCWlmIChjb250ZXh0ID09IDApIFNXVC5lcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOwogCWlmIChkYXRhICE9IG51bGwpIHsKLQkJZGF0YS5kZXZpY2UgPSBnZXREaXNwbGF5ICgpOwotCQlkYXRhLmZvcmVncm91bmQgPSBnZXRGb3JlZ3JvdW5kUGl4ZWwoKTsKLQkJZGF0YS5iYWNrZ3JvdW5kID0gZ2V0QmFja2dyb3VuZFBpeGVsKCk7Ci0JCWRhdGEuZm9udCA9IGZvbnQuaGFuZGxlOwotCQlkYXRhLmNvbnRyb2xIYW5kbGUgPSBoYW5kbGU7Ci0JfQotCi0JaW50IHdIYW5kbGU9IDA7Ci0JaWYgKE1hY1V0aWwuVVNFX0ZSQU1FKSB7Ci0JCVNoZWxsIHNoZWxsPSBnZXRTaGVsbCgpOwotCQlpZiAoc2hlbGwgIT0gbnVsbCkKLQkJCXdIYW5kbGU9IHNoZWxsLnNoZWxsSGFuZGxlOworCQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCQlkYXRhLmRldmljZSA9IGRpc3BsYXk7CisJCWRhdGEuZm9yZWdyb3VuZCA9IGZvcmVncm91bmQgIT0gbnVsbCA/IGZvcmVncm91bmQgOiBkaXNwbGF5LmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfQkxBQ0spLmhhbmRsZTsKKwkJZGF0YS5iYWNrZ3JvdW5kID0gYmFja2dyb3VuZCAhPSBudWxsID8gYmFja2dyb3VuZCA6IGRpc3BsYXkuZ2V0U3lzdGVtQ29sb3IgKFNXVC5DT0xPUl9XSElURSkuaGFuZGxlOworCQlkYXRhLmZvbnQgPSBmb250ICE9IG51bGwgPyBmb250IDogZGVmYXVsdEZvbnQgKCk7CisJCWRhdGEudmlzaWJsZVJnbiA9IHZpc2libGVSZ247CisJCWRhdGEuY29udHJvbCA9IGhhbmRsZTsKIAl9IGVsc2UgewotCQl3SGFuZGxlPSBPUy5HZXRDb250cm9sT3duZXIoaGFuZGxlKTsKKwkJaWYgKHZpc2libGVSZ24gIT0gcGFpbnRSZ24pIE9TLkRpc3Bvc2VSZ24gKHZpc2libGVSZ24pOwogCX0KLQlpbnQgeEdDPSBPUy5HZXRXaW5kb3dQb3J0KHdIYW5kbGUpOwotCWlmICh4R0MgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKLQkKLSAgICByZXR1cm4geEdDOworCXJldHVybiBjb250ZXh0OwogfQotLyoqCSAKLSAqIEludm9rZXMgcGxhdGZvcm0gc3BlY2lmaWMgZnVuY3Rpb25hbGl0eSB0byBkaXNwb3NlIGEgR0MgaGFuZGxlLgotICogPHA+Ci0gKiA8Yj5JTVBPUlRBTlQ6PC9iPiBUaGlzIG1ldGhvZCBpcyA8ZW0+bm90PC9lbT4gcGFydCBvZiB0aGUgcHVibGljCi0gKiBBUEkgZm9yIDxjb2RlPkNvbnRyb2w8L2NvZGU+LiBJdCBpcyBtYXJrZWQgcHVibGljIG9ubHkgc28gdGhhdCBpdAotICogY2FuIGJlIHNoYXJlZCB3aXRoaW4gdGhlIHBhY2thZ2VzIHByb3ZpZGVkIGJ5IFNXVC4gSXQgaXMgbm90Ci0gKiBhdmFpbGFibGUgb24gYWxsIHBsYXRmb3JtcywgYW5kIHNob3VsZCBuZXZlciBiZSBjYWxsZWQgZnJvbQotICogYXBwbGljYXRpb24gY29kZS4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gaGFuZGxlIHRoZSBwbGF0Zm9ybSBzcGVjaWZpYyBHQyBoYW5kbGUKLSAqIEBwYXJhbSBkYXRhIHRoZSBwbGF0Zm9ybSBzcGVjaWZpYyBHQyBkYXRhIAotICoKLSAqIEBwcml2YXRlCi0gKi8KLXB1YmxpYyB2b2lkIGludGVybmFsX2Rpc3Bvc2VfR0MgKGludCB4R0MsIEdDRGF0YSBkYXRhKSB7CisKK3B1YmxpYyB2b2lkIGludGVybmFsX2Rpc3Bvc2VfR0MgKGludCBjb250ZXh0LCBHQ0RhdGEgZGF0YSkgewogCWNoZWNrV2lkZ2V0ICgpOwotICAgIC8qIEFXCi0JaW50IHhEaXNwbGF5ID0gMDsKLQlpZiAoZGF0YSAhPSBudWxsKSB4RGlzcGxheSA9IGRhdGEuZGlzcGxheTsKLQlpZiAoeERpc3BsYXkgPT0gMCAmJiBoYW5kbGUgIT0gMCkgeERpc3BsYXkgPSBPUy5YdERpc3BsYXkgKGhhbmRsZSk7Ci0JaWYgKHhEaXNwbGF5ID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JT1MuWEZyZWVHQyAoeERpc3BsYXksIHhHQyk7Ci0gICAgKi8KKwlpZiAoZGF0YSAhPSBudWxsKSB7CisJCWludCBwYWludENvbnRleHQgPSAwLCBwYWludFJnbiA9IDA7CisJCWlmIChkYXRhLnBhaW50RXZlbnQgIT0gMCkgeworCQkJaW50IHRoZUV2ZW50ID0gZGF0YS5wYWludEV2ZW50OworCQkJaW50IFtdIGJ1ZmZlciA9IG5ldyBpbnQgWzFdOworCQkJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbUNHQ29udGV4dFJlZiwgT1MudHlwZUNHQ29udGV4dFJlZiwgbnVsbCwgNCwgbnVsbCwgYnVmZmVyKTsKKwkJCXBhaW50Q29udGV4dCA9IGJ1ZmZlciBbMF07CQorCQkJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbVJnbkhhbmRsZSwgT1MudHlwZVFEUmduSGFuZGxlLCBudWxsLCA0LCBudWxsLCBidWZmZXIpOworCQkJcGFpbnRSZ24gPSBidWZmZXIgWzBdOworCQl9CisJCWlmIChkYXRhLnZpc2libGVSZ24gIT0gMCAmJiBkYXRhLnZpc2libGVSZ24gIT0gcGFpbnRSZ24pIHsKKwkJCU9TLkRpc3Bvc2VSZ24gKGRhdGEudmlzaWJsZVJnbik7CisJCQlkYXRhLnZpc2libGVSZ24gPSAwOworCQl9CisJCWlmIChwYWludENvbnRleHQgPT0gY29udGV4dCkgcmV0dXJuOworCX0KKwlPUy5DR0NvbnRleHRGbHVzaCAoY29udGV4dCk7CisJT1MuQ0dDb250ZXh0UmVsZWFzZSAoY29udGV4dCk7CiB9Ci0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGlzIGVuYWJsZWQgYW5kIGFsbAotICogb2YgdGhlIHJlY2VpdmVyJ3MgYW5jZXN0b3JzIGFyZSBlbmFibGVkLCBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+Ci0gKiBvdGhlcndpc2UuIEEgZGlzYWJsZWQgY29udHJvbCBpcyB0eXBpY2FsbHkgbm90IHNlbGVjdGFibGUgZnJvbSB0aGUKLSAqIHVzZXIgaW50ZXJmYWNlIGFuZCBkcmF3cyB3aXRoIGFuIGluYWN0aXZlIG9yICJncmF5ZWQiIGxvb2suCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBlbmFibGVkIHN0YXRlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogCi0gKiBAc2VlICNnZXRFbmFibGVkCi0gKi8KKwogcHVibGljIGJvb2xlYW4gaXNFbmFibGVkICgpIHsKIAljaGVja1dpZGdldCgpOwotCXJldHVybiBnZXRFbmFibGVkICgpICYmIHBhcmVudC5pc0VuYWJsZWQgKCk7CisJcmV0dXJuIE9TLklzQ29udHJvbEVuYWJsZWQgKHRvcEhhbmRsZSAoKSk7CiB9Ci0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGhhcyB0aGUgdXNlci1pbnRlcmZhY2UKLSAqIGZvY3VzLCBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGZvY3VzIHN0YXRlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKK2Jvb2xlYW4gaXNGb2N1c0FuY2VzdG9yICgpIHsKKwlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCUNvbnRyb2wgY29udHJvbCA9IGRpc3BsYXkuZ2V0Rm9jdXNDb250cm9sICgpOworCXdoaWxlIChjb250cm9sICE9IG51bGwgJiYgY29udHJvbCAhPSB0aGlzKSB7CisJCWNvbnRyb2wgPSBjb250cm9sLnBhcmVudDsKKwl9CisJcmV0dXJuIGNvbnRyb2wgPT0gdGhpczsKK30KKwogcHVibGljIGJvb2xlYW4gaXNGb2N1c0NvbnRyb2wgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIGhhc0ZvY3VzICgpOwogfQotLyoqCi0gKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSB1bmRlcmx5aW5nIG9wZXJhdGluZwotICogc3lzdGVtIHN1cHBvcnRzIHRoaXMgcmVwYXJlbnRpbmcsIG90aGVyd2lzZSA8Y29kZT5mYWxzZTwvY29kZT4KLSAqCi0gKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSB3aWRnZXQgY2FuIGJlIHJlcGFyZW50ZWQsIG90aGVyd2lzZSA8Y29kZT5mYWxzZTwvY29kZT4KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGJvb2xlYW4gaXNSZXBhcmVudGFibGUgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIGZhbHNlOwogfQogCi1ib29sZWFuIGlzU2hvd2luZyAoKSB7Ci0JLyoKLQkqIFRoaXMgaXMgbm90IGNvbXBsZXRlLiAgTmVlZCB0byBjaGVjayBpZiB0aGUKLQkqIHdpZGdldCBpcyBvYnNjdXJyZWQgYnkgYSBwYXJlbnQgb3Igc2libGluZy4KLQkqLwotCS8qIEFXCi0JaWYgKCFpc1Zpc2libGUgKCkpIHJldHVybiBmYWxzZTsKLQlDb250cm9sIGNvbnRyb2wgPSB0aGlzOwotCXdoaWxlIChjb250cm9sICE9IG51bGwpIHsKLQkJUG9pbnQgc2l6ZSA9IGNvbnRyb2wuZ2V0U2l6ZSAoKTsKLQkJaWYgKHNpemUueCA9PSAwIHx8IHNpemUueSA9PSAwKSB7Ci0JCQlyZXR1cm4gZmFsc2U7Ci0JCX0KLQkJY29udHJvbCA9IGNvbnRyb2wucGFyZW50OwotCX0KLQkqLwotCXJldHVybiB0cnVlOwotCS8qCi0JKiBDaGVjayB0byBzZWUgaWYgY3VycmVudCBkYW1hZ2UgaXMgaW5jbHVkZWQuCi0JKi8KLS8vCWlmICghT1MuSXNXaW5kb3dWaXNpYmxlIChoYW5kbGUpKSByZXR1cm4gZmFsc2U7Ci0vLwlpbnQgZmxhZ3MgPSBPUy5EQ1hfQ0FDSEUgfCBPUy5EQ1hfQ0xJUENISUxEUkVOIHwgT1MuRENYX0NMSVBTSUJMSU5HUzsKLS8vCWludCBoREMgPSBPUy5HZXREQ0V4IChoYW5kbGUsIDAsIGZsYWdzKTsKLS8vCWludCByZXN1bHQgPSBPUy5HZXRDbGlwQm94IChoREMsIG5ldyBSRUNUICgpKTsKLS8vCU9TLlJlbGVhc2VEQyAoaGFuZGxlLCBoREMpOwotLy8JcmV0dXJuIHJlc3VsdCAhPSBPUy5OVUxMUkVHSU9OOwotfQotCiBib29sZWFuIGlzVGFiR3JvdXAgKCkgewotCUNvbnRyb2wgW10gdGFiTGlzdCA9IHBhcmVudC5fZ2V0VGFiTGlzdCAoKTsKLQlpZiAodGFiTGlzdCAhPSBudWxsKSB7Ci0JCWZvciAoaW50IGk9MDsgaTx0YWJMaXN0Lmxlbmd0aDsgaSsrKSB7Ci0JCQlpZiAodGFiTGlzdCBbaV0gPT0gdGhpcykgcmV0dXJuIHRydWU7Ci0JCX0KLQl9Ci0JLyogQVcKLQlpbnQgYml0cyA9IE9TLkdldFdpbmRvd0xvbmcgKGhhbmRsZSwgT1MuR1dMX1NUWUxFKTsKLQlyZXR1cm4gKGJpdHMgJiBPUy5XU19UQUJTVE9QKSAhPSAwOwotCSovCi0JLy8gQVc6IE1vdGlmOgotCWludCBjb2RlID0gdHJhdmVyc2FsQ29kZSAoKTsKLQlpZiAoKGNvZGUgJiAoU1dULlRSQVZFUlNFX0FSUk9XX1BSRVZJT1VTIHwgU1dULlRSQVZFUlNFX0FSUk9XX05FWFQpKSAhPSAwKSByZXR1cm4gZmFsc2U7Ci0JcmV0dXJuIChjb2RlICYgKFNXVC5UUkFWRVJTRV9UQUJfUFJFVklPVVMgfCBTV1QuVFJBVkVSU0VfVEFCX05FWFQpKSAhPSAwOworCXJldHVybiBmYWxzZTsKIH0KIAogYm9vbGVhbiBpc1RhYkl0ZW0gKCkgewotCUNvbnRyb2wgW10gdGFiTGlzdCA9IHBhcmVudC5fZ2V0VGFiTGlzdCAoKTsJCi0JaWYgKHRhYkxpc3QgIT0gbnVsbCkgewotCQlmb3IgKGludCBpPTA7IGk8dGFiTGlzdC5sZW5ndGg7IGkrKykgewotCQkJaWYgKHRhYkxpc3QgW2ldID09IHRoaXMpIHJldHVybiBmYWxzZTsKLQkJfQotCX0KLQkvKiBBVwotCWludCBiaXRzID0gT1MuR2V0V2luZG93TG9uZyAoaGFuZGxlLCBPUy5HV0xfU1RZTEUpOwotCWlmICgoYml0cyAmIE9TLldTX1RBQlNUT1ApICE9IDApIHJldHVybiBmYWxzZTsKLQlpbnQgY29kZSA9IE9TLlNlbmRNZXNzYWdlIChoYW5kbGUsIE9TLldNX0dFVERMR0NPREUsIDAsIDApOwotCWlmICgoY29kZSAmIE9TLkRMR0NfU1RBVElDKSAhPSAwKSByZXR1cm4gZmFsc2U7Ci0JaWYgKChjb2RlICYgT1MuRExHQ19XQU5UQUxMS0VZUykgIT0gMCkgcmV0dXJuIGZhbHNlOwotCWlmICgoY29kZSAmIE9TLkRMR0NfV0FOVEFSUk9XUykgIT0gMCkgcmV0dXJuIGZhbHNlOwotCWlmICgoY29kZSAmIE9TLkRMR0NfV0FOVFRBQikgIT0gMCkgcmV0dXJuIGZhbHNlOwotCSovCi0JLy8gQVc6IE1vdGlmCi0JaW50IGNvZGUgPSB0cmF2ZXJzYWxDb2RlICgpOwotCXJldHVybiAoY29kZSAmIChTV1QuVFJBVkVSU0VfQVJST1dfUFJFVklPVVMgfCBTV1QuVFJBVkVSU0VfQVJST1dfTkVYVCkpICE9IDA7CisJcmV0dXJuIGZhbHNlOwogfQotLyoqCi0gKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSByZWNlaXZlciBpcyB2aXNpYmxlIGFuZCBhbGwKLSAqIG9mIHRoZSByZWNlaXZlcidzIGFuY2VzdG9ycyBhcmUgdmlzaWJsZSBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+Ci0gKiBvdGhlcndpc2UuCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyB2aXNpYmlsaXR5IHN0YXRlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI2dldFZpc2libGUKLSAqLworCiBwdWJsaWMgYm9vbGVhbiBpc1Zpc2libGUgKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JcmV0dXJuIGdldFZpc2libGUgKCkgJiYgcGFyZW50LmlzVmlzaWJsZSAoKTsKKwlyZXR1cm4gT1MuSXNDb250cm9sVmlzaWJsZSAodG9wSGFuZGxlICgpKTsKIH0KLXZvaWQgbWFuYWdlQ2hpbGRyZW4gKCkgewotLyogQVcKLQlPUy5YdFNldE1hcHBlZFdoZW5NYW5hZ2VkIChoYW5kbGUsIGZhbHNlKTsKLQlPUy5YdE1hbmFnZUNoaWxkIChoYW5kbGUpOwotCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTmJvcmRlcldpZHRoLCAwfTsKLQlPUy5YdEdldFZhbHVlcyAoaGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCU9TLlh0UmVzaXplV2lkZ2V0IChoYW5kbGUsIDEsIDEsIGFyZ0xpc3QgWzFdKTsKLQlPUy5YdFNldE1hcHBlZFdoZW5NYW5hZ2VkIChoYW5kbGUsIHRydWUpOwotKi8KLX0KKwogRGVjb3JhdGlvbnMgbWVudVNoZWxsICgpIHsKIAlyZXR1cm4gcGFyZW50Lm1lbnVTaGVsbCAoKTsKIH0KLWJvb2xlYW4gbW5lbW9uaWNIaXQgKGNoYXIga2V5KSB7Ci0JcmV0dXJuIGZhbHNlOwotfQotYm9vbGVhbiBtbmVtb25pY01hdGNoIChjaGFyIGtleSkgewotCXJldHVybiBmYWxzZTsKLX0KLS8qKgotICogTW92ZXMgdGhlIHJlY2VpdmVyIGFib3ZlIHRoZSBzcGVjaWZpZWQgY29udHJvbCBpbiB0aGUKLSAqIGRyYXdpbmcgb3JkZXIuIElmIHRoZSBhcmd1bWVudCBpcyBudWxsLCB0aGVuIHRoZSByZWNlaXZlcgotICogaXMgbW92ZWQgdG8gdGhlIHRvcCBvZiB0aGUgZHJhd2luZyBvcmRlci4gVGhlIGNvbnRyb2wgYXQKLSAqIHRoZSB0b3Agb2YgdGhlIGRyYXdpbmcgb3JkZXIgd2lsbCBub3QgYmUgY292ZXJlZCBieSBvdGhlcgotICogY29udHJvbHMgZXZlbiBpZiB0aGV5IG9jY3VweSBpbnRlcnNlY3RpbmcgYXJlYXMuCi0gKgotICogQHBhcmFtIHRoZSBzaWJsaW5nIGNvbnRyb2wgKG9yIG51bGwpCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfQVJHVU1FTlQgLSBpZiB0aGUgY29udHJvbCBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+IAotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwotcHVibGljIHZvaWQgbW92ZUFib3ZlIChDb250cm9sIGNvbnRyb2wpIHsKLQljaGVja1dpZGdldCgpOwotCWlmIChjb250cm9sICE9IG51bGwgJiYgY29udHJvbC5pc0Rpc3Bvc2VkICgpKSBlcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7Ci0Jc2V0Wk9yZGVyIChjb250cm9sLCB0cnVlKTsKLX0KLS8qKgotICogTW92ZXMgdGhlIHJlY2VpdmVyIGJlbG93IHRoZSBzcGVjaWZpZWQgY29udHJvbCBpbiB0aGUKLSAqIGRyYXdpbmcgb3JkZXIuIElmIHRoZSBhcmd1bWVudCBpcyBudWxsLCB0aGVuIHRoZSByZWNlaXZlcgotICogaXMgbW92ZWQgdG8gdGhlIGJvdHRvbSBvZiB0aGUgZHJhd2luZyBvcmRlci4gVGhlIGNvbnRyb2wgYXQKLSAqIHRoZSBib3R0b20gb2YgdGhlIGRyYXdpbmcgb3JkZXIgd2lsbCBiZSBjb3ZlcmVkIGJ5IGFsbCBvdGhlcgotICogY29udHJvbHMgd2hpY2ggb2NjdXB5IGludGVyc2VjdGluZyBhcmVhcy4KLSAqCi0gKiBAcGFyYW0gdGhlIHNpYmxpbmcgY29udHJvbCAob3IgbnVsbCkKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9BUkdVTUVOVCAtIGlmIHRoZSBjb250cm9sIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4gCi0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCi1wdWJsaWMgdm9pZCBtb3ZlQmVsb3cgKENvbnRyb2wgY29udHJvbCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKGNvbnRyb2wgIT0gbnVsbCAmJiBjb250cm9sLmlzRGlzcG9zZWQgKCkpIGVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKLQlzZXRaT3JkZXIgKGNvbnRyb2wsIGZhbHNlKTsKLX0KLS8qKgotICogQ2F1c2VzIHRoZSByZWNlaXZlciB0byBiZSByZXNpemVkIHRvIGl0cyBwcmVmZXJyZWQgc2l6ZS4KLSAqIEZvciBhIGNvbXBvc2l0ZSwgdGhpcyBpbnZvbHZlcyBjb21wdXRpbmcgdGhlIHByZWZlcnJlZCBzaXplCi0gKiBmcm9tIGl0cyBsYXlvdXQsIGlmIHRoZXJlIGlzIG9uZS4KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjY29tcHV0ZVNpemUKLSAqLwotcHVibGljIHZvaWQgcGFjayAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlwYWNrICh0cnVlKTsKLX0KLS8qKgotICogQ2F1c2VzIHRoZSByZWNlaXZlciB0byBiZSByZXNpemVkIHRvIGl0cyBwcmVmZXJyZWQgc2l6ZS4KLSAqIEZvciBhIGNvbXBvc2l0ZSwgdGhpcyBpbnZvbHZlcyBjb21wdXRpbmcgdGhlIHByZWZlcnJlZCBzaXplCi0gKiBmcm9tIGl0cyBsYXlvdXQsIGlmIHRoZXJlIGlzIG9uZS4KLSAqIDxwPgotICogSWYgdGhlIGNoYW5nZWQgZmxhZyBpcyA8Y29kZT50cnVlPC9jb2RlPiwgaXQgaW5kaWNhdGVzIHRoYXQgdGhlIHJlY2VpdmVyJ3MKLSAqIDxlbT5jb250ZW50czwvZW0+IGhhdmUgY2hhbmdlZCwgdGhlcmVmb3JlIGFueSBjYWNoZXMgdGhhdCBhIGxheW91dCBtYW5hZ2VyCi0gKiBjb250YWluaW5nIHRoZSBjb250cm9sIG1heSBoYXZlIGJlZW4ga2VlcGluZyBuZWVkIHRvIGJlIGZsdXNoZWQuIFdoZW4gdGhlCi0gKiBjb250cm9sIGlzIHJlc2l6ZWQsIHRoZSBjaGFuZ2VkIGZsYWcgd2lsbCBiZSA8Y29kZT5mYWxzZTwvY29kZT4sIHNvIGxheW91dAotICogbWFuYWdlciBjYWNoZXMgY2FuIGJlIHJldGFpbmVkLiAKLSAqIDwvcD4KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjY29tcHV0ZVNpemUKLSAqLwotcHVibGljIHZvaWQgcGFjayAoYm9vbGVhbiBjaGFuZ2VkKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlzZXRTaXplIChjb21wdXRlU2l6ZSAoU1dULkRFRkFVTFQsIFNXVC5ERUZBVUxULCBjaGFuZ2VkKSk7Ci19Ci1pbnQgcHJvY2Vzc0RlZmF1bHRTZWxlY3Rpb24gKE9iamVjdCBjYWxsRGF0YSkgewotCXBvc3RFdmVudCAoU1dULkRlZmF1bHRTZWxlY3Rpb24pOwotCXJldHVybiAwOwotfQotaW50IHByb2Nlc3NGb2N1c0luICgpIHsKLQlzZW5kRXZlbnQgKFNXVC5Gb2N1c0luKTsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzRm9jdXNPdXQgKCkgewotCXNlbmRFdmVudCAoU1dULkZvY3VzT3V0KTsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzSGVscCAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0Jc2VuZEhlbHBFdmVudCAoY2FsbERhdGEpOwotCXJldHVybiAwOwotfQotaW50IHByb2Nlc3NLZXlEb3duIChPYmplY3QgY2FsbERhdGEpIHsKLQlNYWNFdmVudCBtYWNFdmVudCA9IChNYWNFdmVudCkgY2FsbERhdGE7Ci0JaWYgKHRyYW5zbGF0ZVRyYXZlcnNhbCAobWFjRXZlbnQpKQotCQlyZXR1cm4gT1Mua05vRXJyOwotCS8vIHdpZGdldCBjb3VsZCBiZSBkaXNwb3NlZCBhdCB0aGlzIHBvaW50Ci0JaWYgKGlzRGlzcG9zZWQgKCkpIHJldHVybiAwOwotCXJldHVybiBzZW5kS2V5RXZlbnQgKFNXVC5LZXlEb3duLCBtYWNFdmVudCk7Ci19Ci1pbnQgcHJvY2Vzc0tleVVwIChPYmplY3QgY2FsbERhdGEpIHsKLQkvLyB3aWRnZXQgY291bGQgYmUgZGlzcG9zZWQgYXQgdGhpcyBwb2ludAotCWlmIChpc0Rpc3Bvc2VkICgpKSByZXR1cm4gMDsKLQlyZXR1cm4gc2VuZEtleUV2ZW50IChTV1QuS2V5VXAsIChNYWNFdmVudCkgY2FsbERhdGEpOwotfQotaW50IHByb2Nlc3NNb2RpZnkgKE9iamVjdCBjYWxsRGF0YSkgewotCXNlbmRFdmVudCAoU1dULk1vZGlmeSk7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc01vdXNlRG93biAoTWFjTW91c2VFdmVudCBtbUV2ZW50KSB7Ci0JRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKLQlTaGVsbCBzaGVsbCA9IGdldFNoZWxsICgpOwotCWRpc3BsYXkuaGlkZVRvb2xUaXAgKCk7Ci0gICAgaW50IGJ1dHRvbj0gbW1FdmVudC5nZXRCdXR0b24oKTsKLQlzZW5kTW91c2VFdmVudCAoU1dULk1vdXNlRG93biwgYnV0dG9uLCBtbUV2ZW50KTsKLQlpZiAoYnV0dG9uID09IDIgJiYgaG9va3MgKFNXVC5EcmFnRGV0ZWN0KSkgewotCQlzZW5kRXZlbnQgKFNXVC5EcmFnRGV0ZWN0KTsKLQl9Ci0JaWYgKGJ1dHRvbiA9PSAzICYmIG1lbnUgIT0gbnVsbCkgewotICAgICAgICAvKiBBVwotCQlPUy5YbVByb2Nlc3NUcmF2ZXJzYWwgKGhhbmRsZSwgT1MuWG1UUkFWRVJTRV9DVVJSRU5UKTsKLQkJbWVudS5zZXRWaXNpYmxlICh0cnVlKTsKLQkJKi8KLQl9Ci0JaW50IGNsaWNrVGltZSA9IGRpc3BsYXkuZ2V0RG91YmxlQ2xpY2tUaW1lICgpOwotCWludCBsYXN0VGltZSA9IGRpc3BsYXkubGFzdFRpbWUsIGV2ZW50VGltZSA9IG1tRXZlbnQuZ2V0V2hlbigpOwotCWludCBsYXN0QnV0dG9uID0gZGlzcGxheS5sYXN0QnV0dG9uLCBldmVudEJ1dHRvbiA9IGJ1dHRvbjsKLQlpZiAobGFzdEJ1dHRvbiA9PSBldmVudEJ1dHRvbiAmJiBsYXN0VGltZSAhPSAwICYmIE1hdGguYWJzIChsYXN0VGltZSAtIGV2ZW50VGltZSkgPD0gY2xpY2tUaW1lKSB7Ci0JCXNlbmRNb3VzZUV2ZW50IChTV1QuTW91c2VEb3VibGVDbGljaywgZXZlbnRCdXR0b24sIG1tRXZlbnQpOwotCX0KLQlkaXNwbGF5Lmxhc3RUaW1lID0gZXZlbnRUaW1lID09IDAgPyAxIDogZXZlbnRUaW1lOwotCWRpc3BsYXkubGFzdEJ1dHRvbiA9IGV2ZW50QnV0dG9uOwogCitpbnQga0V2ZW50Q29udHJvbENvbnRleHR1YWxNZW51Q2xpY2sgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpZiAobWVudSAhPSBudWxsICYmICFtZW51LmlzRGlzcG9zZWQgKCkpIHsKKwkJb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCBwdCA9IG5ldyBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBvaW50ICgpOworCQlPUy5HZXRFdmVudFBhcmFtZXRlciAodGhlRXZlbnQsIE9TLmtFdmVudFBhcmFtTW91c2VMb2NhdGlvbiwgT1MudHlwZVFEUG9pbnQsIG51bGwsIHB0LnNpemVvZiwgbnVsbCwgcHQpOworCQlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKTsKKwkJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAoaGFuZGxlKTsKKwkJT1MuR2V0V2luZG93Qm91bmRzICh3aW5kb3csIChzaG9ydCkgT1Mua1dpbmRvd0NvbnRlbnRSZ24sIHJlY3QpOworCQltZW51LnNldExvY2F0aW9uIChwdC5oICsgcmVjdC5sZWZ0LCBwdC52ICsgcmVjdC50b3ApOworCQltZW51LnNldFZpc2libGUgKHRydWUpOworCQlyZXR1cm4gT1Mubm9FcnI7CisJfQorCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRDb250cm9sRHJhdyAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWludCByZXN1bHQgPSBzdXBlci5rRXZlbnRDb250cm9sRHJhdyAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaW50IFtdIHRoZUNvbnRyb2wgPSBuZXcgaW50IFsxXTsKKwlPUy5HZXRFdmVudFBhcmFtZXRlciAodGhlRXZlbnQsIE9TLmtFdmVudFBhcmFtRGlyZWN0T2JqZWN0LCBPUy50eXBlQ29udHJvbFJlZiwgbnVsbCwgNCwgbnVsbCwgdGhlQ29udHJvbCk7CisJaWYgKHRoZUNvbnRyb2wgWzBdICE9IGhhbmRsZSkgcmV0dXJuIHJlc3VsdDsKKwlpZiAoIWhvb2tzIChTV1QuUGFpbnQpICYmICFmaWx0ZXJzIChTV1QuUGFpbnQpKSByZXR1cm4gcmVzdWx0OworCisJLyogUmV0cmlldmUgdGhlIGRhbWFnZSByZWdpb24gKi8KKwlpbnQgW10gcmVnaW9uID0gbmV3IGludCBbMV07CQorCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1SZ25IYW5kbGUsIE9TLnR5cGVRRFJnbkhhbmRsZSwgbnVsbCwgNCwgbnVsbCwgcmVnaW9uKTsKKwlSZWN0IGJvdW5kcyA9IG5ldyBSZWN0ICgpOworCU9TLkdldFJlZ2lvbkJvdW5kcyAocmVnaW9uIFswXSwgYm91bmRzKTsKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChoYW5kbGUsIHJlY3QpOworCWlmICghT1MuU2VjdFJlY3QgKHJlY3QsIGJvdW5kcywgYm91bmRzKSkgcmV0dXJuIHJlc3VsdDsKKwlPUy5PZmZzZXRSZWN0IChib3VuZHMsIChzaG9ydCkgLXJlY3QubGVmdCwgKHNob3J0KSAtcmVjdC50b3ApOworCisJR0NEYXRhIGRhdGEgPSBuZXcgR0NEYXRhICgpOworCWRhdGEucGFpbnRFdmVudCA9IHRoZUV2ZW50OworCUdDIGdjID0gR0MuY2FyYm9uX25ldyAodGhpcywgZGF0YSk7CisJCisJLyogU2VuZCB0aGUgcGFpbnQgZXZlbnQgKi8KKwlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKKwlldmVudC5nYyA9IGdjOworCWV2ZW50LnggPSBib3VuZHMubGVmdDsKKwlldmVudC55ID0gYm91bmRzLnRvcDsKKwlldmVudC53aWR0aCA9IGJvdW5kcy5yaWdodCAtIGJvdW5kcy5sZWZ0OworCWV2ZW50LmhlaWdodCA9IGJvdW5kcy5ib3R0b20gLSBib3VuZHMudG9wOworLy8JZ2Muc2V0Q2xpcHBpbmcgKFJlZ2lvbi5jYXJib25fbmV3IChyZWdpb24gWzBdKSk7CisJc2VuZEV2ZW50IChTV1QuUGFpbnQsIGV2ZW50KTsKKwlldmVudC5nYyA9IG51bGw7CisJZ2MuZGlzcG9zZSAoKTsKKworCXJldHVybiByZXN1bHQ7Cit9CisKK2ludCBrRXZlbnRDb250cm9sU2V0Q3Vyc29yIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJQ3Vyc29yIGN1cnNvciA9IGZpbmRDdXJzb3IgKCk7CisJaWYgKGN1cnNvciAhPSBudWxsKSB7CisJCXNldEN1cnNvciAoY3Vyc29yLmhhbmRsZSk7CisJCXJldHVybiBPUy5ub0VycjsKKwl9CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKworaW50IGtFdmVudENvbnRyb2xTZXRGb2N1c1BhcnQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCWlmICghZGlzcGxheS5pZ25vcmVGb2N1cykgeworCQlzaG9ydCBbXSBwYXJ0ID0gbmV3IHNob3J0IFsxXTsKKwkJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbUNvbnRyb2xQYXJ0LCBPUy50eXBlQ29udHJvbFBhcnRDb2RlLCBudWxsLCAyLCBudWxsLCBwYXJ0KTsKKwkJc2VuZEZvY3VzRXZlbnQgKHBhcnQgWzBdICE9IDApOworCX0KKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQkKKworaW50IGtFdmVudE1vdXNlRG93biAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCVNoZWxsIHNoZWxsID0gZ2V0U2hlbGwgKCk7CisJaWYgKChzdGF0ZSAmIEdSQUIpICE9IDApIHsKKwkJaW50IFtdIGNsaWNrQ291bnQgPSBuZXcgaW50IFsxXTsKKwkJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbUNsaWNrQ291bnQsIE9TLnR5cGVVSW50MzIsIG51bGwsIDQsIG51bGwsIGNsaWNrQ291bnQpOworCQlzZW5kTW91c2VFdmVudCAoU1dULk1vdXNlRG93biwgdGhlRXZlbnQpOworCQlpZiAoY2xpY2tDb3VudCBbMF0gPT0gMikgc2VuZE1vdXNlRXZlbnQgKFNXVC5Nb3VzZURvdWJsZUNsaWNrLCB0aGVFdmVudCk7CisJCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisJCWRpc3BsYXkuZ3JhYkNvbnRyb2wgPSB0aGlzOworCX0KIAkvKgogCSogSXQgaXMgcG9zc2libGUgdGhhdCB0aGUgc2hlbGwgbWF5IGJlCiAJKiBkaXNwb3NlZCBhdCB0aGlzIHBvaW50LiAgSWYgdGhpcyBoYXBwZW5zCiAJKiBkb24ndCBzZW5kIHRoZSBhY3RpdmF0ZSBhbmQgZGVhY3RpdmF0ZQogCSogZXZlbnRzLgotCSovCisJKi8JCiAJaWYgKCFzaGVsbC5pc0Rpc3Bvc2VkICgpKSB7CiAJCXNoZWxsLnNldEFjdGl2ZUNvbnRyb2wgKHRoaXMpOwogCX0KLQlyZXR1cm4gMDsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOwogfQotaW50IHByb2Nlc3NNb3VzZUVudGVyIChNYWNNb3VzZUV2ZW50IG1tZSkgewotICAgIC8qIEFXCi0JWENyb3NzaW5nRXZlbnQgeEV2ZW50ID0gbmV3IFhDcm9zc2luZ0V2ZW50ICgpOwotCU9TLm1lbW1vdmUgKHhFdmVudCwgY2FsbERhdGEsIFhDcm9zc2luZ0V2ZW50LnNpemVvZik7Ci0JaWYgKHhFdmVudC5tb2RlICE9IE9TLk5vdGlmeU5vcm1hbCkgcmV0dXJuIDA7Ci0JaWYgKHhFdmVudC5zdWJ3aW5kb3cgIT0gMCkgcmV0dXJuIDA7Ci0gICAgKi8KLQlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKLQlQb2ludCBwPSBNYWNVdGlsLnRvQ29udHJvbChoYW5kbGUsIG1tZS5nZXRXaGVyZSgpKTsKLQlldmVudC54ID0gcC54OwotCWV2ZW50LnkgPSBwLnk7Ci0JcG9zdEV2ZW50IChTV1QuTW91c2VFbnRlciwgZXZlbnQpOwotCXJldHVybiAwOwotfQotaW50IHByb2Nlc3NNb3VzZU1vdmUgKE1hY01vdXNlRXZlbnQgbW1lKSB7Ci0JRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKLQlkaXNwbGF5LmFkZE1vdXNlSG92ZXJUaW1lT3V0IChoYW5kbGUpOwotCXNlbmRNb3VzZUV2ZW50IChTV1QuTW91c2VNb3ZlLCAwLCBtbWUpOwotCXJldHVybiAwOwotfQotaW50IHByb2Nlc3NNb3VzZUV4aXQgKE1hY01vdXNlRXZlbnQgbW1lKSB7Ci0JRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKLQlkaXNwbGF5LnJlbW92ZU1vdXNlSG92ZXJUaW1lT3V0ICgpOwotCWRpc3BsYXkuaGlkZVRvb2xUaXAgKCk7Ci0gICAgLyogQVcKLQlYQ3Jvc3NpbmdFdmVudCB4RXZlbnQgPSBuZXcgWENyb3NzaW5nRXZlbnQgKCk7Ci0JT1MubWVtbW92ZSAoeEV2ZW50LCBjYWxsRGF0YSwgWENyb3NzaW5nRXZlbnQuc2l6ZW9mKTsKLQlpZiAoeEV2ZW50Lm1vZGUgIT0gT1MuTm90aWZ5Tm9ybWFsKSByZXR1cm4gMDsKLQlpZiAoeEV2ZW50LnN1YndpbmRvdyAhPSAwKSByZXR1cm4gMDsKLQkqLwotCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOwotCVBvaW50IHA9IE1hY1V0aWwudG9Db250cm9sKGhhbmRsZSwgbW1lLmdldFdoZXJlKCkpOwotCWV2ZW50LnggPSBwLng7Ci0JZXZlbnQueSA9IHAueTsKLQlwb3N0RXZlbnQgKFNXVC5Nb3VzZUV4aXQsIGV2ZW50KTsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzTW91c2VIb3ZlciAoTWFjTW91c2VFdmVudCBtbWUpIHsKLQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOwotCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOwotCVBvaW50IGxvY2FsID0gdG9Db250cm9sIChkaXNwbGF5LmdldEN1cnNvckxvY2F0aW9uICgpKTsKLQlldmVudC54ID0gbG9jYWwueDsgZXZlbnQueSA9IGxvY2FsLnk7Ci0JcG9zdEV2ZW50IChTV1QuTW91c2VIb3ZlciwgZXZlbnQpOwotCWRpc3BsYXkuc2hvd1Rvb2xUaXAgKGhhbmRsZSwgdG9vbFRpcFRleHQpOwotCXJldHVybiAwOwotfQotaW50IHByb2Nlc3NNb3VzZVVwIChNYWNNb3VzZUV2ZW50IG1tRXZlbnQpIHsKLQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOwotCWRpc3BsYXkuaGlkZVRvb2xUaXAgKCk7Ci0Jc2VuZE1vdXNlRXZlbnQgKFNXVC5Nb3VzZVVwLCBtbUV2ZW50LmdldEJ1dHRvbigpLCBtbUV2ZW50KTsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzUGFpbnQgKE9iamVjdCBjYWxsRGF0YSkgewotCS8vaWYgKCFob29rcyAoU1dULlBhaW50KSkgcmV0dXJuIDA7Ci0JCi0JLyoKLQlpZiAoIWZWaXNpYmxlIHx8IGZEcmF3Q291bnQgPiAwKSB7Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigiQ29udHJvbC5wcm9jZXNzUGFpbnQ6IHByZW1hdHVyZSBleGl0Iik7Ci0JCXJldHVybiAwOwotCX0KLQkqLwotICAgIC8qIEFXCi0JZXZlbnQuY291bnQgPSB4RXZlbnQuY291bnQ7Ci0JZXZlbnQudGltZSA9IE9TLlh0TGFzdFRpbWVzdGFtcFByb2Nlc3NlZCAoeERpc3BsYXkpOwotICAgICovCi0gICAgCi0JR0MgZ2M9IG5ldyBHQyAodGhpcyk7Ci0JTWFjQ29udHJvbEV2ZW50IG1lPSAoTWFjQ29udHJvbEV2ZW50KSBjYWxsRGF0YTsKLQlSZWN0YW5nbGUgcj0gZ2MuY2FyYm9uX2ZvY3VzKG1lLmdldERhbWFnZVJlZ2lvbkhhbmRsZSgpKTsKLQlpZiAociA9PSBudWxsIHx8ICFyLmlzRW1wdHkoKSkgewotCQkJCQotCQlpZiAoIU1hY1V0aWwuSElWSUVXKSB7Ci0JCQkvLyBlcmFzZSBiYWNrZ3JvdW5kCi0JCQkvL2lmICgoc3RhdGUgJiBDQU5WQVMpICE9IDApIHsKLQkJCQlpZiAoKHN0eWxlICYgU1dULk5PX0JBQ0tHUk9VTkQpID09IDApIHsKLQkJCQkJLy9nYy5zZXRCYWNrZ3JvdW5kKGdldERpc3BsYXkoKS5nZXRTeXN0ZW1Db2xvcihTV1QuQ09MT1JfWUVMTE9XKSk7Ci0JCQkJCWdjLmZpbGxSZWN0YW5nbGUocik7Ci0JCQkJfQotCQkJLy99Ci0JCX0KLQkJCi0JCWlmIChob29rcyAoU1dULlBhaW50KSkgewotCQkJRXZlbnQgZXZlbnQgPSBuZXcgRXZlbnQoKTsKLQkJCWV2ZW50LmdjID0gZ2M7Ci0JCQlldmVudC54ID0gci54OyAgZXZlbnQueSA9IHIueTsKLQkJCWV2ZW50LndpZHRoID0gci53aWR0aDsgIGV2ZW50LmhlaWdodCA9IHIuaGVpZ2h0OwotCQkJCi0JCQlzZW5kRXZlbnQgKFNXVC5QYWludCwgZXZlbnQpOwotCQl9Ci0JfQotCQotCWdjLmNhcmJvbl91bmZvY3VzICgpOwotCQotCWlmICghZ2MuaXNEaXNwb3NlZCAoKSkKLQkJZ2MuZGlzcG9zZSAoKTsKIAotCXJldHVybiAwOworaW50IGtFdmVudE1vdXNlRHJhZ2dlZCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXNlbmRNb3VzZUV2ZW50IChTV1QuTW91c2VNb3ZlLCB0aGVFdmVudCk7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKIH0KLWludCBwcm9jZXNzUmVzaXplIChPYmplY3QgY2FsbERhdGEpIHsKLQlzZW5kRXZlbnQgKFNXVC5SZXNpemUpOwotCS8vIHdpZGdldCBjb3VsZCBiZSBkaXNwb3NlZCBhdCB0aGlzIHBvaW50Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc1NlbGVjdGlvbiAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0JcG9zdEV2ZW50IChTV1QuU2VsZWN0aW9uKTsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzU2V0Rm9jdXMgKE9iamVjdCBjYWxsRGF0YSkgewotCS8qCi0JKiBJZ25vcmUgZm9jdXMgY2hhbmdlIGV2ZW50cyB3aGVuIHRoZSB3aW5kb3cgZ2V0dGluZyBvciBsb3NpbmcKLQkqIGZvY3VzIGlzIGEgbWVudS4gIEJlY2F1c2UgWG1HZXRGb2N1c1dpZGdldCgpIGRvZXMgbm90IGFuc3dlcgotCSogdGhlIG1lbnUgc2hlbGwgKGl0IGFuc3dlcnMgdGhlIG1lbnUgcGFyZW50KSwgaXQgaXMgbmVjZXNzYXJ5Ci0JKiB0byB1c2UgWEdldElucHV0Rm9jdXMoKSB0byBnZXQgdGhlIHJlYWwgWCBmb2N1cyB3aW5kb3cuCi0JKi8KLSAgICAvKiBBVwotCWludCB4RGlzcGxheSA9IHhFdmVudC5kaXNwbGF5OwotCWlmICh4RGlzcGxheSA9PSAwKSByZXR1cm4gMDsKLQlpbnQgW10gdW51c2VkID0gbmV3IGludCBbMV0sIHhXaW5kb3cgPSBuZXcgaW50IFsxXTsKLQlPUy5YR2V0SW5wdXRGb2N1cyAoeERpc3BsYXksIHhXaW5kb3csIHVudXNlZCk7Ci0JaWYgKHhXaW5kb3cgWzBdICE9IDApIHsKLQkJaW50IHdpZGdldCA9IE9TLlh0V2luZG93VG9XaWRnZXQgKHhEaXNwbGF5LCB4V2luZG93IFswXSk7Ci0JCWlmICh3aWRnZXQgIT0gMCAmJiBPUy5YdENsYXNzICh3aWRnZXQpID09IE9TLlhtTWVudVNoZWxsV2lkZ2V0Q2xhc3MgKCkpIHJldHVybiAwOwotCX0KLSAgICAqLwotCS8qIFByb2Nlc3MgdGhlIGZvY3VzIGNoYW5nZSBmb3IgdGhlIHdpZGdldCAqLwogCi0JU2hlbGwgc2hlbGwgPSBnZXRTaGVsbCAoKTsKLQlCb29sZWFuIGIgPSAoQm9vbGVhbikgY2FsbERhdGE7Ci0JaWYgKGIuYm9vbGVhblZhbHVlICgpKSB7Ci0JCi0JCXByb2Nlc3NGb2N1c0luICgpOwotCQkvLyB3aWRnZXQgY291bGQgYmUgZGlzcG9zZWQgYXQgdGhpcyBwb2ludAotCQkvKgotCQkqIEl0IGlzIHBvc3NpYmxlIHRoYXQgdGhlIHNoZWxsIG1heSBiZQotCQkqIGRpc3Bvc2VkIGF0IHRoaXMgcG9pbnQuICBJZiB0aGlzIGhhcHBlbnMKLQkJKiBkb24ndCBzZW5kIHRoZSBhY3RpdmF0ZSBhbmQgZGVhY3RpdmF0ZQotCQkqIGV2ZW50cy4KLQkJKi8KLQkJaWYgKCFzaGVsbC5pc0Rpc3Bvc2VkICgpKSB7Ci0JCQlzaGVsbC5zZXRBY3RpdmVDb250cm9sICh0aGlzKTsKLQkJfQotCX0gZWxzZSB7Ci0JCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CitpbnQga0V2ZW50TW91c2VNb3ZlZCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXNlbmRNb3VzZUV2ZW50IChTV1QuTW91c2VNb3ZlLCB0aGVFdmVudCk7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KIAotCQlwcm9jZXNzRm9jdXNPdXQgKCk7Ci0JCS8vIHdpZGdldCBjb3VsZCBiZSBkaXNwb3NlZCBhdCB0aGlzIHBvaW50Ci0JCS8qCi0JCSAqIEl0IGlzIHBvc3NpYmxlIHRoYXQgdGhlIHNoZWxsIG1heSBiZQotCQkgKiBkaXNwb3NlZCBhdCB0aGlzIHBvaW50LiAgSWYgdGhpcyBoYXBwZW5zCi0JCSAqIGRvbid0IHNlbmQgdGhlIGFjdGl2YXRlIGFuZCBkZWFjdGl2YXRlCi0JCSAqIGV2ZW50cy4KLQkJICovCi0JCWlmICghc2hlbGwuaXNEaXNwb3NlZCAoKSkgewotCQkJQ29udHJvbCBjb250cm9sID0gZGlzcGxheS5nZXRGb2N1c0NvbnRyb2wgKCk7Ci0JCQlpZiAoY29udHJvbCA9PSBudWxsIHx8IHNoZWxsICE9IGNvbnRyb2wuZ2V0U2hlbGwgKCkgKSB7Ci0JCQkJc2hlbGwuc2V0QWN0aXZlQ29udHJvbCAobnVsbCk7Ci0JCQl9Ci0JCX0KK2ludCBrRXZlbnRNb3VzZVVwIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJc2VuZE1vdXNlRXZlbnQgKFNXVC5Nb3VzZVVwLCB0aGVFdmVudCk7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKworaW50IGtFdmVudFJhd0tleURvd24gKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpbnQgW10ga2V5Q29kZSA9IG5ldyBpbnQgWzFdOworCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1LZXlDb2RlLCBPUy50eXBlVUludDMyLCBudWxsLCBrZXlDb2RlLmxlbmd0aCAqIDQsIG51bGwsIGtleUNvZGUpOworCS8vTk9UIERPTkUKKwlpZiAoa2V5Q29kZSBbMF0gPT0gMTE0KSB7CisJCS8vSEVMUCBLRVkKIAl9Ci0JcmV0dXJuIDA7CisJaWYgKCFzZW5kS2V5RXZlbnQgKFNXVC5LZXlEb3duLCB0aGVFdmVudCkpIHJldHVybiBPUy5ub0VycjsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOwogfQotdm9pZCBwcm9wYWdhdGVDaGlsZHJlbiAoYm9vbGVhbiBlbmFibGVkKSB7Ci0JcHJvcGFnYXRlV2lkZ2V0IChlbmFibGVkKTsKKworaW50IGtFdmVudFJhd0tleU1vZGlmaWVyc0NoYW5nZWQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpbnQgW10gbW9kaWZpZXJzID0gbmV3IGludCBbMV07CisJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbUtleU1vZGlmaWVycywgT1MudHlwZVVJbnQzMiwgbnVsbCwgbW9kaWZpZXJzLmxlbmd0aCAqIDQsIG51bGwsIG1vZGlmaWVycyk7CisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlpbnQgbGFzdE1vZGlmaWVycyA9IGRpc3BsYXkubGFzdE1vZGlmaWVyczsKKwlpbnQgdHlwZSA9IFNXVC5LZXlVcDsKKwlpZiAoKG1vZGlmaWVycyBbMF0gJiBPUy5zaGlmdEtleSkgIT0gMCAmJiAobGFzdE1vZGlmaWVycyAmIE9TLnNoaWZ0S2V5KSA9PSAwKSB0eXBlID0gU1dULktleURvd247CisJaWYgKChtb2RpZmllcnMgWzBdICYgT1MuY29udHJvbEtleSkgIT0gMCAmJiAobGFzdE1vZGlmaWVycyAmIE9TLmNvbnRyb2xLZXkpID09IDApIHR5cGUgPSBTV1QuS2V5RG93bjsKKwlpZiAoKG1vZGlmaWVycyBbMF0gJiBPUy5jbWRLZXkpICE9IDAgJiYgKGxhc3RNb2RpZmllcnMgJiBPUy5jbWRLZXkpID09IDApIHR5cGUgPSBTV1QuS2V5RG93bjsKKwlpZiAoKG1vZGlmaWVycyBbMF0gJiBPUy5vcHRpb25LZXkpICE9IDAgJiYgKGxhc3RNb2RpZmllcnMgJiBPUy5vcHRpb25LZXkpID09IDApIHR5cGUgPSBTV1QuS2V5RG93bjsKKwlib29sZWFuIHJlc3VsdCA9IHNlbmRLZXlFdmVudCAodHlwZSwgdGhlRXZlbnQpOworCWRpc3BsYXkubGFzdE1vZGlmaWVycyA9IG1vZGlmaWVycyBbMF07CisJcmV0dXJuIHJlc3VsdCA/IE9TLmV2ZW50Tm90SGFuZGxlZEVyciA6IE9TLm5vRXJyOwogfQotdm9pZCBwcm9wYWdhdGVXaWRnZXQgKGJvb2xlYW4gZW5hYmxlZCkgewotCXByb3BhZ2F0ZUhhbmRsZSAoZW5hYmxlZCwgaGFuZGxlKTsKKworaW50IGtFdmVudFJhd0tleVJlcGVhdCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWlmICghc2VuZEtleUV2ZW50IChTV1QuS2V5RG93biwgdGhlRXZlbnQpKSByZXR1cm4gT1Mubm9FcnI7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKIH0KLXZvaWQgcmVhbGl6ZUNoaWxkcmVuICgpIHsKLQlpZiAoIWlzRW5hYmxlZCAoKSkgcHJvcGFnYXRlV2lkZ2V0IChmYWxzZSk7CisKK2ludCBrRXZlbnRSYXdLZXlVcCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWlmICghc2VuZEtleUV2ZW50IChTV1QuS2V5VXAsIHRoZUV2ZW50KSkgcmV0dXJuIE9TLm5vRXJyOworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7CiB9Ci0vKioKLSAqIENhdXNlcyB0aGUgZW50aXJlIGJvdW5kcyBvZiB0aGUgcmVjZWl2ZXIgdG8gYmUgbWFya2VkCi0gKiBhcyBuZWVkaW5nIHRvIGJlIHJlZHJhd24uIFRoZSBuZXh0IHRpbWUgYSBwYWludCByZXF1ZXN0Ci0gKiBpcyBwcm9jZXNzZWQsIHRoZSBjb250cm9sIHdpbGwgYmUgY29tcGxldGVseSBwYWludGVkLgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICN1cGRhdGUKLSAqLworCitwdWJsaWMgdm9pZCBtb3ZlQWJvdmUgKENvbnRyb2wgY29udHJvbCkgeworCWNoZWNrV2lkZ2V0KCk7CisJaW50IGluT3RoZXIgPSAwOworCWlmIChjb250cm9sICE9IG51bGwpIHsKKwkJaWYgKGNvbnRyb2wuaXNEaXNwb3NlZCAoKSkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKKwkJaWYgKHBhcmVudCAhPSBjb250cm9sLnBhcmVudCkgcmV0dXJuOworCQlpbk90aGVyID0gY29udHJvbC50b3BIYW5kbGUgKCk7CisJfQorCXNldFpPcmRlciAoY29udHJvbCwgdHJ1ZSk7Cit9CisKK3B1YmxpYyB2b2lkIG1vdmVCZWxvdyAoQ29udHJvbCBjb250cm9sKSB7CisJY2hlY2tXaWRnZXQoKTsKKwlpbnQgaW5PdGhlciA9IDA7CisJaWYgKGNvbnRyb2wgIT0gbnVsbCkgeworCQlpZiAoY29udHJvbC5pc0Rpc3Bvc2VkICgpKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCQlpZiAocGFyZW50ICE9IGNvbnRyb2wucGFyZW50KSByZXR1cm47CisJCWluT3RoZXIgPSBjb250cm9sLnRvcEhhbmRsZSAoKTsKKwl9CisJc2V0Wk9yZGVyIChjb250cm9sLCBmYWxzZSk7Cit9CisKK3B1YmxpYyB2b2lkIHBhY2sgKCkgeworCWNoZWNrV2lkZ2V0KCk7CisJcGFjayAodHJ1ZSk7Cit9CisKK3B1YmxpYyB2b2lkIHBhY2sgKGJvb2xlYW4gY2hhbmdlZCkgeworCWNoZWNrV2lkZ2V0KCk7CisJc2V0U2l6ZSAoY29tcHV0ZVNpemUgKFNXVC5ERUZBVUxULCBTV1QuREVGQVVMVCwgY2hhbmdlZCkpOworfQorCiBwdWJsaWMgdm9pZCByZWRyYXcgKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JcmVkcmF3V2lkZ2V0ICgwLCAwLCAwLCAwLCBmYWxzZSk7CisJcmVkcmF3V2lkZ2V0IChoYW5kbGUpOwogfQotLyoqCi0gKiBDYXVzZXMgdGhlIHJlY3Rhbmd1bGFyIGFyZWEgb2YgdGhlIHJlY2VpdmVyIHNwZWNpZmllZCBieQotICogdGhlIGFyZ3VtZW50cyB0byBiZSBtYXJrZWQgYXMgbmVlZGluZyB0byBiZSByZWRyYXduLiAKLSAqIFRoZSBuZXh0IHRpbWUgYSBwYWludCByZXF1ZXN0IGlzIHByb2Nlc3NlZCwgdGhhdCBhcmVhIG9mCi0gKiB0aGUgcmVjZWl2ZXIgd2lsbCBiZSBwYWludGVkLiBJZiB0aGUgPGNvZGU+YWxsPC9jb2RlPiBmbGFnCi0gKiBpcyA8Y29kZT50cnVlPC9jb2RlPiwgYW55IGNoaWxkcmVuIG9mIHRoZSByZWNlaXZlciB3aGljaAotICogaW50ZXJzZWN0IHdpdGggdGhlIHNwZWNpZmllZCBhcmVhIHdpbGwgYWxzbyBwYWludCB0aGVpcgotICogaW50ZXJzZWN0aW5nIGFyZWFzLiBJZiB0aGUgPGNvZGU+YWxsPC9jb2RlPiBmbGFnIGlzIAotICogPGNvZGU+ZmFsc2U8L2NvZGU+LCB0aGUgY2hpbGRyZW4gd2lsbCBub3QgYmUgcGFpbnRlZC4KLSAqCi0gKiBAcGFyYW0geCB0aGUgeCBjb29yZGluYXRlIG9mIHRoZSBhcmVhIHRvIGRyYXcKLSAqIEBwYXJhbSB5IHRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIGFyZWEgdG8gZHJhdwotICogQHBhcmFtIHdpZHRoIHRoZSB3aWR0aCBvZiB0aGUgYXJlYSB0byBkcmF3Ci0gKiBAcGFyYW0gaGVpZ2h0IHRoZSBoZWlnaHQgb2YgdGhlIGFyZWEgdG8gZHJhdwotICogQHBhcmFtIGFsbCA8Y29kZT50cnVlPC9jb2RlPiBpZiBjaGlsZHJlbiBzaG91bGQgcmVkcmF3LCBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICN1cGRhdGUKLSAqLworCiBwdWJsaWMgdm9pZCByZWRyYXcgKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBib29sZWFuIGFsbCkgewogCWNoZWNrV2lkZ2V0ICgpOwotCWlmICh3aWR0aCA8PSAwIHx8IGhlaWdodCA8PSAwKSByZXR1cm47Ci0JcmVkcmF3V2lkZ2V0ICh4LCB5LCB3aWR0aCwgaGVpZ2h0LCBhbGwpOworCWlmICghT1MuSXNDb250cm9sVmlzaWJsZSAoaGFuZGxlKSkgcmV0dXJuOworCVJlY3QgcmVjdCA9IG5ldyBSZWN0ICgpOworCU9TLkdldENvbnRyb2xCb3VuZHMgKGhhbmRsZSwgcmVjdCk7CisJeCArPSByZWN0LmxlZnQ7CisJeSArPSByZWN0LnRvcDsKKwlPUy5TZXRSZWN0IChyZWN0LCAoc2hvcnQpIHgsIChzaG9ydCkgeSwgKHNob3J0KSh4ICsgd2lkdGgpLCAoc2hvcnQpKHkgKyBoZWlnaHQpKTsKKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChoYW5kbGUpOworCU9TLkludmFsV2luZG93UmVjdCAod2luZG93LCByZWN0KTsKIH0KLXZvaWQgcmVkcmF3V2lkZ2V0IChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwgYm9vbGVhbiBhbGwpIHsKLQlyZWRyYXdIYW5kbGUgKHgsIHksIHdpZHRoLCBoZWlnaHQsIGhhbmRsZSwgYWxsKTsKKwordm9pZCByZWdpc3RlciAoKSB7CisJc3VwZXIucmVnaXN0ZXIgKCk7CisJV2lkZ2V0VGFibGUucHV0IChoYW5kbGUsIHRoaXMpOwogfQorCit2b2lkIHJlbGVhc2VIYW5kbGUgKCkgeworCXN1cGVyLnJlbGVhc2VIYW5kbGUgKCk7CisJaGFuZGxlID0gMDsKK30KKwogdm9pZCByZWxlYXNlV2lkZ2V0ICgpIHsKIAlzdXBlci5yZWxlYXNlV2lkZ2V0ICgpOwotCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7Ci0JZGlzcGxheS5yZWxlYXNlVG9vbFRpcEhhbmRsZSAoaGFuZGxlKTsKLQl0b29sVGlwVGV4dCA9IG51bGw7CiAJaWYgKG1lbnUgIT0gbnVsbCAmJiAhbWVudS5pc0Rpc3Bvc2VkICgpKSB7CiAJCW1lbnUuZGlzcG9zZSAoKTsKIAl9CkBAIC0xNTQ3LDIzICs3MzcsNyBAQAogCXBhcmVudCA9IG51bGw7CiAJbGF5b3V0RGF0YSA9IG51bGw7CiB9Ci0vKioKLSAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSBjb250cm9sIGlzIG1vdmVkIG9yIHJlc2l6ZWQuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBDb250cm9sTGlzdGVuZXIKLSAqIEBzZWUgI2FkZENvbnRyb2xMaXN0ZW5lcgotICovCisKIHB1YmxpYyB2b2lkIHJlbW92ZUNvbnRyb2xMaXN0ZW5lciAoQ29udHJvbExpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTE1NzEsMjMgKzc0NSw3IEBACiAJZXZlbnRUYWJsZS51bmhvb2sgKFNXVC5Nb3ZlLCBsaXN0ZW5lcik7CiAJZXZlbnRUYWJsZS51bmhvb2sgKFNXVC5SZXNpemUsIGxpc3RlbmVyKTsKIH0KLS8qKgotICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGNvbnRyb2wgZ2FpbnMgb3IgbG9zZXMgZm9jdXMuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBGb2N1c0xpc3RlbmVyCi0gKiBAc2VlICNhZGRGb2N1c0xpc3RlbmVyCi0gKi8KKwogcHVibGljIHZvaWQgcmVtb3ZlRm9jdXNMaXN0ZW5lcihGb2N1c0xpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTE1OTUsNDYgKzc1MywxNCBAQAogCWV2ZW50VGFibGUudW5ob29rKFNXVC5Gb2N1c0luLCBsaXN0ZW5lcik7CiAJZXZlbnRUYWJsZS51bmhvb2soU1dULkZvY3VzT3V0LCBsaXN0ZW5lcik7CiB9Ci0vKioKLSAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSBoZWxwIGV2ZW50cyBhcmUgZ2VuZXJhdGVkIGZvciB0aGUgY29udHJvbC4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIEhlbHBMaXN0ZW5lcgotICogQHNlZSAjYWRkSGVscExpc3RlbmVyCi0gKi8KKwogcHVibGljIHZvaWQgcmVtb3ZlSGVscExpc3RlbmVyIChIZWxwTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWlmIChldmVudFRhYmxlID09IG51bGwpIHJldHVybjsKIAlldmVudFRhYmxlLnVuaG9vayAoU1dULkhlbHAsIGxpc3RlbmVyKTsKIH0KLS8qKgotICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4ga2V5cyBhcmUgcHJlc3NlZCBhbmQgcmVsZWFzZWQgb24gdGhlIHN5c3RlbSBrZXlib2FyZC4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIEtleUxpc3RlbmVyCi0gKiBAc2VlICNhZGRLZXlMaXN0ZW5lcgotICovCisKIHB1YmxpYyB2b2lkIHJlbW92ZUtleUxpc3RlbmVyKEtleUxpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTE2NDIsMjMgKzc2OCw3IEBACiAJZXZlbnRUYWJsZS51bmhvb2soU1dULktleVVwLCBsaXN0ZW5lcik7CiAJZXZlbnRUYWJsZS51bmhvb2soU1dULktleURvd24sIGxpc3RlbmVyKTsKIH0KLS8qKgotICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gbW91c2UgYnV0dG9ucyBhcmUgcHJlc3NlZCBhbmQgcmVsZWFzZWQuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBNb3VzZUxpc3RlbmVyCi0gKiBAc2VlICNhZGRNb3VzZUxpc3RlbmVyCi0gKi8KKwogcHVibGljIHZvaWQgcmVtb3ZlTW91c2VMaXN0ZW5lcihNb3VzZUxpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTE2NjcsNDYgKzc3NywxNCBAQAogCWV2ZW50VGFibGUudW5ob29rKFNXVC5Nb3VzZVVwLCBsaXN0ZW5lcik7CiAJZXZlbnRUYWJsZS51bmhvb2soU1dULk1vdXNlRG91YmxlQ2xpY2ssIGxpc3RlbmVyKTsKIH0KLS8qKgotICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIG1vdXNlIG1vdmVzLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgTW91c2VNb3ZlTGlzdGVuZXIKLSAqIEBzZWUgI2FkZE1vdXNlTW92ZUxpc3RlbmVyCi0gKi8KKwogcHVibGljIHZvaWQgcmVtb3ZlTW91c2VNb3ZlTGlzdGVuZXIoTW91c2VNb3ZlTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWlmIChldmVudFRhYmxlID09IG51bGwpIHJldHVybjsKIAlldmVudFRhYmxlLnVuaG9vayhTV1QuTW91c2VNb3ZlLCBsaXN0ZW5lcik7CiB9Ci0vKioKLSAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSBtb3VzZSBwYXNzZXMgb3IgaG92ZXJzIG92ZXIgY29udHJvbHMuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBNb3VzZVRyYWNrTGlzdGVuZXIKLSAqIEBzZWUgI2FkZE1vdXNlVHJhY2tMaXN0ZW5lcgotICovCisKIHB1YmxpYyB2b2lkIHJlbW92ZU1vdXNlVHJhY2tMaXN0ZW5lcihNb3VzZVRyYWNrTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwpAQCAtMTcxNSw0NTUgKzc5MywyMzMgQEAKIAlldmVudFRhYmxlLnVuaG9vayAoU1dULk1vdXNlRXhpdCwgbGlzdGVuZXIpOwogCWV2ZW50VGFibGUudW5ob29rIChTV1QuTW91c2VIb3ZlciwgbGlzdGVuZXIpOwogfQotLyoqCi0gKiBSZW1vdmVzIHRoZSBsaXN0ZW5lciBmcm9tIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgcmVjZWl2ZXIgbmVlZHMgdG8gYmUgcGFpbnRlZC4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFBhaW50TGlzdGVuZXIKLSAqIEBzZWUgI2FkZFBhaW50TGlzdGVuZXIKLSAqLworCiBwdWJsaWMgdm9pZCByZW1vdmVQYWludExpc3RlbmVyKFBhaW50TGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWlmIChldmVudFRhYmxlID09IG51bGwpIHJldHVybjsKIAlldmVudFRhYmxlLnVuaG9vayhTV1QuUGFpbnQsIGxpc3RlbmVyKTsKLX0vKioKLSAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRyYXZlcnNhbCBldmVudHMgb2NjdXIuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBUcmF2ZXJzZUxpc3RlbmVyCi0gKiBAc2VlICNhZGRUcmF2ZXJzZUxpc3RlbmVyCi0gKi8KK30KKwogcHVibGljIHZvaWQgcmVtb3ZlVHJhdmVyc2VMaXN0ZW5lcihUcmF2ZXJzZUxpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlpZiAoZXZlbnRUYWJsZSA9PSBudWxsKSByZXR1cm47CiAJZXZlbnRUYWJsZS51bmhvb2sgKFNXVC5UcmF2ZXJzZSwgbGlzdGVuZXIpOwogfQotdm9pZCBzZW5kSGVscEV2ZW50IChPYmplY3QgY2FsbERhdGEpIHsKLQlDb250cm9sIGNvbnRyb2wgPSB0aGlzOwotCXdoaWxlIChjb250cm9sICE9IG51bGwpIHsKLQkJaWYgKGNvbnRyb2wuaG9va3MgKFNXVC5IZWxwKSkgewotCQkJY29udHJvbC5wb3N0RXZlbnQgKFNXVC5IZWxwKTsKLQkJCXJldHVybjsKKwkKK3ZvaWQgc2VuZEZvY3VzRXZlbnQgKGJvb2xlYW4gZm9jdXNJbikgeworCVNoZWxsIHNoZWxsID0gZ2V0U2hlbGwgKCk7CisJaWYgKGZvY3VzSW4pIHsKKwkJc2VuZEV2ZW50IChTV1QuRm9jdXNJbik7CisJfSBlbHNlIHsKKwkJc2VuZEV2ZW50IChTV1QuRm9jdXNPdXQpOworCX0KKwkKKwkvKgorCSogSXQgaXMgcG9zc2libGUgdGhhdCB0aGUgc2hlbGwgbWF5IGJlCisJKiBkaXNwb3NlZCBhdCB0aGlzIHBvaW50LiAgSWYgdGhpcyBoYXBwZW5zCisJKiBkb24ndCBzZW5kIHRoZSBhY3RpdmF0ZSBhbmQgZGVhY3RpdmF0ZQorCSogZXZlbnRzLgorCSovCisJaWYgKGZvY3VzSW4pIHsKKwkJaWYgKCFzaGVsbC5pc0Rpc3Bvc2VkICgpKSB7CisJCQlzaGVsbC5zZXRBY3RpdmVDb250cm9sICh0aGlzKTsKIAkJfQotCQljb250cm9sID0gY29udHJvbC5wYXJlbnQ7CisJfSBlbHNlIHsKKwkJaWYgKCFzaGVsbC5pc0Rpc3Bvc2VkICgpKSB7CisJCQlEaXNwbGF5IGRpc3BsYXkgPSBzaGVsbC5nZXREaXNwbGF5ICgpOworCQkJQ29udHJvbCBjb250cm9sID0gZGlzcGxheS5nZXRGb2N1c0NvbnRyb2wgKCk7CisJCQlpZiAoY29udHJvbCA9PSBudWxsIHx8IHNoZWxsICE9IGNvbnRyb2wuZ2V0U2hlbGwgKCkgKSB7CisJCQkJc2hlbGwuc2V0QWN0aXZlQ29udHJvbCAobnVsbCk7CisJCQl9CisJCX0KIAl9CiB9Ci1maW5hbCBpbnQgc2VuZEtleUV2ZW50IChpbnQgdHlwZSwgTWFjRXZlbnQgbUV2ZW50KSB7CisKK2Jvb2xlYW4gc2VuZEtleUV2ZW50IChpbnQgdHlwZSwgaW50IHRoZUV2ZW50KSB7CiAJRXZlbnQgZXZlbnQgPSBuZXcgRXZlbnQgKCk7Ci0gICAgZXZlbnQudGltZSA9IG1FdmVudC5nZXRXaGVuKCk7Ci0Jc2V0S2V5U3RhdGUgKGV2ZW50LCBtRXZlbnQpOwotCXJldHVybiBzZW5kS2V5RXZlbnQgKHR5cGUsIG1FdmVudCwgZXZlbnQpOwotLy8JQ29udHJvbCBjb250cm9sID0gdGhpczsKLS8vCWlmICgoc3RhdGUgJiBDQU5WQVMpICE9IDApIHsKLS8vCQlpZiAoKHN0eWxlICYgU1dULk5PX0ZPQ1VTKSAhPSAwKSB7Ci0vLwkJCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7Ci0vLwkJCWNvbnRyb2wgPSBkaXNwbGF5LmdldEZvY3VzQ29udHJvbCAoKTsKLS8vCQl9Ci0vLwl9Ci0vLwlpZiAoY29udHJvbCAhPSBudWxsKSB7Ci0vLwkJY29udHJvbC5wb3N0RXZlbnQgKHR5cGUsIGV2ZW50KTsKLS8vCX0KKwlldmVudC50eXBlID0gdHlwZTsKKwlzZXRLZXlTdGF0ZSAoZXZlbnQsIHRoZUV2ZW50KTsKKwlyZXR1cm4gc2VuZEtleUV2ZW50ICh0eXBlLCBldmVudCk7CiB9Ci1pbnQgc2VuZEtleUV2ZW50IChpbnQgdHlwZSwgTWFjRXZlbnQgbUV2ZW50LCBFdmVudCBldmVudCkgeworCitib29sZWFuIHNlbmRLZXlFdmVudCAoaW50IHR5cGUsIEV2ZW50IGV2ZW50KSB7CiAJcG9zdEV2ZW50ICh0eXBlLCBldmVudCk7Ci0JcmV0dXJuIDA7CisJcmV0dXJuIHRydWU7CiB9Ci1maW5hbCB2b2lkIHNlbmRNb3VzZUV2ZW50IChpbnQgdHlwZSwgaW50IGJ1dHRvbiwgTWFjTW91c2VFdmVudCBtbWUpIHsKKworYm9vbGVhbiBzZW5kTW91c2VFdmVudCAoaW50IHR5cGUsIGludCB0aGVFdmVudCkgeworCXNob3J0IFtdIGJ1dHRvbiA9IG5ldyBzaG9ydCBbMV07CisJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbU1vdXNlQnV0dG9uLCBPUy50eXBlTW91c2VCdXR0b24sIG51bGwsIDIsIG51bGwsIGJ1dHRvbik7CisJcmV0dXJuIHNlbmRNb3VzZUV2ZW50ICh0eXBlLCBidXR0b24gWzBdLCB0aGVFdmVudCk7Cit9CisKK2Jvb2xlYW4gc2VuZE1vdXNlRXZlbnQgKGludCB0eXBlLCBzaG9ydCBidXR0b24sIGludCB0aGVFdmVudCkgewogCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOwotICAgIGV2ZW50LnRpbWUgPSBtbWUuZ2V0V2hlbigpOwotCWV2ZW50LmJ1dHRvbiA9IGJ1dHRvbjsKLQlQb2ludCBtbD0gTWFjVXRpbC50b0NvbnRyb2woaGFuZGxlLCBtbWUuZ2V0V2hlcmUoKSk7Ci0JZXZlbnQueCA9IG1sLng7ICBldmVudC55ID0gbWwueTsKLQkvLyBBVyBzZXRJbnB1dFN0YXRlIChldmVudCwgbUV2ZW50KTsKLQlldmVudC5zdGF0ZU1hc2s9IG1tZS5nZXRTdGF0ZSgpOworCWV2ZW50LnR5cGUgPSB0eXBlOworCW9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgcHQgPSBuZXcgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCAoKTsKKwlPUy5HZXRFdmVudFBhcmFtZXRlciAodGhlRXZlbnQsIE9TLmtFdmVudFBhcmFtTW91c2VMb2NhdGlvbiwgT1MudHlwZVFEUG9pbnQsIG51bGwsIHB0LnNpemVvZiwgbnVsbCwgcHQpOworCVJlY3QgcmVjdCA9IG5ldyBSZWN0ICgpOworCWludCB3aW5kb3cgPSBPUy5HZXRDb250cm9sT3duZXIgKGhhbmRsZSk7CisJT1MuR2V0V2luZG93Qm91bmRzICh3aW5kb3csIChzaG9ydCkgT1Mua1dpbmRvd0NvbnRlbnRSZ24sIHJlY3QpOworCWV2ZW50LnggPSBwdC5oIC0gcmVjdC5sZWZ0OworCWV2ZW50LnkgPSBwdC52IC0gcmVjdC50b3A7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAoaGFuZGxlLCByZWN0KTsKKwlldmVudC54IC09IHJlY3QubGVmdDsKKwlldmVudC55IC09IHJlY3QudG9wOworCXNldElucHV0U3RhdGUgKGV2ZW50LCB0aGVFdmVudCk7CiAJcG9zdEV2ZW50ICh0eXBlLCBldmVudCk7CisJcmV0dXJuIHRydWU7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgYmFja2dyb3VuZCBjb2xvciB0byB0aGUgY29sb3Igc3BlY2lmaWVkCi0gKiBieSB0aGUgYXJndW1lbnQsIG9yIHRvIHRoZSBkZWZhdWx0IHN5c3RlbSBjb2xvciBmb3IgdGhlIGNvbnRyb2wKLSAqIGlmIHRoZSBhcmd1bWVudCBpcyBudWxsLgotICoKLSAqIEBwYXJhbSBjb2xvciB0aGUgbmV3IGNvbG9yIChvciBudWxsKQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX0FSR1VNRU5UIC0gaWYgdGhlIGFyZ3VtZW50IGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4gCi0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKK2Jvb2xlYW4gc2VuZE1vdXNlRXZlbnQgKGludCB0eXBlLCBzaG9ydCBidXR0b24sIGludCBjaG9yZCwgc2hvcnQgeCwgc2hvcnQgeSwgaW50IG1vZGlmaWVycykgeworCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOworCWV2ZW50LnR5cGUgPSB0eXBlOworCWV2ZW50LnggPSB4OworCWV2ZW50LnkgPSB5OworCXNldElucHV0U3RhdGUgKGV2ZW50LCBidXR0b24sIGNob3JkLCBtb2RpZmllcnMpOworCXNlbmRFdmVudCAodHlwZSwgZXZlbnQpOworCXJldHVybiB0cnVlOworfQorCiBwdWJsaWMgdm9pZCBzZXRCYWNrZ3JvdW5kIChDb2xvciBjb2xvcikgewogCWNoZWNrV2lkZ2V0KCk7Ci0JaW50IHBpeGVsID0gLTE7CiAJaWYgKGNvbG9yICE9IG51bGwpIHsKIAkJaWYgKGNvbG9yLmlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKLQkJcGl4ZWwgPSBjb2xvci5oYW5kbGU7CiAJfQotCXNldEJhY2tncm91bmRQaXhlbCAocGl4ZWwpOworCWJhY2tncm91bmQgPSBjb2xvciAhPSBudWxsID8gY29sb3IuaGFuZGxlIDogbnVsbDsKIH0KLXZvaWQgc2V0QmFja2dyb3VuZFBpeGVsIChpbnQgcGl4ZWwpIHsKLQkvKiBBVwotCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTmZvcmVncm91bmQsIDAsIE9TLlhtTmhpZ2hsaWdodENvbG9yLCAwfTsKLQlPUy5YdEdldFZhbHVlcyAoaGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCU9TLlhtQ2hhbmdlQ29sb3IgKGhhbmRsZSwgcGl4ZWwpOwotCU9TLlh0U2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JKi8KLQlpZiAoYmFja2dyb3VuZCA9PSBwaXhlbCkgcmV0dXJuOwotCWJhY2tncm91bmQgPSBwaXhlbDsKLQlyZWRyYXdIYW5kbGUoMCwgMCwgMCwgMCwgaGFuZGxlLCBmYWxzZSk7Ci19Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3Mgc2l6ZSBhbmQgbG9jYXRpb24gdG8gdGhlIHJlY3Rhbmd1bGFyCi0gKiBhcmVhIHNwZWNpZmllZCBieSB0aGUgYXJndW1lbnRzLiBUaGUgPGNvZGU+eDwvY29kZT4gYW5kIAotICogPGNvZGU+eTwvY29kZT4gYXJndW1lbnRzIGFyZSByZWxhdGl2ZSB0byB0aGUgcmVjZWl2ZXIncwotICogcGFyZW50IChvciBpdHMgZGlzcGxheSBpZiBpdHMgcGFyZW50IGlzIG51bGwpLgotICogPHA+Ci0gKiBOb3RlOiBBdHRlbXB0aW5nIHRvIHNldCB0aGUgd2lkdGggb3IgaGVpZ2h0IG9mIHRoZQotICogcmVjZWl2ZXIgdG8gYSBuZWdhdGl2ZSBudW1iZXIgd2lsbCBjYXVzZSB0aGF0Ci0gKiB2YWx1ZSB0byBiZSBzZXQgdG8gemVybyBpbnN0ZWFkLgotICogPC9wPgotICoKLSAqIEBwYXJhbSB4IHRoZSBuZXcgeCBjb29yZGluYXRlIGZvciB0aGUgcmVjZWl2ZXIKLSAqIEBwYXJhbSB5IHRoZSBuZXcgeSBjb29yZGluYXRlIGZvciB0aGUgcmVjZWl2ZXIKLSAqIEBwYXJhbSB3aWR0aCB0aGUgbmV3IHdpZHRoIGZvciB0aGUgcmVjZWl2ZXIKLSAqIEBwYXJhbSBoZWlnaHQgdGhlIG5ldyBoZWlnaHQgZm9yIHRoZSByZWNlaXZlcgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRCb3VuZHMgKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpbnQgdG9wSGFuZGxlID0gdG9wSGFuZGxlICgpOwotCXdpZHRoID0gTWF0aC5tYXgod2lkdGgsIDApOwotCWhlaWdodCA9IE1hdGgubWF4KGhlaWdodCwgMCk7Ci0JTWFjUmVjdCBicj0gbmV3IE1hY1JlY3QoKTsKLQlzaG9ydFtdIGJvdW5kcz0gYnIuZ2V0RGF0YSgpOwotCXNob3J0W10gcGJvdW5kcz0gbmV3IHNob3J0WzRdOwotCWludGVybmFsR2V0Q29udHJvbEJvdW5kcyh0b3BIYW5kbGUsIGJyKTsKLQlPUy5HZXRDb250cm9sQm91bmRzKHBhcmVudC5oYW5kbGUsIHBib3VuZHMpOwotCWJvb2xlYW4gc2FtZU9yaWdpbjsKLQlpZiAoTWFjVXRpbC5VU0VfRlJBTUUpIHsKLQkJc2FtZU9yaWdpbiA9IGJvdW5kc1sxXSA9PSB4ICYmIGJvdW5kc1swXSA9PSB5OwotCX0gZWxzZSB7Ci0JCXNhbWVPcmlnaW4gPSAoYm91bmRzWzFdLXBib3VuZHNbMV0pID09IHggJiYgKGJvdW5kc1swXS1wYm91bmRzWzBdKSA9PSB5OwotCX0KLQlib29sZWFuIHNhbWVFeHRlbnQgPSAoYm91bmRzWzNdLWJvdW5kc1sxXSkgPT0gd2lkdGggJiYgKGJvdW5kc1syXS1ib3VuZHNbMF0pID09IGhlaWdodDsKLQlpZiAoc2FtZU9yaWdpbiAmJiBzYW1lRXh0ZW50KSByZXR1cm47Ci0JaW50ZXJuYWxTZXRCb3VuZHModG9wSGFuZGxlLCBiciwgcGJvdW5kc1sxXSt4LCBwYm91bmRzWzBdK3ksIHdpZHRoLCBoZWlnaHQpOwotCWlmICghc2FtZU9yaWdpbikgc2VuZEV2ZW50IChTV1QuTW92ZSk7Ci0JaWYgKCFzYW1lRXh0ZW50KSBzZW5kRXZlbnQgKFNXVC5SZXNpemUpOworCXNldEJvdW5kcyAodG9wSGFuZGxlICgpLCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCB0cnVlLCB0cnVlLCB0cnVlKTsKIH0KLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBzaXplIGFuZCBsb2NhdGlvbiB0byB0aGUgcmVjdGFuZ3VsYXIKLSAqIGFyZWEgc3BlY2lmaWVkIGJ5IHRoZSBhcmd1bWVudC4gVGhlIDxjb2RlPng8L2NvZGU+IGFuZCAKLSAqIDxjb2RlPnk8L2NvZGU+IGZpZWxkcyBvZiB0aGUgcmVjdGFuZ2xlIGFyZSByZWxhdGl2ZSB0bwotICogdGhlIHJlY2VpdmVyJ3MgcGFyZW50IChvciBpdHMgZGlzcGxheSBpZiBpdHMgcGFyZW50IGlzIG51bGwpLgotICogPHA+Ci0gKiBOb3RlOiBBdHRlbXB0aW5nIHRvIHNldCB0aGUgd2lkdGggb3IgaGVpZ2h0IG9mIHRoZQotICogcmVjZWl2ZXIgdG8gYSBuZWdhdGl2ZSBudW1iZXIgd2lsbCBjYXVzZSB0aGF0Ci0gKiB2YWx1ZSB0byBiZSBzZXQgdG8gemVybyBpbnN0ZWFkLgotICogPC9wPgotICoKLSAqIEBwYXJhbSByZWN0IHRoZSBuZXcgYm91bmRzIGZvciB0aGUgcmVjZWl2ZXIKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0Qm91bmRzIChSZWN0YW5nbGUgcmVjdCkgewogCWlmIChyZWN0ID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJc2V0Qm91bmRzIChyZWN0LngsIHJlY3QueSwgcmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpOwogfQotLyoqCi0gKiBJZiB0aGUgYXJndW1lbnQgaXMgPGNvZGU+dHJ1ZTwvY29kZT4sIGNhdXNlcyB0aGUgcmVjZWl2ZXIgdG8gaGF2ZQotICogYWxsIG1vdXNlIGV2ZW50cyBkZWxpdmVyZWQgdG8gaXQgdW50aWwgdGhlIG1ldGhvZCBpcyBjYWxsZWQgd2l0aAotICogPGNvZGU+ZmFsc2U8L2NvZGU+IGFzIHRoZSBhcmd1bWVudC4KLSAqCi0gKiBAcGFyYW0gY2FwdHVyZSA8Y29kZT50cnVlPC9jb2RlPiB0byBjYXB0dXJlIHRoZSBtb3VzZSwgYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiB0byByZWxlYXNlIGl0Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldENhcHR1cmUgKGJvb2xlYW4gY2FwdHVyZSkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JU3lzdGVtLm91dC5wcmludGxuKCJDb250cm9sLnNldENhcHR1cmU6IG55aSIpOwotICAgIC8qIEFXCi0JaW50IGRpc3BsYXkgPSBPUy5YdERpc3BsYXkgKGhhbmRsZSk7Ci0JaWYgKGRpc3BsYXkgPT0gMCkgcmV0dXJuOwotCWlmIChjYXB0dXJlKSB7Ci0JCWludCB3aW5kb3cgPSBPUy5YdFdpbmRvdyAoaGFuZGxlKTsKLQkJaWYgKHdpbmRvdyA9PSAwKSByZXR1cm47Ci0JCU9TLlhHcmFiUG9pbnRlciAoCi0JCQlkaXNwbGF5LAotCQkJd2luZG93LAotCQkJMCwKLQkJCU9TLkJ1dHRvblByZXNzTWFzayB8IE9TLkJ1dHRvblJlbGVhc2VNYXNrIHwgT1MuUG9pbnRlck1vdGlvbk1hc2ssCi0JCQlPUy5HcmFiTW9kZUFzeW5jLAotCQkJT1MuR3JhYk1vZGVBc3luYywKLQkJCU9TLk5vbmUsCi0JCQlPUy5Ob25lLAotCQkJT1MuQ3VycmVudFRpbWUpOwotCX0gZWxzZSB7Ci0JCU9TLlhVbmdyYWJQb2ludGVyIChkaXNwbGF5LCBPUy5DdXJyZW50VGltZSk7Ci0JfQotICAgICovCiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgY3Vyc29yIHRvIHRoZSBjdXJzb3Igc3BlY2lmaWVkIGJ5IHRoZQotICogYXJndW1lbnQsIG9yIHRvIHRoZSBkZWZhdWx0IGN1cnNvciBmb3IgdGhhdCBraW5kIG9mIGNvbnRyb2wKLSAqIGlmIHRoZSBhcmd1bWVudCBpcyBudWxsLgotICogPHA+Ci0gKiBXaGVuIHRoZSBtb3VzZSBwb2ludGVyIHBhc3NlcyBvdmVyIGEgY29udHJvbCBpdHMgYXBwZWFyYW5jZQotICogaXMgY2hhbmdlZCB0byBtYXRjaCB0aGUgY29udHJvbCdzIGN1cnNvci4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gY3Vyc29yIHRoZSBuZXcgY3Vyc29yIChvciBudWxsKQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX0FSR1VNRU5UIC0gaWYgdGhlIGFyZ3VtZW50IGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4gCi0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldEN1cnNvciAoQ3Vyc29yIGN1cnNvcikgewogCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKGN1cnNvciA9PSBudWxsKSB7Ci0JCWN1cnNvcj0gbnVsbDsKLQl9IGVsc2UgewotCQlpZiAoY3Vyc29yLmlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKLQkJdGhpcy5jdXJzb3I9IGN1cnNvcjsKKwlpZiAoY3Vyc29yICE9IG51bGwgJiYgY3Vyc29yLmlzRGlzcG9zZWQgKCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CisJdGhpcy5jdXJzb3IgPSBjdXJzb3I7CisJb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCB3aGVyZSA9IG5ldyBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBvaW50ICgpOworCU9TLkdldEdsb2JhbE1vdXNlICh3aGVyZSk7CisJaW50IFtdIHRoZVdpbmRvdyA9IG5ldyBpbnQgWzFdOworCWlmIChPUy5GaW5kV2luZG93ICh3aGVyZSwgdGhlV2luZG93KSAhPSBPUy5pbkNvbnRlbnQpIHJldHVybjsKKwlpZiAodGhlV2luZG93IFswXSA9PSAwKSByZXR1cm47CisJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0V2luZG93Qm91bmRzICh0aGVXaW5kb3cgWzBdLCAoc2hvcnQpIE9TLmtXaW5kb3dDb250ZW50UmduLCByZWN0KTsKKwlDR1BvaW50IGluUG9pbnQgPSBuZXcgQ0dQb2ludCAoKTsKKwlpblBvaW50LnggPSB3aGVyZS5oIC0gcmVjdC5sZWZ0OworCWluUG9pbnQueSA9IHdoZXJlLnYgLSByZWN0LnRvcDsKKwlpbnQgW10gdGhlUm9vdCA9IG5ldyBpbnQgWzFdOworCU9TLkdldFJvb3RDb250cm9sICh0aGVXaW5kb3cgWzBdLCB0aGVSb290KTsKKwlpbnQgW10gdGhlQ29udHJvbCA9IG5ldyBpbnQgWzFdOworCU9TLkhJVmlld0dldFN1YnZpZXdIaXQgKHRoZVJvb3QgWzBdLCBpblBvaW50LCB0cnVlLCB0aGVDb250cm9sKTsKKwlpbnQgY3Vyc29yQ29udHJvbCA9IHRoZUNvbnRyb2wgWzBdOworCXdoaWxlICh0aGVDb250cm9sIFswXSAhPSAwICYmIHRoZUNvbnRyb2wgWzBdICE9IGhhbmRsZSkgeworCQlPUy5HZXRTdXBlckNvbnRyb2wgKHRoZUNvbnRyb2wgWzBdLCB0aGVDb250cm9sKTsKKwl9CisJaWYgKHRoZUNvbnRyb2wgWzBdID09IDApIHJldHVybjsKKwlvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBvaW50IGxvY2FsUG9pbnQgPSBuZXcgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCAoKTsKKwlsb2NhbFBvaW50LmggPSAoc2hvcnQpIGluUG9pbnQueDsKKwlsb2NhbFBvaW50LnYgPSAoc2hvcnQpIGluUG9pbnQueTsKKwlpbnQgbW9kaWZpZXJzID0gT1MuR2V0Q3VycmVudEV2ZW50S2V5TW9kaWZpZXJzICgpOworCWJvb2xlYW4gW10gY3Vyc29yV2FzU2V0ID0gbmV3IGJvb2xlYW4gWzFdOworCU9TLkhhbmRsZUNvbnRyb2xTZXRDdXJzb3IgKGN1cnNvckNvbnRyb2wsIGxvY2FsUG9pbnQsIChzaG9ydCkgbW9kaWZpZXJzLCBjdXJzb3JXYXNTZXQpOworCWlmICghY3Vyc29yV2FzU2V0IFswXSkgT1MuU2V0VGhlbWVDdXJzb3IgKE9TLmtUaGVtZUFycm93Q3Vyc29yKTsKK30KKwordm9pZCBzZXRDdXJzb3IgKGludCBjdXJzb3IpIHsKKwlzd2l0Y2ggKGN1cnNvcikgeworCQljYXNlIE9TLmtUaGVtZVBvaW50aW5nSGFuZEN1cnNvcjoKKwkJY2FzZSBPUy5rVGhlbWVBcnJvd0N1cnNvcjoKKwkJY2FzZSBPUy5rVGhlbWVTcGlubmluZ0N1cnNvcjoKKwkJY2FzZSBPUy5rVGhlbWVDcm9zc0N1cnNvcjoKKwkJY2FzZSBPUy5rVGhlbWVXYXRjaEN1cnNvcjoKKwkJY2FzZSBPUy5rVGhlbWVJQmVhbUN1cnNvcjoKKwkJY2FzZSBPUy5rVGhlbWVOb3RBbGxvd2VkQ3Vyc29yOgorCQljYXNlIE9TLmtUaGVtZVJlc2l6ZUxlZnRSaWdodEN1cnNvcjoKKwkJY2FzZSBPUy5rVGhlbWVSZXNpemVMZWZ0Q3Vyc29yOgorCQljYXNlIE9TLmtUaGVtZVJlc2l6ZVJpZ2h0Q3Vyc29yOgorCQkJT1MuU2V0VGhlbWVDdXJzb3IgKGN1cnNvcik7CisJCQlicmVhazsKKwkJZGVmYXVsdDoKKwkJCU9TLlNldEN1cnNvciAoY3Vyc29yKTsKIAl9CiB9Ci0vKioKLSAqIEVuYWJsZXMgdGhlIHJlY2VpdmVyIGlmIHRoZSBhcmd1bWVudCBpcyA8Y29kZT50cnVlPC9jb2RlPiwKLSAqIGFuZCBkaXNhYmxlcyBpdCBvdGhlcndpc2UuIEEgZGlzYWJsZWQgY29udHJvbCBpcyB0eXBpY2FsbHkKLSAqIG5vdCBzZWxlY3RhYmxlIGZyb20gdGhlIHVzZXIgaW50ZXJmYWNlIGFuZCBkcmF3cyB3aXRoIGFuCi0gKiBpbmFjdGl2ZSBvciAiZ3JheWVkIiBsb29rLgotICoKLSAqIEBwYXJhbSBlbmFibGVkIHRoZSBuZXcgZW5hYmxlZCBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRFbmFibGVkIChib29sZWFuIGVuYWJsZWQpIHsKIAljaGVja1dpZGdldCgpOwotCWVuYWJsZVdpZGdldCAoZW5hYmxlZCk7Ci0JaWYgKCFlbmFibGVkIHx8IChpc0VuYWJsZWQgKCkgJiYgZW5hYmxlZCkpIHsKLQkJcHJvcGFnYXRlQ2hpbGRyZW4gKGVuYWJsZWQpOworCWlmIChlbmFibGVkKSB7CisJCWlmICgoc3RhdGUgJiBESVNBQkxFRCkgPT0gMCkgcmV0dXJuOworCQlzdGF0ZSAmPSB+RElTQUJMRUQ7CisJCU9TLkVuYWJsZUNvbnRyb2wgKHRvcEhhbmRsZSAoKSk7CisJfSBlbHNlIHsKKwkJaWYgKChzdGF0ZSAmIERJU0FCTEVEKSAhPSAwKSByZXR1cm47CisJCXN0YXRlIHw9IERJU0FCTEVEOworCQlPUy5EaXNhYmxlQ29udHJvbCAodG9wSGFuZGxlICgpKTsKIAl9CiB9Ci0vKioKLSAqIENhdXNlcyB0aGUgcmVjZWl2ZXIgdG8gaGF2ZSB0aGUgPGVtPmtleWJvYXJkIGZvY3VzPC9lbT4sIAotICogc3VjaCB0aGF0IGFsbCBrZXlib2FyZCBldmVudHMgd2lsbCBiZSBkZWxpdmVyZWQgdG8gaXQuCi0gKgotICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgY29udHJvbCBnb3QgZm9jdXMsIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gaWYgaXQgd2FzIHVuYWJsZSB0by4KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjZm9yY2VGb2N1cwotICovCisKIHB1YmxpYyBib29sZWFuIHNldEZvY3VzICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBmb3JjZUZvY3VzICgpOwogfQotLyoqCi0gKiBTZXRzIHRoZSBmb250IHRoYXQgdGhlIHJlY2VpdmVyIHdpbGwgdXNlIHRvIHBhaW50IHRleHR1YWwgaW5mb3JtYXRpb24KLSAqIHRvIHRoZSBmb250IHNwZWNpZmllZCBieSB0aGUgYXJndW1lbnQsIG9yIHRvIHRoZSBkZWZhdWx0IGZvbnQgZm9yIHRoYXQKLSAqIGtpbmQgb2YgY29udHJvbCBpZiB0aGUgYXJndW1lbnQgaXMgbnVsbC4KLSAqCi0gKiBAcGFyYW0gZm9udCB0aGUgbmV3IGZvbnQgKG9yIG51bGwpCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfQVJHVU1FTlQgLSBpZiB0aGUgYXJndW1lbnQgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPiAKLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0Rm9udCAoRm9udCBmb250KSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpZiAoZm9udCA9PSBudWxsKSBmb250ID0gZGVmYXVsdEZvbnQgKCk7Ci0JaWYgKGZvbnQuaXNEaXNwb3NlZCgpKSBTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCWlmIChmb250ICE9IG51bGwpIHsgCisJCWlmIChmb250LmlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKKwl9CiAJdGhpcy5mb250ID0gZm9udDsKLQotCWludCBmb250SGFuZGxlID0gZm9udEhhbmRsZSAoKTsKLQlpZiAoT1MuU2V0Q29udHJvbEZvbnRTdHlsZShmb250SGFuZGxlLCBmb250LmhhbmRsZS5mSUQsIGZvbnQuaGFuZGxlLmZTaXplLCBmb250LmhhbmRsZS5mRmFjZSkgIT0gT1Mua05vRXJyKQotCQk7IC8vU3lzdGVtLm91dC5wcmludGxuKCJDb250cm9sLnNldEZvbnQoIit0aGlzKyIpOiBlcnJvciIpOworCXNldEZvbnRTdHlsZSAoZm9udCk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgZm9yZWdyb3VuZCBjb2xvciB0byB0aGUgY29sb3Igc3BlY2lmaWVkCi0gKiBieSB0aGUgYXJndW1lbnQsIG9yIHRvIHRoZSBkZWZhdWx0IHN5c3RlbSBjb2xvciBmb3IgdGhlIGNvbnRyb2wKLSAqIGlmIHRoZSBhcmd1bWVudCBpcyBudWxsLgotICoKLSAqIEBwYXJhbSBjb2xvciB0aGUgbmV3IGNvbG9yIChvciBudWxsKQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX0FSR1VNRU5UIC0gaWYgdGhlIGFyZ3VtZW50IGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4gCi0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKK3ZvaWQgc2V0Rm9udFN0eWxlIChGb250IGZvbnQpIHsKKwlDb250cm9sRm9udFN0eWxlUmVjIGZvbnRTdHlsZSA9IG5ldyBDb250cm9sRm9udFN0eWxlUmVjICgpOworCWlmIChmb250ICE9IG51bGwpIHsKKwkJZm9udFN0eWxlLmZsYWdzIHw9IE9TLmtDb250cm9sVXNlRm9udE1hc2sgfCBPUy5rQ29udHJvbFVzZVNpemVNYXNrIHwgT1Mua0NvbnRyb2xVc2VGYWNlTWFzazsKKwkJZm9udFN0eWxlLmZvbnQgPSBmb250LmlkOworCQlmb250U3R5bGUuc3R5bGUgPSBmb250LnN0eWxlOworCQlmb250U3R5bGUuc2l6ZSA9IGZvbnQuc2l6ZTsKKwl9IGVsc2UgeworCQlmb250U3R5bGUuZmxhZ3MgfD0gT1Mua0NvbnRyb2xVc2VUaGVtZUZvbnRJRE1hc2s7CisJCWZvbnRTdHlsZS5mb250ID0gKHNob3J0KSBkZWZhdWx0VGhlbWVGb250ICgpOworCX0KKwlPUy5TZXRDb250cm9sRm9udFN0eWxlIChoYW5kbGUsIGZvbnRTdHlsZSk7Cit9CisKIHB1YmxpYyB2b2lkIHNldEZvcmVncm91bmQgKENvbG9yIGNvbG9yKSB7CiAJY2hlY2tXaWRnZXQoKTsKLSAgICAvKiBBVwotCWlmIChjb2xvciA9PSBudWxsKSB7Ci0JCXNldEZvcmVncm91bmRQaXhlbCAoZGVmYXVsdEZvcmVncm91bmQgKCkpOwotCX0gZWxzZSB7Ci0JCWlmIChjb2xvci5pc0Rpc3Bvc2VkKCkpIFNXVC5lcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7Ci0JCXNldEZvcmVncm91bmRQaXhlbCAoY29sb3IuaGFuZGxlLnBpeGVsKTsKLQl9Ci0gICAgKi8KLQlpbnQgcGl4ZWwgPSAtMTsKIAlpZiAoY29sb3IgIT0gbnVsbCkgewogCQlpZiAoY29sb3IuaXNEaXNwb3NlZCgpKSBTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwotCQlwaXhlbCA9IGNvbG9yLmhhbmRsZTsKIAl9Ci0Jc2V0Rm9yZWdyb3VuZFBpeGVsIChwaXhlbCk7CisJZm9yZWdyb3VuZCA9IGNvbG9yICE9IG51bGwgPyBjb2xvci5oYW5kbGUgOiBudWxsOwogfQotdm9pZCBzZXRGb3JlZ3JvdW5kUGl4ZWwgKGludCBwaXhlbCkgewotCS8qIEFXCi0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1OZm9yZWdyb3VuZCwgcGl4ZWx9OwotCU9TLlh0U2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JaW50IHhEaXNwbGF5ID0gT1MuWHREaXNwbGF5IChoYW5kbGUpOwotCWlmICh4RGlzcGxheSA9PSAwKSByZXR1cm47Ci0JaW50IHhXaW5kb3cgPSBPUy5YdFdpbmRvdyAoaGFuZGxlKTsKLQlpZiAoeFdpbmRvdyA9PSAwKSByZXR1cm47Ci0JT1MuWENsZWFyQXJlYSAoeERpc3BsYXksIHhXaW5kb3csIDAsIDAsIDAsIDAsIHRydWUpOwotCSovCi0JaWYgKGZvcmVncm91bmQgPT0gcGl4ZWwpIHJldHVybjsKLQlmb3JlZ3JvdW5kID0gcGl4ZWw7Ci0JcmVkcmF3SGFuZGxlKDAsIDAsIDAsIDAsIGhhbmRsZSwgZmFsc2UpOwotfQotdm9pZCBzZXRHcmFiQ3Vyc29yIChpbnQgY3Vyc29yKSB7Ci0JU3lzdGVtLm91dC5wcmludGxuKCJDb250cm9sLnNldEdyYWJDdXJzb3I6IG55aSIpOwotfQotLyoqCi0gKiBTZXRzIHRoZSBsYXlvdXQgZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIHJlY2VpdmVyIHRvIHRoZSBhcmd1bWVudC4KLSAqIAotICogQHBhcmFtIGxheW91dERhdGEgdGhlIG5ldyBsYXlvdXQgZGF0YSBmb3IgdGhlIHJlY2VpdmVyLgotICogCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0TGF5b3V0RGF0YSAoT2JqZWN0IGxheW91dERhdGEpIHsKIAljaGVja1dpZGdldCgpOwogCXRoaXMubGF5b3V0RGF0YSA9IGxheW91dERhdGE7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgbG9jYXRpb24gdG8gdGhlIHBvaW50IHNwZWNpZmllZCBieQotICogdGhlIGFyZ3VtZW50cyB3aGljaCBhcmUgcmVsYXRpdmUgdG8gdGhlIHJlY2VpdmVyJ3MKLSAqIHBhcmVudCAob3IgaXRzIGRpc3BsYXkgaWYgaXRzIHBhcmVudCBpcyBudWxsKS4KLSAqCi0gKiBAcGFyYW0geCB0aGUgbmV3IHggY29vcmRpbmF0ZSBmb3IgdGhlIHJlY2VpdmVyCi0gKiBAcGFyYW0geSB0aGUgbmV3IHkgY29vcmRpbmF0ZSBmb3IgdGhlIHJlY2VpdmVyCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldExvY2F0aW9uIChpbnQgeCwgaW50IHkpIHsKIAljaGVja1dpZGdldCgpOwotICAgIC8qIEFXCi0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1OeCwgMCwgT1MuWG1OeSwgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKHRvcEhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlib29sZWFuIHNhbWVPcmlnaW4gPSAoeCA9PSAoc2hvcnQpIGFyZ0xpc3QgWzFdKSAmJiAoeSA9PSAoc2hvcnQpIGFyZ0xpc3QgWzNdKTsKLQlpZiAoc2FtZU9yaWdpbikgcmV0dXJuOwotCU9TLlh0TW92ZVdpZGdldCAodG9wSGFuZGxlLCB4LCB5KTsKLQlpZiAoIXNhbWVPcmlnaW4pIHNlbmRFdmVudCAoU1dULk1vdmUpOwotICAgICovCi0gCWludCB0b3BIYW5kbGUgPSB0b3BIYW5kbGUgKCk7Ci0JTWFjUmVjdCBicj0gbmV3IE1hY1JlY3QoKTsKLQlzaG9ydFtdIGJvdW5kcz0gYnIuZ2V0RGF0YSgpOwotCXNob3J0W10gcGJvdW5kcz0gbmV3IHNob3J0WzRdOwotCWludGVybmFsR2V0Q29udHJvbEJvdW5kcyh0b3BIYW5kbGUsIGJyKTsKLQlPUy5HZXRDb250cm9sQm91bmRzKHBhcmVudC5oYW5kbGUsIHBib3VuZHMpOwotCWJvb2xlYW4gc2FtZU9yaWdpbjsKLQlpZiAoTWFjVXRpbC5VU0VfRlJBTUUpIHsKLQkJc2FtZU9yaWdpbiA9ICh4ID09IGJvdW5kc1sxXSkgJiYgKHkgPT0gYm91bmRzWzBdKTsKLQl9IGVsc2UgewotCQlzYW1lT3JpZ2luID0gKHggPT0gKGJvdW5kc1sxXS1wYm91bmRzWzFdKSkgJiYgKHkgPT0gKGJvdW5kc1swXS1wYm91bmRzWzBdKSk7Ci0JfQotCWlmIChzYW1lT3JpZ2luKSByZXR1cm47Ci0JaW50ZXJuYWxTZXRCb3VuZHModG9wSGFuZGxlLCBiciwgcGJvdW5kc1sxXSt4LCBwYm91bmRzWzBdK3ksIGJvdW5kc1szXS1ib3VuZHNbMV0sIGJvdW5kc1syXS1ib3VuZHNbMF0pOwotCXNlbmRFdmVudCAoU1dULk1vdmUpOworCXNldEJvdW5kcyAodG9wSGFuZGxlICgpLCB4LCB5LCAwLCAwLCB0cnVlLCBmYWxzZSwgdHJ1ZSk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgbG9jYXRpb24gdG8gdGhlIHBvaW50IHNwZWNpZmllZCBieQotICogdGhlIGFyZ3VtZW50IHdoaWNoIGlzIHJlbGF0aXZlIHRvIHRoZSByZWNlaXZlcidzCi0gKiBwYXJlbnQgKG9yIGl0cyBkaXNwbGF5IGlmIGl0cyBwYXJlbnQgaXMgbnVsbCkuCi0gKgotICogQHBhcmFtIGxvY2F0aW9uIHRoZSBuZXcgbG9jYXRpb24gZm9yIHRoZSByZWNlaXZlcgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRMb2NhdGlvbiAoUG9pbnQgbG9jYXRpb24pIHsKIAlpZiAobG9jYXRpb24gPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlzZXRMb2NhdGlvbiAobG9jYXRpb24ueCwgbG9jYXRpb24ueSk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgcG9wIHVwIG1lbnUgdG8gdGhlIGFyZ3VtZW50LgotICogQWxsIGNvbnRyb2xzIG1heSBvcHRpb25hbGx5IGhhdmUgYSBwb3AgdXAKLSAqIG1lbnUgdGhhdCBpcyBkaXNwbGF5ZWQgd2hlbiB0aGUgdXNlciByZXF1ZXN0cyBvbmUgZm9yCi0gKiB0aGUgY29udHJvbC4gVGhlIHNlcXVlbmNlIG9mIGtleSBzdHJva2VzLCBidXR0b24gcHJlc3NlcwotICogYW5kL29yIGJ1dHRvbiByZWxlYXNlcyB0aGF0IGFyZSB1c2VkIHRvIHJlcXVlc3QgYSBwb3AgdXAKLSAqIG1lbnUgaXMgcGxhdGZvcm0gc3BlY2lmaWMuCi0gKgotICogQHBhcmFtIG1lbnUgdGhlIG5ldyBwb3AgdXAgbWVudQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9NRU5VX05PVF9QT1BfVVAgLSB0aGUgbWVudSBpcyBub3QgYSBwb3AgdXAgbWVudTwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9QQVJFTlQgLSBpZiB0aGUgbWVudSBpcyBub3QgaW4gdGhlIHNhbWUgd2lkZ2V0IHRyZWU8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfQVJHVU1FTlQgLSBpZiB0aGUgbWVudSBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+IAotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRNZW51IChNZW51IG1lbnUpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChtZW51ICE9IG51bGwpIHsKQEAgLTIxNzgsNDExICsxMDM0LDE2MyBAQAogCXRoaXMubWVudSA9IG1lbnU7CiB9CiAKLS8qKgotICogQ2hhbmdlcyB0aGUgcGFyZW50IG9mIHRoZSB3aWRnZXQgdG8gYmUgdGhlIG9uZSBwcm92aWRlZCBpZgotICogdGhlIHVuZGVybHlpbmcgb3BlcmF0aW5nIHN5c3RlbSBzdXBwb3J0cyB0aGlzIGZlYXR1cmUuCi0gKiBBbnN3ZXJzIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBwYXJlbnQgaXMgc3VjY2Vzc2Z1bGx5IGNoYW5nZWQuCi0gKgotICogQHBhcmFtIHBhcmVudCB0aGUgbmV3IHBhcmVudCBmb3IgdGhlIGNvbnRyb2wuCi0gKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBwYXJlbnQgaXMgY2hhbmdlZCBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9BUkdVTUVOVCAtIGlmIHRoZSBhcmd1bWVudCBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+IAotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXJyb3IgPHVsPgotICoJCTxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1Mgd2hlbiBjYWxsZWQgZnJvbSB0aGUgd3JvbmcgdGhyZWFkPC9saT4KLSAqCQk8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIHdoZW4gdGhlIHdpZGdldCBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKgk8L3VsPgotICovCiBwdWJsaWMgYm9vbGVhbiBzZXRQYXJlbnQgKENvbXBvc2l0ZSBwYXJlbnQpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChwYXJlbnQuaXNEaXNwb3NlZCgpKSBTV1QuZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwogCXJldHVybiBmYWxzZTsKIH0KIAotLyoqCi0gKiBJZiB0aGUgYXJndW1lbnQgaXMgPGNvZGU+ZmFsc2U8L2NvZGU+LCBjYXVzZXMgc3Vic2VxdWVudCBkcmF3aW5nCi0gKiBvcGVyYXRpb25zIGluIHRoZSByZWNlaXZlciB0byBiZSBpZ25vcmVkLiBObyBkcmF3aW5nIG9mIGFueSBraW5kCi0gKiBjYW4gb2NjdXIgaW4gdGhlIHJlY2VpdmVyIHVudGlsIHRoZSBmbGFnIGlzIHNldCB0byB0cnVlLgotICogR3JhcGhpY3Mgb3BlcmF0aW9ucyB0aGF0IG9jY3VycmVkIHdoaWxlIHRoZSBmbGFnIHdhcwotICogPGNvZGU+ZmFsc2U8L2NvZGU+IGFyZSBsb3N0LiBXaGVuIHRoZSBmbGFnIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiwKLSAqIHRoZSBlbnRpcmUgd2lkZ2V0IGlzIG1hcmtlZCBhcyBuZWVkaW5nIHRvIGJlIHJlZHJhd24uCi0gKiA8cD4KLSAqIE5vdGU6IFRoaXMgb3BlcmF0aW9uIGlzIGEgaGludCBhbmQgbWF5IG5vdCBiZSBzdXBwb3J0ZWQgb24gc29tZQotICogcGxhdGZvcm1zIG9yIGZvciBzb21lIHdpZGdldHMuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHJlZHJhdyB0aGUgbmV3IHJlZHJhdyBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqIAotICogQHNlZSAjcmVkcmF3Ci0gKiBAc2VlICN1cGRhdGUKLSAqLwogcHVibGljIHZvaWQgc2V0UmVkcmF3IChib29sZWFuIHJlZHJhdykgewogCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKHJlZHJhdykgewotCQlpZiAoLS1kcmF3Q291bnQgPT0gMCkgewotCQkJaW50IHRvcEhhbmRsZT0gdG9wSGFuZGxlKCk7Ci0JCQlPUy5ISVZpZXdTZXREcmF3aW5nRW5hYmxlZCh0b3BIYW5kbGUsIHRydWUpOwotCQkJT1MuSElWaWV3U2V0TmVlZHNEaXNwbGF5KHRvcEhhbmRsZSwgdHJ1ZSk7Ci0JCX0KLQl9IGVsc2UgewotCQlpZiAoZHJhd0NvdW50KysgPT0gMCkKLQkJCU9TLkhJVmlld1NldERyYXdpbmdFbmFibGVkKHRvcEhhbmRsZSgpLCBmYWxzZSk7Ci0JfQorCS8vTk9UIERPTkUKKy8vCWlmIChyZWRyYXcpIHsKKy8vCQlpZiAoLS1kcmF3Q291bnQgPT0gMCkgeworLy8JCQlPUy5ISVZpZXdTZXREcmF3aW5nRW5hYmxlZCAoaGFuZGxlLCB0cnVlKTsKKy8vCQkJT1MuSElWaWV3U2V0TmVlZHNEaXNwbGF5IChoYW5kbGUsIHRydWUpOworLy8JCX0KKy8vCX0gZWxzZSB7CisvLwkJaWYgKGRyYXdDb3VudCsrID09IDApIHsKKy8vCQkJT1MuSElWaWV3U2V0RHJhd2luZ0VuYWJsZWQgKGhhbmRsZSwgZmFsc2UpOworLy8JCX0KKy8vCX0KIH0KLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBzaXplIHRvIHRoZSBwb2ludCBzcGVjaWZpZWQgYnkgdGhlIGFyZ3VtZW50cy4KLSAqIDxwPgotICogTm90ZTogQXR0ZW1wdGluZyB0byBzZXQgdGhlIHdpZHRoIG9yIGhlaWdodCBvZiB0aGUKLSAqIHJlY2VpdmVyIHRvIGEgbmVnYXRpdmUgbnVtYmVyIHdpbGwgY2F1c2UgdGhhdAotICogdmFsdWUgdG8gYmUgc2V0IHRvIHplcm8gaW5zdGVhZC4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gd2lkdGggdGhlIG5ldyB3aWR0aCBmb3IgdGhlIHJlY2VpdmVyCi0gKiBAcGFyYW0gaGVpZ2h0IHRoZSBuZXcgaGVpZ2h0IGZvciB0aGUgcmVjZWl2ZXIKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKworYm9vbGVhbiBzZXRSYWRpb1NlbGVjdGlvbiAoYm9vbGVhbiB2YWx1ZSl7CisJcmV0dXJuIGZhbHNlOworfQorCiBwdWJsaWMgdm9pZCBzZXRTaXplIChpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKIAljaGVja1dpZGdldCgpOwotICAgIC8qCi0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1Od2lkdGgsIDAsIE9TLlhtTmhlaWdodCwgMCwgT1MuWG1OYm9yZGVyV2lkdGgsIDB9OwotCU9TLlh0R2V0VmFsdWVzICh0b3BIYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JaW50IG5ld1dpZHRoID0gTWF0aC5tYXggKHdpZHRoIC0gKGFyZ0xpc3QgWzVdICogMiksIDEpOwotCWludCBuZXdIZWlnaHQgPSBNYXRoLm1heCAoaGVpZ2h0IC0gKGFyZ0xpc3QgWzVdICogMiksIDEpOwotCWJvb2xlYW4gc2FtZUV4dGVudCA9IChuZXdXaWR0aCA9PSBhcmdMaXN0IFsxXSkgJiYgKG5ld0hlaWdodCA9PSBhcmdMaXN0IFszXSk7Ci0JT1MuWHRSZXNpemVXaWRnZXQgKHRvcEhhbmRsZSwgbmV3V2lkdGgsIG5ld0hlaWdodCwgYXJnTGlzdCBbNV0pOwotCSovCi0JaW50IHRvcEhhbmRsZSA9IHRvcEhhbmRsZSAoKTsKLQl3aWR0aCA9IE1hdGgubWF4KHdpZHRoLCAwKTsKLQloZWlnaHQgPSBNYXRoLm1heChoZWlnaHQsIDApOwotCU1hY1JlY3QgYnI9IG5ldyBNYWNSZWN0KCk7Ci0Jc2hvcnRbXSBib3VuZHM9IGJyLmdldERhdGEoKTsKLQlpbnRlcm5hbEdldENvbnRyb2xCb3VuZHModG9wSGFuZGxlLCBicik7Ci0JYm9vbGVhbiBzYW1lRXh0ZW50ID0gKGJvdW5kc1szXS1ib3VuZHNbMV0pID09IHdpZHRoICYmIChib3VuZHNbMl0tYm91bmRzWzBdKSA9PSBoZWlnaHQ7Ci0JaWYgKHNhbWVFeHRlbnQpIHJldHVybjsJCi0JaW50ZXJuYWxTZXRCb3VuZHModG9wSGFuZGxlLCBiciwgYm91bmRzWzFdLCBib3VuZHNbMF0sIHdpZHRoLCBoZWlnaHQpOwotCXNlbmRFdmVudCAoU1dULlJlc2l6ZSk7CisJc2V0Qm91bmRzICh0b3BIYW5kbGUgKCksIDAsIDAsIHdpZHRoLCBoZWlnaHQsIGZhbHNlLCB0cnVlLCB0cnVlKTsKIH0KLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBzaXplIHRvIHRoZSBwb2ludCBzcGVjaWZpZWQgYnkgdGhlIGFyZ3VtZW50LgotICogPHA+Ci0gKiBOb3RlOiBBdHRlbXB0aW5nIHRvIHNldCB0aGUgd2lkdGggb3IgaGVpZ2h0IG9mIHRoZQotICogcmVjZWl2ZXIgdG8gYSBuZWdhdGl2ZSBudW1iZXIgd2lsbCBjYXVzZSB0aGVtIHRvIGJlCi0gKiBzZXQgdG8gemVybyBpbnN0ZWFkLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBzaXplIHRoZSBuZXcgc2l6ZSBmb3IgdGhlIHJlY2VpdmVyCi0gKiBAcGFyYW0gaGVpZ2h0IHRoZSBuZXcgaGVpZ2h0IGZvciB0aGUgcmVjZWl2ZXIKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwb2ludCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0U2l6ZSAoUG9pbnQgc2l6ZSkgewogCWlmIChzaXplID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJc2V0U2l6ZSAoc2l6ZS54LCBzaXplLnkpOwogfQogCiBib29sZWFuIHNldFRhYkdyb3VwRm9jdXMgKCkgewotCXJldHVybiBzZXRUYWJJdGVtRm9jdXMgKCk7CisJcmV0dXJuIGZhbHNlOwogfQogCiBib29sZWFuIHNldFRhYkl0ZW1Gb2N1cyAoKSB7Ci0JaWYgKCFpc1Nob3dpbmcgKCkpIHJldHVybiBmYWxzZTsKLQlyZXR1cm4gc2V0Rm9jdXMgKCk7CisJcmV0dXJuIGZhbHNlOwogfQogCi0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgdG9vbCB0aXAgdGV4dCB0byB0aGUgYXJndW1lbnQsIHdoaWNoCi0gKiBtYXkgYmUgbnVsbCBpbmRpY2F0aW5nIHRoYXQgbm8gdG9vbCB0aXAgdGV4dCBzaG91bGQgYmUgc2hvd24uCi0gKgotICogQHBhcmFtIHN0cmluZyB0aGUgbmV3IHRvb2wgdGlwIHRleHQgKG9yIG51bGwpCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCiBwdWJsaWMgdm9pZCBzZXRUb29sVGlwVGV4dCAoU3RyaW5nIHN0cmluZykgewogCWNoZWNrV2lkZ2V0KCk7CiAJdG9vbFRpcFRleHQgPSBzdHJpbmc7CiB9Ci0vKioKLSAqIE1hcmtzIHRoZSByZWNlaXZlciBhcyB2aXNpYmxlIGlmIHRoZSBhcmd1bWVudCBpcyA8Y29kZT50cnVlPC9jb2RlPiwKLSAqIGFuZCBtYXJrcyBpdCBpbnZpc2libGUgb3RoZXJ3aXNlLiAKLSAqIDxwPgotICogSWYgb25lIG9mIHRoZSByZWNlaXZlcidzIGFuY2VzdG9ycyBpcyBub3QgdmlzaWJsZSBvciBzb21lCi0gKiBvdGhlciBjb25kaXRpb24gbWFrZXMgdGhlIHJlY2VpdmVyIG5vdCB2aXNpYmxlLCBtYXJraW5nCi0gKiBpdCB2aXNpYmxlIG1heSBub3QgYWN0dWFsbHkgY2F1c2UgaXQgdG8gYmUgZGlzcGxheWVkLgotICogPC9wPgotICoKLSAqIEBwYXJhbSB2aXNpYmxlIHRoZSBuZXcgdmlzaWJpbGl0eSBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRWaXNpYmxlIChib29sZWFuIHZpc2libGUpIHsKIAljaGVja1dpZGdldCgpOwotICAgIGlmICh0aGlzLnZpc2libGUgIT0gdmlzaWJsZSkgewotCSAgICB0aGlzLnZpc2libGU9IHZpc2libGU7Ci0JCWludCB0b3BIYW5kbGUgPSB0b3BIYW5kbGUgKCk7Ci0JCWlmIChPUy5Jc0NvbnRyb2xWaXNpYmxlKHRvcEhhbmRsZSkgIT0gdmlzaWJsZSkgewotCQkJT1MuSElWaWV3U2V0VmlzaWJsZSh0b3BIYW5kbGUsIHZpc2libGUpOwotCQkJc2VuZEV2ZW50ICh2aXNpYmxlID8gU1dULlNob3cgOiBTV1QuSGlkZSk7Ci0JCX0KLSAgICB9CisJaWYgKHZpc2libGUpIHsKKwkJaWYgKChzdGF0ZSAmIEhJRERFTikgPT0gMCkgcmV0dXJuOworCQlzdGF0ZSAmPSB+SElEREVOOworCX0gZWxzZSB7CisJCWlmICgoc3RhdGUgJiBISURERU4pICE9IDApIHJldHVybjsKKwkJc3RhdGUgfD0gSElEREVOOworCX0KKwlpZiAodmlzaWJsZSkgeworCQkvKgorCQkqIEl0IGlzIHBvc3NpYmxlIChidXQgdW5saWtlbHkpLCB0aGF0IGFwcGxpY2F0aW9uCisJCSogY29kZSBjb3VsZCBoYXZlIGRpc3Bvc2VkIHRoZSB3aWRnZXQgaW4gdGhlIHNob3cKKwkJKiBldmVudC4gIElmIHRoaXMgaGFwcGVucywganVzdCByZXR1cm4uCisJCSovCisJCXNlbmRFdmVudCAoU1dULlNob3cpOworCQlpZiAoaXNEaXNwb3NlZCAoKSkgcmV0dXJuOworCX0KKwkKKwkvKgorCSogRmVhdHVyZSBpbiB0aGUgTWFjaW50b3NoLiAgSWYgdGhlIHJlY2VpdmVyIGhhcyBmb2N1cywgaGlkaW5nCisJKiB0aGUgcmVjZWl2ZXIgY2F1c2VzIG5vIGNvbnRyb2wgdG8gaGF2ZSBmb2N1cy4gIEFsc28sIHRoZSBmb2N1cworCSogbmVlZHMgdG8gYmUgY2xlYXJlZCBmcm9tIGFueSBUWE5PYmplY3Qgc28gdGhhdCBpdCBzdG9wcyBibGlua2luZworCSogdGhlIGNhcmV0LiAgVGhlIGZpeCBpcyB0byBhc3NpZ24gZm9jdXMgdG8gdGhlIGZpcnN0IGFuY2VzdG9yCisJKiBjb250cm9sIHRoYXQgdGFrZXMgZm9jdXMuICBJZiBubyBjb250cm9sIHdpbGwgdGFrZSBmb2N1cywgY2xlYXIKKwkqIHRoZSBmb2N1cyBjb250cm9sLgorCSovCisJYm9vbGVhbiBmaXhGb2N1cyA9IGZhbHNlOworCWlmICghdmlzaWJsZSkgZml4Rm9jdXMgPSBpc0ZvY3VzQW5jZXN0b3IgKCk7CisJT1MuSElWaWV3U2V0VmlzaWJsZSAodG9wSGFuZGxlICgpLCB2aXNpYmxlKTsKKwlpZiAoIXZpc2libGUpIHsKKwkJLyoKKwkJKiBJdCBpcyBwb3NzaWJsZSAoYnV0IHVubGlrZWx5KSwgdGhhdCBhcHBsaWNhdGlvbgorCQkqIGNvZGUgY291bGQgaGF2ZSBkaXNwb3NlZCB0aGUgd2lkZ2V0IGluIHRoZSBzaG93CisJCSogZXZlbnQuICBJZiB0aGlzIGhhcHBlbnMsIGp1c3QgcmV0dXJuLgorCQkqLworCQlzZW5kRXZlbnQgKFNXVC5IaWRlKTsKKwkJaWYgKGlzRGlzcG9zZWQgKCkpIHJldHVybjsKKwl9CisJaWYgKGZpeEZvY3VzKSBmaXhGb2N1cyAoKTsKIH0KKwordm9pZCBzZXRaT3JkZXIgKCkgeworCWludCB0b3BIYW5kbGUgPSB0b3BIYW5kbGUgKCk7CisJaW50IHBhcmVudEhhbmRsZSA9IHBhcmVudC5oYW5kbGU7CisJT1MuSElWaWV3QWRkU3VidmlldyAocGFyZW50SGFuZGxlLCB0b3BIYW5kbGUpOworCS8vT1MuRW1iZWRDb250cm9sICh0b3BIYW5kbGUsIHBhcmVudEhhbmRsZSk7CisJLyogUGxhY2UgdGhlIGNoaWxkIGF0ICgwLCAwKSBpbiB0aGUgcGFyZW50ICovCisJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAocGFyZW50SGFuZGxlLCByZWN0KTsKKwlyZWN0LnJpZ2h0ID0gcmVjdC5sZWZ0OworCXJlY3QuYm90dG9tID0gcmVjdC50b3A7CisJT1MuU2V0Q29udHJvbEJvdW5kcyAodG9wSGFuZGxlLCByZWN0KTsKK30KKwogdm9pZCBzZXRaT3JkZXIgKENvbnRyb2wgY29udHJvbCwgYm9vbGVhbiBhYm92ZSkgewotCQotCWlmIChjb250cm9sICE9IG51bGwgJiYgY29udHJvbC5wYXJlbnQgIT0gcGFyZW50KSByZXR1cm47Ci0JCi0JaW50IHRoaXNIYW5kbGU9IHRvcEhhbmRsZSgpOwotCWlmIChwYXJlbnQgPT0gbnVsbCkKLQkJZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1BBUkVOVCk7Ci0JaW50IGRlc3RIYW5kbGU9IHBhcmVudC5oYW5kbGU7Ci0JaW50IG90aGVySGFuZGxlPSAwOwotCWlmIChjb250cm9sICE9IG51bGwpCi0JCW90aGVySGFuZGxlPSBjb250cm9sLnRvcEhhbmRsZSgpOwotCQkKLQkvLyBBVzogZG9lc24ndCBoYW5kbGUgcmVwYXJlbnRpbmcgY2FzZSB5ZXQhCi0JT1MuSElWaWV3U2V0Wk9yZGVyKHRoaXNIYW5kbGUsIGFib3ZlID8gT1Mua0hJVmlld1pPcmRlckFib3ZlIDogT1Mua0hJVmlld1pPcmRlckJlbG93LCBvdGhlckhhbmRsZSk7CisJaW50IGluT3AgPSBhYm92ZSA/ICBPUy5rSElWaWV3Wk9yZGVyQmVsb3cgOiAgT1Mua0hJVmlld1pPcmRlckFib3ZlOworCWludCBpbk90aGVyID0gY29udHJvbCA9PSBudWxsID8gMCA6IGNvbnRyb2wudG9wSGFuZGxlICgpOworCU9TLkhJVmlld1NldFpPcmRlciAodG9wSGFuZGxlICgpLCBpbk9wLCBpbk90aGVyKTsKIH0KLS8qKgotICogUmV0dXJucyBhIHBvaW50IHdoaWNoIGlzIHRoZSByZXN1bHQgb2YgY29udmVydGluZyB0aGUKLSAqIGFyZ3VtZW50LCB3aGljaCBpcyBzcGVjaWZpZWQgaW4gZGlzcGxheSByZWxhdGl2ZSBjb29yZGluYXRlcywKLSAqIHRvIGNvb3JkaW5hdGVzIHJlbGF0aXZlIHRvIHRoZSByZWNlaXZlci4KLSAqIDxwPgotICogQHBhcmFtIHBvaW50IHRoZSBwb2ludCB0byBiZSB0cmFuc2xhdGVkIChtdXN0IG5vdCBiZSBudWxsKQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBvaW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCit2b2lkIHNvcnQgKGludCBbXSBpdGVtcykgeworCS8qIFNoZWxsIFNvcnQgZnJvbSBLJlIsIHBnIDEwOCAqLworCWludCBsZW5ndGggPSBpdGVtcy5sZW5ndGg7CisJZm9yIChpbnQgZ2FwPWxlbmd0aC8yOyBnYXA+MDsgZ2FwLz0yKSB7CisJCWZvciAoaW50IGk9Z2FwOyBpPGxlbmd0aDsgaSsrKSB7CisJCQlmb3IgKGludCBqPWktZ2FwOyBqPj0wOyBqLT1nYXApIHsKKwkJICAgCQlpZiAoaXRlbXMgW2pdIDw9IGl0ZW1zIFtqICsgZ2FwXSkgeworCQkJCQlpbnQgc3dhcCA9IGl0ZW1zIFtqXTsKKwkJCQkJaXRlbXMgW2pdID0gaXRlbXMgW2ogKyBnYXBdOworCQkJCQlpdGVtcyBbaiArIGdhcF0gPSBzd2FwOworCQkgICAJCX0KKwkgICAgCX0KKwkgICAgfQorCX0KK30KKwogcHVibGljIFBvaW50IHRvQ29udHJvbCAoUG9pbnQgcG9pbnQpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChwb2ludCA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotICAgIC8qIEFXCi0Jc2hvcnQgW10gcm9vdF94ID0gbmV3IHNob3J0IFsxXSwgcm9vdF95ID0gbmV3IHNob3J0IFsxXTsKLQlPUy5YdFRyYW5zbGF0ZUNvb3JkcyAoaGFuZGxlLCAoc2hvcnQpIDAsIChzaG9ydCkgMCwgcm9vdF94LCByb290X3kpOwotCXJldHVybiBuZXcgUG9pbnQgKHBvaW50LnggLSByb290X3ggWzBdLCBwb2ludC55IC0gcm9vdF95IFswXSk7Ci0gICAgKi8KLQlyZXR1cm4gTWFjVXRpbC50b0NvbnRyb2woaGFuZGxlLCBwb2ludCk7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAoaGFuZGxlKTsKKwlPUy5HZXRXaW5kb3dCb3VuZHMgKHdpbmRvdywgKHNob3J0KSBPUy5rV2luZG93Q29udGVudFJnbiwgcmVjdCk7CisJaW50IHggPSBwb2ludC54IC0gcmVjdC5sZWZ0OworCWludCB5ID0gcG9pbnQueSAtIHJlY3QudG9wOworCU9TLkdldENvbnRyb2xCb3VuZHMgKGhhbmRsZSwgcmVjdCk7CisgICAgcmV0dXJuIG5ldyBQb2ludCAoeCAtIHJlY3QubGVmdCwgeSAtIHJlY3QudG9wKTsKIH0KLS8qKgotICogUmV0dXJucyBhIHBvaW50IHdoaWNoIGlzIHRoZSByZXN1bHQgb2YgY29udmVydGluZyB0aGUKLSAqIGFyZ3VtZW50LCB3aGljaCBpcyBzcGVjaWZpZWQgaW4gY29vcmRpbmF0ZXMgcmVsYXRpdmUgdG8KLSAqIHRoZSByZWNlaXZlciwgdG8gZGlzcGxheSByZWxhdGl2ZSBjb29yZGluYXRlcy4KLSAqIDxwPgotICogQHBhcmFtIHBvaW50IHRoZSBwb2ludCB0byBiZSB0cmFuc2xhdGVkIChtdXN0IG5vdCBiZSBudWxsKQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBvaW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgUG9pbnQgdG9EaXNwbGF5IChQb2ludCBwb2ludCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHBvaW50ID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0gICAgLyogQVcKLQlzaG9ydCBbXSByb290X3ggPSBuZXcgc2hvcnQgWzFdLCByb290X3kgPSBuZXcgc2hvcnQgWzFdOwotCU9TLlh0VHJhbnNsYXRlQ29vcmRzIChoYW5kbGUsIChzaG9ydCkgcG9pbnQueCwgKHNob3J0KSBwb2ludC55LCByb290X3gsIHJvb3RfeSk7Ci0JcmV0dXJuIG5ldyBQb2ludCAocm9vdF94IFswXSwgcm9vdF95IFswXSk7Ci0gICAgKi8KLQlyZXR1cm4gTWFjVXRpbC50b0Rpc3BsYXkoaGFuZGxlLCBwb2ludCk7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAoaGFuZGxlLCByZWN0KTsKKwlpbnQgeCA9IHBvaW50LnggKyByZWN0LmxlZnQ7IAorCWludCB5ID0gcG9pbnQueSArIHJlY3QudG9wOyAKKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChoYW5kbGUpOworCU9TLkdldFdpbmRvd0JvdW5kcyAod2luZG93LCAoc2hvcnQpIE9TLmtXaW5kb3dDb250ZW50UmduLCByZWN0KTsKKyAgICByZXR1cm4gbmV3IFBvaW50ICh4ICsgcmVjdC5sZWZ0LCB5ICsgcmVjdC50b3ApOwogfQotLyogQVcKLWJvb2xlYW4gdHJhbnNsYXRlTW5lbW9uaWMgKGNoYXIga2V5LCBYS2V5RXZlbnQgeEV2ZW50KSB7Ci0JaWYgKCFpc1Zpc2libGUgKCkgfHwgIWlzRW5hYmxlZCAoKSkgcmV0dXJuIGZhbHNlOwotCWJvb2xlYW4gZG9pdCA9IG1uZW1vbmljTWF0Y2ggKGtleSk7Ci0JaWYgKGhvb2tzIChTV1QuVHJhdmVyc2UpKSB7Ci0JCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50KCk7Ci0JCWV2ZW50LmRvaXQgPSBkb2l0OwotCQlldmVudC5kZXRhaWwgPSBTV1QuVFJBVkVSU0VfTU5FTU9OSUM7Ci0JCWV2ZW50LnRpbWUgPSB4RXZlbnQudGltZTsKLQkJc2V0S2V5U3RhdGUgKGV2ZW50LCB4RXZlbnQpOwotCQlzZW5kRXZlbnQgKFNXVC5UcmF2ZXJzZSwgZXZlbnQpOwotCQlkb2l0ID0gZXZlbnQuZG9pdDsKLQl9Ci0JaWYgKGRvaXQpIHJldHVybiBtbmVtb25pY0hpdCAoa2V5KTsKLQlyZXR1cm4gZmFsc2U7Ci19Ci1ib29sZWFuIHRyYW5zbGF0ZU1uZW1vbmljIChpbnQga2V5LCBYS2V5RXZlbnQgeEV2ZW50KSB7Ci0JaWYgKHhFdmVudC5zdGF0ZSAhPSBPUy5Nb2QxTWFzaykgewotCQlpZiAoeEV2ZW50LnN0YXRlICE9IDAgfHwgISh0aGlzIGluc3RhbmNlb2YgQnV0dG9uKSkgewotCQkJcmV0dXJuIGZhbHNlOwotCQl9Ci0JfQotCURlY29yYXRpb25zIHNoZWxsID0gbWVudVNoZWxsICgpOwotCWlmIChzaGVsbC5pc1Zpc2libGUgKCkgJiYgc2hlbGwuaXNFbmFibGVkICgpKSB7Ci0JCWNoYXIgY2ggPSBtYmNzVG9XY3MgKChjaGFyKSBrZXkpOwotCQlyZXR1cm4gY2ggIT0gMCAmJiBzaGVsbC50cmFuc2xhdGVNbmVtb25pYyAoY2gsIHhFdmVudCk7Ci0JfQotCXJldHVybiBmYWxzZTsKLX0KLSovCi1ib29sZWFuIHRyYW5zbGF0ZVRyYXZlcnNhbCAoTWFjRXZlbnQgbUV2ZW50KSB7Ci0JCi0JaW50IGtpbmQ9IG1FdmVudC5nZXRLaW5kKCk7Ci0JaWYgKGtpbmQgIT0gT1Mua0V2ZW50UmF3S2V5RG93biAmJiBraW5kICE9IE9TLmtFdmVudFJhd0tleVJlcGVhdCkKLQkJcmV0dXJuIGZhbHNlOwogCi0JaW50IGRldGFpbCA9IFNXVC5UUkFWRVJTRV9OT05FOwotCS8qIEFXCi0JR2RrRXZlbnRLZXkga2V5RXZlbnQgPSBuZXcgR2RrRXZlbnRLZXkgKCk7Ci0JT1MubWVtbW92ZSAoa2V5RXZlbnQsIGdka0V2ZW50LCBHZGtFdmVudEtleS5zaXplb2YpOwotCWludCBrZXkgPSBrZXlFdmVudC5rZXl2YWw7Ci0JaW50IGNvZGUgPSB0cmF2ZXJzYWxDb2RlIChrZXksIGdka0V2ZW50KTsKLQlpbnQgW10gc3RhdGUgPSBuZXcgaW50IFsxXTsKLQlPUy5nZGtfZXZlbnRfZ2V0X3N0YXRlIChnZGtFdmVudCwgc3RhdGUpOwotCSovCi0JaW50IGNvZGU9IHRyYXZlcnNhbENvZGUgKCk7Ci0JaW50IGtleT0gbUV2ZW50LmdldEtleUNvZGUoKTsKLQlpbnQgc3RhdGU9IG1FdmVudC5nZXRTdGF0ZU1hc2soKTsKLQlib29sZWFuIGFsbCA9IGZhbHNlOwotCXN3aXRjaCAoa2V5KSB7Ci0JCWNhc2UgNTMgLyogT1MuR0RLX0VzY2FwZToKLQkJY2FzZSBPUy5HREtfQ2FuY2VsICovOiB7Ci0JCQlhbGwgPSB0cnVlOwotCQkJZGV0YWlsID0gU1dULlRSQVZFUlNFX0VTQ0FQRTsKLQkJCWJyZWFrOwotCQl9Ci0JCWNhc2UgMzYgLyogT1MuR0RLX1JldHVybiAqLyA6IHsKLQkJCWFsbCA9IHRydWU7Ci0JCQlkZXRhaWwgPSBTV1QuVFJBVkVSU0VfUkVUVVJOOwotCQkJYnJlYWs7Ci0JCX0KLQkJLy9jYXNlIE9TLkdES19JU09fTGVmdF9UYWI6IAotCQljYXNlIDQ4IC8qIE9TLkdES19UYWIgKi8gOiB7Ci0JCQlib29sZWFuIG5leHQgPSAoc3RhdGUgJiBTV1QuU0hJRlQpID09IDA7Ci0JCQkvKgotCQkJKiBOT1RFOiBUaGlzIGNvZGUgY2F1c2VzIFNoaWZ0K1RhYiBhbmQgQ3RybCtUYWIgdG8KLQkJCSogYWx3YXlzIGF0dGVtcHQgdHJhdmVyc2FsIHdoaWNoIGlzIG5vdCBjb3JyZWN0LgotCQkJKiBUaGUgZGVmYXVsdCBzaG91bGQgYmUgdGhlIHNhbWUgYXMgYSBwbGFpbiBUYWIga2V5LgotCQkJKiBUaGlzIGJlaGF2aW9yIGlzIGN1cnJlbnRseSByZWxpZWQgb24gYnkgU3R5bGVkVGV4dC4KLQkJCSogCi0JCQkqIFRoZSBjb3JyZWN0IGJlaGF2aW9yIGlzIHRvIGdpdmUgZXZlcnkga2V5IHRvIGFueQotCQkJKiBjb250cm9sIHRoYXQgd2FudHMgdG8gc2VlIGV2ZXJ5IGtleS4gIFRoZSBkZWZhdWx0Ci0JCQkqIGJlaGF2aW9yIGZvciBhIENhbnZhcyBzaG91bGQgYmUgdG8gc2VlIGV2ZXJ5IGtleS4KLQkJCSovCi0JCQkvKiBBVwotCQkJc3dpdGNoIChzdGF0ZSBbMF0pIHsKLQkJCQljYXNlIE9TLkdES19TSElGVF9NQVNLOgotCQkJCWNhc2UgT1MuR0RLX0NPTlRST0xfTUFTSzoKLQkJCQkJY29kZSB8PSBTV1QuVFJBVkVSU0VfVEFCX1BSRVZJT1VTIHwgU1dULlRSQVZFUlNFX1RBQl9ORVhUOwotCQkJfQotCQkJKi8KLQkJCWRldGFpbCA9IG5leHQgPyBTV1QuVFJBVkVSU0VfVEFCX05FWFQgOiBTV1QuVFJBVkVSU0VfVEFCX1BSRVZJT1VTOwotCQkJYnJlYWs7Ci0JCX0KLQkJY2FzZSAxMjY6IC8vIE9TLkdES19VcDoKLQkJY2FzZSAxMjM6IC8vIE9TLkdES19MZWZ0OgotCQkJZGV0YWlsID0gU1dULlRSQVZFUlNFX0FSUk9XX1BSRVZJT1VTOwotCQkJYnJlYWs7Ci0JCQkKLQkJY2FzZSAxMjU6IC8vIE9TLkdES19Eb3duOgotCQljYXNlIDEyNDogLyogT1MuR0RLX1JpZ2h0OiAqLwotCQkJZGV0YWlsID0gU1dULlRSQVZFUlNFX0FSUk9XX05FWFQ7Ci0JCQlicmVhazsKLQkJCQotCQljYXNlIDExNjogLy8gT1MuR0RLX1BhZ2VfVXA6Ci0JCWNhc2UgMTIxOiAvKiBPUy5HREtfUGFnZV9Eb3duOiAqLyB7Ci0JCQlhbGwgPSB0cnVlOwotCQkJLyogQVcKLQkJCWlmICgoc3RhdGUgWzBdICYgT1MuR0RLX0NPTlRST0xfTUFTSykgPT0gMCkgcmV0dXJuIGZhbHNlOwotCQkJKi8KLQkJCS8qCi0JCQkqIE5PVEU6IFRoaXMgY29kZSBjYXVzZXMgQ3RybCtQZ1VwIGFuZCBDdHJsK1BnRG4gdG8gYWx3YXlzCi0JCQkqIGF0dGVtcHQgdHJhdmVyc2FsIHdoaWNoIGlzIG5vdCBjb3JyZWN0LiAgVGhpcyBiZWhhdmlvciBpcwotCQkJKiBjdXJyZW50bHkgcmVsaWVkIG9uIGJ5IFN0eWxlZFRleHQuCi0JCQkqIAotCQkJKiBUaGUgY29ycmVjdCBiZWhhdmlvciBpcyB0byBnaXZlIGV2ZXJ5IGtleSB0byBhbnkKLQkJCSogY29udHJvbCB0aGF0IHdhbnRzIHRvIHNlZSBldmVyeSBrZXkuICBUaGUgZGVmYXVsdAotCQkJKiBiZWhhdmlvciBmb3IgYSBDYW52YXMgc2hvdWxkIGJlIHRvIHNlZSBldmVyeSBrZXkuCi0JCQkqLwotCQkJY29kZSB8PSBTV1QuVFJBVkVSU0VfUEFHRV9ORVhUIHwgU1dULlRSQVZFUlNFX1BBR0VfUFJFVklPVVM7Ci0JCQlkZXRhaWwgPSBrZXkgPT0gMTIxID8gU1dULlRSQVZFUlNFX1BBR0VfTkVYVCA6IFNXVC5UUkFWRVJTRV9QQUdFX1BSRVZJT1VTOwotCQkJYnJlYWs7Ci0JCX0KLQkJZGVmYXVsdDoKLQkJCXJldHVybiBmYWxzZTsKLQl9Ci0JCi0JRXZlbnQgZXZlbnQgPSBuZXcgRXZlbnQgKCk7Ci0JZXZlbnQuZG9pdCA9IChjb2RlICYgZGV0YWlsKSAhPSAwOwotCWV2ZW50LmRldGFpbCA9IGRldGFpbDsKLQkvKiBBVwotCWV2ZW50LnRpbWUgPSBrZXlFdmVudC50aW1lOwotCXNldElucHV0U3RhdGUgKGV2ZW50LCBnZGtFdmVudCk7Ci0JKi8KLQlTaGVsbCBzaGVsbCA9IGdldFNoZWxsICgpOwotCUNvbnRyb2wgY29udHJvbCA9IHRoaXM7Ci0JZG8gewotCQlpZiAoY29udHJvbC50cmF2ZXJzZSAoZXZlbnQpKSByZXR1cm4gdHJ1ZTsKLQkJaWYgKCFldmVudC5kb2l0ICYmIGNvbnRyb2wuaG9va3MgKFNXVC5UcmF2ZXJzZSkpIHsKLQkJCXJldHVybiBmYWxzZTsKLQkJfQotCQlpZiAoY29udHJvbCA9PSBzaGVsbCkgcmV0dXJuIGZhbHNlOwotCQljb250cm9sID0gY29udHJvbC5wYXJlbnQ7Ci0JfSB3aGlsZSAoYWxsICYmIGNvbnRyb2wgIT0gbnVsbCk7CitpbnQgdG9wSGFuZGxlICgpIHsKKwlyZXR1cm4gaGFuZGxlOworfQorCitib29sZWFuIHRyYXZlcnNlTW5lbW9uaWMgKGNoYXIga2V5KSB7CiAJcmV0dXJuIGZhbHNlOwogfQotaW50IHRyYXZlcnNhbENvZGUgKCkgewotCS8qIEFXCi0JaW50IFtdIGFyZ0xpc3QgPSBuZXcgaW50IFtdIHtPUy5YbU50cmF2ZXJzYWxPbiwgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlpZiAoYXJnTGlzdCBbMV0gPT0gMCkgcmV0dXJuIDA7Ci0JKi8KLQlpbnQgY29kZSA9IFNXVC5UUkFWRVJTRV9SRVRVUk4gfCBTV1QuVFJBVkVSU0VfVEFCX05FWFQgfCBTV1QuVFJBVkVSU0VfVEFCX1BSRVZJT1VTOwotCVNoZWxsIHNoZWxsID0gZ2V0U2hlbGwgKCk7Ci0JaWYgKHNoZWxsLnBhcmVudCAhPSBudWxsKSBjb2RlIHw9IFNXVC5UUkFWRVJTRV9FU0NBUEU7Ci0JLyogQVcKLQlpZiAoZ2V0TmF2aWdhdGlvblR5cGUgKCkgPT0gT1MuWG1OT05FKSB7Ci0JCWNvZGUgfD0gU1dULlRSQVZFUlNFX0FSUk9XX05FWFQgfCBTV1QuVFJBVkVSU0VfQVJST1dfUFJFVklPVVM7Ci0JfQotCSovCi0JcmV0dXJuIGNvZGU7Ci19Ci1ib29sZWFuIHRyYXZlcnNlTW5lbW9uaWMgKGNoYXIga2V5KSB7Ci0JaWYgKCFpc1Zpc2libGUgKCkgfHwgIWlzRW5hYmxlZCAoKSkgcmV0dXJuIGZhbHNlOwotCXJldHVybiBtbmVtb25pY01hdGNoIChrZXkpICYmIG1uZW1vbmljSGl0IChrZXkpOwotfQotLyoqCi0gKiBCYXNlZCBvbiB0aGUgYXJndW1lbnQsIHBlcmZvcm0gb25lIG9mIHRoZSBleHBlY3RlZCBwbGF0Zm9ybQotICogdHJhdmVyc2FsIGFjdGlvbi4gVGhlIGFyZ3VtZW50IHNob3VsZCBiZSBvbmUgb2YgdGhlIGNvbnN0YW50czoKLSAqIDxjb2RlPlNXVC5UUkFWRVJTRV9FU0NBUEU8L2NvZGU+LCA8Y29kZT5TV1QuVFJBVkVSU0VfUkVUVVJOPC9jb2RlPiwgCi0gKiA8Y29kZT5TV1QuVFJBVkVSU0VfVEFCX05FWFQ8L2NvZGU+LCA8Y29kZT5TV1QuVFJBVkVSU0VfVEFCX1BSRVZJT1VTPC9jb2RlPiwgCi0gKiA8Y29kZT5TV1QuVFJBVkVSU0VfQVJST1dfTkVYVDwvY29kZT4gYW5kIDxjb2RlPlNXVC5UUkFWRVJTRV9BUlJPV19QUkVWSU9VUzwvY29kZT4uCi0gKgotICogQHBhcmFtIHRyYXZlcnNhbCB0aGUgdHlwZSBvZiB0cmF2ZXJzYWwKLSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgdHJhdmVyc2FsIHN1Y2NlZWRlZAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgYm9vbGVhbiB0cmF2ZXJzZSAoaW50IHRyYXZlcnNhbCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKCFpc0ZvY3VzQ29udHJvbCAoKSAmJiAhc2V0Rm9jdXMgKCkpIHJldHVybiBmYWxzZTsKQEAgLTI2MTIsNzEgKzEyMjAsMTkgQEAKIH0KIAogYm9vbGVhbiB0cmF2ZXJzZUVzY2FwZSAoKSB7Ci0JU2hlbGwgc2hlbGwgPSBnZXRTaGVsbCAoKTsKLQlpZiAoc2hlbGwucGFyZW50ID09IG51bGwpIHJldHVybiBmYWxzZTsKLQlpZiAoIXNoZWxsLmlzVmlzaWJsZSAoKSB8fCAhc2hlbGwuaXNFbmFibGVkICgpKSByZXR1cm4gZmFsc2U7Ci0Jc2hlbGwuY2xvc2UgKCk7Ci0JcmV0dXJuIHRydWU7CisJcmV0dXJuIGZhbHNlOwogfQogCiBib29sZWFuIHRyYXZlcnNlR3JvdXAgKGJvb2xlYW4gbmV4dCkgewotCUNvbnRyb2wgcm9vdCA9IGNvbXB1dGVUYWJSb290ICgpOwotCUNvbnRyb2wgZ3JvdXAgPSBjb21wdXRlVGFiR3JvdXAgKCk7Ci0JQ29udHJvbCBbXSBsaXN0ID0gcm9vdC5jb21wdXRlVGFiTGlzdCAoKTsKLQlpbnQgbGVuZ3RoID0gbGlzdC5sZW5ndGg7Ci0JaW50IGluZGV4ID0gMDsKLQl3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHsKLQkJaWYgKGxpc3QgW2luZGV4XSA9PSBncm91cCkgYnJlYWs7Ci0JCWluZGV4Kys7Ci0JfQotCS8qCi0JKiBJdCBpcyBwb3NzaWJsZSAoYnV0IHVubGlrZWx5KSwgdGhhdCBhcHBsaWNhdGlvbgotCSogY29kZSBjb3VsZCBoYXZlIGRpc3Bvc2VkIHRoZSB3aWRnZXQgaW4gZm9jdXMgaW4KLQkqIG9yIG91dCBldmVudHMuICBFbnN1cmUgdGhhdCBhIGRpc3Bvc2VkIHdpZGdldCBpcwotCSogbm90IGFjY2Vzc2VkLgotCSovCi0JaWYgKGluZGV4ID09IGxlbmd0aCkgcmV0dXJuIGZhbHNlOwotCWludCBzdGFydCA9IGluZGV4LCBvZmZzZXQgPSAobmV4dCkgPyAxIDogLTE7Ci0Jd2hpbGUgKChpbmRleCA9ICgoaW5kZXggKyBvZmZzZXQgKyBsZW5ndGgpICUgbGVuZ3RoKSkgIT0gc3RhcnQpIHsKLQkJQ29udHJvbCBjb250cm9sID0gbGlzdCBbaW5kZXhdOwotCQlpZiAoIWNvbnRyb2wuaXNEaXNwb3NlZCAoKSAmJiBjb250cm9sLnNldFRhYkdyb3VwRm9jdXMgKCkpIHsKLQkJCWlmICghaXNEaXNwb3NlZCAoKSAmJiAhaXNGb2N1c0NvbnRyb2wgKCkpIHJldHVybiB0cnVlOwotCQl9Ci0JfQotCWlmIChncm91cC5pc0Rpc3Bvc2VkICgpKSByZXR1cm4gZmFsc2U7Ci0JcmV0dXJuIGdyb3VwLnNldFRhYkdyb3VwRm9jdXMgKCk7CisJcmV0dXJuIGZhbHNlOwogfQogCiBib29sZWFuIHRyYXZlcnNlSXRlbSAoYm9vbGVhbiBuZXh0KSB7Ci0JQ29udHJvbCBbXSBjaGlsZHJlbiA9IHBhcmVudC5fZ2V0Q2hpbGRyZW4gKCk7Ci0JaW50IGxlbmd0aCA9IGNoaWxkcmVuLmxlbmd0aDsKLQlpbnQgaW5kZXggPSAwOwotCXdoaWxlIChpbmRleCA8IGxlbmd0aCkgewotCQlpZiAoY2hpbGRyZW4gW2luZGV4XSA9PSB0aGlzKSBicmVhazsKLQkJaW5kZXgrKzsKLQl9Ci0JLyoKLQkqIEl0IGlzIHBvc3NpYmxlIChidXQgdW5saWtlbHkpLCB0aGF0IGFwcGxpY2F0aW9uCi0JKiBjb2RlIGNvdWxkIGhhdmUgZGlzcG9zZWQgdGhlIHdpZGdldCBpbiBmb2N1cyBpbgotCSogb3Igb3V0IGV2ZW50cy4gIEVuc3VyZSB0aGF0IGEgZGlzcG9zZWQgd2lkZ2V0IGlzCi0JKiBub3QgYWNjZXNzZWQuCi0JKi8KLQlpbnQgc3RhcnQgPSBpbmRleCwgb2Zmc2V0ID0gKG5leHQpID8gMSA6IC0xOwotCXdoaWxlICgoaW5kZXggPSAoaW5kZXggKyBvZmZzZXQgKyBsZW5ndGgpICUgbGVuZ3RoKSAhPSBzdGFydCkgewotCQlDb250cm9sIGNoaWxkID0gY2hpbGRyZW4gW2luZGV4XTsKLQkJaWYgKCFjaGlsZC5pc0Rpc3Bvc2VkICgpICYmIGNoaWxkLmlzVGFiSXRlbSAoKSkgewotCQkJaWYgKGNoaWxkLnNldFRhYkl0ZW1Gb2N1cyAoKSkgcmV0dXJuIHRydWU7Ci0JCX0KLQl9CiAJcmV0dXJuIGZhbHNlOwogfQogCiBib29sZWFuIHRyYXZlcnNlUmV0dXJuICgpIHsKLQlCdXR0b24gYnV0dG9uID0gbWVudVNoZWxsICgpLmdldERlZmF1bHRCdXR0b24gKCk7Ci0JaWYgKGJ1dHRvbiA9PSBudWxsIHx8IGJ1dHRvbi5pc0Rpc3Bvc2VkICgpKSByZXR1cm4gZmFsc2U7Ci0JaWYgKCFidXR0b24uaXNWaXNpYmxlICgpIHx8ICFidXR0b24uaXNFbmFibGVkICgpKSByZXR1cm4gZmFsc2U7Ci0JYnV0dG9uLmNsaWNrICgpOwotCXJldHVybiB0cnVlOworCXJldHVybiBmYWxzZTsKIH0KIAogYm9vbGVhbiB0cmF2ZXJzZVBhZ2UgKGJvb2xlYW4gbmV4dCkgewpAQCAtMjY4NCw5NiArMTI0MCwxMyBAQAogfQogCiBib29sZWFuIHRyYXZlcnNlTW5lbW9uaWMgKEV2ZW50IGV2ZW50KSB7Ci0JLy8gVGhpcyBjb2RlIGlzIGludGVudGlvbmFsbHkgY29tbWVudGVkLgotCS8vIFRyYXZlcnNlTW5lbW9uaWMgYWx3YXlzIG9yaWdpbmF0ZXMgZnJvbSB0aGUgT1MgYW5kCi0JLy8gbmV2ZXIgdGhyb3VnaCB0aGUgQVBJLCBhbmQgb24gdGhlIEdUSyBwbGF0Zm9ybSwgYWNjZWxzCi0JLy8gYXJlIGhvb2tlZCBieSB0aGUgT1MgYmVmb3JlIHdlIGdldCB0aGUga2V5IGV2ZW50LgotCS8vIGludCBzaGVsbEhhbmRsZSA9IF9nZXRTaGVsbCAoKS50b3BIYW5kbGUgKCk7Ci0JLy8gcmV0dXJuIE9TLmd0a19hY2NlbF9ncm91cHNfYWN0aXZhdGUgKHNoZWxsSGFuZGxlLCBrZXlDb2RlLCBzdGF0ZU1hc2spOwotCXJldHVybiB0cnVlOworCXJldHVybiBmYWxzZTsKIH0KLS8qKgotICogRm9yY2VzIGFsbCBvdXRzdGFuZGluZyBwYWludCByZXF1ZXN0cyBmb3IgdGhlIHdpZGdldCB0cmVlCi0gKiB0byBiZSBwcm9jZXNzZWQgYmVmb3JlIHRoaXMgbWV0aG9kIHJldHVybnMuCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI3JlZHJhdwotICovCisKIHB1YmxpYyB2b2lkIHVwZGF0ZSAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLSAgICAvKiBBVwotCWludCBkaXNwbGF5ID0gT1MuWHREaXNwbGF5IChoYW5kbGUpOwotCWlmIChkaXNwbGF5ID09IDApIHJldHVybjsKLQlpbnQgd2luZG93ID0gT1MuWHRXaW5kb3cgKGhhbmRsZSk7Ci0JaWYgKHdpbmRvdyA9PSAwKSByZXR1cm47Ci0JWEFueUV2ZW50IGV2ZW50ID0gbmV3IFhBbnlFdmVudCAoKTsKLQlPUy5YU3luYyAoZGlzcGxheSwgZmFsc2UpOyAgT1MuWFN5bmMgKGRpc3BsYXksIGZhbHNlKTsKLQl3aGlsZSAoT1MuWENoZWNrV2luZG93RXZlbnQgKGRpc3BsYXksIHdpbmRvdywgT1MuRXhwb3N1cmVNYXNrLCBldmVudCkpIHsKLQkJT1MuWHREaXNwYXRjaEV2ZW50IChldmVudCk7Ci0JfQotICAgICovCi0JZ2V0RGlzcGxheSgpLnVwZGF0ZSgpOworCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisJZGlzcGxheS51cGRhdGUgKCk7CiB9CiAKLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLS8vIE1hYyBzdHVmZgotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCS8qKgotCSAqIFNldHMgdGhlIGJvdW5kcyBvZiB0aGUgZ2l2ZW4gY29udHJvbC4KLQkgKi8KLQlwcml2YXRlIHZvaWQgaW50ZXJuYWxTZXRCb3VuZHMoaW50IGhuZGwsIE1hY1JlY3Qgb2xkQm91bmRzLCBpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgewotCQlpZiAoTWFjVXRpbC5VU0VfRlJBTUUpIHsKLQkJCU1hY1JlY3QgbmV3Qm91bmRzPSBuZXcgTWFjUmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKLQkJCWhhbmRsZVJlc2l6ZShobmRsLCBuZXdCb3VuZHMpOwotCQl9IGVsc2UgewotCQkJaW50IHdIYW5kbGU9IE9TLkdldENvbnRyb2xPd25lcihobmRsKTsKLQkJCU9TLkludmFsV2luZG93UmVjdCh3SGFuZGxlLCBvbGRCb3VuZHMuZ2V0RGF0YSgpKTsKLQkJCQotCQkJTWFjUmVjdCBuZXdCb3VuZHM9IG5ldyBNYWNSZWN0KHgsIHksIHdpZHRoLCBoZWlnaHQpOwotCQkJaGFuZGxlUmVzaXplKGhuZGwsIG5ld0JvdW5kcyk7Ci0JCQlPUy5JbnZhbFdpbmRvd1JlY3Qod0hhbmRsZSwgbmV3Qm91bmRzLmdldERhdGEoKSk7Ci0JCX0KLQl9Ci0JCi0JLyoqCi0JICogc3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUgaWYgYSByZXNpemUgbXVzdCB0cmlnZ2VyIHNvbWUgaW50ZXJuYWwgbGF5b3V0LgotCSAqLwotCXZvaWQgaGFuZGxlUmVzaXplKGludCBobmRsLCBNYWNSZWN0IGJvdW5kcykgewotCQlpZiAoTWFjVXRpbC5VU0VfRlJBTUUpCi0JCQlPUy5ISVZpZXdTZXRGcmFtZShobmRsLCBib3VuZHMuZ2V0WCgpLCBib3VuZHMuZ2V0WSgpLCBib3VuZHMuZ2V0V2lkdGgoKSwgYm91bmRzLmdldEhlaWdodCgpKTsKLQkJZWxzZQotCQkJT1MuU2V0Q29udHJvbEJvdW5kcyhobmRsLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQl9Ci0JCi0JLyoqCi0JICogc3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUuCi0JICovCi0Jdm9pZCBpbnRlcm5hbEdldENvbnRyb2xCb3VuZHMoaW50IGhuZGwsIE1hY1JlY3QgYm91bmRzKSB7Ci0JCWlmIChNYWNVdGlsLlVTRV9GUkFNRSkgewotCQkJZmxvYXRbXSBmPSBuZXcgZmxvYXRbNF07Ci0JCQlPUy5ISVZpZXdHZXRGcmFtZShobmRsLCBmKTsKLQkJCWJvdW5kcy5zZXQoKGludClmWzBdLCAoaW50KWZbMV0sIChpbnQpZlsyXSwgKGludClmWzNdKTsKLQkJfSBlbHNlIHsKLQkJCU9TLkdldENvbnRyb2xCb3VuZHMoaG5kbCwgYm91bmRzLmdldERhdGEoKSk7Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBIb29rIChvdmVyd3JpdHRlbiBpbiBUZXh0IGFuZCBDb21ibykKLQkgKi8KLQkvKgotCWZpbmFsIGludCBzZW5kS2V5RXZlbnQoaW50IHR5cGUsIGludCBuZXh0SGFuZGxlciwgaW50IGVSZWZIYW5kbGUpIHsKLQkJCi0JCU1hY0V2ZW50IG1FdmVudD0gbmV3IE1hY0V2ZW50KGVSZWZIYW5kbGUpOwotCQlpZiAodHJhbnNsYXRlVHJhdmVyc2FsKG1FdmVudCkpCi0JCQlyZXR1cm4gMDsKLQotCQlwcm9jZXNzRXZlbnQgKHR5cGUsIG5ldyBNYWNFdmVudChlUmVmSGFuZGxlKSk7Ci0JCXJldHVybiBPUy5rTm9FcnI7Ci0JfQotCSovCiB9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0RlY29yYXRpb25zLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvRGVjb3JhdGlvbnMuamF2YQppbmRleCA3YTUwM2RlLi43YzZhYzk4IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvRGVjb3JhdGlvbnMuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvRGVjb3JhdGlvbnMuamF2YQpAQCAtNyw0MTMgKzcsMTE3IEBACiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCiAKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLk9TOworCiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7CiAKLS8qKgotICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgcHJvdmlkZSB0aGUgYXBwZWFyYW5jZSBhbmQKLSAqIGJlaGF2aW9yIG9mIDxjb2RlPlNoZWxsczwvY29kZT4sIGJ1dCBhcmUgbm90IHRvcAotICogbGV2ZWwgc2hlbGxzIG9yIGRpYWxvZ3MuIENsYXNzIDxjb2RlPlNoZWxsPC9jb2RlPgotICogc2hhcmVzIGEgc2lnbmlmaWNhbnQgYW1vdW50IG9mIGNvZGUgd2l0aCB0aGlzIGNsYXNzLAotICogYW5kIGlzIGEgc3ViY2xhc3MuCi0gKiA8cD4KLSAqIEluc3RhbmNlcyBhcmUgYWx3YXlzIGRpc3BsYXllZCBpbiBvbmUgb2YgdGhlIG1heGltaXplZCwgCi0gKiBtaW5pbWl6ZWQgb3Igbm9ybWFsIHN0YXRlczoKLSAqIDx1bD4KLSAqIDxsaT4KLSAqIFdoZW4gYW4gaW5zdGFuY2UgaXMgbWFya2VkIGFzIDxlbT5tYXhpbWl6ZWQ8L2VtPiwgdGhlCi0gKiB3aW5kb3cgbWFuYWdlciB3aWxsIHR5cGljYWxseSByZXNpemUgaXQgdG8gZmlsbCB0aGUKLSAqIGVudGlyZSB2aXNpYmxlIGFyZWEgb2YgdGhlIGRpc3BsYXksIGFuZCB0aGUgaW5zdGFuY2UKLSAqIGlzIHVzdWFsbHkgcHV0IGluIGEgc3RhdGUgd2hlcmUgaXQgY2FuIG5vdCBiZSByZXNpemVkIAotICogKGV2ZW4gaWYgaXQgaGFzIHN0eWxlIDxjb2RlPlJFU0laRTwvY29kZT4pIHVudGlsIGl0IGlzCi0gKiBubyBsb25nZXIgbWF4aW1pemVkLgotICogPC9saT48bGk+Ci0gKiBXaGVuIGFuIGluc3RhbmNlIGlzIGluIHRoZSA8ZW0+bm9ybWFsPC9lbT4gc3RhdGUgKG5laXRoZXIKLSAqIG1heGltaXplZCBvciBtaW5pbWl6ZWQpLCBpdHMgYXBwZWFyYW5jZSBpcyBjb250cm9sbGVkIGJ5Ci0gKiB0aGUgc3R5bGUgY29uc3RhbnRzIHdoaWNoIHdlcmUgc3BlY2lmaWVkIHdoZW4gaXQgd2FzIGNyZWF0ZWQKLSAqIGFuZCB0aGUgcmVzdHJpY3Rpb25zIG9mIHRoZSB3aW5kb3cgbWFuYWdlciAoc2VlIGJlbG93KS4KLSAqIDwvbGk+PGxpPgotICogV2hlbiBhbiBpbnN0YW5jZSBoYXMgYmVlbiBtYXJrZWQgYXMgPGVtPm1pbmltaXplZDwvZW0+LAotICogaXRzIGNvbnRlbnRzIChjbGllbnQgYXJlYSkgd2lsbCB1c3VhbGx5IG5vdCBiZSB2aXNpYmxlLAotICogYW5kIGRlcGVuZGluZyBvbiB0aGUgd2luZG93IG1hbmFnZXIsIGl0IG1heSBiZQotICogImljb25pZmllZCIgKHRoYXQgaXMsIHJlcGxhY2VkIG9uIHRoZSBkZXNrdG9wIGJ5IGEgc21hbGwKLSAqIHNpbXBsaWZpZWQgcmVwcmVzZW50YXRpb24gb2YgaXRzZWxmKSwgcmVsb2NhdGVkIHRvIGEKLSAqIGRpc3Rpbmd1aXNoZWQgYXJlYSBvZiB0aGUgc2NyZWVuLCBvciBoaWRkZW4uIENvbWJpbmF0aW9ucwotICogb2YgdGhlc2UgY2hhbmdlcyBhcmUgYWxzbyBwb3NzaWJsZS4KLSAqIDwvbGk+Ci0gKiA8L3VsPgotICogPC9wPgotICogTm90ZTogVGhlIHN0eWxlcyBzdXBwb3J0ZWQgYnkgdGhpcyBjbGFzcyBtdXN0IGJlIHRyZWF0ZWQKLSAqIGFzIDxlbT5ISU5UPC9lbT5zLCBzaW5jZSB0aGUgd2luZG93IG1hbmFnZXIgZm9yIHRoZQotICogZGVza3RvcCBvbiB3aGljaCB0aGUgaW5zdGFuY2UgaXMgdmlzaWJsZSBoYXMgdWx0aW1hdGUKLSAqIGNvbnRyb2wgb3ZlciB0aGUgYXBwZWFyYW5jZSBhbmQgYmVoYXZpb3Igb2YgZGVjb3JhdGlvbnMuCi0gKiBGb3IgZXhhbXBsZSwgc29tZSB3aW5kb3cgbWFuYWdlcnMgb25seSBzdXBwb3J0IHJlc2l6YWJsZQotICogd2luZG93cyBhbmQgd2lsbCBhbHdheXMgYXNzdW1lIHRoZSBSRVNJWkUgc3R5bGUsIGV2ZW4gaWYKLSAqIGl0IGlzIG5vdCBzZXQuCi0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPkJPUkRFUiwgQ0xPU0UsIE1JTiwgTUFYLCBOT19UUklNLCBSRVNJWkUsIFRJVExFLCBPTl9UT1AsIFRPT0w8L2RkPgotICogPGR0PjxiPkV2ZW50czo8L2I+PC9kdD4KLSAqIDxkZD4obm9uZSk8L2RkPgotICogPC9kbD4KLSAqIENsYXNzIDxjb2RlPlNXVDwvY29kZT4gcHJvdmlkZXMgdHdvICJjb252ZW5pZW5jZSBjb25zdGFudHMiCi0gKiBmb3IgdGhlIG1vc3QgY29tbW9ubHkgcmVxdWlyZWQgc3R5bGUgY29tYmluYXRpb25zOgotICogPGRsPgotICogPGR0Pjxjb2RlPlNIRUxMX1RSSU08L2NvZGU+PC9kdD4KLSAqIDxkZD4KLSAqIHRoZSByZXN1bHQgb2YgY29tYmluaW5nIHRoZSBjb25zdGFudHMgd2hpY2ggYXJlIHJlcXVpcmVkCi0gKiB0byBwcm9kdWNlIGEgdHlwaWNhbCBhcHBsaWNhdGlvbiB0b3AgbGV2ZWwgc2hlbGw6ICh0aGF0IAotICogaXMsIDxjb2RlPkNMT1NFIHwgVElUTEUgfCBNSU4gfCBNQVggfCBSRVNJWkU8L2NvZGU+KQotICogPC9kZD4KLSAqIDxkdD48Y29kZT5ESUFMT0dfVFJJTTwvY29kZT48L2R0PgotICogPGRkPgotICogdGhlIHJlc3VsdCBvZiBjb21iaW5pbmcgdGhlIGNvbnN0YW50cyB3aGljaCBhcmUgcmVxdWlyZWQKLSAqIHRvIHByb2R1Y2UgYSB0eXBpY2FsIGFwcGxpY2F0aW9uIGRpYWxvZyBzaGVsbDogKHRoYXQgCi0gKiBpcywgPGNvZGU+VElUTEUgfCBDTE9TRSB8IEJPUkRFUjwvY29kZT4pCi0gKiA8L2RkPgotICogPC9kbD4KLSAqIDxwPgotICogSU1QT1JUQU5UOiBUaGlzIGNsYXNzIGlzIGludGVuZGVkIHRvIGJlIHN1YmNsYXNzZWQgPGVtPm9ubHk8L2VtPgotICogd2l0aGluIHRoZSBTV1QgaW1wbGVtZW50YXRpb24uCi0gKiA8L3A+Ci0gKgotICogQHNlZSAjZ2V0TWluaW1pemVkCi0gKiBAc2VlICNnZXRNYXhpbWl6ZWQKLSAqIEBzZWUgU2hlbGwKLSAqIEBzZWUgU1dUCi0gKi8KIHB1YmxpYyBjbGFzcyBEZWNvcmF0aW9ucyBleHRlbmRzIENhbnZhcyB7Ci0JU3RyaW5nIGxhYmVsOwogCUltYWdlIGltYWdlOwotCS8qIEFXCi0JaW50IGRpYWxvZ0hhbmRsZTsKLQkqLwotCS8vIEFXCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZJUlNUX01FTlVfSVRFTV9JRD0gMTAwMDsKLQkvLyBBVwotCWJvb2xlYW4gbWluaW1pemVkLCBtYXhpbWl6ZWQ7CiAJTWVudSBtZW51QmFyOwotCU1lbnUgW10gbWVudXM7Ci0JTWVudUl0ZW0gW10gaXRlbXM7CisJU3RyaW5nIHRleHQgPSAiIjsKKwlib29sZWFuIG1pbmltaXplZCwgbWF4aW1pemVkOwogCUNvbnRyb2wgc2F2ZWRGb2N1czsKIAlCdXR0b24gZGVmYXVsdEJ1dHRvbiwgc2F2ZURlZmF1bHQ7CisJCiBEZWNvcmF0aW9ucyAoKSB7CiAJLyogRG8gbm90aGluZyAqLwogfQotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gaXRzIHBhcmVudAotICogYW5kIGEgc3R5bGUgdmFsdWUgZGVzY3JpYmluZyBpdHMgYmVoYXZpb3IgYW5kIGFwcGVhcmFuY2UuCi0gKiA8cD4KLSAqIFRoZSBzdHlsZSB2YWx1ZSBpcyBlaXRoZXIgb25lIG9mIHRoZSBzdHlsZSBjb25zdGFudHMgZGVmaW5lZCBpbgotICogY2xhc3MgPGNvZGU+U1dUPC9jb2RlPiB3aGljaCBpcyBhcHBsaWNhYmxlIHRvIGluc3RhbmNlcyBvZiB0aGlzCi0gKiBjbGFzcywgb3IgbXVzdCBiZSBidWlsdCBieSA8ZW0+Yml0d2lzZSBPUjwvZW0+J2luZyB0b2dldGhlciAKLSAqICh0aGF0IGlzLCB1c2luZyB0aGUgPGNvZGU+aW50PC9jb2RlPiAifCIgb3BlcmF0b3IpIHR3byBvciBtb3JlCi0gKiBvZiB0aG9zZSA8Y29kZT5TV1Q8L2NvZGU+IHN0eWxlIGNvbnN0YW50cy4gVGhlIGNsYXNzIGRlc2NyaXB0aW9uCi0gKiBsaXN0cyB0aGUgc3R5bGUgY29uc3RhbnRzIHRoYXQgYXJlIGFwcGxpY2FibGUgdG8gdGhlIGNsYXNzLgotICogU3R5bGUgYml0cyBhcmUgYWxzbyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIGNvbXBvc2l0ZSBjb250cm9sIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqIEBwYXJhbSBzdHlsZSB0aGUgc3R5bGUgb2YgY29udHJvbCB0byBjb25zdHJ1Y3QKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU1dUI0JPUkRFUgotICogQHNlZSBTV1QjQ0xPU0UKLSAqIEBzZWUgU1dUI01JTgotICogQHNlZSBTV1QjTUFYCi0gKiBAc2VlIFNXVCNSRVNJWkUKLSAqIEBzZWUgU1dUI1RJVExFCi0gKiBAc2VlIFNXVCNOT19UUklNCi0gKiBAc2VlIFNXVCNTSEVMTF9UUklNCi0gKiBAc2VlIFNXVCNESUFMT0dfVFJJTQotICogQHNlZSBTV1QjT05fVE9QCi0gKiBAc2VlIFNXVCNUT09MCi0gKiBAc2VlIFdpZGdldCNjaGVja1N1YmNsYXNzCi0gKiBAc2VlIFdpZGdldCNnZXRTdHlsZQotICovCisKIHB1YmxpYyBEZWNvcmF0aW9ucyAoQ29tcG9zaXRlIHBhcmVudCwgaW50IHN0eWxlKSB7CiAJc3VwZXIgKHBhcmVudCwgY2hlY2tTdHlsZSAoc3R5bGUpKTsKIH0KLXZvaWQgYWRkIChNZW51IG1lbnUpIHsKLQlpZiAobWVudXMgPT0gbnVsbCkgbWVudXMgPSBuZXcgTWVudSBbNF07Ci0JZm9yIChpbnQgaT0wOyBpPG1lbnVzLmxlbmd0aDsgaSsrKSB7Ci0JCWlmIChtZW51cyBbaV0gPT0gbnVsbCkgewotCQkJbWVudXMgW2ldID0gbWVudTsKLQkJCXJldHVybjsKLQkJfQotCX0KLQlNZW51IFtdIG5ld01lbnVzID0gbmV3IE1lbnUgW21lbnVzLmxlbmd0aCArIDRdOwotCW5ld01lbnVzIFttZW51cy5sZW5ndGhdID0gbWVudTsKLQlTeXN0ZW0uYXJyYXljb3B5IChtZW51cywgMCwgbmV3TWVudXMsIDAsIG1lbnVzLmxlbmd0aCk7Ci0JbWVudXMgPSBuZXdNZW51czsKLX0KLXZvaWQgYWRkIChNZW51SXRlbSBpdGVtKSB7Ci0JaWYgKGl0ZW1zID09IG51bGwpIGl0ZW1zID0gbmV3IE1lbnVJdGVtIFsxMl07Ci0JZm9yIChpbnQgaT0wOyBpPGl0ZW1zLmxlbmd0aDsgaSsrKSB7Ci0JCWlmIChpdGVtcyBbaV0gPT0gbnVsbCkgewotCQkJaXRlbS5pZCA9IEZJUlNUX01FTlVfSVRFTV9JRCArIGk7Ci0JCQlpdGVtcyBbaV0gPSBpdGVtOwotCQkJcmV0dXJuOwotCQl9Ci0JfQotCU1lbnVJdGVtIFtdIG5ld0l0ZW1zID0gbmV3IE1lbnVJdGVtIFtpdGVtcy5sZW5ndGggKyAxMl07Ci0JaXRlbS5pZCA9IEZJUlNUX01FTlVfSVRFTV9JRCArIGl0ZW1zLmxlbmd0aDsKLQluZXdJdGVtcyBbaXRlbXMubGVuZ3RoXSA9IGl0ZW07Ci0JU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIDAsIG5ld0l0ZW1zLCAwLCBpdGVtcy5sZW5ndGgpOwotCWl0ZW1zID0gbmV3SXRlbXM7Ci19Ci12b2lkIGJyaW5nVG9Ub3AgKCkgewotCS8qCi0JKiBGZWF0dXJlIGluIFguICBDYWxsaW5nIFhTZXRJbnB1dEZvY3VzKCkgd2hlbiB0aGUKLQkqIHdpZGdldCBpcyBub3Qgdmlld2FibGUgY2F1c2VzIGFuIFggYmFkIG1hdGNoIGVycm9yLgotCSogVGhlIGZpeCBpcyB0byBjYWxsIFhTZXRJbnB1dEZvY3VzKCkgd2hlbiB0aGUgd2lkZ2V0Ci0JKiBpcyB2aWV3YWJsZS4KLQkqLwotCWlmIChtaW5pbWl6ZWQpIHJldHVybjsKLQlpZiAoIWlzVmlzaWJsZSAoKSkgcmV0dXJuOwotICAgIC8qIEFXCi0JaW50IGRpc3BsYXkgPSBPUy5YdERpc3BsYXkgKGhhbmRsZSk7Ci0JaWYgKGRpc3BsYXkgPT0gMCkgcmV0dXJuOwotCWludCB3aW5kb3cgPSBPUy5YdFdpbmRvdyAoaGFuZGxlKTsKLQlpZiAod2luZG93ID09IDApIHJldHVybjsKLQlPUy5YU2V0SW5wdXRGb2N1cyAoZGlzcGxheSwgd2luZG93LCBPUy5SZXZlcnRUb1BhcmVudCwgT1MuQ3VycmVudFRpbWUpOwotICAgICovCi19CisKIHN0YXRpYyBpbnQgY2hlY2tTdHlsZSAoaW50IHN0eWxlKSB7CiAJaWYgKChzdHlsZSAmIChTV1QuTUVOVSB8IFNXVC5NSU4gfCBTV1QuTUFYIHwgU1dULkNMT1NFKSkgIT0gMCkgewogCQlzdHlsZSB8PSBTV1QuVElUTEU7CiAJfQogCXJldHVybiBzdHlsZTsKIH0KKwogcHJvdGVjdGVkIHZvaWQgY2hlY2tTdWJjbGFzcyAoKSB7CiAJaWYgKCFpc1ZhbGlkU3ViY2xhc3MgKCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9TVUJDTEFTUyk7CiB9CisKIENvbnRyb2wgY29tcHV0ZVRhYkdyb3VwICgpIHsKIAlyZXR1cm4gdGhpczsKIH0KKwogQ29udHJvbCBjb21wdXRlVGFiUm9vdCAoKSB7CiAJcmV0dXJuIHRoaXM7CiB9Ci12b2lkIGNyZWF0ZUhhbmRsZSAoaW50IGluZGV4KSB7Ci0Jc3RhdGUgfD0gSEFORExFIHwgQ0FOVkFTOwotCWNyZWF0ZVNjcm9sbGVkSGFuZGxlIChwYXJlbnQuaGFuZGxlKTsKLX0KLXZvaWQgY3JlYXRlV2lkZ2V0IChpbnQgaW5kZXgpIHsKLQlzdXBlci5jcmVhdGVXaWRnZXQgKGluZGV4KTsKLQlsYWJlbCA9ICIiOwotfQotLyogQVcKLWludCBkaWFsb2dIYW5kbGUgKCkgewotCWlmIChkaWFsb2dIYW5kbGUgIT0gMCkgcmV0dXJuIGRpYWxvZ0hhbmRsZTsKLQlyZXR1cm4gZGlhbG9nSGFuZGxlID0gT1MuY3JlYXRlRGlhbG9nU2hlbGwoaGFuZGxlLCAwKTsKLX0KLSovCi0vKiBBVwotTWVudSBmaW5kTWVudSAoaW50IGlkKSB7Ci0JU3lzdGVtLm91dC5wcmludGxuKCIqKioqKioqKiogRGVjb3JhdG9yLmZpbmRNZW51ICoqKioqKioqKiIpOwotCWlmIChtZW51cyA9PSBudWxsKSByZXR1cm4gbnVsbDsKLQlmb3IgKGludCBpPSAwOyBpIDwgbWVudXMubGVuZ3RoOyBpKyspIHsKLQkJTWVudSBtZW51PSBtZW51c1tpXTsKLQkJaWYgKG1lbnUgIT0gbnVsbCkgewotCQkJaWYgKE9TLkdldE1lbnVJRChtZW51LmhhbmRsZSkgPT0gaWQpCi0JCQkJcmV0dXJuIG1lbnU7Ci0JCX0KLQl9Ci0JcmV0dXJuIG51bGw7Ci19Ci0qLwotLy8gQVcKLU1lbnVJdGVtIGZpbmRNZW51SXRlbSAoaW50IGlkKSB7Ci0JaWYgKGl0ZW1zID09IG51bGwpIHJldHVybiBudWxsOwotCWlkLT0gRklSU1RfTUVOVV9JVEVNX0lEOwotCWlmICgwIDw9IGlkICYmIGlkIDwgaXRlbXMubGVuZ3RoKSByZXR1cm4gaXRlbXMgW2lkXTsKLQlyZXR1cm4gbnVsbDsKLX0KLS8vIEFXCi0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3MgZGVmYXVsdCBidXR0b24gaWYgb25lIGhhZAotICogcHJldmlvdXNseSBiZWVuIHNldCwgb3RoZXJ3aXNlIHJldHVybnMgbnVsbC4KLSAqCi0gKiBAcmV0dXJuIHRoZSBkZWZhdWx0IGJ1dHRvbiBvciBudWxsCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI3NldERlZmF1bHRCdXR0b24KLSAqLworCiBwdWJsaWMgQnV0dG9uIGdldERlZmF1bHRCdXR0b24gKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIGRlZmF1bHRCdXR0b247CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3MgaW1hZ2UgaWYgaXQgaGFkIHByZXZpb3VzbHkgYmVlbiAKLSAqIHNldCB1c2luZyA8Y29kZT5zZXRJbWFnZSgpPC9jb2RlPi4gVGhlIGltYWdlIGlzIHR5cGljYWxseQotICogZGlzcGxheWVkIGJ5IHRoZSB3aW5kb3cgbWFuYWdlciB3aGVuIHRoZSBpbnN0YW5jZSBpcwotICogbWFya2VkIGFzIGljb25pZmllZCwgYW5kIG1heSBhbHNvIGJlIGRpc3BsYXllZCBzb21ld2hlcmUKLSAqIGluIHRoZSB0cmltIHdoZW4gdGhlIGluc3RhbmNlIGlzIGluIG5vcm1hbCBvciBtYXhpbWl6ZWQKLSAqIHN0YXRlcy4KLSAqIDxwPgotICogTm90ZTogVGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gbnVsbCBpZiBjYWxsZWQgYmVmb3JlCi0gKiA8Y29kZT5zZXRJbWFnZSgpPC9jb2RlPiBpcyBjYWxsZWQuIEl0IGRvZXMgbm90IHByb3ZpZGUKLSAqIGFjY2VzcyB0byBhIHdpbmRvdyBtYW5hZ2VyIHByb3ZpZGVkLCAiZGVmYXVsdCIgaW1hZ2UKLSAqIGV2ZW4gaWYgb25lIGV4aXN0cy4KLSAqIDwvcD4KLSAqIAotICogQHJldHVybiB0aGUgaW1hZ2UKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIEltYWdlIGdldEltYWdlICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBpbWFnZTsKIH0KLS8qKgotICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVjZWl2ZXIgaXMgY3VycmVudGx5Ci0gKiBtYXhpbWl6ZWQsIGFuZCBmYWxzZSBvdGhlcndpc2UuIAotICogPHA+Ci0gKgotICogQHJldHVybiB0aGUgbWF4aW1pemVkIHN0YXRlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI3NldE1heGltaXplZAotICovCisKIHB1YmxpYyBib29sZWFuIGdldE1heGltaXplZCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlyZXR1cm4gbWF4aW1pemVkOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSByZWNlaXZlcidzIG1lbnUgYmFyIGlmIG9uZSBoYWQgcHJldmlvdXNseQotICogYmVlbiBzZXQsIG90aGVyd2lzZSByZXR1cm5zIG51bGwuCi0gKgotICogQHJldHVybiB0aGUgbWVudSBiYXIgb3IgbnVsbAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgTWVudSBnZXRNZW51QmFyICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBtZW51QmFyOwogfQotLyoqCi0gKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSByZWNlaXZlciBpcyBjdXJyZW50bHkKLSAqIG1pbmltaXplZCwgYW5kIGZhbHNlIG90aGVyd2lzZS4gCi0gKiA8cD4KLSAqCi0gKiBAcmV0dXJuIHRoZSBtaW5pbWl6ZWQgc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjc2V0TWluaW1pemVkCi0gKi8KKwogcHVibGljIGJvb2xlYW4gZ2V0TWluaW1pemVkICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBtaW5pbWl6ZWQ7CiB9CisKIFN0cmluZyBnZXROYW1lVGV4dCAoKSB7CiAJcmV0dXJuIGdldFRleHQgKCk7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3MgdGV4dCwgd2hpY2ggaXMgdGhlIHN0cmluZyB0aGF0IHRoZQotICogd2luZG93IG1hbmFnZXIgd2lsbCB0eXBpY2FsbHkgZGlzcGxheSBhcyB0aGUgcmVjZWl2ZXIncwotICogPGVtPnRpdGxlPC9lbT4uIElmIHRoZSB0ZXh0IGhhcyBub3QgcHJldmlvdXNseSBiZWVuIHNldCwgCi0gKiByZXR1cm5zIGFuIGVtcHR5IHN0cmluZy4KLSAqCi0gKiBAcmV0dXJuIHRoZSB0ZXh0Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlyZXR1cm4gbGFiZWw7CisJcmV0dXJuIHRleHQ7CiB9CisKIGJvb2xlYW4gaXNUYWJHcm91cCAoKSB7CiAJcmV0dXJuIHRydWU7CiB9CisKIGJvb2xlYW4gaXNUYWJJdGVtICgpIHsKIAlyZXR1cm4gZmFsc2U7CiB9CisKIERlY29yYXRpb25zIG1lbnVTaGVsbCAoKSB7CiAJcmV0dXJuIHRoaXM7CiB9Ci1pbnQgcHJvY2Vzc1NldEZvY3VzIChPYmplY3QgY2FsbERhdGEpIHsKLQlpbnQgcmVzdWx0PSBzdXBlci5wcm9jZXNzU2V0Rm9jdXMgKGNhbGxEYXRhKTsKLQkKLQlCb29sZWFuIGI9IChCb29sZWFuKSBjYWxsRGF0YTsKLQlpZiAoYi5ib29sZWFuVmFsdWUgKCkpIHsJLy8gZm9jdXNJbgotCQlyZXN0b3JlRm9jdXMgKCk7Ci0JfSBlbHNlIHsJLy8gZm9jdU91dAotCQlzYXZlRm9jdXMgKCk7Ci0JfQotCQotCXJldHVybiByZXN1bHQ7Ci19Ci0vKiBBVwotdm9pZCBwcm9wYWdhdGVXaWRnZXQgKGJvb2xlYW4gZW5hYmxlZCkgewotCXN1cGVyLnByb3BhZ2F0ZVdpZGdldCAoZW5hYmxlZCk7Ci0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1ObWVudUJhciwgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKHNjcm9sbGVkSGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCWlmIChhcmdMaXN0IFsxXSAhPSAwKSBwcm9wYWdhdGVIYW5kbGUgKGVuYWJsZWQsIGFyZ0xpc3QgWzFdKTsKLX0KLSovCi0vKiBBVwotdm9pZCByZWxlYXNlSGFuZGxlICgpIHsKLQlzdXBlci5yZWxlYXNlSGFuZGxlICgpOwotCWRpYWxvZ0hhbmRsZSA9IDA7Ci19Ci0qLworCiB2b2lkIHJlbGVhc2VXaWRnZXQgKCkgewotCWlmIChtZW51cyAhPSBudWxsKSB7Ci0JCWZvciAoaW50IGk9MDsgaTxtZW51cy5sZW5ndGg7IGkrKykgewotCQkJTWVudSBtZW51ID0gbWVudXMgW2ldOwotCQkJaWYgKG1lbnUgIT0gbnVsbCAmJiAhbWVudS5pc0Rpc3Bvc2VkICgpKSB7Ci0JCQkJbWVudS5yZWxlYXNlV2lkZ2V0ICgpOwotCQkJCW1lbnUucmVsZWFzZUhhbmRsZSAoKTsKLQkJCX0KLQkJfQotCX0KKwlpZiAobWVudUJhciAhPSBudWxsKSBtZW51QmFyLmRpc3Bvc2UgKCk7CiAJbWVudUJhciA9IG51bGw7CisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlNZW51IFtdIG1lbnVzID0gZGlzcGxheS5nZXRNZW51cyAodGhpcyk7CisJaWYgKG1lbnVzICE9IG51bGwpIHsKKwkJZG8geworCQkJaW50IGluZGV4ID0gMDsKKwkJCXdoaWxlIChpbmRleCA8IG1lbnVzLmxlbmd0aCkgeworCQkJCU1lbnUgbWVudSA9IG1lbnVzIFtpbmRleF07CisJCQkJaWYgKG1lbnUgIT0gbnVsbCAmJiAhbWVudS5pc0Rpc3Bvc2VkICgpKSB7CisJCQkJCXdoaWxlIChtZW51LmdldFBhcmVudE1lbnUgKCkgIT0gbnVsbCkgeworCQkJCQkJbWVudSA9IG1lbnUuZ2V0UGFyZW50TWVudSAoKTsKKwkJCQkJfQorCQkJCQltZW51LmRpc3Bvc2UgKCk7CisJCQkJCWJyZWFrOworCQkJCX0KKwkJCQlpbmRleCsrOworCQkJfQorCQkJaWYgKGluZGV4ID09IG1lbnVzLmxlbmd0aCkgYnJlYWs7CisJCX0gd2hpbGUgKHRydWUpOworCX0KIAltZW51cyA9IG51bGw7CiAJc3VwZXIucmVsZWFzZVdpZGdldCAoKTsKIAlkZWZhdWx0QnV0dG9uID0gc2F2ZURlZmF1bHQgPSBudWxsOwotCWxhYmVsID0gbnVsbDsKLX0KLXZvaWQgcmVtb3ZlIChNZW51IG1lbnUpIHsKLQlpZiAobWVudXMgPT0gbnVsbCkgcmV0dXJuOwotCWZvciAoaW50IGk9MDsgaTxtZW51cy5sZW5ndGg7IGkrKykgewotCQlpZiAobWVudXMgW2ldID09IG1lbnUpIHsKLQkJCW1lbnVzIFtpXSA9IG51bGw7Ci0JCQlyZXR1cm47Ci0JCX0KLQl9Ci19Ci12b2lkIHJlbW92ZSAoTWVudUl0ZW0gaXRlbSkgewotCWlmIChpdGVtcyA9PSBudWxsKSByZXR1cm47Ci0JaXRlbXMgW2l0ZW0uaWQgLSBGSVJTVF9NRU5VX0lURU1fSURdID0gbnVsbDsKLQlpdGVtLmlkID0gLTE7CiB9CiAKIGJvb2xlYW4gcmVzdG9yZUZvY3VzICgpIHsKQEAgLTQyMywzMyArMTI3LDE2IEBACiB9CiAKIHZvaWQgc2F2ZUZvY3VzICgpIHsKLQlDb250cm9sIGNvbnRyb2wgPSBnZXREaXNwbGF5ICgpLmdldEZvY3VzQ29udHJvbCAoKTsKLQlpZiAoY29udHJvbCAhPSBudWxsKSBzZXRTYXZlZEZvY3VzIChjb250cm9sKTsKKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChoYW5kbGUpOworCUNvbnRyb2wgY29udHJvbCA9IGdldERpc3BsYXkgKCkuZ2V0Rm9jdXNDb250cm9sICh3aW5kb3cpOworCWlmIChjb250cm9sICE9IG51bGwpIHNhdmVkRm9jdXMgPSBjb250cm9sOwogfQotLyoqCi0gKiBJZiB0aGUgYXJndW1lbnQgaXMgbm90IG51bGwsIHNldHMgdGhlIHJlY2VpdmVyJ3MgZGVmYXVsdAotICogYnV0dG9uIHRvIHRoZSBhcmd1bWVudCwgYW5kIGlmIHRoZSBhcmd1bWVudCBpcyBudWxsLCBzZXRzCi0gKiB0aGUgcmVjZWl2ZXIncyBkZWZhdWx0IGJ1dHRvbiB0byB0aGUgZmlyc3QgYnV0dG9uIHdoaWNoCi0gKiB3YXMgc2V0IGFzIHRoZSByZWNlaXZlcidzIGRlZmF1bHQgYnV0dG9uIChjYWxsZWQgdGhlIAotICogPGVtPnNhdmVkIGRlZmF1bHQgYnV0dG9uPC9lbT4pLiBJZiBubyBkZWZhdWx0IGJ1dHRvbiBoYWQKLSAqIHByZXZpb3VzbHkgYmVlbiBzZXQsIG9yIHRoZSBzYXZlZCBkZWZhdWx0IGJ1dHRvbiB3YXMKLSAqIGRpc3Bvc2VkLCB0aGUgcmVjZWl2ZXIncyBkZWZhdWx0IGJ1dHRvbiB3aWxsIGJlIHNldCB0bwotICogbnVsbC4gCi0gKgotICogQHBhcmFtIHRoZSBuZXcgZGVmYXVsdCBidXR0b24KLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9BUkdVTUVOVCAtIGlmIHRoZSBidXR0b24gaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPiAKLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0RGVmYXVsdEJ1dHRvbiAoQnV0dG9uIGJ1dHRvbikgewogCWNoZWNrV2lkZ2V0KCk7CiAJc2V0RGVmYXVsdEJ1dHRvbiAoYnV0dG9uLCB0cnVlKTsKIH0KKwogdm9pZCBzZXREZWZhdWx0QnV0dG9uIChCdXR0b24gYnV0dG9uLCBib29sZWFuIHNhdmUpIHsKIAlpZiAoYnV0dG9uID09IG51bGwpIHsKIAkJaWYgKGRlZmF1bHRCdXR0b24gPT0gc2F2ZURlZmF1bHQpIHsKQEAgLTQ3MSw5NiArMTU4LDIwIEBACiAJaWYgKHNhdmUgfHwgc2F2ZURlZmF1bHQgPT0gbnVsbCkgc2F2ZURlZmF1bHQgPSBkZWZhdWx0QnV0dG9uOwogCWlmIChzYXZlRGVmYXVsdCAhPSBudWxsICYmIHNhdmVEZWZhdWx0LmlzRGlzcG9zZWQgKCkpIHNhdmVEZWZhdWx0ID0gbnVsbDsKIH0KLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBpbWFnZSB0byB0aGUgYXJndW1lbnQsIHdoaWNoIG1heQotICogYmUgbnVsbC4gVGhlIGltYWdlIGlzIHR5cGljYWxseSBkaXNwbGF5ZWQgYnkgdGhlIHdpbmRvdwotICogbWFuYWdlciB3aGVuIHRoZSBpbnN0YW5jZSBpcyBtYXJrZWQgYXMgaWNvbmlmaWVkLCBhbmQKLSAqIG1heSBhbHNvIGJlIGRpc3BsYXllZCBzb21ld2hlcmUgaW4gdGhlIHRyaW0gd2hlbiB0aGUKLSAqIGluc3RhbmNlIGlzIGluIG5vcm1hbCBvciBtYXhpbWl6ZWQgc3RhdGVzLgotICogCi0gKiBAcGFyYW0gaW1hZ2UgdGhlIG5ldyBpbWFnZSAob3IgbnVsbCkKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9BUkdVTUVOVCAtIGlmIHRoZSBpbWFnZSBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+IAotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRJbWFnZSAoSW1hZ2UgaW1hZ2UpIHsKIAljaGVja1dpZGdldCgpOwotCS8qIEFXCi0JaW50IHBpeG1hcCA9IDAsIG1hc2sgPSAwOwotCSovCiAJaWYgKGltYWdlICE9IG51bGwpIHsKIAkJaWYgKGltYWdlLmlzRGlzcG9zZWQoKSkgZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwotICAgICAgICAvKiBBVwotCQlzd2l0Y2ggKGltYWdlLnR5cGUpIHsKLQkJCWNhc2UgU1dULkJJVE1BUDoKLQkJCQlwaXhtYXAgPSBpbWFnZS5waXhtYXA7Ci0JCQkJYnJlYWs7Ci0JCQljYXNlIFNXVC5JQ09OOgotCQkJCXBpeG1hcCA9IGltYWdlLnBpeG1hcDsKLQkJCQltYXNrID0gaW1hZ2UubWFzazsKLQkJCQlicmVhazsKLQkJCWRlZmF1bHQ6Ci0JCQkJZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX0lNQUdFKTsKLQkJfQotICAgICAgICAqLwogCX0KIAl0aGlzLmltYWdlID0gaW1hZ2U7Ci0gICAgLyogQVcKLQlpbnQgW10gYXJnTGlzdCA9IHsKLQkJT1MuWG1OaWNvblBpeG1hcCwgcGl4bWFwLAotCQlPUy5YbU5pY29uTWFzaywgbWFzaywKLQl9OwotCWludCB0b3BIYW5kbGUgPSB0b3BIYW5kbGUgKCk7Ci0JT1MuWHRTZXRWYWx1ZXMgKHRvcEhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLSAgICAqLwogfQotLyoqCi0gKiBTZXRzIHRoZSBtYXhpbWl6ZWQgc3RhdGUgb2YgdGhlIHJlY2VpdmVyLgotICogSWYgdGhlIGFyZ3VtZW50IGlzIDxjb2RlPnRydWU8L2NvZGU+IGNhdXNlcyB0aGUgcmVjZWl2ZXIKLSAqIHRvIHN3aXRjaCB0byB0aGUgbWF4aW1pemVkIHN0YXRlLCBhbmQgaWYgdGhlIGFyZ3VtZW50IGlzCi0gKiA8Y29kZT5mYWxzZTwvY29kZT4gYW5kIHRoZSByZWNlaXZlciB3YXMgcHJldmlvdXNseSBtYXhpbWl6ZWQsCi0gKiBjYXVzZXMgdGhlIHJlY2VpdmVyIHRvIHN3aXRjaCBiYWNrIHRvIGVpdGhlciB0aGUgbWluaW1pemVkCi0gKiBvciBub3JtYWwgc3RhdGVzLgotICogPHA+Ci0gKiBOb3RlOiBUaGUgcmVzdWx0IG9mIGludGVybWl4aW5nIGNhbGxzIHRvPGNvZGU+c2V0TWF4aW1pemVkKHRydWUpPC9jb2RlPgotICogYW5kIDxjb2RlPnNldE1pbmltaXplZCh0cnVlKTwvY29kZT4gd2lsbCB2YXJ5IGJ5IHBsYXRmb3JtLiBUeXBpY2FsbHksCi0gKiB0aGUgYmVoYXZpb3Igd2lsbCBtYXRjaCB0aGUgcGxhdGZvcm0gdXNlcidzIGV4cGVjdGF0aW9ucywgYnV0IG5vdAotICogYWx3YXlzLiBUaGlzIHNob3VsZCBiZSBhdm9pZGVkIGlmIHBvc3NpYmxlLgotICogPC9wPgotICoKLSAqIEBwYXJhbSB0aGUgbmV3IG1heGltaXplZCBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNzZXRNaW5pbWl6ZWQKLSAqLworCiBwdWJsaWMgdm9pZCBzZXRNYXhpbWl6ZWQgKGJvb2xlYW4gbWF4aW1pemVkKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAl0aGlzLm1heGltaXplZCA9IG1heGltaXplZDsKIH0KLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBtZW51IGJhciB0byB0aGUgYXJndW1lbnQsIHdoaWNoCi0gKiBtYXkgYmUgbnVsbC4KLSAqCi0gKiBAcGFyYW0gbWVudSB0aGUgbmV3IG1lbnUgYmFyCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfQVJHVU1FTlQgLSBpZiB0aGUgbWVudSBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+IAotICogICAgPGxpPkVSUk9SX0lOVkFMSURfUEFSRU5UIC0gaWYgdGhlIG1lbnUgaXMgbm90IGluIHRoZSBzYW1lIHdpZGdldCB0cmVlPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0TWVudUJhciAoTWVudSBtZW51KSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobWVudUJhciA9PSBtZW51KSByZXR1cm47CkBAIC01NjksMTE3ICsxODAsMjAgQEAKIAkJaWYgKChtZW51LnN0eWxlICYgU1dULkJBUikgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9NRU5VX05PVF9CQVIpOwogCQlpZiAobWVudS5wYXJlbnQgIT0gdGhpcykgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1BBUkVOVCk7CiAJfQotCi0JLyogRW5zdXJlIHRoZSBuZXcgbWVudSBiYXIgaXMgY29ycmVjdGx5IGVuYWJsZWQgKi8KLQlpZiAobWVudUJhciAhPSBudWxsKSB7Ci0JCWlmICghaXNFbmFibGVkICgpICYmIG1lbnVCYXIuZ2V0RW5hYmxlZCAoKSkgewotCQkJcHJvcGFnYXRlSGFuZGxlICh0cnVlLCBtZW51QmFyLmhhbmRsZSk7Ci0JCX0KLQl9Ci0JaWYgKG1lbnUgIT0gbnVsbCkgewotCQlpZiAoIWlzRW5hYmxlZCAoKSkgewotCQkJcHJvcGFnYXRlSGFuZGxlIChmYWxzZSwgbWVudS5oYW5kbGUpOwotCQl9Ci0JfQotCi0JLyoKLQkqIEJ1ZyBpbiBNb3RpZi4gIFdoZW4gYSBYbU1haW5XaW5kb3dTZXRBcmVhcyAoKSBpcyB1c2VkCi0JKiB0byByZXBsYWNlIGFuIGV4aXN0aW5nIG1lbnUsIGJvdGggbWVudXMgbXVzdCBiZSBtYW5hZ2VkCi0JKiBiZWZvcmUgdGhlIGNhbGwgdG8gWG1NYWluV2luZG93U2V0QXJlYXMgKCkgb3IgdGhlIG5ldwotCSogbWVudSB3aWxsIG5vdCBiZSBsYXllZCBvdXQgcHJvcGVybHkuCi0JKi8KLQkvKiBBVwotCWludCBuZXdIYW5kbGUgPSAobWVudSAhPSBudWxsKSA/IG1lbnUuaGFuZGxlIDogMDsKLQlpbnQgb2xkSGFuZGxlID0gKG1lbnVCYXIgIT0gbnVsbCkgPyBtZW51QmFyLmhhbmRsZSA6IDA7Ci0JKi8KIAltZW51QmFyID0gbWVudTsKLSAgICAvKiBBVwotCWludCBoSGFuZGxlID0gKGhvcml6b250YWxCYXIgIT0gbnVsbCkgPyBob3Jpem9udGFsQmFyLmhhbmRsZSA6IDA7Ci0JaW50IHZIYW5kbGUgPSAodmVydGljYWxCYXIgIT0gbnVsbCkgPyB2ZXJ0aWNhbEJhci5oYW5kbGUgOiAwOwotCWlmIChuZXdIYW5kbGUgIT0gMCkgewotCQlPUy5YdFNldE1hcHBlZFdoZW5NYW5hZ2VkIChuZXdIYW5kbGUsIGZhbHNlKTsKLQkJT1MuWHRNYW5hZ2VDaGlsZCAobmV3SGFuZGxlKTsKLQl9Ci0JaW50IGNsaWVudEhhbmRsZSA9IChmb3JtSGFuZGxlICE9IDApID8gZm9ybUhhbmRsZSA6IGhhbmRsZTsKLQlPUy5YbU1haW5XaW5kb3dTZXRBcmVhcyAoc2Nyb2xsZWRIYW5kbGUsIG5ld0hhbmRsZSwgMCwgaEhhbmRsZSwgdkhhbmRsZSwgY2xpZW50SGFuZGxlKTsKLQlpZiAob2xkSGFuZGxlICE9IDApIE9TLlh0VW5tYW5hZ2VDaGlsZCAob2xkSGFuZGxlKTsKLQlpZiAobmV3SGFuZGxlICE9IDApIHsKLQkJT1MuWHRTZXRNYXBwZWRXaGVuTWFuYWdlZCAobmV3SGFuZGxlLCB0cnVlKTsKLQl9Ci0gICAgKi8KLQkvKgotCSogQnVnIGluIE1vdGlmLiAgV2hlbiBhIG1lbnUgYmFyIGlzIHJlbW92ZWQgYWZ0ZXIgdGhlCi0JKiBtYWluIHdpbmRvdyBoYXMgYmVlbiByZWFsaXplZCwgdGhlIG1haW4gd2luZG93IGRvZXMKLQkqIG5vdCBsYXlvdXQgdGhlIG5ldyBtZW51IGJhciBvciB0aGUgd29yayB3aW5kb3cuCi0JKiBUaGUgZml4IGlzIHRvIGZvcmNlIGEgbGF5b3V0IGJ5IHRlbXBvcmFyaWx5IHJlc2l6aW5nCi0JKiB0aGUgbWFpbiB3aW5kb3cuCi0JKi8KLSAgICAvKiBBVwotCWlmIChuZXdIYW5kbGUgPT0gMCAmJiBPUy5YdElzUmVhbGl6ZWQgKHNjcm9sbGVkSGFuZGxlKSkgewotCQlpbnQgW10gYXJnTGlzdCA9IHtPUy5YbU53aWR0aCwgMCwgT1MuWG1OaGVpZ2h0LCAwLCBPUy5YbU5ib3JkZXJXaWR0aCwgMH07Ci0JCU9TLlh0R2V0VmFsdWVzIChzY3JvbGxlZEhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQkJT1MuWHRSZXNpemVXaWRnZXQgKHNjcm9sbGVkSGFuZGxlLCBhcmdMaXN0IFsxXSArIDEsIGFyZ0xpc3QgWzNdLCBhcmdMaXN0IFs1XSk7Ci0JCU9TLlh0UmVzaXplV2lkZ2V0IChzY3JvbGxlZEhhbmRsZSwgYXJnTGlzdCBbMV0sIGFyZ0xpc3QgWzNdLCBhcmdMaXN0IFs1XSk7Ci0JfQotICAgICovCisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlkaXNwbGF5LnVwZGF0ZU1lbnVCYXIgKCk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIG1pbmltaXplZCBzdGF0ZWQgb2YgdGhlIHJlY2VpdmVyLgotICogSWYgdGhlIGFyZ3VtZW50IGlzIDxjb2RlPnRydWU8L2NvZGU+IGNhdXNlcyB0aGUgcmVjZWl2ZXIKLSAqIHRvIHN3aXRjaCB0byB0aGUgbWluaW1pemVkIHN0YXRlLCBhbmQgaWYgdGhlIGFyZ3VtZW50IGlzCi0gKiA8Y29kZT5mYWxzZTwvY29kZT4gYW5kIHRoZSByZWNlaXZlciB3YXMgcHJldmlvdXNseSBtaW5pbWl6ZWQsCi0gKiBjYXVzZXMgdGhlIHJlY2VpdmVyIHRvIHN3aXRjaCBiYWNrIHRvIGVpdGhlciB0aGUgbWF4aW1pemVkCi0gKiBvciBub3JtYWwgc3RhdGVzLgotICogPHA+Ci0gKiBOb3RlOiBUaGUgcmVzdWx0IG9mIGludGVybWl4aW5nIGNhbGxzIHRvPGNvZGU+c2V0TWF4aW1pemVkKHRydWUpPC9jb2RlPgotICogYW5kIDxjb2RlPnNldE1pbmltaXplZCh0cnVlKTwvY29kZT4gd2lsbCB2YXJ5IGJ5IHBsYXRmb3JtLiBUeXBpY2FsbHksCi0gKiB0aGUgYmVoYXZpb3Igd2lsbCBtYXRjaCB0aGUgcGxhdGZvcm0gdXNlcidzIGV4cGVjdGF0aW9ucywgYnV0IG5vdAotICogYWx3YXlzLiBUaGlzIHNob3VsZCBiZSBhdm9pZGVkIGlmIHBvc3NpYmxlLgotICogPC9wPgotICoKLSAqIEBwYXJhbSB0aGUgbmV3IG1heGltaXplZCBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNzZXRNYXhpbWl6ZWQKLSAqLworCiBwdWJsaWMgdm9pZCBzZXRNaW5pbWl6ZWQgKGJvb2xlYW4gbWluaW1pemVkKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAl0aGlzLm1pbmltaXplZCA9IG1pbmltaXplZDsKIH0KLXZvaWQgc2V0U2F2ZWRGb2N1cyAoQ29udHJvbCBjb250cm9sKSB7Ci0JaWYgKHRoaXMgPT0gY29udHJvbCkgcmV0dXJuOwotCXNhdmVkRm9jdXMgPSBjb250cm9sOwotfQotLyoqCi0gKiBTZXRzIHRoZSByZWNlaXZlcidzIHRleHQsIHdoaWNoIGlzIHRoZSBzdHJpbmcgdGhhdCB0aGUKLSAqIHdpbmRvdyBtYW5hZ2VyIHdpbGwgdHlwaWNhbGx5IGRpc3BsYXkgYXMgdGhlIHJlY2VpdmVyJ3MKLSAqIDxlbT50aXRsZTwvZW0+LCB0byB0aGUgYXJndW1lbnQsIHdoaWNoIG1heSBub3QgYmUgbnVsbC4gCi0gKgotICogQHBhcmFtIHRleHQgdGhlIG5ldyB0ZXh0Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldFRleHQgKFN0cmluZyBzdHJpbmcpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChzdHJpbmcgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQlsYWJlbCA9IHN0cmluZzsKKwl0ZXh0ID0gc3RyaW5nOwogfQotcHVibGljIHZvaWQgc2V0VmlzaWJsZSAoYm9vbGVhbiB2aXNpYmxlKSB7Ci0Jc3VwZXIuc2V0VmlzaWJsZSAodmlzaWJsZSk7Ci0JaWYgKCF2aXNpYmxlKSByZXR1cm47Ci0JaWYgKHNhdmVkRm9jdXMgIT0gbnVsbCAmJiAhc2F2ZWRGb2N1cy5pc0Rpc3Bvc2VkICgpKSB7Ci0JCXNhdmVkRm9jdXMuc2V0Rm9jdXMgKCk7Ci0JfQotCXNhdmVkRm9jdXMgPSBudWxsOwotfQorCiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvRGlyZWN0b3J5RGlhbG9nLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvRGlyZWN0b3J5RGlhbG9nLmphdmEKaW5kZXggZjMwMWI5Ni4uNzJlNTVmYSAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0RpcmVjdG9yeURpYWxvZy5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9EaXJlY3RvcnlEaWFsb2cuamF2YQpAQCAtMTAsMTgyICsxMCw5NyBAQAogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKIAotLyoqCi0gKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBhbGxvdyB0aGUgdXNlciB0byBuYXZpZ2F0ZQotICogdGhlIGZpbGUgc3lzdGVtIGFuZCBzZWxlY3QgYSBkaXJlY3RvcnkuCi0gKiA8cD4KLSAqIElNUE9SVEFOVDogVGhpcyBjbGFzcyBpcyBpbnRlbmRlZCB0byBiZSBzdWJjbGFzc2VkIDxlbT5vbmx5PC9lbT4KLSAqIHdpdGhpbiB0aGUgU1dUIGltcGxlbWVudGF0aW9uLgotICogPC9wPgotICovCisKIHB1YmxpYyBjbGFzcyBEaXJlY3RvcnlEaWFsb2cgZXh0ZW5kcyBEaWFsb2cgewotCVN0cmluZyBmaWx0ZXJQYXRoID0gIiI7Ci0JU3RyaW5nIG1lc3NhZ2UgPSAiIjsKLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIG9ubHkgaXRzCi0gKiBwYXJlbnQuCi0gKiA8cD4KLSAqIE5vdGU6IEN1cnJlbnRseSwgbnVsbCBjYW4gYmUgcGFzc2VkIGluIGZvciB0aGUgcGFyZW50LgotICogVGhpcyBoYXMgdGhlIGVmZmVjdCBvZiBjcmVhdGluZyB0aGUgZGlhbG9nIG9uIHRoZSBjdXJyZW50bHkgYWN0aXZlCi0gKiBkaXNwbGF5IGlmIHRoZXJlIGlzIG9uZS4gSWYgdGhlcmUgaXMgbm8gY3VycmVudCBkaXNwbGF5LCB0aGUgCi0gKiBkaWFsb2cgaXMgY3JlYXRlZCBvbiBhICJkZWZhdWx0IiBkaXNwbGF5LiA8Yj5QYXNzaW5nIGluIG51bGwgYXMKLSAqIHRoZSBwYXJlbnQgaXMgbm90IGNvbnNpZGVyZWQgdG8gYmUgZ29vZCBjb2Rpbmcgc3R5bGUsCi0gKiBhbmQgbWF5IG5vdCBiZSBzdXBwb3J0ZWQgaW4gYSBmdXR1cmUgcmVsZWFzZSBvZiBTV1QuPC9iPgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBzaGVsbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwlTdHJpbmcgbWVzc2FnZSA9ICIiLCBmaWx0ZXJQYXRoID0gIiI7CisKIHB1YmxpYyBEaXJlY3RvcnlEaWFsb2cgKFNoZWxsIHBhcmVudCkgewotCXRoaXMgKHBhcmVudCwgU1dULlBSSU1BUllfTU9EQUwpOworCXRoaXMgKHBhcmVudCwgU1dULkFQUExJQ0FUSU9OX01PREFMKTsKIH0KLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIGl0cyBwYXJlbnQKLSAqIGFuZCBhIHN0eWxlIHZhbHVlIGRlc2NyaWJpbmcgaXRzIGJlaGF2aW9yIGFuZCBhcHBlYXJhbmNlLgotICogPHA+Ci0gKiBUaGUgc3R5bGUgdmFsdWUgaXMgZWl0aGVyIG9uZSBvZiB0aGUgc3R5bGUgY29uc3RhbnRzIGRlZmluZWQgaW4KLSAqIGNsYXNzIDxjb2RlPlNXVDwvY29kZT4gd2hpY2ggaXMgYXBwbGljYWJsZSB0byBpbnN0YW5jZXMgb2YgdGhpcwotICogY2xhc3MsIG9yIG11c3QgYmUgYnVpbHQgYnkgPGVtPmJpdHdpc2UgT1I8L2VtPidpbmcgdG9nZXRoZXIgCi0gKiAodGhhdCBpcywgdXNpbmcgdGhlIDxjb2RlPmludDwvY29kZT4gInwiIG9wZXJhdG9yKSB0d28gb3IgbW9yZQotICogb2YgdGhvc2UgPGNvZGU+U1dUPC9jb2RlPiBzdHlsZSBjb25zdGFudHMuIFRoZSBjbGFzcyBkZXNjcmlwdGlvbgotICogbGlzdHMgdGhlIHN0eWxlIGNvbnN0YW50cyB0aGF0IGFyZSBhcHBsaWNhYmxlIHRvIHRoZSBjbGFzcy4KLSAqIFN0eWxlIGJpdHMgYXJlIGFsc28gaW5oZXJpdGVkIGZyb20gc3VwZXJjbGFzc2VzLgotICogPC9wPgotICogTm90ZTogQ3VycmVudGx5LCBudWxsIGNhbiBiZSBwYXNzZWQgaW4gZm9yIHRoZSBwYXJlbnQuCi0gKiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGNyZWF0aW5nIHRoZSBkaWFsb2cgb24gdGhlIGN1cnJlbnRseSBhY3RpdmUKLSAqIGRpc3BsYXkgaWYgdGhlcmUgaXMgb25lLiBJZiB0aGVyZSBpcyBubyBjdXJyZW50IGRpc3BsYXksIHRoZSAKLSAqIGRpYWxvZyBpcyBjcmVhdGVkIG9uIGEgImRlZmF1bHQiIGRpc3BsYXkuIDxiPlBhc3NpbmcgaW4gbnVsbCBhcwotICogdGhlIHBhcmVudCBpcyBub3QgY29uc2lkZXJlZCB0byBiZSBnb29kIGNvZGluZyBzdHlsZSwKLSAqIGFuZCBtYXkgbm90IGJlIHN1cHBvcnRlZCBpbiBhIGZ1dHVyZSByZWxlYXNlIG9mIFNXVC48L2I+Ci0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIHNoZWxsIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcGFyZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHBhcmVudDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgRGlyZWN0b3J5RGlhbG9nIChTaGVsbCBwYXJlbnQsIGludCBzdHlsZSkgewogCXN1cGVyIChwYXJlbnQsIHN0eWxlKTsKIAljaGVja1N1YmNsYXNzICgpOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBwYXRoIHdoaWNoIHRoZSBkaWFsb2cgd2lsbCB1c2UgdG8gZmlsdGVyCi0gKiB0aGUgZGlyZWN0b3JpZXMgaXQgc2hvd3MuCi0gKgotICogQHJldHVybiB0aGUgZmlsdGVyIHBhdGgKLSAqLworCiBwdWJsaWMgU3RyaW5nIGdldEZpbHRlclBhdGggKCkgewogCXJldHVybiBmaWx0ZXJQYXRoOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBkaWFsb2cncyBtZXNzYWdlLCB3aGljaCBpcyBhIGRlc2NyaXB0aW9uIG9mCi0gKiB0aGUgcHVycG9zZSBmb3Igd2hpY2ggaXQgd2FzIG9wZW5lZC4gVGhpcyBtZXNzYWdlIHdpbGwgYmUKLSAqIHZpc2libGUgb24gdGhlIGRpYWxvZyB3aGlsZSBpdCBpcyBvcGVuLgotICoKLSAqIEByZXR1cm4gdGhlIG1lc3NhZ2UKLSAqLworCiBwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UgKCkgewogCXJldHVybiBtZXNzYWdlOwogfQotcHJpdmF0ZSBTdHJpbmcgaW50ZXJwcmV0T3NBbnN3ZXIoaW50IGRpYWxvZykgewotCWludFtdIHRtcD0gbmV3IGludFsxXTsKLQlPUy5OYXZEaWFsb2dHZXRSZXBseShkaWFsb2csIHRtcCk7Ci0JaW50IHJlcGx5PSB0bXBbMF07Ci0JCi0JaW50IHNlbGVjdGlvbj0gT1MuTmF2UmVwbHlSZWNvcmRHZXRTZWxlY3Rpb24ocmVwbHkpOwotCU9TLkFFQ291bnRJdGVtcyhzZWxlY3Rpb24sIHRtcCk7Ci0JaW50IGNvdW50PSB0bXBbMF07Ci0JCi0JaWYgKGNvdW50ID4gMCkgewotCQlPUy5BRUdldE50aFB0cihzZWxlY3Rpb24sIDEsIHRtcCk7Ci0JCXJldHVybiBNYWNVdGlsLmdldFN0cmluZ0FuZFJlbGVhc2UodG1wWzBdKTsKLQl9Ci0JcmV0dXJuIG51bGw7Ci19Ci0vKioKLSAqIE1ha2VzIHRoZSBkaWFsb2cgdmlzaWJsZSBhbmQgYnJpbmdzIGl0IHRvIHRoZSBmcm9udAotICogb2YgdGhlIGRpc3BsYXkuCi0gKgotICogQHJldHVybiBhIHN0cmluZyBkZXNjcmliaW5nIHRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBzZWxlY3RlZCBkaXJlY3RvcnksCi0gKiAgICAgICAgIG9yIG51bGwgaWYgdGhlIGRpYWxvZyB3YXMgY2FuY2VsbGVkIG9yIGFuIGVycm9yIG9jY3VycmVkCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSBkaWFsb2cgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgZGlhbG9nPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIFN0cmluZyBvcGVuICgpIHsKLQlpbnQgZGlhbG9nPSAwOwotCWludCB0aXRsZUhhbmRsZT0gMDsKLQlpbnQgbWVzc2FnZUhhbmRsZT0gMDsKLQl0cnkgewotCQlpbnRbXSBkaWFsb2dIYW5kbGU9IG5ldyBpbnRbMV07Ci0JCQotCQlpbnQgcGFyZW50V2luZG93SGFuZGxlPSAwOwotCQlpZiAocGFyZW50ICE9IG51bGwpCi0JCQlwYXJlbnRXaW5kb3dIYW5kbGU9IHBhcmVudC5zaGVsbEhhbmRsZTsKLQkJCQotCQl0aXRsZUhhbmRsZT0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyh0aXRsZSk7Ci0JCW1lc3NhZ2VIYW5kbGU9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMobWVzc2FnZSk7Ci0JCQotCQlpbnQgZmxhZ3M9IDA7Ci0JCU9TLk5hdkNyZWF0ZUNob29zZUZvbGRlckRpYWxvZyhmbGFncywgdGl0bGVIYW5kbGUsIG1lc3NhZ2VIYW5kbGUsIHBhcmVudFdpbmRvd0hhbmRsZSwgZGlhbG9nSGFuZGxlKTsKLQkJZGlhbG9nPSBkaWFsb2dIYW5kbGVbMF07Ci0JCQotCQlpZiAoZGlhbG9nICE9IDApIHsKLQkJCQkJCi0JCQlPUy5OYXZEaWFsb2dSdW4oZGlhbG9nKTsKLQkJCi0JCQlzd2l0Y2ggKE9TLk5hdkRpYWxvZ0dldFVzZXJBY3Rpb24oZGlhbG9nKSkgewotCQkJY2FzZSBPUy5rTmF2VXNlckFjdGlvbkNhbmNlbDoKLQkJCQlicmVhazsKLQkJCQkKLQkJCWNhc2UgT1Mua05hdlVzZXJBY3Rpb25PcGVuOgotCQkJY2FzZSBPUy5rTmF2VXNlckFjdGlvbkNob29zZToJCQkKLQkJCQlyZXR1cm4gaW50ZXJwcmV0T3NBbnN3ZXIoZGlhbG9nKTsKKwlTdHJpbmcgZGlyZWN0b3J5UGF0aCA9IG51bGw7CQorCWludCB0aXRsZVB0ciA9IDA7CisJaW50IG1lc3NhZ2VQdHIgPSAwOworCWlmICh0aXRsZSAhPSBudWxsKSB7CisJCWNoYXIgW10gYnVmZmVyID0gbmV3IGNoYXIgW3RpdGxlLmxlbmd0aCAoKV07CisJCXRpdGxlLmdldENoYXJzICgwLCBidWZmZXIubGVuZ3RoLCBidWZmZXIsIDApOworCQl0aXRsZVB0ciA9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMgKE9TLmtDRkFsbG9jYXRvckRlZmF1bHQsIGJ1ZmZlciwgYnVmZmVyLmxlbmd0aCk7CisJfQorCWlmIChtZXNzYWdlICE9IG51bGwpIHsKKwkJY2hhciBbXSBidWZmZXIgPSBuZXcgY2hhciBbbWVzc2FnZS5sZW5ndGggKCldOworCQltZXNzYWdlLmdldENoYXJzICgwLCBidWZmZXIubGVuZ3RoLCBidWZmZXIsIDApOworCQltZXNzYWdlUHRyID0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgYnVmZmVyLCBidWZmZXIubGVuZ3RoKTsKKwl9CisKKwlOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnMgb3B0aW9ucyA9IG5ldyBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnMgKCk7CisJb3B0aW9ucy5wYXJlbnRXaW5kb3cgPSBPUy5HZXRDb250cm9sT3duZXIgKHBhcmVudC5oYW5kbGUpOworCS8vIE5FRURTIFdPUksgLSBubyB0aXRsZSBkaXNwbGF5ZWQKKwlvcHRpb25zLndpbmRvd1RpdGxlID0gb3B0aW9ucy5jbGllbnROYW1lID0gdGl0bGVQdHI7CisJb3B0aW9ucy5vcHRpb25GbGFncyA9IE9TLmtOYXZTdXBwb3J0UGFja2FnZXMgfCBPUy5rTmF2QWxsb3dPcGVuUGFja2FnZXMgfCBPUy5rTmF2QWxsb3dJbnZpc2libGVGaWxlczsKKwlvcHRpb25zLm1lc3NhZ2UgPSBtZXNzYWdlUHRyOworCW9wdGlvbnMubG9jYXRpb25faCA9IC0xOworCW9wdGlvbnMubG9jYXRpb25fdiA9IC0xOworCWludCBbXSBvdXREaWFsb2cgPSBuZXcgaW50IFsxXTsKKwkvLyBORUVEUyBXT1JLIC0gdXNlIGluRmlsdGVyUHJvYyB0byBoYW5kbGUgZmlsdGVyaW5nCisJaWYgKE9TLk5hdkNyZWF0ZUNob29zZUZvbGRlckRpYWxvZyAob3B0aW9ucywgMCwgMCwgMCwgb3V0RGlhbG9nKSA9PSBPUy5ub0VycikgeworCQlPUy5OYXZEaWFsb2dSdW4gKG91dERpYWxvZyBbMF0pOworCQlpZiAoT1MuTmF2RGlhbG9nR2V0VXNlckFjdGlvbiAob3V0RGlhbG9nIFswXSkgPT0gT1Mua05hdlVzZXJBY3Rpb25DaG9vc2UpIHsKKwkJCU5hdlJlcGx5UmVjb3JkIHJlY29yZCA9IG5ldyBOYXZSZXBseVJlY29yZCAoKTsKKwkJCU9TLk5hdkRpYWxvZ0dldFJlcGx5IChvdXREaWFsb2cgWzBdLCByZWNvcmQpOworCQkJQUVEZXNjIHNlbGVjdGlvbiA9IG5ldyBBRURlc2MgKCk7CisJCQlzZWxlY3Rpb24uZGVzY3JpcHRvclR5cGUgPSByZWNvcmQuc2VsZWN0aW9uX2Rlc2NyaXB0b3JUeXBlOworCQkJc2VsZWN0aW9uLmRhdGFIYW5kbGUgPSByZWNvcmQuc2VsZWN0aW9uX2RhdGFIYW5kbGU7CisJCQlpbnQgW10gY291bnQgPSBuZXcgaW50IFsxXTsKKwkJCU9TLkFFQ291bnRJdGVtcyAoc2VsZWN0aW9uLCBjb3VudCk7CisJCQlpZiAoY291bnQgWzBdID4gMCkgeworCQkJCWludCBbXSB0aGVBRUtleXdvcmQgPSBuZXcgaW50IFsxXTsKKwkJCQlpbnQgW10gdHlwZUNvZGUgPSBuZXcgaW50IFsxXTsKKwkJCQlpbnQgbWF4aW11bVNpemUgPSA4MDsgLy8gc2l6ZSBvZiBGU1JlZgorCQkJCWludCBkYXRhUHRyID0gT1MuTmV3UHRyIChtYXhpbXVtU2l6ZSk7CisJCQkJaW50IFtdIGFjdHVhbFNpemUgPSBuZXcgaW50IFsxXTsKKwkJCQlpbnQgc3RhdHVzID0gT1MuQUVHZXROdGhQdHIgKHNlbGVjdGlvbiwgMSwgT1MudHlwZUZTUmVmLCB0aGVBRUtleXdvcmQsIHR5cGVDb2RlLCBkYXRhUHRyLCBtYXhpbXVtU2l6ZSwgYWN0dWFsU2l6ZSk7CisJCQkJaWYgKHN0YXR1cyA9PSBPUy5ub0VyciAmJiB0eXBlQ29kZSBbMF0gPT0gT1MudHlwZUZTUmVmKSB7CisJCQkJCWJ5dGUgW10gZnNSZWYgPSBuZXcgYnl0ZSBbYWN0dWFsU2l6ZSBbMF1dOworCQkJCQlPUy5tZW1jcHkgKGZzUmVmLCBkYXRhUHRyLCBhY3R1YWxTaXplIFswXSk7CisJCQkJCWludCBkaXJVcmwgPSBPUy5DRlVSTENyZWF0ZUZyb21GU1JlZiAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgZnNSZWYpOworCQkJCQlpbnQgZGlyU3RyaW5nID0gT1MuQ0ZVUkxDb3B5RmlsZVN5c3RlbVBhdGgoZGlyVXJsLCBPUy5rQ0ZVUkxQT1NJWFBhdGhTdHlsZSk7CisJCQkJCU9TLkNGUmVsZWFzZSAoZGlyVXJsKTsJCQkJCQkKKwkJCQkJaW50IGxlbmd0aCA9IE9TLkNGU3RyaW5nR2V0TGVuZ3RoIChkaXJTdHJpbmcpOworCQkJCQljaGFyIFtdIGJ1ZmZlcj0gbmV3IGNoYXIgW2xlbmd0aF07CisJCQkJCUNGUmFuZ2UgcmFuZ2UgPSBuZXcgQ0ZSYW5nZSAoKTsKKwkJCQkJcmFuZ2UubGVuZ3RoID0gbGVuZ3RoOworCQkJCQlPUy5DRlN0cmluZ0dldENoYXJhY3RlcnMgKGRpclN0cmluZywgcmFuZ2UsIGJ1ZmZlcik7CisJCQkJCU9TLkNGUmVsZWFzZSAoZGlyU3RyaW5nKTsKKwkJCQkJZGlyZWN0b3J5UGF0aCA9IG5ldyBTdHJpbmcgKGJ1ZmZlcik7CisJCQkJfQorCQkJCU9TLkRpc3Bvc2VQdHIgKGRhdGFQdHIpOwogCQkJfQogCQl9Ci0JCQotCQlyZXR1cm4gbnVsbDsKLQotCX0gZmluYWxseSB7Ci0JCWlmICh0aXRsZUhhbmRsZSAhPSAwKQotCQkJT1MuQ0ZSZWxlYXNlKHRpdGxlSGFuZGxlKTsKLQkJaWYgKG1lc3NhZ2VIYW5kbGUgIT0gMCkKLQkJCU9TLkNGUmVsZWFzZShtZXNzYWdlSGFuZGxlKTsKLQkJaWYgKGRpYWxvZyAhPSAwKQotCQkJT1MuTmF2RGlhbG9nRGlzcG9zZShkaWFsb2cpOwogCX0KKwlpZiAodGl0bGVQdHIgIT0gMCkgT1MuQ0ZSZWxlYXNlICh0aXRsZVB0cik7CQorCWlmIChtZXNzYWdlUHRyICE9IDApIE9TLkNGUmVsZWFzZSAobWVzc2FnZVB0cik7CisJaWYgKG91dERpYWxvZyBbMF0gIT0gMCkgT1MuTmF2RGlhbG9nRGlzcG9zZSAob3V0RGlhbG9nIFswXSk7CisJcmV0dXJuIGRpcmVjdG9yeVBhdGg7CiB9Ci0vKioKLSAqIFNldHMgdGhlIGRpYWxvZydzIG1lc3NhZ2UsIHdoaWNoIGlzIGEgZGVzY3JpcHRpb24gb2YKLSAqIHRoZSBwdXJwb3NlIGZvciB3aGljaCBpdCB3YXMgb3BlbmVkLiBUaGlzIG1lc3NhZ2Ugd2lsbCBiZQotICogdmlzaWJsZSBvbiB0aGUgZGlhbG9nIHdoaWxlIGl0IGlzIG9wZW4uCi0gKgotICogQHBhcmFtIHN0cmluZyB0aGUgbWVzc2FnZQotICovCisKIHB1YmxpYyB2b2lkIHNldE1lc3NhZ2UgKFN0cmluZyBzdHJpbmcpIHsKIAltZXNzYWdlID0gc3RyaW5nOwogfQotLyoqCi0gKiBTZXRzIHRoZSBwYXRoIHdoaWNoIHRoZSBkaWFsb2cgd2lsbCB1c2UgdG8gZmlsdGVyCi0gKiB0aGUgZGlyZWN0b3JpZXMgaXQgc2hvd3MgdG8gdGhlIGFyZ3VtZW50LCB3aGljaCBtYXkgYmUKLSAqIG51bGwuCi0gKgotICogQHBhcmFtIHN0cmluZyB0aGUgZmlsdGVyIHBhdGgKLSAqLworCiBwdWJsaWMgdm9pZCBzZXRGaWx0ZXJQYXRoIChTdHJpbmcgc3RyaW5nKSB7CiAJZmlsdGVyUGF0aCA9IHN0cmluZzsKIH0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9EaXNwbGF5LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvRGlzcGxheS5qYXZhCmluZGV4IGE1ODA5MGUuLjdlZTk5ZGMgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9EaXNwbGF5LmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0Rpc3BsYXkuamF2YQpAQCAtNywxMjQgKzcsMzUgQEAKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAgKi8KIAotaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7Ci1pbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOworCitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkNHUG9pbnQ7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5DR1JlY3Q7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5SZWN0OworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uSElDb21tYW5kOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUkdCQ29sb3I7CiAKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuQ2FsbGJhY2s7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi4qOwogCi0vKioKLSAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGFyZSByZXNwb25zaWJsZSBmb3IgbWFuYWdpbmcgdGhlCi0gKiBjb25uZWN0aW9uIGJldHdlZW4gU1dUIGFuZCB0aGUgdW5kZXJseWluZyBvcGVyYXRpbmcKLSAqIHN5c3RlbS4gVGhlaXIgbW9zdCBpbXBvcnRhbnQgZnVuY3Rpb24gaXMgdG8gaW1wbGVtZW50Ci0gKiB0aGUgU1dUIGV2ZW50IGxvb3AgaW4gdGVybXMgb2YgdGhlIHBsYXRmb3JtIGV2ZW50IG1vZGVsLgotICogVGhleSBhbHNvIHByb3ZpZGUgdmFyaW91cyBtZXRob2RzIGZvciBhY2Nlc3NpbmcgaW5mb3JtYXRpb24KLSAqIGFib3V0IHRoZSBvcGVyYXRpbmcgc3lzdGVtLCBhbmQgaGF2ZSBvdmVyYWxsIGNvbnRyb2wgb3ZlcgotICogdGhlIG9wZXJhdGluZyBzeXN0ZW0gcmVzb3VyY2VzIHdoaWNoIFNXVCBhbGxvY2F0ZXMuCi0gKiA8cD4KLSAqIEFwcGxpY2F0aW9ucyB3aGljaCBhcmUgYnVpbHQgd2l0aCBTV1Qgd2lsbCA8ZW0+YWxtb3N0IGFsd2F5czwvZW0+Ci0gKiByZXF1aXJlIG9ubHkgYSBzaW5nbGUgZGlzcGxheS4gSW4gcGFydGljdWxhciwgc29tZSBwbGF0Zm9ybXMKLSAqIHdoaWNoIFNXVCBzdXBwb3J0cyB3aWxsIG5vdCBhbGxvdyBtb3JlIHRoYW4gb25lIDxlbT5hY3RpdmU8L2VtPgotICogZGlzcGxheS4gSW4gb3RoZXIgd29yZHMsIHNvbWUgcGxhdGZvcm1zIGRvIG5vdCBzdXBwb3J0Ci0gKiBjcmVhdGluZyBhIG5ldyBkaXNwbGF5IGlmIG9uZSBhbHJlYWR5IGV4aXN0cyB0aGF0IGhhcyBub3QgYmVlbgotICogc2VudCB0aGUgPGNvZGU+ZGlzcG9zZSgpPC9jb2RlPiBtZXNzYWdlLgotICogPHA+Ci0gKiBJbiBTV1QsIHRoZSB0aHJlYWQgd2hpY2ggY3JlYXRlcyBhIDxjb2RlPkRpc3BsYXk8L2NvZGU+Ci0gKiBpbnN0YW5jZSBpcyBkaXN0aW5ndWlzaGVkIGFzIHRoZSA8ZW0+dXNlci1pbnRlcmZhY2UgdGhyZWFkPC9lbT4KLSAqIGZvciB0aGF0IGRpc3BsYXkuCi0gKiA8L3A+Ci0gKiBUaGUgdXNlci1pbnRlcmZhY2UgdGhyZWFkIGZvciBhIHBhcnRpY3VsYXIgZGlzcGxheSBoYXMgdGhlCi0gKiBmb2xsb3dpbmcgc3BlY2lhbCBhdHRyaWJ1dGVzOgotICogPHVsPgotICogPGxpPgotICogVGhlIGV2ZW50IGxvb3AgZm9yIHRoYXQgZGlzcGxheSBtdXN0IGJlIHJ1biBmcm9tIHRoZSB0aHJlYWQuCi0gKiA8L2xpPgotICogPGxpPgotICogU29tZSBTV1QgQVBJIG1ldGhvZHMgKG5vdGFibHksIG1vc3Qgb2YgdGhlIHB1YmxpYyBtZXRob2RzIGluCi0gKiA8Y29kZT5XaWRnZXQ8L2NvZGU+IGFuZCBpdHMgc3ViY2xhc3NlcyksIG1heSBvbmx5IGJlIGNhbGxlZAotICogZnJvbSB0aGUgdGhyZWFkLiAoVG8gc3VwcG9ydCBtdWx0aS10aHJlYWRlZCB1c2VyLWludGVyZmFjZQotICogYXBwbGljYXRpb25zLCBjbGFzcyA8Y29kZT5EaXNwbGF5PC9jb2RlPiBwcm92aWRlcyBpbnRlci10aHJlYWQKLSAqIGNvbW11bmljYXRpb24gbWV0aG9kcyB3aGljaCBhbGxvdyB0aHJlYWRzIG90aGVyIHRoYW4gdGhlIAotICogdXNlci1pbnRlcmZhY2UgdGhyZWFkIHRvIHJlcXVlc3QgdGhhdCBpdCBwZXJmb3JtIG9wZXJhdGlvbnMKLSAqIG9uIHRoZWlyIGJlaGFsZi4pCi0gKiA8L2xpPgotICogPGxpPgotICogVGhlIHRocmVhZCBpcyBub3QgYWxsb3dlZCB0byBjb25zdHJ1Y3Qgb3RoZXIgCi0gKiA8Y29kZT5EaXNwbGF5PC9jb2RlPnMgdW50aWwgdGhhdCBkaXNwbGF5IGhhcyBiZWVuIGRpc3Bvc2VkLgotICogKE5vdGUgdGhhdCwgdGhpcyBpcyBpbiBhZGRpdGlvbiB0byB0aGUgcmVzdHJpY3Rpb24gbWVudGlvbmVkCi0gKiBhYm92ZSBjb25jZXJuaW5nIHBsYXRmb3JtIHN1cHBvcnQgZm9yIG11bHRpcGxlIGRpc3BsYXlzLiBUaHVzLAotICogdGhlIG9ubHkgd2F5IHRvIGhhdmUgbXVsdGlwbGUgc2ltdWx0YW5lb3VzbHkgYWN0aXZlIGRpc3BsYXlzLAotICogZXZlbiBvbiBwbGF0Zm9ybXMgd2hpY2ggc3VwcG9ydCBpdCwgaXMgdG8gaGF2ZSBtdWx0aXBsZSB0aHJlYWRzLikKLSAqIDwvbGk+Ci0gKiA8L3VsPgotICogRW5mb3JjaW5nIHRoZXNlIGF0dHJpYnV0ZXMgYWxsb3dzIFNXVCB0byBiZSBpbXBsZW1lbnRlZCBkaXJlY3RseQotICogb24gdGhlIHVuZGVybHlpbmcgb3BlcmF0aW5nIHN5c3RlbSdzIGV2ZW50IG1vZGVsLiBUaGlzIGhhcyAKLSAqIG51bWVyb3VzIGJlbmVmaXRzIGluY2x1ZGluZyBzbWFsbGVyIGZvb3RwcmludCwgYmV0dGVyIHVzZSBvZiAKLSAqIHJlc291cmNlcywgc2FmZXIgbWVtb3J5IG1hbmFnZW1lbnQsIGNsZWFyZXIgcHJvZ3JhbSBsb2dpYywKLSAqIGJldHRlciBwZXJmb3JtYW5jZSwgYW5kIGZld2VyIG92ZXJhbGwgb3BlcmF0aW5nIHN5c3RlbSB0aHJlYWRzCi0gKiByZXF1aXJlZC4gVGhlIGRvd24gc2lkZSBob3dldmVyLCBpcyB0aGF0IGNhcmUgbXVzdCBiZSB0YWtlbgotICogKG9ubHkpIHdoZW4gY29uc3RydWN0aW5nIG11bHRpLXRocmVhZGVkIGFwcGxpY2F0aW9ucyB0byB1c2UgdGhlCi0gKiBpbnRlci10aHJlYWQgY29tbXVuaWNhdGlvbiBtZWNoYW5pc21zIHdoaWNoIHRoaXMgY2xhc3MgcHJvdmlkZXMKLSAqIHdoZW4gcmVxdWlyZWQuCi0gKiA8L3A+PHA+Ci0gKiBBbGwgU1dUIEFQSSBtZXRob2RzIHdoaWNoIG1heSBvbmx5IGJlIGNhbGxlZCBmcm9tIHRoZSB1c2VyLWludGVyZmFjZQotICogdGhyZWFkIGFyZSBkaXN0aW5ndWlzaGVkIGluIHRoZWlyIGRvY3VtZW50YXRpb24gYnkgaW5kaWNhdGluZyB0aGF0Ci0gKiB0aGV5IHRocm93IHRoZSAiPGNvZGU+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTPC9jb2RlPiIKLSAqIFNXVCBleGNlcHRpb24uCi0gKiA8L3A+Ci0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPihub25lKTwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPkNsb3NlLCBEaXNwb3NlPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cD4KLSAqIElNUE9SVEFOVDogVGhpcyBjbGFzcyBpcyA8ZW0+bm90PC9lbT4gaW50ZW5kZWQgdG8gYmUgc3ViY2xhc3NlZC4KLSAqIDwvcD4KLSAqIAotICogQHNlZSAjc3luY0V4ZWMKLSAqIEBzZWUgI2FzeW5jRXhlYwotICogQHNlZSAjd2FrZQotICogQHNlZSAjcmVhZEFuZERpc3BhdGNoCi0gKiBAc2VlICNzbGVlcAotICogQHNlZSAjZGlzcG9zZQotICovCiBwdWJsaWMgY2xhc3MgRGlzcGxheSBleHRlbmRzIERldmljZSB7CiAKLQkvKiBXaW5kb3dzLCBFdmVudHMgYW5kIENhbGxiYWNrcyAqLwotCXN0YXRpYyBTdHJpbmcgQVBQX05BTUUgPSAiU1dUIjsKKwkvL1RFTVBPUkFSWQorCWludCB0ZXh0SGlnaGxpZ2h0VGhpY2tuZXNzID0gNDsKKwkKKwkvKiBXaW5kb3dzIGFuZCBFdmVudHMgKi8KIAlFdmVudCBbXSBldmVudFF1ZXVlOwotCUV2ZW50VGFibGUgZXZlbnRUYWJsZTsKLQkKLQkvKiBEZWZhdWx0IEZvbnRzLCBDb2xvcnMsIEluc2V0cywgV2lkdGhzIGFuZCBIZWlnaHRzLiAqLwotCUZvbnQgZGVmYXVsdEZvbnQ7Ci0JRm9udCBsaXN0Rm9udCwgdGV4dEZvbnQsIGJ1dHRvbkZvbnQsIGxhYmVsRm9udCwgZ3JvdXBGb250OwkJCi0JcHJpdmF0ZSBzaG9ydCBmSG92ZXJUaGVtZUZvbnQ7Ci0KLQlpbnQgZGlhbG9nQmFja2dyb3VuZCwgZGlhbG9nRm9yZWdyb3VuZDsKLQlpbnQgYnV0dG9uQmFja2dyb3VuZCwgYnV0dG9uRm9yZWdyb3VuZCwgYnV0dG9uU2hhZG93VGhpY2tuZXNzOwotCWludCBjb21wb3NpdGVCYWNrZ3JvdW5kLCBjb21wb3NpdGVGb3JlZ3JvdW5kOwotCWludCBjb21wb3NpdGVUb3BTaGFkb3csIGNvbXBvc2l0ZUJvdHRvbVNoYWRvdywgY29tcG9zaXRlQm9yZGVyOwotCWludCBsaXN0QmFja2dyb3VuZCwgbGlzdEZvcmVncm91bmQsIGxpc3RTZWxlY3QsIHRleHRCYWNrZ3JvdW5kLCB0ZXh0Rm9yZWdyb3VuZDsKLQlpbnQgbGFiZWxCYWNrZ3JvdW5kLCBsYWJlbEZvcmVncm91bmQsIHNjcm9sbEJhckJhY2tncm91bmQsIHNjcm9sbEJhckZvcmVncm91bmQ7Ci0JaW50IHNjcm9sbGVkSW5zZXRYLCBzY3JvbGxlZEluc2V0WSwgc2Nyb2xsZWRNYXJnaW5YLCBzY3JvbGxlZE1hcmdpblk7Ci0JaW50IGRlZmF1bHRCYWNrZ3JvdW5kLCBkZWZhdWx0Rm9yZWdyb3VuZDsKLQlpbnQgdGV4dEhpZ2hsaWdodFRoaWNrbmVzczsKLQkKLQkvKiBTeXN0ZW0gQ29sb3JzICovCi0JQ29sb3IgQ09MT1JfV0lER0VUX0RBUktfU0hBRE9XLCBDT0xPUl9XSURHRVRfTk9STUFMX1NIQURPVywgQ09MT1JfV0lER0VUX0xJR0hUX1NIQURPVzsKLQlDb2xvciBDT0xPUl9XSURHRVRfSElHSExJR0hUX1NIQURPVywgQ09MT1JfV0lER0VUX0JBQ0tHUk9VTkQsIENPTE9SX1dJREdFVF9CT1JERVI7Ci0JQ29sb3IgQ09MT1JfTElTVF9GT1JFR1JPVU5ELCBDT0xPUl9MSVNUX0JBQ0tHUk9VTkQsIENPTE9SX0xJU1RfU0VMRUNUSU9OLCBDT0xPUl9MSVNUX1NFTEVDVElPTl9URVhUOwotCUNvbG9yIENPTE9SX0lORk9fQkFDS0dST1VORDsKLQkKLQkvKiBJbml0aWFsIEd1ZXNzZXMgZm9yIFNoZWxsIFRyaW1taW5ncy4gKi8KLQlpbnQgYm9yZGVyVHJpbVdpZHRoID0gNCwgYm9yZGVyVHJpbUhlaWdodCA9IDQ7Ci0JaW50IHJlc2l6ZVRyaW1XaWR0aCA9IDYsIHJlc2l6ZVRyaW1IZWlnaHQgPSA2OwotCWludCB0aXRsZUJvcmRlclRyaW1XaWR0aCA9IDUsIHRpdGxlQm9yZGVyVHJpbUhlaWdodCA9IDI4OwotCWludCB0aXRsZVJlc2l6ZVRyaW1XaWR0aCA9IDYsIHRpdGxlUmVzaXplVHJpbUhlaWdodCA9IDI5OwotCWludCB0aXRsZVRyaW1XaWR0aCA9IDAsIHRpdGxlVHJpbUhlaWdodCA9IDIzOworCUNhbGxiYWNrIGFjdGlvbkNhbGxiYWNrLCBjb21tYW5kQ2FsbGJhY2ssIGNvbnRyb2xDYWxsYmFjazsKKwlDYWxsYmFjayBkcmF3SXRlbUNhbGxiYWNrLCBpdGVtRGF0YUNhbGxiYWNrLCBpdGVtTm90aWZpY2F0aW9uQ2FsbGJhY2ssIGhlbHBDYWxsYmFjazsKKwlDYWxsYmFjayBoaXRUZXN0Q2FsbGJhY2ssIGtleWJvYXJkQ2FsbGJhY2ssIG1lbnVDYWxsYmFjaywgbW91c2VIb3ZlckNhbGxiYWNrOworCUNhbGxiYWNrIG1vdXNlQ2FsbGJhY2ssIHRyYWNraW5nQ2FsbGJhY2ssIHdpbmRvd0NhbGxiYWNrOworCWludCBhY3Rpb25Qcm9jLCBjb21tYW5kUHJvYywgY29udHJvbFByb2M7CisJaW50IGRyYXdJdGVtUHJvYywgaXRlbURhdGFQcm9jLCBpdGVtTm90aWZpY2F0aW9uUHJvYywgaGVscFByb2M7CisJaW50IGhpdFRlc3RQcm9jLCBrZXlib2FyZFByb2MsIG1lbnVQcm9jLCBtb3VzZUhvdmVyUHJvYzsKKwlpbnQgbW91c2VQcm9jLCB0cmFja2luZ1Byb2MsIHdpbmRvd1Byb2M7CisJRXZlbnRUYWJsZSBldmVudFRhYmxlLCBmaWx0ZXJUYWJsZTsKKwlpbnQgcXVldWUsIGxhc3RNb2RpZmllcnM7CiAJCiAJLyogU3luYy9Bc3luYyBXaWRnZXQgQ29tbXVuaWNhdGlvbiAqLwogCVN5bmNocm9uaXplciBzeW5jaHJvbml6ZXIgPSBuZXcgU3luY2hyb25pemVyICh0aGlzKTsKQEAgLTEzNCw0NCArNDUsNjcgQEAKIAlSdW5uYWJsZSBbXSBkaXNwb3NlTGlzdDsKIAkKIAkvKiBUaW1lcnMgKi8KLQlpbnQgW10gdGltZXJJRHM7CisJaW50IFtdIHRpbWVySWRzOwogCVJ1bm5hYmxlIFtdIHRpbWVyTGlzdDsKKwlDYWxsYmFjayB0aW1lckNhbGxiYWNrOwogCWludCB0aW1lclByb2M7CQorCQkKKwkvKiBDdXJyZW50IGNhcmV0ICovCisJQ2FyZXQgY3VycmVudENhcmV0OworCUNhbGxiYWNrIGNhcmV0Q2FsbGJhY2s7CisJaW50IGNhcmV0SUQsIGNhcmV0UHJvYzsKKwkKKwkvKiBHcmFicyAqLworCUNvbnRyb2wgZ3JhYkNvbnRyb2w7CisKKwkvKiBIb3ZlciBIZWxwICovCisJaW50IGhlbHBTdHJpbmc7CisJQ29udHJvbCBoZWxwQ29udHJvbDsKKwlpbnQgbGFzdEhlbHBYLCBsYXN0SGVscFk7CisJCisJLyogTW91c2UgRW50ZXIvRXhpdCAqLworCUNvbnRyb2wgY3VycmVudENvbnRyb2w7CisJCisJLyogTW91c2UgSG92ZXIgKi8KKwlDb250cm9sIGhvdmVyQ29udHJvbDsKKwlpbnQgbW91c2VIb3ZlcklEOworCQorCS8qIE1lbnVzICovCisJTWVudSBtZW51QmFyOworCU1lbnUgW10gbWVudXMsIHBvcHVwczsKKwlNZW51SXRlbSBbXSBpdGVtczsKKwlzdGF0aWMgZmluYWwgaW50IElEX1RFTVBPUkFSWSA9IDEwMDA7CisJc3RhdGljIGZpbmFsIGludCBJRF9TVEFSVCA9IDEwMDE7CisJCisJLyogSW5zZXRzICovCisJUmVjdCBidXR0b25JbnNldCwgdGFiRm9sZGVySW5zZXQsIGNvbWJvSW5zZXQ7CisJCisJLyogRm9jdXMgKi8KKwlib29sZWFuIGlnbm9yZUZvY3VzOwogCQogCS8qIEtleSBNYXBwaW5ncy4gKi8KIAlzdGF0aWMgaW50IFtdIFtdIEtleVRhYmxlID0gewotCQotCQkvLyBBVwotCQkvL3s0OSwJCQkJMHgyMH0sCS8vIHNwYWNlCi0JCXs1MSwJCQkJU1dULkJTfSwKLQkJLy97MzYsCQkJCVNXVC5DUn0sCi0JCS8vIEFXCisKKwkJLyogTm9uLU51bWVyaWMgS2V5cGFkIEtleXMgKi8KKwkJezEyNiwJU1dULkFSUk9XX1VQfSwKKwkJezEyNSwJU1dULkFSUk9XX0RPV059LAorCQl7MTIzLAlTV1QuQVJST1dfTEVGVH0sCisJCXsxMjQsCVNXVC5BUlJPV19SSUdIVH0sCisJCXsxMTYsCVNXVC5QQUdFX1VQfSwKKwkJezEyMSwJU1dULlBBR0VfRE9XTn0sCisJCXsxMTUsCVNXVC5IT01FfSwKKwkJezExOSwJU1dULkVORH0sCisJCXs3MSwJU1dULklOU0VSVH0sCisKKwkJLyogVmlydHVhbCBhbmQgQXNjaWkgS2V5cyAqLworCQl7NTEsCVNXVC5CU30sCisJCXszNiwJU1dULkNSfSwKKwkJezExNywJU1dULkRFTH0sCisJCXs1MywJU1dULkVTQ30sCisJCXs3NiwJU1dULkxGfSwKKwkJezQ4LAlTV1QuVEFCfSwJCiAJCQotCQkvLyBLZXlib2FyZCBhbmQgTW91c2UgTWFza3MKLS8vCQl7T1MuWEtfQWx0X0wsCQlTV1QuQUxUfSwKLS8vCQl7T1MuWEtfQWx0X1IsCQlTV1QuQUxUfSwKLS8vCQl7T1MuWEtfU2hpZnRfTCwJCVNXVC5TSElGVH0sCi0vLwkJe09TLlhLX1NoaWZ0X1IsCQlTV1QuU0hJRlR9LAotLy8JCXtPUy5YS19Db250cm9sX0wsCVNXVC5DT05UUk9MfSwKLS8vCQl7T1MuWEtfQ29udHJvbF9SLAlTV1QuQ09OVFJPTH0sCi0JCQotLy8JCXtPUy5WS19MQlVUVE9OLCBTV1QuQlVUVE9OMX0sCi0vLwkJe09TLlZLX01CVVRUT04sIFNXVC5CVVRUT04zfSwKLS8vCQl7T1MuVktfUkJVVFRPTiwgU1dULkJVVFRPTjJ9LAotCQkKLQkJLy8gTm9uLU51bWVyaWMgS2V5cGFkIENvbnN0YW50cwotCQl7MTI2LAkJCQlTV1QuQVJST1dfVVB9LAotCQl7MTI1LAkJCQlTV1QuQVJST1dfRE9XTn0sCi0JCXsxMjMsCQkJCVNXVC5BUlJPV19MRUZUfSwKLQkJezEyNCwJCQkJU1dULkFSUk9XX1JJR0hUfSwKLQkJezExNiwJCQkJU1dULlBBR0VfVVB9LAotCQl7MTIxLAkJCQlTV1QuUEFHRV9ET1dOfSwKLQkJezExNSwJCQkJU1dULkhPTUV9LAotCQl7MTE5LAkJCQlTV1QuRU5EfSwKLQkJezcxLAkJCQlTV1QuSU5TRVJUfSwKLS8vCQl7T1MuWEtfRGVsZXRlLAkJU1dULkRFTEVURX0sCi0JCi0JCS8vIEZ1bmN0aW9ucyBLZXlzIAorCQkvKiBGdW5jdGlvbnMgS2V5cyAqLwogCQl7MTIyLAkJU1dULkYxfSwKIAkJezEyMCwJCVNXVC5GMn0sCiAJCXs5OSwJCVNXVC5GM30sCkBAIC0xODQsNjMgKzExOCwyMiBAQAogCQl7MTA5LAkJU1dULkYxMH0sCiAJCXsxMDMsCQlTV1QuRjExfSwKIAkJezExMSwJCVNXVC5GMTJ9LAorCQkKKwkJLyogTnVtZXJpYyBLZXlwYWQgS2V5cyAqLwogCX07CiAKIAkvKiBNdWx0aXBsZSBEaXNwbGF5cy4gKi8KIAlzdGF0aWMgRGlzcGxheSBEZWZhdWx0OwogCXN0YXRpYyBEaXNwbGF5IFtdIERpc3BsYXlzID0gbmV3IERpc3BsYXkgWzRdOwotCi0JLyogRG91YmxlIENsaWNrICovCi0JaW50IGxhc3RUaW1lLCBsYXN0QnV0dG9uOwotCQotCS8qIEN1cnJlbnQgY2FyZXQgKi8KLQlDYXJldCBjdXJyZW50Q2FyZXQ7Ci0JaW50IGNhcmV0SUQsIGNhcmV0UHJvYzsKLQkJCQorCQkJCQogCS8qIFBhY2thZ2UgTmFtZSAqLwogCXN0YXRpYyBmaW5hbCBTdHJpbmcgUEFDS0FHRV9QUkVGSVggPSAib3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuIjsKLQkKLQkvKiBNb3VzZSBIb3ZlciAqLwotCWludCBtb3VzZUhvdmVySUQsIG1vdXNlSG92ZXJQcm9jOwotCWludCBtb3VzZUhvdmVySGFuZGxlLCB0b29sVGlwV2luZG93SGFuZGxlOwogCQkJCiAJLyogRGlzcGxheSBEYXRhICovCiAJT2JqZWN0IGRhdGE7CiAJU3RyaW5nIFtdIGtleXM7CiAJT2JqZWN0IFtdIHZhbHVlczsKIAkKLQkvKiBBVyBNYWMgKi8KLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVE9PTFRJUF9NQVJHSU49IDM7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEhPVkVSX1RJTUVPVVQ9IDUwMDsJLy8gaW4gbWlsbGkgc2Vjb25kcwotCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTV1RfVVNFUl9FVkVOVD0gKCdTJzw8MjQpICsgKCdXJzw8MTYpICsgKCdUJzw8OCkgKyAnMSc7Ci0KLQlwcml2YXRlIGludCBmTWVudUlkPSA1MDAwOwotCQotCS8vIENhbGxiYWNrcwotCXByaXZhdGUgQXJyYXlMaXN0IGZDYWxsYmFja3M7Ci0JLy8gY2FsbGJhY2sgcHJvY3MKLQlpbnQgZkFwcGxpY2F0aW9uUHJvYzsKLQlpbnQgZldpbmRvd1Byb2M7Ci0JaW50IGZNb3VzZVByb2M7Ci0JaW50IGZNZW51UHJvYzsKLQlpbnQgZkNvbnRyb2xBY3Rpb25Qcm9jOwotCWludCBmVXNlclBhbmVEcmF3UHJvYywgZlVzZXJQYW5lSGl0VGVzdFByb2MsIGZVc2VyUGFuZVRyYWNraW5nUHJvYzsKLQlpbnQgZkRhdGFCcm93c2VyRGF0YVByb2MsIGZEYXRhQnJvd3NlckNvbXBhcmVQcm9jLCBmRGF0YUJyb3dzZXJJdGVtTm90aWZpY2F0aW9uUHJvYzsKLQkKLQlwcml2YXRlIGludCBmVXBkYXRlUmVnaW9uOwotCXByaXZhdGUgaW50IGZUcmFja2VkQ29udHJvbDsKLQlwcml2YXRlIGludCBmRm9jdXNDb250cm9sOwotCXByaXZhdGUgaW50IGZDdXJyZW50Q29udHJvbDsKLQlwcml2YXRlIFN0cmluZyBmVG9vbFRpcFRleHQ7Ci0JcHJpdmF0ZSBpbnQgZkxhc3RIb3ZlckhhbmRsZTsKLQlib29sZWFuIGZJbkNvbnRleHRNZW51OwkvLyB0cnVlIHdoaWxlIHRyYWNraW5nIGNvbnRleHQgbWVudQotCXB1YmxpYyBpbnQgZkN1cnJlbnRDdXJzb3I7Ci0JcHJpdmF0ZSBTaGVsbCBmTWVudVJvb3RTaGVsbDsKLQkKLQlwcml2YXRlIHN0YXRpYyBib29sZWFuIGZnQ2FyYm9uSW5pdGlhbGl6ZWQ7Ci0JcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBmZ0luaXRDdXJzb3JDYWxsZWQ7Ci0JLyogZW5kIEFXICovCi0JCiAJLyoKIAkqIFRFTVBPUkFSWSBDT0RFLiAgSW5zdGFsbCB0aGUgcnVubmFibGUgdGhhdAogCSogZ2V0cyB0aGUgY3VycmVudCBkaXNwbGF5LiBUaGlzIGNvZGUgd2lsbApAQCAtMjU4LDYgKzE1MSwyNiBAQAogCQl9OwogCX0KIAkKKwlzdGF0aWMgeworCQkvKgorCQkqIEZlYXR1cmUgaW4gdGhlIE1hY2ludG9zaC4gIE9uIE9TIDEwLjIsIGl0IGlzIG5lY2Vzc2FyeQorCQkqIHRvIGV4cGxpY2l0bHkgY2hlY2sgaW4gd2l0aCB0aGUgUHJvY2VzcyBNYW5hZ2VyIGFuZCBzZXQKKwkJKiB0aGUgY3VycmVudCBwcm9jZXNzIHRvIGJlIHRoZSBmcm9udCBwcm9jZXNzIGluIG9yZGVyIGZvcgorCQkqIHdpbmRvd3MgdG8gY29tZSB0byB0aGUgZnJvbnQgYnkgZGVmYXVsdC4gIFRoZSBmaXggaXMgY2FsbAorCQkqIGJvdGggR2V0Q3VycmVudFByb2Nlc3MoKSBhbmQgU2V0RnJvbnRQcm9jZXNzKCkuCisJCSogCisJCSogTk9URTogSXQgaXMgbm90IGFjdHVhbGx5IG5lY2Vzc2FyeSB0byB1c2UgdGhlIHByb2Nlc3MKKwkJKiBzZXJpYWwgbnVtYmVyIHJldHVybmVkIGJ5IEdldEN1cnJlbnRQcm9jZXNzKCkgaW4gdGhlCisJCSogY2FsbCB0byBTZXRGcm9udFByb2Nlc3MoKSAoaWUuIGtDdXJyZW50UHJvY2VzcyBjYW4gYmUKKwkJKiB1c2VkKSBidXQgYm90aCBmdW5jdGlvbnMgbXVzdCBiZSBjYWxsZWQgaW4gb3JkZXIgZm9yCisJCSogd2luZG93cyB0byBjb21lIHRvIHRoZSBmcm9udC4KKwkJKi8KKwkJaW50IFtdIHBzbiA9IG5ldyBpbnQgWzJdOworCQlpZiAoT1MuR2V0Q3VycmVudFByb2Nlc3MgKHBzbikgPT0gT1Mubm9FcnIpIHsKKwkJCU9TLlNldEZyb250UHJvY2VzcyAocHNuKTsKKwkJfQorCX0KKwkKIC8qCiAqIFRFTVBPUkFSWSBDT0RFLgogKi8KQEAgLTI2NSw1MyArMTc4LDMzIEBACiAJQ3VycmVudERldmljZSA9IGRldmljZTsKIH0KIAotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MuCi0gKiA8cD4KLSAqIE5vdGU6IFRoZSByZXN1bHRpbmcgZGlzcGxheSBpcyBtYXJrZWQgYXMgdGhlIDxlbT5jdXJyZW50PC9lbT4KLSAqIGRpc3BsYXkuIElmIHRoaXMgaXMgdGhlIGZpcnN0IGRpc3BsYXkgd2hpY2ggaGFzIGJlZW4gCi0gKiBjb25zdHJ1Y3RlZCBzaW5jZSB0aGUgYXBwbGljYXRpb24gc3RhcnRlZCwgaXQgaXMgYWxzbwotICogbWFya2VkIGFzIHRoZSA8ZW0+ZGVmYXVsdDwvZW0+IGRpc3BsYXkuCi0gKiA8L3A+Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI2dldEN1cnJlbnQKLSAqIEBzZWUgI2dldERlZmF1bHQKLSAqIEBzZWUgV2lkZ2V0I2NoZWNrU3ViY2xhc3MKLSAqIEBzZWUgU2hlbGwKLSAqLwotcHVibGljIERpc3BsYXkgKCkgewotCXRoaXMgKG51bGwpOwotfQotcHVibGljIERpc3BsYXkgKERldmljZURhdGEgZGF0YSkgewotCXN1cGVyIChjaGVja051bGwgKGRhdGEpKTsKK3N0YXRpYyBpbnQgdHJhbnNsYXRlS2V5IChpbnQga2V5KSB7CisJZm9yIChpbnQgaT0wOyBpPEtleVRhYmxlLmxlbmd0aDsgaSsrKSB7CisJCWlmIChLZXlUYWJsZSBbaV0gWzBdID09IGtleSkgcmV0dXJuIEtleVRhYmxlIFtpXSBbMV07CisJfQorCXJldHVybiAwOwogfQogCi0vKioKLSAqIEFkZHMgdGhlIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZlZCB3aGVuIGFuIGV2ZW50IG9mIHRoZSBnaXZlbiB0eXBlIG9jY3Vycy4gV2hlbiB0aGUKLSAqIGV2ZW50IGRvZXMgb2NjdXIgaW4gdGhlIGRpc3BsYXksIHRoZSBsaXN0ZW5lciBpcyBub3RpZmllZCBieQotICogc2VuZGluZyBpdCB0aGUgPGNvZGU+aGFuZGxlRXZlbnQoKTwvY29kZT4gbWVzc2FnZS4KLSAqCi0gKiBAcGFyYW0gZXZlbnRUeXBlIHRoZSB0eXBlIG9mIGV2ZW50IHRvIGxpc3RlbiBmb3IKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGV2ZW50IG9jY3VycwotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBMaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlTGlzdGVuZXIKLSAqIAotICogQHNpbmNlIDIuMCAKLSAqLworc3RhdGljIGludCB1bnRyYW5zbGF0ZUtleSAoaW50IGtleSkgeworCWZvciAoaW50IGk9MDsgaTxLZXlUYWJsZS5sZW5ndGg7IGkrKykgeworCQlpZiAoS2V5VGFibGUgW2ldIFsxXSA9PSBrZXkpIHJldHVybiBLZXlUYWJsZSBbaV0gWzBdOworCX0KKwlyZXR1cm4gMDsKK30KKworaW50IGFjdGlvblByb2MgKGludCB0aGVDb250cm9sLCBpbnQgcGFydENvZGUpIHsKKwlXaWRnZXQgd2lkZ2V0ID0gV2lkZ2V0VGFibGUuZ2V0ICh0aGVDb250cm9sKTsKKwlpZiAod2lkZ2V0ICE9IG51bGwpIHJldHVybiB3aWRnZXQuYWN0aW9uUHJvYyAodGhlQ29udHJvbCwgcGFydENvZGUpOworCXJldHVybiBPUy5ub0VycjsKK30KKworcHVibGljIHZvaWQgYWRkRmlsdGVyIChpbnQgZXZlbnRUeXBlLCBMaXN0ZW5lciBsaXN0ZW5lcikgeworCWNoZWNrRGV2aWNlICgpOworCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWlmIChmaWx0ZXJUYWJsZSA9PSBudWxsKSBmaWx0ZXJUYWJsZSA9IG5ldyBFdmVudFRhYmxlICgpOworCWZpbHRlclRhYmxlLmhvb2sgKGV2ZW50VHlwZSwgbGlzdGVuZXIpOworfQorCiBwdWJsaWMgdm9pZCBhZGRMaXN0ZW5lciAoaW50IGV2ZW50VHlwZSwgTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja0RldmljZSAoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTMxOSw4MiArMjEyLDk1IEBACiAJZXZlbnRUYWJsZS5ob29rIChldmVudFR5cGUsIGxpc3RlbmVyKTsKIH0KIAotLyoqCi0gKiBSZXF1ZXN0cyB0aGF0IHRoZSBjb25uZWN0aW9uIGJldHdlZW4gU1dUIGFuZCB0aGUgdW5kZXJseWluZwotICogb3BlcmF0aW5nIHN5c3RlbSBiZSBjbG9zZWQuCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNkaXNwb3NlCi0gKiAKLSAqIEBzaW5jZSAyLjAKLSAqLwotcHVibGljIHZvaWQgY2xvc2UgKCkgewotCWNoZWNrRGV2aWNlICgpOwotCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOwotCXNlbmRFdmVudCAoU1dULkNsb3NlLCBldmVudCk7Ci0JaWYgKGV2ZW50LmRvaXQpIGRpc3Bvc2UgKCk7Cit2b2lkIGFkZE1lbnUgKE1lbnUgbWVudSkgeworCWlmIChtZW51cyA9PSBudWxsKSBtZW51cyA9IG5ldyBNZW51IFsxMl07CisJZm9yIChpbnQgaT0wOyBpPG1lbnVzLmxlbmd0aDsgaSsrKSB7CisJCWlmIChtZW51cyBbaV0gPT0gbnVsbCkgeworCQkJbWVudS5pZCA9IChzaG9ydCkoSURfU1RBUlQgKyBpKTsKKwkJCW1lbnVzIFtpXSA9IG1lbnU7CisJCQlyZXR1cm47CisJCX0KKwl9CisJTWVudSBbXSBuZXdNZW51cyA9IG5ldyBNZW51IFttZW51cy5sZW5ndGggKyAxMl07CisJbWVudS5pZCA9IChzaG9ydCkoSURfU1RBUlQgKyBtZW51cy5sZW5ndGgpOworCW5ld01lbnVzIFttZW51cy5sZW5ndGhdID0gbWVudTsKKwlTeXN0ZW0uYXJyYXljb3B5IChtZW51cywgMCwgbmV3TWVudXMsIDAsIG1lbnVzLmxlbmd0aCk7CisJbWVudXMgPSBuZXdNZW51czsKIH0KIAotdm9pZCBhZGRNb3VzZUhvdmVyVGltZU91dCAoaW50IGhhbmRsZSkgewotCWlmIChtb3VzZUhvdmVySUQgIT0gMCkgT1MuUmVtb3ZlRXZlbnRMb29wVGltZXIobW91c2VIb3ZlcklEKTsKLQltb3VzZUhvdmVySUQgPSAwOwotCWlmIChoYW5kbGUgPT0gZkxhc3RIb3ZlckhhbmRsZSkgcmV0dXJuOwotCWludFtdIHRpbWVyPSBuZXcgaW50WzFdOwotCU9TLkluc3RhbGxFdmVudExvb3BUaW1lcihPUy5HZXRDdXJyZW50RXZlbnRMb29wKCksIEhPVkVSX1RJTUVPVVQgLyAxMDAwLjAsIDAuMCwgbW91c2VIb3ZlclByb2MsIGhhbmRsZSwgdGltZXIpOwotCW1vdXNlSG92ZXJJRCA9IHRpbWVyWzBdOwotCW1vdXNlSG92ZXJIYW5kbGUgPSBoYW5kbGU7Cit2b2lkIGFkZE1lbnVJdGVtIChNZW51SXRlbSBpdGVtKSB7CisJaWYgKGl0ZW1zID09IG51bGwpIGl0ZW1zID0gbmV3IE1lbnVJdGVtIFsxMl07CisJZm9yIChpbnQgaT0wOyBpPGl0ZW1zLmxlbmd0aDsgaSsrKSB7CisJCWlmIChpdGVtcyBbaV0gPT0gbnVsbCkgeworCQkJaXRlbS5pZCA9IElEX1NUQVJUICsgaTsKKwkJCWl0ZW1zIFtpXSA9IGl0ZW07CisJCQlyZXR1cm47CisJCX0KKwl9CisJTWVudUl0ZW0gW10gbmV3SXRlbXMgPSBuZXcgTWVudUl0ZW0gW2l0ZW1zLmxlbmd0aCArIDEyXTsKKwlpdGVtLmlkID0gSURfU1RBUlQgKyBpdGVtcy5sZW5ndGg7CisJbmV3SXRlbXMgW2l0ZW1zLmxlbmd0aF0gPSBpdGVtOworCVN5c3RlbS5hcnJheWNvcHkgKGl0ZW1zLCAwLCBuZXdJdGVtcywgMCwgaXRlbXMubGVuZ3RoKTsKKwlpdGVtcyA9IG5ld0l0ZW1zOwogfQotc3RhdGljIERldmljZURhdGEgY2hlY2tOdWxsIChEZXZpY2VEYXRhIGRhdGEpIHsKLQlpZiAoZGF0YSA9PSBudWxsKSBkYXRhID0gbmV3IERldmljZURhdGEgKCk7Ci0JcmV0dXJuIGRhdGE7CisKK3ZvaWQgYWRkUG9wdXAgKE1lbnUgbWVudSkgeworCWlmIChwb3B1cHMgPT0gbnVsbCkgcG9wdXBzID0gbmV3IE1lbnUgWzRdOworCWludCBsZW5ndGggPSBwb3B1cHMubGVuZ3RoOworCWZvciAoaW50IGk9MDsgaTxsZW5ndGg7IGkrKykgeworCQlpZiAocG9wdXBzIFtpXSA9PSBtZW51KSByZXR1cm47CisJfQorCWludCBpbmRleCA9IDA7CisJd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSB7CisJCWlmIChwb3B1cHMgW2luZGV4XSA9PSBudWxsKSBicmVhazsKKwkJaW5kZXgrKzsKKwl9CisJaWYgKGluZGV4ID09IGxlbmd0aCkgeworCQlNZW51IFtdIG5ld1BvcHVwcyA9IG5ldyBNZW51IFtsZW5ndGggKyA0XTsKKwkJU3lzdGVtLmFycmF5Y29weSAocG9wdXBzLCAwLCBuZXdQb3B1cHMsIDAsIGxlbmd0aCk7CisJCXBvcHVwcyA9IG5ld1BvcHVwczsKKwl9CisJcG9wdXBzIFtpbmRleF0gPSBtZW51OwogfQotcHJvdGVjdGVkIHZvaWQgY2hlY2tEZXZpY2UgKCkgewotCWlmICghaXNWYWxpZFRocmVhZCAoKSkgZXJyb3IgKFNXVC5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MpOwotCWlmIChpc0Rpc3Bvc2VkICgpKSBlcnJvciAoU1dULkVSUk9SX0RFVklDRV9ESVNQT1NFRCk7Ci19Ci0vKioKLSAqIENhdXNlcyB0aGUgPGNvZGU+cnVuKCk8L2NvZGU+IG1ldGhvZCBvZiB0aGUgcnVubmFibGUgdG8KLSAqIGJlIGludm9rZWQgYnkgdGhlIHVzZXItaW50ZXJmYWNlIHRocmVhZCBhdCB0aGUgbmV4dCAKLSAqIHJlYXNvbmFibGUgb3Bwb3J0dW5pdHkuIFRoZSBjYWxsZXIgb2YgdGhpcyBtZXRob2QgY29udGludWVzIAotICogdG8gcnVuIGluIHBhcmFsbGVsLCBhbmQgaXMgbm90IG5vdGlmaWVkIHdoZW4gdGhlCi0gKiBydW5uYWJsZSBoYXMgY29tcGxldGVkLgotICoKLSAqIEBwYXJhbSBydW5uYWJsZSBjb2RlIHRvIHJ1biBvbiB0aGUgdXNlci1pbnRlcmZhY2UgdGhyZWFkLgotICoKLSAqIEBzZWUgI3N5bmNFeGVjCi0gKi8KKwogcHVibGljIHZvaWQgYXN5bmNFeGVjIChSdW5uYWJsZSBydW5uYWJsZSkgewogCWlmIChpc0Rpc3Bvc2VkICgpKSBlcnJvciAoU1dULkVSUk9SX0RFVklDRV9ESVNQT1NFRCk7CiAJc3luY2hyb25pemVyLmFzeW5jRXhlYyAocnVubmFibGUpOwogfQotLyoqCi0gKiBDYXVzZXMgdGhlIHN5c3RlbSBoYXJkd2FyZSB0byBlbWl0IGEgc2hvcnQgc291bmQKLSAqIChpZiBpdCBzdXBwb3J0cyB0aGlzIGNhcGFiaWxpdHkpLgotICovCisKIHB1YmxpYyB2b2lkIGJlZXAgKCkgewogCWNoZWNrRGV2aWNlICgpOwotCU9TLlN5c0JlZXAoKHNob3J0KTEwMCk7CisJT1MuU3lzQmVlcCAoKHNob3J0KSAxMDApOwogfQorCiBpbnQgY2FyZXRQcm9jIChpbnQgaWQsIGludCBjbGllbnREYXRhKSB7Ci0JaWYgKGlkICE9IGNhcmV0SUQpIHsKLQkJcmV0dXJuIDA7Ci0JfQotCU9TLlJlbW92ZUV2ZW50TG9vcFRpbWVyKGlkKTsKLQljYXJldElEID0gMDsKIAlpZiAoY3VycmVudENhcmV0ID09IG51bGwpIHJldHVybiAwOwogCWlmIChjdXJyZW50Q2FyZXQuYmxpbmtDYXJldCAoKSkgewogCQlpbnQgYmxpbmtSYXRlID0gY3VycmVudENhcmV0LmJsaW5rUmF0ZTsKLQkJaW50W10gdGltZXI9IG5ldyBpbnRbMV07Ci0JCU9TLkluc3RhbGxFdmVudExvb3BUaW1lcihPUy5HZXRDdXJyZW50RXZlbnRMb29wKCksIGJsaW5rUmF0ZSAvIDEwMDAuMCwgMC4wLCBjYXJldFByb2MsIDAsIHRpbWVyKTsKLQkJY2FyZXRJRCA9IHRpbWVyWzBdOworCQlPUy5TZXRFdmVudExvb3BUaW1lck5leHRGaXJlVGltZSAoaWQsIGJsaW5rUmF0ZSAvIDEwMDAuMCk7CiAJfSBlbHNlIHsKIAkJY3VycmVudENhcmV0ID0gbnVsbDsKIAl9CiAJcmV0dXJuIDA7CiB9CisKK3Byb3RlY3RlZCB2b2lkIGNoZWNrRGV2aWNlICgpIHsKKwlpZiAoIWlzVmFsaWRUaHJlYWQgKCkpIGVycm9yIChTV1QuRVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTKTsKKwlpZiAoaXNEaXNwb3NlZCAoKSkgZXJyb3IgKFNXVC5FUlJPUl9ERVZJQ0VfRElTUE9TRUQpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjaGVja1N1YmNsYXNzICgpIHsKKwlpZiAoIURpc3BsYXkuaXNWYWxpZENsYXNzIChnZXRDbGFzcyAoKSkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9TVUJDTEFTUyk7Cit9CisKK3B1YmxpYyBEaXNwbGF5ICgpIHsKKwl0aGlzIChudWxsKTsKK30KKworcHVibGljIERpc3BsYXkgKERldmljZURhdGEgZGF0YSkgeworCXN1cGVyIChkYXRhKTsKK30KKwogc3RhdGljIHN5bmNocm9uaXplZCB2b2lkIGNoZWNrRGlzcGxheSAoVGhyZWFkIHRocmVhZCkgewogCWZvciAoaW50IGk9MDsgaTxEaXNwbGF5cy5sZW5ndGg7IGkrKykgewogCQlpZiAoRGlzcGxheXMgW2ldICE9IG51bGwgJiYgRGlzcGxheXMgW2ldLnRocmVhZCA9PSB0aHJlYWQpIHsKQEAgLTQwMiwxMSArMzA4LDY4IEBACiAJCX0KIAl9CiB9Ci1wcm90ZWN0ZWQgdm9pZCBjaGVja1N1YmNsYXNzICgpIHsKLQlpZiAoIURpc3BsYXkuaXNWYWxpZENsYXNzIChnZXRDbGFzcyAoKSkpIHsKLQkJZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1NVQkNMQVNTKTsKKworaW50IGNvbW1hbmRQcm9jIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IGV2ZW50S2luZCA9IE9TLkdldEV2ZW50S2luZCAodGhlRXZlbnQpOworCUhJQ29tbWFuZCBjb21tYW5kID0gbmV3IEhJQ29tbWFuZCAoKTsKKwlPUy5HZXRFdmVudFBhcmFtZXRlciAodGhlRXZlbnQsIE9TLmtFdmVudFBhcmFtRGlyZWN0T2JqZWN0LCBPUy50eXBlSElDb21tYW5kLCBudWxsLCBISUNvbW1hbmQuc2l6ZW9mLCBudWxsLCBjb21tYW5kKTsKKwlzd2l0Y2ggKGV2ZW50S2luZCkgeworCQljYXNlIE9TLmtFdmVudFByb2Nlc3NDb21tYW5kOiB7CisJCQlpZiAoY29tbWFuZC5jb21tYW5kSUQgPT0gT1Mua0FFUXVpdEFwcGxpY2F0aW9uKSB7CisJCQkJY2xvc2UgKCk7CisJCQkJcmV0dXJuIE9TLm5vRXJyOworCQkJfQorCQkJaWYgKChjb21tYW5kLmF0dHJpYnV0ZXMgJiBPUy5rSElDb21tYW5kRnJvbU1lbnUpICE9IDApIHsKKwkJCQlpZiAodXNlckRhdGEgIT0gMCkgeworCQkJCQlXaWRnZXQgd2lkZ2V0ID0gV2lkZ2V0VGFibGUuZ2V0ICh1c2VyRGF0YSk7CisJCQkJCWlmICh3aWRnZXQgIT0gbnVsbCkgcmV0dXJuIHdpZGdldC5jb21tYW5kUHJvYyAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJCQkJfSBlbHNlIHsKKwkJCQkJaW50IG1lbnVSZWYgPSBjb21tYW5kLm1lbnVfbWVudVJlZjsKKwkJCQkJc2hvcnQgbWVudUlEID0gT1MuR2V0TWVudUlEIChtZW51UmVmKTsKKwkJCQkJTWVudSBtZW51ID0gZmluZE1lbnUgKG1lbnVJRCk7CisJCQkJCWlmIChtZW51ICE9IG51bGwpIHsKKwkJCQkJCWludCBbXSBvdXRDb21tYW5kSUQgPSBuZXcgaW50IFsxXTsKKwkJCQkJCXNob3J0IG1lbnVJbmRleCA9IGNvbW1hbmQubWVudV9tZW51SXRlbUluZGV4OworCQkJCQkJT1MuR2V0TWVudUl0ZW1Db21tYW5kSUQgKG1lbnVSZWYsIG1lbnVJbmRleCwgb3V0Q29tbWFuZElEKTsKKwkJCQkJCU1lbnVJdGVtIGl0ZW0gPSBmaW5kTWVudUl0ZW0gKG91dENvbW1hbmRJRCBbMF0pOworCQkJCQkJcmV0dXJuIGl0ZW0ua0V2ZW50UHJvY2Vzc0NvbW1hbmQgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCQkJCQl9CisJCQkJCU9TLkhpbGl0ZU1lbnUgKChzaG9ydCkgMCk7CisJCQkJfQorCQkJfQorCQl9CiAJfQorCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7CiB9CisKK1JlY3QgY29tcHV0ZUluc2V0IChpbnQgY29udHJvbCkgeworCWludCB0ZW1wUmduID0gT1MuTmV3UmduICgpOworCVJlY3QgcmVjdCA9IG5ldyBSZWN0ICgpOworCU9TLkdldENvbnRyb2xSZWdpb24gKGNvbnRyb2wsIChzaG9ydCkgT1Mua0NvbnRyb2xTdHJ1Y3R1cmVNZXRhUGFydCwgdGVtcFJnbik7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAoY29udHJvbCwgcmVjdCk7CisJUmVjdCByZ25SZWN0ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0UmVnaW9uQm91bmRzICh0ZW1wUmduLCByZ25SZWN0KTsKKwlPUy5EaXNwb3NlUmduICh0ZW1wUmduKTsKKwlyZWN0LmxlZnQgLT0gcmduUmVjdC5sZWZ0OworCXJlY3QudG9wIC09IHJnblJlY3QudG9wOworCXJlY3QucmlnaHQgPSAoc2hvcnQpIChyZ25SZWN0LnJpZ2h0IC0gcmVjdC5yaWdodCk7CisJcmVjdC5ib3R0b20gPSAoc2hvcnQpIChyZ25SZWN0LmJvdHRvbSAtIHJlY3QuYm90dG9tKTsKKwlyZXR1cm4gcmVjdDsgCit9CisKK2ludCBjb250cm9sUHJvYyAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKHVzZXJEYXRhKTsKKwlpZiAod2lkZ2V0ICE9IG51bGwpIHJldHVybiB3aWRnZXQuY29udHJvbFByb2MgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK3B1YmxpYyB2b2lkIGNsb3NlICgpIHsKKwljaGVja0RldmljZSAoKTsKKwlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKKwlzZW5kRXZlbnQgKFNXVC5DbG9zZSwgZXZlbnQpOworCWlmIChldmVudC5kb2l0KSBkaXNwb3NlICgpOworfQorCiBwcm90ZWN0ZWQgdm9pZCBjcmVhdGUgKERldmljZURhdGEgZGF0YSkgewogCWNoZWNrU3ViY2xhc3MgKCk7CiAJY2hlY2tEaXNwbGF5ICh0aHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCAoKSk7CkBAIC00MTQsNTQgKzM3NywyNyBAQAogCXJlZ2lzdGVyICh0aGlzKTsKIAlpZiAoRGVmYXVsdCA9PSBudWxsKSBEZWZhdWx0ID0gdGhpczsKIH0KKwogdm9pZCBjcmVhdGVEaXNwbGF5IChEZXZpY2VEYXRhIGRhdGEpIHsKLQkKLQkvKiBJbml0aWFsaXplIENhcmJvbiAqLwotCXN5bmNocm9uaXplZCAoRGlzcGxheS5jbGFzcykgewotCQlpZiAoIWZnQ2FyYm9uSW5pdGlhbGl6ZWQpIHsKLQkJCU9TLlJlZ2lzdGVyQXBwZWFyYW5jZUNsaWVudCgpOwotCQkJT1MuVFhOSW5pdFRleHRlbnNpb24oKTsKLQkJCS8vT1MuSW5pdEN1cnNvcigpOwotCQkJT1MuUURTd2FwVGV4dEZsYWdzKE9TLmtRRFVzZUNHVGV4dFJlbmRlcmluZyArIE9TLmtRRFVzZUNHVGV4dE1ldHJpY3MpOwotCQkJaWYgKE9TLkluaXRDb250ZXh0dWFsTWVudXMoKSAhPSBPUy5rTm9FcnIpCi0JCQkJU3lzdGVtLm91dC5wcmludGxuKCJEaXNwbGF5LmNyZWF0ZURpc3BsYXk6IGVycm9yIGluIE9TLkluaXRDb250ZXh0dWFsTWVudXMiKTsKLQkJCWludFtdIHBzbj0gbmV3IGludFsyXTsKLQkJCWlmIChPUy5HZXRDdXJyZW50UHJvY2Vzcyhwc24pID09IE9TLmtOb0VycikKLQkgICAgCQlPUy5TZXRGcm9udFByb2Nlc3MocHNuKTsKLQkJCQkKLQkJCU9TLkluaXQoKTsKLQkgICAgfQotCQlmZ0NhcmJvbkluaXRpYWxpemVkID0gdHJ1ZTsKLQl9Ci0JCi0JZkdEZXZpY2VIYW5kbGU9IE9TLkdldE1haW5EZXZpY2UoKTsKKwlxdWV1ZSA9IE9TLkdldEN1cnJlbnRFdmVudFF1ZXVlICgpOworCU9TLlRYTkluaXRUZXh0ZW5zaW9uICgwLCAwLCAwKTsKIH0KKwogc3luY2hyb25pemVkIHN0YXRpYyB2b2lkIGRlcmVnaXN0ZXIgKERpc3BsYXkgZGlzcGxheSkgewogCWZvciAoaW50IGk9MDsgaTxEaXNwbGF5cy5sZW5ndGg7IGkrKykgewogCQlpZiAoZGlzcGxheSA9PSBEaXNwbGF5cyBbaV0pIERpc3BsYXlzIFtpXSA9IG51bGw7CiAJfQogfQorCiBwcm90ZWN0ZWQgdm9pZCBkZXN0cm95ICgpIHsKIAlpZiAodGhpcyA9PSBEZWZhdWx0KSBEZWZhdWx0ID0gbnVsbDsKIAlkZXJlZ2lzdGVyICh0aGlzKTsKIAlkZXN0cm95RGlzcGxheSAoKTsKIH0KKwogdm9pZCBkZXN0cm95RGlzcGxheSAoKSB7Ci0JLy8gZGlzcG9zZSBDYWxsYmFja3MKLQlJdGVyYXRvciBpdGVyPSBmQ2FsbGJhY2tzLml0ZXJhdG9yKCk7Ci0Jd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKSB7Ci0JCUNhbGxiYWNrIGNiPSAoQ2FsbGJhY2spIGl0ZXIubmV4dCgpOwotCQljYi5kaXNwb3NlKCk7Ci0JfQotCWZDYWxsYmFja3M9IG51bGw7CiB9Ci0vKioKLSAqIENhdXNlcyB0aGUgPGNvZGU+cnVuKCk8L2NvZGU+IG1ldGhvZCBvZiB0aGUgcnVubmFibGUgdG8KLSAqIGJlIGludm9rZWQgYnkgdGhlIHVzZXItaW50ZXJmYWNlIHRocmVhZCBqdXN0IGJlZm9yZSB0aGUKLSAqIHJlY2VpdmVyIGlzIGRpc3Bvc2VkLgotICoKLSAqIEBwYXJhbSBydW5uYWJsZSBjb2RlIHRvIHJ1biBhdCBkaXNwb3NlIHRpbWUuCi0gKi8KKwogcHVibGljIHZvaWQgZGlzcG9zZUV4ZWMgKFJ1bm5hYmxlIHJ1bm5hYmxlKSB7CiAJY2hlY2tEZXZpY2UgKCk7CiAJaWYgKGRpc3Bvc2VMaXN0ID09IG51bGwpIGRpc3Bvc2VMaXN0ID0gbmV3IFJ1bm5hYmxlIFs0XTsKQEAgLTQ3Niw2MSArNDEyLDQ2IEBACiAJbmV3RGlzcG9zZUxpc3QgW2Rpc3Bvc2VMaXN0Lmxlbmd0aF0gPSBydW5uYWJsZTsKIAlkaXNwb3NlTGlzdCA9IG5ld0Rpc3Bvc2VMaXN0OwogfQorCitpbnQgZHJhd0l0ZW1Qcm9jIChpbnQgYnJvd3NlciwgaW50IGl0ZW0sIGludCBwcm9wZXJ0eSwgaW50IGl0ZW1TdGF0ZSwgaW50IHRoZVJlY3QsIGludCBnZERlcHRoLCBpbnQgY29sb3JEZXZpY2UpIHsKKwlXaWRnZXQgd2lkZ2V0ID0gV2lkZ2V0VGFibGUuZ2V0IChicm93c2VyKTsKKwlpZiAod2lkZ2V0ICE9IG51bGwpIHJldHVybiB3aWRnZXQuZHJhd0l0ZW1Qcm9jIChicm93c2VyLCBpdGVtLCBwcm9wZXJ0eSwgaXRlbVN0YXRlLCB0aGVSZWN0LCBnZERlcHRoLCBjb2xvckRldmljZSk7CisJcmV0dXJuIE9TLm5vRXJyOworfQorCiB2b2lkIGVycm9yIChpbnQgY29kZSkgewogCVNXVC5lcnJvcihjb2RlKTsKIH0KLS8qKgotICogR2l2ZW4gdGhlIG9wZXJhdGluZyBzeXN0ZW0gaGFuZGxlIGZvciBhIHdpZGdldCwgcmV0dXJucwotICogdGhlIGluc3RhbmNlIG9mIHRoZSA8Y29kZT5XaWRnZXQ8L2NvZGU+IHN1YmNsYXNzIHdoaWNoCi0gKiByZXByZXNlbnRzIGl0IGluIHRoZSBjdXJyZW50bHkgcnVubmluZyBhcHBsaWNhdGlvbiwgaWYKLSAqIHN1Y2ggZXhpc3RzLCBvciBudWxsIGlmIG5vIG1hdGNoaW5nIHdpZGdldCBjYW4gYmUgZm91bmQuCi0gKgotICogQHBhcmFtIGhhbmRsZSB0aGUgaGFuZGxlIGZvciB0aGUgd2lkZ2V0Ci0gKiBAcmV0dXJuIHRoZSBTV1Qgd2lkZ2V0IHRoYXQgdGhlIGhhbmRsZSByZXByZXNlbnRzCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCitib29sZWFuIGZpbHRlckV2ZW50IChFdmVudCBldmVudCkgeworCWlmIChmaWx0ZXJUYWJsZSAhPSBudWxsKSBmaWx0ZXJUYWJsZS5zZW5kRXZlbnQgKGV2ZW50KTsKKwlyZXR1cm4gZmFsc2U7Cit9CisKK2Jvb2xlYW4gZmlsdGVycyAoaW50IGV2ZW50VHlwZSkgeworCWlmIChmaWx0ZXJUYWJsZSA9PSBudWxsKSByZXR1cm4gZmFsc2U7CisJcmV0dXJuIGZpbHRlclRhYmxlLmhvb2tzIChldmVudFR5cGUpOworfQorCitNZW51IGZpbmRNZW51IChpbnQgaWQpIHsKKwlpZiAobWVudXMgPT0gbnVsbCkgcmV0dXJuIG51bGw7CisJaW50IGluZGV4ID0gaWQgLSBJRF9TVEFSVDsKKwlpZiAoMCA8PSBpbmRleCAmJiBpbmRleCA8IG1lbnVzLmxlbmd0aCkgcmV0dXJuIG1lbnVzIFtpbmRleF07CisJcmV0dXJuIG51bGw7Cit9CisKK01lbnVJdGVtIGZpbmRNZW51SXRlbSAoaW50IGlkKSB7CisJaWYgKGl0ZW1zID09IG51bGwpIHJldHVybiBudWxsOworCWludCBpbmRleCA9IGlkIC0gSURfU1RBUlQ7CisJaWYgKDAgPD0gaW5kZXggJiYgaW5kZXggPCBpdGVtcy5sZW5ndGgpIHJldHVybiBpdGVtcyBbaW5kZXhdOworCXJldHVybiBudWxsOworfQorCiBwdWJsaWMgV2lkZ2V0IGZpbmRXaWRnZXQgKGludCBoYW5kbGUpIHsKIAljaGVja0RldmljZSAoKTsKIAlyZXR1cm4gV2lkZ2V0VGFibGUuZ2V0IChoYW5kbGUpOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBjdXJyZW50bHkgYWN0aXZlIDxjb2RlPlNoZWxsPC9jb2RlPiwgb3IgbnVsbAotICogaWYgbm8gc2hlbGwgYmVsb25naW5nIHRvIHRoZSBjdXJyZW50bHkgcnVubmluZyBhcHBsaWNhdGlvbgotICogaXMgYWN0aXZlLgotICoKLSAqIEByZXR1cm4gdGhlIGFjdGl2ZSBzaGVsbCBvciBudWxsCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwotcHVibGljIFNoZWxsIGdldEFjdGl2ZVNoZWxsICgpIHsKLQljaGVja0RldmljZSAoKTsKLQlDb250cm9sIGNvbnRyb2wgPSBnZXRGb2N1c0NvbnRyb2wgKCk7Ci0JaWYgKGNvbnRyb2wgPT0gbnVsbCkgcmV0dXJuIG51bGw7Ci0JcmV0dXJuIGNvbnRyb2wuZ2V0U2hlbGwgKCk7Ci19Ci0vKioKLSAqIFJldHVybnMgdGhlIGRpc3BsYXkgd2hpY2ggdGhlIGN1cnJlbnRseSBydW5uaW5nIHRocmVhZCBpcwotICogdGhlIHVzZXItaW50ZXJmYWNlIHRocmVhZCBmb3IsIG9yIG51bGwgaWYgdGhlIGN1cnJlbnRseQotICogcnVubmluZyB0aHJlYWQgaXMgbm90IGEgdXNlci1pbnRlcmZhY2UgdGhyZWFkIGZvciBhbnkgZGlzcGxheS4KLSAqCi0gKiBAcmV0dXJuIHRoZSBjdXJyZW50IGRpc3BsYXkKLSAqLwotcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgRGlzcGxheSBnZXRDdXJyZW50ICgpIHsKLQlyZXR1cm4gZmluZERpc3BsYXkgKFRocmVhZC5jdXJyZW50VGhyZWFkICgpKTsKLX0KLS8qKgotICogUmV0dXJucyB0aGUgZGlzcGxheSB3aGljaCB0aGUgZ2l2ZW4gdGhyZWFkIGlzIHRoZQotICogdXNlci1pbnRlcmZhY2UgdGhyZWFkIGZvciwgb3IgbnVsbCBpZiB0aGUgZ2l2ZW4gdGhyZWFkCi0gKiBpcyBub3QgYSB1c2VyLWludGVyZmFjZSB0aHJlYWQgZm9yIGFueSBkaXNwbGF5LgotICoKLSAqIEBwYXJhbSB0aHJlYWQgdGhlIHVzZXItaW50ZXJmYWNlIHRocmVhZAotICogQHJldHVybiB0aGUgZGlzcGxheSBmb3IgdGhlIGdpdmVuIHRocmVhZAotICovCisKIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIERpc3BsYXkgZmluZERpc3BsYXkgKFRocmVhZCB0aHJlYWQpIHsKIAlmb3IgKGludCBpPTA7IGk8RGlzcGxheXMubGVuZ3RoOyBpKyspIHsKIAkJRGlzcGxheSBkaXNwbGF5ID0gRGlzcGxheXMgW2ldOwpAQCAtNTQwLDkzICs0NjEsNjkgQEAKIAl9CiAJcmV0dXJuIG51bGw7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIGNvbnRyb2wgd2hpY2ggdGhlIG9uLXNjcmVlbiBwb2ludGVyIGlzIGN1cnJlbnRseQotICogb3ZlciB0b3Agb2YsIG9yIG51bGwgaWYgaXQgaXMgbm90IGN1cnJlbnRseSBvdmVyIG9uZSBvZiB0aGUKLSAqIGNvbnRyb2xzIGJ1aWx0IGJ5IHRoZSBjdXJyZW50bHkgcnVubmluZyBhcHBsaWNhdGlvbi4KLSAqCi0gKiBAcmV0dXJuIHRoZSBjb250cm9sIHVuZGVyIHRoZSBjdXJzb3IKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCi1wdWJsaWMgQ29udHJvbCBnZXRDdXJzb3JDb250cm9sICgpIHsKKworcHVibGljIFNoZWxsIGdldEFjdGl2ZVNoZWxsICgpIHsKIAljaGVja0RldmljZSAoKTsKLQlTeXN0ZW0ub3V0LnByaW50bG4oIkRpc3BsYXkuZ2V0Q3Vyc29yQ29udHJvbDogbnlpIik7Ci0JCi0JLyogQVcKLQlpbnQgW10gdW51c2VkID0gbmV3IGludCBbMV0sIGJ1ZmZlciA9IG5ldyBpbnQgWzFdOwotCWludCB4V2luZG93LCB4UGFyZW50ID0gT1MuWERlZmF1bHRSb290V2luZG93ICh4RGlzcGxheSk7Ci0JZG8gewotCQlpZiAoT1MuWFF1ZXJ5UG9pbnRlciAoCi0JCQl4RGlzcGxheSwgeFBhcmVudCwgdW51c2VkLCBidWZmZXIsCi0JCQl1bnVzZWQsIHVudXNlZCwgdW51c2VkLCB1bnVzZWQsIHVudXNlZCkgPT0gMCkgcmV0dXJuIG51bGw7Ci0JCWlmICgoeFdpbmRvdyA9IGJ1ZmZlciBbMF0pICE9IDApIHhQYXJlbnQgPSB4V2luZG93OwotCX0gd2hpbGUgKHhXaW5kb3cgIT0gMCk7Ci0JaW50IGhhbmRsZSA9IE9TLlh0V2luZG93VG9XaWRnZXQgKHhEaXNwbGF5LCB4UGFyZW50KTsKLQlpZiAoaGFuZGxlID09IDApIHJldHVybiBudWxsOwotCWRvIHsKLQkJV2lkZ2V0IHdpZGdldCA9IFdpZGdldFRhYmxlLmdldCAoaGFuZGxlKTsKLQkJaWYgKHdpZGdldCAhPSBudWxsICYmIHdpZGdldCBpbnN0YW5jZW9mIENvbnRyb2wpIHsKLQkJCUNvbnRyb2wgY29udHJvbCA9IChDb250cm9sKSB3aWRnZXQ7Ci0JCQlpZiAoY29udHJvbC5nZXRFbmFibGVkICgpKSByZXR1cm4gY29udHJvbDsKLQkJfQotCX0gd2hpbGUgKChoYW5kbGUgPSBPUy5YdFBhcmVudCAoaGFuZGxlKSkgIT0gMCk7Ci0JKi8KKwlpbnQgdGhlV2luZG93ID0gT1MuQWN0aXZlTm9uRmxvYXRpbmdXaW5kb3cgKCk7CisJaWYgKHRoZVdpbmRvdyA9PSAwKSByZXR1cm4gbnVsbDsKKwlpbnQgW10gdGhlQ29udHJvbCA9IG5ldyBpbnQgWzFdOworCU9TLkdldFJvb3RDb250cm9sICh0aGVXaW5kb3csIHRoZUNvbnRyb2wpOworCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKHRoZUNvbnRyb2wgWzBdKTsKKwlpZiAod2lkZ2V0IGluc3RhbmNlb2YgU2hlbGwpIHJldHVybiAoU2hlbGwpIHdpZGdldDsKIAlyZXR1cm4gbnVsbDsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgbG9jYXRpb24gb2YgdGhlIG9uLXNjcmVlbiBwb2ludGVyIHJlbGF0aXZlCi0gKiB0byB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSBzY3JlZW4uCi0gKgotICogQHJldHVybiB0aGUgY3Vyc29yIGxvY2F0aW9uCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCitwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBEaXNwbGF5IGdldEN1cnJlbnQgKCkgeworCXJldHVybiBmaW5kRGlzcGxheSAoVGhyZWFkLmN1cnJlbnRUaHJlYWQgKCkpOworfQorCitpbnQgZ2V0Q2FyZXRCbGlua1RpbWUgKCkgeworCXJldHVybiBPUy5HZXRDYXJldFRpbWUgKCkgKiAxMDAwIC8gNjA7Cit9CisKK3B1YmxpYyBDb250cm9sIGdldEN1cnNvckNvbnRyb2wgKCkgeworCWNoZWNrRGV2aWNlICgpOworCW9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgd2hlcmUgPSBuZXcgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCAoKTsKKwlPUy5HZXRHbG9iYWxNb3VzZSAod2hlcmUpOworCWludCBbXSB0aGVXaW5kb3cgPSBuZXcgaW50IFsxXTsKKwlpZiAoT1MuRmluZFdpbmRvdyAod2hlcmUsIHRoZVdpbmRvdykgIT0gT1MuaW5Db250ZW50KSByZXR1cm4gbnVsbDsKKwlpZiAodGhlV2luZG93IFswXSA9PSAwKSByZXR1cm4gbnVsbDsKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRXaW5kb3dCb3VuZHMgKHRoZVdpbmRvdyBbMF0sIChzaG9ydCkgT1Mua1dpbmRvd0NvbnRlbnRSZ24sIHJlY3QpOworCUNHUG9pbnQgaW5Qb2ludCA9IG5ldyBDR1BvaW50ICgpOworCWluUG9pbnQueCA9IHdoZXJlLmggLSByZWN0LmxlZnQ7CisJaW5Qb2ludC55ID0gd2hlcmUudiAtIHJlY3QudG9wOworCWludCBbXSB0aGVSb290ID0gbmV3IGludCBbMV07CisJT1MuR2V0Um9vdENvbnRyb2wgKHRoZVdpbmRvdyBbMF0sIHRoZVJvb3QpOworCWludCBbXSB0aGVDb250cm9sID0gbmV3IGludCBbMV07CisJT1MuSElWaWV3R2V0U3Vidmlld0hpdCAodGhlUm9vdCBbMF0sIGluUG9pbnQsIHRydWUsIHRoZUNvbnRyb2wpOworCWlmICh0aGVDb250cm9sIFswXSAhPSAwKSB7CisJCWRvIHsKKwkJCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKHRoZUNvbnRyb2wgWzBdKTsKKwkJCWlmICh3aWRnZXQgIT0gbnVsbCAmJiB3aWRnZXQgaW5zdGFuY2VvZiBDb250cm9sKSB7CisJCQkJQ29udHJvbCBjb250cm9sID0gKENvbnRyb2wpIHdpZGdldDsKKwkJCQlpZiAoY29udHJvbC5nZXRFbmFibGVkICgpKSByZXR1cm4gY29udHJvbDsKKwkJCX0KKwkJCU9TLkdldFN1cGVyQ29udHJvbCAodGhlQ29udHJvbCBbMF0sIHRoZUNvbnRyb2wpOworCQl9IHdoaWxlICh0aGVDb250cm9sIFswXSAhPSAwKTsKKwl9CisJV2lkZ2V0IHdpZGdldCA9IFdpZGdldFRhYmxlLmdldCAodGhlUm9vdCBbMF0pOworCWlmICh3aWRnZXQgIT0gbnVsbCAmJiB3aWRnZXQgaW5zdGFuY2VvZiBDb250cm9sKSByZXR1cm4gKENvbnRyb2wpIHdpZGdldDsKKwlyZXR1cm4gbnVsbDsKK30KKwogcHVibGljIFBvaW50IGdldEN1cnNvckxvY2F0aW9uICgpIHsKIAljaGVja0RldmljZSAoKTsKLQlNYWNQb2ludCBsb2M9IG5ldyBNYWNQb2ludCgpOwotCU9TLkdldEdsb2JhbE1vdXNlKGxvYy5nZXREYXRhKCkpOwotCXJldHVybiBuZXcgUG9pbnQgKGxvYy5nZXRYKCksIGxvYy5nZXRZKCkpOworCW9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgcHQgPSBuZXcgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCAoKTsKKwlPUy5HZXRHbG9iYWxNb3VzZSAocHQpOworCXJldHVybiBuZXcgUG9pbnQgKHB0LmgsIHB0LnYpOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGRpc3BsYXkuIE9uZSBpcyBjcmVhdGVkIChtYWtpbmcgdGhlCi0gKiB0aHJlYWQgdGhhdCBpbnZva2VzIHRoaXMgbWV0aG9kIGl0cyB1c2VyLWludGVyZmFjZSB0aHJlYWQpCi0gKiBpZiBpdCBkaWQgbm90IGFscmVhZHkgZXhpc3QuCi0gKgotICogQHJldHVybiB0aGUgZGVmYXVsdCBkaXNwbGF5Ci0gKi8KKwogcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgRGlzcGxheSBnZXREZWZhdWx0ICgpIHsKIAlpZiAoRGVmYXVsdCA9PSBudWxsKSBEZWZhdWx0ID0gbmV3IERpc3BsYXkgKCk7CiAJcmV0dXJuIERlZmF1bHQ7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIGFwcGxpY2F0aW9uIGRlZmluZWQgcHJvcGVydHkgb2YgdGhlIHJlY2VpdmVyCi0gKiB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSwgb3IgbnVsbCBpZiBpdCBoYXMgbm90IGJlZW4gc2V0LgotICogPHA+Ci0gKiBBcHBsaWNhdGlvbnMgbWF5IGhhdmUgYXNzb2NpYXRlZCBhcmJpdHJhcnkgb2JqZWN0cyB3aXRoIHRoZQotICogcmVjZWl2ZXIgaW4gdGhpcyBmYXNoaW9uLiBJZiB0aGUgb2JqZWN0cyBzdG9yZWQgaW4gdGhlCi0gKiBwcm9wZXJ0aWVzIG5lZWQgdG8gYmUgbm90aWZpZWQgd2hlbiB0aGUgZGlzcGxheSBpcyBkaXNwb3NlZAotICogb2YsIGl0IGlzIHRoZSBhcHBsaWNhdGlvbidzIHJlc3BvbnNpYmlsaXR5IHByb3ZpZGUgYQotICogPGNvZGU+ZGlzcG9zZUV4ZWMoKTwvY29kZT4gaGFuZGxlciB3aGljaCBkb2VzIHNvLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBrZXkgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5Ci0gKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgb3IgbnVsbCBpZiBpdCBoYXMgbm90IGJlZW4gc2V0Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUga2V5IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjc2V0RGF0YQotICogQHNlZSAjZGlzcG9zZUV4ZWMKLSAqLworCiBwdWJsaWMgT2JqZWN0IGdldERhdGEgKFN0cmluZyBrZXkpIHsKIAljaGVja0RldmljZSAoKTsKIAlpZiAoa2V5ID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC02MzYsMTA1ICs1MzMsNzQgQEAKIAl9CiAJcmV0dXJuIG51bGw7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIGFwcGxpY2F0aW9uIGRlZmluZWQsIGRpc3BsYXkgc3BlY2lmaWMgZGF0YQotICogYXNzb2NpYXRlZCB3aXRoIHRoZSByZWNlaXZlciwgb3IgbnVsbCBpZiBpdCBoYXMgbm90IGJlZW4KLSAqIHNldC4gVGhlIDxlbT5kaXNwbGF5IHNwZWNpZmljIGRhdGE8L2VtPiBpcyBhIHNpbmdsZSwKLSAqIHVubmFtZWQgZmllbGQgdGhhdCBpcyBzdG9yZWQgd2l0aCBldmVyeSBkaXNwbGF5LiAKLSAqIDxwPgotICogQXBwbGljYXRpb25zIG1heSBwdXQgYXJiaXRyYXJ5IG9iamVjdHMgaW4gdGhpcyBmaWVsZC4gSWYKLSAqIHRoZSBvYmplY3Qgc3RvcmVkIGluIHRoZSBkaXNwbGF5IHNwZWNpZmljIGRhdGEgbmVlZHMgdG8KLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGRpc3BsYXkgaXMgZGlzcG9zZWQgb2YsIGl0IGlzIHRoZQotICogYXBwbGljYXRpb24ncyByZXNwb25zaWJpbGl0eSBwcm92aWRlIGEKLSAqIDxjb2RlPmRpc3Bvc2VFeGVjKCk8L2NvZGU+IGhhbmRsZXIgd2hpY2ggZG9lcyBzby4KLSAqIDwvcD4KLSAqCi0gKiBAcmV0dXJuIHRoZSBkaXNwbGF5IHNwZWNpZmljIGRhdGEKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gd2hlbiBjYWxsZWQgZnJvbSB0aGUgd3JvbmcgdGhyZWFkPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjc2V0RGF0YQotICogQHNlZSAjZGlzcG9zZUV4ZWMKLSAqLworCiBwdWJsaWMgT2JqZWN0IGdldERhdGEgKCkgewogCWNoZWNrRGV2aWNlICgpOwogCXJldHVybiBkYXRhOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBsb25nZXN0IGR1cmF0aW9uLCBpbiBtaWxsaXNlY29uZHMsIGJldHdlZW4KLSAqIHR3byBtb3VzZSBidXR0b24gY2xpY2tzIHRoYXQgd2lsbCBiZSBjb25zaWRlcmVkIGEKLSAqIDxlbT5kb3VibGUgY2xpY2s8L2VtPiBieSB0aGUgdW5kZXJseWluZyBvcGVyYXRpbmcgc3lzdGVtLgotICoKLSAqIEByZXR1cm4gdGhlIGRvdWJsZSBjbGljayB0aW1lCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldERvdWJsZUNsaWNrVGltZSAoKSB7CiAJY2hlY2tEZXZpY2UgKCk7Ci0JcmV0dXJuIChPUy5HZXREYmxUaW1lKCkgKiAxMDAwKSAvIDYwOyAKKwlyZXR1cm4gT1MuR2V0RGJsVGltZSAoKTsgCiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIGNvbnRyb2wgd2hpY2ggY3VycmVudGx5IGhhcyBrZXlib2FyZCBmb2N1cywKLSAqIG9yIG51bGwgaWYga2V5Ym9hcmQgZXZlbnRzIGFyZSBub3QgY3VycmVudGx5IGdvaW5nIHRvCi0gKiBhbnkgb2YgdGhlIGNvbnRyb2xzIGJ1aWx0IGJ5IHRoZSBjdXJyZW50bHkgcnVubmluZwotICogYXBwbGljYXRpb24uCi0gKgotICogQHJldHVybiB0aGUgY29udHJvbCB1bmRlciB0aGUgY3Vyc29yCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgQ29udHJvbCBnZXRGb2N1c0NvbnRyb2wgKCkgewogCWNoZWNrRGV2aWNlICgpOwotCS8qIEFXCi0JaW50IFtdIGJ1ZmZlcjEgPSBuZXcgaW50IFsxXSwgYnVmZmVyMiA9IG5ldyBpbnQgWzFdOwotCU9TLlhHZXRJbnB1dEZvY3VzICh4RGlzcGxheSwgYnVmZmVyMSwgYnVmZmVyMik7Ci0JaW50IHhXaW5kb3cgPSBidWZmZXIxIFswXTsKLQlpZiAoeFdpbmRvdyA9PSAwKSByZXR1cm4gbnVsbDsKLQlpbnQgaGFuZGxlID0gT1MuWHRXaW5kb3dUb1dpZGdldCAoeERpc3BsYXksIHhXaW5kb3cpOwotCWlmIChoYW5kbGUgPT0gMCkgcmV0dXJuIG51bGw7Ci0JaGFuZGxlID0gT1MuWG1HZXRGb2N1c1dpZGdldCAoaGFuZGxlKTsKLQkqLwotCWludCBoYW5kbGU9IGZGb2N1c0NvbnRyb2w7Ci0JaWYgKGhhbmRsZSA9PSAwKSByZXR1cm4gbnVsbDsKKwlpbnQgdGhlV2luZG93ID0gT1MuQWN0aXZlTm9uRmxvYXRpbmdXaW5kb3cgKCk7CisJaWYgKHRoZVdpbmRvdyA9PSAwKSByZXR1cm4gbnVsbDsKKwlyZXR1cm4gZ2V0Rm9jdXNDb250cm9sICh0aGVXaW5kb3cpOworfQorCitDb250cm9sIGdldEZvY3VzQ29udHJvbCAoaW50IHdpbmRvdykgeworCWludCBbXSB0aGVDb250cm9sID0gbmV3IGludCBbMV07CisJT1MuR2V0S2V5Ym9hcmRGb2N1cyAod2luZG93LCB0aGVDb250cm9sKTsKKwlpZiAodGhlQ29udHJvbCBbMF0gPT0gMCkgcmV0dXJuIG51bGw7CiAJZG8gewotCQlXaWRnZXQgd2lkZ2V0ID0gV2lkZ2V0VGFibGUuZ2V0IChoYW5kbGUpOwotCQlpZiAod2lkZ2V0IGluc3RhbmNlb2YgQ29udHJvbCkgewotCQkJQ29udHJvbCB3aW5kb3cgPSAoQ29udHJvbCkgd2lkZ2V0OwotCQkJaWYgKHdpbmRvdy5nZXRFbmFibGVkICgpKSByZXR1cm4gd2luZG93OworCQlXaWRnZXQgd2lkZ2V0ID0gV2lkZ2V0VGFibGUuZ2V0ICh0aGVDb250cm9sIFswXSk7CisJCWlmICh3aWRnZXQgIT0gbnVsbCAmJiB3aWRnZXQgaW5zdGFuY2VvZiBDb250cm9sKSB7CisJCQlDb250cm9sIGNvbnRyb2wgPSAoQ29udHJvbCkgd2lkZ2V0OworCQkJaWYgKGNvbnRyb2wuZ2V0RW5hYmxlZCAoKSkgcmV0dXJuIGNvbnRyb2w7CiAJCX0KLQl9IHdoaWxlICgoaGFuZGxlID0gTWFjVXRpbC5nZXRTdXBlckNvbnRyb2wgKGhhbmRsZSkpICE9IDApOworCQlPUy5HZXRTdXBlckNvbnRyb2wgKHRoZUNvbnRyb2wgWzBdLCB0aGVDb250cm9sKTsKKwl9IHdoaWxlICh0aGVDb250cm9sIFswXSAhPSAwKTsKIAlyZXR1cm4gbnVsbDsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgbWF4aW11bSBhbGxvd2VkIGRlcHRoIG9mIGljb25zIG9uIHRoaXMgZGlzcGxheS4KLSAqIE9uIHNvbWUgcGxhdGZvcm1zLCB0aGlzIG1heSBiZSBkaWZmZXJlbnQgdGhhbiB0aGUgYWN0dWFsCi0gKiBkZXB0aCBvZiB0aGUgZGlzcGxheS4KLSAqCi0gKiBAcmV0dXJuIHRoZSBtYXhpbXVtIGljb24gZGVwdGgKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBpbnQgZ2V0SWNvbkRlcHRoICgpIHsKLQlyZXR1cm4gODsJLy8gd2UgZG9uJ3Qgc3VwcG9ydCBkaXJlY3QgaWNvbnMgeWV0CisJcmV0dXJuIGdldERlcHRoICgpOwogfQotLyoqCi0gKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgYWxsIHNoZWxscyB3aGljaCBoYXZlIG5vdCBiZWVuCi0gKiBkaXNwb3NlZCBhbmQgaGF2ZSB0aGUgcmVjZWl2ZXIgYXMgdGhlaXIgZGlzcGxheS4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIHNoZWxscwotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKworaW50IGdldExhc3RFdmVudFRpbWUgKCkgeworCS8qCisJKiBUaGlzIGNvZGUgaXMgaW50ZW50aW9uYWxseSBjb21tZW50ZWQuICBFdmVudCB0aW1lIGlzCisJKiBpbiBzZWNvbmRzIGFuZCB3ZSBuZWVkIGFuIGFjY3VyYXRlIHRpbWUgaW4gbWlsbGlzZWNvbmRzLgorCSovCisvLwlyZXR1cm4gKGludCkgKE9TLkdldExhc3RVc2VyRXZlbnRUaW1lICgpICogMTAwMC4wKTsKKwlyZXR1cm4gKGludCkgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzICgpOworfQorCitNZW51IFtdIGdldE1lbnVzIChEZWNvcmF0aW9ucyBzaGVsbCkgeworCWlmIChtZW51cyA9PSBudWxsKSByZXR1cm4gbmV3IE1lbnUgWzBdOworCWludCBjb3VudCA9IDA7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBtZW51cy5sZW5ndGg7IGkrKykgeworCQlNZW51IG1lbnUgPSBtZW51c1tpXTsKKwkJaWYgKG1lbnUgIT0gbnVsbCAmJiBtZW51LnBhcmVudCA9PSBzaGVsbCkgY291bnQrKzsKKwl9CisJaW50IGluZGV4ID0gMDsKKwlNZW51W10gcmVzdWx0ID0gbmV3IE1lbnVbY291bnRdOworCWZvciAoaW50IGkgPSAwOyBpIDwgbWVudXMubGVuZ3RoOyBpKyspIHsKKwkJTWVudSBtZW51ID0gbWVudXNbaV07CisJCWlmIChtZW51ICE9IG51bGwgJiYgbWVudS5wYXJlbnQgPT0gc2hlbGwpIHsKKwkJCXJlc3VsdFtpbmRleCsrXSA9IG1lbnU7CisJCX0KKwl9CisJcmV0dXJuIHJlc3VsdDsKK30KKworTWVudSBnZXRNZW51QmFyICgpIHsKKwlyZXR1cm4gbWVudUJhcjsKK30KKwogcHVibGljIFNoZWxsIFtdIGdldFNoZWxscyAoKSB7CiAJY2hlY2tEZXZpY2UgKCk7CiAJLyoKQEAgLTc2MiwzMDAgKzYyOCwyMzIgQEAKIAl9CiAJcmV0dXJuIHJlc3VsdDsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgdGhyZWFkIHRoYXQgaGFzIGludm9rZWQgPGNvZGU+c3luY0V4ZWM8L2NvZGU+Ci0gKiBvciBudWxsIGlmIG5vIHN1Y2ggcnVubmFibGUgaXMgY3VycmVudGx5IGJlaW5nIGludm9rZWQgYnkKLSAqIHRoZSB1c2VyLWludGVyZmFjZSB0aHJlYWQuCi0gKiA8cD4KLSAqIE5vdGU6IElmIGEgcnVubmFibGUgaW52b2tlZCBieSBhc3luY0V4ZWMgaXMgY3VycmVudGx5Ci0gKiBydW5uaW5nLCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBudWxsLgotICogPC9wPgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3Mgc3luYy1pbnRlcmZhY2UgdGhyZWFkCi0gKi8KKwogcHVibGljIFRocmVhZCBnZXRTeW5jVGhyZWFkICgpIHsKIAlpZiAoaXNEaXNwb3NlZCAoKSkgZXJyb3IgKFNXVC5FUlJPUl9ERVZJQ0VfRElTUE9TRUQpOwogCXJldHVybiBzeW5jaHJvbml6ZXIuc3luY1RocmVhZDsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgbWF0Y2hpbmcgc3RhbmRhcmQgY29sb3IgZm9yIHRoZSBnaXZlbgotICogY29uc3RhbnQsIHdoaWNoIHNob3VsZCBiZSBvbmUgb2YgdGhlIGNvbG9yIGNvbnN0YW50cwotICogc3BlY2lmaWVkIGluIGNsYXNzIDxjb2RlPlNXVDwvY29kZT4uIEFueSB2YWx1ZSBvdGhlcgotICogdGhhbiBvbmUgb2YgdGhlIFNXVCBjb2xvciBjb25zdGFudHMgd2hpY2ggaXMgcGFzc2VkCi0gKiBpbiB3aWxsIHJlc3VsdCBpbiB0aGUgY29sb3IgYmxhY2suIFRoaXMgY29sb3Igc2hvdWxkCi0gKiBub3QgYmUgZnJlZSdkIGJlY2F1c2UgaXQgd2FzIGFsbG9jYXRlZCBieSB0aGUgc3lzdGVtLAotICogbm90IHRoZSBhcHBsaWNhdGlvbi4KLSAqCi0gKiBAcGFyYW0gaWQgdGhlIGNvbG9yIGNvbnN0YW50Ci0gKiBAcmV0dXJuIHRoZSBtYXRjaGluZyBjb2xvcgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTV1QKLSAqLworCiBwdWJsaWMgQ29sb3IgZ2V0U3lzdGVtQ29sb3IgKGludCBpZCkgewogCWNoZWNrRGV2aWNlICgpOwotCUNvbG9yIHhDb2xvciA9IG51bGw7CisJLy9OT1QgRE9ORQorCQorCVJHQkNvbG9yIHJnYiA9IG5ldyBSR0JDb2xvciAoKTsKIAlzd2l0Y2ggKGlkKSB7Ci0JCWNhc2UgU1dULkNPTE9SX0lORk9fRk9SRUdST1VORDogCQlyZXR1cm4gc3VwZXIuZ2V0U3lzdGVtQ29sb3IgKFNXVC5DT0xPUl9CTEFDSyk7Ci0JCWNhc2UgU1dULkNPTE9SX0lORk9fQkFDS0dST1VORDogCQlyZXR1cm4gQ09MT1JfSU5GT19CQUNLR1JPVU5EOwotCQljYXNlIFNXVC5DT0xPUl9USVRMRV9GT1JFR1JPVU5EOgkJcmV0dXJuIHN1cGVyLmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfV0hJVEUpOwotCQljYXNlIFNXVC5DT0xPUl9USVRMRV9CQUNLR1JPVU5EOgkJcmV0dXJuIHN1cGVyLmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfREFSS19CTFVFKTsKLQkJY2FzZSBTV1QuQ09MT1JfVElUTEVfQkFDS0dST1VORF9HUkFESUVOVDoJcmV0dXJuIHN1cGVyLmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfQkxVRSk7Ci0JCWNhc2UgU1dULkNPTE9SX1RJVExFX0lOQUNUSVZFX0ZPUkVHUk9VTkQ6CXJldHVybiBzdXBlci5nZXRTeXN0ZW1Db2xvciAoU1dULkNPTE9SX0JMQUNLKTsKLQkJY2FzZSBTV1QuQ09MT1JfVElUTEVfSU5BQ1RJVkVfQkFDS0dST1VORDoJcmV0dXJuIHN1cGVyLmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfREFSS19HUkFZKTsKLQkJY2FzZSBTV1QuQ09MT1JfVElUTEVfSU5BQ1RJVkVfQkFDS0dST1VORF9HUkFESUVOVDoJcmV0dXJuIHN1cGVyLmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfR1JBWSk7Ci0JCWNhc2UgU1dULkNPTE9SX1dJREdFVF9EQVJLX1NIQURPVzoJeENvbG9yID0gQ09MT1JfV0lER0VUX0RBUktfU0hBRE9XOyBicmVhazsKLQkJY2FzZSBTV1QuQ09MT1JfV0lER0VUX05PUk1BTF9TSEFET1c6CXhDb2xvciA9IENPTE9SX1dJREdFVF9OT1JNQUxfU0hBRE9XOyBicmVhazsKLQkJY2FzZSBTV1QuQ09MT1JfV0lER0VUX0xJR0hUX1NIQURPVzogCXhDb2xvciA9IENPTE9SX1dJREdFVF9MSUdIVF9TSEFET1c7IGJyZWFrOwotCQljYXNlIFNXVC5DT0xPUl9XSURHRVRfSElHSExJR0hUX1NIQURPVzoJeENvbG9yID0gQ09MT1JfV0lER0VUX0hJR0hMSUdIVF9TSEFET1c7IGJyZWFrOwotCQljYXNlIFNXVC5DT0xPUl9XSURHRVRfQkFDS0dST1VORDogCXhDb2xvciA9IENPTE9SX1dJREdFVF9CQUNLR1JPVU5EOyBicmVhazsKLQkJY2FzZSBTV1QuQ09MT1JfV0lER0VUX0ZPUkVHUk9VTkQ6Ci0JCWNhc2UgU1dULkNPTE9SX1dJREdFVF9CT1JERVI6IAkJeENvbG9yID0gQ09MT1JfV0lER0VUX0JPUkRFUjsgYnJlYWs7Ci0JCWNhc2UgU1dULkNPTE9SX0xJU1RfRk9SRUdST1VORDogCXhDb2xvciA9IENPTE9SX0xJU1RfRk9SRUdST1VORDsgYnJlYWs7Ci0JCWNhc2UgU1dULkNPTE9SX0xJU1RfQkFDS0dST1VORDogCXhDb2xvciA9IENPTE9SX0xJU1RfQkFDS0dST1VORDsgYnJlYWs7Ci0JCWNhc2UgU1dULkNPTE9SX0xJU1RfU0VMRUNUSU9OOiAJCXhDb2xvciA9IENPTE9SX0xJU1RfU0VMRUNUSU9OOyBicmVhazsKLQkJY2FzZSBTV1QuQ09MT1JfTElTVF9TRUxFQ1RJT05fVEVYVDogCXhDb2xvciA9IENPTE9SX0xJU1RfU0VMRUNUSU9OX1RFWFQ7IGJyZWFrOworCQljYXNlIFNXVC5DT0xPUl9JTkZPX0ZPUkVHUk9VTkQ6IAkJCQkJCXJldHVybiBzdXBlci5nZXRTeXN0ZW1Db2xvciAoU1dULkNPTE9SX0JMQUNLKTsKKwkJY2FzZSBTV1QuQ09MT1JfSU5GT19CQUNLR1JPVU5EOiAJCQkJCQlyZXR1cm4gQ29sb3IuY2FyYm9uX25ldyAodGhpcywgbmV3IGZsb2F0IFtdIHsweEZGIC8gMjU1ZiwgMHhGRiAvIDI1NWYsIDB4RTEgLyAyNTVmLCAxfSk7CisJCWNhc2UgU1dULkNPTE9SX1RJVExFX0ZPUkVHUk9VTkQ6CQkJCQkJT1MuR2V0VGhlbWVUZXh0Q29sb3IoKHNob3J0KU9TLmtUaGVtZVRleHRDb2xvckRvY3VtZW50V2luZG93VGl0bGVBY3RpdmUsIChzaG9ydClnZXREZXB0aCgpLCB0cnVlLCByZ2IpOyBicmVhazsKKwkJY2FzZSBTV1QuQ09MT1JfVElUTEVfQkFDS0dST1VORDoJCQkJCQlPUy5HZXRUaGVtZUJydXNoQXNDb2xvcigoc2hvcnQpLTUvKnVuZG9jdW1lbnRlZCBkYXJrZXIgaGlnaGxpZ2h0IGNvbG9yKi8sIChzaG9ydClnZXREZXB0aCgpLCB0cnVlLCByZ2IpOyBicmVhazsKKwkJY2FzZSBTV1QuQ09MT1JfVElUTEVfQkFDS0dST1VORF9HUkFESUVOVDogCU9TLkdldFRoZW1lQnJ1c2hBc0NvbG9yKChzaG9ydClPUy5rVGhlbWVCcnVzaFByaW1hcnlIaWdobGlnaHRDb2xvciwgKHNob3J0KWdldERlcHRoKCksIHRydWUsIHJnYikgOyBicmVhazsKKwkJY2FzZSBTV1QuQ09MT1JfVElUTEVfSU5BQ1RJVkVfRk9SRUdST1VORDoJT1MuR2V0VGhlbWVUZXh0Q29sb3IoKHNob3J0KU9TLmtUaGVtZVRleHRDb2xvckRvY3VtZW50V2luZG93VGl0bGVJbmFjdGl2ZSwgKHNob3J0KWdldERlcHRoKCksIHRydWUsIHJnYik7IGJyZWFrOworCQljYXNlIFNXVC5DT0xPUl9USVRMRV9JTkFDVElWRV9CQUNLR1JPVU5EOiAJT1MuR2V0VGhlbWVCcnVzaEFzQ29sb3IoKHNob3J0KU9TLmtUaGVtZUJydXNoU2Vjb25kYXJ5SGlnaGxpZ2h0Q29sb3IsIChzaG9ydClnZXREZXB0aCgpLCB0cnVlLCByZ2IpOyBicmVhazsKKwkJY2FzZSBTV1QuQ09MT1JfVElUTEVfSU5BQ1RJVkVfQkFDS0dST1VORF9HUkFESUVOVDogT1MuR2V0VGhlbWVCcnVzaEFzQ29sb3IoKHNob3J0KU9TLmtUaGVtZUJydXNoU2Vjb25kYXJ5SGlnaGxpZ2h0Q29sb3IsIChzaG9ydClnZXREZXB0aCgpLCB0cnVlLCByZ2IpOyBicmVhazsKKwkJY2FzZSBTV1QuQ09MT1JfV0lER0VUX0RBUktfU0hBRE9XOgkJCQlyZXR1cm4gQ29sb3IuY2FyYm9uX25ldyAodGhpcywgbmV3IGZsb2F0IFtdIHsweDMzIC8gMjU1ZiwgMHgzMyAvIDI1NWYsIDB4MzMgLyAyNTVmLCAxfSk7CisJCWNhc2UgU1dULkNPTE9SX1dJREdFVF9OT1JNQUxfU0hBRE9XOgkJCXJldHVybiBDb2xvci5jYXJib25fbmV3ICh0aGlzLCBuZXcgZmxvYXQgW10gezB4NjYgLyAyNTVmLCAweDY2IC8gMjU1ZiwgMHg2NiAvIDI1NWYsIDF9KTsKKwkJY2FzZSBTV1QuQ09MT1JfV0lER0VUX0xJR0hUX1NIQURPVzogCQkJCXJldHVybiBDb2xvci5jYXJib25fbmV3ICh0aGlzLCBuZXcgZmxvYXQgW10gezB4OTkgLyAyNTVmLCAweDk5IC8gMjU1ZiwgMHg5OSAvIDI1NWYsIDF9KTsKKwkJY2FzZSBTV1QuQ09MT1JfV0lER0VUX0hJR0hMSUdIVF9TSEFET1c6CQlyZXR1cm4gQ29sb3IuY2FyYm9uX25ldyAodGhpcywgbmV3IGZsb2F0IFtdIHsweENDIC8gMjU1ZiwgMHhDQyAvIDI1NWYsIDB4Q0MgLyAyNTVmLCAxfSk7CisJCWNhc2UgU1dULkNPTE9SX1dJREdFVF9CQUNLR1JPVU5EOiAJCQkJCU9TLkdldFRoZW1lQnJ1c2hBc0NvbG9yKChzaG9ydClPUy5rVGhlbWVCcnVzaEJ1dHRvbkZhY2VBY3RpdmUsIChzaG9ydClnZXREZXB0aCgpLCB0cnVlLCByZ2IpOyBicmVhazsKKwkJY2FzZSBTV1QuQ09MT1JfV0lER0VUX0ZPUkVHUk9VTkQ6CQkJCQlPUy5HZXRUaGVtZVRleHRDb2xvcigoc2hvcnQpT1Mua1RoZW1lVGV4dENvbG9yUHVzaEJ1dHRvbkFjdGl2ZSwgKHNob3J0KWdldERlcHRoKCksIHRydWUsIHJnYik7IGJyZWFrOworCQljYXNlIFNXVC5DT0xPUl9XSURHRVRfQk9SREVSOiAJCQkJCQkJcmV0dXJuIHN1cGVyLmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfQkxBQ0spOworCQljYXNlIFNXVC5DT0xPUl9MSVNUX0ZPUkVHUk9VTkQ6IAkJCQkJCU9TLkdldFRoZW1lVGV4dENvbG9yKChzaG9ydClPUy5rVGhlbWVUZXh0Q29sb3JMaXN0VmlldywgKHNob3J0KWdldERlcHRoKCksIHRydWUsIHJnYik7IGJyZWFrOworCQljYXNlIFNXVC5DT0xPUl9MSVNUX0JBQ0tHUk9VTkQ6IAkJCQkJCU9TLkdldFRoZW1lQnJ1c2hBc0NvbG9yKChzaG9ydClPUy5rVGhlbWVCcnVzaExpc3RWaWV3QmFja2dyb3VuZCwgKHNob3J0KWdldERlcHRoKCksIHRydWUsIHJnYik7IGJyZWFrOworCQljYXNlIFNXVC5DT0xPUl9MSVNUX1NFTEVDVElPTl9URVhUOiAJCQkJCU9TLkdldFRoZW1lVGV4dENvbG9yKChzaG9ydClPUy5rVGhlbWVUZXh0Q29sb3JMaXN0VmlldywgKHNob3J0KWdldERlcHRoKCksIHRydWUsIHJnYik7IGJyZWFrOworCQljYXNlIFNXVC5DT0xPUl9MSVNUX1NFTEVDVElPTjoJCQkJCQkJCU9TLkdldFRoZW1lQnJ1c2hBc0NvbG9yKChzaG9ydClPUy5rVGhlbWVCcnVzaFByaW1hcnlIaWdobGlnaHRDb2xvciwgKHNob3J0KWdldERlcHRoKCksIHRydWUsIHJnYik7IGJyZWFrOwogCQlkZWZhdWx0OgogCQkJcmV0dXJuIHN1cGVyLmdldFN5c3RlbUNvbG9yIChpZCk7CQogCX0KLQlpZiAoeENvbG9yID09IG51bGwpCi0JCVN5c3RlbS5vdXQucHJpbnRsbigiRGlzcGxheS5nZXRTeXN0ZW1Db2xvcjogY29sb3IgbnVsbCAiICsgaWQpOwotCWlmICh4Q29sb3IgPT0gbnVsbCkgcmV0dXJuIHN1cGVyLmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfQkxBQ0spOwotCS8vcmV0dXJuIENvbG9yLmNhcmJvbl9uZXcgKHRoaXMsIHhDb2xvcik7Ci0JcmV0dXJuIHhDb2xvcjsKLQkvLyByZXR1cm4gZ2V0U3lzdGVtQ29sb3IodGhpcywgaWQpOworCWZsb2F0IHJlZCA9ICgocmdiLnJlZCA+PiA4KSAmIDB4RkYpIC8gMjU1ZjsKKwlmbG9hdCBncmVlbiA9ICgocmdiLmdyZWVuID4+IDgpICYgMHhGRikgLyAyNTVmOworCWZsb2F0IGJsdWUgPSAoKHJnYi5ibHVlID4+IDgpICYgMHhGRikgLyAyNTVmOworCXJldHVybiBDb2xvci5jYXJib25fbmV3ICh0aGlzLCBuZXcgZmxvYXRbXXtyZWQsIGdyZWVuLCBibHVlLCAxfSk7CiB9Ci0vKioKLSAqIFJldHVybnMgYSByZWFzb25hYmxlIGZvbnQgZm9yIGFwcGxpY2F0aW9ucyB0byB1c2UuCi0gKiBPbiBzb21lIHBsYXRmb3JtcywgdGhpcyB3aWxsIG1hdGNoIHRoZSAiZGVmYXVsdCBmb250IgotICogb3IgInN5c3RlbSBmb250IiBpZiBzdWNoIGNhbiBiZSBmb3VuZC4gIFRoaXMgZm9udAotICogc2hvdWxkIG5vdCBiZSBmcmVlJ2QgYmVjYXVzZSBpdCB3YXMgYWxsb2NhdGVkIGJ5IHRoZQotICogc3lzdGVtLCBub3QgdGhlIGFwcGxpY2F0aW9uLgotICogPHA+Ci0gKiBUeXBpY2FsbHksIGFwcGxpY2F0aW9ucyB3aGljaCB3YW50IHRoZSBkZWZhdWx0IGxvb2sKLSAqIHNob3VsZCBzaW1wbHkgbm90IHNldCB0aGUgZm9udCBvbiB0aGUgd2lkZ2V0cyB0aGV5Ci0gKiBjcmVhdGUuIFdpZGdldHMgYXJlIGFsd2F5cyBjcmVhdGVkIHdpdGggdGhlIGNvcnJlY3QKLSAqIGRlZmF1bHQgZm9udCBmb3IgdGhlIGNsYXNzIG9mIHVzZXItaW50ZXJmYWNlIGNvbXBvbmVudAotICogdGhleSByZXByZXNlbnQuCi0gKiA8L3A+Ci0gKgotICogQHJldHVybiBhIGZvbnQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCi1wdWJsaWMgRm9udCBnZXRTeXN0ZW1Gb250ICgpIHsKLQljaGVja0RldmljZSAoKTsKLQlyZXR1cm4gZGVmYXVsdEZvbnQ7Ci19Ci0vKioKLSAqIFJldHVybnMgdGhlIHVzZXItaW50ZXJmYWNlIHRocmVhZCBmb3IgdGhlIHJlY2VpdmVyLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgdXNlci1pbnRlcmZhY2UgdGhyZWFkCi0gKi8KKwogcHVibGljIFRocmVhZCBnZXRUaHJlYWQgKCkgewogCWlmIChpc0Rpc3Bvc2VkICgpKSBlcnJvciAoU1dULkVSUk9SX0RFVklDRV9ESVNQT1NFRCk7CiAJcmV0dXJuIHRocmVhZDsKIH0KLXZvaWQgaGlkZVRvb2xUaXAgKCkgewotCWlmICh0b29sVGlwV2luZG93SGFuZGxlICE9IDApIHsKLQkJT1MuSGlkZVdpbmRvdyh0b29sVGlwV2luZG93SGFuZGxlKTsKLQkJT1MuRGlzcG9zZVdpbmRvdyh0b29sVGlwV2luZG93SGFuZGxlKTsKLQkJdG9vbFRpcFdpbmRvd0hhbmRsZSA9IDA7Ci0JfQorCitpbnQgaGVscFByb2MgKGludCBpbkNvbnRyb2wsIGludCBpbkdsb2JhbE1vdXNlLCBpbnQgaW5SZXF1ZXN0LCBpbnQgb3V0Q29udGVudFByb3ZpZGVkLCBpbnQgaW9IZWxwQ29udGVudCkgeworCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKGluQ29udHJvbCk7CisJaWYgKHdpZGdldCAhPSBudWxsKSByZXR1cm4gd2lkZ2V0LmhlbHBQcm9jIChpbkNvbnRyb2wsIGluR2xvYmFsTW91c2UsIGluUmVxdWVzdCwgb3V0Q29udGVudFByb3ZpZGVkLCBpb0hlbHBDb250ZW50KTsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOwogfQorCitpbnQgaGl0VGVzdFByb2MgKGludCBicm93c2VyLCBpbnQgaXRlbSwgaW50IHByb3BlcnR5LCBpbnQgdGhlUmVjdCwgaW50IG1vdXNlUmVjdCkgeworCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKGJyb3dzZXIpOworCWlmICh3aWRnZXQgIT0gbnVsbCkgcmV0dXJuIHdpZGdldC5oaXRUZXN0UHJvYyAoYnJvd3NlciwgaXRlbSwgcHJvcGVydHksIHRoZVJlY3QsIG1vdXNlUmVjdCk7CisJcmV0dXJuIE9TLm5vRXJyOworfQorCiBwcm90ZWN0ZWQgdm9pZCBpbml0ICgpIHsKIAlzdXBlci5pbml0ICgpOwotCQkJCQotCS8qIENyZWF0ZSB0aGUgY2FsbGJhY2tzICovCi0JdGltZXJQcm9jPSBjcmVhdGVDYWxsYmFjaygidGltZXJQcm9jIiwgMik7Ci0JY2FyZXRQcm9jPSBjcmVhdGVDYWxsYmFjaygiY2FyZXRQcm9jIiwgMik7Ci0JbW91c2VIb3ZlclByb2M9IGNyZWF0ZUNhbGxiYWNrKCJtb3VzZUhvdmVyUHJvYyIsIDIpOwotCi0JZldpbmRvd1Byb2M9IGNyZWF0ZUNhbGxiYWNrKCJoYW5kbGVXaW5kb3dDYWxsYmFjayIsIDMpOwotCWZNb3VzZVByb2M9IGNyZWF0ZUNhbGxiYWNrKCJoYW5kbGVNb3VzZUNhbGxiYWNrIiwgMyk7Ci0JZkNvbnRyb2xBY3Rpb25Qcm9jPSBjcmVhdGVDYWxsYmFjaygiaGFuZGxlQ29udHJvbEFjdGlvbiIsIDIpOwotCWZVc2VyUGFuZURyYXdQcm9jPSBjcmVhdGVDYWxsYmFjaygiaGFuZGxlVXNlclBhbmVEcmF3IiwgMik7Ci0JZlVzZXJQYW5lSGl0VGVzdFByb2M9IGNyZWF0ZUNhbGxiYWNrKCJoYW5kbGVVc2VyUGFuZUhpdFRlc3QiLCAyKTsKLQlmVXNlclBhbmVUcmFja2luZ1Byb2M9IGNyZWF0ZUNhbGxiYWNrKCJoYW5kbGVVc2VyUGFuZVRyYWNraW5nIiwgMyk7Ci0JZkRhdGFCcm93c2VyRGF0YVByb2M9IGNyZWF0ZUNhbGxiYWNrKCJoYW5kbGVEYXRhQnJvd3NlckRhdGFDYWxsYmFjayIsIDUpOwotCWZEYXRhQnJvd3NlckNvbXBhcmVQcm9jPSBjcmVhdGVDYWxsYmFjaygiaGFuZGxlRGF0YUJyb3dzZXJDb21wYXJlQ2FsbGJhY2siLCA0KTsKLQlmRGF0YUJyb3dzZXJJdGVtTm90aWZpY2F0aW9uUHJvYz0gY3JlYXRlQ2FsbGJhY2soImhhbmRsZURhdGFCcm93c2VySXRlbU5vdGlmaWNhdGlvbkNhbGxiYWNrIiwgMyk7Ci0JZk1lbnVQcm9jPSBjcmVhdGVDYWxsYmFjaygiaGFuZGxlTWVudUNhbGxiYWNrIiwgMyk7CisJaW5pdGlhbGl6ZUNhbGxiYWNrcyAoKTsKKwlpbml0aWFsaXplSW5zZXRzICgpOwkKK30KIAkKLQkvLyBjcmVhdGUgc3RhbmRhcmQgZXZlbnQgaGFuZGxlcgotCWZBcHBsaWNhdGlvblByb2M9IGNyZWF0ZUNhbGxiYWNrKCJoYW5kbGVBcHBsaWNhdGlvbkNhbGxiYWNrIiwgMyk7Ci0JaW50W10gbWFzaz0gbmV3IGludFtdIHsKK3ZvaWQgaW5pdGlhbGl6ZUNhbGxiYWNrcyAoKSB7CisJLyogQ3JlYXRlIENhbGxiYWNrcyAqLworCWFjdGlvbkNhbGxiYWNrID0gbmV3IENhbGxiYWNrICh0aGlzLCAiYWN0aW9uUHJvYyIsIDIpOworCWFjdGlvblByb2MgPSBhY3Rpb25DYWxsYmFjay5nZXRBZGRyZXNzICgpOworCWlmIChhY3Rpb25Qcm9jID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fTU9SRV9DQUxMQkFDS1MpOworCWNhcmV0Q2FsbGJhY2sgPSBuZXcgQ2FsbGJhY2sodGhpcywgImNhcmV0UHJvYyIsIDIpOworCWNhcmV0UHJvYyA9IGNhcmV0Q2FsbGJhY2suZ2V0QWRkcmVzcygpOworCWlmIChjYXJldFByb2MgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19NT1JFX0NBTExCQUNLUyk7CisJY29tbWFuZENhbGxiYWNrID0gbmV3IENhbGxiYWNrICh0aGlzLCAiY29tbWFuZFByb2MiLCAzKTsKKwljb21tYW5kUHJvYyA9IGNvbW1hbmRDYWxsYmFjay5nZXRBZGRyZXNzICgpOworCWlmIChjb21tYW5kUHJvYyA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX01PUkVfQ0FMTEJBQ0tTKTsKKwljb250cm9sQ2FsbGJhY2sgPSBuZXcgQ2FsbGJhY2sgKHRoaXMsICJjb250cm9sUHJvYyIsIDMpOworCWNvbnRyb2xQcm9jID0gY29udHJvbENhbGxiYWNrLmdldEFkZHJlc3MgKCk7CisJaWYgKGNvbnRyb2xQcm9jID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fTU9SRV9DQUxMQkFDS1MpOworCWRyYXdJdGVtQ2FsbGJhY2sgPSBuZXcgQ2FsbGJhY2sgKHRoaXMsICJkcmF3SXRlbVByb2MiLCA3KTsKKwlkcmF3SXRlbVByb2MgPSBkcmF3SXRlbUNhbGxiYWNrLmdldEFkZHJlc3MgKCk7CisJaWYgKGRyYXdJdGVtUHJvYyA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX01PUkVfQ0FMTEJBQ0tTKTsKKwlpdGVtRGF0YUNhbGxiYWNrID0gbmV3IENhbGxiYWNrICh0aGlzLCAiaXRlbURhdGFQcm9jIiwgNSk7CisJaXRlbURhdGFQcm9jID0gaXRlbURhdGFDYWxsYmFjay5nZXRBZGRyZXNzICgpOworCWlmIChpdGVtRGF0YVByb2MgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19NT1JFX0NBTExCQUNLUyk7CisJaXRlbU5vdGlmaWNhdGlvbkNhbGxiYWNrID0gbmV3IENhbGxiYWNrICh0aGlzLCAiaXRlbU5vdGlmaWNhdGlvblByb2MiLCAzKTsKKwlpdGVtTm90aWZpY2F0aW9uUHJvYyA9IGl0ZW1Ob3RpZmljYXRpb25DYWxsYmFjay5nZXRBZGRyZXNzICgpOworCWlmIChpdGVtTm90aWZpY2F0aW9uUHJvYyA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX01PUkVfQ0FMTEJBQ0tTKTsKKwloZWxwQ2FsbGJhY2sgPSBuZXcgQ2FsbGJhY2sgKHRoaXMsICJoZWxwUHJvYyIsIDUpOworCWhlbHBQcm9jID0gaGVscENhbGxiYWNrLmdldEFkZHJlc3MgKCk7CisJaWYgKGhlbHBQcm9jID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fTU9SRV9DQUxMQkFDS1MpOworCWhpdFRlc3RDYWxsYmFjayA9IG5ldyBDYWxsYmFjayAodGhpcywgImhpdFRlc3RQcm9jIiwgNSk7CisJaGl0VGVzdFByb2MgPSBoaXRUZXN0Q2FsbGJhY2suZ2V0QWRkcmVzcyAoKTsKKwlpZiAoaGl0VGVzdFByb2MgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19NT1JFX0NBTExCQUNLUyk7CisJa2V5Ym9hcmRDYWxsYmFjayA9IG5ldyBDYWxsYmFjayAodGhpcywgImtleWJvYXJkUHJvYyIsIDMpOworCWtleWJvYXJkUHJvYyA9IGtleWJvYXJkQ2FsbGJhY2suZ2V0QWRkcmVzcyAoKTsKKwlpZiAoa2V5Ym9hcmRQcm9jID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fTU9SRV9DQUxMQkFDS1MpOworCW1lbnVDYWxsYmFjayA9IG5ldyBDYWxsYmFjayAodGhpcywgIm1lbnVQcm9jIiwgMyk7CisJbWVudVByb2MgPSBtZW51Q2FsbGJhY2suZ2V0QWRkcmVzcyAoKTsKKwlpZiAobWVudVByb2MgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19NT1JFX0NBTExCQUNLUyk7CisJbW91c2VIb3ZlckNhbGxiYWNrID0gbmV3IENhbGxiYWNrICh0aGlzLCAibW91c2VIb3ZlclByb2MiLCAyKTsKKwltb3VzZUhvdmVyUHJvYyA9IG1vdXNlSG92ZXJDYWxsYmFjay5nZXRBZGRyZXNzICgpOworCWlmIChtb3VzZUhvdmVyUHJvYyA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX01PUkVfQ0FMTEJBQ0tTKTsKKwltb3VzZUNhbGxiYWNrID0gbmV3IENhbGxiYWNrICh0aGlzLCAibW91c2VQcm9jIiwgMyk7CisJbW91c2VQcm9jID0gbW91c2VDYWxsYmFjay5nZXRBZGRyZXNzICgpOworCWlmIChtb3VzZVByb2MgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19NT1JFX0NBTExCQUNLUyk7CisJdGltZXJDYWxsYmFjayA9IG5ldyBDYWxsYmFjayAodGhpcywgInRpbWVyUHJvYyIsIDIpOworCXRpbWVyUHJvYyA9IHRpbWVyQ2FsbGJhY2suZ2V0QWRkcmVzcyAoKTsKKwlpZiAodGltZXJQcm9jID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fTU9SRV9DQUxMQkFDS1MpOworCXRyYWNraW5nQ2FsbGJhY2sgPSBuZXcgQ2FsbGJhY2sgKHRoaXMsICJ0cmFja2luZ1Byb2MiLCA2KTsKKwl0cmFja2luZ1Byb2MgPSB0cmFja2luZ0NhbGxiYWNrLmdldEFkZHJlc3MgKCk7CisJaWYgKHRyYWNraW5nUHJvYyA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX01PUkVfQ0FMTEJBQ0tTKTsKKwl3aW5kb3dDYWxsYmFjayA9IG5ldyBDYWxsYmFjayAodGhpcywgIndpbmRvd1Byb2MiLCAzKTsKKwl3aW5kb3dQcm9jID0gd2luZG93Q2FsbGJhY2suZ2V0QWRkcmVzcyAoKTsKKwlpZiAod2luZG93UHJvYyA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX01PUkVfQ0FMTEJBQ0tTKTsKKwkJCisJLyogSW5zdGFsbCBFdmVudCBIYW5kbGVycyAqLworCWludFtdIG1hc2sxID0gbmV3IGludFtdIHsKIAkJT1Mua0V2ZW50Q2xhc3NDb21tYW5kLCBPUy5rRXZlbnRQcm9jZXNzQ29tbWFuZCwKLQkJCi0JCS8vT1Mua0V2ZW50Q2xhc3NBcHBsZUV2ZW50LCBPUy5rQUVRdWl0QXBwbGljYXRpb24sCi0JCU9TLmtFdmVudENsYXNzQXBwbGVFdmVudCwgT1Mua0V2ZW50QXBwbGVFdmVudCwKLQkJCi0JCS8vIHdlIHRyYWNrIGRvd24gZXZlbnRzIGhlcmUgYmVjYXVzZSB3ZSBuZWVkIHRvIGtub3cgd2hlbiB0aGUgdXNlciAKLQkJLy8gY2xpY2tlZCBpbiB0aGUgbWVudSBiYXIKLQkJT1Mua0V2ZW50Q2xhc3NNb3VzZSwgT1Mua0V2ZW50TW91c2VEb3duLAotCQkvLyB3ZSB0cmFjayB1cCwgZHJhZ2dlZCwgYW5kIG1vdmVkIGV2ZW50cyBiZWNhdXNlCi0JCS8vIHdlIG5lZWQgdG8gZ2V0IHRoZXNlIGV2ZW50cyBldmVuIGlmIHRoZSBtb3VzZSBpcyBvdXRzaWRlIG9mIHRoZSB3aW5kb3cuCi0JCU9TLmtFdmVudENsYXNzTW91c2UsIE9TLmtFdmVudE1vdXNlRHJhZ2dlZCwKLQkJT1Mua0V2ZW50Q2xhc3NNb3VzZSwgT1Mua0V2ZW50TW91c2VVcCwKLQkJT1Mua0V2ZW50Q2xhc3NNb3VzZSwgT1Mua0V2ZW50TW91c2VNb3ZlZCwKLQkJCQotCQlTV1RfVVNFUl9FVkVOVCwgNTQzMjEsCi0JCVNXVF9VU0VSX0VWRU5ULCA1NDMyMiwKIAl9OwotCWlmIChPUy5JbnN0YWxsRXZlbnRIYW5kbGVyKE9TLkdldEFwcGxpY2F0aW9uRXZlbnRUYXJnZXQoKSwgZkFwcGxpY2F0aW9uUHJvYywgbWFzaywgMCkgIT0gT1Mua05vRXJyKQotCQllcnJvciAoU1dULkVSUk9SX05PX01PUkVfQ0FMTEJBQ0tTKTsKLQkKLQkKLQlpbnQgdGV4dElucHV0UHJvYz0gY3JlYXRlQ2FsbGJhY2soImhhbmRsZVRleHRDYWxsYmFjayIsIDMpOwotCW1hc2s9IG5ldyBpbnRbXSB7CisJaW50IGFwcFRhcmdldCA9IE9TLkdldEFwcGxpY2F0aW9uRXZlbnRUYXJnZXQgKCk7CisJT1MuSW5zdGFsbEV2ZW50SGFuZGxlciAoYXBwVGFyZ2V0LCBjb21tYW5kUHJvYywgbWFzazEubGVuZ3RoIC8gMiwgbWFzazEsIDAsIG51bGwpOworCWludFtdIG1hc2syID0gbmV3IGludFtdIHsKKwkJT1Mua0V2ZW50Q2xhc3NNb3VzZSwgT1Mua0V2ZW50TW91c2VEb3duLAorCQlPUy5rRXZlbnRDbGFzc01vdXNlLCBPUy5rRXZlbnRNb3VzZURyYWdnZWQsCisvLwkJT1Mua0V2ZW50Q2xhc3NNb3VzZSwgT1Mua0V2ZW50TW91c2VFbnRlcmVkLAorLy8JCU9TLmtFdmVudENsYXNzTW91c2UsIE9TLmtFdmVudE1vdXNlRXhpdGVkLAorCQlPUy5rRXZlbnRDbGFzc01vdXNlLCBPUy5rRXZlbnRNb3VzZU1vdmVkLAorCQlPUy5rRXZlbnRDbGFzc01vdXNlLCBPUy5rRXZlbnRNb3VzZVVwLAorCQlPUy5rRXZlbnRDbGFzc01vdXNlLCBPUy5rRXZlbnRNb3VzZVdoZWVsTW92ZWQsCisJfTsKKwlPUy5JbnN0YWxsRXZlbnRIYW5kbGVyIChhcHBUYXJnZXQsIG1vdXNlUHJvYywgbWFzazIubGVuZ3RoIC8gMiwgbWFzazIsIDAsIG51bGwpOworCWludCBbXSBtYXNrMyA9IG5ldyBpbnRbXSB7CiAJCU9TLmtFdmVudENsYXNzS2V5Ym9hcmQsIE9TLmtFdmVudFJhd0tleURvd24sCisJCU9TLmtFdmVudENsYXNzS2V5Ym9hcmQsIE9TLmtFdmVudFJhd0tleU1vZGlmaWVyc0NoYW5nZWQsCiAJCU9TLmtFdmVudENsYXNzS2V5Ym9hcmQsIE9TLmtFdmVudFJhd0tleVJlcGVhdCwKIAkJT1Mua0V2ZW50Q2xhc3NLZXlib2FyZCwgT1Mua0V2ZW50UmF3S2V5VXAsCiAJfTsKLQlpZiAoT1MuSW5zdGFsbEV2ZW50SGFuZGxlcihPUy5HZXRVc2VyRm9jdXNFdmVudFRhcmdldCgpLCB0ZXh0SW5wdXRQcm9jLCBtYXNrLCAwKSAhPSBPUy5rTm9FcnIpCi0JCWVycm9yIChTV1QuRVJST1JfTk9fTU9SRV9DQUxMQkFDS1MpOwotCQotCQotCWJ1dHRvbkZvbnQgPSBGb250LmNhcmJvbl9uZXcgKHRoaXMsIGdldFRoZW1lRm9udChPUy5rVGhlbWVTbWFsbFN5c3RlbUZvbnQpKTsKLQlidXR0b25TaGFkb3dUaGlja25lc3M9IDE7Ci0KLQkvL3Njcm9sbGVkSW5zZXRYID0gc2Nyb2xsZWRJbnNldFkgPSAxNTsKLQlzY3JvbGxlZE1hcmdpblg9IHNjcm9sbGVkTWFyZ2luWT0gMTU7Ci0JY29tcG9zaXRlRm9yZWdyb3VuZCA9IDB4MDAwMDAwOwotCWNvbXBvc2l0ZUJhY2tncm91bmQgPSAtMTsgLy8gMHhFRUVFRUU7Ci0JCi0JZ3JvdXBGb250ID0gRm9udC5jYXJib25fbmV3ICh0aGlzLCBnZXRUaGVtZUZvbnQoT1Mua1RoZW1lU21hbGxFbXBoYXNpemVkU3lzdGVtRm9udCkpOwotCQotCWRpYWxvZ0ZvcmVncm91bmQ9IDB4MDAwMDAwOwotCWRpYWxvZ0JhY2tncm91bmQ9IDB4ZmZmZmZmOwotCQotCWxhYmVsRm9yZWdyb3VuZCA9IDB4MDAwMDAwOwotCWxhYmVsQmFja2dyb3VuZCA9IC0xOyAKLQlsYWJlbEZvbnQgPSBGb250LmNhcmJvbl9uZXcgKHRoaXMsIGdldFRoZW1lRm9udChPUy5rVGhlbWVTbWFsbFN5c3RlbUZvbnQpKTsKLQkKLQlsaXN0Rm9yZWdyb3VuZCA9IDB4MDAwMDAwOwotCWxpc3RCYWNrZ3JvdW5kID0gMHhmZmZmZmY7Ci0JbGlzdFNlbGVjdCA9IGxpc3RGb3JlZ3JvdW5kOwkvLyBpZiByZXZlcnNlZCBjb2xvcnMKLQlsaXN0Rm9udD0gRm9udC5jYXJib25fbmV3ICh0aGlzLCBuZXcgTWFjRm9udCgoc2hvcnQpMSkpOyAvLyBNYWMgQXBwbCBGb250Ci0KLQlzY3JvbGxCYXJGb3JlZ3JvdW5kID0gMHgwMDAwMDA7Ci0Jc2Nyb2xsQmFyQmFja2dyb3VuZCA9IDB4ZmZmZmZmOwotCi0JdGV4dEZvcmVncm91bmQgPSAweDAwMDAwMDsKLQl0ZXh0QmFja2dyb3VuZCA9IDB4ZmZmZmZmOwotCXRleHRIaWdobGlnaHRUaGlja25lc3MgPSAxOyAvLyA/Pz8KLQl0ZXh0Rm9udD0gRm9udC5jYXJib25fbmV3ICh0aGlzLCBuZXcgTWFjRm9udCgoc2hvcnQpMSkpOwkvLyBNYWMgQXBwbCBGb250Ci0KLQlDT0xPUl9XSURHRVRfREFSS19TSEFET1cgPSAJCUNvbG9yLmNhcmJvbl9uZXcodGhpcywgMHgzMzMzMzMsIHRydWUpOwkKLQlDT0xPUl9XSURHRVRfTk9STUFMX1NIQURPVyA9IAlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4NjY2NjY2LCB0cnVlKTsJCi0JQ09MT1JfV0lER0VUX0xJR0hUX1NIQURPVyA9IAlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4OTk5OTk5LCB0cnVlKTsKLQlDT0xPUl9XSURHRVRfSElHSExJR0hUX1NIQURPVyA9IENvbG9yLmNhcmJvbl9uZXcodGhpcywgMHhDQ0NDQ0MsIHRydWUpOwkKLQlDT0xPUl9XSURHRVRfQkFDS0dST1VORCA9IAkJQ29sb3IuY2FyYm9uX25ldyh0aGlzLCAweEZGRkZGRiwgdHJ1ZSk7CQotCUNPTE9SX1dJREdFVF9CT1JERVIgPSAJCQlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4MDAwMDAwLCB0cnVlKTsJCi0JQ09MT1JfTElTVF9GT1JFR1JPVU5EID0gCQlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4MDAwMDAwLCB0cnVlKTsJCi0JQ09MT1JfTElTVF9CQUNLR1JPVU5EID0gCQlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4RkZGRkZGLCB0cnVlKTsJCi0JQ09MT1JfTElTVF9TRUxFQ1RJT04gPSAJCQlDb2xvci5jYXJib25fbmV3KHRoaXMsIDB4NjY2NkNDLCB0cnVlKTsKLQlDT0xPUl9MSVNUX1NFTEVDVElPTl9URVhUID0gCUNvbG9yLmNhcmJvbl9uZXcodGhpcywgMHhGRkZGRkYsIHRydWUpOwotCUNPTE9SX0lORk9fQkFDS0dST1VORCA9IAkJQ29sb3IuY2FyYm9uX25ldyh0aGlzLCAweEZGRkZFMSwgdHJ1ZSk7Ci0JCi0JZkhvdmVyVGhlbWVGb250PSBPUy5rVGhlbWVTbWFsbFN5c3RlbUZvbnQ7Ci0KLQlkZWZhdWx0Rm9udCA9IEZvbnQuY2FyYm9uX25ldyAodGhpcywgZ2V0VGhlbWVGb250KE9TLmtUaGVtZVNtYWxsU3lzdGVtRm9udCkpOwotCQotCWRlZmF1bHRGb3JlZ3JvdW5kID0gY29tcG9zaXRlRm9yZWdyb3VuZDsKLQlkZWZhdWx0QmFja2dyb3VuZCA9IGNvbXBvc2l0ZUJhY2tncm91bmQ7CisJaW50IGZvY3VzVGFyZ2V0ID0gT1MuR2V0VXNlckZvY3VzRXZlbnRUYXJnZXQgKCk7CisJT1MuSW5zdGFsbEV2ZW50SGFuZGxlciAoZm9jdXNUYXJnZXQsIGtleWJvYXJkUHJvYywgbWFzazMubGVuZ3RoIC8gMiwgbWFzazMsIDAsIG51bGwpOwogfQotLyoqCSAKLSAqIEludm9rZXMgcGxhdGZvcm0gc3BlY2lmaWMgZnVuY3Rpb25hbGl0eSB0byBhbGxvY2F0ZSBhIG5ldyBHQyBoYW5kbGUuCi0gKiA8cD4KLSAqIDxiPklNUE9SVEFOVDo8L2I+IFRoaXMgbWV0aG9kIGlzIDxlbT5ub3Q8L2VtPiBwYXJ0IG9mIHRoZSBwdWJsaWMKLSAqIEFQSSBmb3IgPGNvZGU+RGlzcGxheTwvY29kZT4uIEl0IGlzIG1hcmtlZCBwdWJsaWMgb25seSBzbyB0aGF0IGl0Ci0gKiBjYW4gYmUgc2hhcmVkIHdpdGhpbiB0aGUgcGFja2FnZXMgcHJvdmlkZWQgYnkgU1dULiBJdCBpcyBub3QKLSAqIGF2YWlsYWJsZSBvbiBhbGwgcGxhdGZvcm1zLCBhbmQgc2hvdWxkIG5ldmVyIGJlIGNhbGxlZCBmcm9tCi0gKiBhcHBsaWNhdGlvbiBjb2RlLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBkYXRhIHRoZSBwbGF0Zm9ybSBzcGVjaWZpYyBHQyBkYXRhIAotICogQHJldHVybiB0aGUgcGxhdGZvcm0gc3BlY2lmaWMgR0MgaGFuZGxlCi0gKgotICogQHByaXZhdGUKLSAqLworCit2b2lkIGluaXRpYWxpemVJbnNldHMgKCkgeworCWludCBbXSBvdXRDb250cm9sID0gbmV3IGludCBbMV07CisJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisJcmVjdC5yaWdodCA9IHJlY3QuYm90dG9tID0gKHNob3J0KSAyMDA7CisJCisJT1MuQ3JlYXRlUHVzaEJ1dHRvbkNvbnRyb2wgKDAsIHJlY3QsIDAsIG91dENvbnRyb2wpOworCWJ1dHRvbkluc2V0ID0gY29tcHV0ZUluc2V0IChvdXRDb250cm9sIFswXSk7CisJT1MuRGlzcG9zZUNvbnRyb2wgKG91dENvbnRyb2wgWzBdKTsKKwkKKwlPUy5DcmVhdGVUYWJzQ29udHJvbCAoMCwgcmVjdCwgKHNob3J0KU9TLmtDb250cm9sVGFiU2l6ZUxhcmdlLCAoc2hvcnQpT1Mua0NvbnRyb2xUYWJEaXJlY3Rpb25Ob3J0aCwgKHNob3J0KSAwLCAwLCBvdXRDb250cm9sKTsKKwl0YWJGb2xkZXJJbnNldCA9IGNvbXB1dGVJbnNldCAob3V0Q29udHJvbCBbMF0pOworCU9TLkRpc3Bvc2VDb250cm9sIChvdXRDb250cm9sIFswXSk7CisKKwlDR1JlY3QgY2dSZWN0ID0gbmV3IENHUmVjdCAoKTsKKwljZ1JlY3Qud2lkdGggPSBjZ1JlY3QuaGVpZ2h0ID0gMjAwOworCWludCBpbkF0dHJpYnV0ZXMgPSBPUy5rSElDb21ib0JveEF1dG9Db21wbGV0aW9uQXR0cmlidXRlIHwgT1Mua0hJQ29tYm9Cb3hBdXRvU2l6ZUxpc3RBdHRyaWJ1dGU7CisJT1MuSElDb21ib0JveENyZWF0ZSAoY2dSZWN0LCAwLCBudWxsLCAwLCBpbkF0dHJpYnV0ZXMsIG91dENvbnRyb2wpOworCWNvbWJvSW5zZXQgPSBjb21wdXRlSW5zZXQgKG91dENvbnRyb2wgWzBdKTsKKwkgLy9GSVhNRSAtIAorCWNvbWJvSW5zZXQuYm90dG9tID0gY29tYm9JbnNldC50b3A7CisJT1MuRGlzcG9zZUNvbnRyb2wgKG91dENvbnRyb2wgWzBdKTsKK30KKwogcHVibGljIGludCBpbnRlcm5hbF9uZXdfR0MgKEdDRGF0YSBkYXRhKSB7CiAJaWYgKGlzRGlzcG9zZWQoKSkgU1dULmVycm9yKFNXVC5FUlJPUl9ERVZJQ0VfRElTUE9TRUQpOwotCS8qIEFXCi0JaW50IHhEcmF3YWJsZSA9IE9TLlhEZWZhdWx0Um9vdFdpbmRvdyAoeERpc3BsYXkpOwotCWludCB4R0MgPSBPUy5YQ3JlYXRlR0MgKHhEaXNwbGF5LCB4RHJhd2FibGUsIDAsIG51bGwpOwotCWlmICh4R0MgPT0gMCkgU1dULmVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JT1MuWFNldFN1YndpbmRvd01vZGUgKHhEaXNwbGF5LCB4R0MsIE9TLkluY2x1ZGVJbmZlcmlvcnMpOworCS8vIE5FRURTIFdPUksKKwlpbnQgd2luZG93ID0gT1MuRnJvbnRXaW5kb3cgKCk7CisJaW50IHBvcnQgPSBPUy5HZXRXaW5kb3dQb3J0ICh3aW5kb3cpOworCWludCBbXSBidWZmZXIgPSBuZXcgaW50IFsxXTsKKwlPUy5DcmVhdGVDR0NvbnRleHRGb3JQb3J0IChwb3J0LCBidWZmZXIpOworCWludCBjb250ZXh0ID0gYnVmZmVyIFswXTsKKwlpZiAoY29udGV4dCA9PSAwKSBTV1QuZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKIAlpZiAoZGF0YSAhPSBudWxsKSB7CiAJCWRhdGEuZGV2aWNlID0gdGhpczsKLQkJZGF0YS5kaXNwbGF5ID0geERpc3BsYXk7Ci0JCWRhdGEuZHJhd2FibGUgPSB4RHJhd2FibGU7Ci0JCWRhdGEuZm9udExpc3QgPSBkZWZhdWx0Rm9udDsKLQkJZGF0YS5jb2xvcm1hcCA9IE9TLlhEZWZhdWx0Q29sb3JtYXAgKHhEaXNwbGF5LCBPUy5YRGVmYXVsdFNjcmVlbiAoeERpc3BsYXkpKTsKKwkJZGF0YS5iYWNrZ3JvdW5kID0gZ2V0U3lzdGVtQ29sb3IgKFNXVC5DT0xPUl9XSElURSkuaGFuZGxlOworCQlkYXRhLmZvcmVncm91bmQgPSBnZXRTeXN0ZW1Db2xvciAoU1dULkNPTE9SX0JMQUNLKS5oYW5kbGU7CisJCWRhdGEuZm9udCA9IGdldFN5c3RlbUZvbnQgKCk7CiAJfQotCXJldHVybiB4R0M7Ci0JKi8KKwlyZXR1cm4gY29udGV4dDsKK30KIAotCWlmIChkYXRhICE9IG51bGwpIHsKLQkJZGF0YS5kZXZpY2UgPSB0aGlzOwotCQkvKiBBVwotCQlkYXRhLmRpc3BsYXkgPSB4RGlzcGxheTsKLQkJZGF0YS5kcmF3YWJsZSA9IHhXaW5kb3c7Ci0JCWRhdGEuZm9yZWdyb3VuZCA9IGFyZ0xpc3QgWzFdOwotCQlkYXRhLmJhY2tncm91bmQgPSBhcmdMaXN0IFszXTsKLQkJZGF0YS5mb250TGlzdCA9IGZvbnRMaXN0OwotCQlkYXRhLmNvbG9ybWFwID0gYXJnTGlzdCBbNV07Ci0JCSovCi0JCWRhdGEuZm9yZWdyb3VuZCA9IDB4MDAwMDAwOwotCQlkYXRhLmJhY2tncm91bmQgPSAweGZmZmZmZjsKLQkJZGF0YS5mb250ID0gbmV3IE1hY0ZvbnQoKHNob3J0KTEpOwotCQlkYXRhLmNvbnRyb2xIYW5kbGUgPSAwOwotCX0KK3B1YmxpYyB2b2lkIGludGVybmFsX2Rpc3Bvc2VfR0MgKGludCBjb250ZXh0LCBHQ0RhdGEgZGF0YSkgeworCWlmIChpc0Rpc3Bvc2VkKCkpIFNXVC5lcnJvcihTV1QuRVJST1JfREVWSUNFX0RJU1BPU0VEKTsKKwkvLyBORUVEUyBXT1JLCisJT1MuQ0dDb250ZXh0Rmx1c2ggKGNvbnRleHQpOworCU9TLkNHQ29udGV4dFJlbGVhc2UgKGNvbnRleHQpOworfQogCi0JaW50IHdIYW5kbGU9IE9TLkZyb250V2luZG93KCk7Ci0JaW50IHhHQz0gT1MuR2V0V2luZG93UG9ydCh3SGFuZGxlKTsKLQlpZiAoeEdDID09IDApIFNXVC5lcnJvcihTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JCi0gICAgcmV0dXJuIHhHQzsKLX0KLS8qKgkgCi0gKiBJbnZva2VzIHBsYXRmb3JtIHNwZWNpZmljIGZ1bmN0aW9uYWxpdHkgdG8gZGlzcG9zZSBhIEdDIGhhbmRsZS4KLSAqIDxwPgotICogPGI+SU1QT1JUQU5UOjwvYj4gVGhpcyBtZXRob2QgaXMgPGVtPm5vdDwvZW0+IHBhcnQgb2YgdGhlIHB1YmxpYwotICogQVBJIGZvciA8Y29kZT5EaXNwbGF5PC9jb2RlPi4gSXQgaXMgbWFya2VkIHB1YmxpYyBvbmx5IHNvIHRoYXQgaXQKLSAqIGNhbiBiZSBzaGFyZWQgd2l0aGluIHRoZSBwYWNrYWdlcyBwcm92aWRlZCBieSBTV1QuIEl0IGlzIG5vdAotICogYXZhaWxhYmxlIG9uIGFsbCBwbGF0Zm9ybXMsIGFuZCBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkIGZyb20KLSAqIGFwcGxpY2F0aW9uIGNvZGUuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIGhhbmRsZSB0aGUgcGxhdGZvcm0gc3BlY2lmaWMgR0MgaGFuZGxlCi0gKiBAcGFyYW0gZGF0YSB0aGUgcGxhdGZvcm0gc3BlY2lmaWMgR0MgZGF0YSAKLSAqCi0gKiBAcHJpdmF0ZQotICovCi1wdWJsaWMgdm9pZCBpbnRlcm5hbF9kaXNwb3NlX0dDIChpbnQgZ2MsIEdDRGF0YSBkYXRhKSB7Ci19Ci1ib29sZWFuIGlzVmFsaWRUaHJlYWQgKCkgewotCXJldHVybiB0aHJlYWQgPT0gVGhyZWFkLmN1cnJlbnRUaHJlYWQgKCk7Ci19CiBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkQ2xhc3MgKENsYXNzIGNsYXp6KSB7CiAJU3RyaW5nIG5hbWUgPSBjbGF6ei5nZXROYW1lICgpOwogCWludCBpbmRleCA9IG5hbWUubGFzdEluZGV4T2YgKCcuJyk7CiAJcmV0dXJuIG5hbWUuc3Vic3RyaW5nICgwLCBpbmRleCArIDEpLmVxdWFscyAoUEFDS0FHRV9QUkVGSVgpOwogfQotaW50IG1vdXNlSG92ZXJQcm9jIChpbnQgaWQsIGludCBoYW5kbGUpIHsKLQlpZiAobW91c2VIb3ZlcklEICE9IDApIE9TLlJlbW92ZUV2ZW50TG9vcFRpbWVyKG1vdXNlSG92ZXJJRCk7Ci0JbW91c2VIb3ZlcklEID0gbW91c2VIb3ZlckhhbmRsZSA9IDA7Ci0JaW50IHJjPSB3aW5kb3dQcm9jIChoYW5kbGUsIFNXVC5Nb3VzZUhvdmVyLCBuZXcgTWFjTW91c2VFdmVudCgpKTsKLQlzZW5kVXNlckV2ZW50KDU0MzIxKTsKLQlyZXR1cm4gcmM7CisKK2Jvb2xlYW4gaXNWYWxpZFRocmVhZCAoKSB7CisJcmV0dXJuIHRocmVhZCA9PSBUaHJlYWQuY3VycmVudFRocmVhZCAoKTsKIH0KKworaW50IGl0ZW1EYXRhUHJvYyAoaW50IGJyb3dzZXIsIGludCBpdGVtLCBpbnQgcHJvcGVydHksIGludCBpdGVtRGF0YSwgaW50IHNldFZhbHVlKSB7CisJV2lkZ2V0IHdpZGdldCA9IFdpZGdldFRhYmxlLmdldCAoYnJvd3Nlcik7CisJaWYgKHdpZGdldCAhPSBudWxsKSByZXR1cm4gd2lkZ2V0Lml0ZW1EYXRhUHJvYyAoYnJvd3NlciwgaXRlbSwgcHJvcGVydHksIGl0ZW1EYXRhLCBzZXRWYWx1ZSk7CisJcmV0dXJuIE9TLm5vRXJyOworfQorCitpbnQgaXRlbU5vdGlmaWNhdGlvblByb2MgKGludCBicm93c2VyLCBpbnQgaXRlbSwgaW50IG1lc3NhZ2UpIHsKKwlXaWRnZXQgd2lkZ2V0ID0gV2lkZ2V0VGFibGUuZ2V0IChicm93c2VyKTsKKwlpZiAod2lkZ2V0ICE9IG51bGwpIHJldHVybiB3aWRnZXQuaXRlbU5vdGlmaWNhdGlvblByb2MgKGJyb3dzZXIsIGl0ZW0sIG1lc3NhZ2UpOworCXJldHVybiBPUy5ub0VycjsKK30KKworaW50IGtleWJvYXJkUHJvYyAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKHVzZXJEYXRhKTsKKwlpZiAod2lkZ2V0ID09IG51bGwpIHsKKwkJaW50IHRoZVdpbmRvdyA9IE9TLkFjdGl2ZU5vbkZsb2F0aW5nV2luZG93ICgpOworCQlpZiAodGhlV2luZG93ID09IDApIHJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7CisJCWludCBbXSB0aGVDb250cm9sID0gbmV3IGludCBbMV07CisJCU9TLkdldEtleWJvYXJkRm9jdXMgKHRoZVdpbmRvdywgdGhlQ29udHJvbCk7CisJCWlmICh0aGVDb250cm9sIFswXSA9PSAwKSB7CisJCQlPUy5HZXRSb290Q29udHJvbCAodGhlV2luZG93LCB0aGVDb250cm9sKTsKKwkJfQorCQl3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKHRoZUNvbnRyb2wgWzBdKTsKKwl9CisJaWYgKHdpZGdldCAhPSBudWxsKSByZXR1cm4gd2lkZ2V0LmtleWJvYXJkUHJvYyAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKwogdm9pZCBwb3N0RXZlbnQgKEV2ZW50IGV2ZW50KSB7CiAJLyoKIAkqIFBsYWNlIHRoZSBldmVudCBhdCB0aGUgZW5kIG9mIHRoZSBldmVudCBxdWV1ZS4KQEAgLTEwNzcsNjAgKzg3NSwxMjcgQEAKIAl9CiAJZXZlbnRRdWV1ZSBbaW5kZXhdID0gZXZlbnQ7CiB9Ci0vKioKLSAqIFJlYWRzIGFuIGV2ZW50IGZyb20gdGhlIG9wZXJhdGluZyBzeXN0ZW0ncyBldmVudCBxdWV1ZSwKLSAqIGRpc3BhdGNoZXMgaXQgYXBwcm9wcmlhdGVseSwgYW5kIHJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4KLSAqIGlmIHRoZXJlIGlzIHBvdGVudGlhbGx5IG1vcmUgd29yayB0byBkbywgb3IgPGNvZGU+ZmFsc2U8L2NvZGU+Ci0gKiBpZiB0aGUgY2FsbGVyIGNhbiBzbGVlcCB1bnRpbCBhbm90aGVyIGV2ZW50IGlzIHBsYWNlZCBvbgotICogdGhlIGV2ZW50IHF1ZXVlLgotICogPHA+Ci0gKiBJbiBhZGRpdGlvbiB0byBjaGVja2luZyB0aGUgc3lzdGVtIGV2ZW50IHF1ZXVlLCB0aGlzIG1ldGhvZCBhbHNvCi0gKiBjaGVja3MgaWYgYW55IGludGVyLXRocmVhZCBtZXNzYWdlcyAoY3JlYXRlZCBieSA8Y29kZT5zeW5jRXhlYygpPC9jb2RlPgotICogb3IgPGNvZGU+YXN5bmNFeGVjKCk8L2NvZGU+KSBhcmUgd2FpdGluZyB0byBiZSBwcm9jZXNzZWQsIGFuZCBpZgotICogc28gaGFuZGxlcyB0aGVtIGJlZm9yZSByZXR1cm5pbmcuCi0gKiA8L3A+Ci0gKgotICogQHJldHVybiA8Y29kZT5mYWxzZTwvY29kZT4gaWYgdGhlIGNhbGxlciBjYW4gc2xlZXAgdXBvbiByZXR1cm4gZnJvbSB0aGlzIG1ldGhvZAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjc2xlZXAKLSAqIEBzZWUgI3dha2UKLSAqLwotcHVibGljIGJvb2xlYW4gcmVhZEFuZERpc3BhdGNoICgpIHsKLQljaGVja0RldmljZSAoKTsKLQotCWlmICghZmdJbml0Q3Vyc29yQ2FsbGVkKSB7Ci0JCU9TLkluaXRDdXJzb3IoKTsKLQkJZmdJbml0Q3Vyc29yQ2FsbGVkPSB0cnVlOworCQoraW50IG1lbnVQcm9jIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaWYgKHVzZXJEYXRhICE9IDApIHsKKwkJV2lkZ2V0IHdpZGdldCA9IFdpZGdldFRhYmxlLmdldCAodXNlckRhdGEpOworCQlpZiAod2lkZ2V0ICE9IG51bGwpIHJldHVybiB3aWRnZXQubWVudVByb2MgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCX0gZWxzZSB7CisJCWludCBbXSB0aGVNZW51ID0gbmV3IGludCBbMV07CisJCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1EaXJlY3RPYmplY3QsIE9TLnR5cGVNZW51UmVmLCBudWxsLCA0LCBudWxsLCB0aGVNZW51KTsKKwkJc2hvcnQgbWVudUlEID0gT1MuR2V0TWVudUlEICh0aGVNZW51IFswXSk7CisJCU1lbnUgbWVudSA9IGZpbmRNZW51IChtZW51SUQpOworCQlpZiAobWVudSAhPSBudWxsKSByZXR1cm4gbWVudS5tZW51UHJvYyAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CiAJfQorCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CiAKLQlpbnRbXSBldnQ9IG5ldyBpbnRbMV07Ci0JaW50IHJjPSBPUy5SZWNlaXZlTmV4dEV2ZW50KG51bGwsIE9TLmtFdmVudER1cmF0aW9uTm9XYWl0LCB0cnVlLCBldnQpOwotCi0Jc3dpdGNoIChyYykgewotCWNhc2UgT1Mua05vRXJyOgotCQlpbnQgZXZlbnQ9IGV2dFswXTsKLQkJaWYgKE9TLkdldEV2ZW50Q2xhc3MoZXZlbnQpID09IFNXVF9VU0VSX0VWRU5UICYmIE9TLkdldEV2ZW50S2luZChldmVudCkgPT0gNTQzMjIpIHsKLQkJCU9TLlJlbGVhc2VFdmVudChldmVudCk7CitpbnQgbW91c2VQcm9jIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IGV2ZW50S2luZCA9IE9TLkdldEV2ZW50S2luZCAodGhlRXZlbnQpOworCW9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgd2hlcmUgPSBuZXcgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCAoKTsKKwlPUy5HZXRFdmVudFBhcmFtZXRlciAodGhlRXZlbnQsIE9TLmtFdmVudFBhcmFtTW91c2VMb2NhdGlvbiwgT1MudHlwZVFEUG9pbnQsIG51bGwsIHdoZXJlLnNpemVvZiwgbnVsbCwgd2hlcmUpOworCWludCBbXSB0aGVXaW5kb3cgPSBuZXcgaW50IFsxXTsKKwlpbnQgcGFydCA9IE9TLkZpbmRXaW5kb3cgKHdoZXJlLCB0aGVXaW5kb3cpOworCXN3aXRjaCAocGFydCkgeworCQljYXNlIE9TLmluTWVudUJhcjogeworCQkJaWYgKGV2ZW50S2luZCA9PSBPUy5rRXZlbnRNb3VzZURvd24pIHsKKwkJCQlPUy5NZW51U2VsZWN0ICh3aGVyZSk7CisJCQkJcmV0dXJuIE9TLm5vRXJyOworCQkJfQogCQkJYnJlYWs7CiAJCX0KLQkJT1MuU2VuZEV2ZW50VG9FdmVudFRhcmdldChldmVudCwgT1MuR2V0RXZlbnREaXNwYXRjaGVyVGFyZ2V0KCkpOwotCQlPUy5SZWxlYXNlRXZlbnQoZXZlbnQpOwotCQlydW5EZWZlcnJlZEV2ZW50cygpOworCQljYXNlIE9TLmluQ29udGVudDogeworCQkJUmVjdCB3aW5kb3dSZWN0ID0gbmV3IFJlY3QgKCk7CisJCQlPUy5HZXRXaW5kb3dCb3VuZHMgKHRoZVdpbmRvdyBbMF0sIChzaG9ydCkgT1Mua1dpbmRvd0NvbnRlbnRSZ24sIHdpbmRvd1JlY3QpOworCQkJQ0dQb2ludCBpblBvaW50ID0gbmV3IENHUG9pbnQgKCk7CisJCQlpblBvaW50LnggPSB3aGVyZS5oIC0gd2luZG93UmVjdC5sZWZ0OworCQkJaW5Qb2ludC55ID0gd2hlcmUudiAtIHdpbmRvd1JlY3QudG9wOworCQkJaW50IFtdIHRoZVJvb3QgPSBuZXcgaW50IFsxXTsKKwkJCU9TLkdldFJvb3RDb250cm9sICh0aGVXaW5kb3cgWzBdLCB0aGVSb290KTsKKwkJCWludCBbXSB0aGVDb250cm9sID0gbmV3IGludCBbMV07CisJCQlPUy5ISVZpZXdHZXRTdWJ2aWV3SGl0ICh0aGVSb290IFswXSwgaW5Qb2ludCwgdHJ1ZSwgdGhlQ29udHJvbCk7CisJCQlpZiAodGhlQ29udHJvbCBbMF0gPT0gMCkgdGhlQ29udHJvbCBbMF0gPSB0aGVSb290IFswXTsKKwkJCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKHRoZUNvbnRyb2wgWzBdKTsKKwkJCXN3aXRjaCAoZXZlbnRLaW5kKSB7CisJCQkJY2FzZSBPUy5rRXZlbnRNb3VzZURyYWdnZWQ6CisJCQkJY2FzZSBPUy5rRXZlbnRNb3VzZU1vdmVkOiB7CisJCQkJCW9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgbG9jYWxQb2ludCA9IG5ldyBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBvaW50ICgpOworCQkJCQlsb2NhbFBvaW50LmggPSAoc2hvcnQpIGluUG9pbnQueDsKKwkJCQkJbG9jYWxQb2ludC52ID0gKHNob3J0KSBpblBvaW50Lnk7CisJCQkJCWludCBbXSBtb2RpZmllcnMgPSBuZXcgaW50IFsxXTsKKwkJCQkJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbUtleU1vZGlmaWVycywgT1MudHlwZVVJbnQzMiwgbnVsbCwgNCwgbnVsbCwgbW9kaWZpZXJzKTsKKwkJCQkJYm9vbGVhbiBbXSBjdXJzb3JXYXNTZXQgPSBuZXcgYm9vbGVhbiBbMV07CisJCQkJCU9TLkhhbmRsZUNvbnRyb2xTZXRDdXJzb3IgKHRoZUNvbnRyb2wgWzBdLCBsb2NhbFBvaW50LCAoc2hvcnQpIG1vZGlmaWVycyBbMF0sIGN1cnNvcldhc1NldCk7CisJCQkJCWlmICghY3Vyc29yV2FzU2V0IFswXSkgT1MuU2V0VGhlbWVDdXJzb3IgKE9TLmtUaGVtZUFycm93Q3Vyc29yKTsKKwkJCQkJaWYgKHdpZGdldCAhPSBudWxsKSB7CisJCQkJCQlpZiAod2lkZ2V0ID09IGhvdmVyQ29udHJvbCkgeworCQkJCQkJCWludCBbXSBvdXREZWxheSA9IG5ldyBpbnQgWzFdOworCQkJCQkJCU9TLkhNR2V0VGFnRGVsYXkgKG91dERlbGF5KTsKKwkJCQkJCQlpZiAobW91c2VIb3ZlcklEICE9IDApIHsKKwkJCQkJCQkJT1MuU2V0RXZlbnRMb29wVGltZXJOZXh0RmlyZVRpbWUgKG1vdXNlSG92ZXJJRCwgb3V0RGVsYXkgWzBdIC8gMTAwMC4wKTsKKwkJCQkJCQl9CisJCQkJCQl9IGVsc2UgeworCQkJCQkJCS8vTk9UIERPTkUgLSBnZXQgcmlkIG9mIGluc3RhbmNlb2YgdGVzdAorCQkJCQkJCWlmICh3aWRnZXQgaW5zdGFuY2VvZiBDb250cm9sKSB7CisJCQkJCQkJCWlmIChtb3VzZUhvdmVySUQgIT0gMCkgT1MuUmVtb3ZlRXZlbnRMb29wVGltZXIgKG1vdXNlSG92ZXJJRCk7CisJCQkJCQkJCWhvdmVyQ29udHJvbCA9IChDb250cm9sKSB3aWRnZXQ7CisJCQkJCQkJCWludCBbXSBpZCA9IG5ldyBpbnQgWzFdLCBvdXREZWxheSA9IG5ldyBpbnQgWzFdOworCQkJCQkJCQlPUy5ITUdldFRhZ0RlbGF5IChvdXREZWxheSk7CisJCQkJCQkJCWludCBoYW5kbGUgPSBob3ZlckNvbnRyb2wuaGFuZGxlOworCQkJCQkJCQlpbnQgZXZlbnRMb29wID0gT1MuR2V0Q3VycmVudEV2ZW50TG9vcCAoKTsKKwkJCQkJCQkJT1MuSW5zdGFsbEV2ZW50TG9vcFRpbWVyIChldmVudExvb3AsIG91dERlbGF5IFswXSAvIDEwMDAuMCwgMC4wLCBtb3VzZUhvdmVyUHJvYywgaGFuZGxlLCBpZCk7CisJCQkJCQkJCWlmICgobW91c2VIb3ZlcklEID0gaWQgWzBdKSA9PSAwKSBob3ZlckNvbnRyb2wgPSBudWxsOworCQkJCQkJCX0KKwkJCQkJCX0KKwkJCQkJfQorCQkJCX0KKwkJCX0KKwkJCWlmICh3aWRnZXQgIT0gbnVsbCkgeworCQkJCXJldHVybiB1c2VyRGF0YSAhPSAwID8gd2lkZ2V0Lm1vdXNlUHJvYyAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSkgOiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7CisJCQl9CisJCQlicmVhazsKKwkJfQorCX0KKwlzd2l0Y2ggKGV2ZW50S2luZCkgeworCQljYXNlIE9TLmtFdmVudE1vdXNlRHJhZ2dlZDoKKwkJY2FzZSBPUy5rRXZlbnRNb3VzZU1vdmVkOgorCQkJT1MuSW5pdEN1cnNvciAoKTsKKwl9CisJaWYgKG1vdXNlSG92ZXJJRCAhPSAwKSBPUy5SZW1vdmVFdmVudExvb3BUaW1lciAobW91c2VIb3ZlcklEKTsKKwltb3VzZUhvdmVySUQgPSAwOworCWhvdmVyQ29udHJvbCA9IG51bGw7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKworaW50IG1vdXNlSG92ZXJQcm9jIChpbnQgaWQsIGludCBoYW5kbGUpIHsKKwlpZiAoaG92ZXJDb250cm9sID09IG51bGwpIHJldHVybiAwOworCWlmIChob3ZlckNvbnRyb2wuaGFuZGxlID09IGhhbmRsZSAmJiAhaG92ZXJDb250cm9sLmlzRGlzcG9zZWQgKCkpIHsKKwkJLy9PUFRJTUlaRSAtIHVzZSBPUyBjYWxscworCQlpbnQgY2hvcmQgPSBPUy5HZXRDdXJyZW50RXZlbnRCdXR0b25TdGF0ZSAoKTsKKwkJaW50IG1vZGlmaWVycyA9IE9TLkdldEN1cnJlbnRFdmVudEtleU1vZGlmaWVycyAoKTsKKwkJUG9pbnQgcHQgPSBob3ZlckNvbnRyb2wudG9Db250cm9sIChnZXRDdXJzb3JMb2NhdGlvbiAoKSk7CisJCWhvdmVyQ29udHJvbC5zZW5kTW91c2VFdmVudCAoU1dULk1vdXNlSG92ZXIsIChzaG9ydCkwLCBjaG9yZCwgKHNob3J0KXB0LngsIChzaG9ydClwdC55LCBtb2RpZmllcnMpOworCX0KKwlob3ZlckNvbnRyb2wgPSBudWxsOworCXJldHVybiAwOworfQorCitwdWJsaWMgYm9vbGVhbiByZWFkQW5kRGlzcGF0Y2ggKCkgeworCWNoZWNrRGV2aWNlICgpOworCXJ1bkVudGVyRXhpdCAoKTsKKwlpbnQgW10gb3V0RXZlbnQgPSBuZXcgaW50IFsxXTsKKwlpbnQgc3RhdHVzID0gT1MuUmVjZWl2ZU5leHRFdmVudCAoMCwgbnVsbCwgT1Mua0V2ZW50RHVyYXRpb25Ob1dhaXQsIHRydWUsIG91dEV2ZW50KTsKKwlpZiAoc3RhdHVzID09IE9TLm5vRXJyKSB7CisJCU9TLlNlbmRFdmVudFRvRXZlbnRUYXJnZXQgKG91dEV2ZW50IFswXSwgT1MuR2V0RXZlbnREaXNwYXRjaGVyVGFyZ2V0ICgpKTsKKwkJT1MuUmVsZWFzZUV2ZW50IChvdXRFdmVudCBbMF0pOworCQlydW5Qb3B1cHMgKCk7CisJCXJ1bkRlZmVycmVkRXZlbnRzICgpOworCQlydW5HcmFicyAoKTsKIAkJcmV0dXJuIHRydWU7Ci0KLQljYXNlIE9TLmV2ZW50TG9vcFRpbWVkT3V0RXJyOgotCQlicmVhazsKLQotCWRlZmF1bHQ6Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigicmVhZEFuZERpc3BhdGNoOiBlcnJvciAiICsgcmMpOwotCQlicmVhazsKIAl9CiAJcmV0dXJuIHJ1bkFzeW5jTWVzc2FnZXMgKCk7CiB9CisKIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCByZWdpc3RlciAoRGlzcGxheSBkaXNwbGF5KSB7CiAJZm9yIChpbnQgaT0wOyBpPERpc3BsYXlzLmxlbmd0aDsgaSsrKSB7CiAJCWlmIChEaXNwbGF5cyBbaV0gPT0gbnVsbCkgewpAQCAtMTE0Myw2ICsxMDA4LDcgQEAKIAluZXdEaXNwbGF5cyBbRGlzcGxheXMubGVuZ3RoXSA9IGRpc3BsYXk7CiAJRGlzcGxheXMgPSBuZXdEaXNwbGF5czsKIH0KKwogcHJvdGVjdGVkIHZvaWQgcmVsZWFzZSAoKSB7CiAJU2hlbGwgW10gc2hlbGxzID0gV2lkZ2V0VGFibGUuc2hlbGxzICgpOwogCWZvciAoaW50IGk9MDsgaTxzaGVsbHMubGVuZ3RoOyBpKyspIHsKQEAgLTExNjMsODAgKzEwMjksNTEgQEAKIAlyZWxlYXNlRGlzcGxheSAoKTsKIAlzdXBlci5yZWxlYXNlICgpOwogfQorCiB2b2lkIHJlbGVhc2VEaXNwbGF5ICgpIHsKLQkKLQkvKiBEaXNwb3NlIHRoZSBjYXJldCBjYWxsYmFjayAqLwotCS8qIEFXCi0JaWYgKGNhcmV0SUQgIT0gMCkgT1MuWHRSZW1vdmVUaW1lT3V0IChjYXJldElEKTsKLQkqLwotCWlmIChjYXJldElEICE9IDApIE9TLlJlbW92ZUV2ZW50TG9vcFRpbWVyKGNhcmV0SUQpOwotCWNhcmV0SUQgPSBjYXJldFByb2MgPSAwOwotCQotCS8qIERpc3Bvc2UgdGhlIHRpbWVyIGNhbGxiYWNrICovCi0JaWYgKHRpbWVySURzICE9IG51bGwpIHsKLQkJZm9yIChpbnQgaT0wOyBpPHRpbWVySURzLmxlbmd0aDsgaSsrKSB7Ci0JCQkvKiBBVwotCQkJaWYgKHRpbWVySURzIFtpXSAhPSAwKSBPUy5YdFJlbW92ZVRpbWVPdXQgKHRpbWVySURzIFtpXSk7Ci0JCQkqLwotCQkJaWYgKHRpbWVySURzIFtpXSAhPSAwKSBPUy5SZW1vdmVFdmVudExvb3BUaW1lciAodGltZXJJRHMgW2ldKTsKLQkJfQotCX0KLQl0aW1lcklEcyA9IG51bGw7Ci0JdGltZXJMaXN0ID0gbnVsbDsKKwlhY3Rpb25DYWxsYmFjay5kaXNwb3NlICgpOworCWNhcmV0Q2FsbGJhY2suZGlzcG9zZSAoKTsKKwljb21tYW5kQ2FsbGJhY2suZGlzcG9zZSAoKTsKKwljb250cm9sQ2FsbGJhY2suZGlzcG9zZSAoKTsKKwlkcmF3SXRlbUNhbGxiYWNrLmRpc3Bvc2UgKCk7CisJaXRlbURhdGFDYWxsYmFjay5kaXNwb3NlICgpOworCWl0ZW1Ob3RpZmljYXRpb25DYWxsYmFjay5kaXNwb3NlICgpOworCWhlbHBDYWxsYmFjay5kaXNwb3NlICgpOworCWhpdFRlc3RDYWxsYmFjay5kaXNwb3NlICgpOworCWtleWJvYXJkQ2FsbGJhY2suZGlzcG9zZSAoKTsKKwltZW51Q2FsbGJhY2suZGlzcG9zZSAoKTsKKwltb3VzZUhvdmVyQ2FsbGJhY2suZGlzcG9zZSAoKTsKKwltb3VzZUNhbGxiYWNrLmRpc3Bvc2UgKCk7CisJdHJhY2tpbmdDYWxsYmFjay5kaXNwb3NlICgpOworCXdpbmRvd0NhbGxiYWNrLmRpc3Bvc2UgKCk7CisJYWN0aW9uQ2FsbGJhY2sgPSBjYXJldENhbGxiYWNrID0gY29tbWFuZENhbGxiYWNrID0gbnVsbDsKKwljb250cm9sQ2FsbGJhY2sgPSBkcmF3SXRlbUNhbGxiYWNrID0gaXRlbURhdGFDYWxsYmFjayA9IGl0ZW1Ob3RpZmljYXRpb25DYWxsYmFjayA9IG51bGw7CisJaGVscENhbGxiYWNrID0gaGl0VGVzdENhbGxiYWNrID0ga2V5Ym9hcmRDYWxsYmFjayA9IG1lbnVDYWxsYmFjayA9IG51bGw7CisJbW91c2VIb3ZlckNhbGxiYWNrID0gbW91c2VDYWxsYmFjayA9IHRyYWNraW5nQ2FsbGJhY2sgPSB3aW5kb3dDYWxsYmFjayA9IG51bGw7CisJYWN0aW9uUHJvYyA9IGNhcmV0UHJvYyA9IGNvbW1hbmRQcm9jID0gMDsKKwljb250cm9sUHJvYyA9IGRyYXdJdGVtUHJvYyA9IGl0ZW1EYXRhUHJvYyA9IGl0ZW1Ob3RpZmljYXRpb25Qcm9jID0gMDsKKwloZWxwUHJvYyA9IGhpdFRlc3RQcm9jID0ga2V5Ym9hcmRQcm9jID0gbWVudVByb2MgPSAwOworCW1vdXNlSG92ZXJQcm9jID0gbW91c2VQcm9jID0gdHJhY2tpbmdQcm9jID0gd2luZG93UHJvYyA9IDA7CisJdGltZXJDYWxsYmFjay5kaXNwb3NlICgpOworCXRpbWVyQ2FsbGJhY2sgPSBudWxsOwogCXRpbWVyUHJvYyA9IDA7CisJZ3JhYkNvbnRyb2wgPSBoZWxwQ29udHJvbCA9IGN1cnJlbnRDb250cm9sID0gbnVsbDsKKwlpZiAoaGVscFN0cmluZyAhPSAwKSBPUy5DRlJlbGVhc2UgKGhlbHBTdHJpbmcpOworCWhlbHBTdHJpbmcgPSAwOworCS8vTk9UIERPTkUgLSBjYWxsIHRlcm1pbmF0ZSBUWE4gaWYgdGhpcyBpcyB0aGUgbGFzdCBkaXNwbGF5IAorCS8vTk9URTogLSBkaXNwbGF5IGNyZWF0ZSBhbmQgZGlzcG9zZSBuZWVkcyB0byBiZSBzeW5jaHJvbml6ZWQgb24gYWxsIHBsYXRmb3JtcworLy8JIFRYTlRlcm1pbmF0ZVRleHRlbnNpb24gKCk7CiAKLQkvKiBEaXNwb3NlIHRoZSBtb3VzZSBob3ZlciBjYWxsYmFjayAqLwotCWlmIChtb3VzZUhvdmVySUQgIT0gMCkgT1MuUmVtb3ZlRXZlbnRMb29wVGltZXIobW91c2VIb3ZlcklEKTsKLQltb3VzZUhvdmVySUQgPSBtb3VzZUhvdmVyUHJvYyA9IG1vdXNlSG92ZXJIYW5kbGUgPSB0b29sVGlwV2luZG93SGFuZGxlID0gMDsKLQotCS8qIEZyZWUgdGhlIGZvbnQgbGlzdHMgKi8KLQkvKiBBVwotCWlmIChidXR0b25Gb250ICE9IDApIE9TLlhtRm9udExpc3RGcmVlIChidXR0b25Gb250KTsKLQlpZiAobGFiZWxGb250ICE9IDApIE9TLlhtRm9udExpc3RGcmVlIChsYWJlbEZvbnQpOwotCWlmICh0ZXh0Rm9udCAhPSAwKSBPUy5YbUZvbnRMaXN0RnJlZSAodGV4dEZvbnQpOwotCWlmIChsaXN0Rm9udCAhPSAwKSBPUy5YbUZvbnRMaXN0RnJlZSAobGlzdEZvbnQpOwotCWxpc3RGb250ID0gdGV4dEZvbnQgPSBsYWJlbEZvbnQgPSBidXR0b25Gb250ID0gMDsKLQkqLwotCWRlZmF1bHRGb250ID0gbnVsbDsJCi0JCi0JLyogUmVsZWFzZSByZWZlcmVuY2VzICovCi0JdGhyZWFkID0gbnVsbDsKLQlidXR0b25CYWNrZ3JvdW5kID0gYnV0dG9uRm9yZWdyb3VuZCA9IDA7Ci0JZGVmYXVsdEJhY2tncm91bmQgPSBkZWZhdWx0Rm9yZWdyb3VuZCA9IDA7Ci0JQ09MT1JfV0lER0VUX0RBUktfU0hBRE9XID0gQ09MT1JfV0lER0VUX05PUk1BTF9TSEFET1cgPSBDT0xPUl9XSURHRVRfTElHSFRfU0hBRE9XID0KLQlDT0xPUl9XSURHRVRfSElHSExJR0hUX1NIQURPVyA9IENPTE9SX1dJREdFVF9CQUNLR1JPVU5EID0gQ09MT1JfV0lER0VUX0JPUkRFUiA9Ci0JQ09MT1JfTElTVF9GT1JFR1JPVU5EID0gQ09MT1JfTElTVF9CQUNLR1JPVU5EID0gQ09MT1JfTElTVF9TRUxFQ1RJT04gPSBDT0xPUl9MSVNUX1NFTEVDVElPTl9URVhUID0gbnVsbDsKLQlDT0xPUl9JTkZPX0JBQ0tHUk9VTkQgPSBudWxsOwotfQotdm9pZCByZWxlYXNlVG9vbFRpcEhhbmRsZSAoaW50IGhhbmRsZSkgewotCWlmIChtb3VzZUhvdmVySGFuZGxlID09IGhhbmRsZSkgcmVtb3ZlTW91c2VIb3ZlclRpbWVPdXQgKCk7Ci0JaWYgKHRvb2xUaXBXaW5kb3dIYW5kbGUgIT0gMCkgewotCQkvKiBBVwotCQlpbnQgc2hlbGxQYXJlbnQgPSBPUy5YdFBhcmVudCh0b29sVGlwV2luZG93SGFuZGxlKTsKLQkJaWYgKGhhbmRsZSA9PSBzaGVsbFBhcmVudCkgdG9vbFRpcFdpbmRvd0hhbmRsZSA9IDA7Ci0JCSovCi0JfQogfQogCi0vKioKLSAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmVkIHdoZW4gYW4gZXZlbnQgb2YgdGhlIGdpdmVuIHR5cGUgb2NjdXJzLgotICoKLSAqIEBwYXJhbSBldmVudFR5cGUgdGhlIHR5cGUgb2YgZXZlbnQgdG8gbGlzdGVuIGZvcgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgbm8gbG9uZ2VyIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGV2ZW50IG9jY3VycwotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBMaXN0ZW5lcgotICogQHNlZSAjYWRkTGlzdGVuZXIKLSAqIAotICogQHNpbmNlIDIuMCAKLSAqLworcHVibGljIHZvaWQgcmVtb3ZlRmlsdGVyIChpbnQgZXZlbnRUeXBlLCBMaXN0ZW5lciBsaXN0ZW5lcikgeworCWNoZWNrRGV2aWNlICgpOworCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWlmIChmaWx0ZXJUYWJsZSA9PSBudWxsKSByZXR1cm47CisJZmlsdGVyVGFibGUudW5ob29rIChldmVudFR5cGUsIGxpc3RlbmVyKTsKKwlpZiAoZmlsdGVyVGFibGUuc2l6ZSAoKSA9PSAwKSBmaWx0ZXJUYWJsZSA9IG51bGw7Cit9CisKIHB1YmxpYyB2b2lkIHJlbW92ZUxpc3RlbmVyIChpbnQgZXZlbnRUeXBlLCBMaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrRGV2aWNlICgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwpAQCAtMTI0NCwxMyArMTA4MSw1NiBAQAogCWV2ZW50VGFibGUudW5ob29rIChldmVudFR5cGUsIGxpc3RlbmVyKTsKIH0KIAotdm9pZCByZW1vdmVNb3VzZUhvdmVyVGltZU91dCAoKSB7Ci0JaWYgKG1vdXNlSG92ZXJJRCAhPSAwKSBPUy5SZW1vdmVFdmVudExvb3BUaW1lcihtb3VzZUhvdmVySUQpOwotCW1vdXNlSG92ZXJJRCA9IG1vdXNlSG92ZXJIYW5kbGUgPSAwOwordm9pZCByZW1vdmVNZW51IChNZW51IG1lbnUpIHsKKwlpZiAobWVudXMgPT0gbnVsbCkgcmV0dXJuOworCW1lbnVzIFttZW51LmlkIC0gSURfU1RBUlRdID0gbnVsbDsKIH0KKwordm9pZCByZW1vdmVNZW51SXRlbSAoTWVudUl0ZW0gaXRlbSkgeworCWlmIChpdGVtcyA9PSBudWxsKSByZXR1cm47CisJaXRlbXMgW2l0ZW0uaWQgLSBJRF9TVEFSVF0gPSBudWxsOworfQorCit2b2lkIHJlbW92ZVBvcHVwIChNZW51IG1lbnUpIHsKKwlpZiAocG9wdXBzID09IG51bGwpIHJldHVybjsKKwlmb3IgKGludCBpPTA7IGk8cG9wdXBzLmxlbmd0aDsgaSsrKSB7CisJCWlmIChwb3B1cHMgW2ldID09IG1lbnUpIHsKKwkJCXBvcHVwcyBbaV0gPSBudWxsOworCQkJcmV0dXJuOworCQl9CisJfQorfQorCiBib29sZWFuIHJ1bkFzeW5jTWVzc2FnZXMgKCkgewogCXJldHVybiBzeW5jaHJvbml6ZXIucnVuQXN5bmNNZXNzYWdlcyAoKTsKIH0KKworYm9vbGVhbiBydW5FbnRlckV4aXQgKCkgeworCS8vT1BUSU1JWkUgLSB1c2UgT1MgY2FsbHMsIG5vIGdhcmJhZ2UsIHdpZGdldCBhbHJlYWR5IGhpdCB0ZXN0ZWQgaW4gbW91c2UgbW92ZQorCVBvaW50IHBvaW50ID0gbnVsbDsKKwlpbnQgY2hvcmQgPSAwLCBtb2RpZmllcnMgPSAwOworCUNvbnRyb2wgY29udHJvbCA9IGdldEN1cnNvckNvbnRyb2wgKCk7CisJaWYgKGNvbnRyb2wgIT0gY3VycmVudENvbnRyb2wpIHsKKwkJaWYgKGN1cnJlbnRDb250cm9sICE9IG51bGwgJiYgIWN1cnJlbnRDb250cm9sLmlzRGlzcG9zZWQgKCkpIHsKKwkJCXBvaW50ID0gZ2V0Q3Vyc29yTG9jYXRpb24gKCk7CisJCQljaG9yZCA9IE9TLkdldEN1cnJlbnRFdmVudEJ1dHRvblN0YXRlICgpOworCQkJbW9kaWZpZXJzID0gT1MuR2V0Q3VycmVudEV2ZW50S2V5TW9kaWZpZXJzICgpOworCQkJUG9pbnQgcHQgPSBjdXJyZW50Q29udHJvbC50b0NvbnRyb2wgKHBvaW50KTsKKwkJCWN1cnJlbnRDb250cm9sLnNlbmRNb3VzZUV2ZW50IChTV1QuTW91c2VFeGl0LCAoc2hvcnQpMCwgY2hvcmQsIChzaG9ydClwdC54LCAoc2hvcnQpcHQueSwgbW9kaWZpZXJzKTsKKwkJfQorCQlpZiAoKGN1cnJlbnRDb250cm9sID0gY29udHJvbCkgIT0gbnVsbCkgeworCQkJaWYgKHBvaW50ID09IG51bGwpIHsKKwkJCQlwb2ludCA9IGdldEN1cnNvckxvY2F0aW9uICgpOworCQkJCWNob3JkID0gT1MuR2V0Q3VycmVudEV2ZW50QnV0dG9uU3RhdGUgKCk7CisJCQkJbW9kaWZpZXJzID0gT1MuR2V0Q3VycmVudEV2ZW50S2V5TW9kaWZpZXJzICgpOworCQkJfQorCQkJUG9pbnQgcHQgPSBjdXJyZW50Q29udHJvbC50b0NvbnRyb2wgKHBvaW50KTsKKwkJCWN1cnJlbnRDb250cm9sLnNlbmRNb3VzZUV2ZW50IChTV1QuTW91c2VFbnRlciwgKHNob3J0KTAsIGNob3JkLCAoc2hvcnQpcHQueCwgKHNob3J0KXB0LnksIG1vZGlmaWVycyk7CisJCX0KKwl9CisJcmV0dXJuIHBvaW50ICE9IG51bGw7Cit9CisKIGJvb2xlYW4gcnVuRGVmZXJyZWRFdmVudHMgKCkgewogCS8qCiAJKiBSdW4gZGVmZXJyZWQgZXZlbnRzLiAgVGhpcyBjb2RlIGlzIGFsd2F5cwpAQCAtMTI4NiwyMiArMTE2Niw5NCBAQAogCWV2ZW50UXVldWUgPSBudWxsOwogCXJldHVybiB0cnVlOwogfQorCit2b2lkIHJ1bkdyYWJzICgpIHsKKwlpZiAoZ3JhYkNvbnRyb2wgPT0gbnVsbCkgcmV0dXJuOworCVJlY3QgcmVjdCA9IG5ldyBSZWN0ICgpOworCWludCBbXSBvdXRNb2RpZmllcnMgPSBuZXcgaW50IFsxXTsKKwlzaG9ydCBbXSBvdXRSZXN1bHQgPSBuZXcgc2hvcnQgWzFdOworCW9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgb3V0UHQgPSBuZXcgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCAoKTsKKwl0cnkgeworCQl3aGlsZSAoZ3JhYkNvbnRyb2wgIT0gbnVsbCAmJiAhZ3JhYkNvbnRyb2wuaXNEaXNwb3NlZCAoKSAmJiBvdXRSZXN1bHQgWzBdICE9IE9TLmtNb3VzZVRyYWNraW5nTW91c2VVcCkgeworCQkJbGFzdE1vZGlmaWVycyA9IE9TLkdldEN1cnJlbnRFdmVudEtleU1vZGlmaWVycyAoKTsKKwkJCWludCBvbGRTdGF0ZSA9IE9TLkdldEN1cnJlbnRFdmVudEJ1dHRvblN0YXRlICgpOworCQkJT1MuVHJhY2tNb3VzZUxvY2F0aW9uV2l0aE9wdGlvbnMgKDAsIDAsIE9TLmtFdmVudER1cmF0aW9uRm9yZXZlciwgb3V0UHQsIG91dE1vZGlmaWVycywgb3V0UmVzdWx0KTsKKwkJCWludCB0eXBlID0gMCwgYnV0dG9uID0gMDsKKwkJCXN3aXRjaCAoKGludClvdXRSZXN1bHQgWzBdKSB7CisJCQkJY2FzZSBPUy5rTW91c2VUcmFja2luZ01vdXNlRG93bjogeworCQkJCQl0eXBlID0gU1dULk1vdXNlRG93bjsKKwkJCQkJaW50IG5ld1N0YXRlID0gT1MuR2V0Q3VycmVudEV2ZW50QnV0dG9uU3RhdGUgKCk7CisJCQkJCWlmICgob2xkU3RhdGUgJiAweDEpID09IDAgJiYgKG5ld1N0YXRlICYgMHgxKSAhPSAwKSBidXR0b24gPSAxOworCQkJCQlpZiAoKG9sZFN0YXRlICYgMHgyKSA9PSAwICYmIChuZXdTdGF0ZSAmIDB4MikgIT0gMCkgYnV0dG9uID0gMjsKKwkJCQkJaWYgKChvbGRTdGF0ZSAmIDB4NCkgPT0gMCAmJiAobmV3U3RhdGUgJiAweDQpICE9IDApIGJ1dHRvbiA9IDM7CisJCQkJCWJyZWFrOworCQkJCX0KKwkJCQljYXNlIE9TLmtNb3VzZVRyYWNraW5nTW91c2VVcDogeworCQkJCQl0eXBlID0gU1dULk1vdXNlVXA7CisJCQkJCWludCBuZXdTdGF0ZSA9IE9TLkdldEN1cnJlbnRFdmVudEJ1dHRvblN0YXRlICgpOworCQkJCQlpZiAoKG9sZFN0YXRlICYgMHgxKSAhPSAwICYmIChuZXdTdGF0ZSAmIDB4MSkgPT0gMCkgYnV0dG9uID0gMTsKKwkJCQkJaWYgKChvbGRTdGF0ZSAmIDB4MikgIT0gMCAmJiAobmV3U3RhdGUgJiAweDIpID09IDApIGJ1dHRvbiA9IDI7CisJCQkJCWlmICgob2xkU3RhdGUgJiAweDQpICE9IDAgJiYgKG5ld1N0YXRlICYgMHg0KSA9PSAwKSBidXR0b24gPSAzOworCQkJCQlicmVhazsKKwkJCQl9CisJCQkJY2FzZSBPUy5rTW91c2VUcmFja2luZ01vdXNlRXhpdGVkOiAJCQkJdHlwZSA9IFNXVC5Nb3VzZUV4aXQ7IGJyZWFrOworCQkJCWNhc2UgT1Mua01vdXNlVHJhY2tpbmdNb3VzZUVudGVyZWQ6IAkJCQl0eXBlID0gU1dULk1vdXNlRW50ZXI7IGJyZWFrOworCQkJCWNhc2UgT1Mua01vdXNlVHJhY2tpbmdNb3VzZURyYWdnZWQ6IAkJCQl0eXBlID0gU1dULk1vdXNlTW92ZTsgYnJlYWs7CisJCQkJY2FzZSBPUy5rTW91c2VUcmFja2luZ01vdXNlS2V5TW9kaWZpZXJzQ2hhbmdlZDoJYnJlYWs7CisJCQkJY2FzZSBPUy5rTW91c2VUcmFja2luZ1VzZXJDYW5jZWxsZWQ6CQkJCWJyZWFrOworCQkJCWNhc2UgT1Mua01vdXNlVHJhY2tpbmdUaW1lZE91dDogCQkJCQlicmVhazsKKwkJCQljYXNlIE9TLmtNb3VzZVRyYWNraW5nTW91c2VNb3ZlZDogCQkJCQl0eXBlID0gU1dULk1vdXNlTW92ZTsgYnJlYWs7CisJCQl9CisJCQlpZiAodHlwZSAhPSAwKSB7CQorCQkJCWludCBoYW5kbGUgPSBncmFiQ29udHJvbC5oYW5kbGU7CisJCQkJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAoaGFuZGxlKTsKKwkJCQlPUy5HZXRXaW5kb3dCb3VuZHMgKHdpbmRvdywgKHNob3J0KSBPUy5rV2luZG93Q29udGVudFJnbiwgcmVjdCk7CisJCQkJaW50IHggPSBvdXRQdC5oIC0gcmVjdC5sZWZ0OworCQkJCWludCB5ID0gb3V0UHQudiAtIHJlY3QudG9wOworCQkJCU9TLkdldENvbnRyb2xCb3VuZHMgKGhhbmRsZSwgcmVjdCk7CisJCQkJeCAtPSByZWN0LmxlZnQ7CisJCQkJeSAtPSAgcmVjdC50b3A7CisJCQkJaW50IGNob3JkID0gT1MuR2V0Q3VycmVudEV2ZW50QnV0dG9uU3RhdGUgKCk7CisJCQkJZ3JhYkNvbnRyb2wuc2VuZE1vdXNlRXZlbnQgKHR5cGUsIChzaG9ydClidXR0b24sIGNob3JkLCAoc2hvcnQpeCwgKHNob3J0KXksIG91dE1vZGlmaWVycyBbMF0pOworCQkJCS8vVEVNUE9SQVJZIENPREUKKwkJCQl1cGRhdGUgKCk7CisJCQl9CisJCX0KKwl9IGZpbmFsbHkgeworCQlncmFiQ29udHJvbCA9IG51bGw7CisJfQorfQorCitib29sZWFuIHJ1blBvcHVwcyAoKSB7CisJaWYgKHBvcHVwcyA9PSBudWxsKSByZXR1cm4gZmFsc2U7CisJZ3JhYkNvbnRyb2wgPSBudWxsOworCWJvb2xlYW4gcmVzdWx0ID0gZmFsc2U7CisJd2hpbGUgKHBvcHVwcyAhPSBudWxsKSB7CisJCU1lbnUgbWVudSA9IHBvcHVwcyBbMF07CisJCWlmIChtZW51ID09IG51bGwpIGJyZWFrOworCQlpbnQgbGVuZ3RoID0gcG9wdXBzLmxlbmd0aDsKKwkJU3lzdGVtLmFycmF5Y29weSAocG9wdXBzLCAxLCBwb3B1cHMsIDAsIC0tbGVuZ3RoKTsKKwkJcG9wdXBzIFtsZW5ndGhdID0gbnVsbDsKKwkJbWVudS5fc2V0VmlzaWJsZSAodHJ1ZSk7CisJCXJlc3VsdCA9IHRydWU7CisJfQorCXBvcHVwcyA9IG51bGw7CisJcmV0dXJuIHJlc3VsdDsKK30KKwogdm9pZCBzZW5kRXZlbnQgKGludCBldmVudFR5cGUsIEV2ZW50IGV2ZW50KSB7Ci0JaWYgKGV2ZW50VGFibGUgPT0gbnVsbCkgcmV0dXJuOworCWlmIChldmVudFRhYmxlID09IG51bGwgJiYgZmlsdGVyVGFibGUgPT0gbnVsbCkgeworCQlyZXR1cm47CisJfQogCWlmIChldmVudCA9PSBudWxsKSBldmVudCA9IG5ldyBFdmVudCAoKTsKIAlldmVudC5kaXNwbGF5ID0gdGhpczsKIAlldmVudC50eXBlID0gZXZlbnRUeXBlOwotCWlmIChldmVudC50aW1lID09IDApIHsKLQkJLyogQVcKLQkJaWYgKE9TLklzV2luQ0UpIHsKLQkJCWV2ZW50LnRpbWUgPSBPUy5HZXRUaWNrQ291bnQgKCk7Ci0JCX0gZWxzZSB7Ci0JCQlldmVudC50aW1lID0gT1MuR2V0TWVzc2FnZVRpbWUgKCk7Ci0JCX0KLQkJKi8KKwlpZiAoZXZlbnQudGltZSA9PSAwKSBldmVudC50aW1lID0gZ2V0TGFzdEV2ZW50VGltZSAoKTsKKwlpZiAoIWZpbHRlckV2ZW50IChldmVudCkpIHsKKwkJaWYgKGV2ZW50VGFibGUgIT0gbnVsbCkgZXZlbnRUYWJsZS5zZW5kRXZlbnQgKGV2ZW50KTsKIAl9Ci0JZXZlbnRUYWJsZS5zZW5kRXZlbnQgKGV2ZW50KTsKIH0KKwogLyoqCiAgKiBPbiBwbGF0Zm9ybXMgd2hpY2ggc3VwcG9ydCBpdCwgc2V0cyB0aGUgYXBwbGljYXRpb24gbmFtZQogICogdG8gYmUgdGhlIGFyZ3VtZW50LiBPbiBNb3RpZiwgZm9yIGV4YW1wbGUsIHRoaXMgY2FuIGJlIHVzZWQKQEAgLTEzMTAsNyArMTI2MiwyMCBAQAogICogQHBhcmFtIG5hbWUgdGhlIG5ldyBhcHAgbmFtZQogICovCiBwdWJsaWMgc3RhdGljIHZvaWQgc2V0QXBwTmFtZSAoU3RyaW5nIG5hbWUpIHsKLQlBUFBfTkFNRSA9IG5hbWU7Cit9CisKK3ZvaWQgc2V0Q3VycmVudENhcmV0IChDYXJldCBjYXJldCkgeworCWlmIChjYXJldElEICE9IDApIE9TLlJlbW92ZUV2ZW50TG9vcFRpbWVyIChjYXJldElEKTsKKwljYXJldElEID0gMDsKKwljdXJyZW50Q2FyZXQgPSBjYXJldDsKKwlpZiAoY3VycmVudENhcmV0ICE9IG51bGwpIHsKKwkJaW50IGJsaW5rUmF0ZSA9IGN1cnJlbnRDYXJldC5ibGlua1JhdGU7CisJCWludCBbXSB0aW1lcklkID0gbmV3IGludCBbMV07CisJCWRvdWJsZSB0aW1lID0gYmxpbmtSYXRlIC8gMTAwMC4wOworCQlpbnQgZXZlbnRMb29wID0gT1MuR2V0Q3VycmVudEV2ZW50TG9vcCAoKTsKKwkJT1MuSW5zdGFsbEV2ZW50TG9vcFRpbWVyIChldmVudExvb3AsIHRpbWUsIHRpbWUsIGNhcmV0UHJvYywgMCwgdGltZXJJZCk7CisJCWNhcmV0SUQgPSB0aW1lcklkIFswXTsKKwl9CiB9CiAKIC8qKgpAQCAtMTMyOCw1MCArMTI5Myw5IEBACiBwdWJsaWMgdm9pZCBzZXRDdXJzb3JMb2NhdGlvbiAoUG9pbnQgcG9pbnQpIHsKIAljaGVja0RldmljZSAoKTsKIAlpZiAocG9pbnQgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQkvKiBBVwotCWludCB4ID0gcG9pbnQueDsKLQlpbnQgeSA9IHBvaW50Lnk7Ci0JaW50IHhXaW5kb3cgPSBPUy5YRGVmYXVsdFJvb3RXaW5kb3cgKHhEaXNwbGF5KTsJCi0JT1MuWFdhcnBQb2ludGVyICh4RGlzcGxheSwgT1MuTm9uZSwgeFdpbmRvdywgMCwgMCwgMCwgMCwgeCwgeSk7Ci0JKi8KLQlTeXN0ZW0ub3V0LnByaW50bG4oIkRpc3BsYXkuc2V0Q3Vyc29yTG9jYXRpb246IG55aSIpOworCS8qIE5vdCBwb3NzaWJsZSBvbiB0aGUgTUFDICovCiB9CiAKLXZvaWQgc2V0Q3VycmVudENhcmV0IChDYXJldCBjYXJldCkgewotCWlmIChjYXJldElEICE9IDApIE9TLlJlbW92ZUV2ZW50TG9vcFRpbWVyKGNhcmV0SUQpOwotCWNhcmV0SUQgPSAwOwotCWN1cnJlbnRDYXJldCA9IGNhcmV0OwotCWlmIChjdXJyZW50Q2FyZXQgIT0gbnVsbCkgewotCQlpbnQgYmxpbmtSYXRlID0gY3VycmVudENhcmV0LmJsaW5rUmF0ZTsKLQkJaW50W10gdGltZXI9IG5ldyBpbnRbMV07Ci0JCU9TLkluc3RhbGxFdmVudExvb3BUaW1lcihPUy5HZXRDdXJyZW50RXZlbnRMb29wKCksIGJsaW5rUmF0ZSAvIDEwMDAuMCwgMC4wLCBjYXJldFByb2MsIDAsIHRpbWVyKTsKLQkJY2FyZXRJRCA9IHRpbWVyWzBdOwotCX0KLX0KLS8qKgotICogU2V0cyB0aGUgYXBwbGljYXRpb24gZGVmaW5lZCBwcm9wZXJ0eSBvZiB0aGUgcmVjZWl2ZXIKLSAqIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIHRvIHRoZSBnaXZlbiBhcmd1bWVudC4KLSAqIDxwPgotICogQXBwbGljYXRpb25zIG1heSBoYXZlIGFzc29jaWF0ZWQgYXJiaXRyYXJ5IG9iamVjdHMgd2l0aCB0aGUKLSAqIHJlY2VpdmVyIGluIHRoaXMgZmFzaGlvbi4gSWYgdGhlIG9iamVjdHMgc3RvcmVkIGluIHRoZQotICogcHJvcGVydGllcyBuZWVkIHRvIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGRpc3BsYXkgaXMgZGlzcG9zZWQKLSAqIG9mLCBpdCBpcyB0aGUgYXBwbGljYXRpb24ncyByZXNwb25zaWJpbGl0eSBwcm92aWRlIGEKLSAqIDxjb2RlPmRpc3Bvc2VFeGVjKCk8L2NvZGU+IGhhbmRsZXIgd2hpY2ggZG9lcyBzby4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0ga2V5IHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eQotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGtleSBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI3NldERhdGEKLSAqIEBzZWUgI2Rpc3Bvc2VFeGVjCi0gKi8KIHB1YmxpYyB2b2lkIHNldERhdGEgKFN0cmluZyBrZXksIE9iamVjdCB2YWx1ZSkgewogCWNoZWNrRGV2aWNlICgpOwogCWlmIChrZXkgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTE0MTksNDUgKzEzNDMsMTIgQEAKIAlrZXlzID0gbmV3S2V5czsKIAl2YWx1ZXMgPSBuZXdWYWx1ZXM7CiB9Ci0vKioKLSAqIFNldHMgdGhlIGFwcGxpY2F0aW9uIGRlZmluZWQsIGRpc3BsYXkgc3BlY2lmaWMgZGF0YQotICogYXNzb2NpYXRlZCB3aXRoIHRoZSByZWNlaXZlciwgdG8gdGhlIGFyZ3VtZW50LgotICogVGhlIDxlbT5kaXNwbGF5IHNwZWNpZmljIGRhdGE8L2VtPiBpcyBhIHNpbmdsZSwKLSAqIHVubmFtZWQgZmllbGQgdGhhdCBpcyBzdG9yZWQgd2l0aCBldmVyeSBkaXNwbGF5LiAKLSAqIDxwPgotICogQXBwbGljYXRpb25zIG1heSBwdXQgYXJiaXRyYXJ5IG9iamVjdHMgaW4gdGhpcyBmaWVsZC4gSWYKLSAqIHRoZSBvYmplY3Qgc3RvcmVkIGluIHRoZSBkaXNwbGF5IHNwZWNpZmljIGRhdGEgbmVlZHMgdG8KLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGRpc3BsYXkgaXMgZGlzcG9zZWQgb2YsIGl0IGlzIHRoZQotICogYXBwbGljYXRpb24ncyByZXNwb25zaWJpbGl0eSBwcm92aWRlIGEKLSAqIDxjb2RlPmRpc3Bvc2VFeGVjKCk8L2NvZGU+IGhhbmRsZXIgd2hpY2ggZG9lcyBzby4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gZGF0YSB0aGUgbmV3IGRpc3BsYXkgc3BlY2lmaWMgZGF0YQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSB3aGVuIGNhbGxlZCBmcm9tIHRoZSB3cm9uZyB0aHJlYWQ8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNnZXREYXRhCi0gKiBAc2VlICNkaXNwb3NlRXhlYwotICovCisKIHB1YmxpYyB2b2lkIHNldERhdGEgKE9iamVjdCBkYXRhKSB7CiAJY2hlY2tEZXZpY2UgKCk7CiAJdGhpcy5kYXRhID0gZGF0YTsKIH0KLS8qKgotICogU2V0cyB0aGUgc3luY2hyb25pemVyIHVzZWQgYnkgdGhlIGRpc3BsYXkgdG8gYmUKLSAqIHRoZSBhcmd1bWVudCwgd2hpY2ggY2FuIG5vdCBiZSBudWxsLgotICoKLSAqIEBwYXJhbSBzeW5jaHJvbml6ZXIgdGhlIG5ldyBzeW5jaHJvbml6ZXIgZm9yIHRoZSBkaXNwbGF5IChtdXN0IG5vdCBiZSBudWxsKQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHN5bmNocm9uaXplciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldFN5bmNocm9uaXplciAoU3luY2hyb25pemVyIHN5bmNocm9uaXplcikgewogCWNoZWNrRGV2aWNlICgpOwogCWlmIChzeW5jaHJvbml6ZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTE0NjYsMTQzICsxMzU3LDY4IEBACiAJfQogCXRoaXMuc3luY2hyb25pemVyID0gc3luY2hyb25pemVyOwogfQotdm9pZCBzZXRUb29sVGlwVGV4dCAoaW50IGhhbmRsZSwgU3RyaW5nIHRvb2xUaXBUZXh0KSB7Ci0vKiBBVwotCWlmICh0b29sVGlwSGFuZGxlID09IDApIHJldHVybjsKLQlpbnQgc2hlbGxIYW5kbGUgPSBPUy5YdFBhcmVudCAodG9vbFRpcEhhbmRsZSk7Ci0JaW50IHNoZWxsUGFyZW50ID0gT1MuWHRQYXJlbnQgKHNoZWxsSGFuZGxlKTsKLQlpZiAoaGFuZGxlICE9IHNoZWxsUGFyZW50KSByZXR1cm47Ci0qLwotCXNob3dUb29sVGlwIChoYW5kbGUsIHRvb2xUaXBUZXh0KTsKKwordm9pZCBzZXRNZW51QmFyIChNZW51IG1lbnUpIHsKKwkvKgorCSogRmVhdHVyZSBpbiB0aGUgTWFjaW50b3NoLiAgU2V0Um9vdE1lbnUoKSBkb2VzIG5vdAorCSogYWNjZXB0IE5VTEwgdG8gaW5kaWNhdGUgdGhhdCB0aGVpciBzaG91bGQgYmUgbm8KKwkqIG1lbnUgYmFyLiBUaGUgZml4IGlzIHRvIGNyZWF0ZSBhIHRlbXBvcmFyeSBlbXB0eQorCSogbWVudSwgc2V0IHRoYXQgdG8gYmUgdGhlIG1lbnUgYmFyLCBjbGVhciB0aGUgbWVudQorCSogYmFyIGFuZCB0aGVuIGRlbGV0ZSB0aGUgdGVtcG9yYXJ5IG1lbnUuCisJKi8KKwlpZiAobWVudSA9PSBtZW51QmFyKSByZXR1cm47CisJaW50IHRoZU1lbnUgPSAwOworCWlmIChtZW51ID09IG51bGwpIHsKKwkJaW50IG91dE1lbnVSZWYgW10gPSBuZXcgaW50IFsxXTsKKwkJT1MuQ3JlYXRlTmV3TWVudSAoKHNob3J0KSBJRF9URU1QT1JBUlksIDAsIG91dE1lbnVSZWYpOworCQl0aGVNZW51ID0gb3V0TWVudVJlZiBbMF07CisJfSBlbHNlIHsKKwkJdGhlTWVudSA9IG1lbnUuaGFuZGxlOworCX0KKwlPUy5TZXRSb290TWVudSAodGhlTWVudSk7CisJaWYgKG1lbnUgPT0gbnVsbCkgeworCQlPUy5DbGVhck1lbnVCYXIgKCk7CisJCU9TLkRlbGV0ZU1lbnUgKE9TLkdldE1lbnVJRCAodGhlTWVudSkpOworCQlPUy5EaXNwb3NlTWVudSAodGhlTWVudSk7CisJfQorCW1lbnVCYXIgPSBtZW51OwogfQotdm9pZCBzaG93VG9vbFRpcCAoaW50IGhhbmRsZSwgU3RyaW5nIHRvb2xUaXBUZXh0KSB7CiAKLQlpZiAodG9vbFRpcFRleHQgPT0gbnVsbCB8fCB0b29sVGlwVGV4dC5sZW5ndGggKCkgPT0gMCkgewotCQlpZiAodG9vbFRpcFdpbmRvd0hhbmRsZSAhPSAwKQotCQkJT1MuSGlkZVdpbmRvdyh0b29sVGlwV2luZG93SGFuZGxlKTsKLQkJcmV0dXJuOwotCX0KLQotCWlmICh0b29sVGlwV2luZG93SGFuZGxlICE9IDApCi0JCSByZXR1cm47Ci0JCi0JaWYgKGhhbmRsZSAhPSBmQ3VycmVudENvbnRyb2wpIHsKLQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIkRpc3BsYXkuc2hvd1Rvb2xUaXA6IGhhbmRsZSBpcyBub3QgY3VycmVudCIpOwotCQkvL2JlZXAoKTsKLQkJcmV0dXJuOwotCX0KLQlpZiAoZkluQ29udGV4dE1lbnUpIHsKLQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIkRpc3BsYXkuc2hvd1Rvb2xUaXA6IG1lbnUgaXMgdmlzaWJsZSIpOwotCQkvL2JlZXAoKTsKLQkJcmV0dXJuOwotCX0JCi0JaWYgKE9TLlN0aWxsRG93bigpKSB7Ci0JCS8vU3lzdGVtLm91dC5wcmludGxuKCJEaXNwbGF5LnNob3dUb29sVGlwOiBidXR0b24gaXMgZG93biIpOwotCQkvL2JlZXAoKTsKLQkJcmV0dXJuOwotCX0JCi0JCi0JdG9vbFRpcFRleHQ9IE1hY1V0aWwucmVtb3ZlTW5lbW9uaWNzKHRvb2xUaXBUZXh0KTsKLQkKLQkvLyByZW1lbWJlciB0ZXh0Ci0JZlRvb2xUaXBUZXh0PSB0b29sVGlwVGV4dDsKLQkKLQkvLyBjYWxjdWxhdGUgdGV4dCBib3VuZGluZyBib3gKLQlzaG9ydFtdIGJvdW5kcz0gbmV3IHNob3J0WzJdOwotCXNob3J0W10gYmFzZUxpbmU9IG5ldyBzaG9ydFsxXTsKLQlpbnQgc0hhbmRsZT0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyh0b29sVGlwVGV4dCk7Ci0JT1MuR2V0VGhlbWVUZXh0RGltZW5zaW9ucyhzSGFuZGxlLCBmSG92ZXJUaGVtZUZvbnQsIE9TLmtUaGVtZVN0YXRlQWN0aXZlLCBmYWxzZSwgYm91bmRzLCBiYXNlTGluZSk7Ci0JaWYgKGJvdW5kc1sxXSA+IDIwMCkgewkvLyB0b28gd2lkZSAtPiB3cmFwIHRleHQKLQkJYm91bmRzWzFdPSAoc2hvcnQpIDIwMDsKLQkJT1MuR2V0VGhlbWVUZXh0RGltZW5zaW9ucyhzSGFuZGxlLCBmSG92ZXJUaGVtZUZvbnQsIE9TLmtUaGVtZVN0YXRlQWN0aXZlLCB0cnVlLCBib3VuZHMsIGJhc2VMaW5lKTsKLQl9Ci0JT1MuQ0ZSZWxlYXNlKHNIYW5kbGUpOwotCWludCB3aWR0aD0gYm91bmRzWzFdICsgMipUT09MVElQX01BUkdJTjsKLQlpbnQgaGVpZ2h0PSBib3VuZHNbMF0gKyAyKlRPT0xUSVBfTUFSR0lOOwotCQotCS8vIHBvc2l0aW9uIGp1c3QgYmVsb3cgbW91c2UgY3Vyc29yCi0JTWFjUG9pbnQgbG9jPSBuZXcgTWFjUG9pbnQoKTsKLQlPUy5HZXRHbG9iYWxNb3VzZShsb2MuZ2V0RGF0YSgpKTsKLQlpbnQgeD0gbG9jLmdldFgoKSArIDE2OwotCWludCB5PSBsb2MuZ2V0WSgpICsgMTY7Ci0KLQkvLyBFbnN1cmUgdGhhdCB0aGUgdG9vbCB0aXAgaXMgb24gdGhlIHNjcmVlbi4KLQlNYWNSZWN0IHNjcmVlbkJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQlPUy5HZXRBdmFpbGFibGVXaW5kb3dQb3NpdGlvbmluZ0JvdW5kcyhPUy5HZXRNYWluRGV2aWNlKCksIHNjcmVlbkJvdW5kcy5nZXREYXRhKCkpOwotCXggPSBNYXRoLm1heCAoMCwgTWF0aC5taW4gKHgsIHNjcmVlbkJvdW5kcy5nZXRXaWR0aCgpIC0gd2lkdGggKSk7Ci0JeSA9IE1hdGgubWF4ICgwLCBNYXRoLm1pbiAoeSwgc2NyZWVuQm91bmRzLmdldEhlaWdodCgpIC0gaGVpZ2h0ICkpOwotCi0JLy8gY3JlYXRlIHdpbmRvdwotCWludFtdIHdIYW5kbGU9IG5ldyBpbnRbMV07Ci0JaWYgKE9TLkNyZWF0ZU5ld1dpbmRvdyhPUy5rSGVscFdpbmRvd0NsYXNzLCAwLCBuZXcgTWFjUmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0KS5nZXREYXRhKCksIHdIYW5kbGUpID09IE9TLmtOb0VycikgewotCQl0b29sVGlwV2luZG93SGFuZGxlPSB3SGFuZGxlWzBdOwotCQlpbnRbXSBtYXNrPSBuZXcgaW50W10gewotCQkJT1Mua0V2ZW50Q2xhc3NXaW5kb3csIE9TLmtFdmVudFdpbmRvd0RyYXdDb250ZW50Ci0JCX07Ci0JCU9TLkluc3RhbGxFdmVudEhhbmRsZXIoT1MuR2V0V2luZG93RXZlbnRUYXJnZXQodG9vbFRpcFdpbmRvd0hhbmRsZSksIGZXaW5kb3dQcm9jLCBtYXNrLCB0b29sVGlwV2luZG93SGFuZGxlKTsKLQkJT1MuU2hvd1dpbmRvdyh0b29sVGlwV2luZG93SGFuZGxlKTsKLQkJZkxhc3RIb3ZlckhhbmRsZT0gaGFuZGxlOwotCX0KLX0KLS8qKgotICogQ2F1c2VzIHRoZSB1c2VyLWludGVyZmFjZSB0aHJlYWQgdG8gPGVtPnNsZWVwPC9lbT4gKHRoYXQgaXMsCi0gKiB0byBiZSBwdXQgaW4gYSBzdGF0ZSB3aGVyZSBpdCBkb2VzIG5vdCBjb25zdW1lIENQVSBjeWNsZXMpCi0gKiB1bnRpbCBhbiBldmVudCBpcyByZWNlaXZlZCBvciBpdCBpcyBvdGhlcndpc2UgYXdha2VuZWQuCi0gKgotICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbiBldmVudCByZXF1aXJpbmcgZGlzcGF0Y2hpbmcgd2FzIHBsYWNlZCBvbiB0aGUgcXVldWUuCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICN3YWtlCi0gKi8KIHB1YmxpYyBib29sZWFuIHNsZWVwICgpIHsKIAljaGVja0RldmljZSAoKTsKLQlyZXR1cm4gT1MuUmVjZWl2ZU5leHRFdmVudChudWxsLCBPUy5rRXZlbnREdXJhdGlvbkZvcmV2ZXIsIGZhbHNlLCBudWxsKSA9PSBPUy5rTm9FcnI7CisJLy9OT1QgRE9ORSAtIHRpbWVycyBzaG91bGRuJ3QgcnVuIGhlcmUKKwlyZXR1cm4gT1MuUmVjZWl2ZU5leHRFdmVudCAoMCwgbnVsbCwgT1Mua0V2ZW50RHVyYXRpb25Gb3JldmVyLCBmYWxzZSwgbnVsbCkgPT0gT1Mubm9FcnI7CiB9Ci0vKioKLSAqIENhdXNlcyB0aGUgPGNvZGU+cnVuKCk8L2NvZGU+IG1ldGhvZCBvZiB0aGUgcnVubmFibGUgdG8KLSAqIGJlIGludm9rZWQgYnkgdGhlIHVzZXItaW50ZXJmYWNlIHRocmVhZCBhdCB0aGUgbmV4dCAKLSAqIHJlYXNvbmFibGUgb3Bwb3J0dW5pdHkuIFRoZSB0aHJlYWQgd2hpY2ggY2FsbHMgdGhpcyBtZXRob2QKLSAqIGlzIHN1c3BlbmRlZCB1bnRpbCB0aGUgcnVubmFibGUgY29tcGxldGVzLgotICoKLSAqIEBwYXJhbSBydW5uYWJsZSBjb2RlIHRvIHJ1biBvbiB0aGUgdXNlci1pbnRlcmZhY2UgdGhyZWFkLgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9GQUlMRURfRVhFQyAtIGlmIGFuIGV4Y2VwdGlvbiBvY2N1cmVkIHdoZW4gZXhlY3V0aW5nIHRoZSBydW5uYWJsZTwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI2FzeW5jRXhlYwotICovCisKIHB1YmxpYyB2b2lkIHN5bmNFeGVjIChSdW5uYWJsZSBydW5uYWJsZSkgewogCWlmIChpc0Rpc3Bvc2VkICgpKSBlcnJvciAoU1dULkVSUk9SX0RFVklDRV9ESVNQT1NFRCk7CiAJc3luY2hyb25pemVyLnN5bmNFeGVjIChydW5uYWJsZSk7CiB9Ci0vKioKLSAqIENhdXNlcyB0aGUgPGNvZGU+cnVuKCk8L2NvZGU+IG1ldGhvZCBvZiB0aGUgcnVubmFibGUgdG8KLSAqIGJlIGludm9rZWQgYnkgdGhlIHVzZXItaW50ZXJmYWNlIHRocmVhZCBhZnRlciB0aGUgc3BlY2lmaWVkCi0gKiBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGhhdmUgZWxhcHNlZC4gSWYgbWlsbGlzZWNvbmRzIGlzIGxlc3MKLSAqIHRoYW4gemVybywgdGhlIHJ1bm5hYmxlIGlzIG5vdCBleGVjdXRlZC4KLSAqCi0gKiBAcGFyYW0gbWlsbGlzZWNvbmRzIHRoZSBkZWxheSBiZWZvcmUgcnVubmluZyB0aGUgcnVubmFibGUKLSAqIEBwYXJhbSBydW5uYWJsZSBjb2RlIHRvIHJ1biBvbiB0aGUgdXNlci1pbnRlcmZhY2UgdGhyZWFkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcnVubmFibGUgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNhc3luY0V4ZWMKLSAqLworCiBwdWJsaWMgdm9pZCB0aW1lckV4ZWMgKGludCBtaWxsaXNlY29uZHMsIFJ1bm5hYmxlIHJ1bm5hYmxlKSB7CiAJY2hlY2tEZXZpY2UgKCk7CisJaWYgKHJ1bm5hYmxlID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaWYgKHRpbWVyTGlzdCA9PSBudWxsKSB0aW1lckxpc3QgPSBuZXcgUnVubmFibGUgWzRdOwotCWlmICh0aW1lcklEcyA9PSBudWxsKSB0aW1lcklEcyA9IG5ldyBpbnQgWzRdOworCWlmICh0aW1lcklkcyA9PSBudWxsKSB0aW1lcklkcyA9IG5ldyBpbnQgWzRdOwogCWludCBpbmRleCA9IDA7CiAJd2hpbGUgKGluZGV4IDwgdGltZXJMaXN0Lmxlbmd0aCkgeworCQlpZiAodGltZXJMaXN0IFtpbmRleF0gPT0gcnVubmFibGUpIGJyZWFrOworCQlpbmRleCsrOworCX0KKwlpZiAoaW5kZXggIT0gdGltZXJMaXN0Lmxlbmd0aCkgeworCQlpbnQgdGltZXJJZCA9IHRpbWVySWRzIFtpbmRleF07CisJCWlmIChtaWxsaXNlY29uZHMgPCAwKSB7CisJCQlPUy5SZW1vdmVFdmVudExvb3BUaW1lciAodGltZXJJZCk7CisJCQl0aW1lckxpc3QgW2luZGV4XSA9IG51bGw7CisJCQl0aW1lcklkcyBbaW5kZXhdID0gMDsKKwkJfSBlbHNlIHsKKwkJCU9TLlNldEV2ZW50TG9vcFRpbWVyTmV4dEZpcmVUaW1lICh0aW1lcklkLCBtaWxsaXNlY29uZHMgLyAxMDAwLjApOworCQl9CisJCXJldHVybjsKKwl9IAorCWlmIChtaWxsaXNlY29uZHMgPCAwKSByZXR1cm47CisJaW5kZXggPSAwOworCXdoaWxlIChpbmRleCA8IHRpbWVyTGlzdC5sZW5ndGgpIHsKIAkJaWYgKHRpbWVyTGlzdCBbaW5kZXhdID09IG51bGwpIGJyZWFrOwogCQlpbmRleCsrOwogCX0KQEAgLTE2MTAsODY5ICsxNDI2LDk5IEBACiAJCVJ1bm5hYmxlIFtdIG5ld1RpbWVyTGlzdCA9IG5ldyBSdW5uYWJsZSBbdGltZXJMaXN0Lmxlbmd0aCArIDRdOwogCQlTeXN0ZW0uYXJyYXljb3B5ICh0aW1lckxpc3QsIDAsIG5ld1RpbWVyTGlzdCwgMCwgdGltZXJMaXN0Lmxlbmd0aCk7CiAJCXRpbWVyTGlzdCA9IG5ld1RpbWVyTGlzdDsKLQkJaW50IFtdIG5ld1RpbWVySURzID0gbmV3IGludCBbdGltZXJJRHMubGVuZ3RoICsgNF07Ci0JCVN5c3RlbS5hcnJheWNvcHkgKHRpbWVySURzLCAwLCBuZXdUaW1lcklEcywgMCwgdGltZXJJRHMubGVuZ3RoKTsKLQkJdGltZXJJRHMgPSBuZXdUaW1lcklEczsKKwkJaW50IFtdIG5ld1RpbWVySWRzID0gbmV3IGludCBbdGltZXJJZHMubGVuZ3RoICsgNF07CisJCVN5c3RlbS5hcnJheWNvcHkgKHRpbWVySWRzLCAwLCBuZXdUaW1lcklkcywgMCwgdGltZXJJZHMubGVuZ3RoKTsKKwkJdGltZXJJZHMgPSBuZXdUaW1lcklkczsKIAl9Ci0JaW50W10gdGltZXI9IG5ldyBpbnRbMV07Ci0JT1MuSW5zdGFsbEV2ZW50TG9vcFRpbWVyKE9TLkdldEN1cnJlbnRFdmVudExvb3AoKSwgbWlsbGlzZWNvbmRzIC8gMTAwMC4wLCAwLjAsIHRpbWVyUHJvYywgaW5kZXgsIHRpbWVyKTsKLQlpbnQgdGltZXJJRCA9IHRpbWVyWzBdOwotCQotCWlmICh0aW1lcklEICE9IDApIHsKLQkJdGltZXJJRHMgW2luZGV4XSA9IHRpbWVySUQ7CisJaW50IFtdIHRpbWVySWQgPSBuZXcgaW50IFsxXTsKKwlpbnQgZXZlbnRMb29wID0gT1MuR2V0Q3VycmVudEV2ZW50TG9vcCAoKTsKKwlPUy5JbnN0YWxsRXZlbnRMb29wVGltZXIgKGV2ZW50TG9vcCwgbWlsbGlzZWNvbmRzIC8gMTAwMC4wLCAwLjAsIHRpbWVyUHJvYywgaW5kZXgsIHRpbWVySWQpOworCWlmICh0aW1lcklkIFswXSAhPSAwKSB7CisJCXRpbWVySWRzIFtpbmRleF0gPSB0aW1lcklkIFswXTsKIAkJdGltZXJMaXN0IFtpbmRleF0gPSBydW5uYWJsZTsKIAl9CiB9CisKIGludCB0aW1lclByb2MgKGludCBpZCwgaW50IGluZGV4KSB7Ci0JaWYgKGlkICE9IDApCi0JCU9TLlJlbW92ZUV2ZW50TG9vcFRpbWVyKGlkKTsKIAlpZiAodGltZXJMaXN0ID09IG51bGwpIHJldHVybiAwOwogCWlmICgwIDw9IGluZGV4ICYmIGluZGV4IDwgdGltZXJMaXN0Lmxlbmd0aCkgewogCQlSdW5uYWJsZSBydW5uYWJsZSA9IHRpbWVyTGlzdCBbaW5kZXhdOwogCQl0aW1lckxpc3QgW2luZGV4XSA9IG51bGw7Ci0JCXRpbWVySURzIFtpbmRleF0gPSAwOworCQl0aW1lcklkcyBbaW5kZXhdID0gMDsKIAkJaWYgKHJ1bm5hYmxlICE9IG51bGwpIHJ1bm5hYmxlLnJ1biAoKTsKIAl9CiAJcmV0dXJuIDA7CiB9Ci1zdGF0aWMgaW50IHRyYW5zbGF0ZUtleSAoaW50IGtleSkgewotCWZvciAoaW50IGk9MDsgaTxLZXlUYWJsZS5sZW5ndGg7IGkrKykgewotCQlpZiAoS2V5VGFibGUgW2ldIFswXSA9PSBrZXkpIHJldHVybiBLZXlUYWJsZSBbaV0gWzFdOwotCX0KLQlyZXR1cm4gMDsKKworaW50IHRyYWNraW5nUHJvYyAoaW50IGJyb3dzZXIsIGludCBpdGVtSUQsIGludCBwcm9wZXJ0eSwgaW50IHRoZVJlY3QsIGludCBzdGFydFB0LCBpbnQgbW9kaWZpZXJzKSB7CisJV2lkZ2V0IHdpZGdldCA9IFdpZGdldFRhYmxlLmdldCAoYnJvd3Nlcik7CisJaWYgKHdpZGdldCAhPSBudWxsKSByZXR1cm4gd2lkZ2V0LnRyYWNraW5nUHJvYyAoYnJvd3NlciwgaXRlbUlELCBwcm9wZXJ0eSwgdGhlUmVjdCwgc3RhcnRQdCwgbW9kaWZpZXJzKTsKKwlyZXR1cm4gT1Mubm9FcnI7CiB9Ci1zdGF0aWMgaW50IHVudHJhbnNsYXRlS2V5IChpbnQga2V5KSB7Ci0JZm9yIChpbnQgaT0wOyBpPEtleVRhYmxlLmxlbmd0aDsgaSsrKSB7Ci0JCWlmIChLZXlUYWJsZSBbaV0gWzFdID09IGtleSkgcmV0dXJuIEtleVRhYmxlIFtpXSBbMF07Ci0JfQotCXJldHVybiAwOwotfQotLyoqCi0gKiBGb3JjZXMgYWxsIG91dHN0YW5kaW5nIHBhaW50IHJlcXVlc3RzIGZvciB0aGUgZGlzcGxheQotICogdG8gYmUgcHJvY2Vzc2VkIGJlZm9yZSB0aGlzIG1ldGhvZCByZXR1cm5zLgotICoKLSAqIEBzZWUgQ29udHJvbCN1cGRhdGUKLSAqLworCiBwdWJsaWMgdm9pZCB1cGRhdGUgKCkgewogCWNoZWNrRGV2aWNlICgpOwotCS8qIEFXCi0JWEFueUV2ZW50IGV2ZW50ID0gbmV3IFhBbnlFdmVudCAoKTsKLQlpbnQgbWFzayA9IE9TLkV4cG9zdXJlTWFzayB8IE9TLlJlc2l6ZVJlZGlyZWN0TWFzayB8Ci0JCU9TLlN0cnVjdHVyZU5vdGlmeU1hc2sgfCBPUy5TdWJzdHJ1Y3R1cmVOb3RpZnlNYXNrIHwKLQkJT1MuU3Vic3RydWN0dXJlUmVkaXJlY3RNYXNrOwotCU9TLlhTeW5jICh4RGlzcGxheSwgZmFsc2UpOyBPUy5YU3luYyAoeERpc3BsYXksIGZhbHNlKTsKLQl3aGlsZSAoT1MuWENoZWNrTWFza0V2ZW50ICh4RGlzcGxheSwgbWFzaywgZXZlbnQpKSBPUy5YdERpc3BhdGNoRXZlbnQgKGV2ZW50KTsKLQkqLwotCWludCB3SGFuZGxlPSAwOwotCWludFtdIG1hY0V2ZW50PSBuZXcgaW50WzZdOwotCXdoaWxlIChPUy5HZXROZXh0RXZlbnQoT1MudXBkYXRlTWFzaywgbWFjRXZlbnQpKSB7Ci0JCWlmIChtYWNFdmVudFswXSA9PSBPUy51cGRhdGVFdnQpIHsKLQkJCXdIYW5kbGU9IG1hY0V2ZW50WzFdOwotCQkJdXBkYXRlV2luZG93KHdIYW5kbGUpOwotCQl9CisJaW50IFtdIG91dEV2ZW50ID0gbmV3IGludCBbMV07CisJaW50IFtdIG1hc2sgPSBuZXcgaW50IFtdIHtPUy5rRXZlbnRDbGFzc1dpbmRvdywgT1Mua0V2ZW50V2luZG93VXBkYXRlfTsKKwl3aGlsZSAoT1MuUmVjZWl2ZU5leHRFdmVudCAobWFzay5sZW5ndGggLyAyLCBtYXNrLCBPUy5rRXZlbnREdXJhdGlvbk5vV2FpdCwgdHJ1ZSwgb3V0RXZlbnQpID09IE9TLm5vRXJyKSB7CisJCU9TLlNlbmRFdmVudFRvRXZlbnRUYXJnZXQgKG91dEV2ZW50IFswXSwgT1MuR2V0RXZlbnREaXNwYXRjaGVyVGFyZ2V0ICgpKTsKKwkJT1MuUmVsZWFzZUV2ZW50IChvdXRFdmVudCBbMF0pOworCX0KK30KKwordm9pZCB1cGRhdGVNZW51QmFyICgpIHsKKwl1cGRhdGVNZW51QmFyIChnZXRBY3RpdmVTaGVsbCAoKSk7Cit9CisKK3ZvaWQgdXBkYXRlTWVudUJhciAoU2hlbGwgc2hlbGwpIHsKKwlpZiAoc2hlbGwgPT0gbnVsbCkgc2hlbGwgPSBnZXRBY3RpdmVTaGVsbCAoKTsKKwlib29sZWFuIG1vZGFsID0gZmFsc2U7CisJaW50IG1hc2sgPSBTV1QuUFJJTUFSWV9NT0RBTCB8IFNXVC5BUFBMSUNBVElPTl9NT0RBTCB8IFNXVC5TWVNURU1fTU9EQUw7CisJd2hpbGUgKHNoZWxsICE9IG51bGwpIHsKKwkJaWYgKHNoZWxsLm1lbnVCYXIgIT0gbnVsbCkgYnJlYWs7CisJCWlmICgoc2hlbGwuc3R5bGUgJiBtYXNrKSAhPSAwKSBtb2RhbCA9IHRydWU7CisJCXNoZWxsID0gKFNoZWxsKSBzaGVsbC5wYXJlbnQ7CiAJfQogCS8qCi0JaWYgKHdIYW5kbGUgIT0gMCkgewotCQlpbnQgcG9ydD0gT1MuR2V0V2luZG93UG9ydCh3SGFuZGxlKTsKLQkJaWYgKHBvcnQgIT0gMCkKLQkJCU9TLlFERmx1c2hQb3J0QnVmZmVyKHBvcnQsIDApOwotCX0KKwkqIEZlYXR1cmUgaW4gdGhlIE1hY2ludG9zaC4gIEZvciBzb21lIHJlYXNvbiwgd2hlbiBhIG1vZGFsIHNoZWxsCisJKiBpcyBhY3RpdmUsIERpc2FibGVNZW51SXRlbSgpIHdoZW4gY2FsbGVkIHdpdGggemVybyAoaW5kaWNhdGluZworCSogdGhhdCB0aGUgZW50aXJlIG1lbnUgaXMgdG8gYmUgZGlzYWJsZWQpIHdpbGwgbm90IGRpc2FibGUgdGhlCisJKiBjdXJyZW50IG1lbnUgYmFyLiAgVGhlIGZpeCBpcyB0byBkaXNhYmxlIGVhY2ggaW5kaXZpZHVhbCBtZW51CisJKiBpdGVtLgogCSovCisJaWYgKG1lbnVCYXIgIT0gbnVsbCkgeworCQlNZW51SXRlbSBbXSBpdGVtcyA9IG1lbnVCYXIuZ2V0SXRlbXMgKCk7CisJCWZvciAoaW50IGk9MDsgaTxpdGVtcy5sZW5ndGg7IGkrKykgeworCQkJaWYgKGl0ZW1zIFtpXS5nZXRFbmFibGVkICgpKSBpdGVtcyBbaV0uX3NldEVuYWJsZWQgKHRydWUpOworCQl9CisJfQorCXNldE1lbnVCYXIgKHNoZWxsICE9IG51bGwgPyBzaGVsbC5tZW51QmFyIDogbnVsbCk7CisJaWYgKG1lbnVCYXIgIT0gbnVsbCAmJiBtb2RhbCkgeworCQlpbnQgdGhlTWVudSA9IG1lbnVCYXIuaGFuZGxlOworCQlNZW51SXRlbSBbXSBpdGVtcyA9IG1lbnVCYXIuZ2V0SXRlbXMgKCk7CisJCWZvciAoaW50IGk9MDsgaTxpdGVtcy5sZW5ndGg7IGkrKykgaXRlbXMgW2ldLl9zZXRFbmFibGVkIChmYWxzZSk7CisJfQogfQotLyoqCi0gKiBJZiB0aGUgcmVjZWl2ZXIncyB1c2VyLWludGVyZmFjZSB0aHJlYWQgd2FzIDxjb2RlPnNsZWVwPC9jb2RlPidpbmcsIAotICogY2F1c2VzIGl0IHRvIGJlIGF3YWtlbmVkIGFuZCBzdGFydCBydW5uaW5nIGFnYWluLiBOb3RlIHRoYXQgdGhpcwotICogbWV0aG9kIG1heSBiZSBjYWxsZWQgZnJvbSBhbnkgdGhyZWFkLgotICoKLSAqIEBzZWUgI3NsZWVwCi0gKi8KKwogcHVibGljIHZvaWQgd2FrZSAoKSB7CiAJaWYgKGlzRGlzcG9zZWQgKCkpIGVycm9yIChTV1QuRVJST1JfREVWSUNFX0RJU1BPU0VEKTsKIAlpZiAodGhyZWFkID09IFRocmVhZC5jdXJyZW50VGhyZWFkICgpKSByZXR1cm47Ci0JLyogU2VuZCBhIHVzZXIgZXZlbnQgdG8gd2FrZSB1cCBpbiBSZWNlaXZlTmV4dEV2ZW50ICovCi0Jc2VuZFVzZXJFdmVudCg1NDMyMik7Ci19Ci1wdWJsaWMgaW50IHdpbmRvd1Byb2MgKGludCBoYW5kbGUsIGludCBjbGllbnREYXRhKSB7Ci0JV2lkZ2V0IHdpZGdldCA9IFdpZGdldFRhYmxlLmdldCAoaGFuZGxlKTsKLQlpZiAod2lkZ2V0ID09IG51bGwpIHJldHVybiAwOwotCXJldHVybiB3aWRnZXQucHJvY2Vzc0V2ZW50IChjbGllbnREYXRhKTsKLX0KLXB1YmxpYyBpbnQgd2luZG93UHJvYyAoaW50IGhhbmRsZSwgYm9vbGVhbiBjYWxsRGF0YSkgewotCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKGhhbmRsZSk7Ci0JaWYgKHdpZGdldCA9PSBudWxsKSByZXR1cm4gMDsKLQlyZXR1cm4gd2lkZ2V0LnByb2Nlc3NTZXRGb2N1cyAobmV3IEJvb2xlYW4oY2FsbERhdGEpKTsKLX0KLXB1YmxpYyBpbnQgd2luZG93UHJvYyAoaW50IGhhbmRsZSwgaW50IGNsaWVudERhdGEsIGludCBjYWxsRGF0YSkgewotCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKGhhbmRsZSk7Ci0JaWYgKHdpZGdldCA9PSBudWxsKSByZXR1cm4gMDsKLQlyZXR1cm4gd2lkZ2V0LnByb2Nlc3NSZXNpemUgKG5ldyBJbnRlZ2VyKGNhbGxEYXRhKSk7Ci19Ci1wdWJsaWMgaW50IHdpbmRvd1Byb2MgKGludCBoYW5kbGUsIGludCBjbGllbnREYXRhLCBNYWNFdmVudCBjYWxsRGF0YSkgewotCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKGhhbmRsZSk7Ci0JaWYgKHdpZGdldCA9PSBudWxsKSByZXR1cm4gMDsKLQlyZXR1cm4gd2lkZ2V0LnByb2Nlc3NFdmVudCAoY2xpZW50RGF0YSwgY2FsbERhdGEpOwotfQotcHVibGljIGludCB3aW5kb3dQcm9jIChpbnQgaGFuZGxlLCBpbnQgY2xpZW50RGF0YSwgTWFjTW91c2VFdmVudCBtbWUpIHsKLQlXaWRnZXQgd2lkZ2V0ID0gV2lkZ2V0VGFibGUuZ2V0IChoYW5kbGUpOwotCWlmICh3aWRnZXQgPT0gbnVsbCkgcmV0dXJuIDA7Ci0JcmV0dXJuIHdpZGdldC5wcm9jZXNzRXZlbnQgKGNsaWVudERhdGEsIG1tZSk7Ci19Ci1wdWJsaWMgaW50IHdpbmRvd1Byb2MgKGludCBoYW5kbGUsIGludCBjbGllbnREYXRhLCBNYWNDb250cm9sRXZlbnQgbWNlKSB7Ci0JV2lkZ2V0IHdpZGdldCA9IFdpZGdldFRhYmxlLmdldCAoaGFuZGxlKTsKLQlpZiAod2lkZ2V0ID09IG51bGwpIHJldHVybiAwOwotCXJldHVybiB3aWRnZXQucHJvY2Vzc0V2ZW50IChjbGllbnREYXRhLCBtY2UpOwotfQotc3RhdGljIFN0cmluZyBjb252ZXJ0VG9MZihTdHJpbmcgdGV4dCkgewotCWNoYXIgQ3IgPSAnXHInOwotCWNoYXIgTGYgPSAnXG4nOwotCWludCBsZW5ndGggPSB0ZXh0Lmxlbmd0aCAoKTsKLQlpZiAobGVuZ3RoID09IDApIHJldHVybiB0ZXh0OwotCQotCS8qIENoZWNrIGZvciBhbiBMRiBvciBDUi9MRi4gIEFzc3VtZSB0aGUgcmVzdCBvZiB0aGUgc3RyaW5nIAotCSAqIGlzIGZvcm1hdHRlZCB0aGF0IHdheS4gIFRoaXMgd2lsbCBub3Qgd29yayBpZiB0aGUgc3RyaW5nIAotCSAqIGNvbnRhaW5zIG1peGVkIGRlbGltaXRlcnMuICovCi0JaW50IGkgPSB0ZXh0LmluZGV4T2YgKExmLCAwKTsKLQlpZiAoaSA9PSAtMSB8fCBpID09IDApIHJldHVybiB0ZXh0OwotCWlmICh0ZXh0LmNoYXJBdCAoaSAtIDEpICE9IENyKSByZXR1cm4gdGV4dDsKLQotCS8qIFRoZSBzdHJpbmcgaXMgZm9ybWF0dGVkIHdpdGggQ1IvTEYuCi0JICogQ3JlYXRlIGEgbmV3IHN0cmluZyB3aXRoIHRoZSBMRiBsaW5lIGRlbGltaXRlci4gKi8KLQlpID0gMDsKLQlTdHJpbmdCdWZmZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1ZmZlciAoKTsKLQl3aGlsZSAoaSA8IGxlbmd0aCkgewotCQlpbnQgaiA9IHRleHQuaW5kZXhPZiAoQ3IsIGkpOwotCQlpZiAoaiA9PSAtMSkgaiA9IGxlbmd0aDsKLQkJU3RyaW5nIHMgPSB0ZXh0LnN1YnN0cmluZyAoaSwgaik7Ci0JCXJlc3VsdC5hcHBlbmQgKHMpOwotCQlpID0gaiArIDI7Ci0JCXJlc3VsdC5hcHBlbmQgKExmKTsKLQl9Ci0JcmV0dXJuIHJlc3VsdC50b1N0cmluZyAoKTsKKwlpbnQgW10gZXZlbnQgPSBuZXcgaW50IFsxXTsKKwlPUy5DcmVhdGVFdmVudCAoMCwgMCwgMCwgMC4wLCBPUy5rRXZlbnRBdHRyaWJ1dGVVc2VyRXZlbnQsIGV2ZW50KTsKKwlPUy5Qb3N0RXZlbnRUb1F1ZXVlIChxdWV1ZSwgZXZlbnQgWzBdLCAoc2hvcnQpIE9TLmtFdmVudFByaW9yaXR5U3RhbmRhcmQpOwogfQogCi0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0vLyBTb21lIE1hYyBoZWxwZXIgZnVuY3Rpb25zCi0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCitpbnQgd2luZG93UHJvYyAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKHVzZXJEYXRhKTsKKwlpZiAod2lkZ2V0ID09IG51bGwpIHsKKwkJaW50IFtdIHRoZVdpbmRvdyA9IG5ldyBpbnQgWzFdOworCQlPUy5HZXRFdmVudFBhcmFtZXRlciAodGhlRXZlbnQsIE9TLmtFdmVudFBhcmFtRGlyZWN0T2JqZWN0LCBPUy50eXBlV2luZG93UmVmLCBudWxsLCA0LCBudWxsLCB0aGVXaW5kb3cpOworCQlpbnQgW10gdGhlUm9vdCA9IG5ldyBpbnQgWzFdOworCQlPUy5HZXRSb290Q29udHJvbCAodGhlV2luZG93IFswXSwgdGhlUm9vdCk7CisJCXdpZGdldCA9IFdpZGdldFRhYmxlLmdldCAodGhlUm9vdCBbMF0pOworCX0KKwlpZiAod2lkZ2V0ICE9IG51bGwpICByZXR1cm4gd2lkZ2V0LndpbmRvd1Byb2MgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOyAKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQogCi0JaW50IG5leHRNZW51SWQoKSB7Ci0JCXJldHVybiBmTWVudUlkKys7Ci0JfQotCi0Jdm9pZCBmbHVzaCAoaW50IGNIYW5kbGUpIHsKLQkJaW50IHdIYW5kbGU9IE9TLkdldENvbnRyb2xPd25lcihjSGFuZGxlKTsKLQkJaWYgKHdIYW5kbGUgIT0gMCkgewotCQkJaW50IHBvcnQ9IE9TLkdldFdpbmRvd1BvcnQod0hhbmRsZSk7Ci0JCQlpZiAocG9ydCAhPSAwKQotCQkJCU9TLlFERmx1c2hQb3J0QnVmZmVyKHBvcnQsIDApOwotCQl9Ci0JfQotCQotCS8vLS0tLSBjYWxsYmFja3MKLQkKLQlwcml2YXRlIGludCBoYW5kbGVDb250cm9sQWN0aW9uKGludCBjSGFuZGxlLCBpbnQgcGFydENvZGUpIHsKLQkJaWYgKE1hY1V0aWwuSElWSUVXKQotCQkJU3lzdGVtLm91dC5wcmludGxuKCJEaXNwbGF5LmhhbmRsZUNvbnRyb2xBY3Rpb246ICIgKyBjSGFuZGxlICsgIiAiICsgcGFydENvZGUpOwotCQlyZXR1cm4gd2luZG93UHJvYyhjSGFuZGxlLCBTV1QuU2VsZWN0aW9uLCBuZXcgTWFjQ29udHJvbEV2ZW50KGNIYW5kbGUsIHBhcnRDb2RlLCB0cnVlKSk7Ci0JfQotCi0JcHJpdmF0ZSBpbnQgaGFuZGxlVXNlclBhbmVEcmF3KGludCBjSGFuZGxlLCBpbnQgcGFydENvZGUpIHsKLQkJaW50IHVwZGF0ZVJnbj0gZlVwZGF0ZVJlZ2lvbjsKLQkJaWYgKHVwZGF0ZVJnbiA9PSAwKSB7Ci0JCQl1cGRhdGVSZ249IE9TLk5ld1JnbigpOwotCQkJaW50IHdIYW5kbGU9IE9TLkdldENvbnRyb2xPd25lcihjSGFuZGxlKTsKLQkJCU9TLkdldFBvcnRWaXNpYmxlUmVnaW9uKE9TLkdldFdpbmRvd1BvcnQod0hhbmRsZSksIHVwZGF0ZVJnbik7Ci0JCX0KLQkJaW50IHN0YXR1cz0gd2luZG93UHJvYyhjSGFuZGxlLCBTV1QuUGFpbnQsIG5ldyBNYWNDb250cm9sRXZlbnQoY0hhbmRsZSwgZlVwZGF0ZVJlZ2lvbikpOwotCQlpZiAodXBkYXRlUmduICE9IGZVcGRhdGVSZWdpb24gJiYgdXBkYXRlUmduICE9IDApCi0JCQlPUy5EaXNwb3NlUmduKHVwZGF0ZVJnbik7Ci0JCXJldHVybiBzdGF0dXM7Ci0JfQotCQkKLQlwcml2YXRlIGludCBoYW5kbGVVc2VyUGFuZUhpdFRlc3QoaW50IGNIYW5kbGUsIGludCB3aGVyZSkgewotCQlpZiAoTWFjVXRpbC5ISVZJRVcpCi0JCQlTeXN0ZW0ub3V0LnByaW50bG4oImhhbmRsZVVzZXJQYW5lSGl0VGVzdCIpOwotCQlXaWRnZXQgdz0gV2lkZ2V0VGFibGUuZ2V0KGNIYW5kbGUpOwotCQlpZiAodyBpbnN0YW5jZW9mIFRleHQgfHwgdyBpbnN0YW5jZW9mIENvbWJvKQotCQkJcmV0dXJuIDExMjsKLQkJcmV0dXJuIDExMTsKLQl9Ci0JCQotCXByaXZhdGUgaW50IGhhbmRsZVVzZXJQYW5lVHJhY2tpbmcoaW50IGNIYW5kbGUsIGludCB3aGVyZSwgaW50IGFjdGlvblByb2MpIHsKLQkJCi0JCU1hY1BvaW50IHB0PSBuZXcgTWFjUG9pbnQoT1MuSGlXb3JkKHdoZXJlKSwgT1MuTG9Xb3JkKHdoZXJlKSk7Ci0JCXNob3J0W10gdHJhY2tpbmdSZXN1bHQ9IG5ldyBzaG9ydFsxXTsKLQkJCi0JCVdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZS5nZXQgKGNIYW5kbGUpOwotCQlpZiAod2lkZ2V0ID09IG51bGwpIHJldHVybiAwOwotCi0JCXdpZGdldC5wcm9jZXNzTW91c2VEb3duKG5ldyBNYWNNb3VzZUV2ZW50KDEsIHB0LnRvUG9pbnQoKSkpOwotCQkvL1N5c3RlbS5vdXQucHJpbnRsbigiViIgKyBwdC50b1BvaW50KCkpOwotCQkKLQkJLyoKLQkJTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JCU9TLkdldENvbnRyb2xCb3VuZHMoY0hhbmRsZSwgYm91bmRzLmdldERhdGEoKSk7Ci0JCWludCB4PSBib3VuZHMuZ2V0WCgpOwotCQlpbnQgeT0gYm91bmRzLmdldFkoKTsKLQkJU3lzdGVtLm91dC5wcmludGxuKCJCb3VuZHMiICsgYm91bmRzLnRvUmVjdGFuZ2xlKCkpOwotCQkqLwotCQkKLQkJd2hpbGUgKHRydWUpIHsKLQkJCU9TLlRyYWNrTW91c2VMb2NhdGlvbigwLCBwdC5nZXREYXRhKCksIHRyYWNraW5nUmVzdWx0KTsKLQkJCVBvaW50IHA9IHB0LnRvUG9pbnQoKTsKLQkJCXAueC09IDEwMDsKLQkJCXAueS09IDEwMAotCQkJOwotCQkJc3dpdGNoICh0cmFja2luZ1Jlc3VsdFswXSkgewotCQkJY2FzZSA1OiAvLyBrTW91c2VUcmFja2luZ01vdXNlRHJhZ2dlZAotCQkJCXdpZGdldC5wcm9jZXNzTW91c2VNb3ZlKG5ldyBNYWNNb3VzZUV2ZW50KDEsIHApKTsKLQkJCQkvL1N5c3RlbS5vdXQucHJpbnRsbigiLSIgKyBwKTsKLQkJCQlicmVhazsKLQkJCWNhc2UgMjogLy8ga01vdXNlVHJhY2tpbmdNb3VzZVVwCi0JCQljYXNlIDc6IC8vIGtNb3VzZVRyYWNraW5nVXNlckNhbmNlbGxlZAotCQkJCXdpZGdldC5wcm9jZXNzTW91c2VVcChuZXcgTWFjTW91c2VFdmVudCgxLCBwKSk7Ci0JCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIkEiICsgcCk7Ci0JCQkJcmV0dXJuIDA7Ci0JCQl9Ci0JCX0KLQl9Ci0JCi0JcHJpdmF0ZSBpbnQgaGFuZGxlRGF0YUJyb3dzZXJEYXRhQ2FsbGJhY2soaW50IGNIYW5kbGUsIGludCBpdGVtLCBpbnQgcHJvcGVydHksIGludCBpdGVtRGF0YSwgaW50IHNldFZhbHVlKSB7Ci0JCVdpZGdldCB3aWRnZXQ9IFdpZGdldFRhYmxlLmdldChjSGFuZGxlKTsKLQkJaWYgKHdpZGdldCBpbnN0YW5jZW9mIExpc3QpIHsKLQkJCUxpc3QgbGlzdD0gKExpc3QpIHdpZGdldDsKLQkJCXJldHVybiBsaXN0LmhhbmRsZUl0ZW1DYWxsYmFjayhpdGVtLCBwcm9wZXJ0eSwgaXRlbURhdGEpOwotCQl9Ci0JCWlmICh3aWRnZXQgaW5zdGFuY2VvZiBUcmVlMikgewotCQkJVHJlZTIgdHJlZT0gKFRyZWUyKSB3aWRnZXQ7Ci0JCQlyZXR1cm4gdHJlZS5oYW5kbGVJdGVtQ2FsbGJhY2soaXRlbSwgcHJvcGVydHksIGl0ZW1EYXRhLCBzZXRWYWx1ZSk7Ci0JCX0KLQkJcmV0dXJuIE9TLmtOb0VycjsKLQl9Ci0JCi0JcHJpdmF0ZSBpbnQgaGFuZGxlRGF0YUJyb3dzZXJDb21wYXJlQ2FsbGJhY2soaW50IGNIYW5kbGUsIGludCBpdGVtMUlELCBpbnQgaXRlbTJJRCwgaW50IHNvcnRJRCkgewotCQlXaWRnZXQgd2lkZ2V0PSBXaWRnZXRUYWJsZS5nZXQoY0hhbmRsZSk7Ci0JCWlmICh3aWRnZXQgaW5zdGFuY2VvZiBMaXN0KSB7Ci0JCQlMaXN0IGxpc3Q9IChMaXN0KSB3aWRnZXQ7Ci0JCQlyZXR1cm4gbGlzdC5oYW5kbGVDb21wYXJlQ2FsbGJhY2soaXRlbTFJRCwgaXRlbTJJRCwgc29ydElEKTsKLQkJfQotCQlpZiAod2lkZ2V0IGluc3RhbmNlb2YgVHJlZTIpIHsKLQkJCVRyZWUyIHRyZWU9IChUcmVlMikgd2lkZ2V0OwotCQkJcmV0dXJuIHRyZWUuaGFuZGxlQ29tcGFyZUNhbGxiYWNrKGl0ZW0xSUQsIGl0ZW0ySUQsIHNvcnRJRCk7Ci0JCX0KLQkJcmV0dXJuIE9TLmtOb0VycjsKLQl9Ci0JCi0JcHJpdmF0ZSBpbnQgaGFuZGxlRGF0YUJyb3dzZXJJdGVtTm90aWZpY2F0aW9uQ2FsbGJhY2soaW50IGNIYW5kbGUsIGludCBpdGVtLCBpbnQgbWVzc2FnZSkgewotCQlXaWRnZXQgd2lkZ2V0PSBXaWRnZXRUYWJsZS5nZXQoY0hhbmRsZSk7Ci0JCWlmICh3aWRnZXQgaW5zdGFuY2VvZiBMaXN0KSB7Ci0JCQlMaXN0IGxpc3Q9IChMaXN0KSB3aWRnZXQ7Ci0JCQlyZXR1cm4gbGlzdC5oYW5kbGVJdGVtTm90aWZpY2F0aW9uQ2FsbGJhY2soaXRlbSwgbWVzc2FnZSk7Ci0JCX0KLQkJaWYgKHdpZGdldCBpbnN0YW5jZW9mIFRyZWUyKSB7Ci0JCQlUcmVlMiB0cmVlPSAoVHJlZTIpIHdpZGdldDsKLQkJCXJldHVybiB0cmVlLmhhbmRsZUl0ZW1Ob3RpZmljYXRpb25DYWxsYmFjayhpdGVtLCBtZXNzYWdlKTsKLQkJfQotLy8JCWlmIChtZXNzYWdlID09IDE0KSB7CS8vIHNlbGVjdGlvbiBjaGFuZ2VkCi0vLwkJCXdpbmRvd1Byb2MoY0hhbmRsZSwgU1dULlNlbGVjdGlvbiwgbmV3IE1hY0NvbnRyb2xFdmVudChjSGFuZGxlLCBpdGVtLCBmYWxzZSkpOwotLy8JCX0KLQkJcmV0dXJuIE9TLmtOb0VycjsKLQl9Ci0JCi0JcHJpdmF0ZSBpbnQgaGFuZGxlTWVudUNhbGxiYWNrKGludCBuZXh0SGFuZGxlciwgaW50IGVIYW5kbGUsIGludCBtSGFuZGxlKSB7Ci0JCXN3aXRjaCAoT1MuR2V0RXZlbnRLaW5kKGVIYW5kbGUpKSB7Ci0JCWNhc2UgT1Mua0V2ZW50TWVudVBvcHVsYXRlOgotCQljYXNlIE9TLmtFdmVudE1lbnVPcGVuaW5nOgotCQkKLQkJCWlmIChmSW5Db250ZXh0TWVudSkKLQkJCQlPUy5TZXRNZW51Rm9udChtSGFuZGxlLCAoc2hvcnQpMTAyNCwgKHNob3J0KTExKTsJLy8gQVc6IEZJWE1FIG1lbnUgaWQKLQkJCS8qCi0JCQkvLyBjb3B5IHRoZSBtZW51J3MgZm9udAotCQkJc2hvcnRbXSBmb250SUQ9IG5ldyBzaG9ydFsxXTsKLQkJCXNob3J0W10gc2l6ZT0gbmV3IHNob3J0WzFdOwotCQkJT1MuR2V0TWVudUZvbnQoaE1lbnUsIGZvbnRJRCwgc2l6ZSk7Ci0JCQlPUy5TZXRNZW51Rm9udChtZW51LmhhbmRsZSwgZm9udElEWzBdLCBzaXplWzBdKTsKLQkJCSovIAotCQkKLQkJCXdpbmRvd1Byb2MobUhhbmRsZSwgU1dULlNob3csIG5ldyBNYWNFdmVudChlSGFuZGxlLCBuZXh0SGFuZGxlcikpOwotCQkJYnJlYWs7Ci0JCWNhc2UgT1Mua0V2ZW50TWVudUNsb3NlZDoKLQkJCXdpbmRvd1Byb2MobUhhbmRsZSwgU1dULkhpZGUsIG5ldyBNYWNFdmVudChlSGFuZGxlLCBuZXh0SGFuZGxlcikpOwotCQkJYnJlYWs7Ci0JCX0KLQkJcmV0dXJuIE9TLmtOb0VycjsKLQl9Ci0JCi0JcHJpdmF0ZSBpbnQgaGFuZGxlVGV4dENhbGxiYWNrKGludCBuZXh0SGFuZGxlciwgaW50IGVSZWZIYW5kbGUsIGludCB1c2VyRGF0YSkgewotCQkKLQkJaW50IGV2ZW50Q2xhc3M9IE9TLkdldEV2ZW50Q2xhc3MoZVJlZkhhbmRsZSk7Ci0JCWludCBldmVudEtpbmQ9IE9TLkdldEV2ZW50S2luZChlUmVmSGFuZGxlKTsKLQkJCi0JCXN3aXRjaCAoZXZlbnRDbGFzcykgewotCQkJCi0JCWNhc2UgT1Mua0V2ZW50Q2xhc3NUZXh0SW5wdXQ6Ci0JCQlzd2l0Y2ggKGV2ZW50S2luZCkgewotCQkJY2FzZSBPUy5rRXZlbnRUZXh0SW5wdXRVbmljb2RlRm9yS2V5RXZlbnQ6Ci0JCQkJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKLQkJCWRlZmF1bHQ6Ci0JCQkJU3lzdGVtLm91dC5wcmludGxuKCJEaXNwbGF5LmhhbmRsZVRleHRDYWxsYmFjazoga0V2ZW50Q2xhc3NUZXh0SW5wdXQ6IHVuZXhwZWN0ZWQgZXZlbnQga2luZCIpOwotCQkJCWJyZWFrOwotCQkJfQotCQkJYnJlYWs7Ci0JCQkKLQkJY2FzZSBPUy5rRXZlbnRDbGFzc0tleWJvYXJkOgotCQkKLQkJCS8vIGRlY2lkZSB3aGV0aGVyIGEgU1dUIGNvbnRyb2wgaGFzIHRoZSBmb2N1cwotCQkJQ29udHJvbCBmb2N1cz0gZ2V0Rm9jdXNDb250cm9sKCk7Ci0JCQlpZiAoZm9jdXMgPT0gbnVsbCB8fCBmb2N1cy5oYW5kbGUgPT0gMCkKLQkJCQlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOwotCQkJCQotCQkJaW50IGZyb250V2luZG93PSBPUy5Gcm9udFdpbmRvdygpOwotCQkJaWYgKGZpbmRXaWRnZXQoZnJvbnRXaW5kb3cpID09IG51bGwpIHsKLQkJCQlpbnQgdz0gT1MuR2V0Q29udHJvbE93bmVyKGZvY3VzLmhhbmRsZSk7Ci0JCQkJaWYgKHcgIT0gT1MuRnJvbnRXaW5kb3coKSkJLy8gaXRzIHByb2JhYmx5IGEgc3RhbmRhcmQgZGlhbG9nCi0JCQkJCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Ci0JCQl9Ci0JCQkJCQkKLQkJCXN3aXRjaCAoZXZlbnRLaW5kKSB7Ci0JCQljYXNlIE9TLmtFdmVudFJhd0tleURvd246Ci0JCQkJaWYgKE1hY0V2ZW50LmdldEtleUNvZGUoZVJlZkhhbmRsZSkgPT0gMTIyKSB7CS8vIGhlbHAga2V5IGYxCi0JCQkJCXdpbmRvd1Byb2MoZm9jdXMuaGFuZGxlLCBTV1QuSGVscCk7Ci0JCQkJCXJldHVybiBPUy5rTm9FcnI7Ci0JCQkJfQotCQkJCS8vIGZhbGwgdGhyb3VnaCEKLQkJCWNhc2UgT1Mua0V2ZW50UmF3S2V5UmVwZWF0OgotCQkJCXJldHVybiBmb2N1cy5wcm9jZXNzRXZlbnQoU1dULktleURvd24sIG5ldyBNYWNFdmVudChlUmVmSGFuZGxlLCBuZXh0SGFuZGxlcikpOwotCQkJCQotCQkJY2FzZSBPUy5rRXZlbnRSYXdLZXlVcDoKLQkJCQlyZXR1cm4gZm9jdXMucHJvY2Vzc0V2ZW50KFNXVC5LZXlVcCwgbmV3IE1hY0V2ZW50KGVSZWZIYW5kbGUsIG5leHRIYW5kbGVyKSk7Ci0JCQkJCi0JCQlkZWZhdWx0OgotCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiRGlzcGxheS5oYW5kbGVUZXh0Q2FsbGJhY2s6IGtFdmVudENsYXNzS2V5Ym9hcmQ6IHVuZXhwZWN0ZWQgZXZlbnQga2luZCIpOwotCQkJCWJyZWFrOwotCQkJfQotCQkJYnJlYWs7Ci0JCQkKLQkJZGVmYXVsdDoKLQkJCVN5c3RlbS5vdXQucHJpbnRsbigiRGlzcGxheS5oYW5kbGVUZXh0Q2FsbGJhY2s6IHVuZXhwZWN0ZWQgZXZlbnQgY2xhc3MiKTsKLQkJCWJyZWFrOwotCQl9Ci0JCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Ci0JfQotCQotCXByaXZhdGUgaW50IGhhbmRsZU1vdXNlQ2FsbGJhY2soaW50IG5leHRIYW5kbGVyLCBpbnQgZVJlZkhhbmRsZSwgaW50IHdoaWNoV2luZG93KSB7Ci0JCWludCBldmVudENsYXNzPSBPUy5HZXRFdmVudENsYXNzKGVSZWZIYW5kbGUpOwotCQlpbnQgZXZlbnRLaW5kPSBPUy5HZXRFdmVudEtpbmQoZVJlZkhhbmRsZSk7Ci0JCQotCQlzd2l0Y2ggKGV2ZW50Q2xhc3MpIHsKLQkJCQotCQljYXNlIE9TLmtFdmVudENsYXNzTW91c2U6Ci0JCQlyZXR1cm4gaGFuZGxlTW91c2VFdmVudChuZXh0SGFuZGxlciwgZVJlZkhhbmRsZSwgZXZlbnRLaW5kLCB3aGljaFdpbmRvdyk7Ci0JCQotCQlkZWZhdWx0OgotCQkJU3lzdGVtLm91dC5wcmludGxuKCJoYW5kbGVNb3VzZUNhbGxiYWNrOiB1bmV4cGVjdGVkIGV2ZW50IGNsYXNzOiAiICsgTWFjVXRpbC50b1N0cmluZyhldmVudENsYXNzKSk7Ci0JCQlicmVhazsKLQkJfQotCQlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOwotCX0KLQkKLQlwcml2YXRlIGludCBoYW5kbGVXaW5kb3dDYWxsYmFjayhpbnQgbmV4dEhhbmRsZXIsIGludCBlUmVmSGFuZGxlLCBpbnQgd2hpY2hXaW5kb3cpIHsKLQkJCi0JCWludCBldmVudENsYXNzPSBPUy5HZXRFdmVudENsYXNzKGVSZWZIYW5kbGUpOwotCQlpbnQgZXZlbnRLaW5kPSBPUy5HZXRFdmVudEtpbmQoZVJlZkhhbmRsZSk7Ci0JCQotCQlzd2l0Y2ggKGV2ZW50Q2xhc3MpIHsKLQkJCQotCQljYXNlIE9TLmtFdmVudENsYXNzTW91c2U6Ci0JCQlyZXR1cm4gaGFuZGxlTW91c2VFdmVudChuZXh0SGFuZGxlciwgZVJlZkhhbmRsZSwgZXZlbnRLaW5kLCB3aGljaFdpbmRvdyk7Ci0JCQkKLQkJY2FzZSBPUy5rRXZlbnRDbGFzc1dpbmRvdzoKLQkJCXN3aXRjaCAoZXZlbnRLaW5kKSB7Ci0JCQljYXNlIE9TLmtFdmVudFdpbmRvd0FjdGl2YXRlZDoKLQkJCQlXaWRnZXQgd2lkZ2V0ID0gV2lkZ2V0VGFibGUuZ2V0KHdoaWNoV2luZG93KTsKLQkJCQlpZiAod2lkZ2V0IGluc3RhbmNlb2YgU2hlbGwpCi0JCQkJCWZNZW51Um9vdFNoZWxsPSAoU2hlbGwpIHdpZGdldDsKLQkJCQl3aW5kb3dQcm9jKHdoaWNoV2luZG93LCB0cnVlKTsKLQkJCQlicmVhazsgLy9yZXR1cm4gT1Mua05vRXJyOwotCQkJCQotCQkJY2FzZSBPUy5rRXZlbnRXaW5kb3dEZWFjdGl2YXRlZDoKLQkJCQlmTWVudVJvb3RTaGVsbD0gbnVsbDsKLQkJCQl3aW5kb3dQcm9jKHdoaWNoV2luZG93LCBmYWxzZSk7Ci0JCQkJYnJlYWs7IC8vIHJldHVybiBPUy5rTm9FcnI7Ci0JCQkJCi0JCQljYXNlIE9TLmtFdmVudFdpbmRvd0JvdW5kc0NoYW5nZWQ6Ci0JCQkJaW50W10gYXR0cj0gbmV3IGludFsxXTsKLQkJCQlPUy5HZXRFdmVudFBhcmFtZXRlcihlUmVmSGFuZGxlLCBPUy5rRXZlbnRQYXJhbUF0dHJpYnV0ZXMsIE9TLnR5cGVVSW50MzIsIG51bGwsIG51bGwsIGF0dHIpOwkKLQkJCQl3aW5kb3dQcm9jKHdoaWNoV2luZG93LCBTV1QuUmVzaXplLCBhdHRyWzBdKTsKLQkJCQlyZXR1cm4gT1Mua05vRXJyOwotCQkJCQotCQkJY2FzZSBPUy5rRXZlbnRXaW5kb3dDbG9zZToKLQkJCQl3aW5kb3dQcm9jKHdoaWNoV2luZG93LCBTV1QuRGlzcG9zZSk7Ci0JCQkJcmV0dXJuIE9TLmtOb0VycjsKLQkJCQkKLQkJCWNhc2UgT1Mua0V2ZW50V2luZG93RHJhd0NvbnRlbnQ6Ci0JCQkJaWYgKHRvb2xUaXBXaW5kb3dIYW5kbGUgPT0gd2hpY2hXaW5kb3cpIHsKLQkJCQkJcHJvY2Vzc1BhaW50VG9vbFRpcCh3aGljaFdpbmRvdyk7Ci0JCQkJfSBlbHNlIHsKLQkJCQkJaWYgKE1hY1V0aWwuSElWSUVXKQotCQkJCQkJYnJlYWs7Ci0JCQkJCXVwZGF0ZVdpbmRvdzIod2hpY2hXaW5kb3cpOwotCQkJCX0KLQkJCQlyZXR1cm4gT1Mua05vRXJyOwotCQkJCQotCQkJZGVmYXVsdDoKLQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oImhhbmRsZVdpbmRvd0NhbGxiYWNrOiBrRXZlbnRDbGFzc1dpbmRvdyBraW5kOiIgKyBldmVudEtpbmQpOwotCQkJCWJyZWFrOwotCQkJfQotCQkJYnJlYWs7Ci0JCQkKLQkJZGVmYXVsdDoKLQkJCVN5c3RlbS5vdXQucHJpbnRsbigiaGFuZGxlV2luZG93Q2FsbGJhY2s6IHVuZXhwZWN0ZWQgZXZlbnQgY2xhc3M6ICIgKyBNYWNVdGlsLnRvU3RyaW5nKGV2ZW50Q2xhc3MpKTsKLQkJCWJyZWFrOwotCQl9Ci0JCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Ci0JfQotCQotCXByaXZhdGUgaW50IGhhbmRsZUFwcGxpY2F0aW9uQ2FsbGJhY2soaW50IG5leHRIYW5kbGVyLCBpbnQgZVJlZkhhbmRsZSwgaW50IHVzZXJEYXRhKSB7Ci0JCi0JCWludCBldmVudENsYXNzPSBPUy5HZXRFdmVudENsYXNzKGVSZWZIYW5kbGUpOwotCQlpbnQgZXZlbnRLaW5kPSBPUy5HZXRFdmVudEtpbmQoZVJlZkhhbmRsZSk7Ci0JCQotCQlzd2l0Y2ggKGV2ZW50Q2xhc3MpIHsKLQkJCQotCQljYXNlIE9TLmtFdmVudENsYXNzQXBwbGVFdmVudDoKLQkJCi0JCQkvLyBjaGVjayBmb3IgJ3F1aXQnIGV2ZW50cwotCQkJaW50W10gYWVjbGFzcz0gbmV3IGludFsxXTsKLQkJCWlmIChPUy5HZXRFdmVudFBhcmFtZXRlcihlUmVmSGFuZGxlLCBPUy5rRXZlbnRQYXJhbUFFRXZlbnRDbGFzcywgT1MudHlwZVR5cGUsIG51bGwsIG51bGwsIGFlY2xhc3MpID09IE9TLmtOb0VycikgewotCQkJCS8vIFN5c3RlbS5vdXQucHJpbnRsbigia0V2ZW50Q2xhc3NBcHBsZUV2ZW50OiAiICsgTWFjVXRpbC50b1N0cmluZyhhZWNsYXNzWzBdKSk7Ci0JCQkJaW50W10gYWV0eXBlPSBuZXcgaW50WzFdOwotCQkJCWlmIChPUy5HZXRFdmVudFBhcmFtZXRlcihlUmVmSGFuZGxlLCBPUy5rRXZlbnRQYXJhbUFFRXZlbnRJRCwgT1MudHlwZVR5cGUsIG51bGwsIG51bGwsIGFldHlwZSkgPT0gT1Mua05vRXJyKSB7Ci0JCQkJCS8vU3lzdGVtLm91dC5wcmludGxuKCJrRXZlbnRQYXJhbUFFRXZlbnRJRDogIiArIE1hY1V0aWwudG9TdHJpbmcoYWV0eXBlWzBdKSk7Ci0JCQkJCWlmIChhZXR5cGVbMF0gPT0gT1Mua0FFUXVpdEFwcGxpY2F0aW9uKQotCQkJCQkJY2xvc2UoKTsKLQkJCQl9Ci0JCQl9Ci0JCQkKLQkJCU9TLkFFUHJvY2Vzc0FwcGxlRXZlbnQobmV3IE1hY0V2ZW50KGVSZWZIYW5kbGUpLnRvT2xkTWFjRXZlbnQoKSk7Ci0JCQlicmVhazsKLQkJCQotCQljYXNlIE9TLmtFdmVudENsYXNzQ29tbWFuZDoKLQkJCi0JCQlpZiAoZXZlbnRLaW5kID09IE9TLmtFdmVudFByb2Nlc3NDb21tYW5kKSB7Ci0JCQkJaW50W10gcmM9IG5ldyBpbnRbNF07Ci0JCQkJT1MuR2V0RXZlbnRISUNvbW1hbmQoZVJlZkhhbmRsZSwgcmMpOwotCQkJCQotCQkJCWlmIChyY1sxXSA9PSBPUy5rQUVRdWl0QXBwbGljYXRpb24pIHsKLQkJCQkJY2xvc2UoKTsKLQkJCQkJT1MuSGlsaXRlTWVudSgoc2hvcnQpMCk7CS8vIHVuaGlnaGxpZ2h0IHdoYXQgTWVudVNlbGVjdCAob3IgTWVudUtleSkgaGlsaXRlZAotCQkJCQlyZXR1cm4gT1Mua05vRXJyOwotCQkJCX0KLQkJCQkKLQkJCQkvLyB0cnkgdG8gbWFwIHRoZSBNZW51UmVmIHRvIGEgU1dUIE1lbnUKLQkJCQlXaWRnZXQgdz0gZmluZFdpZGdldCAocmNbMl0pOwotCQkJCWlmICh3IGluc3RhbmNlb2YgTWVudSkgewotCQkJCQlNZW51IG1lbnU9IChNZW51KSB3OwotCQkJCQltZW51LmhhbmRsZU1lbnUocmNbM10pOwotCQkJCQlPUy5IaWxpdGVNZW51KChzaG9ydCkwKTsJLy8gdW5oaWdobGlnaHQgd2hhdCBNZW51U2VsZWN0IChvciBNZW51S2V5KSBoaWxpdGVkCi0JCQkJCXJldHVybiBPUy5rTm9FcnI7Ci0JCQkJfQotCQkJCQotCQkJCQotCQkJCU9TLkhpbGl0ZU1lbnUoKHNob3J0KTApOwkvLyB1bmhpZ2hsaWdodCB3aGF0IE1lbnVTZWxlY3QgKG9yIE1lbnVLZXkpIGhpbGl0ZWQKLQkJCQkvLyB3ZSBkbyBub3QgcmV0dXJuIGtOb0VyciBoZXJlIHNvIHRoYXQgdGhlIGRlZmF1bHQgaGFuZGxlcgotCQkJCS8vIHRha2VzIGNhcmUgb2Ygc3BlY2lhbCBtZW51cyBsaWtlIHRoZSBDb21ibyBtZW51LgotCQkJfQotCQkJYnJlYWs7Ci0JCQotCQljYXNlIE9TLmtFdmVudENsYXNzTW91c2U6Ci0JCQlzd2l0Y2ggKGV2ZW50S2luZCkgewotCQkJCQotCQkJY2FzZSBPUy5rRXZlbnRNb3VzZURvd246Ci0JCQkKLQkJCQlmVHJhY2tlZENvbnRyb2w9IDA7Ci0JCQkJCi0JCQkJaGlkZVRvb2xUaXAoKTsKLQkKLQkJCQlNYWNFdmVudCBtRXZlbnQ9IG5ldyBNYWNFdmVudChlUmVmSGFuZGxlKTsKLQkJCQlNYWNQb2ludCB3aGVyZT0gbUV2ZW50LmdldFdoZXJlKCk7Ci0JCQkJaW50W10gdz0gbmV3IGludFsxXTsKLQkJCQlzaG9ydCBwYXJ0PSBPUy5GaW5kV2luZG93KHdoZXJlLmdldERhdGEoKSwgdyk7Ci0JCQkJCQkJCQotCQkJCU9TLlFER2xvYmFsVG9Mb2NhbFBvaW50KE9TLkdldFdpbmRvd1BvcnQod1swXSksIHdoZXJlLmdldERhdGEoKSk7Ci0JCQkJCi0JCQkJaWYgKHBhcnQgPT0gT1MuaW5NZW51QmFyKSB7Ci0JCQkJCU9TLk1lbnVTZWxlY3QobUV2ZW50LmdldFdoZXJlKCkuZ2V0RGF0YSgpKTsKLQkJCQkJLy9kb01lbnVDb21tYW5kKE9TLk1lbnVTZWxlY3QobUV2ZW50LmdldFdoZXJlKCkuZ2V0RGF0YSgpKSk7Ci0JCQkJCXJldHVybiBPUy5rTm9FcnI7Ci0JCQkJfQotCQkJCWJyZWFrOwotCQkJCQotCQkJY2FzZSBPUy5rRXZlbnRNb3VzZURyYWdnZWQ6Ci0JCQljYXNlIE9TLmtFdmVudE1vdXNlVXA6Ci0JCQljYXNlIE9TLmtFdmVudE1vdXNlTW92ZWQ6Ci0JCQkJcmV0dXJuIGhhbmRsZU1vdXNlRXZlbnQobmV4dEhhbmRsZXIsIGVSZWZIYW5kbGUsIGV2ZW50S2luZCwgMCk7Ci0JCQl9Ci0JCQlicmVhazsKLQkJCQkJCQotCQljYXNlIFNXVF9VU0VSX0VWRU5UOgkvLyBTV1QxIHVzZXIgZXZlbnQKLQkJCS8vU3lzdGVtLm91dC5wcmludGxuKCJoYW5kbGVBcHBsaWNhdGlvbkNhbGxiYWNrOiB1c2VyIGV2ZW50ICIgKyBldmVudEtpbmQpOwotCQkJcmV0dXJuIE9TLmtOb0VycjsKLQkJCQotCQlkZWZhdWx0OgotCQkJU3lzdGVtLm91dC5wcmludGxuKCJoYW5kbGVBcHBsaWNhdGlvbkNhbGxiYWNrOiB1bmtub3duIGV2ZW50IGNsYXNzIiArIE1hY1V0aWwudG9TdHJpbmcoZXZlbnRDbGFzcykpOwotCQkJYnJlYWs7Ci0JCX0KLQkJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKLQl9Ci0JCQotCXByaXZhdGUgaW50IGhhbmRsZU1vdXNlRXZlbnQoaW50IG5leHRIYW5kbGVyLCBpbnQgZVJlZkhhbmRsZSwgaW50IGV2ZW50S2luZCwgaW50IHdoaWNoV2luZG93KSB7Ci0JCQotCQlpZiAoTWFjVXRpbC5ISVZJRVcpCi0JCQlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOwotCQkKLQkJaWYgKGV2ZW50S2luZCA9PSBPUy5rRXZlbnRNb3VzZURvd24pCi0JCQlmVHJhY2tlZENvbnRyb2w9IDA7Ci0JCQotCQlNYWNFdmVudCBtZT0gbmV3IE1hY0V2ZW50KGVSZWZIYW5kbGUpOwotCQlNYWNQb2ludCB3aGVyZT0gbWUuZ2V0V2hlcmUoKTsKLQkJCi0JCXNob3J0IHBhcnQ9IDA7Ci0JCWlmICh3aGljaFdpbmRvdyA9PSAwKSB7Ci0JCQlpZiAoZlRyYWNrZWRDb250cm9sICE9IDApIHsKLQkJCQl3aGljaFdpbmRvdz0gT1MuR2V0Q29udHJvbE93bmVyKGZUcmFja2VkQ29udHJvbCk7Ci0JCQl9IGVsc2UgewotCQkJCWludFtdIHc9IG5ldyBpbnRbMV07Ci0JCQkJcGFydD0gT1MuRmluZFdpbmRvdyh3aGVyZS5nZXREYXRhKCksIHcpOwotCQkJCXdoaWNoV2luZG93PSB3WzBdOwotCQkJfQotCQl9IGVsc2UgewotCQkJcGFydD0gT1MuRmluZFdpbmRvdyh3aGVyZS5nZXREYXRhKCksIG5ldyBpbnRbMV0pOwotCQl9Ci0JCQotCQlpZiAod2hpY2hXaW5kb3cgPT0gMCAmJiBldmVudEtpbmQgPT0gT1Mua0V2ZW50TW91c2VEb3duKSB7Ci0JCQlpbnRbXSB3SGFuZGxlPSBuZXcgaW50WzFdOwotCQkJaW50IHJjPSBPUy5HZXRFdmVudFBhcmFtZXRlcihlUmVmSGFuZGxlLCBPUy5rRXZlbnRQYXJhbVdpbmRvd1JlZiwgT1MudHlwZVdpbmRvd1JlZiwgbnVsbCwgbnVsbCwgd0hhbmRsZSk7Ci0JCQlpZiAocmMgPT0gT1Mua05vRXJyKQotCQkJCXdoaWNoV2luZG93PSB3SGFuZGxlWzBdOwotCQl9Ci0JCQotCQlpZiAod2hpY2hXaW5kb3cgPT0gMCkgewotCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIkRpc3BsYXkuaGFuZGxlTW91c2VFdmVudDogIHdoaWNoV2luZG93ID09IDAiKTsKLQkJCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Ci0JCX0KLQkJCQotCQlNYWNFdmVudC50cmFja1N0YXRlTWFzayhlUmVmSGFuZGxlLCBldmVudEtpbmQpOwotCQkJCQotCQlzd2l0Y2ggKGV2ZW50S2luZCkgewotCQkKLQkJY2FzZSBPUy5rRXZlbnRNb3VzZVdoZWVsTW92ZWQ6Ci0JCQlPUy5RREdsb2JhbFRvTG9jYWxQb2ludChPUy5HZXRXaW5kb3dQb3J0KHdoaWNoV2luZG93KSwgd2hlcmUuZ2V0RGF0YSgpKTsJCQkKLQkJCWludCBjbnRybD0gTWFjVXRpbC5maW5kQ29udHJvbFVuZGVyTW91c2Uod2hlcmUsIHdoaWNoV2luZG93LCBudWxsKTsKLQkJCVdpZGdldCB3dz0gZmluZFdpZGdldChjbnRybCk7Ci0JCQlpZiAod3cgaW5zdGFuY2VvZiBDb21wb3NpdGUpIHsKLQkJCQlDb21wb3NpdGUgcz0gKENvbXBvc2l0ZSkgd3c7Ci0JCQkJU2Nyb2xsQmFyIHNiPSBzLmdldFZlcnRpY2FsQmFyKCk7Ci0JCQkJaWYgKHNiICE9IG51bGwpCi0JCQkJCXJldHVybiBzYi5wcm9jZXNzV2hlZWwoZVJlZkhhbmRsZSk7Ci0JCQl9Ci0JCQlicmVhazsKLQkJCi0JCWNhc2UgT1Mua0V2ZW50TW91c2VEb3duOgotCQkJCQkKLQkJCWlmICghT1MuSXNXaW5kb3dBY3RpdmUod2hpY2hXaW5kb3cpKSB7Ci0JCQkJLy8gbGV0IHRoZSBkZWZhdWx0IGhhbmRsZXIgYWN0aXZhdGUgdGhlIHdpbmRvdwotCQkJCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Ci0JCQl9Ci0JCQotCQkJaGlkZVRvb2xUaXAgKCk7Ci0JCQotCQkJaWYgKHBhcnQgPT0gT1MuaW5Db250ZW50IHx8IChNYWNVdGlsLkhJVklFVyAmJiBwYXJ0ID09IE9TLmluU3RydWN0dXJlKSkKLQkJCQlpZiAoZmFsc2UgJiYgTWFjVXRpbC5ISVZJRVcpIHsKLQkJCQkJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKLQkJCQl9IGVsc2UgewotCQkJCQlpZiAoIWhhbmRsZUNvbnRlbnRDbGljayhtZSwgd2hpY2hXaW5kb3cpKQotCQkJCQkJcmV0dXJuIE9TLmtOb0VycjsKLQkJCQl9Ci0KLQkJCWJyZWFrOwotCQkKLQkJY2FzZSBPUy5rRXZlbnRNb3VzZURyYWdnZWQ6Ci0JCQlpZiAoZlRyYWNrZWRDb250cm9sICE9IDApIHsKLQkJCQl3aW5kb3dQcm9jKGZUcmFja2VkQ29udHJvbCwgU1dULk1vdXNlTW92ZSwgbmV3IE1hY01vdXNlRXZlbnQobWUpKTsKLQkJCQlyZXR1cm4gT1Mua05vRXJyOwotCQkJfQotCQkJYnJlYWs7Ci0KLQkJY2FzZSBPUy5rRXZlbnRNb3VzZVVwOgotCQkJaWYgKGZUcmFja2VkQ29udHJvbCAhPSAwKSB7Ci0JCQkJd2luZG93UHJvYyhmVHJhY2tlZENvbnRyb2wsIFNXVC5Nb3VzZVVwLCBuZXcgTWFjTW91c2VFdmVudChtZSkpOwotCQkJCWZUcmFja2VkQ29udHJvbD0gMDsKLQkJCQlyZXR1cm4gT1Mua05vRXJyOwotCQkJfQkKLQkJCWJyZWFrOwotCQkJCi0JCWNhc2UgT1Mua0V2ZW50TW91c2VNb3ZlZDoKLQkJCi0JCQlmVHJhY2tlZENvbnRyb2w9IDA7CQkJCi0JCQkKLQkJCU9TLlFER2xvYmFsVG9Mb2NhbFBvaW50KE9TLkdldFdpbmRvd1BvcnQod2hpY2hXaW5kb3cpLCB3aGVyZS5nZXREYXRhKCkpOwkJCQotCQkJaW50IHdoaWNoQ29udHJvbD0gTWFjVXRpbC5maW5kQ29udHJvbFVuZGVyTW91c2Uod2hlcmUsIHdoaWNoV2luZG93LCBudWxsKTsKLQkJCi0JCQlpZiAoZkN1cnJlbnRDb250cm9sICE9IHdoaWNoQ29udHJvbCkgewotCQkJCi0JCQkJaWYgKGZDdXJyZW50Q29udHJvbCAhPSAwKSB7Ci0JCQkJCWZMYXN0SG92ZXJIYW5kbGU9IDA7Ci0JCQkJCXdpbmRvd1Byb2MoZkN1cnJlbnRDb250cm9sLCBTV1QuTW91c2VFeGl0LCBuZXcgTWFjTW91c2VFdmVudChtZSkpOwotCQkJCX0KLQkJCQkKLQkJCQlmQ3VycmVudENvbnRyb2w9IHdoaWNoQ29udHJvbDsKLQkJCQkKLQkJCQlXaWRnZXQgdz0gZmluZFdpZGdldChmQ3VycmVudENvbnRyb2wpOwotCQkJCWlmICh3IGluc3RhbmNlb2YgQ29udHJvbCkgewotCQkJCQlDb250cm9sIGM9IChDb250cm9sKSB3OwotCQkJCQlpZiAoYy5jdXJzb3IgIT0gbnVsbCkKLQkJCQkJCWMuY3Vyc29yLmluc3RhbGwodGhpcyk7CQotCQkJCQllbHNlCi0JCQkJCQlzZXRDdXJzb3IoMCk7CQkKLQkJCQl9IGVsc2UKLQkJCQkJc2V0Q3Vyc29yKDApOwotCQkJCQotCQkJCXdpbmRvd1Byb2MoZkN1cnJlbnRDb250cm9sLCBTV1QuTW91c2VNb3ZlLCBuZXcgTWFjTW91c2VFdmVudChtZSkpOwotCQkJCQotCQkJCWlmIChmQ3VycmVudENvbnRyb2wgIT0gMCkgewotCQkJCQl3aW5kb3dQcm9jKGZDdXJyZW50Q29udHJvbCwgU1dULk1vdXNlRW50ZXIsIG5ldyBNYWNNb3VzZUV2ZW50KG1lKSk7Ci0JCQkJfQotCQkJCXJldHVybiBPUy5rTm9FcnI7CQkJCi0JCQl9IGVsc2UgewotCQkJCWlmIChmQ3VycmVudENvbnRyb2wgIT0gMCkgewotCQkJCQl3aW5kb3dQcm9jKGZDdXJyZW50Q29udHJvbCwgU1dULk1vdXNlTW92ZSwgbmV3IE1hY01vdXNlRXZlbnQobWUpKTsKLQkJCQkJcmV0dXJuIE9TLmtOb0VycjsKLQkJCQl9Ci0JCQl9Ci0JCQlicmVhazsKLQkJfQotCQkJCQkKLQkJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKLQl9Ci0KLQlib29sZWFuIHNldE1hY0ZvY3VzSGFuZGxlKGludCB3SGFuZGxlLCBpbnQgZm9jdXNIYW5kbGUpIHsKLQkKLQkJaWYgKGZGb2N1c0NvbnRyb2wgIT0gZm9jdXNIYW5kbGUpIHsKLQkJCWludCBvbGRGb2N1cz0gZkZvY3VzQ29udHJvbDsKLQkJCWZGb2N1c0NvbnRyb2w9IGZvY3VzSGFuZGxlOwotCQkJCi0JCQlpZiAob2xkRm9jdXMgIT0gMCkKLQkJCQl3aW5kb3dQcm9jKG9sZEZvY3VzLCBmYWxzZSk7Ci0JCQkKLQkJCQotCQkJaWYgKHdIYW5kbGUgIT0gMCkgewotCQkJCWludFtdIGZvY3VzQ29udHJvbD0gbmV3IGludFsxXTsKLQkJCQlPUy5HZXRLZXlib2FyZEZvY3VzKHdIYW5kbGUsIGZvY3VzQ29udHJvbCk7Ci0JCQkJaWYgKGZvY3VzQ29udHJvbFswXSAhPSBmRm9jdXNDb250cm9sKSB7Ci0JCQkJCU9TLlNldEtleWJvYXJkRm9jdXMod0hhbmRsZSwgZm9jdXNIYW5kbGUsIChzaG9ydCktMSk7Ci0JCQkJCS8vaWYgKHJjICE9IE9TLmtOb0VycikKLQkJCQkJLy8JU3lzdGVtLm91dC5wcmludGxuKCJEaXNwbGF5LnNldE1hY0ZvY3VzSGFuZGxlOiBTZXRLZXlib2FyZEZvY3VzICIgKyByYyk7Ci0JCQkJfQotCQkJfQotCi0JCQlpZiAoZkZvY3VzQ29udHJvbCAhPSAwKQotCQkJCXdpbmRvd1Byb2MoZkZvY3VzQ29udHJvbCwgdHJ1ZSk7Ci0JCX0KLQkJcmV0dXJuIHRydWU7Ci0JfQotCQkJCi0JcHJpdmF0ZSBib29sZWFuIGhhbmRsZUNvbnRlbnRDbGljayhNYWNFdmVudCBtZSwgaW50IHdoaWNoV2luZG93KSB7Ci0JCi0JCU1hY1BvaW50IHdoZXJlPSBtZS5nZXRXaGVyZSgpOwotCQlNYWNQb2ludCBnbG9iYWxQb3M9IG1lLmdldFdoZXJlKCk7Ci0JCQkJCi0JCU9TLlFER2xvYmFsVG9Mb2NhbFBvaW50KE9TLkdldFdpbmRvd1BvcnQod2hpY2hXaW5kb3cpLCB3aGVyZS5nZXREYXRhKCkpOwotCQkKLQkJc2hvcnRbXSBjcGFydD0gbmV3IHNob3J0WzFdOwkJCi0JCWludCB3aGljaENvbnRyb2w9IDA7Ci0JCWlmIChNYWNVdGlsLkhJVklFVykgewotCQkJaW50W10gb3Y9IG5ldyBpbnRbMV07Ci0JCQlpbnQgcm9vdD0gT1MuSElWaWV3R2V0Um9vdCh3aGljaFdpbmRvdyk7Ci0JCQlPUy5ISVZpZXdHZXRWaWV3Rm9yTW91c2VFdmVudChyb290LCBtZS5nZXRFdmVudFJlZigpLCBvdik7Ci0JCQl3aGljaENvbnRyb2w9IG92WzBdOwotCQl9IGVsc2UgewotCQkJd2hpY2hDb250cm9sPSBNYWNVdGlsLmZpbmRDb250cm9sVW5kZXJNb3VzZSh3aGVyZSwgd2hpY2hXaW5kb3csIGNwYXJ0KTsJCQkJCi0JCX0KLQkJCi0JCS8vIGZvY3VzIGNoYW5nZQotCQlzZXRNYWNGb2N1c0hhbmRsZSh3aGljaFdpbmRvdywgd2hpY2hDb250cm9sKTsKLQkJCQkJCQkJCi0JCWlmICh3aGljaENvbnRyb2wgIT0gMCkgewotCQkKLQkJCS8vIGRlYWwgd2l0aCB0aGUgY29udGV4dCBtZW51Ci0JCQlXaWRnZXQgd2M9IFdpZGdldFRhYmxlLmdldCh3aGljaENvbnRyb2wpOwotCQkJaWYgKHdjIGluc3RhbmNlb2YgQ29udHJvbCkgewotCQkJCU1lbnUgY209ICgoQ29udHJvbCl3YykuZ2V0TWVudSgpOwkvLyBpcyBhIGNvbnRleHQgbWVudSBpbnN0YWxsZWQ/Ci0JCQkJaWYgKGNtICE9IG51bGwgJiYgbWUuaXNTaG93Q29udGV4dHVhbE1lbnVDbGljaygpKSB7Ci0JCQkJCXRyeSB7Ci0JCQkJCQlmSW5Db250ZXh0TWVudT0gdHJ1ZTsKLQkJCQkJCS8vIEFXOiBub3QgcmVhZHkgZm9yIHByaW1ldGltZQotCQkJCQkJLy8gT1MuQ29udGV4dHVhbE1lbnVTZWxlY3QoY20uaGFuZGxlLCBnbG9iYWxQb3MuZ2V0RGF0YSgpLCBuZXcgc2hvcnRbMV0sIG5ldyBzaG9ydFsxXSk7Ci0JCQkJCQlPUy5Qb3BVcE1lbnVTZWxlY3QoY20uaGFuZGxlLCAoc2hvcnQpZ2xvYmFsUG9zLmdldFkoKSwgKHNob3J0KWdsb2JhbFBvcy5nZXRYKCksIChzaG9ydCkxKTsKLQkJCQkJfSBmaW5hbGx5IHsKLQkJCQkJCWZJbkNvbnRleHRNZW51PSBmYWxzZTsKLQkJCQkJfQotCQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQkJfQotCQkJfQotCQkJCi0JCQlpZiAoTWFjVXRpbC5ISVZJRVcpIHsKLQkJCQlPUy5ISVZpZXdDbGljayh3aGljaENvbnRyb2wsIG1lLmdldEV2ZW50UmVmKCkpOwotCQkJCXJldHVybiBmYWxzZTsKLQkJCX0KLQkJCi0JCQlzd2l0Y2ggKGNwYXJ0WzBdKSB7Ci0JCQljYXNlIDA6Ci0JCQkJYnJlYWs7Ci0KLQkJCWNhc2UgMTExOgkvLyBVc2VyIHBhbmUKLQkJCQlmVHJhY2tlZENvbnRyb2w9IHdoaWNoQ29udHJvbDsJLy8gc3RhcnRzIG1vdXNlIHRyYWNraW5nCi0JCQkJd2luZG93UHJvYyh3aGljaENvbnRyb2wsIFNXVC5Nb3VzZURvd24sIG5ldyBNYWNNb3VzZUV2ZW50KG1lKSk7Ci0JCQkJYnJlYWs7Ci0KLQkJCWNhc2UgMTEyOgkvLyBVc2VyIHBhbmUKLQkJCQl3aW5kb3dQcm9jKHdoaWNoQ29udHJvbCwgU1dULk1vdXNlRG93biwgbmV3IE1hY01vdXNlRXZlbnQobWUpKTsKLQkJCQlicmVhazsKLQkJCQkKLQkJCWRlZmF1bHQ6Ci0JCQkJd2luZG93UHJvYyh3aGljaENvbnRyb2wsIFNXVC5Nb3VzZURvd24sIG5ldyBNYWNNb3VzZUV2ZW50KG1lKSk7Ci0JCQkJCi0JCQkJaWYgKE1hY1V0aWwuSElWSUVXKSB7Ci0JCQkJCS8vIEFXOiBKYWd1YXI6Ci0JCQkJCU9TLkhJVmlld0NsaWNrKHdoaWNoQ29udHJvbCwgbWUuZ2V0RXZlbnRSZWYoKSk7Ci0JCQkJfSBlbHNlIHsKLQkJCQkJaW50IGNwYXJ0Mj0gT1MuSGFuZGxlQ29udHJvbENsaWNrKHdoaWNoQ29udHJvbCwgd2hlcmUuZ2V0RGF0YSgpLCBtZS5nZXRNb2RpZmllcnMoKSwgLTEpOwotCQkJCQlpZiAoY3BhcnQyICE9IDApIHsKLQkJCQkJCXdpbmRvd1Byb2Mod2hpY2hDb250cm9sLCBTV1QuU2VsZWN0aW9uLCBuZXcgTWFjQ29udHJvbEV2ZW50KHdoaWNoQ29udHJvbCwgY3BhcnQyLCBmYWxzZSkpOwotCQkJCQl9Ci0JCQkJfQotCQkJCWJyZWFrOwotCQkJfQotCQl9Ci0JCXJldHVybiBmYWxzZTsKLQl9Ci0JCQotCXB1YmxpYyB2b2lkIHVwZGF0ZVdpbmRvdyhpbnQgd2hpY2hXaW5kb3cpIHsKLQkKLQkJaW50IGN1clBvcnQ9IE9TLkdldFBvcnQoKTsKLQkJT1MuU2V0UG9ydFdpbmRvd1BvcnQod2hpY2hXaW5kb3cpOwotCQlPUy5CZWdpblVwZGF0ZSh3aGljaFdpbmRvdyk7Ci0JCQotCQl1cGRhdGVXaW5kb3cyKHdoaWNoV2luZG93KTsKLQotCQlPUy5FbmRVcGRhdGUod2hpY2hXaW5kb3cpOwotCQlPUy5TZXRQb3J0KGN1clBvcnQpOwotCX0KLQotCXB1YmxpYyB2b2lkIHVwZGF0ZVdpbmRvdzIoaW50IHdoaWNoV2luZG93KSB7Ci0JCWlmICh0b29sVGlwV2luZG93SGFuZGxlID09IHdoaWNoV2luZG93KSB7Ci0JCQlwcm9jZXNzUGFpbnRUb29sVGlwKHdoaWNoV2luZG93KTsKLQkJfSBlbHNlIHsKLQkJCWZVcGRhdGVSZWdpb249IE9TLk5ld1JnbigpOwotCQkJT1MuR2V0UG9ydFZpc2libGVSZWdpb24oT1MuR2V0V2luZG93UG9ydCh3aGljaFdpbmRvdyksIGZVcGRhdGVSZWdpb24pOwotCi0JCQlPUy5FcmFzZVJnbihmVXBkYXRlUmVnaW9uKTsKLQkJCU9TLlVwZGF0ZUNvbnRyb2xzKHdoaWNoV2luZG93LCBmVXBkYXRlUmVnaW9uKTsKLQkJCQkJCQkKLQkJCU9TLkRpc3Bvc2VSZ24oZlVwZGF0ZVJlZ2lvbik7Ci0JCQlmVXBkYXRlUmVnaW9uPSAwOwotCQl9Ci0JfQotCQkKLQkvKgotCXN0YXRpYyB2b2lkIHByb2Nlc3NBbGxVcGRhdGVFdmVudHMyKGludCBjSGFuZGxlKSB7Ci0JCQotCQlpZiAodHJ1ZSkgewotCQkJaW50W10gbWFjRXZlbnQ9IG5ldyBpbnRbNl07Ci0JCQl3aGlsZSAoT1MuR2V0TmV4dEV2ZW50KE9TLnVwZGF0ZU1hc2ssIG1hY0V2ZW50KSkKLQkJCQlpZiAobWFjRXZlbnRbMF0gPT0gT1MudXBkYXRlRXZ0KQotCQkJCQlnZXREZWZhdWx0KCkudXBkYXRlV2luZG93KG1hY0V2ZW50WzFdKTsKLQkJfSBlbHNlIHsKLQkJCWludFtdIG1hc2s9IG5ldyBpbnRbXSB7Ci0JCQkJT1Mua0V2ZW50Q2xhc3NXaW5kb3csIE9TLmtFdmVudFdpbmRvd0RyYXdDb250ZW50Ci0JCQl9OwotCQkJaW50W10gZXZ0PSBuZXcgaW50WzFdOwotCQkJd2hpbGUgKE9TLlJlY2VpdmVOZXh0RXZlbnQobWFzaywgMC4wMSwgdHJ1ZSwgZXZ0KSA9PSBPUy5rTm9FcnIpIHsKLQkJCQkvL1N5c3RlbS5vdXQucHJpbnRsbigiZ290IHVwZGF0ZSIpOwotCQkJCWludCByYz0gT1MuU2VuZEV2ZW50VG9FdmVudFRhcmdldChldnRbMF0sIE9TLkdldEV2ZW50RGlzcGF0Y2hlclRhcmdldCgpKTsKLSAgICAgICAgICAgICAgICBpZiAocmMgIT0gT1Mua05vRXJyKQotCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oInByb2Nlc3NBbGxVcGRhdGVFdmVudHM6ICIgKyByYyk7Ci0JCQkJT1MuUmVsZWFzZUV2ZW50KGV2dFswXSk7Ci0JCQl9Ci0JCX0KLQotCQlpbnQgd0hhbmRsZT0gT1MuR2V0Q29udHJvbE93bmVyKGNIYW5kbGUpOwotCQlpZiAod0hhbmRsZSAhPSAwKSB7Ci0JCQlpbnQgcG9ydD0gT1MuR2V0V2luZG93UG9ydCh3SGFuZGxlKTsKLQkJCWlmIChwb3J0ICE9IDApIHsKLQkJCQlPUy5RREZsdXNoUG9ydEJ1ZmZlcihwb3J0LCAwKTsKLQkJCQkvL1N5c3RlbS5vdXQucHJpbnRsbigiUURGbHVzaFBvcnRCdWZmZXIiKTsKLQkJCX0KLQkJfQotCX0KLQkqLwotCQotCXByaXZhdGUgdm9pZCBwcm9jZXNzUGFpbnRUb29sVGlwKGludCB3SGFuZGxlKSB7Ci0JCQkKLQkJQ29sb3IgaW5mb0ZvcmVncm91bmQgPSBnZXRTeXN0ZW1Db2xvciAoU1dULkNPTE9SX0lORk9fRk9SRUdST1VORCk7Ci0JCUNvbG9yIGluZm9CYWNrZ3JvdW5kID0gZ2V0U3lzdGVtQ29sb3IgKFNXVC5DT0xPUl9JTkZPX0JBQ0tHUk9VTkQpOwotCQlNYWNVdGlsLlJHQkJhY2tDb2xvcihpbmZvQmFja2dyb3VuZC5oYW5kbGUpOwotCQlNYWNVdGlsLlJHQkZvcmVDb2xvcihpbmZvRm9yZWdyb3VuZC5oYW5kbGUpOwotCQkKLQkJTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JCU9TLkdldFdpbmRvd0JvdW5kcyh3SGFuZGxlLCBPUy5rV2luZG93Q29udGVudFJnbiwgYm91bmRzLmdldERhdGEoKSk7Ci0JCQotCQlib3VuZHM9IG5ldyBNYWNSZWN0KDAsIDAsIGJvdW5kcy5nZXRXaWR0aCgpLCBib3VuZHMuZ2V0SGVpZ2h0KCkpOwotCQkKLQkJT1MuRXJhc2VSZWN0KGJvdW5kcy5nZXREYXRhKCkpOwotCQkKLQkJaWYgKGZUb29sVGlwVGV4dCAhPSBudWxsKSB7Ci0JCQlpbnQgc0hhbmRsZT0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyhmVG9vbFRpcFRleHQpOwotCQkJYm91bmRzPSBuZXcgTWFjUmVjdChUT09MVElQX01BUkdJTiwgVE9PTFRJUF9NQVJHSU4sCi0JCQkJCQkJYm91bmRzLmdldFdpZHRoKCktMipUT09MVElQX01BUkdJTiwgYm91bmRzLmdldEhlaWdodCgpLTIqVE9PTFRJUF9NQVJHSU4pOwotCQkJT1MuRHJhd1RoZW1lVGV4dEJveChzSGFuZGxlLCBmSG92ZXJUaGVtZUZvbnQsIE9TLmtUaGVtZVN0YXRlQWN0aXZlLCB0cnVlLCBib3VuZHMuZ2V0RGF0YSgpLCAoc2hvcnQpMCwgMCk7Ci0JCQlPUy5DRlJlbGVhc2Uoc0hhbmRsZSk7Ci0JCX0KLQl9Ci0JCi0JcHJpdmF0ZSB2b2lkIHNlbmRVc2VyRXZlbnQoaW50IGtpbmQpIHsKLQkJaW50W10gZXZlbnQ9IG5ldyBpbnRbMV07Ci0JCU9TLkNyZWF0ZUV2ZW50KDAsIFNXVF9VU0VSX0VWRU5ULCBraW5kLCAwLjAsIE9TLmtFdmVudEF0dHJpYnV0ZVVzZXJFdmVudCwgZXZlbnQpOwotCQlpZiAoZXZlbnRbMF0gIT0gMCkKLQkJCU9TLlBvc3RFdmVudFRvUXVldWUoT1MuR2V0TWFpbkV2ZW50UXVldWUoKSwgZXZlbnRbMF0sIChzaG9ydCkyKTsKLQl9Ci0JCi0JcHVibGljIHN0YXRpYyBNYWNGb250IGdldFRoZW1lRm9udChzaG9ydCB0aGVtZUZvbnRJZCkgewotCQlieXRlW10gZm9udE5hbWU9IG5ldyBieXRlWzI1Nl07Ci0JCXNob3J0W10gZm9udFNpemU9IG5ldyBzaG9ydFsxXTsKLQkJYnl0ZVtdIHN0eWxlPSBuZXcgYnl0ZVsxXTsKLQkJT1MuR2V0VGhlbWVGb250KHRoZW1lRm9udElkLCBPUy5zbVN5c3RlbVNjcmlwdCwgZm9udE5hbWUsIGZvbnRTaXplLCBzdHlsZSk7Ci0JCXJldHVybiBuZXcgTWFjRm9udChNYWNVdGlsLnRvU3RyaW5nKGZvbnROYW1lKSwgZm9udFNpemVbMF0sIHN0eWxlWzBdKTsKLQl9Ci0JCi0JcHVibGljIHZvaWQgc2V0Q3Vyc29yKGludCBjdXJzb3IpIHsKLQkJaWYgKGZDdXJyZW50Q3Vyc29yICE9IGN1cnNvcikgewotCQkJZkN1cnJlbnRDdXJzb3I9IGN1cnNvcjsKLQkJCWlmIChjdXJzb3IgPT0gMCkKLQkJCQlPUy5Jbml0Q3Vyc29yKCk7Ci0JCQllbHNlCi0JCQkJT1MuU2V0Q3Vyc29yKGN1cnNvcik7Ci0JCX0KLQl9Ci0JCi0JcHJpdmF0ZSBpbnQgY3JlYXRlQ2FsbGJhY2soU3RyaW5nIG1ldGhvZCwgaW50IGFyZ0NvdW50KSB7Ci0JCUNhbGxiYWNrIGNiPSBuZXcgQ2FsbGJhY2sodGhpcywgbWV0aG9kLCBhcmdDb3VudCk7Ci0JCWlmIChmQ2FsbGJhY2tzID09IG51bGwpCi0JCQlmQ2FsbGJhY2tzPSBuZXcgQXJyYXlMaXN0KCk7Ci0JCWZDYWxsYmFja3MuYWRkKGNiKTsKLQkJaW50IHByb2M9IGNiLmdldEFkZHJlc3MoKTsKLQkJaWYgKHByb2MgPT0gMCkKLQkJCWVycm9yIChTV1QuRVJST1JfTk9fTU9SRV9DQUxMQkFDS1MpOwotCQlyZXR1cm4gcHJvYzsKLQl9CiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvRmlsZURpYWxvZy5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0ZpbGVEaWFsb2cuamF2YQppbmRleCA0MDBiMWYwLi41ZDYxODk0IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvRmlsZURpYWxvZy5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9GaWxlRGlhbG9nLmphdmEKQEAgLTcsMzI0ICs3LDE5NSBAQAogICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKICAqLwogIAotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CiAKLS8qKgotICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgYWxsb3cgdGhlIHVzZXIgdG8gbmF2aWdhdGUKLSAqIHRoZSBmaWxlIHN5c3RlbSBhbmQgc2VsZWN0IG9yIGVudGVyIGEgZmlsZSBuYW1lLgotICogPGRsPgotICogPGR0PjxiPlN0eWxlczo8L2I+PC9kdD4KLSAqIDxkZD5TQVZFLCBPUEVOLCBNVUxUSTwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPihub25lKTwvZGQ+Ci0gKiA8L2RsPgotICogPHA+Ci0gKiBJTVBPUlRBTlQ6IFRoaXMgY2xhc3MgaXMgaW50ZW5kZWQgdG8gYmUgc3ViY2xhc3NlZCA8ZW0+b25seTwvZW0+Ci0gKiB3aXRoaW4gdGhlIFNXVCBpbXBsZW1lbnRhdGlvbi4KLSAqIDwvcD4KLSAqLwotcHVibGljIC8qZmluYWwqLyBjbGFzcyBGaWxlRGlhbG9nIGV4dGVuZHMgRGlhbG9nIHsKK3B1YmxpYyBjbGFzcyBGaWxlRGlhbG9nIGV4dGVuZHMgRGlhbG9nIHsKIAlTdHJpbmcgW10gZmlsdGVyTmFtZXMgPSBuZXcgU3RyaW5nIFswXTsKIAlTdHJpbmcgW10gZmlsdGVyRXh0ZW5zaW9ucyA9IG5ldyBTdHJpbmcgWzBdOwotCVN0cmluZyBmaWx0ZXJQYXRoID0gIiI7Ci0JU3RyaW5nIFtdIGZpbGVOYW1lcyA9IG5ldyBTdHJpbmdbXSB7ICIiIH07Ci0Jc3RhdGljIGZpbmFsIFN0cmluZyBGSUxURVIgPSAiKiI7CisJU3RyaW5nIFtdIGZpbGVOYW1lcyA9IG5ldyBTdHJpbmdbMF07CQorCVN0cmluZyBmaWx0ZXJQYXRoID0gIiIsIGZpbGVOYW1lID0gIiI7CiAKLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIG9ubHkgaXRzCi0gKiBwYXJlbnQuCi0gKiA8cD4KLSAqIE5vdGU6IEN1cnJlbnRseSwgbnVsbCBjYW4gYmUgcGFzc2VkIGluIGZvciB0aGUgcGFyZW50LgotICogVGhpcyBoYXMgdGhlIGVmZmVjdCBvZiBjcmVhdGluZyB0aGUgZGlhbG9nIG9uIHRoZSBjdXJyZW50bHkgYWN0aXZlCi0gKiBkaXNwbGF5IGlmIHRoZXJlIGlzIG9uZS4gSWYgdGhlcmUgaXMgbm8gY3VycmVudCBkaXNwbGF5LCB0aGUgCi0gKiBkaWFsb2cgaXMgY3JlYXRlZCBvbiBhICJkZWZhdWx0IiBkaXNwbGF5LiA8Yj5QYXNzaW5nIGluIG51bGwgYXMKLSAqIHRoZSBwYXJlbnQgaXMgbm90IGNvbnNpZGVyZWQgdG8gYmUgZ29vZCBjb2Rpbmcgc3R5bGUsCi0gKiBhbmQgbWF5IG5vdCBiZSBzdXBwb3J0ZWQgaW4gYSBmdXR1cmUgcmVsZWFzZSBvZiBTV1QuPC9iPgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBzaGVsbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyBGaWxlRGlhbG9nIChTaGVsbCBwYXJlbnQpIHsKLQl0aGlzIChwYXJlbnQsIFNXVC5QUklNQVJZX01PREFMKTsKKwl0aGlzIChwYXJlbnQsIFNXVC5BUFBMSUNBVElPTl9NT0RBTCk7CiB9CiAKLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIGl0cyBwYXJlbnQKLSAqIGFuZCBhIHN0eWxlIHZhbHVlIGRlc2NyaWJpbmcgaXRzIGJlaGF2aW9yIGFuZCBhcHBlYXJhbmNlLgotICogPHA+Ci0gKiBUaGUgc3R5bGUgdmFsdWUgaXMgZWl0aGVyIG9uZSBvZiB0aGUgc3R5bGUgY29uc3RhbnRzIGRlZmluZWQgaW4KLSAqIGNsYXNzIDxjb2RlPlNXVDwvY29kZT4gd2hpY2ggaXMgYXBwbGljYWJsZSB0byBpbnN0YW5jZXMgb2YgdGhpcwotICogY2xhc3MsIG9yIG11c3QgYmUgYnVpbHQgYnkgPGVtPmJpdHdpc2UgT1I8L2VtPidpbmcgdG9nZXRoZXIgCi0gKiAodGhhdCBpcywgdXNpbmcgdGhlIDxjb2RlPmludDwvY29kZT4gInwiIG9wZXJhdG9yKSB0d28gb3IgbW9yZQotICogb2YgdGhvc2UgPGNvZGU+U1dUPC9jb2RlPiBzdHlsZSBjb25zdGFudHMuIFRoZSBjbGFzcyBkZXNjcmlwdGlvbgotICogbGlzdHMgdGhlIHN0eWxlIGNvbnN0YW50cyB0aGF0IGFyZSBhcHBsaWNhYmxlIHRvIHRoZSBjbGFzcy4KLSAqIFN0eWxlIGJpdHMgYXJlIGFsc28gaW5oZXJpdGVkIGZyb20gc3VwZXJjbGFzc2VzLgotICogPC9wPgotICogTm90ZTogQ3VycmVudGx5LCBudWxsIGNhbiBiZSBwYXNzZWQgaW4gZm9yIHRoZSBwYXJlbnQuCi0gKiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGNyZWF0aW5nIHRoZSBkaWFsb2cgb24gdGhlIGN1cnJlbnRseSBhY3RpdmUKLSAqIGRpc3BsYXkgaWYgdGhlcmUgaXMgb25lLiBJZiB0aGVyZSBpcyBubyBjdXJyZW50IGRpc3BsYXksIHRoZSAKLSAqIGRpYWxvZyBpcyBjcmVhdGVkIG9uIGEgImRlZmF1bHQiIGRpc3BsYXkuIDxiPlBhc3NpbmcgaW4gbnVsbCBhcwotICogdGhlIHBhcmVudCBpcyBub3QgY29uc2lkZXJlZCB0byBiZSBnb29kIGNvZGluZyBzdHlsZSwKLSAqIGFuZCBtYXkgbm90IGJlIHN1cHBvcnRlZCBpbiBhIGZ1dHVyZSByZWxlYXNlIG9mIFNXVC48L2I+Ci0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIHNoZWxsIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcGFyZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHBhcmVudDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIEZpbGVEaWFsb2cgKFNoZWxsIHBhcmVudCwgaW50IHN0eWxlKSB7CiAJc3VwZXIgKHBhcmVudCwgc3R5bGUpOworCWNoZWNrU3ViY2xhc3MgKCk7CiB9CiAKLS8qKgotICogUmV0dXJucyB0aGUgcGF0aCBvZiB0aGUgZmlyc3QgZmlsZSB0aGF0IHdhcwotICogc2VsZWN0ZWQgaW4gdGhlIGRpYWxvZyByZWxhdGl2ZSB0byB0aGUgZmlsdGVyIHBhdGgsCi0gKiBvciBlbXB0eSBzdHJpbmcgaWYgdGhlIGRpYWxvZyB3YXMgY2FuY2VsbGVkLgotICogCi0gKiBAcmV0dXJuIHRoZSByZWxhdGl2ZSBwYXRoIG9mIHRoZSBmaWxlCi0gKi8KIHB1YmxpYyBTdHJpbmcgZ2V0RmlsZU5hbWUgKCkgewotCWlmIChmaWxlTmFtZXMubGVuZ3RoID4gMCkKLQkJcmV0dXJuIGZpbGVOYW1lc1swXTsKLQlyZXR1cm4gIiI7CisJcmV0dXJuIGZpbGVOYW1lOwogfQogCi0vKioKLSAqIFJldHVybnMgdGhlIHBhdGhzIG9mIGFsbCBmaWxlcyB0aGF0IHdlcmUgc2VsZWN0ZWQKLSAqIGluIHRoZSBkaWFsb2cgcmVsYXRpdmUgdG8gdGhlIGZpbHRlciBwYXRoLCBvciBudWxsCi0gKiBpZiBub25lIGFyZSBhdmFpbGFibGUuCi0gKiAKLSAqIEByZXR1cm4gdGhlIHJlbGF0aXZlIHBhdGhzIG9mIHRoZSBmaWxlcwotICovCiBwdWJsaWMgU3RyaW5nIFtdIGdldEZpbGVOYW1lcyAoKSB7CiAJcmV0dXJuIGZpbGVOYW1lczsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIHRoZSBmaWxlIGV4dGVuc2lvbnMgd2hpY2ggdGhlIGRpYWxvZyB3aWxsCi0gKiB1c2UgdG8gZmlsdGVyIHRoZSBmaWxlcyBpdCBzaG93cy4KLSAqCi0gKiBAcmV0dXJuIHRoZSBmaWxlIGV4dGVuc2lvbnMgZmlsdGVyCi0gKi8KIHB1YmxpYyBTdHJpbmcgW10gZ2V0RmlsdGVyRXh0ZW5zaW9ucyAoKSB7CiAJcmV0dXJuIGZpbHRlckV4dGVuc2lvbnM7CiB9CiAKLS8qKgotICogUmV0dXJucyB0aGUgZmlsZSBuYW1lcyB3aGljaCB0aGUgZGlhbG9nIHdpbGwKLSAqIHVzZSB0byBmaWx0ZXIgdGhlIGZpbGVzIGl0IHNob3dzLgotICoKLSAqIEByZXR1cm4gdGhlIGZpbGUgbmFtZSBmaWx0ZXIKLSAqLwogcHVibGljIFN0cmluZyBbXSBnZXRGaWx0ZXJOYW1lcyAoKSB7CiAJcmV0dXJuIGZpbHRlck5hbWVzOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBwYXRoIHdoaWNoIHRoZSBkaWFsb2cgd2lsbCB1c2UgdG8gZmlsdGVyCi0gKiB0aGUgZGlyZWN0b3JpZXMgaXQgc2hvd3MuCi0gKgotICogQHJldHVybiB0aGUgZmlsdGVyIHBhdGgKLSAqLworCiBwdWJsaWMgU3RyaW5nIGdldEZpbHRlclBhdGggKCkgewogCXJldHVybiBmaWx0ZXJQYXRoOwogfQotcHJpdmF0ZSBTdHJpbmcgaW50ZXJwcmV0T3NBbnN3ZXIoaW50IGRpYWxvZykgewotCVN0cmluZyBzZXBhcmF0b3IgPSBTeXN0ZW0uZ2V0UHJvcGVydHkgKCJmaWxlLnNlcGFyYXRvciIpOwotCQotCVN0cmluZyBmaXJzdFJlc3VsdD0gbnVsbDsKIAotCWludFtdIHRtcD0gbmV3IGludFsxXTsKLQlPUy5OYXZEaWFsb2dHZXRSZXBseShkaWFsb2csIHRtcCk7Ci0JaW50IHJlcGx5PSB0bXBbMF07Ci0JCi0JaW50IHNlbGVjdGlvbj0gT1MuTmF2UmVwbHlSZWNvcmRHZXRTZWxlY3Rpb24ocmVwbHkpOwotCU9TLkFFQ291bnRJdGVtcyhzZWxlY3Rpb24sIHRtcCk7Ci0JaW50IGNvdW50PSB0bXBbMF07Ci0JCi0JU3RyaW5nIGNvbW1vblBhdGg9IG51bGw7Ci0JaWYgKGNvdW50ID4gMCkgewotCQlTdHJpbmcgZmlsZU5hbWU9IG51bGw7Ci0JCWZpbGVOYW1lcz0gbmV3IFN0cmluZ1tjb3VudF07Ci0JCWZvciAoaW50IGk9IDA7IGkgPCBjb3VudDsgaSsrKSB7Ci0JCQlPUy5BRUdldE50aFB0cihzZWxlY3Rpb24sIGkrMSwgdG1wKTsKLQkJCVN0cmluZyBmdWxsUGF0aD0gTWFjVXRpbC5nZXRTdHJpbmdBbmRSZWxlYXNlKHRtcFswXSk7Ci0JCQlpZiAoZmlyc3RSZXN1bHQgPT0gbnVsbCkKLQkJCQlmaXJzdFJlc3VsdD0gZnVsbFBhdGg7Ci0JCQlpZiAoZnVsbFBhdGggIT0gbnVsbCAmJiBmdWxsUGF0aC5sZW5ndGgoKSA+IDApIHsKLQkJCQlpbnQgc2VwYXJhdG9ySW5kZXg9IGZ1bGxQYXRoLmxhc3RJbmRleE9mKHNlcGFyYXRvcik7Ci0JCQkJaWYgKHNlcGFyYXRvckluZGV4ID49IDApIHsKLQkJCQkJZmlsZU5hbWU9IGZ1bGxQYXRoLnN1YnN0cmluZyhzZXBhcmF0b3JJbmRleCtzZXBhcmF0b3IubGVuZ3RoKCkpOwotCQkJCQlTdHJpbmcgZnA9IGZ1bGxQYXRoLnN1YnN0cmluZygwLCBzZXBhcmF0b3JJbmRleCk7Ci0JCQkJCWlmIChjb21tb25QYXRoID09IG51bGwpCi0JCQkJCQljb21tb25QYXRoPSBmcDsJLy8gcmVtZW1iZXIgY29tbW9uIGZpbHRlclBhdGgKLQkJCQkJZWxzZSB7Ci0JCQkJCQlpZiAoIWNvbW1vblBhdGguZXF1YWxzKGZwKSkJLy8gdmVyaWZ5IHRoYXQgZmlsdGVyUGF0aCBpcyBpbiBmYWN0IGNvbW1vbgotCQkJCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiRmlsZURpYWxvZy5nZXRQYXRoczogbWlzbWF0Y2ggaW4gZmlsdGVyUGF0aHMiKTsKLQkJCQkJfQotCQkJCX0gZWxzZSB7Ci0JCQkJCWZpbGVOYW1lPSBmdWxsUGF0aDsKLQkJCQl9Ci0JCQkJZmlsZU5hbWVzW2ldPSBmaWxlTmFtZTsKLQkJCX0KLQkJfQotCX0gZWxzZSB7Ci0JCWZpbGVOYW1lcz0gbnVsbDsKLQl9Ci0JCi0JaWYgKGNvbW1vblBhdGggIT0gbnVsbCkKLQkJZmlsdGVyUGF0aD0gY29tbW9uUGF0aDsKLQllbHNlCi0JCWZpbHRlclBhdGg9ICIiOwotCQotCU9TLk5hdkRpYWxvZ0Rpc3Bvc2VSZXBseShyZXBseSk7Ci0JCi0JcmV0dXJuIGZpcnN0UmVzdWx0OwotfQotLyoqCi0gKiBNYWtlcyB0aGUgZGlhbG9nIHZpc2libGUgYW5kIGJyaW5ncyBpdCB0byB0aGUgZnJvbnQKLSAqIG9mIHRoZSBkaXNwbGF5LgotICoKLSAqIEByZXR1cm4gYSBzdHJpbmcgZGVzY3JpYmluZyB0aGUgYWJzb2x1dGUgcGF0aCBvZiB0aGUgZmlyc3Qgc2VsZWN0ZWQgZmlsZSwKLSAqICAgICAgICAgb3IgbnVsbCBpZiB0aGUgZGlhbG9nIHdhcyBjYW5jZWxsZWQgb3IgYW4gZXJyb3Igb2NjdXJyZWQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIGRpYWxvZyBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBkaWFsb2c8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIFN0cmluZyBvcGVuICgpIHsKKwlTdHJpbmcgZnVsbFBhdGggPSBudWxsOworCWZpbGVOYW1lcyA9IG51bGw7CisJCQorCWludCB0aXRsZVB0ciA9IDA7CisJaWYgKHRpdGxlICE9IG51bGwpIHsKKwkJY2hhciBbXSBidWZmZXIgPSBuZXcgY2hhciBbdGl0bGUubGVuZ3RoICgpXTsKKwkJdGl0bGUuZ2V0Q2hhcnMgKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlciwgMCk7CisJCXRpdGxlUHRyID0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgYnVmZmVyLCBidWZmZXIubGVuZ3RoKTsKKwl9CisJaW50IGZpbGVOYW1lUHRyID0gMDsKKwlpZiAoZmlsZU5hbWUgIT0gbnVsbCkgeworCQljaGFyIFtdIGJ1ZmZlciA9IG5ldyBjaGFyIFtmaWxlTmFtZS5sZW5ndGggKCldOworCQlmaWxlTmFtZS5nZXRDaGFycyAoMCwgYnVmZmVyLmxlbmd0aCwgYnVmZmVyLCAwKTsKKwkJZmlsZU5hbWVQdHIgPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzIChPUy5rQ0ZBbGxvY2F0b3JEZWZhdWx0LCBidWZmZXIsIGJ1ZmZlci5sZW5ndGgpOwkJCisJfQorCQkKKwlOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnMgb3B0aW9ucyA9IG5ldyBOYXZEaWFsb2dDcmVhdGlvbk9wdGlvbnMgKCk7CisJb3B0aW9ucy53aW5kb3dUaXRsZSA9IG9wdGlvbnMuY2xpZW50TmFtZSA9IHRpdGxlUHRyOworCW9wdGlvbnMucGFyZW50V2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChwYXJlbnQuaGFuZGxlKTsKKwlvcHRpb25zLm9wdGlvbkZsYWdzID0gT1Mua05hdlN1cHBvcnRQYWNrYWdlcyB8IE9TLmtOYXZBbGxvd09wZW5QYWNrYWdlcyB8IE9TLmtOYXZBbGxvd0ludmlzaWJsZUZpbGVzOworCW9wdGlvbnMubG9jYXRpb25faCA9IC0xOworCW9wdGlvbnMubG9jYXRpb25fdiA9IC0xOworCW9wdGlvbnMuc2F2ZUZpbGVOYW1lID0gZmlsZU5hbWVQdHI7CiAKLQlpbnQgZGlhbG9nPSAwOwotCVN0cmluZyByZXN1bHQ9IG51bGw7Ci0JCi0JaW50IHRpdGxlSGFuZGxlPSAwOwotCXRyeSB7Ci0JCWludCBwYXJlbnRXaW5kb3dIYW5kbGU9IDA7Ci0JCWlmIChwYXJlbnQgIT0gbnVsbCkKLQkJCXBhcmVudFdpbmRvd0hhbmRsZT0gcGFyZW50LnNoZWxsSGFuZGxlOwotCQkKLQkJdGl0bGVIYW5kbGU9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnModGl0bGUpOwotCi0JCWludCBzdGF0dXM9IDA7Ci0JCWludCBmbGFncz0gMDsKLQkJaW50W10gZGlhbG9nSGFuZGxlPSBuZXcgaW50WzFdOwotCQkKLQkJaWYgKChzdHlsZSAmIFNXVC5TQVZFKSAhPSAwKSB7Ci0JCQlzdGF0dXM9IE9TLk5hdkNyZWF0ZVB1dEZpbGVEaWFsb2coZmxhZ3MsIHRpdGxlSGFuZGxlLCBwYXJlbnRXaW5kb3dIYW5kbGUsIGRpYWxvZ0hhbmRsZSwKLQkJCQkJCQlNYWNVdGlsLk9TVHlwZSgiVEVYVCIpLCBNYWNVdGlsLk9TVHlwZSgiS0FITCIpKTsKLQkJfSBlbHNlIC8qIGlmICgoc3R5bGUgJiBTV1QuT1BFTikgIT0gMCkgKi8gewotCQkJaWYgKChzdHlsZSAmIFNXVC5NVUxUSSkgIT0gMCkKLQkJCQlmbGFncyB8PSBPUy5rTmF2QWxsb3dNdWx0aXBsZUZpbGVzOwotCQkJc3RhdHVzPSBPUy5OYXZDcmVhdGVHZXRGaWxlRGlhbG9nKGZsYWdzLCB0aXRsZUhhbmRsZSwgcGFyZW50V2luZG93SGFuZGxlLCBkaWFsb2dIYW5kbGUpOwotCQl9Ci0JCQotCQlpZiAoc3RhdHVzID09IDApIHsKLQkJCWRpYWxvZz0gZGlhbG9nSGFuZGxlWzBdOwotCQl9IGVsc2UgewotCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIkZpbGVEaWFsb2cub3Blbjogc3RhdHVzICIgKyBzdGF0dXMpOwotCQl9Ci0JCQotCQlpZiAoZGlhbG9nICE9IDApIHsKLQkJCS8vU3lzdGVtLm91dC5wcmludGxuKCJGaWxlRGlhbG9nLm9wZW46IGdvdCBkaWFsb2ciKTsKLQkJCi0JCQlpZiAoKHN0eWxlICYgU1dULlNBVkUpICE9IDApIHsKLQkJCQlpbnQgZmlsZU5hbWVIYW5kbGU9IDA7Ci0JCQkJdHJ5IHsKLQkJCQkJZmlsZU5hbWVIYW5kbGU9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMoZmlsZU5hbWVzWzBdKTsKLQkJCQkJT1MuTmF2RGlhbG9nU2V0U2F2ZUZpbGVOYW1lKGRpYWxvZywgZmlsZU5hbWVIYW5kbGUpOwotCQkJCX0gZmluYWxseSB7Ci0JCQkJCWlmIChmaWxlTmFtZUhhbmRsZSAhPSAwKQotCQkJCQkJT1MuQ0ZSZWxlYXNlKGZpbGVOYW1lSGFuZGxlKTsKKwlpbnQgW10gb3V0RGlhbG9nID0gbmV3IGludCBbMV07CisJaWYgKChzdHlsZSAmIFNXVC5TQVZFKSAhPSAwKSB7CisJCS8vIE5FRURTIFdPUksgLSBmaWx0ZXIgZXh0ZW5zaW9ucywgc3RhcnQgaW4gZmlsdGVyIHBhdGgsIGFsbG93IHVzZXIKKwkJLy8gdG8gc2VsZWN0IGV4aXN0aW5nIGZpbGVzLgorCQlPUy5OYXZDcmVhdGVQdXRGaWxlRGlhbG9nIChvcHRpb25zLCAwLCAwLCAwLCAwLCBvdXREaWFsb2cpOwkJCisJfSBlbHNlIHsKKwkJaWYgKChzdHlsZSAmIFNXVC5NVUxUSSkgIT0gMCkgb3B0aW9ucy5vcHRpb25GbGFncyB8PSBPUy5rTmF2QWxsb3dNdWx0aXBsZUZpbGVzOworCQkvLyBORUVEUyBXT1JLIC0gZmlsdGVyIGV4dGVuc2lvbnMsIHN0YXJ0IGluIGZpbHRlciBwYXRoLCBzZWxlY3QgZmlsZSBuYW1lIGlmIGl0IGV4aXN0cworCQlPUy5OYXZDcmVhdGVHZXRGaWxlRGlhbG9nKG9wdGlvbnMsIDAsIDAsIDAsIDAsIDAsIG91dERpYWxvZyk7CisJfQorCWlmIChvdXREaWFsb2cgWzBdICE9IDApIHsKKwkJT1MuTmF2RGlhbG9nUnVuIChvdXREaWFsb2cgWzBdKTsKKwkJaW50IGFjdGlvbiA9IE9TLk5hdkRpYWxvZ0dldFVzZXJBY3Rpb24gKG91dERpYWxvZyBbMF0pOworCQlzd2l0Y2ggKGFjdGlvbikgeworCQkJY2FzZSBPUy5rTmF2VXNlckFjdGlvbk9wZW46CisJCQljYXNlIE9TLmtOYXZVc2VyQWN0aW9uQ2hvb3NlOgkJCQkJCQkKKwkJCWNhc2UgT1Mua05hdlVzZXJBY3Rpb25TYXZlQXM6IHsKKwkJCQlOYXZSZXBseVJlY29yZCByZWNvcmQgPSBuZXcgTmF2UmVwbHlSZWNvcmQgKCk7CisJCQkJT1MuTmF2RGlhbG9nR2V0UmVwbHkgKG91dERpYWxvZyBbMF0sIHJlY29yZCk7CisJCQkJQUVEZXNjIHNlbGVjdGlvbiA9IG5ldyBBRURlc2MgKCk7CisJCQkJc2VsZWN0aW9uLmRlc2NyaXB0b3JUeXBlID0gcmVjb3JkLnNlbGVjdGlvbl9kZXNjcmlwdG9yVHlwZTsKKwkJCQlzZWxlY3Rpb24uZGF0YUhhbmRsZSA9IHJlY29yZC5zZWxlY3Rpb25fZGF0YUhhbmRsZTsKKwkJCQlpbnQgW10gY291bnQgPSBuZXcgaW50IFsxXTsKKwkJCQlPUy5BRUNvdW50SXRlbXMgKHNlbGVjdGlvbiwgY291bnQpOworCQkJCWlmIChjb3VudCBbMF0gPiAwKSB7CisJCQkJCWZpbGVOYW1lcyA9IG5ldyBTdHJpbmcgW2NvdW50IFswXV07CisJCQkJCWludCBtYXhpbXVtU2l6ZSA9IDgwOyAvLyBzaXplIG9mIEZTUmVmCisJCQkJCWludCBkYXRhUHRyID0gT1MuTmV3UHRyIChtYXhpbXVtU2l6ZSk7CisJCQkJCWludFtdIGFlS2V5d29yZCA9IG5ldyBpbnQgWzFdOworCQkJCQlpbnRbXSB0eXBlQ29kZSA9IG5ldyBpbnQgWzFdOworCQkJCQlpbnRbXSBhY3R1YWxTaXplID0gbmV3IGludCBbMV07CisJCQkJCWludCBwYXRoU3RyaW5nID0gMDsKKwkJCQkJaW50IGZ1bGxTdHJpbmcgPSAwOworCQkJCQlpbnQgZmlsZVN0cmluZyA9IDA7CisJCQkJCQkJCQkJCQkKKwkJCQkJaWYgKChzdHlsZSAmIFNXVC5TQVZFKSAhPSAwKSB7CisJCQkJCQlpZiAoT1MuQUVHZXROdGhQdHIgKHNlbGVjdGlvbiwgMSwgT1MudHlwZUZTUmVmLCBhZUtleXdvcmQsIHR5cGVDb2RlLCBkYXRhUHRyLCBtYXhpbXVtU2l6ZSwgYWN0dWFsU2l6ZSkgPT0gT1Mubm9FcnIpIHsKKwkJCQkJCQlieXRlW10gZnNSZWYgPSBuZXcgYnl0ZVthY3R1YWxTaXplWzBdXTsKKwkJCQkJCQlPUy5tZW1jcHkgKGZzUmVmLCBkYXRhUHRyLCBhY3R1YWxTaXplIFswXSk7CisJCQkJCQkJaW50IHBhdGhVcmwgPSBPUy5DRlVSTENyZWF0ZUZyb21GU1JlZiAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgZnNSZWYpOworCQkJCQkJCWludCBmdWxsVXJsID0gT1MuQ0ZVUkxDcmVhdGVDb3B5QXBwZW5kaW5nUGF0aENvbXBvbmVudChPUy5rQ0ZBbGxvY2F0b3JEZWZhdWx0LCBwYXRoVXJsLCByZWNvcmQuc2F2ZUZpbGVOYW1lLCBmYWxzZSk7CisJCQkJCQkJcGF0aFN0cmluZyA9IE9TLkNGVVJMQ29weUZpbGVTeXN0ZW1QYXRoKHBhdGhVcmwsIE9TLmtDRlVSTFBPU0lYUGF0aFN0eWxlKTsKKwkJCQkJCQlmdWxsU3RyaW5nID0gT1MuQ0ZVUkxDb3B5RmlsZVN5c3RlbVBhdGgoZnVsbFVybCwgT1Mua0NGVVJMUE9TSVhQYXRoU3R5bGUpOworCQkJCQkJCWZpbGVTdHJpbmcgPSByZWNvcmQuc2F2ZUZpbGVOYW1lOworCQkJCQkJCU9TLkNGUmVsZWFzZSAocGF0aFVybCk7CisJCQkJCQkJT1MuQ0ZSZWxlYXNlIChmdWxsVXJsKTsKKwkJCQkJCX0KKwkJCQkJfSBlbHNlIHsKKwkJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQgWzBdOyBpKyspIHsKKwkJCQkJCQlpZiAoT1MuQUVHZXROdGhQdHIgKHNlbGVjdGlvbiwgaSsxLCBPUy50eXBlRlNSZWYsIGFlS2V5d29yZCwgdHlwZUNvZGUsIGRhdGFQdHIsIG1heGltdW1TaXplLCBhY3R1YWxTaXplKSA9PSBPUy5ub0VycikgeworCQkJCQkJCQlieXRlW10gZnNSZWYgPSBuZXcgYnl0ZVthY3R1YWxTaXplWzBdXTsKKwkJCQkJCQkJT1MubWVtY3B5IChmc1JlZiwgZGF0YVB0ciwgYWN0dWFsU2l6ZSBbMF0pOworCQkJCQkJCQlpbnQgdXJsID0gT1MuQ0ZVUkxDcmVhdGVGcm9tRlNSZWYgKE9TLmtDRkFsbG9jYXRvckRlZmF1bHQsIGZzUmVmKTsKKwkJCQkJCQkJaWYgKGkgPT0gMCkgeworCQkJCQkJCQkJaW50IHBhdGhVcmwgPSBPUy5DRlVSTENyZWF0ZUNvcHlEZWxldGluZ0xhc3RQYXRoQ29tcG9uZW50KE9TLmtDRkFsbG9jYXRvckRlZmF1bHQsIHVybCk7CisJCQkJCQkJCQlwYXRoU3RyaW5nID0gT1MuQ0ZVUkxDb3B5RmlsZVN5c3RlbVBhdGggKHBhdGhVcmwsIE9TLmtDRlVSTFBPU0lYUGF0aFN0eWxlKTsKKwkJCQkJCQkJCWZ1bGxTdHJpbmcgPSBPUy5DRlVSTENvcHlGaWxlU3lzdGVtUGF0aCAodXJsLCBPUy5rQ0ZVUkxQT1NJWFBhdGhTdHlsZSk7CisJCQkJCQkJCQlmaWxlU3RyaW5nID0gT1MuQ0ZVUkxDb3B5TGFzdFBhdGhDb21wb25lbnQgKHVybCk7CisJCQkJCQkJCQlPUy5DRlJlbGVhc2UgKHBhdGhVcmwpOworCQkJCQkJCQl9IGVsc2UgeworCQkJCQkJCQkJaW50IGxhc3RTdHJpbmcgPSBPUy5DRlVSTENvcHlMYXN0UGF0aENvbXBvbmVudCAodXJsKTsKKwkJCQkJCQkJCWludCBsZW5ndGggPSBPUy5DRlN0cmluZ0dldExlbmd0aCAobGFzdFN0cmluZyk7CisJCQkJCQkJCQljaGFyIFtdIGJ1ZmZlcj0gbmV3IGNoYXIgW2xlbmd0aF07CisJCQkJCQkJCQlDRlJhbmdlIHJhbmdlID0gbmV3IENGUmFuZ2UgKCk7CisJCQkJCQkJCQlyYW5nZS5sZW5ndGggPSBsZW5ndGg7CisJCQkJCQkJCQlPUy5DRlN0cmluZ0dldENoYXJhY3RlcnMgKGxhc3RTdHJpbmcsIHJhbmdlLCBidWZmZXIpOworCQkJCQkJCQkJZmlsZU5hbWVzIFtpXSA9IG5ldyBTdHJpbmcgKGJ1ZmZlcik7CisJCQkJCQkJCQlPUy5DRlJlbGVhc2UgKGxhc3RTdHJpbmcpOworCQkJCQkJCQl9CisJCQkJCQkJCU9TLkNGUmVsZWFzZSAodXJsKTsKKwkJCQkJCQl9CisJCQkJCQl9CisJCQkJCX0KKwkJCQkJT1MuRGlzcG9zZVB0ciAoZGF0YVB0cik7CisJCQkJCQorCQkJCQlpZiAocGF0aFN0cmluZyAhPSAwKSB7CQkKKwkJCQkJCWludCBsZW5ndGggPSBPUy5DRlN0cmluZ0dldExlbmd0aCAocGF0aFN0cmluZyk7CisJCQkJCQljaGFyIFtdIGJ1ZmZlcj0gbmV3IGNoYXIgW2xlbmd0aF07CisJCQkJCQlDRlJhbmdlIHJhbmdlID0gbmV3IENGUmFuZ2UgKCk7CisJCQkJCQlyYW5nZS5sZW5ndGggPSBsZW5ndGg7CisJCQkJCQlPUy5DRlN0cmluZ0dldENoYXJhY3RlcnMgKHBhdGhTdHJpbmcsIHJhbmdlLCBidWZmZXIpOworCQkJCQkJT1MuQ0ZSZWxlYXNlIChwYXRoU3RyaW5nKTsKKwkJCQkJCWZpbHRlclBhdGggPSBuZXcgU3RyaW5nIChidWZmZXIpOworCQkJCQl9CisJCQkJCWlmIChmdWxsU3RyaW5nICE9IDApIHsKKwkJCQkJCWludCBsZW5ndGggPSBPUy5DRlN0cmluZ0dldExlbmd0aCAoZnVsbFN0cmluZyk7CisJCQkJCQljaGFyIFtdIGJ1ZmZlcj0gbmV3IGNoYXIgW2xlbmd0aF07CisJCQkJCQlDRlJhbmdlIHJhbmdlID0gbmV3IENGUmFuZ2UgKCk7CisJCQkJCQlyYW5nZS5sZW5ndGggPSBsZW5ndGg7CisJCQkJCQlPUy5DRlN0cmluZ0dldENoYXJhY3RlcnMgKGZ1bGxTdHJpbmcsIHJhbmdlLCBidWZmZXIpOworCQkJCQkJT1MuQ0ZSZWxlYXNlIChmdWxsU3RyaW5nKTsKKwkJCQkJCWZ1bGxQYXRoID0gbmV3IFN0cmluZyAoYnVmZmVyKTsKKwkJCQkJfSAKKwkJCQkJaWYgKGZpbGVTdHJpbmcgIT0gMCkgeworCQkJCQkJaW50IGxlbmd0aCA9IE9TLkNGU3RyaW5nR2V0TGVuZ3RoIChmaWxlU3RyaW5nKTsKKwkJCQkJCWNoYXIgW10gYnVmZmVyPSBuZXcgY2hhciBbbGVuZ3RoXTsKKwkJCQkJCUNGUmFuZ2UgcmFuZ2UgPSBuZXcgQ0ZSYW5nZSAoKTsKKwkJCQkJCXJhbmdlLmxlbmd0aCA9IGxlbmd0aDsKKwkJCQkJCU9TLkNGU3RyaW5nR2V0Q2hhcmFjdGVycyAoZmlsZVN0cmluZywgcmFuZ2UsIGJ1ZmZlcik7CisJCQkJCQlPUy5DRlJlbGVhc2UgKGZpbGVTdHJpbmcpOworCQkJCQkJZmlsZU5hbWUgPSBmaWxlTmFtZXMgWzBdID0gbmV3IFN0cmluZyAoYnVmZmVyKTsKKwkJCQkJfQogCQkJCX0KIAkJCX0KLQkJCi0JCQkvL1N5c3RlbS5vdXQucHJpbnRsbigiRmlsZURpYWxvZy5vcGVuOiB2b3IgcnVuIik7Ci0JCQlPUy5OYXZEaWFsb2dSdW4oZGlhbG9nKTsKLQkJCS8vU3lzdGVtLm91dC5wcmludGxuKCJGaWxlRGlhbG9nLm9wZW46IG5hY2ggcnVuIik7Ci0JCQotCQkJaW50IGFjdGlvbj0gT1MuTmF2RGlhbG9nR2V0VXNlckFjdGlvbihkaWFsb2cpOwotCQkJc3dpdGNoIChhY3Rpb24pIHsKLQkJCWNhc2UgT1Mua05hdlVzZXJBY3Rpb25DYW5jZWw6Ci0JCQkJYnJlYWs7Ci0JCQkJCi0JCQljYXNlIE9TLmtOYXZVc2VyQWN0aW9uT3BlbjoKLQkJCWNhc2UgT1Mua05hdlVzZXJBY3Rpb25DaG9vc2U6CQkJCi0JCQkJcmVzdWx0PSBpbnRlcnByZXRPc0Fuc3dlcihkaWFsb2cpOwotCQkJCWJyZWFrOwotCQkJCQotCQkJY2FzZSBPUy5rTmF2VXNlckFjdGlvblNhdmVBczoKLQkJCQlyZXN1bHQ9IE1hY1V0aWwuZ2V0U3RyaW5nQW5kUmVsZWFzZShPUy5OYXZEaWFsb2dHZXRTYXZlRmlsZU5hbWUoZGlhbG9nKSk7Ci0JCQkJYnJlYWs7Ci0JCQl9Ci0JCX0gZWxzZSB7Ci0JCQkvL1N5c3RlbS5vdXQucHJpbnRsbigiRmlsZURpYWxvZy5vcGVuOiBkaWFsb2cgPT0gbnVsbCIpOwogCQl9Ci0KLQl9IGZpbmFsbHkgewotCQlpZiAodGl0bGVIYW5kbGUgIT0gMCkKLQkJCU9TLkNGUmVsZWFzZSh0aXRsZUhhbmRsZSk7Ci0JCWlmIChkaWFsb2cgIT0gMCkKLQkJCU9TLk5hdkRpYWxvZ0Rpc3Bvc2UoZGlhbG9nKTsKIAl9Ci0JCi0JcmV0dXJuIHJlc3VsdDsKKworCWlmICh0aXRsZVB0ciAhPSAwKSBPUy5DRlJlbGVhc2UgKHRpdGxlUHRyKTsKKwlpZiAoZmlsZU5hbWVQdHIgIT0gMCkgT1MuQ0ZSZWxlYXNlIChmaWxlTmFtZVB0cik7CQorCWlmIChvdXREaWFsb2cgWzBdICE9IDApIE9TLk5hdkRpYWxvZ0Rpc3Bvc2UgKG91dERpYWxvZyBbMF0pOworCisJcmV0dXJuIGZ1bGxQYXRoOwkKIH0KIAotLyoqCi0gKiBTZXQgdGhlIGluaXRpYWwgZmlsZW5hbWUgd2hpY2ggdGhlIGRpYWxvZyB3aWxsCi0gKiBzZWxlY3QgYnkgZGVmYXVsdCB3aGVuIG9wZW5lZCB0byB0aGUgYXJndW1lbnQsCi0gKiB3aGljaCBtYXkgYmUgbnVsbC4gIFRoZSBuYW1lIHdpbGwgYmUgcHJlZml4ZWQgd2l0aAotICogdGhlIGZpbHRlciBwYXRoIHdoZW4gb25lIGlzIHN1cHBsaWVkLgotICogCi0gKiBAcGFyYW0gc3RyaW5nIHRoZSBmaWxlIG5hbWUKLSAqLwogcHVibGljIHZvaWQgc2V0RmlsZU5hbWUgKFN0cmluZyBzdHJpbmcpIHsKLQlmaWxlTmFtZXMgPSBuZXcgU3RyaW5nW10geyBzdHJpbmcgfTsKKwlmaWxlTmFtZSA9IHN0cmluZzsKIH0KIAotLyoqCi0gKiBTZXQgdGhlIGZpbGUgZXh0ZW5zaW9ucyB3aGljaCB0aGUgZGlhbG9nIHdpbGwKLSAqIHVzZSB0byBmaWx0ZXIgdGhlIGZpbGVzIGl0IHNob3dzIHRvIHRoZSBhcmd1bWVudCwKLSAqIHdoaWNoIG1heSBiZSBudWxsLgotICoKLSAqIEBwYXJhbSBleHRlbnNpb25zIHRoZSBmaWxlIGV4dGVuc2lvbiBmaWx0ZXIKLSAqLwogcHVibGljIHZvaWQgc2V0RmlsdGVyRXh0ZW5zaW9ucyAoU3RyaW5nIFtdIGV4dGVuc2lvbnMpIHsKIAlmaWx0ZXJFeHRlbnNpb25zID0gZXh0ZW5zaW9uczsKIH0KIAotLyoqCi0gKiBTZXRzIHRoZSBmaWxlIG5hbWVzIHdoaWNoIHRoZSBkaWFsb2cgd2lsbAotICogdXNlIHRvIGZpbHRlciB0aGUgZmlsZXMgaXQgc2hvd3MgdG8gdGhlIGFyZ3VtZW50LAotICogd2hpY2ggbWF5IGJlIG51bGwuCi0gKgotICogQHBhcmFtIG5hbWVzIHRoZSBmaWxlIG5hbWUgZmlsdGVyCi0gKi8KIHB1YmxpYyB2b2lkIHNldEZpbHRlck5hbWVzIChTdHJpbmcgW10gbmFtZXMpIHsKIAlmaWx0ZXJOYW1lcyA9IG5hbWVzOwogfQotLyoqCi0gKiBTZXRzIHRoZSBwYXRoIHdoaWNoIHRoZSBkaWFsb2cgd2lsbCB1c2UgdG8gZmlsdGVyCi0gKiB0aGUgZGlyZWN0b3JpZXMgaXQgc2hvd3MgdG8gdGhlIGFyZ3VtZW50LCB3aGljaCBtYXkgYmUKLSAqIG51bGwuCi0gKgotICogQHBhcmFtIHN0cmluZyB0aGUgZmlsdGVyIHBhdGgKLSAqLworCiBwdWJsaWMgdm9pZCBzZXRGaWx0ZXJQYXRoIChTdHJpbmcgc3RyaW5nKSB7CiAJZmlsdGVyUGF0aCA9IHN0cmluZzsKIH0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Gb250RGlhbG9nLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvRm9udERpYWxvZy5qYXZhCmluZGV4IGFlOGM5MWMuLjExZmYzMTcgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Gb250RGlhbG9nLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0ZvbnREaWFsb2cuamF2YQpAQCAtOSw5MzUgKzksMTM3IEBACiAgCiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uT1M7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Gb250U2VsZWN0aW9uUURTdHlsZTsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuQ2FsbGJhY2s7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5SR0JDb2xvcjsKIAotaW1wb3J0IGphdmEudXRpbC4qOwotCi0vKioKLSAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGFsbG93IHRoZSB1c2VyIHRvIHNlbGVjdCBhIGZvbnQKLSAqIGZyb20gYWxsIGF2YWlsYWJsZSBmb250cyBpbiB0aGUgc3lzdGVtLgotICogPHA+Ci0gKiBJTVBPUlRBTlQ6IFRoaXMgY2xhc3MgaXMgaW50ZW5kZWQgdG8gYmUgc3ViY2xhc3NlZCA8ZW0+b25seTwvZW0+Ci0gKiB3aXRoaW4gdGhlIFNXVCBpbXBsZW1lbnRhdGlvbi4KLSAqIDwvcD4KLSAqLwogcHVibGljIGNsYXNzIEZvbnREaWFsb2cgZXh0ZW5kcyBEaWFsb2cgewotCS8qCi0JICogVGFibGUgY29udGFpbmluZyBhbGwgYXZhaWxhYmxlIGZvbnRzIGFzIEZvbnREYXRhIG9iamVjdHMuCi0JICogVGhlIHRhYmxlIGlzIHN0cnVjdHVyZWQgYXMgYSBzZXJpZXMgb2YgZW1iZWRkZWQgSGFzaHRhYmxlcyBhcyBmb2xsb3dzOgotCSAqIDxicj5jaGFyYWN0ZXJSZWdpc3RyeU5hbWUgLT4gZmFjZU5hbWUgLT4gZXh0ZW5kZWRTdHlsZSAtPiBzaXplIC0+IHN0eWxlCi0JICovCi0JcHJpdmF0ZSBIYXNodGFibGUgY2hhcmFjdGVyU2V0cyA9IG5ldyBIYXNodGFibGUgKCk7Ci0JcHJpdmF0ZSBGb250RGF0YSBpbml0aWFsRm9udERhdGE7Ci0JcHJpdmF0ZSBGb250IHNhbXBsZUZvbnQ7CQkJLy8gdGhlIGN1cnJlbnQgZGlzcGxheWVkIHNhbXBsZSBmb250Ci0JcHJpdmF0ZSBib29sZWFuIG9rU2VsZWN0ZWQgPSBmYWxzZTsKLQlwcml2YXRlIGJvb2xlYW4gaWdub3JlRXZlbnRzID0gZmFsc2U7Ci0KLQkvLyB3aWRnZXRzCQotCXByaXZhdGUgU2hlbGwgc2hlbGw7Ci0JcHJpdmF0ZSBDb21ibyBjaGFyU2V0Q29tYm87Ci0JcHJpdmF0ZSBDb21ibyBmYWNlTmFtZUNvbWJvOwotCXByaXZhdGUgQ29tYm8gZm9udFNpemVDb21ibzsJCi0JcHJpdmF0ZSBDb21ibyBmb250U3R5bGVDb21ibzsKLQlwcml2YXRlIENvbWJvIGV4dFN0eWxlQ29tYm87Ci0JcHJpdmF0ZSBMYWJlbCBzYW1wbGVMYWJlbDsKLQlwcml2YXRlIEJ1dHRvbiBva0J1dHRvbjsKLQlwcml2YXRlIEJ1dHRvbiBjYW5jZWxCdXR0b247Ci0KLQkvLyBjb25zdGFudHMKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVYVF9TQU1QTEUgPSAiQWFCYll5WnoiOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTQ0FMQUJMRV9TSVpFU1tdID0gbmV3IFN0cmluZ1tdIHsiOCIsICIxMCIsICIxMSIsICIxMiIsICIxNCIsICIxNiIsICIxOCIsICIyMiIsICIyNCIsICIyNiJ9OwotCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NJWkUgPSAxNDsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9TVFlMRSA9ICJtZWRpdW0iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIEludGVnZXIgU0NBTEFCTEVfS0VZID0gbmV3IEludGVnZXIgKDApOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIEludGVnZXIgTk9fU0VMRUNUSU9OID0gbmV3IEludGVnZXIgKC0xKTsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09MVU1OMV9XSURUSCA9IDIwMDsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09MVU1OMl9XSURUSCA9IDE1MDsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09MVU1OM19XSURUSCA9IDEwMDsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJFRklYX0lTTzg4NTkgPSAiaXNvODg1OSI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBSRUZJWF9JU082NDYgPSAiaXNvNjQ2IjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJFRklYX1VOSUNPREUgPSAidWNzIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJFRklYX0pBUEFORVNFID0gImppcyI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBSRUZJWF9TSU1QTElGSUVEQ0hJTkVTRSA9ICJnYiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBSRUZJWF9UUkFESVRJT05BTENISU5FU0UgPSAiY25zIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJFRklYX0tPUkVBTiA9ICJrcyI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFtdIElTT19DSEFSU0VUUyA9IG5ldyBTdHJpbmcgW10gewotCQkiIiwJLy8gdW5kZWZpbmVkCi0JCVNXVC5nZXRNZXNzYWdlICgiU1dUX0NoYXJzZXRfV2VzdGVybiIpLAotCQlTV1QuZ2V0TWVzc2FnZSAoIlNXVF9DaGFyc2V0X0Vhc3RFdXJvcGVhbiIpLAotCQlTV1QuZ2V0TWVzc2FnZSAoIlNXVF9DaGFyc2V0X1NvdXRoRXVyb3BlYW4iKSwKLQkJU1dULmdldE1lc3NhZ2UgKCJTV1RfQ2hhcnNldF9Ob3J0aEV1cm9wZWFuIiksCi0JCVNXVC5nZXRNZXNzYWdlICgiU1dUX0NoYXJzZXRfQ3lyaWxsaWMiKSwKLQkJU1dULmdldE1lc3NhZ2UgKCJTV1RfQ2hhcnNldF9BcmFiaWMiKSwKLQkJU1dULmdldE1lc3NhZ2UgKCJTV1RfQ2hhcnNldF9HcmVlayIpLAotCQlTV1QuZ2V0TWVzc2FnZSAoIlNXVF9DaGFyc2V0X0hlYnJldyIpLAotCQlTV1QuZ2V0TWVzc2FnZSAoIlNXVF9DaGFyc2V0X1R1cmtpc2giKSwKLQkJU1dULmdldE1lc3NhZ2UgKCJTV1RfQ2hhcnNldF9Ob3JkaWMiKSwKLQkJU1dULmdldE1lc3NhZ2UgKCJTV1RfQ2hhcnNldF9UaGFpIiksCi0JCSIiLAkvLyB1bmRlZmluZWQKLQkJU1dULmdldE1lc3NhZ2UgKCJTV1RfQ2hhcnNldF9CYWx0aWNSaW0iKSwKLQkJU1dULmdldE1lc3NhZ2UgKCJTV1RfQ2hhcnNldF9DZWx0aWMiKSwKLQkJU1dULmdldE1lc3NhZ2UgKCJTV1RfQ2hhcnNldF9FdXJvIikKLQl9OwotCisJRm9udERhdGEgZm9udERhdGE7CiAJUkdCIHJnYjsKLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIG9ubHkgaXRzCi0gKiBwYXJlbnQuCi0gKiA8cD4KLSAqIE5vdGU6IEN1cnJlbnRseSwgbnVsbCBjYW4gYmUgcGFzc2VkIGluIGZvciB0aGUgcGFyZW50LgotICogVGhpcyBoYXMgdGhlIGVmZmVjdCBvZiBjcmVhdGluZyB0aGUgZGlhbG9nIG9uIHRoZSBjdXJyZW50bHkgYWN0aXZlCi0gKiBkaXNwbGF5IGlmIHRoZXJlIGlzIG9uZS4gSWYgdGhlcmUgaXMgbm8gY3VycmVudCBkaXNwbGF5LCB0aGUgCi0gKiBkaWFsb2cgaXMgY3JlYXRlZCBvbiBhICJkZWZhdWx0IiBkaXNwbGF5LiA8Yj5QYXNzaW5nIGluIG51bGwgYXMKLSAqIHRoZSBwYXJlbnQgaXMgbm90IGNvbnNpZGVyZWQgdG8gYmUgZ29vZCBjb2Rpbmcgc3R5bGUsCi0gKiBhbmQgbWF5IG5vdCBiZSBzdXBwb3J0ZWQgaW4gYSBmdXR1cmUgcmVsZWFzZSBvZiBTV1QuPC9iPgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBzaGVsbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwlib29sZWFuIG9wZW47CisKIHB1YmxpYyBGb250RGlhbG9nIChTaGVsbCBwYXJlbnQpIHsKLQl0aGlzIChwYXJlbnQsIFNXVC5OT05FKTsKKwl0aGlzIChwYXJlbnQsIFNXVC5BUFBMSUNBVElPTl9NT0RBTCk7CiB9CiAKLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIGl0cyBwYXJlbnQKLSAqIGFuZCBhIHN0eWxlIHZhbHVlIGRlc2NyaWJpbmcgaXRzIGJlaGF2aW9yIGFuZCBhcHBlYXJhbmNlLgotICogPHA+Ci0gKiBUaGUgc3R5bGUgdmFsdWUgaXMgZWl0aGVyIG9uZSBvZiB0aGUgc3R5bGUgY29uc3RhbnRzIGRlZmluZWQgaW4KLSAqIGNsYXNzIDxjb2RlPlNXVDwvY29kZT4gd2hpY2ggaXMgYXBwbGljYWJsZSB0byBpbnN0YW5jZXMgb2YgdGhpcwotICogY2xhc3MsIG9yIG11c3QgYmUgYnVpbHQgYnkgPGVtPmJpdHdpc2UgT1I8L2VtPidpbmcgdG9nZXRoZXIgCi0gKiAodGhhdCBpcywgdXNpbmcgdGhlIDxjb2RlPmludDwvY29kZT4gInwiIG9wZXJhdG9yKSB0d28gb3IgbW9yZQotICogb2YgdGhvc2UgPGNvZGU+U1dUPC9jb2RlPiBzdHlsZSBjb25zdGFudHMuIFRoZSBjbGFzcyBkZXNjcmlwdGlvbgotICogbGlzdHMgdGhlIHN0eWxlIGNvbnN0YW50cyB0aGF0IGFyZSBhcHBsaWNhYmxlIHRvIHRoZSBjbGFzcy4KLSAqIFN0eWxlIGJpdHMgYXJlIGFsc28gaW5oZXJpdGVkIGZyb20gc3VwZXJjbGFzc2VzLgotICogPC9wPgotICogTm90ZTogQ3VycmVudGx5LCBudWxsIGNhbiBiZSBwYXNzZWQgaW4gZm9yIHRoZSBwYXJlbnQuCi0gKiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGNyZWF0aW5nIHRoZSBkaWFsb2cgb24gdGhlIGN1cnJlbnRseSBhY3RpdmUKLSAqIGRpc3BsYXkgaWYgdGhlcmUgaXMgb25lLiBJZiB0aGVyZSBpcyBubyBjdXJyZW50IGRpc3BsYXksIHRoZSAKLSAqIGRpYWxvZyBpcyBjcmVhdGVkIG9uIGEgImRlZmF1bHQiIGRpc3BsYXkuIDxiPlBhc3NpbmcgaW4gbnVsbCBhcwotICogdGhlIHBhcmVudCBpcyBub3QgY29uc2lkZXJlZCB0byBiZSBnb29kIGNvZGluZyBzdHlsZSwKLSAqIGFuZCBtYXkgbm90IGJlIHN1cHBvcnRlZCBpbiBhIGZ1dHVyZSByZWxlYXNlIG9mIFNXVC48L2I+Ci0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIHNoZWxsIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcGFyZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHBhcmVudDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIEZvbnREaWFsb2cgKFNoZWxsIHBhcmVudCwgaW50IHN0eWxlKSB7Ci0Jc3VwZXIgKHBhcmVudCwgc3R5bGUgfCBTV1QuVElUTEUgfCBTV1QuQk9SREVSIHwgU1dULkFQUExJQ0FUSU9OX01PREFMKTsKKwlzdXBlciAocGFyZW50LCBzdHlsZSk7CiAJY2hlY2tTdWJjbGFzcyAoKTsKIH0KIAotLyoqCi0gKiBBZGQgdGhlIGZvbnRzIGZvdW5kIGluICdmb250cycgdG8gdGhlIGxpc3Qgb2YgZm9udHMuCi0gKiBGb250cyBhcmUgc3RvcmVkIGJ5IGNoYXJhY3RlciBzZXQgYW5kIGZhY2UgbmFtZS4gRm9yIGVhY2ggY2hhcmFjdGVyIAotICogc2V0L2ZhY2UgbmFtZSBjb21iaW5hdGlvbiB0aGVyZSBpcyBvbmUgRm9udEV4dFN0eWxlcyBvYmplY3QgdGhhdCAKLSAqIGNhcHR1cmVzIHRoZSBkaWZmZXJlbnQgZXh0ZW5kZWQgc3R5bGVzIGFuZCB0aGUgc2l6ZXMgYW5kIHN0eWxlcyAKLSAqIGF2YWlsYWJsZSBmb3IgdGhhdCBleHRlbmRlZCBzdHlsZS4KLSAqLwotdm9pZCBhZGRGb250cyAoRm9udERhdGEgZm9udHNbXSkgewotCi0JZm9yIChpbnQgaSA9IDA7IGkgPCBmb250cy5sZW5ndGg7IGkrKykgewotCQlGb250RGF0YSBmb250ID0gZm9udHMgW2ldOwotCi0JCVN0cmluZyBjaGFyU2V0TmFtZSA9IGdldFRyYW5zbGF0ZWRDaGFyU2V0IChmb250KTsKLQkJSGFzaHRhYmxlIGNoYXJTZXQgPSAoSGFzaHRhYmxlKSBjaGFyYWN0ZXJTZXRzLmdldCAoY2hhclNldE5hbWUpOwotCQlpZiAoY2hhclNldCA9PSBudWxsKSB7Ci0JCQljaGFyU2V0ID0gbmV3IEhhc2h0YWJsZSAoOSk7Ci0JCQljaGFyYWN0ZXJTZXRzLnB1dCAoY2hhclNldE5hbWUsIGNoYXJTZXQpOwotCQl9Ci0KLQkJU3RyaW5nIGZhY2VOYW1lID0gZ2V0VHJhbnNsYXRlZEZhY2VOYW1lIChmb250KTsKLQkJSGFzaHRhYmxlIGZhY2VTZXQgPSAoSGFzaHRhYmxlKSBjaGFyU2V0LmdldCAoZmFjZU5hbWUpOwotCQlpZiAoZmFjZVNldCA9PSBudWxsKSB7Ci0JCQlmYWNlU2V0ID0gbmV3IEhhc2h0YWJsZSAoOSk7Ci0JCQljaGFyU2V0LnB1dCAoZmFjZU5hbWUsIGZhY2VTZXQpOwotCQl9Ci0KLQkJU3RyaW5nIGV4dFN0eWxlTmFtZSA9IGZvbnQuYWRkU3R5bGU7Ci0JCUhhc2h0YWJsZSBleHRTdHlsZVNldCA9IChIYXNodGFibGUpIGZhY2VTZXQuZ2V0IChleHRTdHlsZU5hbWUpOwotCQlpZiAoZXh0U3R5bGVTZXQgPT0gbnVsbCkgewotCQkJZXh0U3R5bGVTZXQgPSBuZXcgSGFzaHRhYmxlICg5KTsKLQkJCWZhY2VTZXQucHV0IChleHRTdHlsZU5hbWUsIGV4dFN0eWxlU2V0KTsKLQkJfQotCQkKLQkJSW50ZWdlciBzaXplVmFsdWUgPSBuZXcgSW50ZWdlciAoZm9udC5nZXRIZWlnaHQgKCkpOwotCQlIYXNodGFibGUgc2l6ZVNldCA9IChIYXNodGFibGUpIGV4dFN0eWxlU2V0LmdldCAoc2l6ZVZhbHVlKTsKLQkJaWYgKHNpemVTZXQgPT0gbnVsbCkgewotCQkJc2l6ZVNldCA9IG5ldyBIYXNodGFibGUgKDkpOwotCQkJZXh0U3R5bGVTZXQucHV0IChzaXplVmFsdWUsIHNpemVTZXQpOwotCQl9Ci0JCQotCQlTdHJpbmcgc3R5bGUgPSBmb250LndlaWdodDsKLQkJc2l6ZVNldC5wdXQgKHN0eWxlLGZvbnQpOwotCX0KLX0KLQotLyoqCi0gKiBDcmVhdGUgdGhlIHdpZGdldHMgb2YgdGhlIGRpYWxvZy4KLSAqLwotdm9pZCBjcmVhdGVDaGlsZHJlbiAoKSB7Ci0JTGFiZWwgY2hhcmFjdGVyU2V0TGFiZWwgPSBuZXcgTGFiZWwgKHNoZWxsLCBTV1QuTk9ORSk7Ci0JTGFiZWwgZmFjZU5hbWVMYWJlbCA9IG5ldyBMYWJlbCAoc2hlbGwsIFNXVC5OT05FKTsKLQlMYWJlbCBleHRlbmRlZFN0eWxlTGFiZWwgPSBuZXcgTGFiZWwgKHNoZWxsLCBTV1QuTk9ORSk7CQotCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQgKCk7Ci0JCi0JbGF5b3V0Lm51bUNvbHVtbnMgPSA0OwotCWxheW91dC5tYXJnaW5XaWR0aCA9IDE1OwotCWxheW91dC5tYXJnaW5IZWlnaHQgPSAxNTsKLQlsYXlvdXQuaG9yaXpvbnRhbFNwYWNpbmcgPSAxMDsKLQlsYXlvdXQudmVydGljYWxTcGFjaW5nID0gMjsKLQlzaGVsbC5zZXRMYXlvdXQgKGxheW91dCk7Ci0KLQkvLyByb3cgb25lCi0JY2hhcmFjdGVyU2V0TGFiZWwuc2V0VGV4dCAoU1dULmdldE1lc3NhZ2UgKCJTV1RfQ2hhcmFjdGVyX3NldCIpICsgIjoiKTsKLQlmYWNlTmFtZUxhYmVsLnNldFRleHQgKFNXVC5nZXRNZXNzYWdlICgiU1dUX0ZvbnQiKSArICI6Iik7Ci0JZXh0ZW5kZWRTdHlsZUxhYmVsLnNldFRleHQgKFNXVC5nZXRNZXNzYWdlICgiU1dUX0V4dGVuZGVkX3N0eWxlIikgKyAiOiIpOwotCQotCW5ldyBMYWJlbCAoc2hlbGwsIFNXVC5OT05FKTsKLQotCS8vIHJvdyB0d28JCi0JY2hhclNldENvbWJvID0gbmV3IENvbWJvIChzaGVsbCwgU1dULlNJTVBMRSB8IFNXVC5WX1NDUk9MTCk7Ci0JR3JpZERhdGEgZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEgKCk7Ci0JZ3JpZERhdGEud2lkdGhIaW50ID0gQ09MVU1OMV9XSURUSDsKLQlncmlkRGF0YS5oZWlnaHRIaW50ID0gMTUwOwotCWdyaWREYXRhLnZlcnRpY2FsU3BhbiA9IDI7Ci0JY2hhclNldENvbWJvLnNldExheW91dERhdGEgKGdyaWREYXRhKTsKLQljaGFyU2V0Q29tYm8uc2V0RGF0YSAoTk9fU0VMRUNUSU9OKTsKLQkKLQlmYWNlTmFtZUNvbWJvID0gbmV3IENvbWJvIChzaGVsbCwgU1dULlNJTVBMRSB8IFNXVC5WX1NDUk9MTCk7Ci0JZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEgKCk7Ci0JZ3JpZERhdGEud2lkdGhIaW50ID0gQ09MVU1OMl9XSURUSDsKLQlncmlkRGF0YS5oZWlnaHRIaW50ID0gMTUwOwkKLQlncmlkRGF0YS52ZXJ0aWNhbFNwYW4gPSAyOwotCWdyaWREYXRhLnZlcnRpY2FsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKLQlmYWNlTmFtZUNvbWJvLnNldExheW91dERhdGEgKGdyaWREYXRhKTsKLQlmYWNlTmFtZUNvbWJvLnNldERhdGEgKE5PX1NFTEVDVElPTik7Ci0JCi0JZXh0U3R5bGVDb21ibyA9IG5ldyBDb21ibyAoc2hlbGwsIFNXVC5TSU1QTEUgfCBTV1QuVl9TQ1JPTEwpOwotCWdyaWREYXRhID0gbmV3IEdyaWREYXRhICgpOwotCWdyaWREYXRhLndpZHRoSGludCA9IENPTFVNTjNfV0lEVEg7Ci0JZ3JpZERhdGEuaGVpZ2h0SGludCA9IDE1MDsJCi0JZ3JpZERhdGEudmVydGljYWxTcGFuID0gMjsKLQlncmlkRGF0YS52ZXJ0aWNhbEFsaWdubWVudCA9IEdyaWREYXRhLkZJTEw7CQotCWV4dFN0eWxlQ29tYm8uc2V0TGF5b3V0RGF0YSAoZ3JpZERhdGEpOwotCWV4dFN0eWxlQ29tYm8uc2V0RGF0YSAoTk9fU0VMRUNUSU9OKTsKLQkKLQkvLyBjcmVhdGUgb2sgYW5kIGNhbmNlbCBidXR0b25zIChyb3cgdHdvIGFuZCB0aHJlZSkKLQljcmVhdGVPa0NhbmNlbCAoKTsKLQkKLQkvLyByb3cgZm91cgotCWNyZWF0ZUVtcHR5Um93ICgpOwotCQotCS8vIHJvdyBmaXZlCi0JTGFiZWwgZm9udFNpemVMYWJlbCA9IG5ldyBMYWJlbCAoc2hlbGwsIFNXVC5OT05FKTsJCi0JZm9udFNpemVMYWJlbC5zZXRUZXh0IChTV1QuZ2V0TWVzc2FnZSAoIlNXVF9TaXplIikgKyAiOiIpOwkKLQlMYWJlbCBmb250U3R5bGVMYWJlbCA9IG5ldyBMYWJlbCAoc2hlbGwsIFNXVC5OT05FKTsKLQlmb250U3R5bGVMYWJlbC5zZXRUZXh0IChTV1QuZ2V0TWVzc2FnZSAoIlNXVF9TdHlsZSIpICsgIjoiKTsKLQkKLQlMYWJlbCBmaWxsTGFiZWwgPSBuZXcgTGFiZWwgKHNoZWxsLCBTV1QuTk9ORSk7Ci0JZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEgKCk7Ci0JZ3JpZERhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwotCWZpbGxMYWJlbC5zZXRMYXlvdXREYXRhIChncmlkRGF0YSk7Ci0KLQkvLyByb3cgc2l4Ci0JZm9udFNpemVDb21ibyA9IG5ldyBDb21ibyAoc2hlbGwsIFNXVC5TSU1QTEUgfCBTV1QuVl9TQ1JPTEwpOwotCWdyaWREYXRhID0gbmV3IEdyaWREYXRhICgpOwotCWdyaWREYXRhLmhvcml6b250YWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwotCWdyaWREYXRhLnZlcnRpY2FsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsJCQotCWdyaWREYXRhLmhlaWdodEhpbnQgPSAxMTA7CQotCWZvbnRTaXplQ29tYm8uc2V0TGF5b3V0RGF0YSAoZ3JpZERhdGEpOwotCWZvbnRTaXplQ29tYm8uc2V0RGF0YSAoTk9fU0VMRUNUSU9OKTsKLQkJCQotCWZvbnRTdHlsZUNvbWJvID0gbmV3IENvbWJvIChzaGVsbCwgU1dULlNJTVBMRSB8IFNXVC5WX1NDUk9MTCk7Ci0JZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEgKCk7Ci0JZ3JpZERhdGEuaG9yaXpvbnRhbEFsaWdubWVudCA9IEdyaWREYXRhLkZJTEw7Ci0JZ3JpZERhdGEudmVydGljYWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwkJCi0JZm9udFN0eWxlQ29tYm8uc2V0TGF5b3V0RGF0YSAoZ3JpZERhdGEpOwotCWZvbnRTdHlsZUNvbWJvLnNldERhdGEgKE5PX1NFTEVDVElPTik7Ci0JCi0JZmlsbExhYmVsID0gbmV3IExhYmVsIChzaGVsbCwgU1dULk5PTkUpOwotCWdyaWREYXRhID0gbmV3IEdyaWREYXRhICgpOwotCWdyaWREYXRhLmhvcml6b250YWxTcGFuID0gMjsKLQlmaWxsTGFiZWwuc2V0TGF5b3V0RGF0YSAoZ3JpZERhdGEpOwotCi0JLy8gcm93IHNldmVuCi0JY3JlYXRlRW1wdHlSb3cgKCk7Ci0JCi0JLy8gcm93IGVpZ2h0Ci0JR3JvdXAgc2FtcGxlR3JvdXAgPSBuZXcgR3JvdXAgKHNoZWxsLCBTV1QuTk9ORSk7Ci0Jc2FtcGxlR3JvdXAuc2V0VGV4dCAoU1dULmdldE1lc3NhZ2UgKCJTV1RfU2FtcGxlIikpOwotCWdyaWREYXRhID0gbmV3IEdyaWREYXRhICgpOwotCWdyaWREYXRhLmhlaWdodEhpbnQgPSA3MDsJCi0JZ3JpZERhdGEuaG9yaXpvbnRhbFNwYW4gPSAzOwotCWdyaWREYXRhLmhvcml6b250YWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwkKLQlzYW1wbGVHcm91cC5zZXRMYXlvdXREYXRhIChncmlkRGF0YSk7Ci0KLQkvLyBzZXR1cCBncm91cCBib3ggd2l0aCBzYW1wbGUgdGV4dCAKLQlsYXlvdXQgPSBuZXcgR3JpZExheW91dCAoKTsKLQlsYXlvdXQubWFyZ2luV2lkdGggPSAxMDsKLQlsYXlvdXQubWFyZ2luSGVpZ2h0ID0gMTA7Ci0Jc2FtcGxlR3JvdXAuc2V0TGF5b3V0IChsYXlvdXQpOwotCQotCXNhbXBsZUxhYmVsID0gbmV3IExhYmVsIChzYW1wbGVHcm91cCwgU1dULkNFTlRFUik7Ci0Jc2FtcGxlTGFiZWwuc2V0VGV4dCAoVEVYVF9TQU1QTEUpOwotCWdyaWREYXRhID0gbmV3IEdyaWREYXRhICgpOwotCWdyaWREYXRhLmdyYWJFeGNlc3NIb3Jpem9udGFsU3BhY2UgPSB0cnVlOwotCWdyaWREYXRhLmdyYWJFeGNlc3NWZXJ0aWNhbFNwYWNlID0gdHJ1ZTsJCi0JZ3JpZERhdGEudmVydGljYWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwkKLQlncmlkRGF0YS5ob3Jpem9udGFsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsJCi0Jc2FtcGxlTGFiZWwuc2V0TGF5b3V0RGF0YSAoZ3JpZERhdGEpOwotCXNoZWxsLnNldFNpemUgKDQ0NSwgNDEwKTsKLX0KLQotLyoqCi0gKiBGaWxsIG9uZSByb3cgaW4gdGhlIGdyaWQgbGF5b3V0IHdpdGggZW1wdHkgd2lkZ2V0cy4KLSAqIFVzZWQgdG8gYWNoaWV2ZSBhIGJpZ2dlciB2ZXJ0aWNhbCBzcGFjaW5nIGJldHdlZW4gc2VwYXJhdGUgCi0gKiBncm91cHMgb2Ygd2lkZ2V0cyAoaWUuIG5ldyByb3dzIG9mIFRleHQvQ29tYm8gY29tYmluYXRpb25zKS4KLSAqLwotdm9pZCBjcmVhdGVFbXB0eVJvdyAoKSB7Ci0JTGFiZWwgZmlsbExhYmVsID0gbmV3IExhYmVsIChzaGVsbCwgU1dULk5PTkUpOwotCUdyaWREYXRhIGdyaWREYXRhID0gbmV3IEdyaWREYXRhICgpOwotCQotCWdyaWREYXRhLmhlaWdodEhpbnQgPSA1OwotCWdyaWREYXRhLmhvcml6b250YWxTcGFuID0gKChHcmlkTGF5b3V0KSBzaGVsbC5nZXRMYXlvdXQgKCkpLm51bUNvbHVtbnM7Ci0JZmlsbExhYmVsLnNldExheW91dERhdGEgKGdyaWREYXRhKTsKLX0KLQotLyoqCi0gKiBDcmVhdGUgdGhlIHdpZGdldHMgb2YgdGhlIGRpYWxvZy4KLSAqLwotdm9pZCBjcmVhdGVPa0NhbmNlbCAoKSB7Ci0Jb2tCdXR0b24gPSBuZXcgQnV0dG9uIChzaGVsbCwgU1dULlBVU0gpOwotCW9rQnV0dG9uLnNldFRleHQgKFNXVC5nZXRNZXNzYWdlICgiU1dUX09LIikpOwotCXNoZWxsLnNldERlZmF1bHRCdXR0b24gKG9rQnV0dG9uKTsJCi0JR3JpZERhdGEgZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEgKCk7Ci0JZ3JpZERhdGEuaG9yaXpvbnRhbEFsaWdubWVudCA9IEdyaWREYXRhLkZJTEw7Ci0JZ3JpZERhdGEud2lkdGhIaW50ID0gNzA7Ci0Jb2tCdXR0b24uc2V0TGF5b3V0RGF0YSAoZ3JpZERhdGEpOwotCi0JY2FuY2VsQnV0dG9uID0gbmV3IEJ1dHRvbiAoc2hlbGwsIFNXVC5QVVNIKTsKLQljYW5jZWxCdXR0b24uc2V0VGV4dCAoU1dULmdldE1lc3NhZ2UgKCJTV1RfQ2FuY2VsIikpOwotCWdyaWREYXRhID0gbmV3IEdyaWREYXRhICgpOwotCWdyaWREYXRhLmhvcml6b250YWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwotCWdyaWREYXRhLnZlcnRpY2FsQWxpZ25tZW50ID0gR3JpZERhdGEuQkVHSU5OSU5HOwkJCi0JY2FuY2VsQnV0dG9uLnNldExheW91dERhdGEgKGdyaWREYXRhKTsKLX0KLQotSGFzaHRhYmxlIGdldEV4dFN0eWxlcyAoU3RyaW5nIGNoYXJzZXROYW1lLCBTdHJpbmcgZmFjZU5hbWUpIHsKLQlIYXNodGFibGUgZmFjZXMgPSBnZXRGYWNlcyAoY2hhcnNldE5hbWUpOwotCWlmIChmYWNlcyA9PSBudWxsKSByZXR1cm4gbnVsbDsKLQlyZXR1cm4gKEhhc2h0YWJsZSkgZmFjZXMuZ2V0IChmYWNlTmFtZSk7Ci19Ci0KLUhhc2h0YWJsZSBnZXRGYWNlcyAoU3RyaW5nIGNoYXJzZXROYW1lKSB7Ci0JcmV0dXJuIChIYXNodGFibGUpIGdldEZvbnRzICgpLmdldCAoY2hhcnNldE5hbWUpOwotfQotCi0vKioKLSAqIFJldHVybnMgYSBGb250RGF0YSBvYmplY3QgZGVzY3JpYmluZyB0aGUgZm9udCB0aGF0IHdhcwotICogc2VsZWN0ZWQgaW4gdGhlIGRpYWxvZywgb3IgbnVsbCBpZiBub25lIGlzIGF2YWlsYWJsZS4KLSAqIAotICogQHJldHVybiB0aGUgRm9udERhdGEgZm9yIHRoZSBzZWxlY3RlZCBmb250LCBvciBudWxsCi0gKi8KIHB1YmxpYyBGb250RGF0YSBnZXRGb250RGF0YSAoKSB7Ci0JaWYgKHNhbXBsZUZvbnQgIT0gbnVsbCkgewotCQlyZXR1cm4gc2FtcGxlRm9udC5nZXRGb250RGF0YSAoKVswXTsKLQl9Ci0JcmV0dXJuIGluaXRpYWxGb250RGF0YTsKKwlyZXR1cm4gZm9udERhdGE7CiB9CiAKLUZvbnREYXRhIGdldEZvbnREYXRhIChTdHJpbmcgY2hhcnNldE5hbWUsIFN0cmluZyBmYWNlTmFtZSwgU3RyaW5nIGV4dFN0eWxlLCBpbnQgc2l6ZSwgU3RyaW5nIHN0eWxlKSB7Ci0JSGFzaHRhYmxlIHN0eWxlcyA9IGdldFN0eWxlcyAoY2hhcnNldE5hbWUsIGZhY2VOYW1lLCBleHRTdHlsZSwgc2l6ZSk7Ci0JaWYgKHN0eWxlcyA9PSBudWxsKSByZXR1cm4gbnVsbDsKLQlyZXR1cm4gKEZvbnREYXRhKSBzdHlsZXMuZ2V0IChzdHlsZSk7Ci19Ci0KLS8qKgotICogUmV0dXJucyB0aGUgY29sbGVjdGlvbiBvZiBmb250cyB0aGF0IGFyZSBkaXNwbGF5ZWQgYnkgdGhlIAotICogcmVjZWl2ZXIuCi0gKiBTZWUgdGhlIGNsYXNzIGRlZmluaXRpb24gZm9yIGFuIGV4cGxhbmF0aW9uIG9mIHRoZSBzdHJ1Y3R1cmUKLSAqIG9mIHRoZSByZXR1cm5lZCBIYXNodGFibGUuCi0gKi8KLUhhc2h0YWJsZSBnZXRGb250cyAoKSB7Ci0JcmV0dXJuIGNoYXJhY3RlclNldHM7Ci19Ci0KLS8qKgotICogUmV0dXJucyB0aGUgY3VycmVudGx5IHNlbGVjdGVkIGNvbG9yIGluIHRoZSByZWNlaXZlci4KLSAqCi0gKiBAcmV0dXJuIHRoZSBSR0IgdmFsdWUgZm9yIHRoZSBzZWxlY3RlZCBjb2xvciwgbWF5IGJlIG51bGwKLSAqCi0gKiBAc2VlIFBhbGV0dGVEYXRhI2dldFJHQnMKLSAqLwogcHVibGljIFJHQiBnZXRSR0IgKCkgewogCXJldHVybiByZ2I7CiB9CiAKLS8qKgotICogUmV0dXJucyBhIEZvbnREYXRhIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIGxvYWQgdGhlIHNlbGVjdGVkIAotICogZm9udC4KLSAqLwotRm9udERhdGEgZ2V0U2VsZWN0aW9uRm9udERhdGEgKCkgewotCVN0cmluZyBjaGFyU2V0TmFtZSA9IGNoYXJTZXRDb21iby5nZXRUZXh0ICgpOwotCVN0cmluZyBmYWNlTmFtZSA9IGZhY2VOYW1lQ29tYm8uZ2V0VGV4dCAoKTsKLQlTdHJpbmcgZXh0U3R5bGUgPSBleHRTdHlsZUNvbWJvLmdldFRleHQgKCk7Ci0JaW50IHNpemUgPSBERUZBVUxUX1NJWkU7Ci0JdHJ5IHsKLQkJc2l6ZSA9IEludGVnZXIudmFsdWVPZiAoZm9udFNpemVDb21iby5nZXRUZXh0ICgpKS5pbnRWYWx1ZSAoKTsKLQl9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgewotCQkvKgotCQkgKiBUaGlzIGJsb2NrIGlzIHB1cnBvc2VseSBsZWZ0IGVtcHR5IHNpbmNlIGEgZGVmYXVsdAotCQkgKiB2YWx1ZSBpcyBhbHJlYWR5IHNwZWNpZmllZCBhYm92ZS4KLQkJICovCi0JfQotCVN0cmluZyBzdHlsZSA9IGZvbnRTdHlsZUNvbWJvLmdldFRleHQgKCk7Ci0JRm9udERhdGEgcmVzdWx0ID0gZ2V0Rm9udERhdGEgKGNoYXJTZXROYW1lLCBmYWNlTmFtZSwgZXh0U3R5bGUsIHNpemUsIHN0eWxlKTsKLQotCWlmIChyZXN1bHQgPT0gbnVsbCkgewotCQkvKgotCQkqIE9uZSBvciBtb3JlIG9mIHRoZSBkaWFsb2cncyB3aWRnZXRzIGNvbnRhaW4gY3VzdG9tIHR5cGVkIHZhbHVlcy4KLQkJKiBDcmVhdGUgYSBGb250RGF0YSB0aGF0IG1pcnJvcnMgdGhlc2UgdmFsdWVzIHNvIHRoYXQgdGhlIEZvbnQgY3JlYXRlZAotCQkqIGJlbG93IHdpbGwgdHJ5IHRvIGZpbmQgdGhlIGJlc3QgbWF0Y2guCi0JCSovCi0JCXJlc3VsdCA9IG5ldyBGb250RGF0YSAoKTsKLQkJcmVzdWx0LmNoYXJhY3RlclNldFJlZ2lzdHJ5ID0gY2hhclNldE5hbWU7Ci0JCXJlc3VsdC5zZXROYW1lKGZhY2VOYW1lKTsKLQkJcmVzdWx0LmFkZFN0eWxlID0gZXh0U3R5bGU7Ci0JCXJlc3VsdC53ZWlnaHQgPSBzdHlsZTsKLQl9Ci0JcmVzdWx0LnNldEhlaWdodCAoc2l6ZSk7Ci0JcmV0dXJuIHJlc3VsdDsKLX0KLQotSGFzaHRhYmxlIGdldFNpemVzIChTdHJpbmcgY2hhcnNldE5hbWUsIFN0cmluZyBmYWNlTmFtZSwgU3RyaW5nIGV4dFN0eWxlKSB7Ci0JSGFzaHRhYmxlIGV4dFN0eWxlcyA9IGdldEV4dFN0eWxlcyAoY2hhcnNldE5hbWUsIGZhY2VOYW1lKTsKLQlpZiAoZXh0U3R5bGVzID09IG51bGwpIHJldHVybiBudWxsOwotCXJldHVybiAoSGFzaHRhYmxlKSBleHRTdHlsZXMuZ2V0IChleHRTdHlsZSk7Ci19Ci0KLUhhc2h0YWJsZSBnZXRTdHlsZXMgKFN0cmluZyBjaGFyc2V0TmFtZSwgU3RyaW5nIGZhY2VOYW1lLCBTdHJpbmcgZXh0U3R5bGUsIGludCBzaXplKSB7Ci0JSGFzaHRhYmxlIHNpemVzID0gZ2V0U2l6ZXMgKGNoYXJzZXROYW1lLCBmYWNlTmFtZSwgZXh0U3R5bGUpOwotCWlmIChzaXplcyA9PSBudWxsKSByZXR1cm4gbnVsbDsKLQlIYXNodGFibGUgcmVzdWx0ID0gKEhhc2h0YWJsZSkgc2l6ZXMuZ2V0IChuZXcgSW50ZWdlciAoc2l6ZSkpOwotCWlmIChyZXN1bHQgPT0gbnVsbCkKLQkJcmVzdWx0ID0gKEhhc2h0YWJsZSkgc2l6ZXMuZ2V0IChTQ0FMQUJMRV9LRVkpOwotCXJldHVybiByZXN1bHQ7Ci19Ci0JCi0vKioKLSAqIFJldHVybnMgdGhlIGNoYXJhY3RlciBzZXQgZm91bmQgaW4gJ2ZvbnREYXRhJyBwcmVmaXhlZAotICogd2l0aCBhIHN0cmluZyBleHBsYWluaW5nIHRoZSBjaGFyYWN0ZXIgc2V0LgotICovCi1TdHJpbmcgZ2V0VHJhbnNsYXRlZENoYXJTZXQgKEZvbnREYXRhIGZvbnREYXRhKSB7Ci0JU3RyaW5nIGNoYXJhY3RlclNldCA9IGZvbnREYXRhLmNoYXJhY3RlclNldFJlZ2lzdHJ5OwotCVN0cmluZyB0cmFuc2xhdGVkQ2hhclNldCA9IG51bGw7Ci0KLQlpZiAoY2hhcmFjdGVyU2V0LnN0YXJ0c1dpdGggKFBSRUZJWF9JU084ODU5KSkgewotCQlpbnQgY2hhclNldE5hbWUgPSAxOwotCQl0cnkgewotCQkJY2hhclNldE5hbWUgPSBJbnRlZ2VyLnZhbHVlT2YgKGZvbnREYXRhLmNoYXJhY3RlclNldE5hbWUpLmludFZhbHVlICgpOwotCQl9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgewotCQkJLyoKLQkJCSAqIFRoaXMgYmxvY2sgaXMgcHVycG9zZWx5IGxlZnQgZW1wdHkgc2luY2UgYSBkZWZhdWx0Ci0JCQkgKiB2YWx1ZSBpcyBhbHJlYWR5IHNwZWNpZmllZCBhYm92ZS4KLQkJCSAqLwotCQl9Ci0KLQkJY2hhcmFjdGVyU2V0ICs9ICItIiArIGNoYXJTZXROYW1lOwotCQl0cmFuc2xhdGVkQ2hhclNldCA9IElTT19DSEFSU0VUUyBbY2hhclNldE5hbWVdOwotCX0KLQllbHNlCQotCWlmIChjaGFyYWN0ZXJTZXQuc3RhcnRzV2l0aCAoUFJFRklYX0lTTzY0NikpIHsKLQkJdHJhbnNsYXRlZENoYXJTZXQgPSBTV1QuZ2V0TWVzc2FnZSgiU1dUX0NoYXJzZXRfQVNDSUkiKTsKLQl9Ci0JZWxzZQkKLQlpZiAoY2hhcmFjdGVyU2V0LnN0YXJ0c1dpdGggKFBSRUZJWF9VTklDT0RFKSkgewotCQl0cmFuc2xhdGVkQ2hhclNldCA9IFNXVC5nZXRNZXNzYWdlKCJTV1RfQ2hhcnNldF9Vbmljb2RlIik7Ci0JfQotCWVsc2UJCi0JaWYgKGNoYXJhY3RlclNldC5zdGFydHNXaXRoIChQUkVGSVhfSkFQQU5FU0UpKSB7Ci0JCXRyYW5zbGF0ZWRDaGFyU2V0ID0gU1dULmdldE1lc3NhZ2UoIlNXVF9DaGFyc2V0X0phcGFuZXNlIik7Ci0JfQotCWVsc2UJCi0JaWYgKGNoYXJhY3RlclNldC5zdGFydHNXaXRoIChQUkVGSVhfU0lNUExJRklFRENISU5FU0UpKSB7Ci0JCXRyYW5zbGF0ZWRDaGFyU2V0ID0gU1dULmdldE1lc3NhZ2UoIlNXVF9DaGFyc2V0X1NpbXBsaWZpZWRDaGluZXNlIik7Ci0JfQotCWVsc2UJCi0JaWYgKGNoYXJhY3RlclNldC5zdGFydHNXaXRoIChQUkVGSVhfVFJBRElUSU9OQUxDSElORVNFKSkgewotCQl0cmFuc2xhdGVkQ2hhclNldCA9IFNXVC5nZXRNZXNzYWdlKCJTV1RfQ2hhcnNldF9UcmFkaXRpb25hbENoaW5lc2UiKTsKLQl9Ci0JZWxzZQkKLQlpZiAoY2hhcmFjdGVyU2V0LnN0YXJ0c1dpdGggKFBSRUZJWF9LT1JFQU4pKSB7Ci0JCXRyYW5zbGF0ZWRDaGFyU2V0ID0gU1dULmdldE1lc3NhZ2UoIlNXVF9DaGFyc2V0X0tvcmVhbiIpOwotCX0KLQlpZiAodHJhbnNsYXRlZENoYXJTZXQgIT0gbnVsbCkgewotCQl0cmFuc2xhdGVkQ2hhclNldCArPSAiICgiICsgY2hhcmFjdGVyU2V0ICsgJyknOwotCX0KLQllbHNlIHsKLQkJdHJhbnNsYXRlZENoYXJTZXQgPSBjaGFyYWN0ZXJTZXQ7Ci0JfQotCXJldHVybiB0cmFuc2xhdGVkQ2hhclNldDsKLX0KLQotLyoqCi0gKiBSZXR1cm5zIHRoZSBmYWNlIG5hbWUgYXMgc3BlY2lmaWVkIGluIEZvbnREYXRhLmZhbWlseU5hbWUgZm9sbG93ZWQgYnkKLSAqIHRoZSBmb3VuZHJ5IHNldCBpbiBwYXJhbnRoZXNlcyBpZiBhdmFpbGFibGUuCi0gKiBXZSBkaXNwbGF5IHRoZSBmYWNlIG5hbWUgZmlyc3Qgc28gdGhhdCB0aGUgbGlzdCBib3ggc29ydHMgdGhlIGZvbnRzIGJ5IAotICogZmFjZSBuYW1lLCBub3QgYnkgZm91bmRyeS4gVXNlcnMgZ2VuZXJhbGx5IHdhbnQgdG8gc2VsZWN0IGZvbnRzIGJhc2VkIAotICogb24gdGhlIGZhY2UgbmFtZSBhbmQgbm90IGJ5IGZvdW5kcnkuIE9uY2UgdGhleSd2ZSBmb3VuZCB0aGUgZGVzaXJlZCAKLSAqIGZhY2UgbmFtZSBpbiB0aGUgbGlzdCB0aGV5IGNhbiBjb21wYXJlIHRoZSBmb250IHZhcmlhdGlvbnMgZnJvbSAKLSAqIGRpZmZlcmVudCBmb3VuZHJpZXMgaWYgYXZhaWxhYmxlLgotICovCi1TdHJpbmcgZ2V0VHJhbnNsYXRlZEZhY2VOYW1lIChGb250RGF0YSBmb250RGF0YSkgewotCVN0cmluZ0J1ZmZlciBmYWNlTmFtZUJ1ZmZlcjsKLQkKLQlpZiAoZm9udERhdGEuZm91bmRyeSAhPSBudWxsICYmIGZvbnREYXRhLmZvdW5kcnkubGVuZ3RoICgpID4gMCkgewotCQlmYWNlTmFtZUJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIgKGZvbnREYXRhLmZvbnRGYW1pbHkpOwotCQlmYWNlTmFtZUJ1ZmZlci5hcHBlbmQgKCIgKCIpOwotCQlmYWNlTmFtZUJ1ZmZlci5hcHBlbmQgKGZvbnREYXRhLmZvdW5kcnkpOwotCQlmYWNlTmFtZUJ1ZmZlci5hcHBlbmQgKCcpJyk7CQkJCi0JfQotCWVsc2UgewotCQlmYWNlTmFtZUJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIgKGZvbnREYXRhLmdldE5hbWUgKCkpOwotCX0KLQlyZXR1cm4gZmFjZU5hbWVCdWZmZXIudG9TdHJpbmcgKCk7Ci19Ci0KLS8qKgotICogSGFuZGxlIHRoZSBldmVudHMgdGhlIHJlY2VpdmVyIGlzIGxpc3RlbmluZyB0by4KLSAqIENvbWJvIHNlbGVjdGlvbnMgY2F1c2UgdGhlIGRvd25zdHJlYW0gY29tYm9zIHRvIGJlIGluaXRpYWxpemVkIAotICogd2l0aCBmb250IGRhdGEgYW5kIHRoZSBzYW1wbGUgdGV4dCB0byBiZSB1cGRhdGVkLgotICovCi12b2lkIGhhbmRsZUV2ZW50IChFdmVudCBldmVudCkgewotCWlmIChpZ25vcmVFdmVudHMpIHJldHVybjsKLQlpZiAoZXZlbnQud2lkZ2V0IGluc3RhbmNlb2YgQ29tYm8pIHsKLQkJQ29tYm8gY29tYm8gPSAoQ29tYm8pIGV2ZW50LndpZGdldDsKLQkJaW50IHByZXZTZWxlY3RJbmRleCA9ICgoSW50ZWdlcikgY29tYm8uZ2V0RGF0YSAoKSkuaW50VmFsdWUgKCk7Ci0JCVN0cmluZyB0ZXh0ID0gY29tYm8uZ2V0VGV4dCAoKTsKLQkJaW50IG5ld1NlbGVjdEluZGV4ID0gY29tYm8uaW5kZXhPZiAodGV4dCk7Ci0JCWlmIChwcmV2U2VsZWN0SW5kZXggIT0gbmV3U2VsZWN0SW5kZXggfHwgbmV3U2VsZWN0SW5kZXggPT0gLTEpIHsKLQkJCWlnbm9yZUV2ZW50cyA9IHRydWU7Ci0JCQljb21iby5zZXREYXRhIChuZXcgSW50ZWdlciAobmV3U2VsZWN0SW5kZXgpKTsKLQkJCWlmIChjb21ibyA9PSBjaGFyU2V0Q29tYm8pIGluaXRGYWNlTmFtZUNvbWJvICgpOwotCQkJZWxzZSBpZiAoY29tYm8gPT0gZmFjZU5hbWVDb21ibykgaW5pdEV4dFN0eWxlQ29tYm8gKCk7Ci0JCQllbHNlIGlmIChjb21ibyA9PSBleHRTdHlsZUNvbWJvKSBpbml0U2l6ZUNvbWJvICgpOwotCQkJZWxzZSBpZiAoY29tYm8gPT0gZm9udFNpemVDb21ibykgaW5pdFN0eWxlQ29tYm8gKCk7Ci0JCQl1cGRhdGVTYW1wbGVGb250ICgpOwotCQkJaWYgKG5ld1NlbGVjdEluZGV4ICE9IC0xKSB7Ci0JCQkJLy8gaW4gY2FzZSBpdCBjYW1lIGJ5IHR5cGluZyB0aGUgbmFtZQotCQkJCWNvbWJvLnNlbGVjdCAobmV3U2VsZWN0SW5kZXgpOworaW50IGZvbnRQcm9jIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IGtpbmQgPSBPUy5HZXRFdmVudEtpbmQgKHRoZUV2ZW50KTsKKwlzd2l0Y2ggKGtpbmQpIHsKKwkJY2FzZSBPUy5rRXZlbnRGb250UGFuZWxDbG9zZWQ6CisJCQlvcGVuID0gZmFsc2U7CisJCQlicmVhazsKKwkJY2FzZSBPUy5rRXZlbnRGb250U2VsZWN0aW9uOgorCQkJaWYgKGZvbnREYXRhID09IG51bGwpIGZvbnREYXRhID0gbmV3IEZvbnREYXRhKCk7CisJCQlzaG9ydCBbXSBmb250RmFtaWx5ID0gbmV3IHNob3J0IFsxXTsKKwkJCWlmIChPUy5HZXRFdmVudFBhcmFtZXRlciAodGhlRXZlbnQsIE9TLmtFdmVudFBhcmFtRk1Gb250RmFtaWx5LCBPUy50eXBlU0ludDE2LCBudWxsLCAyLCBudWxsLCBmb250RmFtaWx5KSA9PSBPUy5ub0VycikgeworCQkJCWJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVsyNTZdOworCQkJCU9TLkZNR2V0Rm9udEZhbWlseU5hbWUoZm9udEZhbWlseSBbMF0sIGJ1ZmZlcik7CisJCQkJaW50IGxlbmd0aCA9IGJ1ZmZlclswXSAmIDB4RkY7CisJCQkJY2hhcltdIGNoYXJzID0gbmV3IGNoYXJbbGVuZ3RoXTsKKwkJCQlmb3IgKGludCBpPTA7IGk8bGVuZ3RoOyBpKyspIHsKKwkJCQkJY2hhcnNbaV09IChjaGFyKWJ1ZmZlcltpKzFdOworCQkJCX0KKwkJCQlmb250RGF0YS5zZXROYW1lIChuZXcgU3RyaW5nKGNoYXJzKSk7CiAJCQl9Ci0JCQlpZ25vcmVFdmVudHMgPSBmYWxzZTsKLQkJfQotCX0JCQotCWVsc2UKLQlpZiAoZXZlbnQud2lkZ2V0ID09IG9rQnV0dG9uKSB7Ci0JCW9rU2VsZWN0ZWQgPSB0cnVlOwotCQlzaGVsbC5jbG9zZSAoKTsKLQl9Ci0JZWxzZQotCWlmIChldmVudC53aWRnZXQgPT0gY2FuY2VsQnV0dG9uKSB7Ci0JCW9rU2VsZWN0ZWQgPSBmYWxzZTsKLQkJc2hlbGwuY2xvc2UgKCk7Ci0JfQkKLX0KLQotLyoqCi0gKiBJbml0aWFsaXplIHRoZSBleHRlbmRlZCBzdHlsZXMgY29tYm8gd2l0aCB0aGUgZXh0ZW5kZWQgc3R5bGVzCi0gKiBhdmFpbGFibGUgZm9yIHRoZSBzZWxlY3RlZCBmb250LgotICogRG93bnN0cmVhbSBjb21ib3MgYXJlIGluaXRpYWxpemVkIGFzIHdlbGwgKHN0eWxlIGFuZCBzaXplKS4KLSAqLwotdm9pZCBpbml0RXh0U3R5bGVDb21ibyAoKSB7Ci0JU3RyaW5nIG9sZFNlbGVjdCA9IGV4dFN0eWxlQ29tYm8uZ2V0VGV4dCAoKTsKLQlleHRTdHlsZUNvbWJvLnJlbW92ZUFsbCAoKTsKLQkKLQlTdHJpbmcgY2hhcmFjdGVyU2V0ID0gY2hhclNldENvbWJvLmdldFRleHQgKCk7Ci0JU3RyaW5nIGZhY2VOYW1lID0gZmFjZU5hbWVDb21iby5nZXRUZXh0ICgpOwotCUhhc2h0YWJsZSBleHRTdHlsZXMgPSBnZXRFeHRTdHlsZXMgKGNoYXJhY3RlclNldCwgZmFjZU5hbWUpOwotCWlmIChleHRTdHlsZXMgPT0gbnVsbCkgcmV0dXJuOwotCXNldEl0ZW1zU29ydGVkIChleHRTdHlsZUNvbWJvLCBleHRTdHlsZXMpOwotCQotCWludCBzZWxlY3RJbmRleCA9IGV4dFN0eWxlQ29tYm8uaW5kZXhPZiAob2xkU2VsZWN0KTsKLQlzZWxlY3RJbmRleCA9IE1hdGgubWF4ICgwLCBzZWxlY3RJbmRleCk7Ci0JZXh0U3R5bGVDb21iby5zZWxlY3QgKHNlbGVjdEluZGV4KTsKLQlleHRTdHlsZUNvbWJvLnNldERhdGEgKG5ldyBJbnRlZ2VyIChzZWxlY3RJbmRleCkpOwotCWluaXRTaXplQ29tYm8gKCk7Ci19Ci0KLS8qKgotICogSW5pdGlhbGl6ZSB0aGUgZmFjZSBuYW1lIGNvbWJvIGJveCB3aXRoIGFsbCBmb250IG5hbWVzIAotICogYXZhaWxhYmxlIGluIHRoZSBzZWxlY3RlZCBjaGFyYWN0ZXIgc2V0LgotICogRG93bnN0cmVhbSBjb21ib3MgYXJlIGluaXRpYWxpemVkIGFzIHdlbGwgKGV4dGVuZGVkIHN0eWxlKS4KLSAqLwotdm9pZCBpbml0RmFjZU5hbWVDb21ibyAoKSB7Ci0JU3RyaW5nIG9sZFNlbGVjdCA9IGZhY2VOYW1lQ29tYm8uZ2V0VGV4dCAoKTsKLQlmYWNlTmFtZUNvbWJvLnJlbW92ZUFsbCAoKTsKLQkKLQlIYXNodGFibGUgZmFjZU5hbWVzID0gZ2V0RmFjZXMgKGNoYXJTZXRDb21iby5nZXRUZXh0ICgpKTsKLQlzZXRJdGVtc1NvcnRlZCAoZmFjZU5hbWVDb21ibywgZmFjZU5hbWVzKTsKLQkKLQlpbnQgc2VsZWN0SW5kZXggPSBmYWNlTmFtZUNvbWJvLmluZGV4T2YgKG9sZFNlbGVjdCk7Ci0Jc2VsZWN0SW5kZXggPSBNYXRoLm1heCAoMCwgc2VsZWN0SW5kZXgpOwotCWZhY2VOYW1lQ29tYm8uc2VsZWN0IChzZWxlY3RJbmRleCk7Ci0JZmFjZU5hbWVDb21iby5zZXREYXRhIChuZXcgSW50ZWdlciAoc2VsZWN0SW5kZXgpKTsKLQlpbml0RXh0U3R5bGVDb21ibyAoKTsKLX0KLQotLyoqCi0gKiBJbml0aWFsaXplIHRoZSB3aWRnZXRzIG9mIHRoZSByZWNlaXZlciB3aXRoIHRoZSBkYXRhIG9mIAotICogYWxsIGluc3RhbGxlZCBmb250cy4KLSAqIElmIHRoZSB1c2VyIHNwZWNpZmllZCBhIGRlZmF1bHQgZm9udCBwcmVzZWxlY3QgdGhhdCBmb250IGluIAotICogdGhlIGNvbWJvIGJveGVzLgotICovCi12b2lkIGluaXRpYWxpemVXaWRnZXRzICgpIHsKLQlEaXNwbGF5IGRpc3BsYXkgPSBzaGVsbC5nZXREaXNwbGF5ICgpOwotCWFkZEZvbnRzIChkaXNwbGF5LmdldEZvbnRMaXN0IChudWxsLCBmYWxzZSkpOwkJLy8gZ2V0IGFsbCBmb250cyBhdmFpbGFiZSBvbiB0aGUgY3VycmVudCBkaXNwbGF5Ci0JYWRkRm9udHMgKGRpc3BsYXkuZ2V0Rm9udExpc3QgKG51bGwsIHRydWUpKTsKLQlzZXRJdGVtc1NvcnRlZCAoY2hhclNldENvbWJvLCBnZXRGb250cyAoKSk7Ci0JaWYgKGluaXRpYWxGb250RGF0YSAhPSBudWxsKSB7Ci0JCUZvbnQgaW5pdGlhbEZvbnQgPSBuZXcgRm9udCAoZGlzcGxheSwgaW5pdGlhbEZvbnREYXRhKTsJLy8gdmVyaWZ5IHRoYXQgdGhlIGluaXRpYWwgZm9udCBkYXRhIGlzIGEgdmFsaWQgZm9udAotCQlpbml0aWFsRm9udERhdGEgPSBudWxsOwotCQlpZ25vcmVFdmVudHMgPSB0cnVlOwotCQlzZXRGb250Q29tYm9zIChpbml0aWFsRm9udC5nZXRGb250RGF0YSAoKVswXSk7Ci0JCWlnbm9yZUV2ZW50cyA9IGZhbHNlOwotCQlpbml0aWFsRm9udC5kaXNwb3NlICgpOwotCQl1cGRhdGVTYW1wbGVGb250ICgpOwotCX0KLX0KLQotLyoqCi0gKiBJbml0aWFsaXplIHRoZSBzaXplIGNvbWJvIHdpdGggdGhlIHNpemVzIHRoZSBzZWxlY3RlZCBmb250IAotICogaXMgYXZhaWxhYmxlIGluLgotICogSWYgdGhlIHNlbGVjdGVkIGZvbnQgaXMgc2NhbGFibGUgYSBzZWxlY3Rpb24gb2YgcHJlc2V0IHNpemVzIAotICogaXMgdXNlZC4KLSAqLwotdm9pZCBpbml0U2l6ZUNvbWJvICgpIHsKLQlTdHJpbmcgb2xkU2VsZWN0ID0gZm9udFNpemVDb21iby5nZXRUZXh0ICgpOwotCWZvbnRTaXplQ29tYm8ucmVtb3ZlQWxsICgpOwotCQotCVN0cmluZyBjaGFyYWN0ZXJTZXQgPSBjaGFyU2V0Q29tYm8uZ2V0VGV4dCAoKTsKLQlTdHJpbmcgZmFjZU5hbWUgPSBmYWNlTmFtZUNvbWJvLmdldFRleHQgKCk7Ci0JU3RyaW5nIGV4dFN0eWxlID0gZXh0U3R5bGVDb21iby5nZXRUZXh0ICgpOwotCUhhc2h0YWJsZSBzaXplcyA9IGdldFNpemVzIChjaGFyYWN0ZXJTZXQsIGZhY2VOYW1lLCBleHRTdHlsZSk7Ci0JaWYgKHNpemVzID09IG51bGwpIHJldHVybjsKLQlpZiAoc2l6ZXMuZ2V0IChTQ0FMQUJMRV9LRVkpID09IG51bGwpIHsKLQkJLyoKLQkJICogRm9udCBpcyBub3Qgc2NhbGFibGUgc28ganVzdCBwcmVzZW50IHRoZSBwcm92aWRlZCBzaXplcy4KLQkJICovCi0JCXNldFNpemVJdGVtc1NvcnRlZCAoc2l6ZXMua2V5cyAoKSk7Ci0JfSBlbHNlIHsKLQkJLyoKLQkJICogRm9udCBpcyBzY2FsYWJsZSBzbyBwcmVzZW50IHRoZSBwcm92aWRlZCBzaXplcyBhbmQgc2NhbGFibGUKLQkJICogc2l6ZXMgZm9yIHNlbGVjdGlvbi4KLQkJICovCi0JCVZlY3RvciBhbGxTaXplcyA9IG5ldyBWZWN0b3IgKCk7Ci0JCS8qCi0JCSAqIEFkZCB0aGUgc2NhbGFibGUgc2l6ZXMuCi0JCSAqLwotCQlmb3IgKGludCBpID0gMDsgaSA8IFNDQUxBQkxFX1NJWkVTLmxlbmd0aDsgaSsrKSB7Ci0JCQlhbGxTaXplcy5hZGRFbGVtZW50IChuZXcgSW50ZWdlciAoU0NBTEFCTEVfU0laRVMgW2ldKSk7Ci0JCX0KLQkJLyoKLQkJICogQWRkIHRoZSBwcm92aWRlZCBzaXplcy4KLQkJICovCi0JCUVudW1lcmF0aW9uIHByb3ZpZGVkU2l6ZXMgPSBzaXplcy5rZXlzICgpOwotCQl3aGlsZSAocHJvdmlkZWRTaXplcy5oYXNNb3JlRWxlbWVudHMgKCkpIHsKLQkJCUludGVnZXIgc2l6ZSA9IChJbnRlZ2VyKSBwcm92aWRlZFNpemVzLm5leHRFbGVtZW50ICgpOwotCQkJaWYgKCFzaXplLmVxdWFscyAoU0NBTEFCTEVfS0VZKSAmJiAhYWxsU2l6ZXMuY29udGFpbnMgKHNpemUpKSB7Ci0JCQkJYWxsU2l6ZXMuYWRkRWxlbWVudCAoc2l6ZSk7CisJCQlzaG9ydCBbXSBmb250U3R5bGUgPSBuZXcgc2hvcnQgWzFdOworCQkJaWYgKE9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1GTUZvbnRTdHlsZSwgT1MudHlwZVNJbnQxNiwgbnVsbCwgMiwgbnVsbCwgZm9udFN0eWxlKSA9PSBPUy5ub0VycikgeworCQkJCWludCBzdHlsZSA9IFNXVC5OT1JNQUw7CisJCQkJaWYgKChmb250U3R5bGUgWzBdICYgT1MuYm9sZCkgIT0gMCkgc3R5bGUgfD0gU1dULkJPTEQ7CisJCQkJaWYgKChmb250U3R5bGUgWzBdICYgT1MuaXRhbGljKSAhPSAwKSBzdHlsZSB8PSBTV1QuSVRBTElDOworCQkJCWZvbnREYXRhLnNldFN0eWxlIChzdHlsZSk7CiAJCQl9Ci0JCX0KLQkJc2V0U2l6ZUl0ZW1zU29ydGVkIChhbGxTaXplcy5lbGVtZW50cyAoKSk7CisJCQlzaG9ydCBbXSBmb250U2l6ZSA9IG5ldyBzaG9ydCBbMV07CisJCQlpZiAoT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbUZNRm9udFNpemUsIE9TLnR5cGVTSW50MTYsIG51bGwsIDIsIG51bGwsIGZvbnRTaXplKSA9PSBPUy5ub0VycikgeworCQkJCWZvbnREYXRhLnNldEhlaWdodCAoZm9udFNpemUgWzBdKTsKKwkJCX0KKwkJCS8vIE5FRURTIFdPUksgLSBjb2xvciBub3Qgc3VwcG9ydGVkIGluIG5hdGl2ZSBkaWFsb2cgZm9yIENhcmJvbgorCQkJUkdCQ29sb3IgY29sb3IgPSBuZXcgUkdCQ29sb3IgKCk7CisJCQlpbnQgW10gYWN0dWFsU2l6ZSA9IG5ldyBpbnQgWzFdOworCQkJaWYgKE9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1Gb250Q29sb3IsIE9TLnR5cGVSR0JDb2xvciwgbnVsbCwgUkdCQ29sb3Iuc2l6ZW9mLCBhY3R1YWxTaXplLCBjb2xvcikgPT0gT1Mubm9FcnIpIHsKKwkJCQlpbnQgcmVkID0gKGNvbG9yLnJlZCA+PiA4KSAmIDB4RkY7CisJCQkJaW50IGdyZWVuID0gKGNvbG9yLmdyZWVuID4+IDgpICYgMHhGRjsKKwkJCQlpbnQgYmx1ZSA9CShjb2xvci5ibHVlID4+IDgpICYgMHhGRjsKKwkJCQlyZ2IgPSBuZXcgUkdCKHJlZCwgZ3JlZW4sIGJsdWUpOworCQkJfQorCQkJYnJlYWs7CiAJfQotCQotCWludCBzZWxlY3RJbmRleCA9IGZvbnRTaXplQ29tYm8uaW5kZXhPZiAob2xkU2VsZWN0KTsKLQlpZiAoc2VsZWN0SW5kZXggPT0gLTEpIHsKLQkJc2VsZWN0SW5kZXggPSBmb250U2l6ZUNvbWJvLmluZGV4T2YgKFN0cmluZy52YWx1ZU9mIChERUZBVUxUX1NJWkUpKTsKLQl9Ci0Jc2VsZWN0SW5kZXggPSBNYXRoLm1heCAoMCwgc2VsZWN0SW5kZXgpOwotCWZvbnRTaXplQ29tYm8uc2VsZWN0IChzZWxlY3RJbmRleCk7Ci0JZm9udFNpemVDb21iby5zZXREYXRhIChuZXcgSW50ZWdlciAoc2VsZWN0SW5kZXgpKTsKLQlpbml0U3R5bGVDb21ibyAoKTsKKwlyZXR1cm4gT1Mubm9FcnI7CiB9Ci0KLS8qKgotICogSW5pdGlhbGl6ZSB0aGUgc3R5bGVzIGNvbWJvIHdpdGggdGhlIHN0eWxlcyB0aGUgc2VsZWN0ZWQgZm9udCAKLSAqIGlzIGF2YWlsYWJsZSBpbi4KLSAqLwotdm9pZCBpbml0U3R5bGVDb21ibyAoKSB7Ci0JU3RyaW5nIG9sZFNlbGVjdCA9IGZvbnRTdHlsZUNvbWJvLmdldFRleHQgKCk7Ci0JZm9udFN0eWxlQ29tYm8ucmVtb3ZlQWxsICgpOwogCQotCVN0cmluZyBjaGFyYWN0ZXJTZXQgPSBjaGFyU2V0Q29tYm8uZ2V0VGV4dCAoKTsKLQlTdHJpbmcgZmFjZU5hbWUgPSBmYWNlTmFtZUNvbWJvLmdldFRleHQgKCk7Ci0JU3RyaW5nIGV4dFN0eWxlID0gZXh0U3R5bGVDb21iby5nZXRUZXh0ICgpOwotCWludCBzaXplID0gREVGQVVMVF9TSVpFOwotCXRyeSB7Ci0JCXNpemUgPSBJbnRlZ2VyLnZhbHVlT2YgKGZvbnRTaXplQ29tYm8uZ2V0VGV4dCAoKSkuaW50VmFsdWUgKCk7Ci0JfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKLQkJLyoKLQkJICogVGhpcyBibG9jayBpcyBwdXJwb3NlbHkgbGVmdCBlbXB0eSBzaW5jZSBhIGRlZmF1bHQKLQkJICogdmFsdWUgaXMgYWxyZWFkeSBzcGVjaWZpZWQgYWJvdmUuCi0JCSAqLwotCX0KLQlIYXNodGFibGUgc3R5bGVzID0gZ2V0U3R5bGVzIChjaGFyYWN0ZXJTZXQsIGZhY2VOYW1lLCBleHRTdHlsZSwgc2l6ZSk7Ci0JaWYgKHN0eWxlcyA9PSBudWxsKSByZXR1cm47Ci0Jc2V0SXRlbXNTb3J0ZWQgKGZvbnRTdHlsZUNvbWJvLCBzdHlsZXMpOwotCQotCWludCBzZWxlY3RJbmRleCA9IGZvbnRTdHlsZUNvbWJvLmluZGV4T2YgKG9sZFNlbGVjdCk7Ci0JaWYgKHNlbGVjdEluZGV4ID09IC0xKSB7Ci0JCXNlbGVjdEluZGV4ID0gZm9udFN0eWxlQ29tYm8uaW5kZXhPZiAoU3RyaW5nLnZhbHVlT2YgKERFRkFVTFRfU1RZTEUpKTsKLQl9Ci0Jc2VsZWN0SW5kZXggPSBNYXRoLm1heCAoMCwgc2VsZWN0SW5kZXgpOwotCWZvbnRTdHlsZUNvbWJvLnNlbGVjdCAoc2VsZWN0SW5kZXgpOwotCWZvbnRTdHlsZUNvbWJvLnNldERhdGEgKG5ldyBJbnRlZ2VyIChzZWxlY3RJbmRleCkpOwotCWZvbnRTdHlsZUNvbWJvLnNlbGVjdCAoTWF0aC5tYXggKDAsIHNlbGVjdEluZGV4KSk7Ci19Ci0KLS8qKgotICogUmVnaXN0ZXIgdGhlIHJlY2VpdmVyIHRvIHJlY2VpdmUgZXZlbnRzLgotICovCi12b2lkIGluc3RhbGxMaXN0ZW5lcnMgKCkgewotCUxpc3RlbmVyIGxpc3RlbmVyID0gbmV3IExpc3RlbmVyICgpIHsKLQkJcHVibGljIHZvaWQgaGFuZGxlRXZlbnQgKEV2ZW50IGV2ZW50KSB7Ci0JCQlGb250RGlhbG9nLnRoaXMuaGFuZGxlRXZlbnQgKGV2ZW50KTsKLQkJfQotCX07Ci0Jb2tCdXR0b24uYWRkTGlzdGVuZXIgKFNXVC5TZWxlY3Rpb24sIGxpc3RlbmVyKTsKLQljYW5jZWxCdXR0b24uYWRkTGlzdGVuZXIgKFNXVC5TZWxlY3Rpb24sIGxpc3RlbmVyKTsKLQljaGFyU2V0Q29tYm8uYWRkTGlzdGVuZXIgKFNXVC5TZWxlY3Rpb24sIGxpc3RlbmVyKTsKLQljaGFyU2V0Q29tYm8uYWRkTGlzdGVuZXIgKFNXVC5Nb2RpZnksIGxpc3RlbmVyKTsKLQlmYWNlTmFtZUNvbWJvLmFkZExpc3RlbmVyIChTV1QuTW9kaWZ5LCBsaXN0ZW5lcik7Ci0JZm9udFN0eWxlQ29tYm8uYWRkTGlzdGVuZXIgKFNXVC5Nb2RpZnksIGxpc3RlbmVyKTsKLQlleHRTdHlsZUNvbWJvLmFkZExpc3RlbmVyIChTV1QuTW9kaWZ5LCBsaXN0ZW5lcik7Ci0JZm9udFNpemVDb21iby5hZGRMaXN0ZW5lciAoU1dULk1vZGlmeSwgbGlzdGVuZXIpOwotfQotCi0vKioKLSAqIE1ha2VzIHRoZSBkaWFsb2cgdmlzaWJsZSBhbmQgYnJpbmdzIGl0IHRvIHRoZSBmcm9udAotICogb2YgdGhlIGRpc3BsYXkuCi0gKgotICogQHJldHVybiBhIEZvbnREYXRhIG9iamVjdCBkZXNjcmliaW5nIHRoZSBmb250IHRoYXQgd2FzIHNlbGVjdGVkLAotICogICAgICAgICBvciBudWxsIGlmIHRoZSBkaWFsb2cgd2FzIGNhbmNlbGxlZCBvciBhbiBlcnJvciBvY2N1cnJlZAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgZGlhbG9nIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIGRpYWxvZzwvbGk+Ci0gKiA8L3VsPgotICovCiBwdWJsaWMgRm9udERhdGEgb3BlbiAoKSB7Ci0Jc2hlbGwgPSBuZXcgU2hlbGwgKGdldFBhcmVudCAoKSwgZ2V0U3R5bGUgKCkgfCBTV1QuVElUTEUgfCBTV1QuQk9SREVSIHwgU1dULkFQUExJQ0FUSU9OX01PREFMKTsKLQljcmVhdGVDaGlsZHJlbiAoKTsKLQlpbnN0YWxsTGlzdGVuZXJzICgpOwkKLQkKLQlpbml0aWFsaXplV2lkZ2V0cyAoKTsKLQlzZXRGb250RGF0YSAobnVsbCk7Ci0Jb3BlbkRpYWxvZyAoKTsKLQlEaXNwbGF5IGRpc3BsYXkgPSBzaGVsbC5nZXREaXNwbGF5ICgpOwotCXdoaWxlICghc2hlbGwuaXNEaXNwb3NlZCAoKSkgeworCUZvbnRTZWxlY3Rpb25RRFN0eWxlIHFkU3R5bGUgPSBuZXcgRm9udFNlbGVjdGlvblFEU3R5bGUoKTsKKwlxZFN0eWxlLnZlcnNpb24gPSBPUy5rRm9udFNlbGVjdGlvblFEU3R5bGVWZXJzaW9uWmVybzsKKwkvLyBORUVEUyBXT1JLIC0gY29sb3Igbm90IHN1cHBvcnRlZCBpbiBuYXRpdmUgZGlhbG9nIGZvciBDYXJib24KKwlpZiAocmdiICE9IG51bGwpIHsKKwkJcWRTdHlsZS5oYXNDb2xvciA9IHRydWU7CisJCXFkU3R5bGUuY29sb3JfcmVkID0gKHNob3J0KShyZ2IucmVkICogMjU3KTsKKwkJcWRTdHlsZS5jb2xvcl9ncmVlbiA9IChzaG9ydCkocmdiLmdyZWVuICogMjU3KTsKKwkJcWRTdHlsZS5jb2xvcl9ibHVlID0gKHNob3J0KShyZ2IuYmx1ZSAqIDI1Nyk7CisJfQorCWlmIChmb250RGF0YSAhPSBudWxsKSB7CisJCVN0cmluZyBmYW1pbHlOYW1lID0gZm9udERhdGEubmFtZTsKKwkJYnl0ZSBbXSBidWZmZXIgPSBuZXcgYnl0ZSBbMjU2XTsKKwkJaW50IGxlbmd0aCA9IGZhbWlseU5hbWUubGVuZ3RoKCk7CisJCWlmIChsZW5ndGggPiAyNTUpIGxlbmd0aCA9IDI1NTsKKwkJYnVmZmVyIFswXSA9IChieXRlKWxlbmd0aDsKKwkJZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSB7CisJCQlidWZmZXIgW2krMV0gPSAoYnl0ZSkgZmFtaWx5TmFtZS5jaGFyQXQoaSk7CisJCX0KKwkJaW50IGlkID0gT1MuRk1HZXRGb250RmFtaWx5RnJvbU5hbWUgKGJ1ZmZlcik7CisJCWlmIChpZCA9PSBPUy5rSW52YWxpZEZvbnRGYW1pbHkpIGlkID0gT1MuR2V0QXBwRm9udCgpOworCQlxZFN0eWxlLmluc3RhbmNlX2ZvbnRGYW1pbHkgPSAoc2hvcnQpaWQ7CisJCWludCBzdHlsZSA9IGZvbnREYXRhLnN0eWxlOworCQlpbnQgZm9udFN0eWxlID0gT1Mubm9ybWFsOworCQlpZiAoKHN0eWxlICYgU1dULkJPTEQpICE9IDApIGZvbnRTdHlsZSB8PSBPUy5ib2xkOworCQlpZiAoKHN0eWxlICYgU1dULklUQUxJQykgIT0gMCkgZm9udFN0eWxlIHw9IE9TLml0YWxpYzsKKwkJcWRTdHlsZS5pbnN0YW5jZV9mb250U3R5bGUgPSAoc2hvcnQpZm9udFN0eWxlOworCQlxZFN0eWxlLnNpemUgPSAoc2hvcnQpZm9udERhdGEuaGVpZ2h0OworCX0KKwlpbnQgcHRyID0gT1MuTmV3UHRyKEZvbnRTZWxlY3Rpb25RRFN0eWxlLnNpemVvZik7CisJT1MubWVtY3B5IChwdHIsIHFkU3R5bGUsIEZvbnRTZWxlY3Rpb25RRFN0eWxlLnNpemVvZik7CisJT1MuU2V0Rm9udEluZm9Gb3JTZWxlY3Rpb24oT1Mua0ZvbnRTZWxlY3Rpb25RRFR5cGUsIDEsIHB0ciwgMCk7CisJT1MuRGlzcG9zZVB0ciAocHRyKTsKKwlpbnRbXSBtYXNrID0gbmV3IGludFtdIHsKKwkJT1Mua0V2ZW50Q2xhc3NGb250LCBPUy5rRXZlbnRGb250U2VsZWN0aW9uLAorCQlPUy5rRXZlbnRDbGFzc0ZvbnQsIE9TLmtFdmVudEZvbnRQYW5lbENsb3NlZCwKKwl9OworCUNhbGxiYWNrIGZvbnRQYW5lbENhbGxiYWNrID0gbmV3IENhbGxiYWNrICh0aGlzLCAiZm9udFByb2MiLCAzKTsKKwlpbnQgYXBwVGFyZ2V0ID0gT1MuR2V0QXBwbGljYXRpb25FdmVudFRhcmdldCAoKTsKKwlpbnQgW10gb3V0UmVmID0gbmV3IGludCBbMV07CisJT1MuSW5zdGFsbEV2ZW50SGFuZGxlciAoYXBwVGFyZ2V0LCBmb250UGFuZWxDYWxsYmFjay5nZXRBZGRyZXNzKCksIG1hc2subGVuZ3RoIC8gMiwgbWFzaywgMCwgb3V0UmVmKTsKKwlmb250RGF0YSA9IG51bGw7CisJcmdiID0gbnVsbDsKKwlvcGVuID0gdHJ1ZTsKKwlPUy5GUFNob3dIaWRlRm9udFBhbmVsICgpOwkKKwlEaXNwbGF5IGRpc3BsYXkgPSBwYXJlbnQuZ2V0RGlzcGxheSAoKTsKKwl3aGlsZSAoIXBhcmVudC5pc0Rpc3Bvc2VkKCkgJiYgb3BlbikgewogCQlpZiAoIWRpc3BsYXkucmVhZEFuZERpc3BhdGNoICgpKSBkaXNwbGF5LnNsZWVwICgpOwotCX0KLQkKLQlGb250RGF0YSByZXN1bHQgPSBudWxsOwotCWlmIChva1NlbGVjdGVkKSByZXN1bHQgPSBnZXRGb250RGF0YSAoKTsKLQlpZiAoc2FtcGxlRm9udCAhPSBudWxsKSBzYW1wbGVGb250LmRpc3Bvc2UgKCk7Ci0JcmV0dXJuIHJlc3VsdDsKKwl9OworCU9TLlJlbW92ZUV2ZW50SGFuZGxlciAob3V0UmVmIFswXSk7CisJZm9udFBhbmVsQ2FsbGJhY2suZGlzcG9zZSAoKTsKKwlyZXR1cm4gZm9udERhdGE7CiB9CiAKLS8qKgotICogT3BlbiB0aGUgcmVjZWl2ZXIgYW5kIHNldCBpdHMgc2l6ZSB0byB0aGUgc2l6ZSBjYWxjdWxhdGVkIGJ5IAotICogdGhlIGxheW91dCBtYW5hZ2VyLgotICovCi12b2lkIG9wZW5EaWFsb2cgKCkgewotCS8vIFN0YXJ0IGV2ZXJ5dGhpbmcgb2ZmIGJ5IHNldHRpbmcgdGhlIHNoZWxsIHNpemUgdG8gaXRzIGNvbXB1dGVkIHNpemUuCi0JUG9pbnQgcHQgPSBzaGVsbC5jb21wdXRlU2l6ZShTV1QuREVGQVVMVCwgU1dULkRFRkFVTFQsIGZhbHNlKTsKLQkKLQkvLyBFbnN1cmUgdGhhdCB0aGUgd2lkdGggb2YgdGhlIHNoZWxsIGZpdHMgdGhlIGRpc3BsYXkuCi0JUmVjdGFuZ2xlIGRpc3BsYXlSZWN0ID0gc2hlbGwuZ2V0RGlzcGxheSgpLmdldEJvdW5kcygpOwotCWludCB3aWR0aExpbWl0ID0gZGlzcGxheVJlY3Qud2lkdGggKiA3IC8gODsKLQlpbnQgaGVpZ2h0TGltaXQgPSBkaXNwbGF5UmVjdC5oZWlnaHQgKiA3IC8gODsKLQlpZiAocHQueCA+IHdpZHRoTGltaXQpIHsKLQkJcHQgPSBzaGVsbC5jb21wdXRlU2l6ZSAod2lkdGhMaW1pdCwgU1dULkRFRkFVTFQsIGZhbHNlKTsKLQl9Ci0JCi0JLy8gY2VudHJlIHRoZSBkaWFsb2cgb24gaXRzIHBhcmVudCwgYW5kIGVuc3VyZSB0aGF0IHRoZQotCS8vIHdob2xlIGRpYWxvZyBhcHBlYXJzIHdpdGhpbiB0aGUgc2NyZWVuIGJvdW5kcwotCVJlY3RhbmdsZSBwYXJlbnRCb3VuZHMgPSBnZXRQYXJlbnQgKCkuZ2V0Qm91bmRzICgpOwotCWludCBvcmlnaW5YID0gKHBhcmVudEJvdW5kcy53aWR0aCAtIHB0LngpIC8gMiArIHBhcmVudEJvdW5kcy54OwotCW9yaWdpblggPSBNYXRoLm1heCAob3JpZ2luWCwgMCk7Ci0Jb3JpZ2luWCA9IE1hdGgubWluIChvcmlnaW5YLCB3aWR0aExpbWl0IC0gcHQueCk7Ci0JaW50IG9yaWdpblkgPSAocGFyZW50Qm91bmRzLmhlaWdodCAtIHB0LnkpIC8gMiArIHBhcmVudEJvdW5kcy55OwotCW9yaWdpblkgPSBNYXRoLm1heCAob3JpZ2luWSwgMCk7Ci0Jb3JpZ2luWSA9IE1hdGgubWluIChvcmlnaW5ZLCBoZWlnaHRMaW1pdCAtIHB0LnkpOwotCXNoZWxsLnNldEJvdW5kcyAob3JpZ2luWCwgb3JpZ2luWSwgcHQueCwgcHQueSk7Ci0JCi0JU3RyaW5nIHRpdGxlID0gZ2V0VGV4dCAoKTsKLQlpZiAodGl0bGUubGVuZ3RoICgpID09IDApIHRpdGxlID0gU1dULmdldE1lc3NhZ2UgKCJTV1RfRm9udERpYWxvZ19UaXRsZSIpOwotCXNoZWxsLnNldFRleHQodGl0bGUpOwotCQotCS8vIE9wZW4gdGhlIHdpbmRvdy4KLQlzaGVsbC5vcGVuKCk7Ci19Ci0KLS8qKgotICogSW5pdGlhbGl6ZSB0aGUgY29tYm8gYm94ZXMgd2l0aCB0aGUgZGF0YSBvZiB0aGUgcHJlc2VsZWN0ZWQKLSAqIGZvbnQgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyLgotICovCi12b2lkIHNldEZvbnRDb21ib3MgKEZvbnREYXRhIGZvbnREYXRhKSB7Ci0JU3RyaW5nIGNoYXJhY3RlclNldCA9IGdldFRyYW5zbGF0ZWRDaGFyU2V0IChmb250RGF0YSk7Ci0JU3RyaW5nIGZhY2VOYW1lID0gZ2V0VHJhbnNsYXRlZEZhY2VOYW1lIChmb250RGF0YSk7Ci0JY2hhclNldENvbWJvLnNldFRleHQgKGNoYXJhY3RlclNldCk7Ci0JY2hhclNldENvbWJvLnNldERhdGEgKG5ldyBJbnRlZ2VyIChjaGFyU2V0Q29tYm8uaW5kZXhPZiAoY2hhcmFjdGVyU2V0KSkpOwotCi0JaW5pdEZhY2VOYW1lQ29tYm8gKCk7Ci0JZmFjZU5hbWVDb21iby5zZXRUZXh0IChmYWNlTmFtZSk7Ci0JZmFjZU5hbWVDb21iby5zZXREYXRhIChuZXcgSW50ZWdlciAoZmFjZU5hbWVDb21iby5pbmRleE9mIChmYWNlTmFtZSkpKTsKLQotCWluaXRFeHRTdHlsZUNvbWJvICgpOwotCWV4dFN0eWxlQ29tYm8uc2V0VGV4dCAoZm9udERhdGEuYWRkU3R5bGUpOwotCWV4dFN0eWxlQ29tYm8uc2V0RGF0YSAobmV3IEludGVnZXIgKGV4dFN0eWxlQ29tYm8uaW5kZXhPZiAoZm9udERhdGEuYWRkU3R5bGUpKSk7Ci0JCQotCWluaXRTaXplQ29tYm8gKCk7Ci0JU3RyaW5nIHZhbHVlID0gU3RyaW5nLnZhbHVlT2YgKGZvbnREYXRhLmdldEhlaWdodCAoKSk7Ci0JZm9udFNpemVDb21iby5zZXRUZXh0ICh2YWx1ZSk7Ci0JZm9udFNpemVDb21iby5zZXREYXRhIChuZXcgSW50ZWdlciAoZm9udFNpemVDb21iby5pbmRleE9mICh2YWx1ZSkpKTsKLQkKLQlpbml0U3R5bGVDb21ibyAoKTsKLQlmb250U3R5bGVDb21iby5zZXRUZXh0IChmb250RGF0YS53ZWlnaHQpOwotCWZvbnRTdHlsZUNvbWJvLnNldERhdGEgKG5ldyBJbnRlZ2VyIChmb250U3R5bGVDb21iby5pbmRleE9mIChmb250RGF0YS53ZWlnaHQpKSk7Ci19Ci0KLS8qKgotICogU2V0cyBhIEZvbnREYXRhIG9iamVjdCBkZXNjcmliaW5nIHRoZSBmb250IHRvIGJlCi0gKiBzZWxlY3RlZCBieSBkZWZhdWx0IGluIHRoZSBkaWFsb2csIG9yIG51bGwgdG8gbGV0Ci0gKiB0aGUgcGxhdGZvcm0gY2hvb3NlIG9uZS4KLSAqIAotICogQHBhcmFtIGZvbnREYXRhIHRoZSBGb250RGF0YSB0byB1c2UgaW5pdGlhbGx5LCBvciBudWxsCi0gKi8KIHB1YmxpYyB2b2lkIHNldEZvbnREYXRhIChGb250RGF0YSBmb250RGF0YSkgewotCWluaXRpYWxGb250RGF0YSA9IGZvbnREYXRhOworCXRoaXMuZm9udERhdGEgPSBmb250RGF0YTsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIHRoZSByZWNlaXZlcidzIHNlbGVjdGVkIGNvbG9yIHRvIGJlIHRoZSBhcmd1bWVudC4KLSAqCi0gKiBAcGFyYW0gcmdiIHRoZSBuZXcgUkdCIHZhbHVlIGZvciB0aGUgc2VsZWN0ZWQgY29sb3IsIG1heSBiZQotICogICAgICAgIG51bGwgdG8gbGV0IHRoZSBwbGF0Zm9ybSB0byBzZWxlY3QgYSBkZWZhdWx0IHdoZW4KLSAqICAgICAgICBvcGVuKCkgaXMgY2FsbGVkCi0gKgotICogQHNlZSBQYWxldHRlRGF0YSNnZXRSR0JzCi0gKi8KIHB1YmxpYyB2b2lkIHNldFJHQiAoUkdCIHJnYikgewogCXRoaXMucmdiID0gcmdiOwogfQogCi0vKioKLSAqIFNldCB0aGUgY29udGVudHMgb2YgJ2NvbWJvJyB0byB0aGUga2V5cyBvZiAnaXRlbXMnLgotICogS2V5cyBhcmUgc29ydGVkIGluIGFzY2VuZGluZyBvcmRlciBmaXJzdCBhbmQgaGF2ZSB0byBiZSBTdHJpbmdzLgotICovCi12b2lkIHNldEl0ZW1zU29ydGVkIChDb21ibyBjb21ibywgSGFzaHRhYmxlIGl0ZW1zKSB7Ci0JRW51bWVyYXRpb24gaXRlbUtleXMgPSBpdGVtcy5rZXlzICgpOwotCVN0cmluZyBbXSBzb3J0ZWRJdGVtcyA9IG5ldyBTdHJpbmdbaXRlbXMuc2l6ZSAoKV07Ci0JaW50IGluZGV4ID0gMDsKLQl3aGlsZSAoaXRlbUtleXMuaGFzTW9yZUVsZW1lbnRzICgpKSB7Ci0JCVN0cmluZyBpdGVtID0gKFN0cmluZykgaXRlbUtleXMubmV4dEVsZW1lbnQgKCk7Ci0JCWlmIChpdGVtLmxlbmd0aCAoKSAhPSAwKSBzb3J0ZWRJdGVtc1tpbmRleCsrXSA9IGl0ZW07Ci0JfQotCWlmIChpbmRleCAhPSBzb3J0ZWRJdGVtcy5sZW5ndGgpIHsKLQkJU3RyaW5nIFtdIG5ld0l0ZW1zID0gbmV3IFN0cmluZ1tpbmRleF07Ci0JCVN5c3RlbS5hcnJheWNvcHkgKHNvcnRlZEl0ZW1zLCAwLCBuZXdJdGVtcywgMCwgaW5kZXgpOwotCQlzb3J0ZWRJdGVtcyA9IG5ld0l0ZW1zOwotCX0KLQlzb3J0IChzb3J0ZWRJdGVtcyk7Ci0JY29tYm8uc2V0SXRlbXMgKHNvcnRlZEl0ZW1zKTsKLX0KLQotLyoqCi0gKiBTZXQgdGhlIGNvbnRlbnRzIG9mIHRoZSBzaXplIGNvbWJvIHRvIHRoZSBrZXlzIG9mICdpdGVtcycuCi0gKiBLZXlzIGFyZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyIGZpcnN0IGFuZCBoYXZlIHRvIGJlIEludGVnZXJzLgotICovCi12b2lkIHNldFNpemVJdGVtc1NvcnRlZCAoRW51bWVyYXRpb24gaXRlbXNFbnVtKSB7Ci0JVmVjdG9yIGl0ZW1zID0gbmV3IFZlY3RvciAoKTsKLQl3aGlsZSAoaXRlbXNFbnVtLmhhc01vcmVFbGVtZW50cyAoKSkgewotCQlpdGVtcy5hZGRFbGVtZW50IChpdGVtc0VudW0ubmV4dEVsZW1lbnQgKCkpOwotCX0KLQlJbnRlZ2VyW10gc29ydGVkSXRlbXMgPSBuZXcgSW50ZWdlciBbaXRlbXMuc2l6ZSAoKV07Ci0JaXRlbXMuY29weUludG8gKHNvcnRlZEl0ZW1zKTsKLQlzb3J0IChzb3J0ZWRJdGVtcyk7Ci0JU3RyaW5nW10gc29ydGVkSXRlbVN0cmluZ3MgPSBuZXcgU3RyaW5nIFtpdGVtcy5zaXplICgpXTsKLQlmb3IgKGludCBpID0gMDsgaSA8IHNvcnRlZEl0ZW1TdHJpbmdzLmxlbmd0aDsgaSsrKSB7Ci0JCXNvcnRlZEl0ZW1TdHJpbmdzIFtpXSA9IFN0cmluZy52YWx1ZU9mIChzb3J0ZWRJdGVtcyBbaV0uaW50VmFsdWUgKCkpOwotCX0KLQlmb250U2l6ZUNvbWJvLnNldEl0ZW1zIChzb3J0ZWRJdGVtU3RyaW5ncyk7Ci19Ci0KLS8qKgotICogU29ydCAnaXRlbXMnIGluIGFzY2VuZGluZyBvcmRlci4KLSAqLwotdm9pZCBzb3J0IChJbnRlZ2VyW10gaXRlbXMpIHsKLQkvKiBTaGVsbCBTb3J0IGZyb20gSyZSLCBwZyAxMDggKi8KLQlpbnQgbGVuZ3RoID0gaXRlbXMubGVuZ3RoOwotCWZvciAoaW50IGdhcCA9IGxlbmd0aCAvIDI7IGdhcCA+IDA7IGdhcCAvPSAyKSB7Ci0JCWZvciAoaW50IGkgPSBnYXA7IGkgPCBsZW5ndGg7IGkrKykgewotCQkJZm9yIChpbnQgaiA9IGkgLSBnYXA7IGogPj0gMDsgaiAtPSBnYXApIHsKLQkJICAgCQlpZiAoaXRlbXMgW2pdLmludFZhbHVlICgpID4gaXRlbXMgW2ogKyBnYXBdLmludFZhbHVlICgpKSB7Ci0JCQkJCUludGVnZXIgc3dhcCA9IGl0ZW1zIFtqXTsKLQkJCQkJaXRlbXNbal0gPSBpdGVtcyBbaiArIGdhcF07Ci0JCQkJCWl0ZW1zW2ogKyBnYXBdID0gc3dhcDsKLQkJICAgCQl9Ci0JICAgIAl9Ci0JICAgIH0KLQl9Ci19Ci0KLS8qKgotICogU29ydCAnaXRlbXMnIGluIGFzY2VuZGluZyBvcmRlci4KLSAqLwotdm9pZCBzb3J0IChTdHJpbmcgaXRlbXNbXSkgewotCS8qIFNoZWxsIFNvcnQgZnJvbSBLJlIsIHBnIDEwOCAqLwotCWludCBsZW5ndGggPSBpdGVtcy5sZW5ndGg7Ci0JZm9yIChpbnQgZ2FwID0gbGVuZ3RoIC8gMjsgZ2FwID4gMDsgZ2FwIC89IDIpIHsKLQkJZm9yIChpbnQgaSA9IGdhcDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0JCQlmb3IgKGludCBqID0gaSAtIGdhcDsgaiA+PSAwOyBqIC09IGdhcCkgewotCQkgICAJCWlmIChpdGVtcyBbal0uY29tcGFyZVRvIChpdGVtcyBbaiArIGdhcF0pID4gMCkgewotCQkJCQlTdHJpbmcgc3dhcCA9IGl0ZW1zIFtqXTsKLQkJCQkJaXRlbXMgW2pdID0gaXRlbXNbaiArIGdhcF07Ci0JCQkJCWl0ZW1zIFtqICsgZ2FwXSA9IHN3YXA7Ci0JCSAgIAkJfQotCSAgICAJfQotCSAgICB9Ci0JfQotfQotCi0vKioKLSAqIFNldCB0aGUgZm9udCBvZiB0aGUgc2FtcGxlIHRleHQgdG8gdGhlIHNlbGVjdGVkIGZvbnQuCi0gKiBEaXNwbGF5IGFuIGVycm9yIGluIHBsYWNlIG9mIHRoZSBzYW1wbGUgdGV4dCBpZiB0aGUgc2VsZWN0ZWQgCi0gKiBmb250IGNvdWxkIG5vdCBiZSBsb2FkZWQuCi0gKi8KLXZvaWQgdXBkYXRlU2FtcGxlRm9udCAoKSB7Ci0JRm9udERhdGEgc2VsZWN0aW9uRm9udERhdGEgPSBnZXRTZWxlY3Rpb25Gb250RGF0YSAoKTsKLQkvKgotCSAqIHNhbXBsZUZvbnQgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyB0aGUgb25lIHNwZWNpZmllZCBpbiBzZWxlY3Rpb25Gb250RGF0YS4KLQkgKiBUaGlzIGhhcHBlbnMgd2hlbiBzZWxlY3Rpb25Gb250RGF0YSBzcGVjaWZpZXMgYSBmb250IGFsaWFzLgotCSAqLwotCUZvbnQgbmV3U2FtcGxlRm9udCA9IG5ldyBGb250IChzaGVsbC5nZXREaXNwbGF5ICgpLCBzZWxlY3Rpb25Gb250RGF0YSk7Ci0Jc2FtcGxlTGFiZWwuc2V0Rm9udCAobmV3U2FtcGxlRm9udCk7Ci0JaWYgKHNhbXBsZUZvbnQgIT0gbnVsbCkgc2FtcGxlRm9udC5kaXNwb3NlICgpOwotCXNhbXBsZUZvbnQgPSBuZXdTYW1wbGVGb250OwotfQogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0dyb3VwLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvR3JvdXAuamF2YQppbmRleCA1NzUyOWIxLi40ZmUwNGRhIDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvR3JvdXAuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvR3JvdXAuamF2YQpAQCAtNyw5ICs3LDEwIEBACiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCiAKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LlNXVDsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLk9TOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUmVjdDsKIAogLyoqCiAgKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBwcm92aWRlIGFuIGV0Y2hlZCBib3JkZXIKQEAgLTMxLDExICszMiw5IEBACiAgKiBJTVBPUlRBTlQ6IFRoaXMgY2xhc3MgaXMgPGVtPm5vdDwvZW0+IGludGVuZGVkIHRvIGJlIHN1YmNsYXNzZWQuCiAgKiA8L3A+CiAgKi8KLXB1YmxpYyAvKmZpbmFsKi8gY2xhc3MgR3JvdXAgZXh0ZW5kcyBDb21wb3NpdGUgewotCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IExBQkVMX0hFSUdIVD0gMjA7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BUkdJTj0gNDsKLQorcHVibGljIGNsYXNzIEdyb3VwIGV4dGVuZHMgQ29tcG9zaXRlIHsKKwlTdHJpbmcgdGV4dDsKKwkKIC8qKgogICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIGl0cyBwYXJlbnQKICAqIGFuZCBhIHN0eWxlIHZhbHVlIGRlc2NyaWJpbmcgaXRzIGJlaGF2aW9yIGFuZCBhcHBlYXJhbmNlLgpAQCAtNzEsNiArNzAsNyBAQAogcHVibGljIEdyb3VwIChDb21wb3NpdGUgcGFyZW50LCBpbnQgc3R5bGUpIHsKIAlzdXBlciAocGFyZW50LCBjaGVja1N0eWxlIChzdHlsZSkpOwogfQorCiBzdGF0aWMgaW50IGNoZWNrU3R5bGUgKGludCBzdHlsZSkgewogCS8qCiAJKiBFdmVuIHRob3VnaCBpdCBpcyBsZWdhbCB0byBjcmVhdGUgdGhpcyB3aWRnZXQKQEAgLTgxLDkzICs4MSw1OSBAQAogCSovCiAJcmV0dXJuIHN0eWxlICYgfihTV1QuSF9TQ1JPTEwgfCBTV1QuVl9TQ1JPTEwpOwogfQorCiBwcm90ZWN0ZWQgdm9pZCBjaGVja1N1YmNsYXNzICgpIHsKIAlpZiAoIWlzVmFsaWRTdWJjbGFzcyAoKSkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1NVQkNMQVNTKTsKIH0KKwogcHVibGljIFJlY3RhbmdsZSBjb21wdXRlVHJpbSAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKLQljaGVja1dpZGdldCgpOwotICAgIC8qIEFXCi0JaW50IHRyaW1YLCB0cmltWSwgdHJpbVdpZHRoLCB0cmltSGVpZ2h0OwotCWludCBbXSBhcmdMaXN0ID0gewotCQlPUy5YbU53aWR0aCwgMCwKLQkJT1MuWG1OaGVpZ2h0LCAwLAotCQlPUy5YbU5zaGFkb3dUaGlja25lc3MsIDAsCi0JCU9TLlhtTm1hcmdpbldpZHRoLCAwLAotCQlPUy5YbU5tYXJnaW5IZWlnaHQsIDAKLQl9OwotCU9TLlh0R2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JaW50IHRoaWNrbmVzcyA9IGFyZ0xpc3QgWzVdOwotCWludCBtYXJnaW5XaWR0aCA9IGFyZ0xpc3QgWzddOwotCWludCBtYXJnaW5IZWlnaHQgPSBhcmdMaXN0IFs5XTsKLQlpbnQgYm9yZGVyV2lkdGggPSBnZXRCb3JkZXJXaWR0aCAoKTsKLQl0cmltWCA9IHggLSBtYXJnaW5XaWR0aCArIHRoaWNrbmVzcyAtIGJvcmRlcldpZHRoOwotCXRyaW1ZID0geSAtIG1hcmdpbkhlaWdodCArIHRoaWNrbmVzcyAtIGJvcmRlcldpZHRoOwotCXRyaW1XaWR0aCA9IHdpZHRoICsgKChtYXJnaW5XaWR0aCArIHRoaWNrbmVzcyArIGJvcmRlcldpZHRoKSAqIDIpOwotCXRyaW1IZWlnaHQgPSBoZWlnaHQgKyAoKG1hcmdpbkhlaWdodCArIHRoaWNrbmVzcyArIGJvcmRlcldpZHRoKSAqIDIpOwotCWlmIChPUy5YdElzTWFuYWdlZCAobGFiZWxIYW5kbGUpKSB7Ci0JCWludCBbXSBhcmdMaXN0MiA9IHtPUy5YbU55LCAwLCBPUy5YbU5oZWlnaHQsIDB9OwotCQlPUy5YdEdldFZhbHVlcyAobGFiZWxIYW5kbGUsIGFyZ0xpc3QyLCBhcmdMaXN0Mi5sZW5ndGggLyAyKTsKLQkJaW50IGxhYmVsSGVpZ2h0ID0gKChzaG9ydCkgYXJnTGlzdDIgWzFdKSArIGFyZ0xpc3QyIFszXTsKLQkJdHJpbVkgPSB5IC0gbGFiZWxIZWlnaHQ7Ci0JCXRyaW1IZWlnaHQgPSBoZWlnaHQgKyBsYWJlbEhlaWdodCArIChtYXJnaW5IZWlnaHQgKyB0aGlja25lc3MpOwotCX0KLSAgICAqLwotCXJldHVybiBuZXcgUmVjdGFuZ2xlICh4LU1BUkdJTiwgeS1MQUJFTF9IRUlHSFQsIHdpZHRoKygyKk1BUkdJTiksIGhlaWdodCtMQUJFTF9IRUlHSFQrTUFSR0lOKTsKKwljaGVja1dpZGdldCAoKTsKKwlSZWN0IGJvdW5kcyA9IG5ldyBSZWN0ICgpOworCU9TLkdldENvbnRyb2xCb3VuZHMgKGhhbmRsZSwgYm91bmRzKTsKKwlpbnQgcmduSGFuZGxlID0gT1MuTmV3UmduICgpOworCU9TLkdldENvbnRyb2xSZWdpb24gKGhhbmRsZSwgKHNob3J0KU9TLmtDb250cm9sQ29udGVudE1ldGFQYXJ0LCByZ25IYW5kbGUpOworCVJlY3QgY2xpZW50ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0UmVnaW9uQm91bmRzIChyZ25IYW5kbGUsIGNsaWVudCk7CisJT1MuRGlzcG9zZVJnbiAocmduSGFuZGxlKTsKKwl4IC09IGNsaWVudC5sZWZ0IC0gYm91bmRzLmxlZnQ7CisJeSAtPSBjbGllbnQudG9wIC0gYm91bmRzLnRvcDsKKwl3aWR0aCArPSBNYXRoLm1heCAoOCwgKGJvdW5kcy5yaWdodCAtIGJvdW5kcy5sZWZ0KSAtIChjbGllbnQucmlnaHQgLSBjbGllbnQubGVmdCkpOworCWhlaWdodCArPSBNYXRoLm1heCAoMjIsIChib3VuZHMuYm90dG9tIC0gYm91bmRzLnRvcCkgLSAoY2xpZW50LmJvdHRvbSAtIGNsaWVudC50b3ApKTsKKwlyZXR1cm4gbmV3IFJlY3RhbmdsZSAoeCwgeSwgd2lkdGgsIGhlaWdodCk7CiB9Ci12b2lkIGNyZWF0ZUhhbmRsZSAoaW50IGluZGV4KSB7Ci0Jc3RhdGUgfD0gSEFORExFOwotCWludCBwYXJlbnRIYW5kbGUgPSBwYXJlbnQuaGFuZGxlOwotICAgIC8qCi0JZm9ybUhhbmRsZSA9IE9TLlhtQ3JlYXRlRm9ybSAocGFyZW50SGFuZGxlLCBudWxsLCBhcmdMaXN0MSwgYXJnTGlzdDEubGVuZ3RoIC8gMik7Ci0JaWYgKGZvcm1IYW5kbGUgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKLSAgICAqLwotICAgIC8qIEFXCi0JaW50IFtdIGFyZ0xpc3QyID0gewotCQlPUy5YbU5zaGFkb3dUeXBlLCBzaGFkb3dUeXBlICgpLAotCQlPUy5YbU50b3BBdHRhY2htZW50LCBPUy5YbUFUVEFDSF9GT1JNLAotCQlPUy5YbU5ib3R0b21BdHRhY2htZW50LCBPUy5YbUFUVEFDSF9GT1JNLAotCQlPUy5YbU5sZWZ0QXR0YWNobWVudCwgT1MuWG1BVFRBQ0hfRk9STSwKLQkJT1MuWG1OcmlnaHRBdHRhY2htZW50LCBPUy5YbUFUVEFDSF9GT1JNLAotCQlPUy5YbU5yZXNpemFibGUsIDAsCi0JfTsKLQloYW5kbGUgPSBPUy5YbUNyZWF0ZUZyYW1lIChmb3JtSGFuZGxlLCBudWxsLCBhcmdMaXN0MiwgYXJnTGlzdDIubGVuZ3RoIC8gMik7Ci0gICAgKi8KLQloYW5kbGU9IE1hY1V0aWwubmV3Q29udHJvbChwYXJlbnRIYW5kbGUsIE9TLmtDb250cm9sR3JvdXBCb3hUZXh0VGl0bGVQcm9jKTsKLQlpZiAoaGFuZGxlID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0Jc2V0Rm9udChkZWZhdWx0Rm9udCgpKTsKKwordm9pZCBjcmVhdGVIYW5kbGUgKCkgeworCWludCBbXSBvdXRDb250cm9sID0gbmV3IGludCBbMV07CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAocGFyZW50LmhhbmRsZSk7CisJT1MuQ3JlYXRlR3JvdXBCb3hDb250cm9sICh3aW5kb3csIG51bGwsIDAsIHRydWUsIG91dENvbnRyb2wpOworCWlmIChvdXRDb250cm9sIFswXSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCWhhbmRsZSA9IG91dENvbnRyb2wgWzBdOwogfQotRm9udCBkZWZhdWx0Rm9udCAoKSB7Ci0JcmV0dXJuIGdldERpc3BsYXkgKCkuZ3JvdXBGb250OworCitpbnQgZGVmYXVsdFRoZW1lRm9udCAoKSB7CQorCXJldHVybiBPUy5rVGhlbWVFbXBoYXNpemVkU3lzdGVtRm9udDsKIH0KKwordm9pZCBkcmF3V2lkZ2V0IChpbnQgY29udHJvbCkgeworCWRyYXdCYWNrZ3JvdW5kIChoYW5kbGUsIGJhY2tncm91bmQpOworfQorCiBwdWJsaWMgUmVjdGFuZ2xlIGdldENsaWVudEFyZWEgKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0gICAgLyogQVcKLQlpbnQgW10gYXJnTGlzdCA9IHsKLQkJT1MuWG1Od2lkdGgsIDAsCi0JCU9TLlhtTmhlaWdodCwgMCwKLQkJT1MuWG1Oc2hhZG93VGhpY2tuZXNzLCAwLAotCQlPUy5YbU5tYXJnaW5XaWR0aCwgMCwKLQkJT1MuWG1ObWFyZ2luSGVpZ2h0LCAwCi0JfTsKLQlPUy5YdEdldFZhbHVlcyAoaGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCWludCB0aGlja25lc3MgPSBhcmdMaXN0IFs1XTsKLQlpbnQgbWFyZ2luV2lkdGggPSBhcmdMaXN0IFs3XTsKLQlpbnQgbWFyZ2luSGVpZ2h0ID0gYXJnTGlzdCBbOV07Ci0JaW50IHggPSBtYXJnaW5XaWR0aCArIHRoaWNrbmVzczsKLQlpbnQgeSA9IG1hcmdpbkhlaWdodCArIHRoaWNrbmVzczsKLQlpbnQgd2lkdGggPSBhcmdMaXN0IFsxXSAtICgobWFyZ2luV2lkdGggKyB0aGlja25lc3MpICogMikgLSAxOwotCWludCBoZWlnaHQgPSBhcmdMaXN0IFszXSAtICgobWFyZ2luSGVpZ2h0ICsgdGhpY2tuZXNzKSAqIDIpIC0gMTsKLQlpZiAoT1MuWHRJc01hbmFnZWQgKGxhYmVsSGFuZGxlKSkgewotCQlpbnQgW10gYXJnTGlzdDIgPSB7T1MuWG1OeSwgMCwgT1MuWG1OaGVpZ2h0LCAwfTsKLQkJT1MuWHRHZXRWYWx1ZXMgKGxhYmVsSGFuZGxlLCBhcmdMaXN0MiwgYXJnTGlzdDIubGVuZ3RoIC8gMik7Ci0JCXkgPSAoKHNob3J0KSBhcmdMaXN0MiBbMV0pICsgYXJnTGlzdDIgWzNdOwotCQloZWlnaHQgPSBhcmdMaXN0IFszXSAtIHkgLSAobWFyZ2luSGVpZ2h0ICsgdGhpY2tuZXNzKSAtIDE7Ci0JfQorCVJlY3QgYm91bmRzID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAoaGFuZGxlLCBib3VuZHMpOworCWludCByZ25IYW5kbGUgPSBPUy5OZXdSZ24gKCk7CisJT1MuR2V0Q29udHJvbFJlZ2lvbiAoaGFuZGxlLCAoc2hvcnQpT1Mua0NvbnRyb2xDb250ZW50TWV0YVBhcnQsIHJnbkhhbmRsZSk7CisJUmVjdCBjbGllbnQgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRSZWdpb25Cb3VuZHMgKHJnbkhhbmRsZSwgY2xpZW50KTsKKwlPUy5EaXNwb3NlUmduIChyZ25IYW5kbGUpOworCWludCB4ID0gTWF0aC5tYXggKDAsIGNsaWVudC5sZWZ0IC0gYm91bmRzLmxlZnQpOworCWludCB5ID0gTWF0aC5tYXggKDAsIGNsaWVudC50b3AgLSBib3VuZHMudG9wKTsKKwlpbnQgd2lkdGggPSBNYXRoLm1heCAoMCwgY2xpZW50LnJpZ2h0IC0gY2xpZW50LmxlZnQpOworCWludCBoZWlnaHQgPSBNYXRoLm1heCAoMCwgY2xpZW50LmJvdHRvbSAtIGNsaWVudC50b3ApOwogCXJldHVybiBuZXcgUmVjdGFuZ2xlICh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKLSAgICAqLwotCVBvaW50IGU9IGdldFNpemUoKTsKLSAgICByZXR1cm4gbmV3IFJlY3RhbmdsZShNQVJHSU4sIExBQkVMX0hFSUdIVCwgZS54LSgyKk1BUkdJTiksIGUueS0oTEFCRUxfSEVJR0hUK01BUkdJTikpOwogfQorCiAvKioKICAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3MgdGV4dCwgd2hpY2ggaXMgdGhlIHN0cmluZyB0aGF0IHRoZQogICogaXMgdXNlZCBhcyB0aGUgPGVtPnRpdGxlPC9lbT4uIElmIHRoZSB0ZXh0IGhhcyBub3QgcHJldmlvdXNseQpAQCAtMTgxLDIxICsxNDcsMTAgQEAKICAqIDwvdWw+CiAgKi8KIHB1YmxpYyBTdHJpbmcgZ2V0VGV4dCAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlpbnRbXSBzSGFuZGxlPSBuZXcgaW50WzFdOwotICAgIE9TLkdldENvbnRyb2xUaXRsZUFzQ0ZTdHJpbmcoaGFuZGxlLCBzSGFuZGxlKTsKLQlyZXR1cm4gTWFjVXRpbC5nZXRTdHJpbmdBbmRSZWxlYXNlKHNIYW5kbGVbMF0pOworCWNoZWNrV2lkZ2V0ICgpOworCXJldHVybiB0ZXh0OwogfQotLyogQVcKLWJvb2xlYW4gbW5lbW9uaWNIaXQgKGNoYXIga2V5KSB7Ci0JcmV0dXJuIHNldEZvY3VzICgpOwotfQotYm9vbGVhbiBtbmVtb25pY01hdGNoIChjaGFyIGtleSkgewotCWNoYXIgbW5lbW9uaWMgPSBmaW5kTW5lbW9uaWMgKGdldFRleHQgKCkpOwotCWlmIChtbmVtb25pYyA9PSAnXDAnKSByZXR1cm4gZmFsc2U7Ci0JcmV0dXJuIENoYXJhY3Rlci50b1VwcGVyQ2FzZSAoa2V5KSA9PSBDaGFyYWN0ZXIudG9VcHBlckNhc2UgKG1uZW1vbmljKTsKLX0KLSovCisKIC8qKgogICogU2V0cyB0aGUgcmVjZWl2ZXIncyB0ZXh0LCB3aGljaCBpcyB0aGUgc3RyaW5nIHRoYXQgd2lsbAogICogYmUgZGlzcGxheWVkIGFzIHRoZSByZWNlaXZlcidzIDxlbT50aXRsZTwvZW0+LCB0byB0aGUgYXJndW1lbnQsCkBAIC0yMTQsMTMgKzE2OSwyMiBAQAogcHVibGljIHZvaWQgc2V0VGV4dCAoU3RyaW5nIHN0cmluZykgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHN0cmluZyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCWludCBzSGFuZGxlPSAwOwotCXRyeSB7Ci0JCXNIYW5kbGU9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMoTWFjVXRpbC5yZW1vdmVNbmVtb25pY3Moc3RyaW5nKSk7Ci0JCU9TLlNldENvbnRyb2xUaXRsZVdpdGhDRlN0cmluZyhoYW5kbGUsIHNIYW5kbGUpOwotCX0gZmluYWxseSB7Ci0JCWlmIChzSGFuZGxlICE9IDApCi0JCQlPUy5DRlJlbGVhc2Uoc0hhbmRsZSk7CisJaWYgKChzdHlsZSAmIFNXVC5BUlJPVykgIT0gMCkgcmV0dXJuOworCXRleHQgPSBzdHJpbmc7CisJY2hhciBbXSBidWZmZXIgPSBuZXcgY2hhciBbdGV4dC5sZW5ndGggKCldOworCXRleHQuZ2V0Q2hhcnMgKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlciwgMCk7CisJaW50IGk9MCwgaj0wOworCXdoaWxlIChpIDwgYnVmZmVyLmxlbmd0aCkgeworCQlpZiAoKGJ1ZmZlciBbaisrXSA9IGJ1ZmZlciBbaSsrXSkgPT0gTW5lbW9uaWMpIHsKKwkJCWlmIChpID09IGJ1ZmZlci5sZW5ndGgpIHtjb250aW51ZTt9CisJCQlpZiAoYnVmZmVyIFtpXSA9PSBNbmVtb25pYykge2krKzsgY29udGludWU7fQorCQkJai0tOworCQl9CiAJfQorCWludCBwdHIgPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzIChPUy5rQ0ZBbGxvY2F0b3JEZWZhdWx0LCBidWZmZXIsIGopOworCWlmIChwdHIgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfU0VUX1RFWFQpOworCU9TLlNldENvbnRyb2xUaXRsZVdpdGhDRlN0cmluZyAoaGFuZGxlLCBwdHIpOworCU9TLkNGUmVsZWFzZSAocHRyKTsKIH0KLX0KKworfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9MYWJlbC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0xhYmVsLmphdmEKaW5kZXggNjg4NTkyYi4uMTg5Y2VhYiAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0xhYmVsLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0xhYmVsLmphdmEKQEAgLTcsNDMxICs3LDE1OSBAQAogICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKICAqLwogCitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKKwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKIAotLyoqCi0gKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyByZXByZXNlbnQgYSBub24tc2VsZWN0YWJsZQotICogdXNlciBpbnRlcmZhY2Ugb2JqZWN0IHRoYXQgZGlzcGxheXMgYSBzdHJpbmcgb3IgaW1hZ2UuCi0gKiBXaGVuIFNFUEFSQVRPUiBpcyBzcGVjaWZpZWQsIGRpc3BsYXlzIGEgc2luZ2xlCi0gKiB2ZXJ0aWNhbCBvciBob3Jpem9udGFsIGxpbmUuCi0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPlNFUEFSQVRPUiwgSE9SSVpPTlRBTCwgVkVSVElDQUw8L2RkPgotICogPGRkPlNIQURPV19JTiwgU0hBRE9XX09VVCwgU0hBRE9XX05PTkU8L2RkPgotICogPGRkPkNFTlRFUiwgTEVGVCwgUklHSFQsIFdSQVA8L2RkPgotICogPGR0PjxiPkV2ZW50czo8L2I+PC9kdD4KLSAqIDxkZD4obm9uZSk8L2RkPgotICogPC9kbD4KLSAqIDxwPgotICogTm90ZTogT25seSBvbmUgb2YgU0hBRE9XX0lOLCBTSEFET1dfT1VUIGFuZCBTSEFET1dfTk9ORSBtYXkgYmUgc3BlY2lmaWVkLgotICogU0hBRE9XX05PTkUgaXMgYSBISU5ULiBPbmx5IG9uZSBvZiBIT1JJWk9OVEFMIGFuZCBWRVJUSUNBTCBtYXkgYmUgc3BlY2lmaWVkLgotICogT25seSBvbmUgb2YgQ0VOVEVSLCBMRUZUIGFuZCBSSUdIVCBtYXkgYmUgc3BlY2lmaWVkLgotICogPC9wPjxwPgotICogSU1QT1JUQU5UOiBUaGlzIGNsYXNzIGlzIGludGVuZGVkIHRvIGJlIHN1YmNsYXNzZWQgPGVtPm9ubHk8L2VtPgotICogd2l0aGluIHRoZSBTV1QgaW1wbGVtZW50YXRpb24uCi0gKiA8L3A+Ci0gKi8KLXB1YmxpYyAvKmZpbmFsKi8gY2xhc3MgTGFiZWwgZXh0ZW5kcyBDb250cm9sIHsKK3B1YmxpYyBjbGFzcyBMYWJlbCBleHRlbmRzIENvbnRyb2wgewogCVN0cmluZyB0ZXh0ID0gIiI7Ci0JSW1hZ2UgaW1hZ2UsIGRpc2FibGVkOworCUltYWdlIGltYWdlOworCWJvb2xlYW4gaXNJbWFnZTsKIAotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gaXRzIHBhcmVudAotICogYW5kIGEgc3R5bGUgdmFsdWUgZGVzY3JpYmluZyBpdHMgYmVoYXZpb3IgYW5kIGFwcGVhcmFuY2UuCi0gKiA8cD4KLSAqIFRoZSBzdHlsZSB2YWx1ZSBpcyBlaXRoZXIgb25lIG9mIHRoZSBzdHlsZSBjb25zdGFudHMgZGVmaW5lZCBpbgotICogY2xhc3MgPGNvZGU+U1dUPC9jb2RlPiB3aGljaCBpcyBhcHBsaWNhYmxlIHRvIGluc3RhbmNlcyBvZiB0aGlzCi0gKiBjbGFzcywgb3IgbXVzdCBiZSBidWlsdCBieSA8ZW0+Yml0d2lzZSBPUjwvZW0+J2luZyB0b2dldGhlciAKLSAqICh0aGF0IGlzLCB1c2luZyB0aGUgPGNvZGU+aW50PC9jb2RlPiAifCIgb3BlcmF0b3IpIHR3byBvciBtb3JlCi0gKiBvZiB0aG9zZSA8Y29kZT5TV1Q8L2NvZGU+IHN0eWxlIGNvbnN0YW50cy4gVGhlIGNsYXNzIGRlc2NyaXB0aW9uCi0gKiBsaXN0cyB0aGUgc3R5bGUgY29uc3RhbnRzIHRoYXQgYXJlIGFwcGxpY2FibGUgdG8gdGhlIGNsYXNzLgotICogU3R5bGUgYml0cyBhcmUgYWxzbyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIGNvbXBvc2l0ZSBjb250cm9sIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqIEBwYXJhbSBzdHlsZSB0aGUgc3R5bGUgb2YgY29udHJvbCB0byBjb25zdHJ1Y3QKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU1dUI1NFUEFSQVRPUgotICogQHNlZSBTV1QjSE9SSVpPTlRBTAotICogQHNlZSBTV1QjVkVSVElDQUwKLSAqIEBzZWUgU1dUI1NIQURPV19JTgotICogQHNlZSBTV1QjU0hBRE9XX09VVAotICogQHNlZSBTV1QjU0hBRE9XX05PTkUKLSAqIEBzZWUgU1dUI0NFTlRFUgotICogQHNlZSBTV1QjTEVGVAotICogQHNlZSBTV1QjUklHSFQKLSAqIEBzZWUgU1dUI1dSQVAKLSAqIEBzZWUgV2lkZ2V0I2NoZWNrU3ViY2xhc3MKLSAqIEBzZWUgV2lkZ2V0I2dldFN0eWxlCi0gKi8KIHB1YmxpYyBMYWJlbCAoQ29tcG9zaXRlIHBhcmVudCwgaW50IHN0eWxlKSB7CiAJc3VwZXIgKHBhcmVudCwgY2hlY2tTdHlsZSAoc3R5bGUpKTsKIH0KKwogc3RhdGljIGludCBjaGVja1N0eWxlIChpbnQgc3R5bGUpIHsKIAlpZiAoKHN0eWxlICYgU1dULlNFUEFSQVRPUikgIT0gMCkgcmV0dXJuIHN0eWxlOwogCXJldHVybiBjaGVja0JpdHMgKHN0eWxlLCBTV1QuTEVGVCwgU1dULkNFTlRFUiwgU1dULlJJR0hULCAwLCAwLCAwKTsKIH0KKwogcHVibGljIFBvaW50IGNvbXB1dGVTaXplIChpbnQgd0hpbnQsIGludCBoSGludCwgYm9vbGVhbiBjaGFuZ2VkKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpbnQgYm9yZGVyID0gZ2V0Qm9yZGVyV2lkdGggKCk7CiAJaW50IHdpZHRoID0gMCwgaGVpZ2h0ID0gMDsKLQkKIAlpZiAoKHN0eWxlICYgU1dULlNFUEFSQVRPUikgIT0gMCkgewogCQlpZiAoKHN0eWxlICYgU1dULkhPUklaT05UQUwpICE9IDApIHsKLQkJCXdpZHRoICs9IERFRkFVTFRfV0lEVEg7Ci0JCQloZWlnaHQgKz0gMzsKKwkJCXdpZHRoID0gREVGQVVMVF9XSURUSDsKKwkJCWhlaWdodCA9IDM7CiAJCX0gZWxzZSB7Ci0JCQl3aWR0aCArPSAzOwotCQkJaGVpZ2h0ICs9IERFRkFVTFRfSEVJR0hUOworCQkJd2lkdGggPSAzOworCQkJaGVpZ2h0ID0gREVGQVVMVF9IRUlHSFQ7CiAJCX0KIAl9IGVsc2UgewotCQlpZiAoaW1hZ2UgIT0gbnVsbCkgeworCQlpZiAoaXNJbWFnZSAmJiBpbWFnZSAhPSBudWxsKSB7CiAJCQlSZWN0YW5nbGUgciA9IGltYWdlLmdldEJvdW5kcygpOwotCQkJd2lkdGg9IHIud2lkdGg7Ci0JCQloZWlnaHQ9IHIuaGVpZ2h0OworCQkJd2lkdGggPSByLndpZHRoOworCQkJaGVpZ2h0ID0gci5oZWlnaHQ7CiAJCX0gZWxzZSB7Ci0JCQlzaG9ydFtdIGJvdW5kcz0gbmV3IHNob3J0WzJdOwotCQkJc2hvcnRbXSBiYXNlTGluZT0gbmV3IHNob3J0WzFdOwotCQkJYm9vbGVhbiB3cmFwPSBmYWxzZTsKLQkJCWlmICgoc3R5bGUgJiBTV1QuV1JBUCkgIT0gMCAmJiB3SGludCAhPSBTV1QuREVGQVVMVCkgewotCQkJCXdyYXA9IHRydWU7Ci0JCQkJYm91bmRzWzFdPSAoc2hvcnQpIHdIaW50OwkvLyBJZiB3ZSBhcmUgd3JhcHBpbmcgdGV4dCwgY2FsY3VsYXRlIHRoZSBoZWlnaHQgYmFzZWQgb24gd0hpbnQuCisJCQlpbnQgW10gcHRyID0gbmV3IGludCBbMV07CisJCQlpbnQgW10gYWN0dWFsU2l6ZSA9IG5ldyBpbnQgWzFdOworCQkJT1MuR2V0Q29udHJvbERhdGEgKGhhbmRsZSwgKHNob3J0KTAgLCBPUy5rQ29udHJvbFN0YXRpY1RleHRDRlN0cmluZ1RhZywgNCwgcHRyLCBhY3R1YWxTaXplKTsKKwkJCWlmIChwdHIgWzBdICE9IDApIHsKKwkJCQlvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBvaW50IGJvdW5kcyA9IG5ldyBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBvaW50ICgpOworCQkJCXNob3J0IFtdIGJhc2VMaW5lID0gbmV3IHNob3J0IFsxXTsKKwkJCQlib29sZWFuIHdyYXAgPSBmYWxzZTsKKwkJCQlpZiAoKHN0eWxlICYgU1dULldSQVApICE9IDAgJiYgd0hpbnQgIT0gU1dULkRFRkFVTFQpIHsKKwkJCQkJd3JhcCA9IHRydWU7CisJCQkJCWJvdW5kcy5oID0gKHNob3J0KSB3SGludDsKKwkJCQl9CisJCQkJLy8gTkVFRFMgd29yayAtIG9ubHkgd29ya3MgZm9yIGRlZmF1bHQgZm9udAorCQkJCU9TLkdldFRoZW1lVGV4dERpbWVuc2lvbnMgKHB0ciBbMF0sIChzaG9ydClPUy5rVGhlbWVTeXN0ZW1Gb250LCBPUy5rVGhlbWVTdGF0ZUFjdGl2ZSwgd3JhcCwgYm91bmRzLCBiYXNlTGluZSk7CisJCQkJd2lkdGggPSBib3VuZHMuaDsKKwkJCQloZWlnaHQgPSBib3VuZHMudjsKKwkJCQlPUy5DRlJlbGVhc2UgKHB0ciBbMF0pOworCQkJfSBlbHNlIHsKKwkJCQl3aWR0aCA9IERFRkFVTFRfV0lEVEg7CisJCQkJaGVpZ2h0ID0gREVGQVVMVF9IRUlHSFQ7CiAJCQl9Ci0JCQlpbnQgc0hhbmRsZT0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyhNYWNVdGlsLnJlbW92ZU1uZW1vbmljcyh0ZXh0KSk7Ci0JCQkJCQotCQkJR0MgZ2M9IG5ldyBHQyh0aGlzKTsKLQkJCWdjLmluc3RhbGxGb250KCk7Ci0JCQlPUy5HZXRUaGVtZVRleHREaW1lbnNpb25zKHNIYW5kbGUsIE9TLmtUaGVtZUN1cnJlbnRQb3J0Rm9udCwgT1Mua1RoZW1lU3RhdGVBY3RpdmUsIHdyYXAsIGJvdW5kcywgYmFzZUxpbmUpOwotCQkJZ2MuZGlzcG9zZSgpOwotCQkJCi0JCQlPUy5DRlJlbGVhc2Uoc0hhbmRsZSk7Ci0JCQl3aWR0aCA9IGJvdW5kc1sxXTsKLQkJCWhlaWdodCA9IGJvdW5kc1swXTsKIAkJfQotCQkvKgotCQkqIEZlYXR1cmUgaW4gTW90aWYuIElmIGEgbGFiZWwncyBsYWJlbFR5cGUgaXMgWG1TVFJJTkcgYnV0IGl0Ci0JCSogaGFzIG5vIGxhYmVsIHNldCBpbnRvIGl0IHlldCwgcmVjb21wdXRpbmcgdGhlIHNpemUgd2lsbAotCQkqIG5vdCB0YWtlIGludG8gYWNjb3VudCB0aGUgaGVpZ2h0IG9mIHRoZSBmb250LCBhcyB3ZSB3b3VsZAotCQkqIGxpa2UgaXQgdG8uIFRha2UgY2FyZSBvZiB0aGlzIGNhc2UuCi0JCSovCi0JCS8qIEFXCi0JCWlmICh0ZXh0Lmxlbmd0aCAoKSA9PSAwKSB7Ci0JCQloZWlnaHQgKz0gZ2V0Rm9udEhlaWdodCAoKTsKLQkJCXdpZHRoID0gMDsKLQkJfQotCQkqLwogCX0KIAlpZiAod0hpbnQgIT0gU1dULkRFRkFVTFQpIHdpZHRoID0gd0hpbnQ7CiAJaWYgKGhIaW50ICE9IFNXVC5ERUZBVUxUKSBoZWlnaHQgPSBoSGludDsKLQlyZXR1cm4gbmV3IFBvaW50ICh3aWR0aCArIDIqYm9yZGVyLCBoZWlnaHQgKyAyKmJvcmRlcik7CisJcmV0dXJuIG5ldyBQb2ludCAod2lkdGgsIGhlaWdodCk7CiB9Ci12b2lkIGNyZWF0ZUhhbmRsZSAoaW50IGluZGV4KSB7Ci0Jc3RhdGUgfD0gSEFORExFOwotCWludCBwYXJlbnRIYW5kbGUgPSBwYXJlbnQuaGFuZGxlOwotCWludCBib3JkZXJXaWR0aCA9IChzdHlsZSAmIFNXVC5CT1JERVIpICE9IDAgPyAxIDogMDsKKwordm9pZCBjcmVhdGVIYW5kbGUgKCkgeworCXN0YXRlIHw9IEdSQUI7CisJaW50IFtdIG91dENvbnRyb2wgPSBuZXcgaW50IFsxXTsKKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChwYXJlbnQuaGFuZGxlKTsKIAlpZiAoKHN0eWxlICYgU1dULlNFUEFSQVRPUikgIT0gMCkgewotICAJCWhhbmRsZT0gTWFjVXRpbC5uZXdDb250cm9sKHBhcmVudEhhbmRsZSwgKHNob3J0KTAsIChzaG9ydCkwLCAoc2hvcnQpMTAwLCBPUy5rQ29udHJvbFNlcGFyYXRvckxpbmVQcm9jKTsKLQkJaWYgKChzdHlsZSAmIFNXVC5IT1JJWk9OVEFMKSAhPSAwKQotCQkJT1MuU2l6ZUNvbnRyb2woaGFuZGxlLCAoc2hvcnQpIDIwLCAoc2hvcnQpIDEpOwotCQllbHNlCi0JCQlPUy5TaXplQ29udHJvbChoYW5kbGUsIChzaG9ydCkgMSwgKHNob3J0KSAyMCk7CQorCQlPUy5DcmVhdGVTZXBhcmF0b3JDb250cm9sICh3aW5kb3csIG51bGwsIG91dENvbnRyb2wpOwogCX0gZWxzZSB7Ci0JCWhhbmRsZSA9IE1hY1V0aWwuY3JlYXRlRHJhd2luZ0FyZWEocGFyZW50SGFuZGxlLCAtMSwgdHJ1ZSwgMCwgMCwgYm9yZGVyV2lkdGgpOworCQlPUy5DcmVhdGVTdGF0aWNUZXh0Q29udHJvbCAod2luZG93LCBudWxsLCAwLCBudWxsLCBvdXRDb250cm9sKTsKIAl9Ci0JaWYgKGhhbmRsZSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCWlmIChvdXRDb250cm9sIFswXSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCWhhbmRsZSA9IG91dENvbnRyb2wgWzBdOwogfQotaW50IGRlZmF1bHRCYWNrZ3JvdW5kICgpIHsKLQlyZXR1cm4gZ2V0RGlzcGxheSAoKS5sYWJlbEJhY2tncm91bmQ7Ci19Ci1Gb250IGRlZmF1bHRGb250ICgpIHsKLQlyZXR1cm4gZ2V0RGlzcGxheSAoKS5sYWJlbEZvbnQ7Ci19Ci1pbnQgZGVmYXVsdEZvcmVncm91bmQgKCkgewotCXJldHVybiBnZXREaXNwbGF5ICgpLmxhYmVsRm9yZWdyb3VuZDsKLX0KLS8qKgotICogUmV0dXJucyBhIHZhbHVlIHdoaWNoIGRlc2NyaWJlcyB0aGUgcG9zaXRpb24gb2YgdGhlCi0gKiB0ZXh0IG9yIGltYWdlIGluIHRoZSByZWNlaXZlci4gVGhlIHZhbHVlIHdpbGwgYmUgb25lIG9mCi0gKiA8Y29kZT5MRUZUPC9jb2RlPiwgPGNvZGU+UklHSFQ8L2NvZGU+IG9yIDxjb2RlPkNFTlRFUjwvY29kZT4KLSAqIHVubGVzcyB0aGUgcmVjZWl2ZXIgaXMgYSA8Y29kZT5TRVBBUkFUT1I8L2NvZGU+IGxhYmVsLCBpbiAKLSAqIHdoaWNoIGNhc2UsIDxjb2RlPk5PTkU8L2NvZGU+IGlzIHJldHVybmVkLgotICoKLSAqIEByZXR1cm4gdGhlIGFsaWdubWVudCAKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGludCBnZXRBbGlnbm1lbnQgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKChzdHlsZSAmIFNXVC5TRVBBUkFUT1IpICE9IDApIHJldHVybiBTV1QuTEVGVDsKLQlpZiAoKHN0eWxlICYgU1dULkNFTlRFUikgIT0gMCkKLQkJcmV0dXJuIFNXVC5DRU5URVI7Ci0JaWYgKChzdHlsZSAmIFNXVC5SSUdIVCkgIT0gMCkKLQkJcmV0dXJuIFNXVC5SSUdIVDsKKwlpZiAoKHN0eWxlICYgU1dULkNFTlRFUikgIT0gMCkgcmV0dXJuIFNXVC5DRU5URVI7CisJaWYgKChzdHlsZSAmIFNXVC5SSUdIVCkgIT0gMCkgcmV0dXJuIFNXVC5SSUdIVDsKIAlyZXR1cm4gU1dULkxFRlQ7CiB9CisKIHB1YmxpYyBpbnQgZ2V0Qm9yZGVyV2lkdGggKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIChzdHlsZSAmIFNXVC5CT1JERVIpICE9IDAgPyAxIDogMDsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgcmVjZWl2ZXIncyBpbWFnZSBpZiBpdCBoYXMgb25lLCBvciBudWxsCi0gKiBpZiBpdCBkb2VzIG5vdC4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGltYWdlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBJbWFnZSBnZXRJbWFnZSAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlyZXR1cm4gaW1hZ2U7CiB9CisKIFN0cmluZyBnZXROYW1lVGV4dCAoKSB7CiAJcmV0dXJuIGdldFRleHQgKCk7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3MgdGV4dCwgd2hpY2ggd2lsbCBiZSBhbiBlbXB0eQotICogc3RyaW5nIGlmIGl0IGhhcyBuZXZlciBiZWVuIHNldCBvciBpZiB0aGUgcmVjZWl2ZXIgaXMKLSAqIGEgPGNvZGU+U0VQQVJBVE9SPC9jb2RlPiBsYWJlbC4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIHRleHQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIFN0cmluZyBnZXRUZXh0ICgpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSByZXR1cm4gIiI7CiAJcmV0dXJuIHRleHQ7CiB9Ci12b2lkIGhvb2tFdmVudHMgKCkgewotCXN1cGVyLmhvb2tFdmVudHMgKCk7Ci0JRGlzcGxheSBkaXNwbGF5PSBnZXREaXNwbGF5KCk7CQkKLQlPUy5TZXRDb250cm9sRGF0YShoYW5kbGUsIE9TLmtDb250cm9sRW50aXJlQ29udHJvbCwgT1Mua0NvbnRyb2xVc2VyUGFuZURyYXdQcm9jVGFnLCBkaXNwbGF5LmZVc2VyUGFuZURyYXdQcm9jKTsKLX0KLS8qIEFXCi1ib29sZWFuIG1uZW1vbmljSGl0IChjaGFyIGtleSkgewotCUNvbXBvc2l0ZSBjb250cm9sID0gdGhpcy5wYXJlbnQ7Ci0Jd2hpbGUgKGNvbnRyb2wgIT0gbnVsbCkgewotCQlDb250cm9sIFtdIGNoaWxkcmVuID0gY29udHJvbC5fZ2V0Q2hpbGRyZW4gKCk7Ci0JCWludCBpbmRleCA9IDA7Ci0JCXdoaWxlIChpbmRleCA8IGNoaWxkcmVuLmxlbmd0aCkgewotCQkJaWYgKGNoaWxkcmVuIFtpbmRleF0gPT0gdGhpcykgYnJlYWs7Ci0JCQlpbmRleCsrOwotCQl9Ci0JCWluZGV4Kys7Ci0JCWlmIChpbmRleCA8IGNoaWxkcmVuLmxlbmd0aCkgewotCQkJaWYgKGNoaWxkcmVuIFtpbmRleF0uc2V0Rm9jdXMgKCkpIHJldHVybiB0cnVlOwotCQl9Ci0JCWNvbnRyb2wgPSBjb250cm9sLnBhcmVudDsKLQl9Ci0JcmV0dXJuIGZhbHNlOwotfQotYm9vbGVhbiBtbmVtb25pY01hdGNoIChjaGFyIGtleSkgewotCWNoYXIgbW5lbW9uaWMgPSBmaW5kTW5lbW9uaWMgKGdldFRleHQgKCkpOwotCWlmIChtbmVtb25pYyA9PSAnXDAnKSByZXR1cm4gZmFsc2U7Ci0JcmV0dXJuIENoYXJhY3Rlci50b1VwcGVyQ2FzZSAoa2V5KSA9PSBDaGFyYWN0ZXIudG9VcHBlckNhc2UgKG1uZW1vbmljKTsKLX0KLSovCi1pbnQgcHJvY2Vzc1BhaW50IChPYmplY3QgY2FsbERhdGEpIHsKLQlpZiAoKHN0eWxlICYgU1dULlNFUEFSQVRPUikgIT0gMCkgcmV0dXJuIDA7Ci0JCi0JR0MgZ2M9IG5ldyBHQyh0aGlzKTsKLQlNYWNDb250cm9sRXZlbnQgbWU9IChNYWNDb250cm9sRXZlbnQpIGNhbGxEYXRhOwotCVJlY3RhbmdsZSByPSBnYy5jYXJib25fZm9jdXMobWUuZ2V0RGFtYWdlUmVnaW9uSGFuZGxlKCkpOwotCQotCWlmICghIHIuaXNFbXB0eSgpKSB7Ci0JCQotCQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQkJaW50IGhuZGw9IHRvcEhhbmRsZSgpOwotCQlPUy5HZXRDb250cm9sQm91bmRzKGhuZGwsIGJvdW5kcy5nZXREYXRhKCkpOwotCQotCQlpbnQgdz0gYm91bmRzLmdldFdpZHRoKCk7Ci0JCWludCBoPSBib3VuZHMuZ2V0SGVpZ2h0KCk7Ci0JCWludCBib3JkZXJXaWR0aCA9IChzdHlsZSAmIFNXVC5CT1JERVIpICE9IDAgPyAxIDogMDsKLQkJCi0JCWdjLmZpbGxSZWN0YW5nbGUoMCwgMCwgci53aWR0aCwgci5oZWlnaHQpOwotCQkKLQkJYm9vbGVhbiBlbmFibGVkPSBPUy5Jc0NvbnRyb2xFbmFibGVkKGhhbmRsZSk7Ci0JCQorCitpbnQga0V2ZW50Q29udHJvbERyYXcgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpbnQgcmVzdWx0ID0gc3VwZXIua0V2ZW50Q29udHJvbERyYXcgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCWlmIChpc0ltYWdlKSB7CiAJCWlmIChpbWFnZSAhPSBudWxsKSB7Ci0JCQlSZWN0YW5nbGUgaW1hZ2VCb3VuZHM9IGltYWdlLmdldEJvdW5kcygpOwotCQkJSW1hZ2UgaW07Ci0JCQlpZiAoZW5hYmxlZCkKLQkJCQlpbT0gaW1hZ2U7Ci0JCQllbHNlIHsKLQkJCQlpZiAoZGlzYWJsZWQgPT0gbnVsbCkKLQkJCQkJZGlzYWJsZWQgPSBuZXcgSW1hZ2UgKGdldERpc3BsYXkoKSwgaW1hZ2UsIFNXVC5JTUFHRV9ESVNBQkxFKTsKLQkJCQlpbT0gZGlzYWJsZWQ7Ci0JCQl9CQkJCi0JCQlnYy5kcmF3SW1hZ2UoaW0sICh3LWltYWdlQm91bmRzLndpZHRoKSAvIDIsIChoLWltYWdlQm91bmRzLmhlaWdodCkgLyAyKTsKLQkJfSBlbHNlIHsKLQkJCWludCBzSGFuZGxlPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzKE1hY1V0aWwucmVtb3ZlTW5lbW9uaWNzKHRleHQpKTsKLQkJCWJvb2xlYW4gd3JhcD0gKHN0eWxlICYgU1dULldSQVApICE9IDA7Ci0JCQlzaG9ydCBqdXN0PSAwOwotCQkJaWYgKChzdHlsZSAmIFNXVC5SSUdIVCkgIT0gMCkKLQkJCQlqdXN0PSAyOwotCQkJZWxzZSBpZiAoKHN0eWxlICYgU1dULkNFTlRFUikgIT0gMCkKLQkJCQlqdXN0PSAxOwotCQkJTWFjVXRpbC5SR0JGb3JlQ29sb3IoZW5hYmxlZCA/IDB4MDAwMDAwIDogMHg4MDgwODApOwotCQkJZ2MuaW5zdGFsbEZvbnQoKTsKLQkJCWJvdW5kcy5zZXQoYm9yZGVyV2lkdGgsIGJvcmRlcldpZHRoLCB3LTIqYm9yZGVyV2lkdGgsIGgtMipib3JkZXJXaWR0aCk7Ci0JCQlPUy5EcmF3VGhlbWVUZXh0Qm94KHNIYW5kbGUsIE9TLmtUaGVtZUN1cnJlbnRQb3J0Rm9udCwgT1Mua1RoZW1lU3RhdGVBY3RpdmUsIHdyYXAsIGJvdW5kcy5nZXREYXRhKCksIGp1c3QsIDApOwotCQkJT1MuQ0ZSZWxlYXNlKHNIYW5kbGUpOworCQkJR0NEYXRhIGRhdGEgPSBuZXcgR0NEYXRhICgpOworCQkJZGF0YS5wYWludEV2ZW50ID0gdGhlRXZlbnQ7CisJCQlHQyBnYyA9IEdDLmNhcmJvbl9uZXcgKHRoaXMsIGRhdGEpOworCQkJZ2MuZHJhd0ltYWdlIChpbWFnZSwgMCwgMCk7CisJCQlnYy5kaXNwb3NlICgpOwogCQl9Ci0JCQotCQlpZiAoYm9yZGVyV2lkdGggPiAwKSB7Ci0JCQlnYy5zZXRGb3JlZ3JvdW5kKGdldERpc3BsYXkoKS5nZXRTeXN0ZW1Db2xvcihTV1QuQ09MT1JfR1JBWSkpOwotCQkJZ2MuZHJhd1JlY3RhbmdsZSgwLCAwLCB3LTEsIGgtMSk7Ci0JCX0KLQkJCi0JCS8vIEFXOiBkZWJ1Z2dpbmcKLQkJLy9nYy5kcmF3UmVjdGFuZ2xlKDAsIDAsIHIud2lkdGgtMSwgci5oZWlnaHQtMSk7CisJCXJldHVybiBPUy5ub0VycjsKIAl9Ci0JCi0JZ2MuY2FyYm9uX3VuZm9jdXMoKTsKLQlnYy5kaXNwb3NlKCk7Ci0JCi0JcmV0dXJuIDA7CisJcmV0dXJuIHJlc3VsdDsKIH0KLXZvaWQgcHJvcGFnYXRlV2lkZ2V0IChib29sZWFuIGVuYWJsZWQpIHsKLQlzdXBlci5wcm9wYWdhdGVXaWRnZXQgKGVuYWJsZWQpOwotCS8qCi0JKiBMYWJlbHMgbmV2ZXIgcGFydGljaXBhdGUgaW4gZm9jdXMgdHJhdmVyc2FsIHdoZW4KLQkqIGVpdGhlciBlbmFibGVkIG9yIGRpc2FibGVkLgotCSovCi0JLyogQVcKLQlpZiAoZW5hYmxlZCkgewotCQlpbnQgW10gYXJnTGlzdCA9IHtPUy5YbU50cmF2ZXJzYWxPbiwgMH07Ci0JCU9TLlh0U2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JfQotCSovCi19Ci12b2lkIHJlbGVhc2VXaWRnZXQgKCkgewotCXN1cGVyLnJlbGVhc2VXaWRnZXQgKCk7Ci0JaWYgKGRpc2FibGVkICE9IG51bGwpIGRpc2FibGVkLmRpc3Bvc2UgKCk7Ci0JaW1hZ2UgPSBkaXNhYmxlZCA9IG51bGw7Ci19Ci0vKiBBVwotaW50IHNlcGFyYXRvclR5cGUgKCkgewotCWlmICgoc3R5bGUgJiAoU1dULlNIQURPV19JTikpICE9IDApIHJldHVybiBPUy5YbVNIQURPV19FVENIRURfSU47Ci0JaWYgKChzdHlsZSAmIChTV1QuU0hBRE9XX09VVCkpICE9IDApIHJldHVybiBPUy5YbVNIQURPV19FVENIRURfT1VUOwotCXJldHVybiBPUy5YbVNIQURPV19FVENIRURfSU47Ci19Ci0qLwotLyoqCi0gKiBDb250cm9scyBob3cgdGV4dCBhbmQgaW1hZ2VzIHdpbGwgYmUgZGlzcGxheWVkIGluIHRoZSByZWNlaXZlci4KLSAqIFRoZSBhcmd1bWVudCBzaG91bGQgYmUgb25lIG9mIDxjb2RlPkxFRlQ8L2NvZGU+LCA8Y29kZT5SSUdIVDwvY29kZT4KLSAqIG9yIDxjb2RlPkNFTlRFUjwvY29kZT4uICBJZiB0aGUgcmVjZWl2ZXIgaXMgYSA8Y29kZT5TRVBBUkFUT1I8L2NvZGU+Ci0gKiBsYWJlbCwgdGhlIGFyZ3VtZW50IGlzIGlnbm9yZWQgYW5kIHRoZSBhbGlnbm1lbnQgaXMgbm90IGNoYW5nZWQuCi0gKgotICogQHBhcmFtIGFsaWdubWVudCB0aGUgbmV3IGFsaWdubWVudCAKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0QWxpZ25tZW50IChpbnQgYWxpZ25tZW50KSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoKHN0eWxlICYgU1dULlNFUEFSQVRPUikgIT0gMCkgcmV0dXJuOwotCWludCBtYXNrPSBTV1QuTEVGVCB8IFNXVC5DRU5URVIgfCBTV1QuUklHSFQ7Ci0JaW50IG5ld0FsaWdubWVudD0gYWxpZ25tZW50ICYgbWFzazsKLQlpbnQgY3VycmVudEFsaWdubWVudD0gc3R5bGUgJiBtYXNrOwotCWlmIChjdXJyZW50QWxpZ25tZW50ICE9IG5ld0FsaWdubWVudCkgewotCQlzdHlsZSAmPSB+bWFzazsKLQkJc3R5bGUgfD0gbmV3QWxpZ25tZW50OwotCQlyZWRyYXdXaWRnZXQgKDAsIDAsIDAsIDAsIGZhbHNlKTsKLQl9CiB9Ci1wdWJsaWMgdm9pZCBzZXRCb3VuZHMgKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7Ci0Jc3VwZXIuc2V0Qm91bmRzICh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKLQlpZiAoKHN0eWxlICYgU1dULldSQVApICE9IDApIHNldFRleHQgKHRleHQpOwotfQotcHVibGljIHZvaWQgc2V0Rm9udCAoRm9udCBmb250KSB7Ci0Jc3VwZXIuc2V0Rm9udCAoZm9udCk7Ci0JaWYgKChzdHlsZSAmIFNXVC5XUkFQKSAhPSAwKSBzZXRUZXh0ICh0ZXh0KTsKLX0KLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBpbWFnZSB0byB0aGUgYXJndW1lbnQsIHdoaWNoIG1heSBiZQotICogbnVsbCBpbmRpY2F0aW5nIHRoYXQgbm8gaW1hZ2Ugc2hvdWxkIGJlIGRpc3BsYXllZC4KLSAqCi0gKiBAcGFyYW0gaW1hZ2UgdGhlIGltYWdlIHRvIGRpc3BsYXkgb24gdGhlIHJlY2VpdmVyIChtYXkgYmUgbnVsbCkKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9BUkdVTUVOVCAtIGlmIHRoZSBpbWFnZSBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+IAotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRJbWFnZSAoSW1hZ2UgaW1hZ2UpIHsKIAljaGVja1dpZGdldCgpOworCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSByZXR1cm47CiAJdGhpcy5pbWFnZSA9IGltYWdlOwotCWlmIChkaXNhYmxlZCAhPSBudWxsKSBkaXNhYmxlZC5kaXNwb3NlICgpOwotCWRpc2FibGVkID0gbnVsbDsKLQlpZiAoaW1hZ2UgIT0gbnVsbCAmJiBpbWFnZS5pc0Rpc3Bvc2VkKCkpIGVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKLQlyZWRyYXdXaWRnZXQgKDAsIDAsIDAsIDAsIGZhbHNlKTsKKwlpc0ltYWdlID0gdHJ1ZTsKKwlyZWRyYXcgKCk7CiB9Ci1wdWJsaWMgdm9pZCBzZXRTaXplIChpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKLQlzdXBlci5zZXRTaXplICh3aWR0aCwgaGVpZ2h0KTsKLQlpZiAoKHN0eWxlICYgU1dULldSQVApICE9IDApIHNldFRleHQgKHRleHQpOwotfQotLyoqCi0gKiBTZXRzIHRoZSByZWNlaXZlcidzIHRleHQuCi0gKiA8cD4KLSAqIFRoaXMgbWV0aG9kIHNldHMgdGhlIHdpZGdldCBsYWJlbC4gIFRoZSBsYWJlbCBtYXkgaW5jbHVkZQotICogdGhlIG1uZW1vbmljIGNoYXJhY3RlcnMgYW5kIGxpbmUgZGVsaW1pdGVycy4KLSAqIDwvcD4KLSAqIAotICogQHBhcmFtIHN0cmluZyB0aGUgbmV3IHRleHQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSB0ZXh0IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRUZXh0IChTdHJpbmcgc3RyaW5nKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoc3RyaW5nID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaWYgKChzdHlsZSAmIFNXVC5TRVBBUkFUT1IpICE9IDApIHJldHVybjsKKwlpc0ltYWdlID0gZmFsc2U7CiAJdGV4dCA9IHN0cmluZzsKLQotCS8qIFN0cmlwIG91dCBtbmVtb25pYyBtYXJrZXIgc3ltYm9scywgYW5kIHJlbWVtYmVyIHRoZSBtbmVtb25pYy4gKi8KLQljaGFyIFtdIHVuaWNvZGUgPSBuZXcgY2hhciBbc3RyaW5nLmxlbmd0aCAoKV07Ci0Jc3RyaW5nLmdldENoYXJzICgwLCB1bmljb2RlLmxlbmd0aCwgdW5pY29kZSwgMCk7Ci0JaW50IGk9MCwgaj0wLCBtbmVtb25pYz0wOwotCXdoaWxlIChpIDwgdW5pY29kZS5sZW5ndGgpIHsKLQkJaWYgKCh1bmljb2RlIFtqKytdID0gdW5pY29kZSBbaSsrXSkgPT0gTW5lbW9uaWMpIHsKLQkJCWlmIChpID09IHVuaWNvZGUubGVuZ3RoKSB7Y29udGludWU7fQotCQkJaWYgKHVuaWNvZGUgW2ldID09IE1uZW1vbmljKSB7aSsrOyBjb250aW51ZTt9Ci0JCQlpZiAobW5lbW9uaWMgPT0gMCkgbW5lbW9uaWMgPSB1bmljb2RlIFtpXTsKKwljaGFyIFtdIGJ1ZmZlciA9IG5ldyBjaGFyIFt0ZXh0Lmxlbmd0aCAoKV07CisJdGV4dC5nZXRDaGFycyAoMCwgYnVmZmVyLmxlbmd0aCwgYnVmZmVyLCAwKTsKKwlpbnQgaT0wLCBqPTA7CisJd2hpbGUgKGkgPCBidWZmZXIubGVuZ3RoKSB7CisJCWlmICgoYnVmZmVyIFtqKytdID0gYnVmZmVyIFtpKytdKSA9PSBNbmVtb25pYykgeworCQkJaWYgKGkgPT0gYnVmZmVyLmxlbmd0aCkge2NvbnRpbnVlO30KKwkJCWlmIChidWZmZXIgW2ldID09IE1uZW1vbmljKSB7aSsrOyBjb250aW51ZTt9CiAJCQlqLS07CiAJCX0KIAl9Ci0Jd2hpbGUgKGogPCB1bmljb2RlLmxlbmd0aCkgdW5pY29kZSBbaisrXSA9IDA7Ci0KLQlyZWRyYXdXaWRnZXQgKDAsIDAsIDAsIDAsIGZhbHNlKTsKKwlpbnQgcHRyID0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgYnVmZmVyLCBqKTsKKwlpZiAocHRyID09IDApIGVycm9yIChTV1QuRVJST1JfQ0FOTk9UX1NFVF9URVhUKTsKKwlPUy5TZXRDb250cm9sRGF0YSAoaGFuZGxlLCAwICwgT1Mua0NvbnRyb2xTdGF0aWNUZXh0Q0ZTdHJpbmdUYWcsIDQsIG5ldyBpbnRbXXtwdHJ9KTsKKwlPUy5DRlJlbGVhc2UgKHB0cik7CisJcmVkcmF3ICgpOwogfQorCiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvTGlzdC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL0xpc3QuamF2YQppbmRleCAzZjA5OTYzLi5jYzgzYzk2IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvTGlzdC5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9MaXN0LmphdmEKQEAgLTcsMTY5ICs3LDU4IEBACiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCiAKLWltcG9ydCBqYXZhLnV0aWwuKjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLk9TOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uRGF0YUJyb3dzZXJDYWxsYmFja3M7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5EYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlJlY3Q7CiAKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOwogCi0vKiogCi0gKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyByZXByZXNlbnQgYSBzZWxlY3RhYmxlIHVzZXIgaW50ZXJmYWNlCi0gKiBvYmplY3QgdGhhdCBkaXNwbGF5cyBhIGxpc3Qgb2Ygc3RyaW5ncyBhbmQgaXNzdWVzIG5vdGlmaWNpYXRpb24KLSAqIHdoZW4gYSBzdHJpbmcgc2VsZWN0ZWQuICBBIGxpc3QgbWF5IGJlIHNpbmdsZSBvciBtdWx0aSBzZWxlY3QuCi0gKiA8cD4KLSAqIDxkbD4KLSAqIDxkdD48Yj5TdHlsZXM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+U0lOR0xFLCBNVUxUSTwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPlNlbGVjdGlvbiwgRGVmYXVsdFNlbGVjdGlvbjwvZGQ+Ci0gKiA8L2RsPgotICogPHA+Ci0gKiBOb3RlOiBPbmx5IG9uZSBvZiBTSU5HTEUgYW5kIE1VTFRJIG1heSBiZSBzcGVjaWZpZWQuCi0gKiA8L3A+PHA+Ci0gKiBJTVBPUlRBTlQ6IFRoaXMgY2xhc3MgaXMgPGVtPm5vdDwvZW0+IGludGVuZGVkIHRvIGJlIHN1YmNsYXNzZWQuCi0gKiA8L3A+Ci0gKi8KLXB1YmxpYyAvKmZpbmFsKi8gY2xhc3MgTGlzdCBleHRlbmRzIFNjcm9sbGFibGUgeworcHVibGljIGNsYXNzIExpc3QgZXh0ZW5kcyBTY3JvbGxhYmxlIHsKKwlTdHJpbmcgW10gaXRlbXM7CisJaW50IGl0ZW1Db3VudCwgYW5jaG9yRmlyc3QsIGFuY2hvckxhc3Q7CisJYm9vbGVhbiBpZ25vcmVTZWxlY3Q7CisJc3RhdGljIGZpbmFsIGludCBDT0xVTU5fSUQgPSAxMDI0OwogCi0JLy8gQVcKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQ09MX0lEPSAxMjM0NTsKLQlwcml2YXRlIEFycmF5TGlzdCBmRGF0YT0gbmV3IEFycmF5TGlzdCgpOwotCXByaXZhdGUgaW50IGZSb3dJRD0gMTAwMDsKLQkKLQlwcml2YXRlIGNsYXNzIFBhaXIgewotCQlpbnQgZklkOwotCQlTdHJpbmcgZlZhbHVlOwotCi0JCVBhaXIoU3RyaW5nIHYpIHsKLQkJCWZWYWx1ZT0gdjsKLQkJCWZJZD0gZlJvd0lEKys7Ci0JCX0KLQkJCi0JfQotCS8vIEFXCi0JCi0vKioKLSAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50Ci0gKiBhbmQgYSBzdHlsZSB2YWx1ZSBkZXNjcmliaW5nIGl0cyBiZWhhdmlvciBhbmQgYXBwZWFyYW5jZS4KLSAqIDxwPgotICogVGhlIHN0eWxlIHZhbHVlIGlzIGVpdGhlciBvbmUgb2YgdGhlIHN0eWxlIGNvbnN0YW50cyBkZWZpbmVkIGluCi0gKiBjbGFzcyA8Y29kZT5TV1Q8L2NvZGU+IHdoaWNoIGlzIGFwcGxpY2FibGUgdG8gaW5zdGFuY2VzIG9mIHRoaXMKLSAqIGNsYXNzLCBvciBtdXN0IGJlIGJ1aWx0IGJ5IDxlbT5iaXR3aXNlIE9SPC9lbT4naW5nIHRvZ2V0aGVyIAotICogKHRoYXQgaXMsIHVzaW5nIHRoZSA8Y29kZT5pbnQ8L2NvZGU+ICJ8IiBvcGVyYXRvcikgdHdvIG9yIG1vcmUKLSAqIG9mIHRob3NlIDxjb2RlPlNXVDwvY29kZT4gc3R5bGUgY29uc3RhbnRzLiBUaGUgY2xhc3MgZGVzY3JpcHRpb24KLSAqIGxpc3RzIHRoZSBzdHlsZSBjb25zdGFudHMgdGhhdCBhcmUgYXBwbGljYWJsZSB0byB0aGUgY2xhc3MuCi0gKiBTdHlsZSBiaXRzIGFyZSBhbHNvIGluaGVyaXRlZCBmcm9tIHN1cGVyY2xhc3Nlcy4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gcGFyZW50IGEgY29tcG9zaXRlIGNvbnRyb2wgd2hpY2ggd2lsbCBiZSB0aGUgcGFyZW50IG9mIHRoZSBuZXcgaW5zdGFuY2UgKGNhbm5vdCBiZSBudWxsKQotICogQHBhcmFtIHN0eWxlIHRoZSBzdHlsZSBvZiBjb250cm9sIHRvIGNvbnN0cnVjdAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTV1QjU0lOR0xFCi0gKiBAc2VlIFNXVCNNVUxUSQotICogQHNlZSBXaWRnZXQjY2hlY2tTdWJjbGFzcwotICogQHNlZSBXaWRnZXQjZ2V0U3R5bGUKLSAqLwogcHVibGljIExpc3QgKENvbXBvc2l0ZSBwYXJlbnQsIGludCBzdHlsZSkgewogCXN1cGVyIChwYXJlbnQsIGNoZWNrU3R5bGUgKHN0eWxlKSk7CiB9Ci0vKioKLSAqIEFkZHMgdGhlIGFyZ3VtZW50IHRvIHRoZSBlbmQgb2YgdGhlIHJlY2VpdmVyJ3MgbGlzdC4KLSAqCi0gKiBAcGFyYW0gc3RyaW5nIHRoZSBuZXcgaXRlbQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHN0cmluZyBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEVycm9yIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JVEVNX05PVF9BRERFRCAtIGlmIHRoZSBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNhZGQoU3RyaW5nLGludCkKLSAqLworCiBwdWJsaWMgdm9pZCBhZGQgKFN0cmluZyBzdHJpbmcpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChzdHJpbmcgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLSAgICBQYWlyIHA9IG5ldyBQYWlyKHN0cmluZyk7Ci0JZkRhdGEuYWRkKHApOwotCU9TLkFkZERhdGFCcm93c2VySXRlbXMoaGFuZGxlLCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0sIDEsIG5ldyBpbnRbXSB7IHAuZklkIH0sIDApOworCWludCBbXSBpZCA9IG5ldyBpbnQgW10ge2l0ZW1Db3VudCArIDF9OworCWlmIChPUy5BZGREYXRhQnJvd3Nlckl0ZW1zIChoYW5kbGUsIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSwgMSwgaWQsIDApICE9IE9TLm5vRXJyKSB7CisJCWVycm9yIChTV1QuRVJST1JfSVRFTV9OT1RfQURERUQpOworCX0KKwlpZiAoaXRlbUNvdW50ID09IGl0ZW1zLmxlbmd0aCkgeworCQlTdHJpbmcgW10gbmV3SXRlbXMgPSBuZXcgU3RyaW5nIFtpdGVtQ291bnQgKyA0XTsKKwkJU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIDAsIG5ld0l0ZW1zLCAwLCBpdGVtcy5sZW5ndGgpOworCQlpdGVtcyA9IG5ld0l0ZW1zOworCX0KKwlpdGVtcyBbaXRlbUNvdW50KytdID0gc3RyaW5nOwogfQotLyoqCi0gKiBBZGRzIHRoZSBhcmd1bWVudCB0byB0aGUgcmVjZWl2ZXIncyBsaXN0IGF0IHRoZSBnaXZlbgotICogemVyby1yZWxhdGl2ZSBpbmRleC4KLSAqIDxwPgotICogTm90ZTogVG8gYWRkIGFuIGl0ZW0gYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCwgdXNlIHRoZQotICogcmVzdWx0IG9mIGNhbGxpbmcgPGNvZGU+Z2V0SXRlbUNvdW50KCk8L2NvZGU+IGFzIHRoZQotICogaW5kZXggb3IgdXNlIDxjb2RlPmFkZChTdHJpbmcpPC9jb2RlPi4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gc3RyaW5nIHRoZSBuZXcgaXRlbQotICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBmb3IgdGhlIGl0ZW0KLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBzdHJpbmcgaXMgbnVsbDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9SQU5HRSAtIGlmIHRoZSBpbmRleCBpcyBub3QgYmV0d2VlbiAwIGFuZCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBsaXN0IChpbmNsdXNpdmUpPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEVycm9yIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JVEVNX05PVF9BRERFRCAtIGlmIHRoZSBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNhZGQoU3RyaW5nKQotICovCisKIHB1YmxpYyB2b2lkIGFkZCAoU3RyaW5nIHN0cmluZywgaW50IGluZGV4KSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoc3RyaW5nID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0JaWYgKGluZGV4ID09IC0xKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOwotCWludCBzaXplPSBmRGF0YS5zaXplKCk7Ci0JaWYgKCEoMCA8PSBpbmRleCAmJiBpbmRleCA8PSBzaXplKSkgewotCQllcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOwotCX0KLSAgICBQYWlyIHA9IG5ldyBQYWlyKHN0cmluZyk7Ci0JZkRhdGEuYWRkKGluZGV4LCBwKTsKLQlpZiAoT1MuQWRkRGF0YUJyb3dzZXJJdGVtcyhoYW5kbGUsIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSwgMSwgbmV3IGludFtdIHsgcC5mSWQgfSwgMCkgIT0gT1Mua05vRXJyKQorCWlmICghKDAgPD0gaW5kZXggJiYgaW5kZXggPD0gaXRlbUNvdW50KSkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1JBTkdFKTsKKwlpbnQgW10gaWQgPSBuZXcgaW50IFtdIHtpdGVtQ291bnQgKyAxfTsKKwlpZiAoT1MuQWRkRGF0YUJyb3dzZXJJdGVtcyAoaGFuZGxlLCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0sIDEsIGlkLCAwKSAhPSBPUy5ub0VycikgewogCQllcnJvciAoU1dULkVSUk9SX0lURU1fTk9UX0FEREVEKTsKKwl9CisJaWYgKGl0ZW1Db3VudCA9PSBpdGVtcy5sZW5ndGgpIHsKKwkJU3RyaW5nIFtdIG5ld0l0ZW1zID0gbmV3IFN0cmluZyBbaXRlbUNvdW50ICsgNF07CisJCVN5c3RlbS5hcnJheWNvcHkgKGl0ZW1zLCAwLCBuZXdJdGVtcywgMCwgaXRlbXMubGVuZ3RoKTsKKwkJaXRlbXMgPSBuZXdJdGVtczsKKwl9CisJU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIGluZGV4LCBpdGVtcywgaW5kZXggKyAxLCBpdGVtQ291bnQrKyAtIGluZGV4KTsKKwlpdGVtcyBbaW5kZXhdID0gc3RyaW5nOworCU9TLlVwZGF0ZURhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgMCwgMCwgbnVsbCwgT1Mua0RhdGFCcm93c2VySXRlbU5vUHJvcGVydHksIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSk7CiB9Ci0vKioKLSAqIEFkZHMgdGhlIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgcmVjZWl2ZXIncyBzZWxlY3Rpb24gY2hhbmdlcywgYnkgc2VuZGluZwotICogaXQgb25lIG9mIHRoZSBtZXNzYWdlcyBkZWZpbmVkIGluIHRoZSA8Y29kZT5TZWxlY3Rpb25MaXN0ZW5lcjwvY29kZT4KLSAqIGludGVyZmFjZS4KLSAqIDxwPgotICogPGNvZGU+d2lkZ2V0U2VsZWN0ZWQ8L2NvZGU+IGlzIGNhbGxlZCB3aGVuIHRoZSBzZWxlY3Rpb24gY2hhbmdlcy4KLSAqIDxjb2RlPndpZGdldERlZmF1bHRTZWxlY3RlZDwvY29kZT4gaXMgdHlwaWNhbGx5IGNhbGxlZCB3aGVuIGFuIGl0ZW0gaXMgZG91YmxlLWNsaWNrZWQuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTZWxlY3Rpb25MaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlU2VsZWN0aW9uTGlzdGVuZXIKLSAqIEBzZWUgU2VsZWN0aW9uRXZlbnQKLSAqLworCiBwdWJsaWMgdm9pZCBhZGRTZWxlY3Rpb25MaXN0ZW5lcihTZWxlY3Rpb25MaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC0xNzcsNjM5ICs2Niw0NjUgQEAKIAlhZGRMaXN0ZW5lcihTV1QuU2VsZWN0aW9uLHR5cGVkTGlzdGVuZXIpOwogCWFkZExpc3RlbmVyKFNXVC5EZWZhdWx0U2VsZWN0aW9uLHR5cGVkTGlzdGVuZXIpOwogfQorCiBzdGF0aWMgaW50IGNoZWNrU3R5bGUgKGludCBzdHlsZSkgewogCXJldHVybiBjaGVja0JpdHMgKHN0eWxlLCBTV1QuU0lOR0xFLCBTV1QuTVVMVEksIDAsIDAsIDAsIDApOwogfQorCiBwdWJsaWMgUG9pbnQgY29tcHV0ZVNpemUgKGludCB3SGludCwgaW50IGhIaW50LCBib29sZWFuIGNoYW5nZWQpIHsKIAljaGVja1dpZGdldCgpOwotICAgIC8qIEFXCi0JWHRXaWRnZXRHZW9tZXRyeSByZXN1bHQgPSBuZXcgWHRXaWRnZXRHZW9tZXRyeSAoKTsKLQlyZXN1bHQucmVxdWVzdF9tb2RlID0gT1MuQ1dXaWR0aDsKLQlPUy5YdFF1ZXJ5R2VvbWV0cnkgKGhhbmRsZSwgbnVsbCwgcmVzdWx0KTsKLQlpbnQgd2lkdGggPSByZXN1bHQud2lkdGgsIGhlaWdodCA9IDA7Ci0JKi8KLQlpbnQgd2lkdGggPSAzMDAsIGhlaWdodCA9IDA7Ci0JaWYgKHdIaW50ICE9IFNXVC5ERUZBVUxUKSB3aWR0aCA9IHdIaW50OwotCWlmIChoSGludCAhPSBTV1QuREVGQVVMVCkgaGVpZ2h0ID0gaEhpbnQ7Ci0JaWYgKGhIaW50ID09IFNXVC5ERUZBVUxUIHx8IHdIaW50ID09IFNXVC5ERUZBVUxUKSB7Ci0JCS8qIEFXCi0JCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTml0ZW1Db3VudCwgMH07Ci0JCU9TLlh0R2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JCWludCBjb3VudCA9IGFyZ0xpc3QgWzFdOwotCQkqLwotCQlpbnQgY291bnQgPSBmRGF0YS5zaXplKCk7Ci0JCWlmIChoSGludCA9PSBTV1QuREVGQVVMVCkgewotCQkJaWYgKGNvdW50ID09IDApIHsKLQkJCQloZWlnaHQgPSBERUZBVUxUX0hFSUdIVDsKLQkJCX0gZWxzZSB7Ci0JCQkJaGVpZ2h0ID0gZ2V0SXRlbUhlaWdodCAoKSAqIGNvdW50OwotCQkJfQorCWludCB3aWR0aCA9IDA7CisJaWYgKHdIaW50ID09IFNXVC5ERUZBVUxUKSB7CisJCUdDIGdjID0gbmV3IEdDICh0aGlzKTsKKwkJZm9yIChpbnQgaT0wOyBpPGl0ZW1Db3VudDsgaSsrKSB7CisJCQlQb2ludCBleHRlbnQgPSBnYy5zdHJpbmdFeHRlbnQgKGl0ZW1zIFtpXSk7CisJCQl3aWR0aCA9IE1hdGgubWF4ICh3aWR0aCwgZXh0ZW50LngpOwogCQl9Ci0JCWlmICh3SGludCA9PSBTV1QuREVGQVVMVCAmJiBjb3VudCA9PSAwKSB7Ci0JCQl3aWR0aCA9IERFRkFVTFRfV0lEVEg7Ci0JCX0KKwkJZ2MuZGlzcG9zZSAoKTsKKwl9IGVsc2UgeworCQl3aWR0aCA9IHdIaW50OwogCX0KKwlpZiAod2lkdGggPD0gMCkgd2lkdGggPSBERUZBVUxUX1dJRFRIOworCWludCBoZWlnaHQgPSAwOworCWlmIChoSGludCA9PSBTV1QuREVGQVVMVCkgeworCQloZWlnaHQgPSBpdGVtQ291bnQgKiBnZXRJdGVtSGVpZ2h0ICgpOworCX0gZWxzZSB7CisJCWhlaWdodCA9IGhIaW50OworCX0KKwlpZiAoaGVpZ2h0IDw9IDApIGhlaWdodCA9IERFRkFVTFRfSEVJR0hUOwogCVJlY3RhbmdsZSByZWN0ID0gY29tcHV0ZVRyaW0gKDAsIDAsIHdpZHRoLCBoZWlnaHQpOwogCXJldHVybiBuZXcgUG9pbnQgKHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTsKIH0KKwogcHVibGljIFJlY3RhbmdsZSBjb21wdXRlVHJpbSAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKIAljaGVja1dpZGdldCgpOwotCWludCBib3JkZXIgPSBnZXRCb3JkZXJXaWR0aCAoKTsKLQlpbnQgdHJpbVggPSB4IC0gYm9yZGVyOwotCWludCB0cmltWSA9IHkgLSBib3JkZXI7Ci0JaW50IHRyaW1XaWR0aCA9IHdpZHRoICsgKGJvcmRlciAqIDIpOwotCWludCB0cmltSGVpZ2h0ID0gaGVpZ2h0ICsgKGJvcmRlciAqIDIpOwotCURpc3BsYXkgZGlzcGxheT0gZ2V0RGlzcGxheSgpOwotCWlmIChob3Jpem9udGFsQmFyICE9IG51bGwpIHsKLQkJdHJpbUhlaWdodCArPSAxNTsKLQkJdHJpbVkgLT0gZGlzcGxheS5zY3JvbGxlZEluc2V0WTsKLQkJaWYgKHZlcnRpY2FsQmFyICE9IG51bGwpIHsKLQkJCXRyaW1YIC09IGRpc3BsYXkuc2Nyb2xsZWRJbnNldFg7Ci0JCX0KLSAJfQotCWlmICh2ZXJ0aWNhbEJhciAhPSBudWxsKSB7Ci0gCQl0cmltV2lkdGggKz0gMTU7Ci0JCXRyaW1YIC09IGRpc3BsYXkuc2Nyb2xsZWRJbnNldFg7Ci0JCWlmIChob3Jpem9udGFsQmFyICE9IG51bGwpIHsKLQkJCXRyaW1ZIC09IGRpc3BsYXkuc2Nyb2xsZWRJbnNldFk7Ci0JCX0KLQl9Ci0gICAgLyogQVcKLQlpbnQgW10gYXJnTGlzdCA9IHsKLQkJT1MuWG1OaGlnaGxpZ2h0VGhpY2tuZXNzLCAwLCAvLyAxCi0JCU9TLlhtTnNoYWRvd1RoaWNrbmVzcywgMCwgLy8gMwotCQlPUy5YbU5saXN0TWFyZ2luV2lkdGgsIDAsIC8vIDUKLQkJT1MuWG1ObGlzdE1hcmdpbkhlaWdodCwgMCAvLyA3Ci0JfTsKLQlPUy5YdEdldFZhbHVlcyAoaGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCWludCB0aGlja25lc3MgPSBhcmdMaXN0IFsxXSArIChhcmdMaXN0IFszXSAqIDIpOwotCXRyaW1XaWR0aCArPSB0aGlja25lc3MgKyBhcmdMaXN0IFs1XSArIDE7Ci0JdHJpbUhlaWdodCArPSB0aGlja25lc3MgKyBhcmdMaXN0IFs3XSArIDE7Ci0JdHJpbVggLT0gYXJnTGlzdCBbMV0gKyBhcmdMaXN0IFszXSArIGFyZ0xpc3QgWzVdOwotCXRyaW1ZIC09IGFyZ0xpc3QgWzFdICsgYXJnTGlzdCBbM10gKyBhcmdMaXN0IFs3XTsKLQkqLwotCXJldHVybiBuZXcgUmVjdGFuZ2xlICh0cmltWCwgdHJpbVksIHRyaW1XaWR0aCwgdHJpbUhlaWdodCk7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0RGF0YUJyb3dzZXJTY3JvbGxCYXJJbnNldCAoaGFuZGxlLCByZWN0KTsKKwl4IC09IHJlY3QubGVmdDsKKwl5IC09IHJlY3QudG9wOworCXdpZHRoICs9IChyZWN0LmxlZnQgKyByZWN0LnJpZ2h0KSAqIDM7CisJaGVpZ2h0ICs9IHJlY3QudG9wICsgcmVjdC5ib3R0b207CisJcmV0dXJuIG5ldyBSZWN0YW5nbGUgKHgsIHksIHdpZHRoLCBoZWlnaHQpOwogfQotdm9pZCBjcmVhdGVIYW5kbGUgKGludCBpbmRleCkgewotCXN0YXRlIHw9IEhBTkRMRTsKIAotCWludCBwYXJlbnRIYW5kbGUgPSBwYXJlbnQuaGFuZGxlOwotCWludCB3aW5kb3dIYW5kbGU9IE9TLkdldENvbnRyb2xPd25lcihwYXJlbnRIYW5kbGUpOwotCWhhbmRsZT0gT1MuY3JlYXRlRGF0YUJyb3dzZXJDb250cm9sKHdpbmRvd0hhbmRsZSk7Ci0JaWYgKGhhbmRsZSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOwotCU1hY1V0aWwuYWRkQ29udHJvbChoYW5kbGUsIHBhcmVudEhhbmRsZSk7Ci0JTWFjVXRpbC5pbml0TG9jYXRpb24oaGFuZGxlKTsKLQkKLQkvKiBTaW5nbGUgb3IgTXVsdGlwbGUgU2VsZWN0aW9uICovCi0JaW50IG1vZGU9IE9TLmtEYXRhQnJvd3NlclNlbGVjdE9ubHlPbmU7Ci0JaWYgKChzdHlsZSAmIFNXVC5NVUxUSSkgIT0gMCkKLQkJbW9kZT0gT1Mua0RhdGFCcm93c2VyRHJhZ1NlbGVjdCB8IE9TLmtEYXRhQnJvd3NlckNtZFRvZ2dsZXNTZWxlY3Rpb247Ci0JT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3Rpb25GbGFncyhoYW5kbGUsIG1vZGUpOwotCQotCS8qIGhpZGUgdGhlIG5lYWRlciAqLwotCU9TLlNldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJCdG5IZWlnaHQoaGFuZGxlLCAoc2hvcnQpIDApOwotCQotCS8qIGVuYWJsZSBzY3JvbGxiYXJzICovCi0JT1MuU2V0RGF0YUJyb3dzZXJIYXNTY3JvbGxCYXJzKGhhbmRsZSwgKHN0eWxlICYgU1dULkhfU0NST0xMKSAhPSAwLCAoc3R5bGUgJiBTV1QuVl9TQ1JPTEwpICE9IDApOwotCWlmICgoc3R5bGUgJiBTV1QuSF9TQ1JPTEwpID09IDApCi0JCU9TLkF1dG9TaXplRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbnMoaGFuZGxlKTsKLQkJCi0JaW50IGNvbHVtbkRlc2M9IE9TLm5ld0NvbHVtbkRlc2MoQ09MX0lELCBPUy5rRGF0YUJyb3dzZXJUZXh0VHlwZSwKLQkJCQkJT1Mua0RhdGFCcm93c2VyTGlzdFZpZXdTZWxlY3Rpb25Db2x1bW4gfCBPUy5rRGF0YUJyb3dzZXJEZWZhdWx0UHJvcGVydHlGbGFncywKLQkJCQkJKHNob3J0KTAsIChzaG9ydCkyMDAwKTsKLQlPUy5BZGREYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uKGhhbmRsZSwgY29sdW1uRGVzYywgMTAwMDApOwordm9pZCBjcmVhdGVIYW5kbGUgKCkgeworCWludCBbXSBvdXRDb250cm9sID0gbmV3IGludCBbMV07CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAocGFyZW50LmhhbmRsZSk7CisJT1MuQ3JlYXRlRGF0YUJyb3dzZXJDb250cm9sICh3aW5kb3csIG51bGwsIE9TLmtEYXRhQnJvd3Nlckxpc3RWaWV3LCBvdXRDb250cm9sKTsKKwlpZiAob3V0Q29udHJvbCBbMF0gPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwloYW5kbGUgPSBvdXRDb250cm9sIFswXTsKKwlpbnQgc2VsZWN0aW9uRmxhZ3MgPSAoc3R5bGUgJiBTV1QuU0lOR0xFKSAhPSAwID8gT1Mua0RhdGFCcm93c2VyU2VsZWN0T25seU9uZSA6IE9TLmtEYXRhQnJvd3NlckNtZFRvZ2dsZXNTZWxlY3Rpb247CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3Rpb25GbGFncyAoaGFuZGxlLCBzZWxlY3Rpb25GbGFncyk7CisJT1MuU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckJ0bkhlaWdodCAoaGFuZGxlLCAoc2hvcnQpIDApOworCU9TLlNldERhdGFCcm93c2VySGFzU2Nyb2xsQmFycyAoaGFuZGxlLCAoc3R5bGUgJiBTV1QuSF9TQ1JPTEwpICE9IDAsIChzdHlsZSAmIFNXVC5WX1NDUk9MTCkgIT0gMCk7CisJLy9OT1QgRE9ORQorCWlmICgoc3R5bGUgJiBTV1QuSF9TQ1JPTEwpID09IDApIE9TLkF1dG9TaXplRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbnMgKGhhbmRsZSk7CisJRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2MgY29sdW1uID0gbmV3IERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjICgpOworCWNvbHVtbi5oZWFkZXJCdG5EZXNjX3ZlcnNpb24gPSBPUy5rRGF0YUJyb3dzZXJMaXN0Vmlld0xhdGVzdEhlYWRlckRlc2M7CisJY29sdW1uLnByb3BlcnR5RGVzY19wcm9wZXJ0eUlEID0gQ09MVU1OX0lEOworCWNvbHVtbi5wcm9wZXJ0eURlc2NfcHJvcGVydHlUeXBlID0gT1Mua0RhdGFCcm93c2VyVGV4dFR5cGU7CisJY29sdW1uLnByb3BlcnR5RGVzY19wcm9wZXJ0eUZsYWdzID0gT1Mua0RhdGFCcm93c2VyTGlzdFZpZXdTZWxlY3Rpb25Db2x1bW4gfCBPUy5rRGF0YUJyb3dzZXJEZWZhdWx0UHJvcGVydHlGbGFnczsKKwkvL05PVCBET05FCisJY29sdW1uLmhlYWRlckJ0bkRlc2NfbWF4aW11bVdpZHRoPSAweDdGRkY7CisJY29sdW1uLmhlYWRlckJ0bkRlc2NfaW5pdGlhbE9yZGVyPSBPUy5rRGF0YUJyb3dzZXJPcmRlckluY3JlYXNpbmc7CisJT1MuQWRkRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbiAoaGFuZGxlLCBjb2x1bW4sIDApOworCS8vTk9UIERPTkUKKwlPUy5TZXREYXRhQnJvd3NlclRhYmxlVmlld05hbWVkQ29sdW1uV2lkdGggKGhhbmRsZSwgQ09MVU1OX0lELCAoc2hvcnQpODAwKTsKKworCS8qCisJKiBGZWF0dXJlIGluIHRoZSBNYWNpbnRvc2guICBTY3JvbGwgYmFycyBhcmUgbm90IGNyZWF0ZWQgdW50aWwKKwkqIHRoZSB3aWRnZXQgaGFzIGEgbWluaW11bSBzaXplLiAgVGhlIGZpeCBpcyB0byBmb3JjZSB0aGUgc2Nyb2xsCisJKiBiYXJzIHRvIGJlIGNyZWF0ZWQgYnkgdGVtcG9yYXJpbHkgZ2l2aW5nIHRoZSB3aWRnZXQgYSBzaXplIGFuZAorCSogdGhlbiByZXN0b3JpbmcgaXQgdG8gemVyby4KKwkqIAorCSogTk9URTogVGhlIHdpZGdldCBtdXN0IGJlIHZpc2libGUgYW5kIFNpemVDb250cm9sKCkgbXVzdCBiZSB1c2VkCisJKiB0byByZXNpemUgdGhlIHdpZGdldCB0byBhIG1pbmltaW0gc2l6ZSBvciB0aGUgd2lkZ2V0IHdpbGwgbm90CisJKiBjcmVhdGUgdGhlIHNjcm9sbCBiYXJzLiAgVGhpcyB3b3JrIGFyb3VuZCBjdXJyZW50bHkgZmxhc2hlcy4KKwkqLworCU9TLlNpemVDb250cm9sIChoYW5kbGUsIChzaG9ydCkgMHhGRiwgKHNob3J0KSAweEZGKTsKKwlPUy5TaXplQ29udHJvbCAoaGFuZGxlLCAoc2hvcnQpIDAsIChzaG9ydCkgMCk7CiB9Ci1TY3JvbGxCYXIgY3JlYXRlU2Nyb2xsQmFyIChpbnQgdHlwZSkgewotCXJldHVybiBjcmVhdGVTdGFuZGFyZEJhciAodHlwZSk7CisKK3ZvaWQgY3JlYXRlV2lkZ2V0ICgpIHsKKwlzdXBlci5jcmVhdGVXaWRnZXQgKCk7CisJaXRlbXMgPSBuZXcgU3RyaW5nIFs0XTsKIH0KLS8qIEFXCi1pbnQgZGVmYXVsdEJhY2tncm91bmQgKCkgewotCXJldHVybiBnZXREaXNwbGF5ICgpLmxpc3RCYWNrZ3JvdW5kOworCitTY3JvbGxCYXIgY3JlYXRlU2Nyb2xsQmFyIChpbnQgc3R5bGUpIHsKKwlyZXR1cm4gY3JlYXRlU3RhbmRhcmRCYXIgKHN0eWxlKTsKIH0KLWludCBkZWZhdWx0Rm9udCAoKSB7Ci0JcmV0dXJuIGdldERpc3BsYXkgKCkubGlzdEZvbnQ7CisKK2ludCBkZWZhdWx0VGhlbWVGb250ICgpIHsJCisJcmV0dXJuIE9TLmtUaGVtZVZpZXdzRm9udDsKIH0KLWludCBkZWZhdWx0Rm9yZWdyb3VuZCAoKSB7Ci0JcmV0dXJuIGdldERpc3BsYXkgKCkubGlzdEZvcmVncm91bmQ7Ci19Ci0qLwotLyoqCi0gKiBEZXNlbGVjdHMgdGhlIGl0ZW0gYXQgdGhlIGdpdmVuIHplcm8tcmVsYXRpdmUgaW5kZXggaW4gdGhlIHJlY2VpdmVyLgotICogSWYgdGhlIGl0ZW0gYXQgdGhlIGluZGV4IHdhcyBhbHJlYWR5IGRlc2VsZWN0ZWQsIGl0IHJlbWFpbnMKLSAqIGRlc2VsZWN0ZWQuIEluZGljZXMgdGhhdCBhcmUgb3V0IG9mIHJhbmdlIGFyZSBpZ25vcmVkLgotICoKLSAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIGl0ZW0gdG8gZGVzZWxlY3QKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgZGVzZWxlY3QgKGludCBpbmRleCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0gICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCBmRGF0YS5zaXplKCkpIHsKLSAgICAJUGFpciBwPSAoUGFpcikgZkRhdGEuZ2V0KGluZGV4KTsKLSAgICAJaWYgKHAgIT0gbnVsbCkKLQkJCU9TLlNldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyhoYW5kbGUsIDEsIG5ldyBpbnRbXSB7IHAuZklkIH0sIE9TLmtEYXRhQnJvd3Nlckl0ZW1zUmVtb3ZlKTsKLSAgICB9CisJaWYgKDAgPCBpbmRleCAmJiBpbmRleCA8IGl0ZW1Db3VudCkgeworCQlpZ25vcmVTZWxlY3QgPSB0cnVlOworCQlpbnQgW10gaWQgPSBuZXcgaW50IFtdIHtpbmRleCArIDF9OworCQlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMgKGhhbmRsZSwgaWQubGVuZ3RoLCBpZCwgT1Mua0RhdGFCcm93c2VySXRlbXNSZW1vdmUpOworCQlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKKwl9CiB9Ci0vKioKLSAqIERlc2VsZWN0cyB0aGUgaXRlbXMgYXQgdGhlIGdpdmVuIHplcm8tcmVsYXRpdmUgaW5kaWNlcyBpbiB0aGUgcmVjZWl2ZXIuCi0gKiBJZiB0aGUgaXRlbSBhdCB0aGUgZ2l2ZW4gemVyby1yZWxhdGl2ZSBpbmRleCBpbiB0aGUgcmVjZWl2ZXIgCi0gKiBpcyBzZWxlY3RlZCwgaXQgaXMgZGVzZWxlY3RlZC4gIElmIHRoZSBpdGVtIGF0IHRoZSBpbmRleAotICogd2FzIG5vdCBzZWxlY3RlZCwgaXQgcmVtYWlucyBkZXNlbGVjdGVkLiAgVGhlIHJhbmdlIG9mIHRoZQotICogaW5kaWNlcyBpcyBpbmNsdXNpdmUuIEluZGljZXMgdGhhdCBhcmUgb3V0IG9mIHJhbmdlIGFyZSBpZ25vcmVkLgotICoKLSAqIEBwYXJhbSBzdGFydCB0aGUgc3RhcnQgaW5kZXggb2YgdGhlIGl0ZW1zIHRvIGRlc2VsZWN0Ci0gKiBAcGFyYW0gZW5kIHRoZSBlbmQgaW5kZXggb2YgdGhlIGl0ZW1zIHRvIGRlc2VsZWN0Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIGRlc2VsZWN0IChpbnQgc3RhcnQsIGludCBlbmQpIHsKIAljaGVja1dpZGdldCgpOwotCWlmIChzdGFydCA+IGVuZCkgcmV0dXJuOwotCWludFtdIGlkcz0gZ2V0SWRzKHN0YXJ0LCBlbmQpOwotCU9TLlNldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyhoYW5kbGUsIGlkcy5sZW5ndGgsIGlkcywgT1Mua0RhdGFCcm93c2VySXRlbXNSZW1vdmUpOworCS8vTk9UIERPTkUgLSByYW5nZSBjaGVjaworCWludCBsZW5ndGggPSBlbmQgLSBzdGFydCArIDE7CisJaWYgKGxlbmd0aCA8PSAwKSByZXR1cm47CisJaW50IFtdIGlkcyA9IG5ldyBpbnQgW2xlbmd0aF07CisJZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSBpZHMgW2ldID0gZW5kIC0gaSArIDE7CisJaWdub3JlU2VsZWN0ID0gdHJ1ZTsKKwlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMgKGhhbmRsZSwgbGVuZ3RoLCBpZHMsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zUmVtb3ZlKTsKKwlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKIH0KLS8qKgotICogRGVzZWxlY3RzIHRoZSBpdGVtcyBhdCB0aGUgZ2l2ZW4gemVyby1yZWxhdGl2ZSBpbmRpY2VzIGluIHRoZSByZWNlaXZlci4KLSAqIElmIHRoZSBpdGVtIGF0IHRoZSBnaXZlbiB6ZXJvLXJlbGF0aXZlIGluZGV4IGluIHRoZSByZWNlaXZlciAKLSAqIGlzIHNlbGVjdGVkLCBpdCBpcyBkZXNlbGVjdGVkLiAgSWYgdGhlIGl0ZW0gYXQgdGhlIGluZGV4Ci0gKiB3YXMgbm90IHNlbGVjdGVkLCBpdCByZW1haW5zIGRlc2VsZWN0ZWQuIEluZGljZXMgdGhhdCBhcmUgb3V0Ci0gKiBvZiByYW5nZSBhbmQgZHVwbGljYXRlIGluZGljZXMgYXJlIGlnbm9yZWQuCi0gKgotICogQHBhcmFtIGluZGljZXMgdGhlIGFycmF5IG9mIGluZGljZXMgZm9yIHRoZSBpdGVtcyB0byBkZXNlbGVjdAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBkZXNlbGVjdCAoaW50IFtdIGluZGljZXMpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChpbmRpY2VzID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0JaW50W10gaWRzPSBnZXRJZHMoaW5kaWNlcyk7Ci0JT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zKGhhbmRsZSwgaWRzLmxlbmd0aCwgaWRzLCBPUy5rRGF0YUJyb3dzZXJJdGVtc1JlbW92ZSk7CisJLy9OT1QgRE9ORSAtIHJhbmdlIGNoZWNrCisJaW50IGxlbmd0aCA9IGluZGljZXMubGVuZ3RoOworCWludCBbXSBpZHMgPSBuZXcgaW50IFtsZW5ndGhdOworCWZvciAoaW50IGk9MDsgaTxsZW5ndGg7IGkrKykgaWRzIFtpXSA9IGluZGljZXMgW2xlbmd0aCAtIGkgLSAxXSArIDE7CisJaWdub3JlU2VsZWN0ID0gdHJ1ZTsKKwlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMgKGhhbmRsZSwgbGVuZ3RoLCBpZHMsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zUmVtb3ZlKTsKKwlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKIH0KLS8qKgotICogRGVzZWxlY3RzIGFsbCBzZWxlY3RlZCBpdGVtcyBpbiB0aGUgcmVjZWl2ZXIuCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIGRlc2VsZWN0QWxsICgpIHsKLQljaGVja1dpZGdldCgpOwotCWludCBuPSBmRGF0YS5zaXplKCk7Ci0JaWYgKG4gPD0gMCkgcmV0dXJuOwotCWludFtdIGlkcz0gZ2V0SWRzKDAsIG4tMSk7Ci0JT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zKGhhbmRsZSwgaWRzLmxlbmd0aCwgaWRzLCBPUy5rRGF0YUJyb3dzZXJJdGVtc1JlbW92ZSk7CisJY2hlY2tXaWRnZXQgKCk7CisJaWdub3JlU2VsZWN0ID0gdHJ1ZTsKKwlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMgKGhhbmRsZSwgMCwgbnVsbCwgT1Mua0RhdGFCcm93c2VySXRlbXNSZW1vdmUpOworCWlnbm9yZVNlbGVjdCA9IGZhbHNlOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSB6ZXJvLXJlbGF0aXZlIGluZGV4IG9mIHRoZSBpdGVtIHdoaWNoIGlzIGN1cnJlbnRseQotICogaGFzIHRoZSBmb2N1cyBpbiB0aGUgcmVjZWl2ZXIsIG9yIC0xIGlmIG5vIGl0ZW0gaXMgaGFzIGZvY3VzLgotICoKLSAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBzZWxlY3RlZCBpdGVtCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKK3B1YmxpYyBSZWN0YW5nbGUgZ2V0Q2xpZW50QXJlYSAoKSB7CisJY2hlY2tXaWRnZXQoKTsKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKSwgaW5zZXQgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChoYW5kbGUsIHJlY3QpOworCU9TLkdldERhdGFCcm93c2VyU2Nyb2xsQmFySW5zZXQgKGhhbmRsZSwgaW5zZXQpOworCXJldHVybiBuZXcgUmVjdGFuZ2xlIChpbnNldC5sZWZ0LCBpbnNldC50b3AsIHJlY3QucmlnaHQgLSByZWN0LmxlZnQgKyBpbnNldC5yaWdodCwgcmVjdC5ib3R0b20gLSByZWN0LnRvcCArIGluc2V0LmJvdHRvbSk7Cit9CisKIHB1YmxpYyBpbnQgZ2V0Rm9jdXNJbmRleCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLSAgICAvKiBBVwotCXJldHVybiBPUy5YbUxpc3RHZXRLYmRJdGVtUG9zIChoYW5kbGUpIC0gMTsKLSAgICAqLwotICAgIHJldHVybiAtMTsKKwlpbnQgW10gZmlyc3QgPSBuZXcgaW50IFsxXSwgbGFzdCA9IG5ldyBpbnQgWzFdOworCWlmIChPUy5HZXREYXRhQnJvd3NlclNlbGVjdGlvbkFuY2hvciAoaGFuZGxlLCBmaXJzdCwgbGFzdCkgIT0gT1Mubm9FcnIpIHJldHVybiAtMTsKKyAgICByZXR1cm4gZmlyc3QgWzBdIC0gMTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgaXRlbSBhdCB0aGUgZ2l2ZW4sIHplcm8tcmVsYXRpdmUgaW5kZXggaW4gdGhlCi0gKiByZWNlaXZlci4gVGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIHJhbmdlLgotICoKLSAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIGl0ZW0gdG8gcmV0dXJuCi0gKiBAcmV0dXJuIHRoZSBpdGVtIGF0IHRoZSBnaXZlbiBpbmRleAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1JBTkdFIC0gaWYgdGhlIGluZGV4IGlzIG5vdCBiZXR3ZWVuIDAgYW5kIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGxpc3QgbWludXMgMSAoaW5jbHVzaXZlKTwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfQ0FOTk9UX0dFVF9JVEVNIC0gaWYgdGhlIG9wZXJhdGlvbiBmYWlscyBiZWNhdXNlIG9mIGFuIG9wZXJhdGluZyBzeXN0ZW0gZmFpbHVyZTwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBTdHJpbmcgZ2V0SXRlbSAoaW50IGluZGV4KSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpbnQgc2l6ZT0gZkRhdGEuc2l6ZSgpOwotCWlmICghKDAgPD0gaW5kZXggJiYgaW5kZXggPCBzaXplKSkKLQkJZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1JBTkdFKTsKLQlQYWlyIHA9IChQYWlyKSBmRGF0YS5nZXQoaW5kZXgpOwotCXJldHVybiBwLmZWYWx1ZTsKKwlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbUNvdW50KSkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1JBTkdFKTsKKwlyZXR1cm4gaXRlbXMgW2luZGV4XTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGl0ZW1zIGNvbnRhaW5lZCBpbiB0aGUgcmVjZWl2ZXIuCi0gKgotICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGl0ZW1zCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfQ0FOTk9UX0dFVF9DT1VOVCAtIGlmIHRoZSBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldEl0ZW1Db3VudCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlyZXR1cm4gZkRhdGEuc2l6ZSgpOworCXJldHVybiBpdGVtQ291bnQ7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIGhlaWdodCBvZiB0aGUgYXJlYSB3aGljaCB3b3VsZCBiZSB1c2VkIHRvCi0gKiBkaXNwbGF5IDxlbT5vbmU8L2VtPiBvZiB0aGUgaXRlbXMgaW4gdGhlIHRyZWUuCi0gKgotICogQHJldHVybiB0aGUgaGVpZ2h0IG9mIG9uZSBpdGVtCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfQ0FOTk9UX0dFVF9JVEVNX0hFSUdIVCAtIGlmIHRoZSBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldEl0ZW1IZWlnaHQgKCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0gICAgcmV0dXJuIDE1OwkvLyBBVyBGSVhNRQorCWNoZWNrV2lkZ2V0ICgpOworCXNob3J0IFtdIGhlaWdodCA9IG5ldyBzaG9ydCBbMV07CisJaWYgKE9TLkdldERhdGFCcm93c2VyVGFibGVWaWV3Um93SGVpZ2h0IChoYW5kbGUsIGhlaWdodCkgIT0gT1Mubm9FcnIpIHsKKwkJZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfR0VUX0lURU1fSEVJR0hUKTsKKwl9CisJcmV0dXJuIGhlaWdodCBbMF07CiB9Ci0vKioKLSAqIFJldHVybnMgYW4gYXJyYXkgb2YgPGNvZGU+U3RyaW5nPC9jb2RlPnMgd2hpY2ggYXJlIHRoZSBpdGVtcwotICogaW4gdGhlIHJlY2VpdmVyLiAKLSAqIDxwPgotICogTm90ZTogVGhpcyBpcyBub3QgdGhlIGFjdHVhbCBzdHJ1Y3R1cmUgdXNlZCBieSB0aGUgcmVjZWl2ZXIKLSAqIHRvIG1haW50YWluIGl0cyBsaXN0IG9mIGl0ZW1zLCBzbyBtb2RpZnlpbmcgdGhlIGFycmF5IHdpbGwKLSAqIG5vdCBhZmZlY3QgdGhlIHJlY2VpdmVyLiAKLSAqIDwvcD4KLSAqCi0gKiBAcmV0dXJuIHRoZSBpdGVtcyBpbiB0aGUgcmVjZWl2ZXIncyBsaXN0Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfQ0FOTk9UX0dFVF9JVEVNIC0gaWYgdGhlIG9wZXJhdGlvbiBmYWlscyBiZWNhdXNlIG9mIGFuIG9wZXJhdGluZyBzeXN0ZW0gZmFpbHVyZSB3aGlsZSBnZXR0aW5nIGFuIGl0ZW08L2xpPgotICogICAgPGxpPkVSUk9SX0NBTk5PVF9HRVRfQ09VTlQgLSBpZiB0aGUgb3BlcmF0aW9uIGZhaWxzIGJlY2F1c2Ugb2YgYW4gb3BlcmF0aW5nIHN5c3RlbSBmYWlsdXJlIHdoaWxlIGdldHRpbmcgdGhlIGl0ZW0gY291bnQ8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgU3RyaW5nIFtdIGdldEl0ZW1zICgpIHsKIAljaGVja1dpZGdldCgpOwotICAgIFN0cmluZ1tdIHJlc3VsdD0gbmV3IFN0cmluZ1tmRGF0YS5zaXplKCldOwotICAgIEl0ZXJhdG9yIGl0ZXI9IGZEYXRhLml0ZXJhdG9yKCk7Ci0gICAgZm9yIChpbnQgaT0gMDsgaXRlci5oYXNOZXh0KCk7IGkrKykgewotICAgIAlQYWlyIHA9IChQYWlyKSBpdGVyLm5leHQoKTsKLSAgICAJcmVzdWx0W2ldPSBwLmZWYWx1ZTsKLSAgICB9CisgICAgU3RyaW5nIFtdIHJlc3VsdCA9IG5ldyBTdHJpbmcgW2l0ZW1Db3VudF07CisJU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIDAsIHJlc3VsdCwgMCwgaXRlbUNvdW50KTsKIAlyZXR1cm4gcmVzdWx0OwogfQotLyoqCi0gKiBSZXR1cm5zIGFuIGFycmF5IG9mIDxjb2RlPlN0cmluZzwvY29kZT5zIHRoYXQgYXJlIGN1cnJlbnRseQotICogc2VsZWN0ZWQgaW4gdGhlIHJlY2VpdmVyLiBBbiBlbXB0eSBhcnJheSBpbmRpY2F0ZXMgdGhhdCBubwotICogaXRlbXMgYXJlIHNlbGVjdGVkLgotICogPHA+Ci0gKiBOb3RlOiBUaGlzIGlzIG5vdCB0aGUgYWN0dWFsIHN0cnVjdHVyZSB1c2VkIGJ5IHRoZSByZWNlaXZlcgotICogdG8gbWFpbnRhaW4gaXRzIHNlbGVjdGlvbiwgc28gbW9kaWZ5aW5nIHRoZSBhcnJheSB3aWxsCi0gKiBub3QgYWZmZWN0IHRoZSByZWNlaXZlci4gCi0gKiA8L3A+Ci0gKiBAcmV0dXJuIGFuIGFycmF5IHJlcHJlc2VudGluZyB0aGUgc2VsZWN0aW9uCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfQ0FOTk9UX0dFVF9TRUxFQ1RJT04gLSBpZiB0aGUgb3BlcmF0aW9uIGZhaWxzIGJlY2F1c2Ugb2YgYW4gb3BlcmF0aW5nIHN5c3RlbSBmYWlsdXJlIHdoaWxlIGdldHRpbmcgdGhlIHNlbGVjdGlvbjwvbGk+Ci0gKiAgICA8bGk+RVJST1JfQ0FOTk9UX0dFVF9JVEVNIC0gaWYgdGhlIG9wZXJhdGlvbiBmYWlscyBiZWNhdXNlIG9mIGFuIG9wZXJhdGluZyBzeXN0ZW0gZmFpbHVyZSB3aGlsZSBnZXR0aW5nIGFuIGl0ZW08L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgU3RyaW5nIFtdIGdldFNlbGVjdGlvbiAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlpbnRbXSBpZHM9IE1hY1V0aWwuZ2V0U2VsZWN0aW9uSURzKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCBmYWxzZSk7Ci0JU3RyaW5nW10gcmVzdWx0PSBuZXcgU3RyaW5nW2lkcy5sZW5ndGhdOwotCWZvciAoaW50IGk9IDA7IGkgPCBpZHMubGVuZ3RoOyBpKyspCi0JCXJlc3VsdFtpXT0gZ2V0KGlkc1tpXSk7CisJY2hlY2tXaWRnZXQgKCk7CisJaW50IHB0ciA9IE9TLk5ld0hhbmRsZSAoMCk7CisJaWYgKE9TLkdldERhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCB0cnVlLCBPUy5rRGF0YUJyb3dzZXJJdGVtSXNTZWxlY3RlZCwgcHRyKSAhPSBPUy5ub0VycikgeworCQllcnJvciAoU1dULkVSUk9SX0NBTk5PVF9HRVRfU0VMRUNUSU9OKTsKKwl9CisJaW50IGNvdW50ID0gT1MuR2V0SGFuZGxlU2l6ZSAocHRyKSAvIDQ7CisJU3RyaW5nIFtdIHJlc3VsdCA9IG5ldyBTdHJpbmcgW2NvdW50XTsKKwlPUy5ITG9jayAocHRyKTsKKwlpbnQgW10gc3RhcnQgPSBuZXcgaW50IFsxXTsKKwlPUy5tZW1jcHkgKHN0YXJ0LCBwdHIsIDQpOworCWludCBbXSBpZCA9IG5ldyBpbnQgWzFdOworCWZvciAoaW50IGk9MDsgaTxjb3VudDsgaSsrKSB7CisJCU9TLm1lbWNweSAoaWQsIHN0YXJ0IFswXSArIChpICogNCksIDQpOworCQlyZXN1bHQgW2ldID0gaXRlbXMgW2lkIFswXSAtIDFdOworCX0KKwlPUy5IVW5sb2NrIChwdHIpOworCU9TLkRpc3Bvc2VIYW5kbGUgKHB0cik7CiAJcmV0dXJuIHJlc3VsdDsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHNlbGVjdGVkIGl0ZW1zIGNvbnRhaW5lZCBpbiB0aGUgcmVjZWl2ZXIuCi0gKgotICogQHJldHVybiB0aGUgbnVtYmVyIG9mIHNlbGVjdGVkIGl0ZW1zCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfQ0FOTk9UX0dFVF9DT1VOVCAtIGlmIHRoZSBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldFNlbGVjdGlvbkNvdW50ICgpIHsKLQljaGVja1dpZGdldCgpOwotCWludFtdIHJlc3VsdD0gbmV3IGludFsxXTsKLQlpZiAoT1MuR2V0RGF0YUJyb3dzZXJJdGVtQ291bnQoaGFuZGxlLCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0sIGZhbHNlLCBPUy5rRGF0YUJyb3dzZXJJdGVtSXNTZWxlY3RlZCwgcmVzdWx0KSAhPSBPUy5rTm9FcnIpCisJY2hlY2tXaWRnZXQgKCk7CisJaW50IFtdIGNvdW50ID0gbmV3IGludCBbMV07CisJaWYgKE9TLkdldERhdGFCcm93c2VySXRlbUNvdW50IChoYW5kbGUsIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSwgdHJ1ZSwgT1Mua0RhdGFCcm93c2VySXRlbUlzU2VsZWN0ZWQsIGNvdW50KSAhPSBPUy5ub0VycikgewogCQllcnJvciAoU1dULkVSUk9SX0NBTk5PVF9HRVRfQ09VTlQpOwotCXJldHVybiByZXN1bHRbMF07CisJfQorCXJldHVybiBjb3VudCBbMF07CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIHplcm8tcmVsYXRpdmUgaW5kZXggb2YgdGhlIGl0ZW0gd2hpY2ggaXMgY3VycmVudGx5Ci0gKiBzZWxlY3RlZCBpbiB0aGUgcmVjZWl2ZXIsIG9yIC0xIGlmIG5vIGl0ZW0gaXMgc2VsZWN0ZWQuCi0gKgotICogQHJldHVybiB0aGUgaW5kZXggb2YgdGhlIHNlbGVjdGVkIGl0ZW0KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEVycm9yIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9DQU5OT1RfR0VUX1NFTEVDVElPTiAtIGlmIHRoZSBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldFNlbGVjdGlvbkluZGV4ICgpIHsKIAljaGVja1dpZGdldCgpOwotCWludFtdIGlkcz0gTWFjVXRpbC5nZXRTZWxlY3Rpb25JRHMoaGFuZGxlLCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0sIGZhbHNlKTsKLQlpZiAoaWRzLmxlbmd0aCA+IDApCi0JCXJldHVybiBnZXRJbmRleChpZHNbMF0pOwotCXJldHVybiAtMTsKKwlpbnQgW10gZmlyc3QgPSBuZXcgaW50IFsxXSwgbGFzdCA9IG5ldyBpbnQgWzFdOworCWlmIChPUy5HZXREYXRhQnJvd3NlclNlbGVjdGlvbkFuY2hvciAoaGFuZGxlLCBmaXJzdCwgbGFzdCkgIT0gT1Mubm9FcnIpIHJldHVybiAtMTsKKyAgICByZXR1cm4gZmlyc3QgWzBdIC0gMTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgemVyby1yZWxhdGl2ZSBpbmRpY2VzIG9mIHRoZSBpdGVtcyB3aGljaCBhcmUgY3VycmVudGx5Ci0gKiBzZWxlY3RlZCBpbiB0aGUgcmVjZWl2ZXIuICBUaGUgYXJyYXkgaXMgZW1wdHkgaWYgbm8gaXRlbXMgYXJlIHNlbGVjdGVkLgotICogPHA+Ci0gKiBOb3RlOiBUaGlzIGlzIG5vdCB0aGUgYWN0dWFsIHN0cnVjdHVyZSB1c2VkIGJ5IHRoZSByZWNlaXZlcgotICogdG8gbWFpbnRhaW4gaXRzIHNlbGVjdGlvbiwgc28gbW9kaWZ5aW5nIHRoZSBhcnJheSB3aWxsCi0gKiBub3QgYWZmZWN0IHRoZSByZWNlaXZlci4gCi0gKiA8L3A+Ci0gKiBAcmV0dXJuIHRoZSBhcnJheSBvZiBpbmRpY2VzIG9mIHRoZSBzZWxlY3RlZCBpdGVtcwotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXJyb3IgPHVsPgotICogICAgPGxpPkVSUk9SX0NBTk5PVF9HRVRfU0VMRUNUSU9OIC0gaWYgdGhlIG9wZXJhdGlvbiBmYWlscyBiZWNhdXNlIG9mIGFuIG9wZXJhdGluZyBzeXN0ZW0gZmFpbHVyZTwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBpbnQgW10gZ2V0U2VsZWN0aW9uSW5kaWNlcyAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLSAgICBpbnRbXSBpZHM9IE1hY1V0aWwuZ2V0U2VsZWN0aW9uSURzKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCBmYWxzZSk7Ci0JaW50W10gcmVzdWx0PSBuZXcgaW50W2lkcy5sZW5ndGhdOwotCWZvciAoaW50IGk9IDA7IGkgPCBpZHMubGVuZ3RoOyBpKyspCi0JCXJlc3VsdFtpXT0gZ2V0SW5kZXgoaWRzW2ldKTsKKwljaGVja1dpZGdldCAoKTsKKwlpbnQgcHRyID0gT1MuTmV3SGFuZGxlICgwKTsKKwlpZiAoT1MuR2V0RGF0YUJyb3dzZXJJdGVtcyAoaGFuZGxlLCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0sIHRydWUsIE9TLmtEYXRhQnJvd3Nlckl0ZW1Jc1NlbGVjdGVkLCBwdHIpICE9IE9TLm5vRXJyKSB7CisJCWVycm9yIChTV1QuRVJST1JfQ0FOTk9UX0dFVF9TRUxFQ1RJT04pOworCX0KKwlpbnQgY291bnQgPSBPUy5HZXRIYW5kbGVTaXplIChwdHIpIC8gNDsKKwlpbnQgW10gcmVzdWx0ID0gbmV3IGludCBbY291bnRdOworCU9TLkhMb2NrIChwdHIpOworCWludCBbXSBzdGFydCA9IG5ldyBpbnQgWzFdOworCU9TLm1lbWNweSAoc3RhcnQsIHB0ciwgNCk7CisJaW50IFtdIGlkID0gbmV3IGludCBbMV07CisJZm9yIChpbnQgaT0wOyBpPGNvdW50OyBpKyspIHsKKwkJT1MubWVtY3B5IChpZCwgc3RhcnQgWzBdICsgKGkgKiA0KSwgNCk7CisJCXJlc3VsdCBbaV0gPSBpZCBbMF0gLSAxOworCX0KKwlPUy5IVW5sb2NrIChwdHIpOworCU9TLkRpc3Bvc2VIYW5kbGUgKHB0cik7CiAJcmV0dXJuIHJlc3VsdDsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgemVyby1yZWxhdGl2ZSBpbmRleCBvZiB0aGUgaXRlbSB3aGljaCBpcyBjdXJyZW50bHkKLSAqIGF0IHRoZSB0b3Agb2YgdGhlIHJlY2VpdmVyLiBUaGlzIGluZGV4IGNhbiBjaGFuZ2Ugd2hlbiBpdGVtcyBhcmUKLSAqIHNjcm9sbGVkIG9yIG5ldyBpdGVtcyBhcmUgYWRkZWQgb3IgcmVtb3ZlZC4KLSAqCi0gKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgdG9wIGl0ZW0KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGludCBnZXRUb3BJbmRleCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLSAgICBpbnRbXSB0b3A9IG5ldyBpbnRbMV07Ci0gICAgaW50W10gbGVmdD0gbmV3IGludFsxXTsKLSAgICBPUy5HZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uKGhhbmRsZSwgdG9wLCBsZWZ0KTsKLSAgICByZXR1cm4gdG9wWzBdIC8gZ2V0SXRlbUhlaWdodCgpOworICAgIGludFtdIHRvcCA9IG5ldyBpbnQgWzFdLCBsZWZ0ID0gbmV3IGludCBbMV07CisgICAgT1MuR2V0RGF0YUJyb3dzZXJTY3JvbGxQb3NpdGlvbiAoaGFuZGxlLCB0b3AsIGxlZnQpOworICAgIHJldHVybiB0b3AgWzBdIC8gZ2V0SXRlbUhlaWdodCAoKTsKIH0KKwogdm9pZCBob29rRXZlbnRzICgpIHsKIAlzdXBlci5ob29rRXZlbnRzICgpOwogCURpc3BsYXkgZGlzcGxheT0gZ2V0RGlzcGxheSgpOwotCU9TLnNldERhdGFCcm93c2VyQ2FsbGJhY2tzKGhhbmRsZSwgZGlzcGxheS5mRGF0YUJyb3dzZXJEYXRhUHJvYywKLQkJCQlkaXNwbGF5LmZEYXRhQnJvd3NlckNvbXBhcmVQcm9jLCBkaXNwbGF5LmZEYXRhQnJvd3Nlckl0ZW1Ob3RpZmljYXRpb25Qcm9jKTsKKwlEYXRhQnJvd3NlckNhbGxiYWNrcyBjYWxsYmFja3MgPSBuZXcgRGF0YUJyb3dzZXJDYWxsYmFja3MgKCk7CisJY2FsbGJhY2tzLnZlcnNpb24gPSBPUy5rRGF0YUJyb3dzZXJMYXRlc3RDYWxsYmFja3M7CisJT1MuSW5pdERhdGFCcm93c2VyQ2FsbGJhY2tzIChjYWxsYmFja3MpOworCWNhbGxiYWNrcy52MV9pdGVtRGF0YUNhbGxiYWNrID0gZGlzcGxheS5pdGVtRGF0YVByb2M7CisJY2FsbGJhY2tzLnYxX2l0ZW1Ob3RpZmljYXRpb25DYWxsYmFjayA9IGRpc3BsYXkuaXRlbU5vdGlmaWNhdGlvblByb2M7CisJT1MuU2V0RGF0YUJyb3dzZXJDYWxsYmFja3MgKGhhbmRsZSwgY2FsbGJhY2tzKTsKIH0KLS8qKgotICogR2V0cyB0aGUgaW5kZXggb2YgYW4gaXRlbS4KLSAqIDxwPgotICogVGhlIGxpc3QgaXMgc2VhcmNoZWQgc3RhcnRpbmcgYXQgMCB1bnRpbCBhbgotICogaXRlbSBpcyBmb3VuZCB0aGF0IGlzIGVxdWFsIHRvIHRoZSBzZWFyY2ggaXRlbS4KLSAqIElmIG5vIGl0ZW0gaXMgZm91bmQsIC0xIGlzIHJldHVybmVkLiAgSW5kZXhpbmcKLSAqIGlzIHplcm8gYmFzZWQuCi0gKgotICogQHBhcmFtIHN0cmluZyB0aGUgc2VhcmNoIGl0ZW0KLSAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBpdGVtCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgc3RyaW5nIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwotcHVibGljIGludCBpbmRleE9mIChTdHJpbmcgc3RyaW5nKSB7CisKK2ludCBpdGVtRGF0YVByb2MgKGludCBicm93c2VyLCBpbnQgaWQsIGludCBwcm9wZXJ0eSwgaW50IGl0ZW1EYXRhLCBpbnQgc2V0VmFsdWUpIHsKKwlpbnQgaW5kZXggPSBpZCAtIDE7CisJc3dpdGNoIChwcm9wZXJ0eSkgeworCQljYXNlIENPTFVNTl9JRDogeworCQkJU3RyaW5nIHRleHQgPSBpdGVtcyBbaW5kZXhdOworCQkJY2hhciBbXSBidWZmZXIgPSBuZXcgY2hhciBbdGV4dC5sZW5ndGggKCldOworCQkJdGV4dC5nZXRDaGFycyAoMCwgYnVmZmVyLmxlbmd0aCwgYnVmZmVyLCAwKTsKKwkJCWludCBwdHIgPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzIChPUy5rQ0ZBbGxvY2F0b3JEZWZhdWx0LCBidWZmZXIsIGJ1ZmZlci5sZW5ndGgpOworCQkJaWYgKHB0ciA9PSAwKSBlcnJvciAoU1dULkVSUk9SX0NBTk5PVF9TRVRfVEVYVCk7CisJCQlPUy5TZXREYXRhQnJvd3Nlckl0ZW1EYXRhVGV4dCAoaXRlbURhdGEsIHB0cik7CisJCQlPUy5DRlJlbGVhc2UgKHB0cik7CisJCQlicmVhazsKKwkJfQorCX0KKwlyZXR1cm4gT1Mubm9FcnI7Cit9CisKK2ludCBrRXZlbnRNb3VzZURvd24gKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpbnQgcmVzdWx0ID0gc3VwZXIua0V2ZW50TW91c2VEb3duIChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwlpZiAocmVzdWx0ID09IE9TLm5vRXJyKSByZXR1cm4gcmVzdWx0OworCS8qCisJKiBGZWF0dXJlIGluIHRoZSBNYWNpbnRvc2guICBGb3Igc29tZSByZWFzb24sIHdoZW4gdGhlIHVzZXIKKwkqIGNsaWNrcyBvbiB0aGUgZGF0YSBicm93c2VyLCBmb2N1cyBpcyBhc3NpZ25lZCwgdGhlbiBsb3N0CisJKiBhbmQgdGhlbiByZWFzc2lnbmVkIGNhdXNpbmcga0V2ZW5Db250cm9sU2V0Rm9jdXNQYXJ0IGV2ZW50cy4KKwkqIFRoZSBmaXggaXMgdG8gaWdub3JlIGtFdmVuQ29udHJvbFNldEZvY3VzUGFydCB3aGVuIHRoZSB1c2VyCisJKiBjbGlja3MgYW5kIHNlbmQgdGhlIGZvY3VzIGV2ZW50cyBmcm9tIGtFdmVudE1vdXNlRG93bi4KKwkqLworCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisJQ29udHJvbCBvbGRGb2N1cyA9IGRpc3BsYXkuZ2V0Rm9jdXNDb250cm9sICgpOworCWRpc3BsYXkuaWdub3JlRm9jdXMgPSB0cnVlOworCXJlc3VsdCA9IE9TLkNhbGxOZXh0RXZlbnRIYW5kbGVyIChuZXh0SGFuZGxlciwgdGhlRXZlbnQpOworCWRpc3BsYXkuaWdub3JlRm9jdXMgPSBmYWxzZTsKKwlpZiAob2xkRm9jdXMgIT0gdGhpcykgeworCQlpZiAob2xkRm9jdXMgIT0gbnVsbCkgb2xkRm9jdXMuc2VuZEZvY3VzRXZlbnQgKGZhbHNlKTsKKwkJaWYgKGlzRW5hYmxlZCAoKSkgc2VuZEZvY3VzRXZlbnQgKHRydWUpOworCX0KKwlyZXR1cm4gcmVzdWx0OworfQorCitpbnQga0V2ZW50UmF3S2V5RG93biAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWludCByZXN1bHQgPSBzdXBlci5rRXZlbnRSYXdLZXlEb3duIChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwlpZiAocmVzdWx0ID09IE9TLm5vRXJyKSByZXR1cm4gcmVzdWx0OworCS8qCisJKiBGZWF0dXJlIGluIHRoZSBNYWNpbnRvc2guICBGb3Igc29tZSByZWFzb24sIHdoZW4gdGhlIHVzZXIgaGl0cyBhbgorCSogdXAgb3IgZG93biBhcnJvdyB0byB0cmF2ZXJzZSB0aGUgaXRlbXMgaW4gYSBEYXRhIEJyb3dzZXIsIHRoZSBpdGVtCisJKiBzY3JvbGxzIHRvIHRoZSBsZWZ0IHN1Y2ggdGhhdCB0aGUgd2hpdGUgc3BhY2UgdGhhdCBpcyBub3JtYWxseQorCSogdmlzaWJsZSB0byB0aGUgcmlnaHQgb2YgdGhlIGV2ZXJ5IGl0ZW0gaXMgc2Nyb2xsZWQgb3V0IG9mIHZpZXcuCisJKiBUaGUgZml4IGlzIHRvIGRvIHRoZSBhcnJvdyB0cmF2ZXJzYWwgaW4gSmF2YSBhbmQgbm90IGNhbGwgdGhlCisJKiBkZWZhdWx0IGhhbmRsZXIuCisJKi8KKwlpbnQgW10ga2V5Q29kZSA9IG5ldyBpbnQgWzFdOworCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1LZXlDb2RlLCBPUy50eXBlVUludDMyLCBudWxsLCBrZXlDb2RlLmxlbmd0aCAqIDQsIG51bGwsIGtleUNvZGUpOworCXN3aXRjaCAoa2V5Q29kZSBbMF0pIHsKKwkJY2FzZSAxMjU6IHsgLyogRG93biAqLworCQkJaW50IGluZGV4ID0gZ2V0U2VsZWN0aW9uSW5kZXggKCk7CisJCQlzZXRTZWxlY3Rpb24gKE1hdGgubWluIChpdGVtQ291bnQgLSAxLCBpbmRleCArIDEpKTsKKwkJCXJldHVybiBPUy5ub0VycjsKKwkJfQorCQljYXNlIDEyNjogeyAvKiBVcCovCisJCQlpbnQgaW5kZXggPSBnZXRTZWxlY3Rpb25JbmRleCAoKTsKKwkJCXNldFNlbGVjdGlvbiAoTWF0aC5tYXggKDAsIGluZGV4IC0gMSkpOworCQkJcmV0dXJuIE9TLm5vRXJyOworCQl9CisJfQorCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRSYXdLZXlSZXBlYXQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpbnQgcmVzdWx0ID0gc3VwZXIua0V2ZW50UmF3S2V5UmVwZWF0IChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwlpZiAocmVzdWx0ID09IE9TLm5vRXJyKSByZXR1cm4gcmVzdWx0OworCS8qCisJKiBGZWF0dXJlIGluIHRoZSBNYWNpbnRvc2guICBGb3Igc29tZSByZWFzb24sIHdoZW4gdGhlIHVzZXIgaGl0cyBhbgorCSogdXAgb3IgZG93biBhcnJvdyB0byB0cmF2ZXJzZSB0aGUgaXRlbXMgaW4gYSBEYXRhIEJyb3dzZXIsIHRoZSBpdGVtCisJKiBzY3JvbGxzIHRvIHRoZSBsZWZ0IHN1Y2ggdGhhdCB0aGUgd2hpdGUgc3BhY2UgdGhhdCBpcyBub3JtYWxseQorCSogdmlzaWJsZSB0byB0aGUgcmlnaHQgb2YgdGhlIGV2ZXJ5IGl0ZW0gaXMgc2Nyb2xsZWQgb3V0IG9mIHZpZXcuCisJKiBUaGUgZml4IGlzIHRvIGRvIHRoZSBhcnJvdyB0cmF2ZXJzYWwgaW4gSmF2YSBhbmQgbm90IGNhbGwgdGhlCisJKiBkZWZhdWx0IGhhbmRsZXIuCisJKi8KKwlpbnQgW10ga2V5Q29kZSA9IG5ldyBpbnQgWzFdOworCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1LZXlDb2RlLCBPUy50eXBlVUludDMyLCBudWxsLCBrZXlDb2RlLmxlbmd0aCAqIDQsIG51bGwsIGtleUNvZGUpOworCXN3aXRjaCAoa2V5Q29kZSBbMF0pIHsKKwkJY2FzZSAxMjU6IHsgLyogRG93biAqLworCQkJaW50IGluZGV4ID0gZ2V0U2VsZWN0aW9uSW5kZXggKCk7CisJCQlzZXRTZWxlY3Rpb24gKE1hdGgubWluIChpdGVtQ291bnQgLSAxLCBpbmRleCArIDEpKTsKKwkJCXJldHVybiBPUy5ub0VycjsKKwkJfQorCQljYXNlIDEyNjogeyAvKiBVcCovCisJCQlpbnQgaW5kZXggPSBnZXRTZWxlY3Rpb25JbmRleCAoKTsKKwkJCXNldFNlbGVjdGlvbiAoTWF0aC5tYXggKDAsIGluZGV4IC0gMSkpOworCQkJcmV0dXJuIE9TLm5vRXJyOworCQl9CisJfQorCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBpdGVtTm90aWZpY2F0aW9uUHJvYyAoaW50IGJyb3dzZXIsIGludCBpZCwgaW50IG1lc3NhZ2UpIHsKKwlzd2l0Y2ggKG1lc3NhZ2UpIHsKKwkJY2FzZSBPUy5rRGF0YUJyb3dzZXJJdGVtU2VsZWN0ZWQ6CisJCWNhc2UgT1Mua0RhdGFCcm93c2VySXRlbURlc2VsZWN0ZWQ6IHsKKwkJCWlmIChpZ25vcmVTZWxlY3QpIGJyZWFrOworCQkJaW50IFtdIGZpcnN0ID0gbmV3IGludCBbMV0sIGxhc3QgPSBuZXcgaW50IFsxXTsKKwkJCU9TLkdldERhdGFCcm93c2VyU2VsZWN0aW9uQW5jaG9yIChoYW5kbGUsIGZpcnN0LCBsYXN0KTsKKwkJCWJvb2xlYW4gc2VsZWN0ZWQgPSBmYWxzZTsKKwkJCWlmICgoc3R5bGUgJiBTV1QuTVVMVEkpICE9IDApIHsKKwkJCQlpbnQgbW9kaWZpZXJzID0gT1MuR2V0Q3VycmVudEV2ZW50S2V5TW9kaWZpZXJzICgpOworCQkJCWlmICgobW9kaWZpZXJzICYgT1Muc2hpZnRLZXkpICE9IDApIHsKKwkJCQkJaWYgKG1lc3NhZ2UgPT0gT1Mua0RhdGFCcm93c2VySXRlbVNlbGVjdGVkKSB7CisJCQkJCQlzZWxlY3RlZCA9IGZpcnN0IFswXSA9PSBpZCB8fCBsYXN0IFswXSA9PSBpZDsKKwkJCQkJfSBlbHNlIHsKKwkJCQkJCXNlbGVjdGVkID0gaWQgPT0gYW5jaG9yRmlyc3QgfHwgaWQgPT0gYW5jaG9yTGFzdDsKKwkJCQkJfQorCQkJCX0gZWxzZSB7CisJCQkJCWlmICgobW9kaWZpZXJzICYgT1MuY21kS2V5KSAhPSAwKSB7CisJCQkJCQlzZWxlY3RlZCA9IHRydWU7CisJCQkJCX0gZWxzZSB7CisJCQkJCQlzZWxlY3RlZCA9IGZpcnN0IFswXSA9PSBsYXN0IFswXTsKKwkJCQkJfQorCQkJCX0KKwkJCX0gZWxzZSB7CisJCQkJc2VsZWN0ZWQgPSBtZXNzYWdlID09IE9TLmtEYXRhQnJvd3Nlckl0ZW1TZWxlY3RlZDsKKwkJCX0KKwkJCWlmIChzZWxlY3RlZCkgeworCQkJCWFuY2hvckZpcnN0ID0gZmlyc3QgWzBdOworCQkJCWFuY2hvckxhc3QgPSBsYXN0IFswXTsKKwkJCQlwb3N0RXZlbnQgKFNXVC5TZWxlY3Rpb24pOworCQkJfQorCQkJYnJlYWs7CisJCX0JCisJCWNhc2UgT1Mua0RhdGFCcm93c2VySXRlbURvdWJsZUNsaWNrZWQ6IHsKKwkJCXBvc3RFdmVudCAoU1dULkRlZmF1bHRTZWxlY3Rpb24pOworCQkJYnJlYWs7CisJCX0KKwl9CisJcmV0dXJuIE9TLm5vRXJyOworfQorCitwdWJsaWMgaW50IGluZGV4T2YgKFN0cmluZyBpdGVtKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlyZXR1cm4gZ2V0SW5kZXgoc3RyaW5nLCAwKTsKKwlpZiAoaXRlbSA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWZvciAoaW50IGk9MDsgaTxpdGVtQ291bnQ7IGkrKykgeworCQlpZiAoaXRlbXMgW2ldID09IGl0ZW0pIHJldHVybiBpOworCX0KKwlyZXR1cm4gLTE7CiB9Ci0vKioKLSAqIFNlYXJjaGVzIHRoZSByZWNlaXZlcidzIGxpc3Qgc3RhcnRpbmcgYXQgdGhlIGdpdmVuLCAKLSAqIHplcm8tcmVsYXRpdmUgaW5kZXggdW50aWwgYW4gaXRlbSBpcyBmb3VuZCB0aGF0IGlzIGVxdWFsCi0gKiB0byB0aGUgYXJndW1lbnQsIGFuZCByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGF0IGl0ZW0uIElmCi0gKiBubyBpdGVtIGlzIGZvdW5kIG9yIHRoZSBzdGFydGluZyBpbmRleCBpcyBvdXQgb2YgcmFuZ2UsCi0gKiByZXR1cm5zIC0xLgotICoKLSAqIEBwYXJhbSBzdHJpbmcgdGhlIHNlYXJjaCBpdGVtCi0gKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUgaXRlbQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHN0cmluZyBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEVycm9yIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9DQU5OT1RfR0VUX0NPVU5UIC0gaWYgdGhlIG9wZXJhdGlvbiBmYWlscyBiZWNhdXNlIG9mIGFuIG9wZXJhdGluZyBzeXN0ZW0gZmFpbHVyZSB3aGlsZSBnZXR0aW5nIHRoZSBpdGVtIGNvdW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9DQU5OT1RfR0VUX0lURU0gLSBpZiB0aGUgb3BlcmF0aW9uIGZhaWxzIGJlY2F1c2Ugb2YgYW4gb3BlcmF0aW5nIHN5c3RlbSBmYWlsdXJlIHdoaWxlIGdldHRpbmcgYW4gaXRlbTwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBpbnQgaW5kZXhPZiAoU3RyaW5nIHN0cmluZywgaW50IHN0YXJ0KSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlyZXR1cm4gZ2V0SW5kZXgoc3RyaW5nLCBzdGFydCk7CisJaWYgKHN0cmluZyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWZvciAoaW50IGk9c3RhcnQ7IGk8aXRlbUNvdW50OyBpKyspIHsKKwkJaWYgKGl0ZW1zIFtpXSA9PSBzdHJpbmcpIHJldHVybiBpOworCX0KKwlyZXR1cm4gLTE7CiB9Ci0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGl0ZW0gaXMgc2VsZWN0ZWQsCi0gKiBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4gIEluZGljZXMgb3V0IG9mCi0gKiByYW5nZSBhcmUgaWdub3JlZC4KLSAqCi0gKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBpdGVtCi0gKiBAcmV0dXJuIHRoZSB2aXNpYmlsaXR5IHN0YXRlIG9mIHRoZSBpdGVtIGF0IHRoZSBpbmRleAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgYm9vbGVhbiBpc1NlbGVjdGVkIChpbnQgaW5kZXgpIHsKIAljaGVja1dpZGdldCgpOwotICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgZkRhdGEuc2l6ZSgpKSB7Ci0JCVBhaXIgcD0gKFBhaXIpIGZEYXRhLmdldChpbmRleCk7Ci0JCWlmIChwICE9IG51bGwpCi0JCQlyZXR1cm4gT1MuSXNEYXRhQnJvd3Nlckl0ZW1TZWxlY3RlZChoYW5kbGUsIHAuZklkKTsKLSAgICB9Ci0gICAgcmV0dXJuIGZhbHNlOworCXJldHVybiBPUy5Jc0RhdGFCcm93c2VySXRlbVNlbGVjdGVkIChoYW5kbGUsIGluZGV4ICsgMSk7CiB9Ci0vKioKLSAqIFJlbW92ZXMgdGhlIGl0ZW0gZnJvbSB0aGUgcmVjZWl2ZXIgYXQgdGhlIGdpdmVuCi0gKiB6ZXJvLXJlbGF0aXZlIGluZGV4LgotICoKLSAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggZm9yIHRoZSBpdGVtCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfUkFOR0UgLSBpZiB0aGUgaW5kZXggaXMgbm90IGJldHdlZW4gMCBhbmQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgbGlzdCBtaW51cyAxIChpbmNsdXNpdmUpPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEVycm9yIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JVEVNX05PVF9SRU1PVkVEIC0gaWYgdGhlIG9wZXJhdGlvbiBmYWlscyBiZWNhdXNlIG9mIGFuIG9wZXJhdGluZyBzeXN0ZW0gZmFpbHVyZTwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHJlbW92ZSAoaW50IGluZGV4KSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpZiAoaW5kZXggPT0gLTEpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7Ci0JaW50IHNpemU9IGZEYXRhLnNpemUoKTsKLQlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDwgc2l6ZSkpIHsKLQkJZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1JBTkdFKTsKKwlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbUNvdW50KSkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1JBTkdFKTsKKwlpbnQgW10gaWQgPSBuZXcgaW50IFtdIHtpdGVtQ291bnR9OworCWlmIChPUy5SZW1vdmVEYXRhQnJvd3Nlckl0ZW1zIChoYW5kbGUsIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSwgaWQubGVuZ3RoLCBpZCwgMCkgIT0gT1Mubm9FcnIpIHsKKwkJZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9SRU1PVkVEKTsKIAl9Ci0JUGFpciBwPSAoUGFpcikgZkRhdGEucmVtb3ZlKGluZGV4KTsKLQlPUy5SZW1vdmVEYXRhQnJvd3Nlckl0ZW1zKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCAxLCBuZXcgaW50W10geyBwLmZJZCB9LCAwKTsKKwlTeXN0ZW0uYXJyYXljb3B5IChpdGVtcywgaW5kZXggKyAxLCBpdGVtcywgaW5kZXgsIC0taXRlbUNvdW50IC0gaW5kZXgpOworCWl0ZW1zIFtpdGVtQ291bnRdID0gbnVsbDsKKwlPUy5VcGRhdGVEYXRhQnJvd3Nlckl0ZW1zIChoYW5kbGUsIDAsIDAsIG51bGwsIE9TLmtEYXRhQnJvd3Nlckl0ZW1Ob1Byb3BlcnR5LCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0pOwogfQotLyoqCi0gKiBSZW1vdmVzIHRoZSBpdGVtcyBmcm9tIHRoZSByZWNlaXZlciB3aGljaCBhcmUKLSAqIGJldHdlZW4gdGhlIGdpdmVuIHplcm8tcmVsYXRpdmUgc3RhcnQgYW5kIGVuZCAKLSAqIGluZGljZXMgKGluY2x1c2l2ZSkuCi0gKgotICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBvZiB0aGUgcmFuZ2UKLSAqIEBwYXJhbSBlbmQgdGhlIGVuZCBvZiB0aGUgcmFuZ2UKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9SQU5HRSAtIGlmIGVpdGhlciB0aGUgc3RhcnQgb3IgZW5kIGFyZSBub3QgYmV0d2VlbiAwIGFuZCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBsaXN0IG1pbnVzIDEgKGluY2x1c2l2ZSk8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXJyb3IgPHVsPgotICogICAgPGxpPkVSUk9SX0lURU1fTk9UX1JFTU9WRUQgLSBpZiB0aGUgb3BlcmF0aW9uIGZhaWxzIGJlY2F1c2Ugb2YgYW4gb3BlcmF0aW5nIHN5c3RlbSBmYWlsdXJlPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgcmVtb3ZlIChpbnQgc3RhcnQsIGludCBlbmQpIHsKIAljaGVja1dpZGdldCgpOwotCWlmIChzdGFydCA+IGVuZCkgcmV0dXJuOwotCWludCBuPSBmRGF0YS5zaXplKCk7Ci0JaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSBuIHx8IGVuZCA8IDAgfHwgZW5kID49IG4pCisJaWYgKCEoMCA8PSBzdGFydCAmJiBzdGFydCA8PSBlbmQgJiYgZW5kIDwgaXRlbUNvdW50KSkgewogCQllcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOwotCWludFtdIGlkcz0gZ2V0SWRzKHN0YXJ0LCBlbmQpOwotCWlmIChPUy5SZW1vdmVEYXRhQnJvd3Nlckl0ZW1zKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCBpZHMubGVuZ3RoLCBpZHMsIDApICE9IE9TLmtOb0VycikKLQkJZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9SRU1PVkVEKTsKKwl9CisJaW50IGxlbmd0aCA9IGVuZCAtIHN0YXJ0ICsgMTsKKwlmb3IgKGludCBpPTA7IGk8bGVuZ3RoOyBpKyspIHJlbW92ZSAoc3RhcnQpOwogfQotLyoqCi0gKiBTZWFyY2hlcyB0aGUgcmVjZWl2ZXIncyBsaXN0IHN0YXJ0aW5nIGF0IHRoZSBmaXJzdCBpdGVtCi0gKiB1bnRpbCBhbiBpdGVtIGlzIGZvdW5kIHRoYXQgaXMgZXF1YWwgdG8gdGhlIGFyZ3VtZW50LCAKLSAqIGFuZCByZW1vdmVzIHRoYXQgaXRlbSBmcm9tIHRoZSBsaXN0LgotICoKLSAqIEBwYXJhbSBzdHJpbmcgdGhlIGl0ZW0gdG8gcmVtb3ZlCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgc3RyaW5nIGlzIG51bGw8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfQVJHVU1FTlQgLSBpZiB0aGUgc3RyaW5nIGlzIG5vdCBmb3VuZCBpbiB0aGUgbGlzdDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSVRFTV9OT1RfUkVNT1ZFRCAtIGlmIHRoZSBvcGVyYXRpb24gZmFpbHMgYmVjYXVzZSBvZiBhbiBvcGVyYXRpbmcgc3lzdGVtIGZhaWx1cmU8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCByZW1vdmUgKFN0cmluZyBzdHJpbmcpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChzdHJpbmcgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQlQYWlyIHA9IGdldFBhaXIoc3RyaW5nKTsKLQlpZiAocCA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwotCWZEYXRhLnJlbW92ZShwKTsKLQlpZiAoT1MuUmVtb3ZlRGF0YUJyb3dzZXJJdGVtcyhoYW5kbGUsIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSwgMSwgbmV3IGludFtdIHsgcC5mSWQgfSwgMCkgIT0gT1Mua05vRXJyKQotCQllcnJvciAoU1dULkVSUk9SX0lURU1fTk9UX1JFTU9WRUQpOworCWludCBpbmRleCA9IGluZGV4T2YgKHN0cmluZywgMCk7CisJaWYgKGluZGV4ID09IC0xKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCXJlbW92ZSAoaW5kZXgpOwogfQotLyoqCi0gKiBSZW1vdmVzIHRoZSBpdGVtcyBmcm9tIHRoZSByZWNlaXZlciBhdCB0aGUgZ2l2ZW4KLSAqIHplcm8tcmVsYXRpdmUgaW5kaWNlcy4KLSAqCi0gKiBAcGFyYW0gaW5kaWNlcyB0aGUgYXJyYXkgb2YgaW5kaWNlcyBvZiB0aGUgaXRlbXMKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9SQU5HRSAtIGlmIHRoZSBpbmRleCBpcyBub3QgYmV0d2VlbiAwIGFuZCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBsaXN0IG1pbnVzIDEgKGluY2x1c2l2ZSk8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXJyb3IgPHVsPgotICogICAgPGxpPkVSUk9SX0lURU1fTk9UX1JFTU9WRUQgLSBpZiB0aGUgb3BlcmF0aW9uIGZhaWxzIGJlY2F1c2Ugb2YgYW4gb3BlcmF0aW5nIHN5c3RlbSBmYWlsdXJlPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgcmVtb3ZlIChpbnQgW10gaW5kaWNlcykgewotCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGluZGljZXMgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQlpbnRbXSBpZHM9IGdldElkcyhpbmRpY2VzKTsKLQlpZiAoT1MuUmVtb3ZlRGF0YUJyb3dzZXJJdGVtcyhoYW5kbGUsIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSwgaWRzLmxlbmd0aCwgaWRzLCAwKSAhPSBPUy5rTm9FcnIpCi0JCWVycm9yIChTV1QuRVJST1JfSVRFTV9OT1RfUkVNT1ZFRCk7CisJaW50IFtdIG5ld0luZGljZXMgPSBuZXcgaW50IFtpbmRpY2VzLmxlbmd0aF07CisJU3lzdGVtLmFycmF5Y29weSAoaW5kaWNlcywgMCwgbmV3SW5kaWNlcywgMCwgaW5kaWNlcy5sZW5ndGgpOworCXNvcnQgKG5ld0luZGljZXMpOworCWludCBsYXN0ID0gLTE7CisJZm9yIChpbnQgaT0wOyBpPG5ld0luZGljZXMubGVuZ3RoOyBpKyspIHsKKwkJaW50IGluZGV4ID0gbmV3SW5kaWNlcyBbaV07CisJCWlmIChpbmRleCAhPSBsYXN0IHx8IGkgPT0gMCkgcmVtb3ZlIChpbmRleCk7CisJCWxhc3QgPSBpbmRleDsKKwl9CiB9Ci0vKioKLSAqIFJlbW92ZXMgYWxsIG9mIHRoZSBpdGVtcyBmcm9tIHRoZSByZWNlaXZlci4KLSAqIDxwPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHJlbW92ZUFsbCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlmRGF0YS5jbGVhcigpOwotCU9TLlJlbW92ZURhdGFCcm93c2VySXRlbXMoaGFuZGxlLCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0sIDAsIG51bGwsIDApOworCU9TLlJlbW92ZURhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCAwLCBudWxsLCAwKTsKKwlpdGVtcyA9IG5ldyBTdHJpbmcgWzRdOworCWl0ZW1Db3VudCA9IGFuY2hvckZpcnN0ID0gYW5jaG9yTGFzdCA9IDA7CiB9Ci0vKioKLSAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSByZWNlaXZlcidzIHNlbGVjdGlvbiBjaGFuZ2VzLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIG5vIGxvbmdlciBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNlbGVjdGlvbkxpc3RlbmVyCi0gKiBAc2VlICNhZGRTZWxlY3Rpb25MaXN0ZW5lcgotICovCisKIHB1YmxpYyB2b2lkIHJlbW92ZVNlbGVjdGlvbkxpc3RlbmVyKFNlbGVjdGlvbkxpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTgxNyw0NTAgKzUzMiwxNzEgQEAKIAlldmVudFRhYmxlLnVuaG9vayhTV1QuU2VsZWN0aW9uLCBsaXN0ZW5lcik7CiAJZXZlbnRUYWJsZS51bmhvb2soU1dULkRlZmF1bHRTZWxlY3Rpb24sbGlzdGVuZXIpOwogfQotLyoqCi0gKiBTZWxlY3RzIHRoZSBpdGVtIGF0IHRoZSBnaXZlbiB6ZXJvLXJlbGF0aXZlIGluZGV4IGluIHRoZSByZWNlaXZlcidzIAotICogbGlzdC4gIElmIHRoZSBpdGVtIGF0IHRoZSBpbmRleCB3YXMgYWxyZWFkeSBzZWxlY3RlZCwgaXQgcmVtYWlucwotICogc2VsZWN0ZWQuIEluZGljZXMgdGhhdCBhcmUgb3V0IG9mIHJhbmdlIGFyZSBpZ25vcmVkLgotICoKLSAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIGl0ZW0gdG8gc2VsZWN0Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNlbGVjdCAoaW50IGluZGV4KSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpZiAoaW5kZXggPT0gLTEpIHJldHVybjsKLSAgICBQYWlyIHA9IChQYWlyKSBmRGF0YS5nZXQoaW5kZXgpOwotICAgIGlmIChwICE9IG51bGwpCi0JCU9TLlNldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyhoYW5kbGUsIDEsIG5ldyBpbnRbXSB7IHAuZklkIH0sIE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduKTsKKwlpZiAoMCA8PSBpbmRleCAmJiBpbmRleCA8IGl0ZW1Db3VudCkgeworCQlpbnQgW10gaWQgPSBuZXcgaW50IFtdIHtpbmRleCArIDF9OworCQlpZ25vcmVTZWxlY3QgPSB0cnVlOworCQlpbnQgb3BlcmF0aW9uID0gKHN0eWxlICYgU1dULlNJTkdMRSkgIT0gMCA/IE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduOiBPUy5rRGF0YUJyb3dzZXJJdGVtc0FkZDsKKwkJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGlkLmxlbmd0aCwgaWQsIG9wZXJhdGlvbik7CisJCWlnbm9yZVNlbGVjdCA9IGZhbHNlOworCX0KIH0KLS8qKgotICogU2VsZWN0cyB0aGUgaXRlbXMgYXQgdGhlIGdpdmVuIHplcm8tcmVsYXRpdmUgaW5kaWNlcyBpbiB0aGUgcmVjZWl2ZXIuCi0gKiBJZiB0aGUgaXRlbSBhdCB0aGUgaW5kZXggd2FzIGFscmVhZHkgc2VsZWN0ZWQsIGl0IHJlbWFpbnMKLSAqIHNlbGVjdGVkLiBUaGUgcmFuZ2Ugb2YgdGhlIGluZGljZXMgaXMgaW5jbHVzaXZlLiBJbmRpY2VzIHRoYXQgYXJlCi0gKiBvdXQgb2YgcmFuZ2UgYXJlIGlnbm9yZWQuCi0gKgotICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBvZiB0aGUgcmFuZ2UKLSAqIEBwYXJhbSBlbmQgdGhlIGVuZCBvZiB0aGUgcmFuZ2UKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2VsZWN0IChpbnQgc3RhcnQsIGludCBlbmQpIHsKIAljaGVja1dpZGdldCgpOwotCWlmIChzdGFydCA+IGVuZCkgcmV0dXJuOwotCWlmICgoc3R5bGUgJiBTV1QuU0lOR0xFKSAhPSAwKSB7Ci0gICAgICAgIC8qIEFXCi0JCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTml0ZW1Db3VudCwgMH07Ci0JCU9TLlh0R2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JCWludCBpbmRleCA9IE1hdGgubWluIChhcmdMaXN0WzFdIC0gMSwgZW5kKSArIDE7Ci0JCWlmIChpbmRleCAhPSAwICYmIGluZGV4ID49IHN0YXJ0KSBPUy5YbUxpc3RTZWxlY3RQb3MgKGhhbmRsZSwgaW5kZXgsIGZhbHNlKTsKLSAgICAgICAgKi8KLQkJcmV0dXJuOwotCX0KLSAgICBpbnRbXSBpZHM9IGdldElkcyhzdGFydCwgZW5kKTsKLQlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMoaGFuZGxlLCBpZHMubGVuZ3RoLCBpZHMsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduKTsKKwkvL05PVCBET05FIC0gcmFuZ2UgY2hlY2sKKwlpbnQgbGVuZ3RoID0gZW5kIC0gc3RhcnQgKyAxOworCWlmIChsZW5ndGggPD0gMCkgcmV0dXJuOworCWludCBbXSBpZHMgPSBuZXcgaW50IFtsZW5ndGhdOworCWZvciAoaW50IGk9MDsgaTxsZW5ndGg7IGkrKykgaWRzIFtpXSA9IGVuZCAtIGkgKyAxOworCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJaW50IG9wZXJhdGlvbiA9IChzdHlsZSAmIFNXVC5TSU5HTEUpICE9IDAgPyBPUy5rRGF0YUJyb3dzZXJJdGVtc0Fzc2lnbjogT1Mua0RhdGFCcm93c2VySXRlbXNBZGQ7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGxlbmd0aCwgaWRzLCBvcGVyYXRpb24pOworCWlnbm9yZVNlbGVjdCA9IGZhbHNlOwogfQotLyoqCi0gKiBTZWxlY3RzIHRoZSBpdGVtcyBhdCB0aGUgZ2l2ZW4gemVyby1yZWxhdGl2ZSBpbmRpY2VzIGluIHRoZSByZWNlaXZlci4KLSAqIElmIHRoZSBpdGVtIGF0IHRoZSBnaXZlbiB6ZXJvLXJlbGF0aXZlIGluZGV4IGluIHRoZSByZWNlaXZlciAKLSAqIGlzIG5vdCBzZWxlY3RlZCwgaXQgaXMgc2VsZWN0ZWQuICBJZiB0aGUgaXRlbSBhdCB0aGUgaW5kZXgKLSAqIHdhcyBzZWxlY3RlZCwgaXQgcmVtYWlucyBzZWxlY3RlZC4gSW5kaWNlcyB0aGF0IGFyZSBvdXQKLSAqIG9mIHJhbmdlIGFuZCBkdXBsaWNhdGUgaW5kaWNlcyBhcmUgaWdub3JlZC4KLSAqCi0gKiBAcGFyYW0gaW5kaWNlcyB0aGUgYXJyYXkgb2YgaW5kaWNlcyBmb3IgdGhlIGl0ZW1zIHRvIHNlbGVjdAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZWxlY3QgKGludCBbXSBpbmRpY2VzKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoaW5kaWNlcyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCWlmICgoc3R5bGUgJiBTV1QuU0lOR0xFKSAhPSAwKSB7Ci0JCS8qIEFXCi0JCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTml0ZW1Db3VudCwgMH07Ci0JCU9TLlh0R2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JCWludCBjb3VudCA9IGFyZ0xpc3QgWzFdOwotCQlmb3IgKGludCBpID0gMDsgaSA8IGluZGljZXMubGVuZ3RoOyBpKyspIHsKLQkJCWludCBpbmRleCA9IGluZGljZXMgW2ldOwotCQkJaWYgKDAgPD0gaW5kZXggJiYgaW5kZXggPCBjb3VudCkgewotCQkJCXNlbGVjdCAoaW5kZXgpOwotCQkJCXJldHVybjsKLQkJCX0KLQkJfQotCQkqLwotCQlyZXR1cm47Ci0JfQotCWludFtdIGlkcz0gZ2V0SWRzKGluZGljZXMpOwotCU9TLlNldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyhoYW5kbGUsIGlkcy5sZW5ndGgsIGlkcywgT1Mua0RhdGFCcm93c2VySXRlbXNBc3NpZ24pOworCS8vTk9UIERPTkUgLSByYW5nZSBjaGVjaworCWludCBsZW5ndGggPSBpbmRpY2VzLmxlbmd0aDsKKwlpbnQgW10gaWRzID0gbmV3IGludCBbbGVuZ3RoXTsKKwlmb3IgKGludCBpPTA7IGk8bGVuZ3RoOyBpKyspIGlkcyBbaV0gPSBpbmRpY2VzIFtsZW5ndGggLSBpIC0gMV0gKyAxOworCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJaW50IG9wZXJhdGlvbiA9IChzdHlsZSAmIFNXVC5TSU5HTEUpICE9IDAgPyBPUy5rRGF0YUJyb3dzZXJJdGVtc0Fzc2lnbjogT1Mua0RhdGFCcm93c2VySXRlbXNBZGQ7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGlkcy5sZW5ndGgsIGlkcywgb3BlcmF0aW9uKTsKKwlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKIH0KKwogdm9pZCBzZWxlY3QgKFN0cmluZyBbXSBpdGVtcykgewogCWNoZWNrV2lkZ2V0KCk7Ci0JaW50W10gaWRzPSBnZXRJZHMoaXRlbXMpOwotCU9TLlNldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyhoYW5kbGUsIGlkcy5sZW5ndGgsIGlkcywgT1Mua0RhdGFCcm93c2VySXRlbXNBc3NpZ24pOworCWlmIChpdGVtcyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCS8vTk9UIERPTkUgLSByYW5nZSBjaGVjaworCWludCBsZW5ndGggPSBpdGVtcy5sZW5ndGg7CisJaW50IFtdIGlkcyA9IG5ldyBpbnQgW2xlbmd0aF07CisJZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSBpZHMgW2ldID0gaW5kZXhPZiAoaXRlbXMgW2xlbmd0aCAtIGkgLSAxXSkgKyAxOworCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJaW50IG9wZXJhdGlvbiA9IChzdHlsZSAmIFNXVC5TSU5HTEUpICE9IDAgPyBPUy5rRGF0YUJyb3dzZXJJdGVtc0Fzc2lnbjogT1Mua0RhdGFCcm93c2VySXRlbXNBZGQ7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGxlbmd0aCwgaWRzLCBvcGVyYXRpb24pOworCWlnbm9yZVNlbGVjdCA9IGZhbHNlOwogfQotLyoqCi0gKiBTZWxlY3RzIGFsbCB0aGUgaXRlbXMgaW4gdGhlIHJlY2VpdmVyLgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZWxlY3RBbGwgKCkgewotCWNoZWNrV2lkZ2V0KCk7CisJY2hlY2tXaWRnZXQgKCk7CiAJaWYgKChzdHlsZSAmIFNXVC5TSU5HTEUpICE9IDApIHJldHVybjsKLQlpbnQgbj0gZkRhdGEuc2l6ZSgpOwotCWlmIChuIDw9IDApIHJldHVybjsKLQlpbnRbXSBpZHM9IGdldElkcygwLCBuLTEpOwotCU9TLlNldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyhoYW5kbGUsIGlkcy5sZW5ndGgsIGlkcywgT1Mua0RhdGFCcm93c2VySXRlbXNBc3NpZ24pOworCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIDAsIG51bGwsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduKTsKKwlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKIH0KLXZvaWQgc2V0Rm9jdXNJbmRleCAoaW50IGluZGV4KSB7Ci0gICAgLyogQVcKLQlPUy5YbUxpc3RTZXRLYmRJdGVtUG9zIChoYW5kbGUsIGluZGV4ICsgMSk7Ci0gICAgKi8KLQlTeXN0ZW0ub3V0LnByaW50bG4oIkxpc3Quc2V0Rm9jdXNJbmRleDogbnlpIik7Ci19Ci0vKioKLSAqIFNldHMgdGhlIHRleHQgb2YgdGhlIGl0ZW0gaW4gdGhlIHJlY2VpdmVyJ3MgbGlzdCBhdCB0aGUgZ2l2ZW4KLSAqIHplcm8tcmVsYXRpdmUgaW5kZXggdG8gdGhlIHN0cmluZyBhcmd1bWVudC4gVGhpcyBpcyBlcXVpdmFsZW50Ci0gKiB0byA8Y29kZT5yZW1vdmU8L2NvZGU+J2luZyB0aGUgb2xkIGl0ZW0gYXQgdGhlIGluZGV4LCBhbmQgdGhlbgotICogPGNvZGU+YWRkPC9jb2RlPidpbmcgdGhlIG5ldyBpdGVtIGF0IHRoYXQgaW5kZXguCi0gKgotICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBmb3IgdGhlIGl0ZW0KLSAqIEBwYXJhbSBzdHJpbmcgdGhlIG5ldyB0ZXh0IGZvciB0aGUgaXRlbQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1JBTkdFIC0gaWYgdGhlIGluZGV4IGlzIG5vdCBiZXR3ZWVuIDAgYW5kIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGxpc3QgbWludXMgMSAoaW5jbHVzaXZlKTwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSVRFTV9OT1RfUkVNT1ZFRCAtIGlmIHRoZSByZW1vdmUgb3BlcmF0aW9uIGZhaWxzIGJlY2F1c2Ugb2YgYW4gb3BlcmF0aW5nIHN5c3RlbSBmYWlsdXJlPC9saT4KLSAqICAgIDxsaT5FUlJPUl9JVEVNX05PVF9BRERFRCAtIGlmIHRoZSBhZGQgb3BlcmF0aW9uIGZhaWxzIGJlY2F1c2Ugb2YgYW4gb3BlcmF0aW5nIHN5c3RlbSBmYWlsdXJlPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0SXRlbSAoaW50IGluZGV4LCBTdHJpbmcgc3RyaW5nKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoc3RyaW5nID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0JaWYgKGluZGV4ID09IC0xKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOwotCWludCBzaXplPSBmRGF0YS5zaXplKCk7Ci0JaWYgKCEoMCA8PSBpbmRleCAmJiBpbmRleCA8IHNpemUpKSB7Ci0JCWVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7Ci0JfQotICAgIFBhaXIgcD0gKFBhaXIpIGZEYXRhLmdldChpbmRleCk7Ci0gICAgcC5mVmFsdWU9IHN0cmluZzsKLSAgICBPUy5VcGRhdGVEYXRhQnJvd3Nlckl0ZW1zKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCAxLCBuZXcgaW50W10geyBwLmZJZCB9LCBPUy5rRGF0YUJyb3dzZXJJdGVtTm9Qcm9wZXJ0eSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtKTsKKwlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbUNvdW50KSkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1JBTkdFKTsKKwlpbnQgW10gaWQgPSBuZXcgaW50IFtdIHtpbmRleCArIDF9OworCWl0ZW1zIFtpbmRleF0gPSBzdHJpbmc7CisgICAgT1MuVXBkYXRlRGF0YUJyb3dzZXJJdGVtcyAoaGFuZGxlLCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0sIGlkLmxlbmd0aCwgaWQsIE9TLmtEYXRhQnJvd3Nlckl0ZW1Ob1Byb3BlcnR5LCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0pOwogfQotLyoqCi0gKiBTZXRzIHRoZSByZWNlaXZlcidzIGl0ZW1zIHRvIGJlIHRoZSBnaXZlbiBhcnJheSBvZiBpdGVtcy4KLSAqCi0gKiBAcGFyYW0gaXRlbXMgdGhlIGFycmF5IG9mIGl0ZW1zCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSVRFTV9OT1RfQURERUQgLSBpZiB0aGUgb3BlcmF0aW9uIGZhaWxzIGJlY2F1c2Ugb2YgYW4gb3BlcmF0aW5nIHN5c3RlbSBmYWlsdXJlPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0SXRlbXMgKFN0cmluZyBbXSBpdGVtcykgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGl0ZW1zID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0KLQlmRGF0YS5jbGVhcigpOwotCWludCBjb3VudD0gaXRlbXMubGVuZ3RoOwotCWludFtdIGlkcz0gbmV3IGludFtjb3VudF07Ci0JZm9yIChpbnQgaT0gMDsgaSA8IGNvdW50OyBpKyspIHsKLQkJUGFpciBwPSBuZXcgUGFpcihpdGVtc1tpXSk7Ci0JCWZEYXRhLmFkZChwKTsKLQkJaWRzW2ldPSBwLmZJZDsKLQl9Ci0JaWYgKE9TLkFkZERhdGFCcm93c2VySXRlbXMoaGFuZGxlLCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0sIGlkcy5sZW5ndGgsIGlkcywgMCkgIT0gT1Mua05vRXJyKQorCU9TLlJlbW92ZURhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCAwLCBudWxsLCAwKTsKKwlpZiAoT1MuQWRkRGF0YUJyb3dzZXJJdGVtcyhoYW5kbGUsIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSwgaXRlbXMubGVuZ3RoLCBudWxsLCAwKSAhPSBPUy5ub0VycikgewogCQllcnJvciAoU1dULkVSUk9SX0lURU1fTk9UX0FEREVEKTsKKwl9CisJdGhpcy5pdGVtcyA9IG5ldyBTdHJpbmcgW2l0ZW1zLmxlbmd0aF07CisJU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIDAsIHRoaXMuaXRlbXMsIDAsIGl0ZW1zLmxlbmd0aCk7CisJaXRlbUNvdW50ID0gaXRlbXMubGVuZ3RoOwogfQotLyoqCi0gKiBTZWxlY3RzIHRoZSBpdGVtIGF0IHRoZSBnaXZlbiB6ZXJvLXJlbGF0aXZlIGluZGV4IGluIHRoZSByZWNlaXZlci4gCi0gKiBJZiB0aGUgaXRlbSBhdCB0aGUgaW5kZXggd2FzIGFscmVhZHkgc2VsZWN0ZWQsIGl0IHJlbWFpbnMgc2VsZWN0ZWQuCi0gKiBUaGUgY3VycmVudCBzZWxlY3RlZCBpcyBmaXJzdCBjbGVhcmVkLCB0aGVuIHRoZSBuZXcgaXRlbXMgYXJlIHNlbGVjdGVkLgotICogSW5kaWNlcyB0aGF0IGFyZSBvdXQgb2YgcmFuZ2UgYXJlIGlnbm9yZWQuCi0gKgotICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgaXRlbSB0byBzZWxlY3QKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiBAc2VlIExpc3QjZGVzZWxlY3RBbGwoKQotICogQHNlZSBMaXN0I3NlbGVjdChpbnQpCi0gKi8KKwogcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uIChpbnQgaW5kZXgpIHsKLQlpZiAoKHN0eWxlICYgU1dULk1VTFRJKSAhPSAwKSBkZXNlbGVjdEFsbCAoKTsKLQlzZWxlY3QgKGluZGV4KTsKKwljaGVja1dpZGdldCgpOworCWlmICgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbUNvdW50KSB7CisJCWludCBbXSBpZCA9IG5ldyBpbnQgW10ge2luZGV4ICsgMX07CisJCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJCU9TLlNldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyAoaGFuZGxlLCBpZC5sZW5ndGgsIGlkLCBPUy5rRGF0YUJyb3dzZXJJdGVtc0Fzc2lnbik7CisJCWlnbm9yZVNlbGVjdCA9IGZhbHNlOworCQlzaG93SW5kZXggKGluZGV4KTsKKwl9CiB9Ci0vKioKLSAqIFNlbGVjdHMgdGhlIGl0ZW1zIGF0IHRoZSBnaXZlbiB6ZXJvLXJlbGF0aXZlIGluZGljZXMgaW4gdGhlIHJlY2VpdmVyLiAKLSAqIFRoZSBjdXJyZW50IHNlbGVjdGVkIGlmIGZpcnN0IGNsZWFyZWQsIHRoZW4gdGhlIG5ldyBpdGVtcyBhcmUgc2VsZWN0ZWQuCi0gKgotICogQHBhcmFtIHN0YXJ0IHRoZSBzdGFydCBpbmRleCBvZiB0aGUgaXRlbXMgdG8gc2VsZWN0Ci0gKiBAcGFyYW0gZW5kIHRoZSBlbmQgaW5kZXggb2YgdGhlIGl0ZW1zIHRvIHNlbGVjdAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFRhYmxlI2Rlc2VsZWN0QWxsKCkKLSAqIEBzZWUgVGFibGUjc2VsZWN0KGludCxpbnQpCi0gKi8KKwogcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uIChpbnQgc3RhcnQsIGludCBlbmQpIHsKLQlpZiAoKHN0eWxlICYgU1dULk1VTFRJKSAhPSAwKSBkZXNlbGVjdEFsbCAoKTsKLQlzZWxlY3QgKHN0YXJ0LCBlbmQpOworCWNoZWNrV2lkZ2V0ICgpOworCWludCBsZW5ndGggPSBlbmQgLSBzdGFydCArIDE7CisJaWYgKGxlbmd0aCA8PSAwKSByZXR1cm47CisJaW50IGNvdW50ID0gbGVuZ3RoOworCWludCBbXSBpZHMgPSBuZXcgaW50IFtsZW5ndGhdOworCWZvciAoaW50IGk9c3RhcnQ7IGk8PWVuZDsgaSsrKSB7CisJCWlmICgwIDw9IGkgJiYgaSA8IGl0ZW1Db3VudCkgaWRzIFstLWNvdW50XSA9IGkgKyAxOworCX0KKwlpZiAoY291bnQgIT0gMCkgcmV0dXJuOworCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGNvdW50LCBpZHMsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduKTsKKwlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKKwlpZiAoaWRzLmxlbmd0aCA+IDApIHNob3dJbmRleCAoaWRzIFswXSAtIDEpOwogfQotLyoqCi0gKiBTZWxlY3RzIHRoZSBpdGVtcyBhdCB0aGUgZ2l2ZW4gemVyby1yZWxhdGl2ZSBpbmRpY2VzIGluIHRoZSByZWNlaXZlci4gCi0gKiBUaGUgY3VycmVudCBzZWxlY3Rpb24gaXMgZmlyc3QgY2xlYXJlZCwgdGhlbiB0aGUgbmV3IGl0ZW1zIGFyZSBzZWxlY3RlZC4KLSAqCi0gKiBAcGFyYW0gaW5kaWNlcyB0aGUgaW5kaWNlcyBvZiB0aGUgaXRlbXMgdG8gc2VsZWN0Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgTGlzdCNkZXNlbGVjdEFsbCgpCi0gKiBAc2VlIExpc3Qjc2VsZWN0KGludFtdKQotICovCi1wdWJsaWMgdm9pZCBzZXRTZWxlY3Rpb24oaW50W10gaW5kaWNlcykgewotCWlmICgoc3R5bGUgJiBTV1QuTVVMVEkpICE9IDApIGRlc2VsZWN0QWxsICgpOwotCXNlbGVjdCAoaW5kaWNlcyk7CisKK3B1YmxpYyB2b2lkIHNldFNlbGVjdGlvbiAoaW50IFtdIGluZGljZXMpIHsKKwlpZiAoaW5kaWNlcyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWludCBsZW5ndGggPSBpbmRpY2VzLmxlbmd0aDsKKwlpbnQgY291bnQgPSBsZW5ndGg7CisJaW50IFtdIGlkcyA9IG5ldyBpbnQgW2xlbmd0aF07CisJZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSB7CisJCWludCBpbmRleCA9IGluZGljZXMgW2ldOworCQlpZiAoMCA8PSBpbmRleCAmJiBpbmRleCA8IGl0ZW1Db3VudCkgaWRzIFstLWNvdW50XSA9IGluZGV4ICsgMTsKKwl9CisJaWYgKGNvdW50ICE9IDApIHJldHVybjsKKwlpZ25vcmVTZWxlY3QgPSB0cnVlOworCU9TLlNldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyAoaGFuZGxlLCBjb3VudCwgaWRzLCBPUy5rRGF0YUJyb3dzZXJJdGVtc0Fzc2lnbik7CisJaWdub3JlU2VsZWN0ID0gZmFsc2U7CisJaWYgKGlkcy5sZW5ndGggPiAwKSBzaG93SW5kZXggKGlkcyBbMF0gLSAxKTsKIH0KLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBzZWxlY3Rpb24gdG8gYmUgdGhlIGdpdmVuIGFycmF5IG9mIGl0ZW1zLgotICogVGhlIGN1cnJlbnQgc2VsZWN0ZWQgaXMgZmlyc3QgY2xlYXJlZCwgdGhlbiB0aGUgbmV3IGl0ZW1zIGFyZQotICogc2VsZWN0ZWQuCi0gKgotICogQHBhcmFtIGl0ZW1zIHRoZSBhcnJheSBvZiBpdGVtcwotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIExpc3QjZGVzZWxlY3RBbGwoKQotICogQHNlZSBMaXN0I3NlbGVjdChpbnQpCi0gKi8KKwogcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uIChTdHJpbmcgW10gaXRlbXMpIHsKIAljaGVja1dpZGdldCgpOwotCWludFtdIGlkcz0gZ2V0SWRzKGl0ZW1zKTsKLQlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMoaGFuZGxlLCBpZHMubGVuZ3RoLCBpZHMsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduKTsKKwlpZiAoaXRlbXMgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlpbnQgbGVuZ3RoID0gaXRlbXMubGVuZ3RoOworCWludCBjb3VudCA9IGxlbmd0aDsKKwlpbnQgW10gaWRzID0gbmV3IGludCBbbGVuZ3RoXTsKKwlmb3IgKGludCBpPTA7IGk8bGVuZ3RoOyBpKyspIHsKKwkJaW50IGluZGV4ID0gaW5kZXhPZiAoaXRlbXMgW2ldKTsKKwkJaWYgKDAgPD0gaW5kZXggJiYgaW5kZXggPCBpdGVtQ291bnQpIGlkcyBbLS1jb3VudF0gPSBpbmRleCArIDE7CisJfQorCWlmIChjb3VudCAhPSAwKSByZXR1cm47CisJaWdub3JlU2VsZWN0ID0gdHJ1ZTsKKwlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMgKGhhbmRsZSwgY291bnQsIGlkcywgT1Mua0RhdGFCcm93c2VySXRlbXNBc3NpZ24pOworCWlnbm9yZVNlbGVjdCA9IGZhbHNlOworCWlmIChpZHMubGVuZ3RoID4gMCkgc2hvd0luZGV4IChpZHMgWzBdIC0gMSk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHplcm8tcmVsYXRpdmUgaW5kZXggb2YgdGhlIGl0ZW0gd2hpY2ggaXMgY3VycmVudGx5Ci0gKiBhdCB0aGUgdG9wIG9mIHRoZSByZWNlaXZlci4gVGhpcyBpbmRleCBjYW4gY2hhbmdlIHdoZW4gaXRlbXMKLSAqIGFyZSBzY3JvbGxlZCBvciBuZXcgaXRlbXMgYXJlIGFkZGVkIGFuZCByZW1vdmVkLgotICoKLSAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIHRvcCBpdGVtCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldFRvcEluZGV4IChpbnQgaW5kZXgpIHsKIAljaGVja1dpZGdldCgpOwotICAgIGludFtdIHRvcD0gbmV3IGludFsxXTsKLSAgICBpbnRbXSBsZWZ0PSBuZXcgaW50WzFdOwotICAgIE9TLkdldERhdGFCcm93c2VyU2Nyb2xsUG9zaXRpb24oaGFuZGxlLCB0b3AsIGxlZnQpOwotICAgIHRvcFswXT0gaW5kZXggKiBnZXRJdGVtSGVpZ2h0KCkgKyA0OwotICAgIE9TLlNldERhdGFCcm93c2VyU2Nyb2xsUG9zaXRpb24oaGFuZGxlLCB0b3BbMF0sIGxlZnRbMF0pOworICAgIGludCBbXSB0b3AgPSBuZXcgaW50IFsxXSwgbGVmdCA9IG5ldyBpbnQgWzFdOworICAgIE9TLkdldERhdGFCcm93c2VyU2Nyb2xsUG9zaXRpb24gKGhhbmRsZSwgdG9wLCBsZWZ0KTsKKyAgICB0b3AgWzBdID0gaW5kZXggKiBnZXRJdGVtSGVpZ2h0ICgpOworICAgIE9TLlNldERhdGFCcm93c2VyU2Nyb2xsUG9zaXRpb24gKGhhbmRsZSwgdG9wIFswXSwgbGVmdCBbMF0pOwogfQotLyoqCi0gKiBTaG93cyB0aGUgc2VsZWN0aW9uLiAgSWYgdGhlIHNlbGVjdGlvbiBpcyBhbHJlYWR5IHNob3dpbmcgaW4gdGhlIHJlY2VpdmVyLAotICogdGhpcyBtZXRob2Qgc2ltcGx5IHJldHVybnMuICBPdGhlcndpc2UsIHRoZSBpdGVtcyBhcmUgc2Nyb2xsZWQgdW50aWwKLSAqIHRoZSBzZWxlY3Rpb24gaXMgdmlzaWJsZS4KLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwordm9pZCBzaG93SW5kZXggKGludCBpbmRleCkgeworCWlmICgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbUNvdW50KSB7CisJCXNob3J0IFtdIHdpZHRoID0gbmV3IHNob3J0IFsxXTsKKwkJT1MuR2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdOYW1lZENvbHVtbldpZHRoIChoYW5kbGUsIENPTFVNTl9JRCwgd2lkdGgpOworCQlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKSwgaW5zZXQgPSBuZXcgUmVjdCAoKTsKKwkJT1MuR2V0Q29udHJvbEJvdW5kcyAoaGFuZGxlLCByZWN0KTsKKwkJT1MuR2V0RGF0YUJyb3dzZXJTY3JvbGxCYXJJbnNldCAoaGFuZGxlLCBpbnNldCk7CisJCU9TLlNldERhdGFCcm93c2VyVGFibGVWaWV3TmFtZWRDb2x1bW5XaWR0aCAoaGFuZGxlLCBDT0xVTU5fSUQsIChzaG9ydCkocmVjdC5yaWdodCAtIHJlY3QubGVmdCAtIGluc2V0LmxlZnQgLSBpbnNldC5yaWdodCkpOworCQlPUy5SZXZlYWxEYXRhQnJvd3Nlckl0ZW0gKGhhbmRsZSwgaW5kZXggKyAxLCBDT0xVTU5fSUQsIChieXRlKSBPUy5rRGF0YUJyb3dzZXJSZXZlYWxXaXRob3V0U2VsZWN0aW5nKTsKKwkJT1MuU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdOYW1lZENvbHVtbldpZHRoIChoYW5kbGUsIENPTFVNTl9JRCwgKHNob3J0KXdpZHRoIFswXSk7CisJfQorfQorCiBwdWJsaWMgdm9pZCBzaG93U2VsZWN0aW9uICgpIHsKLQljaGVja1dpZGdldCgpOwkKLQlpbnRbXSBpZHM9IE1hY1V0aWwuZ2V0U2VsZWN0aW9uSURzKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCBmYWxzZSk7Ci0JaWYgKGlkcy5sZW5ndGggPiAwICYmIGlkc1swXSAhPSAwKQotCQlPUy5SZXZlYWxEYXRhQnJvd3Nlckl0ZW0oaGFuZGxlLCBpZHNbMF0sIENPTF9JRCwgZmFsc2UpOworCWNoZWNrV2lkZ2V0KCk7CisJaW50IGluZGV4ID0gZ2V0U2VsZWN0aW9uSW5kZXggKCk7CisJaWYgKGluZGV4ID49IDApIHNob3dJbmRleCAoaW5kZXgpOwogfQogCi0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLS8vIE1hYyBzdHVmZgotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQlpbnQgcHJvY2Vzc1NlbGVjdGlvbiAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0JCS8vU3lzdGVtLm91dC5wcmludGxuKCJMaXN0LnByb2Nlc3NTZWxlY3Rpb246ICIgKyBnZXRTZWxlY3Rpb25JbmRleCgpKTsKLQkJcmV0dXJuIHN1cGVyLnByb2Nlc3NTZWxlY3Rpb24oY2FsbERhdGEpOwotCX0KLQotCWludCBzZW5kS2V5RXZlbnQgKGludCB0eXBlLCBNYWNFdmVudCBtRXZlbnQsIEV2ZW50IGV2ZW50KSB7Ci0JCS8vcHJvY2Vzc0V2ZW50ICh0eXBlLCBuZXcgTWFjRXZlbnQoZVJlZkhhbmRsZSkpOwotCQlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOwotCX0KLQkJCQotCWludCBoYW5kbGVJdGVtQ2FsbGJhY2soaW50IHJvd0lELCBpbnQgY29sSUQsIGludCBpdGVtKSB7Ci0JCQotCQlpZiAoY29sSUQgIT0gQ09MX0lEKSB7Ci0JCQkvL1N5c3RlbS5vdXQucHJpbnRsbigiTGlzdC5oYW5kbGVJdGVtQ2FsbGJhY2s6IHdyb25nIGNvbHVtbiBpZDogIiArIGNvbElEKTsKLQkJCXJldHVybiBPUy5rTm9FcnI7Ci0JCX0KLQkJCQotCQlTdHJpbmcgcz0gZ2V0KHJvd0lEKTsKLQkJaWYgKHMgPT0gbnVsbCkgewotCQkJU3lzdGVtLm91dC5wcmludGxuKCJMaXN0LmhhbmRsZUl0ZW1DYWxsYmFjazogY2FuJ3QgZmluZCByb3cgd2l0aCBpZDogIiArIHJvd0lEKTsKLQkJCXJldHVybiAtMTsKLQkJfQotCQkJCi0JCWludCBzSGFuZGxlPSAwOwotCQl0cnkgewotCQkJc0hhbmRsZT0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyhzKTsKLQkJCU9TLlNldERhdGFCcm93c2VySXRlbURhdGFUZXh0KGl0ZW0sIHNIYW5kbGUpOwotCQl9IGZpbmFsbHkgewotCQkJaWYgKHNIYW5kbGUgIT0gMCkKLQkJCQlPUy5DRlJlbGVhc2Uoc0hhbmRsZSk7Ci0JCX0KLQkJcmV0dXJuIE9TLmtOb0VycjsKLQl9Ci0KLQlpbnQgaGFuZGxlQ29tcGFyZUNhbGxiYWNrKGludCBpdGVtMUlELCBpbnQgaXRlbTJJRCwgaW50IGl0ZW0pIHsKLQkJaWYgKGdldEluZGV4KGl0ZW0xSUQpIDwgZ2V0SW5kZXgoaXRlbTJJRCkpCi0JCQlyZXR1cm4gMTsKLQkJcmV0dXJuIDA7Ci0JfQotCQotCWludCBoYW5kbGVJdGVtTm90aWZpY2F0aW9uQ2FsbGJhY2soaW50IGl0ZW0sIGludCBtZXNzYWdlKSB7Ci0JCXJldHVybiBPUy5rTm9FcnI7Ci0JfQotCQotCS8qKgotCSAqIFJldHVybnMgc3RyaW5nIHZhbHVlIG9mIHJvdyB3aXRoIHRoZSBnaXZlbiBJRAotCSAqLwotCXByaXZhdGUgU3RyaW5nIGdldChpbnQgaWQpIHsKLQkJSXRlcmF0b3IgaXRlcj0gZkRhdGEuaXRlcmF0b3IoKTsKLQkJd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKSB7Ci0JCQlQYWlyIHA9IChQYWlyKSBpdGVyLm5leHQoKTsKLSAgICAJCWlmIChwLmZJZCA9PSBpZCkKLSAgICAJCQlyZXR1cm4gcC5mVmFsdWU7Ci0gICAgCX0KLQkJcmV0dXJuIG51bGw7Ci0JfQotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgaW5kZXggb2Ygcm93IHdpdGggdGhlIGdpdmVuIElECi0JICovCi0JcHJpdmF0ZSBpbnQgZ2V0SW5kZXgoaW50IGlkKSB7Ci0JCUl0ZXJhdG9yIGl0ZXI9IGZEYXRhLml0ZXJhdG9yKCk7Ci0JCWZvciAoaW50IGk9IDA7IGl0ZXIuaGFzTmV4dCgpOyBpKyspIHsKLQkJCVBhaXIgcD0gKFBhaXIpIGl0ZXIubmV4dCgpOwotICAgIAkJaWYgKHAuZklkID09IGlkKQotICAgIAkJCXJldHVybiBpOwkJCQotCQl9Ci0JCXJldHVybiAtMTsKLQl9Ci0JCi0JLyoqCi0JICogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IHJvdyB0aGF0IG1hdGNoZXMgdGhlIGdpdmVuIHN0cmluZwotCSAqLwotCXByaXZhdGUgaW50IGdldEluZGV4KFN0cmluZyBzLCBpbnQgc3RhcnQpIHsKLQkJaWYgKHMgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQkJaW50IG49IGZEYXRhLnNpemUoKTsKLQkJZm9yIChpbnQgaT0gc3RhcnQ7IGkgPCBuOyBpKyspIHsKLQkJCVBhaXIgcD0gKFBhaXIpIGZEYXRhLmdldChpKTsKLQkJCWlmIChzLmVxdWFscyhwLmZWYWx1ZSkpCi0JCQkJcmV0dXJuIGk7Ci0JCX0KLQkJcmV0dXJuIC0xOwotCX0KLQkKLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBJRCBvZiB0aGUgZmlyc3Qgcm93IHRoYXQgbWF0Y2hlcyB0aGUgZ2l2ZW4gc3RyaW5nCi0JICovCi0JcHJpdmF0ZSBQYWlyIGdldFBhaXIoU3RyaW5nIHMpIHsKLQkJSXRlcmF0b3IgaXRlcj0gZkRhdGEuaXRlcmF0b3IoKTsKLQkJd2hpbGUgKGl0ZXIuaGFzTmV4dCgpKSB7Ci0JCQlQYWlyIHA9IChQYWlyKSBpdGVyLm5leHQoKTsKLSAgICAJCWlmIChzLmVxdWFscyhwLmZWYWx1ZSkpCi0gICAgCQkJcmV0dXJuIHA7Ci0gICAgCX0KLQkJcmV0dXJuIG51bGw7Ci0JfQotCQotCS8qKgotCSAqIFJldHVybnMgdGhlIElEIG9mIHRoZSBmaXJzdCByb3cgdGhhdCBtYXRjaGVzIHRoZSBnaXZlbiBzdHJpbmcKLQkgKi8KLQlwcml2YXRlIGludCBnZXRJRChTdHJpbmcgcykgewotCQlJdGVyYXRvciBpdGVyPSBmRGF0YS5pdGVyYXRvcigpOwotCQl3aGlsZSAoaXRlci5oYXNOZXh0KCkpIHsKLQkJCVBhaXIgcD0gKFBhaXIpIGl0ZXIubmV4dCgpOwotICAgIAkJaWYgKHMuZXF1YWxzKHAuZlZhbHVlKSkKLSAgICAJCQlyZXR1cm4gcC5mSWQ7Ci0gICAgCX0KLQkJcmV0dXJuIDA7Ci0JfQotCQotCXByaXZhdGUgaW50W10gZ2V0SWRzKGludFtdIGluZGljZXMpIHsKLQkJaW50IGNvdW50PSBmRGF0YS5zaXplKCk7Ci0JCWludFtdIGlkcz0gbmV3IGludFtpbmRpY2VzLmxlbmd0aF07Ci0JCWZvciAoaW50IGk9IDA7IGkgPCBpbmRpY2VzLmxlbmd0aDsgaSsrKSB7Ci0JCQlpbnQgaW5kZXg9IGluZGljZXNbaV07Ci0JCQlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDwgY291bnQpKSBicmVhazsKLQkJCVBhaXIgcD0gKFBhaXIpIGZEYXRhLmdldChpbmRleCk7Ci0JCQlpZHNbaV09IHAuZklkOwotCQl9Ci0JCXJldHVybiBpZHM7Ci0JfQotCQotCXByaXZhdGUgaW50W10gZ2V0SWRzKFN0cmluZ1tdIGl0ZW1zKSB7Ci0JCWludCBjb3VudD0gaXRlbXMubGVuZ3RoOwotCQlpbnRbXSBpZHM9IG5ldyBpbnRbY291bnRdOwotCQlmb3IgKGludCBpPTA7IGk8Y291bnQ7IGkrKykgewotCQkJaW50IGlkPSBnZXRJRChpdGVtc1tpXSk7Ci0JCQlpZHNbaV09IGlkOwotCQl9Ci0JCXJldHVybiBpZHM7Ci0JfQotCQotCXByaXZhdGUgaW50W10gZ2V0SWRzKGludCBzdGFydCwgaW50IGVuZCkgewotCQlpbnQgbj0gZkRhdGEuc2l6ZSgpOwotCQlpZiAoc3RhcnQgPCAwICYmIHN0YXJ0ID49IG4pCi0JCQllcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOwotCQlpZiAoZW5kID49IG4pCi0JCQllcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOwotCQlpbnQgY291bnQ9IGVuZC1zdGFydCsxOwotCQlpbnRbXSBpZHM9IG5ldyBpbnRbY291bnRdOwotCQlmb3IgKGludCBpPSAwOyBpIDwgY291bnQ7IGkrKykgewotCQkJUGFpciBwPSAoUGFpcikgZkRhdGEuZ2V0KHN0YXJ0K2kpOwotCQkJaWRzW2ldPSBwLmZJZDsKLQkJfQotCQlyZXR1cm4gaWRzOwotCX0KIH0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9NZW51LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvTWVudS5qYXZhCmluZGV4IGExOGIyMDYuLjM5NmUxZGQgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9NZW51LmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL01lbnUuamF2YQpAQCAtMTEsMTg5ICsxMSwzMiBAQAogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CiAKLS8qKgotICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgYXJlIHVzZXIgaW50ZXJmYWNlIG9iamVjdHMgdGhhdCBjb250YWluCi0gKiBtZW51IGl0ZW1zLgotICogPGRsPgotICogPGR0PjxiPlN0eWxlczo8L2I+PC9kdD4KLSAqIDxkZD5CQVIsIERST1BfRE9XTiwgUE9QX1VQPC9kZD4KLSAqIDxkdD48Yj5FdmVudHM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+SGVscCwgSGlkZSwgU2hvdyA8L2RkPgotICogPC9kbD4KLSAqIDxwPgotICogTm90ZTogT25seSBvbmUgb2YgQkFSLCBEUk9QX0RPV04gYW5kIFBPUF9VUCBtYXkgYmUgc3BlY2lmaWVkLgotICogPC9wPjxwPgotICogSU1QT1JUQU5UOiBUaGlzIGNsYXNzIGlzIDxlbT5ub3Q8L2VtPiBpbnRlbmRlZCB0byBiZSBzdWJjbGFzc2VkLgotICogPC9wPgotICovCiBwdWJsaWMgY2xhc3MgTWVudSBleHRlbmRzIFdpZGdldCB7CisJaW50IGhhbmRsZTsKKwlzaG9ydCBpZCwgbGFzdEluZGV4OwogCWludCB4LCB5OwotCXNob3J0IGxhc3RJbmRleDsKIAlib29sZWFuIGhhc0xvY2F0aW9uOwogCU1lbnVJdGVtIGNhc2NhZGUsIGRlZmF1bHRJdGVtOwogCURlY29yYXRpb25zIHBhcmVudDsKIAotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gaXRzIHBhcmVudCwKLSAqIGFuZCBzZXRzIHRoZSBzdHlsZSBmb3IgdGhlIGluc3RhbmNlIHNvIHRoYXQgdGhlIGluc3RhbmNlCi0gKiB3aWxsIGJlIGEgcG9wdXAgbWVudSBvbiB0aGUgZ2l2ZW4gcGFyZW50J3Mgc2hlbGwuCi0gKgotICogQHBhcmFtIHBhcmVudCBhIGNvbnRyb2wgd2hpY2ggd2lsbCBiZSB0aGUgcGFyZW50IG9mIHRoZSBuZXcgaW5zdGFuY2UgKGNhbm5vdCBiZSBudWxsKQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTV1QjUE9QX1VQCi0gKiBAc2VlIFdpZGdldCNjaGVja1N1YmNsYXNzCi0gKiBAc2VlIFdpZGdldCNnZXRTdHlsZQotICovCiBwdWJsaWMgTWVudSAoQ29udHJvbCBwYXJlbnQpIHsKIAl0aGlzIChjaGVja051bGwgKHBhcmVudCkuZ2V0U2hlbGwgKCksIFNXVC5QT1BfVVApOwogfQogCi0vKioKLSAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50Ci0gKiAod2hpY2ggbXVzdCBiZSBhIDxjb2RlPkRlY29yYXRpb25zPC9jb2RlPikgYW5kIGEgc3R5bGUgdmFsdWUKLSAqIGRlc2NyaWJpbmcgaXRzIGJlaGF2aW9yIGFuZCBhcHBlYXJhbmNlLgotICogPHA+Ci0gKiBUaGUgc3R5bGUgdmFsdWUgaXMgZWl0aGVyIG9uZSBvZiB0aGUgc3R5bGUgY29uc3RhbnRzIGRlZmluZWQgaW4KLSAqIGNsYXNzIDxjb2RlPlNXVDwvY29kZT4gd2hpY2ggaXMgYXBwbGljYWJsZSB0byBpbnN0YW5jZXMgb2YgdGhpcwotICogY2xhc3MsIG9yIG11c3QgYmUgYnVpbHQgYnkgPGVtPmJpdHdpc2UgT1I8L2VtPidpbmcgdG9nZXRoZXIgCi0gKiAodGhhdCBpcywgdXNpbmcgdGhlIDxjb2RlPmludDwvY29kZT4gInwiIG9wZXJhdG9yKSB0d28gb3IgbW9yZQotICogb2YgdGhvc2UgPGNvZGU+U1dUPC9jb2RlPiBzdHlsZSBjb25zdGFudHMuIFRoZSBjbGFzcyBkZXNjcmlwdGlvbgotICogbGlzdHMgdGhlIHN0eWxlIGNvbnN0YW50cyB0aGF0IGFyZSBhcHBsaWNhYmxlIHRvIHRoZSBjbGFzcy4KLSAqIFN0eWxlIGJpdHMgYXJlIGFsc28gaW5oZXJpdGVkIGZyb20gc3VwZXJjbGFzc2VzLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBkZWNvcmF0aW9ucyBjb250cm9sIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqIEBwYXJhbSBzdHlsZSB0aGUgc3R5bGUgb2YgbWVudSB0byBjb25zdHJ1Y3QKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU1dUI0JBUgotICogQHNlZSBTV1QjRFJPUF9ET1dOCi0gKiBAc2VlIFNXVCNQT1BfVVAKLSAqIEBzZWUgV2lkZ2V0I2NoZWNrU3ViY2xhc3MKLSAqIEBzZWUgV2lkZ2V0I2dldFN0eWxlCi0gKi8KIHB1YmxpYyBNZW51IChEZWNvcmF0aW9ucyBwYXJlbnQsIGludCBzdHlsZSkgewogCXN1cGVyIChwYXJlbnQsIGNoZWNrU3R5bGUgKHN0eWxlKSk7CiAJdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CiAJY3JlYXRlV2lkZ2V0ICgpOwogfQogCi0vKioKLSAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50Ci0gKiAod2hpY2ggbXVzdCBiZSBhIDxjb2RlPk1lbnU8L2NvZGU+KSBhbmQgc2V0cyB0aGUgc3R5bGUKLSAqIGZvciB0aGUgaW5zdGFuY2Ugc28gdGhhdCB0aGUgaW5zdGFuY2Ugd2lsbCBiZSBhIGRyb3AtZG93bgotICogbWVudSBvbiB0aGUgZ2l2ZW4gcGFyZW50J3MgcGFyZW50LgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBtZW51IHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU1dUI0RST1BfRE9XTgotICogQHNlZSBXaWRnZXQjY2hlY2tTdWJjbGFzcwotICogQHNlZSBXaWRnZXQjZ2V0U3R5bGUKLSAqLwogcHVibGljIE1lbnUgKE1lbnUgcGFyZW50TWVudSkgewogCXRoaXMgKGNoZWNrTnVsbCAocGFyZW50TWVudSkucGFyZW50LCBTV1QuRFJPUF9ET1dOKTsKIH0KIAotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gaXRzIHBhcmVudAotICogKHdoaWNoIG11c3QgYmUgYSA8Y29kZT5NZW51SXRlbTwvY29kZT4pIGFuZCBzZXRzIHRoZSBzdHlsZQotICogZm9yIHRoZSBpbnN0YW5jZSBzbyB0aGF0IHRoZSBpbnN0YW5jZSB3aWxsIGJlIGEgZHJvcC1kb3duCi0gKiBtZW51IG9uIHRoZSBnaXZlbiBwYXJlbnQncyBwYXJlbnQgbWVudS4KLSAqCi0gKiBAcGFyYW0gcGFyZW50IGEgbWVudSBpdGVtIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU1dUI0RST1BfRE9XTgotICogQHNlZSBXaWRnZXQjY2hlY2tTdWJjbGFzcwotICogQHNlZSBXaWRnZXQjZ2V0U3R5bGUKLSAqLwogcHVibGljIE1lbnUgKE1lbnVJdGVtIHBhcmVudEl0ZW0pIHsKIAl0aGlzIChjaGVja051bGwgKHBhcmVudEl0ZW0pLnBhcmVudCk7CiB9CiAKLS8qKgotICogQWRkcyB0aGUgbGlzdGVuZXIgdG8gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIGhlbHAgZXZlbnRzIGFyZSBnZW5lcmF0ZWQgZm9yIHRoZSBjb250cm9sLAotICogYnkgc2VuZGluZyBpdCBvbmUgb2YgdGhlIG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhlCi0gKiA8Y29kZT5IZWxwTGlzdGVuZXI8L2NvZGU+IGludGVyZmFjZS4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIEhlbHBMaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlSGVscExpc3RlbmVyCi0gKi8KLXB1YmxpYyB2b2lkIGFkZEhlbHBMaXN0ZW5lciAoSGVscExpc3RlbmVyIGxpc3RlbmVyKSB7Ci0JY2hlY2tXaWRnZXQgKCk7Ci0JaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0JVHlwZWRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IFR5cGVkTGlzdGVuZXIgKGxpc3RlbmVyKTsKLQlhZGRMaXN0ZW5lciAoU1dULkhlbHAsIHR5cGVkTGlzdGVuZXIpOwotfQotCi0vKioKLSAqIEFkZHMgdGhlIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiBtZW51cyBhcmUgaGlkZGVuIG9yIHNob3duLCBieSBzZW5kaW5nIGl0Ci0gKiBvbmUgb2YgdGhlIG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhlIDxjb2RlPk1lbnVMaXN0ZW5lcjwvY29kZT4KLSAqIGludGVyZmFjZS4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIE1lbnVMaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlTWVudUxpc3RlbmVyCi0gKi8KLXB1YmxpYyB2b2lkIGFkZE1lbnVMaXN0ZW5lciAoTWVudUxpc3RlbmVyIGxpc3RlbmVyKSB7Ci0JY2hlY2tXaWRnZXQgKCk7Ci0JaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7Ci0JVHlwZWRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IFR5cGVkTGlzdGVuZXIgKGxpc3RlbmVyKTsKLQlhZGRMaXN0ZW5lciAoU1dULkhpZGUsdHlwZWRMaXN0ZW5lcik7Ci0JYWRkTGlzdGVuZXIgKFNXVC5TaG93LHR5cGVkTGlzdGVuZXIpOwotfQotCiBzdGF0aWMgQ29udHJvbCBjaGVja051bGwgKENvbnRyb2wgY29udHJvbCkgewogCWlmIChjb250cm9sID09IG51bGwpIFNXVC5lcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCXJldHVybiBjb250cm9sOwpAQCAtMjEzLDExOSArNTYsOTcgQEAKIAlyZXR1cm4gY2hlY2tCaXRzIChzdHlsZSwgU1dULlBPUF9VUCwgU1dULkJBUiwgU1dULkRST1BfRE9XTiwgMCwgMCwgMCk7CiB9CiAKK3B1YmxpYyB2b2lkIF9zZXRWaXNpYmxlIChib29sZWFuIHZpc2libGUpIHsKKwlpZiAoKHN0eWxlICYgKFNXVC5CQVIgfCBTV1QuRFJPUF9ET1dOKSkgIT0gMCkgcmV0dXJuOworCWlmICghdmlzaWJsZSkgcmV0dXJuOworCWludCBsZWZ0ID0geCwgdG9wID0geTsKKwlpZiAoIWhhc0xvY2F0aW9uKSB7CisJCW9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgd2hlcmUgPSBuZXcgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCAoKTsKKwkJT1MuR2V0R2xvYmFsTW91c2UgKHdoZXJlKTsKKwkJbGVmdCA9IHdoZXJlLmg7IHRvcCA9IHdoZXJlLnY7CisJfQorCWludCBpbmRleCA9IGRlZmF1bHRJdGVtICE9IG51bGwgPyBpbmRleE9mIChkZWZhdWx0SXRlbSkgKyAxIDogbGFzdEluZGV4OworCWludCByZXN1bHQgPSBPUy5Qb3BVcE1lbnVTZWxlY3QgKGhhbmRsZSwgKHNob3J0KXRvcCwgKHNob3J0KWxlZnQsIChzaG9ydCkoaW5kZXgpKTsKKwlsYXN0SW5kZXggPSBPUy5Mb1dvcmQgKHJlc3VsdCk7Cit9CisKK3B1YmxpYyB2b2lkIGFkZEhlbHBMaXN0ZW5lciAoSGVscExpc3RlbmVyIGxpc3RlbmVyKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJVHlwZWRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IFR5cGVkTGlzdGVuZXIgKGxpc3RlbmVyKTsKKwlhZGRMaXN0ZW5lciAoU1dULkhlbHAsIHR5cGVkTGlzdGVuZXIpOworfQorCitwdWJsaWMgdm9pZCBhZGRNZW51TGlzdGVuZXIgKE1lbnVMaXN0ZW5lciBsaXN0ZW5lcikgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCVR5cGVkTGlzdGVuZXIgdHlwZWRMaXN0ZW5lciA9IG5ldyBUeXBlZExpc3RlbmVyIChsaXN0ZW5lcik7CisJYWRkTGlzdGVuZXIgKFNXVC5IaWRlLHR5cGVkTGlzdGVuZXIpOworCWFkZExpc3RlbmVyIChTV1QuU2hvdyx0eXBlZExpc3RlbmVyKTsKK30KKwogdm9pZCBjcmVhdGVIYW5kbGUgKCkgewotCXN0YXRlIHw9IEhJRERFTjsKLQlEaXNwbGF5IGRpc3BsYXk9IGdldERpc3BsYXkoKTsKLQlpbnQgbWVudUhhbmRsZVtdPSBuZXcgaW50WzFdOwotCWlmIChPUy5DcmVhdGVOZXdNZW51KGRpc3BsYXkubmV4dE1lbnVJZCgpLCAwLCBtZW51SGFuZGxlKSA9PSBPUy5rTm9FcnIpCi0JCWhhbmRsZT0gbWVudUhhbmRsZVswXTsKLQlpZiAoaGFuZGxlID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JT1MuUmV0YWluTWVudShoYW5kbGUpOwotCWludFtdIG1hc2sgPSBuZXcgaW50W10gewotCQlPUy5rRXZlbnRDbGFzc01lbnUsIE9TLmtFdmVudE1lbnVPcGVuaW5nLAotCQlPUy5rRXZlbnRDbGFzc01lbnUsIE9TLmtFdmVudE1lbnVDbG9zZWQKLQl9OwotCS8vT1MuSW5zdGFsbEV2ZW50SGFuZGxlcihPUy5HZXRNZW51RXZlbnRUYXJnZXQoaGFuZGxlKSwgZGlzcGxheS5mTWVudVByb2MsIG1hc2subGVuZ3RoIC8gMiwgbWFzaywgaGFuZGxlLCBudWxsKTsKLQlPUy5JbnN0YWxsRXZlbnRIYW5kbGVyKE9TLkdldE1lbnVFdmVudFRhcmdldChoYW5kbGUpLCBkaXNwbGF5LmZNZW51UHJvYywgbWFzaywgaGFuZGxlKTsKKwlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCWludCBtZW51UHJvYyA9IGRpc3BsYXkubWVudVByb2M7CisJZGlzcGxheS5hZGRNZW51ICh0aGlzKTsKKwlpbnQgb3V0TWVudVJlZiBbXSA9IG5ldyBpbnQgWzFdOworCU9TLkNyZWF0ZU5ld01lbnUgKGlkLCAwLCBvdXRNZW51UmVmKTsKKwlpZiAob3V0TWVudVJlZiBbMF0gPT0gMCkgeworCQlkaXNwbGF5LnJlbW92ZU1lbnUgKHRoaXMpOworCQllcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCX0KKwloYW5kbGUgPSBvdXRNZW51UmVmIFswXTsKIH0KIAogdm9pZCBjcmVhdGVJdGVtIChNZW51SXRlbSBpdGVtLCBpbnQgaW5kZXgpIHsKIAljaGVja1dpZGdldCAoKTsKIAlpbnQgY291bnQgPSBPUy5Db3VudE1lbnVJdGVtcyAoaGFuZGxlKTsKIAlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDw9IGNvdW50KSkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1JBTkdFKTsKLQlwYXJlbnQuYWRkIChpdGVtKTsKLQlib29sZWFuIHN1Y2Nlc3MgPSBmYWxzZTsKLQkvKgotCWlmIChPUy5Jc1dpbkNFKSB7Ci0JCWludCBmbGFncyA9IE9TLk1GX0JZUE9TSVRJT047Ci0JCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSBmbGFncyB8PSBPUy5NRl9TRVBBUkFUT1I7Ci0JCXN1Y2Nlc3MgPSBPUy5JbnNlcnRNZW51IChoYW5kbGUsIGluZGV4LCBmbGFncywgaXRlbS5pZCwgbnVsbCk7IAotCX0gZWxzZSB7Ci0JCWludCBoSGVhcCA9IE9TLkdldFByb2Nlc3NIZWFwICgpOwotCQlpbnQgcHN6VGV4dCA9IE9TLkhlYXBBbGxvYyAoaEhlYXAsIE9TLkhFQVBfWkVST19NRU1PUlksIFRDSEFSLnNpemVvZik7Ci0JCU1FTlVJVEVNSU5GTyBpbmZvID0gbmV3IE1FTlVJVEVNSU5GTyAoKTsKLQkJaW5mby5jYlNpemUgPSBNRU5VSVRFTUlORk8uc2l6ZW9mOwotCQlpbmZvLmZNYXNrID0gT1MuTUlJTV9JRCB8IE9TLk1JSU1fVFlQRTsKLQkJaW5mby53SUQgPSBpdGVtLmlkOwotCQlpbmZvLmZUeXBlID0gaXRlbS53aWRnZXRTdHlsZSAoKTsKLQkJaW5mby5kd1R5cGVEYXRhID0gcHN6VGV4dDsKLQkJc3VjY2VzcyA9IE9TLkluc2VydE1lbnVJdGVtIChoYW5kbGUsIGluZGV4LCB0cnVlLCBpbmZvKTsKLQkJaWYgKHBzelRleHQgIT0gMCkgT1MuSGVhcEZyZWUgKGhIZWFwLCAwLCBwc3pUZXh0KTsKLQl9Ci0JKi8KLQkKLQkvKgotCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSByZXR1cm4gT1MuTUZUX1NFUEFSQVRPUjsKLQlpZiAoKHN0eWxlICYgU1dULlJBRElPKSAhPSAwKSByZXR1cm4gT1MuTUZUX1JBRElPQ0hFQ0s7Ci0JcmV0dXJuIE9TLk1GVF9TVFJJTkc7Ci0JKi8KLQkKLQlpbnQgYXR0cmlidXRlcz0gMDsKLQlpZiAoKGl0ZW0uc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSAKLQkJYXR0cmlidXRlcz0gT1Mua01lbnVJdGVtQXR0clNlcGFyYXRvcjsKLQlpZiAoT1MuSW5zZXJ0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nKGhhbmRsZSwgMCwgKHNob3J0KSBpbmRleCwgYXR0cmlidXRlcywgaXRlbS5pZCkgPT0gT1Mua05vRXJyKQotCQlzdWNjZXNzPSB0cnVlOwotCQotCWlmICghc3VjY2VzcykgewotCQlwYXJlbnQucmVtb3ZlIChpdGVtKTsKKwlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCWRpc3BsYXkuYWRkTWVudUl0ZW0gKGl0ZW0pOworCWludCBhdHRyaWJ1dGVzID0gMDsKKwlpZiAoKGl0ZW0uc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSBhdHRyaWJ1dGVzID0gT1Mua01lbnVJdGVtQXR0clNlcGFyYXRvcjsKKwlpbnQgcmVzdWx0ID0gT1MuSW5zZXJ0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nIChoYW5kbGUsIDAsIChzaG9ydCkgaW5kZXgsIGF0dHJpYnV0ZXMsIGl0ZW0uaWQpOworCWlmIChyZXN1bHQgIT0gT1Mubm9FcnIpIHsKKwkJZGlzcGxheS5yZW1vdmVNZW51SXRlbSAoaXRlbSk7CiAJCWVycm9yIChTV1QuRVJST1JfSVRFTV9OT1RfQURERUQpOwogCX0KLQkvKiBBVwkKLQlyZWRyYXcgKCk7Ci0JKi8KLX0KLQotdm9pZCBjcmVhdGVXaWRnZXQgKCkgewotCWNyZWF0ZUhhbmRsZSAoKTsKLQlwYXJlbnQuYWRkICh0aGlzKTsKLQlyZWdpc3RlciAoKTsKLX0KLQotdm9pZCBkZXN0cm95QWNjZWxlcmF0b3JUYWJsZSAoKSB7Ci0JLyogQVcKLQlwYXJlbnQuZGVzdHJveUFjY2VsZXJhdG9yVGFibGUgKCk7Ci0JKi8KKwlpZiAoKHN0eWxlICYgU1dULkJBUikgIT0gMCkgeworLy8JCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisvLwkJc2hvcnQgbWVudUlEID0gZGlzcGxheS5uZXh0TWVudUlkICgpOworLy8JCWludCBvdXRNZW51UmVmIFtdID0gbmV3IGludCBbMV07CisvLwkJaWYgKE9TLkNyZWF0ZU5ld01lbnUgKG1lbnVJRCwgMCwgb3V0TWVudVJlZikgIT0gT1Mubm9FcnIpIHsKKy8vCQkJZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKy8vCQl9CisvLwkJT1MuU2V0TWVudUl0ZW1IaWVyYXJjaGljYWxNZW51IChoYW5kbGUsIChzaG9ydCkgKGluZGV4ICsgMSksIG91dE1lbnVSZWYgWzBdKTsKKwl9CiB9CiAKIHZvaWQgZGVzdHJveUl0ZW0gKE1lbnVJdGVtIGl0ZW0pIHsKLQkvKiBBVwotCWlmICghT1MuUmVtb3ZlTWVudSAoaGFuZGxlLCBpdGVtLmlkLCBPUy5NRl9CWUNPTU1BTkQpKSB7CisJc2hvcnQgW10gb3V0SW5kZXggPSBuZXcgc2hvcnQgWzFdOworCWlmIChPUy5HZXRJbmRNZW51SXRlbVdpdGhDb21tYW5kSUQgKGhhbmRsZSwgaXRlbS5pZCwgMSwgbnVsbCwgb3V0SW5kZXgpICE9IE9TLm5vRXJyKSB7CiAJCWVycm9yIChTV1QuRVJST1JfSVRFTV9OT1RfUkVNT1ZFRCk7CiAJfQotCSovCi0Jc2hvcnRbXSBpbmRleD0gbmV3IHNob3J0WzFdOwotCU9TLkdldEluZE1lbnVJdGVtV2l0aENvbW1hbmRJRChoYW5kbGUsIGl0ZW0uaWQsIDEsIG51bGwsIGluZGV4KTsKLQlpZiAoaW5kZXhbMF0gPj0gMSkgewotCQlPUy5EZWxldGVNZW51SXRlbShoYW5kbGUsIGluZGV4WzBdKTsKLQl9IGVsc2UKLQkJZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9SRU1PVkVEKTsKLQkKLQlyZWRyYXcgKCk7CisJaWYgKChzdHlsZSAmIFNXVC5CQVIpICE9IDApIHsKKy8vCQlpbnQgW10gb3V0TWVudVJlZiA9IG5ldyBpbnQgWzFdOworLy8JCU9TLkdldE1lbnVJdGVtSGllcmFyY2hpY2FsTWVudSAoaGFuZGxlLCBvdXRJbmRleCBbMF0sIG91dE1lbnVSZWYpOworLy8JCWlmIChvdXRNZW51UmVmIFswXSAhPSAwKSB7CisvLwkJCU9TLkRlbGV0ZU1lbnUgKE9TLkdldE1lbnVJRCAob3V0TWVudVJlZiBbMF0pKTsKKy8vCQkJT1MuRGlzcG9zZU1lbnUgKG91dE1lbnVSZWYgWzBdKTsKKy8vCQl9CisJfQorCU9TLkRlbGV0ZU1lbnVJdGVtIChoYW5kbGUsIG91dEluZGV4IFswXSk7CiB9CiAKIHZvaWQgZGVzdHJveVdpZGdldCAoKSB7Ci0JaW50IGhNZW51ID0gaGFuZGxlOworCWludCB0aGVNZW51ID0gaGFuZGxlOwogCXJlbGVhc2VIYW5kbGUgKCk7Ci0JaWYgKGhNZW51ICE9IDApIHsKLQkJLyogQVcKLQkJT1MuRGVzdHJveU1lbnUgKGhNZW51KTsKLQkJKi8KLQkJT1MuRGlzcG9zZU1lbnUgKGhNZW51KTsKKwlpZiAodGhlTWVudSAhPSAwKSB7CisJCU9TLkRlbGV0ZU1lbnUgKE9TLkdldE1lbnVJRCAodGhlTWVudSkpOworCQlPUy5EaXNwb3NlTWVudSAodGhlTWVudSk7CiAJfQogfQogCi0vKioKLSAqIFJldHVybnMgdGhlIGRlZmF1bHQgbWVudSBpdGVtIG9yIG51bGwgaWYgbm9uZSBoYXMKLSAqIGJlZW4gcHJldmlvdXNseSBzZXQuCi0gKgotICogQHJldHVybiB0aGUgZGVmYXVsdCBtZW51IGl0ZW0uCi0gKgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIE1lbnVJdGVtIGdldERlZmF1bHRJdGVtICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBkZWZhdWx0SXRlbTsKQEAgLTMzNywxMDcgKzE1OCwzOSBAQAogCXJldHVybiBwYXJlbnQuZ2V0RGlzcGxheSAoKTsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSByZWNlaXZlciBpcyBlbmFibGVkLCBhbmQKLSAqIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuIEEgZGlzYWJsZWQgY29udHJvbCBpcyB0eXBpY2FsbHkKLSAqIG5vdCBzZWxlY3RhYmxlIGZyb20gdGhlIHVzZXIgaW50ZXJmYWNlIGFuZCBkcmF3cyB3aXRoIGFuCi0gKiBpbmFjdGl2ZSBvciAiZ3JheWVkIiBsb29rLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgZW5hYmxlZCBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIGJvb2xlYW4gZ2V0RW5hYmxlZCAoKSB7Ci0JY2hlY2tXaWRnZXQgKCk7Ci0JLyogQVcKKwljaGVja1dpZGdldCgpOwogCXJldHVybiAoc3RhdGUgJiBESVNBQkxFRCkgPT0gMDsKLQkqLwotCXJldHVybiBPUy5Jc01lbnVJdGVtRW5hYmxlZChoYW5kbGUsIChzaG9ydCkwKTsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIHRoZSBpdGVtIGF0IHRoZSBnaXZlbiwgemVyby1yZWxhdGl2ZSBpbmRleCBpbiB0aGUKLSAqIHJlY2VpdmVyLiBUaHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZSBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuCi0gKgotICogQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgaXRlbSB0byByZXR1cm4KLSAqIEByZXR1cm4gdGhlIGl0ZW0gYXQgdGhlIGdpdmVuIGluZGV4Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfUkFOR0UgLSBpZiB0aGUgaW5kZXggaXMgbm90IGJldHdlZW4gMCBhbmQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgbGlzdCBtaW51cyAxIChpbmNsdXNpdmUpPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyBNZW51SXRlbSBnZXRJdGVtIChpbnQgaW5kZXgpIHsKIAljaGVja1dpZGdldCAoKTsKLQlpbnRbXSBjb21tYW5kSUQ9IG5ldyBpbnRbMV07Ci0JaWYgKE9TLkdldE1lbnVJdGVtQ29tbWFuZElEKGhhbmRsZSwgKHNob3J0KShpbmRleCsxKSwgY29tbWFuZElEKSAhPSBPUy5rTm9FcnIpCisJaW50IFtdIG91dENvbW1hbmRJRD0gbmV3IGludCBbMV07CisJaWYgKE9TLkdldE1lbnVJdGVtQ29tbWFuZElEIChoYW5kbGUsIChzaG9ydCkoaW5kZXgrMSksIG91dENvbW1hbmRJRCkgIT0gT1Mubm9FcnIpIHsKIAkJZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1JBTkdFKTsKLQlyZXR1cm4gcGFyZW50LmZpbmRNZW51SXRlbSAoY29tbWFuZElEWzBdKTsKKwl9CisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlyZXR1cm4gZGlzcGxheS5maW5kTWVudUl0ZW0gKG91dENvbW1hbmRJRFswXSk7CiB9CiAKLS8qKgotICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGl0ZW1zIGNvbnRhaW5lZCBpbiB0aGUgcmVjZWl2ZXIuCi0gKgotICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGl0ZW1zCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCiBwdWJsaWMgaW50IGdldEl0ZW1Db3VudCAoKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJcmV0dXJuIE9TLkNvdW50TWVudUl0ZW1zIChoYW5kbGUpOwogfQogCi0vKioKLSAqIFJldHVybnMgYW4gYXJyYXkgb2YgPGNvZGU+TWVudUl0ZW08L2NvZGU+cyB3aGljaCBhcmUgdGhlIGl0ZW1zCi0gKiBpbiB0aGUgcmVjZWl2ZXIuIAotICogPHA+Ci0gKiBOb3RlOiBUaGlzIGlzIG5vdCB0aGUgYWN0dWFsIHN0cnVjdHVyZSB1c2VkIGJ5IHRoZSByZWNlaXZlcgotICogdG8gbWFpbnRhaW4gaXRzIGxpc3Qgb2YgaXRlbXMsIHNvIG1vZGlmeWluZyB0aGUgYXJyYXkgd2lsbAotICogbm90IGFmZmVjdCB0aGUgcmVjZWl2ZXIuIAotICogPC9wPgotICoKLSAqIEByZXR1cm4gdGhlIGl0ZW1zIGluIHRoZSByZWNlaXZlcgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIE1lbnVJdGVtIFtdIGdldEl0ZW1zICgpIHsKIAljaGVja1dpZGdldCAoKTsKLQlpbnQgaW5kZXggPSAwOwotCWludCBsZW5ndGggPSBPUy5Db3VudE1lbnVJdGVtcyhoYW5kbGUpOworCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisJaW50IGxlbmd0aCA9IE9TLkNvdW50TWVudUl0ZW1zIChoYW5kbGUpOwogCU1lbnVJdGVtIFtdIGl0ZW1zID0gbmV3IE1lbnVJdGVtIFtsZW5ndGhdOwotCS8qIEFXCi0JTUVOVUlURU1JTkZPIGluZm8gPSBuZXcgTUVOVUlURU1JTkZPICgpOwotCWluZm8uY2JTaXplID0gTUVOVUlURU1JTkZPLnNpemVvZjsKLQlpbmZvLmZNYXNrID0gT1MuTUlJTV9JRDsKLQl3aGlsZSAoT1MuR2V0TWVudUl0ZW1JbmZvIChoYW5kbGUsIGluZGV4LCB0cnVlLCBpbmZvKSkgewotCSovCi0JaW50W10gY29tbWFuZElEPSBuZXcgaW50WzFdOwkKLQl3aGlsZSAoT1MuR2V0TWVudUl0ZW1Db21tYW5kSUQoaGFuZGxlLCAoc2hvcnQpKGluZGV4KzEpLCBjb21tYW5kSUQpID09IE9TLmtOb0VycikgewotCQlpZiAoaW5kZXggPT0gaXRlbXMubGVuZ3RoKSB7Ci0JCQlNZW51SXRlbSBbXSBuZXdJdGVtcyA9IG5ldyBNZW51SXRlbSBbaW5kZXggKyA0XTsKLQkJCVN5c3RlbS5hcnJheWNvcHkgKG5ld0l0ZW1zLCAwLCBpdGVtcywgMCwgaW5kZXgpOwotCQkJaXRlbXMgPSBuZXdJdGVtczsKKwlpbnQgW10gb3V0Q29tbWFuZElEPSBuZXcgaW50IFsxXTsJCisJZm9yIChpbnQgaT0wOyBpPGl0ZW1zLmxlbmd0aDsgaSsrKSB7CisJCWlmIChPUy5HZXRNZW51SXRlbUNvbW1hbmRJRCAoaGFuZGxlLCAoc2hvcnQpKGkrMSksIG91dENvbW1hbmRJRCkgIT0gT1Mubm9FcnIpIHsKKwkJCWVycm9yIChTV1QuRVJST1JfQ0FOTk9UX0dFVF9JVEVNKTsKIAkJfQotCQlpdGVtcyBbaW5kZXhdID0gcGFyZW50LmZpbmRNZW51SXRlbSAoY29tbWFuZElEIFswXSk7Ci0JCWlmIChpdGVtcyBbaW5kZXhdICE9IG51bGwpCi0JCQlpbmRleCsrOworCQlpdGVtcyBbaV0gPSBkaXNwbGF5LmZpbmRNZW51SXRlbSAob3V0Q29tbWFuZElEIFswXSk7CiAJfQotCWlmIChpbmRleCA9PSBpdGVtcy5sZW5ndGgpIHJldHVybiBpdGVtczsKLQlNZW51SXRlbSBbXSByZXN1bHQgPSBuZXcgTWVudUl0ZW0gW2luZGV4XTsKLQlTeXN0ZW0uYXJyYXljb3B5IChyZXN1bHQsIDAsIGl0ZW1zLCAwLCBpbmRleCk7Ci0JcmV0dXJuIHJlc3VsdDsKKwlyZXR1cm4gaXRlbXM7CiB9CiAKIFN0cmluZyBnZXROYW1lVGV4dCAoKSB7CkBAIC00NTMsMTU3ICsyMDYsNzcgQEAKIAlyZXR1cm4gcmVzdWx0OwogfQogCi0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3MgcGFyZW50LCB3aGljaCBtdXN0IGJlIGEgPGNvZGU+RGVjb3JhdGlvbnM8L2NvZGU+LgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgcGFyZW50Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCiBwdWJsaWMgRGVjb3JhdGlvbnMgZ2V0UGFyZW50ICgpIHsKIAljaGVja1dpZGdldCAoKTsKIAlyZXR1cm4gcGFyZW50OwogfQogCi0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3MgcGFyZW50IGl0ZW0sIHdoaWNoIG11c3QgYmUgYQotICogPGNvZGU+TWVudUl0ZW08L2NvZGU+IG9yIG51bGwgd2hlbiB0aGUgcmVjZWl2ZXIgaXMgYQotICogcm9vdC4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIHBhcmVudCBpdGVtCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCiBwdWJsaWMgTWVudUl0ZW0gZ2V0UGFyZW50SXRlbSAoKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJcmV0dXJuIGNhc2NhZGU7CiB9CiAKLS8qKgotICogUmV0dXJucyB0aGUgcmVjZWl2ZXIncyBwYXJlbnQgaXRlbSwgd2hpY2ggbXVzdCBiZSBhCi0gKiA8Y29kZT5NZW51PC9jb2RlPiBvciBudWxsIHdoZW4gdGhlIHJlY2VpdmVyIGlzIGEKLSAqIHJvb3QuCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBwYXJlbnQgaXRlbQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIE1lbnUgZ2V0UGFyZW50TWVudSAoKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJaWYgKGNhc2NhZGUgIT0gbnVsbCkgcmV0dXJuIGNhc2NhZGUucGFyZW50OwogCXJldHVybiBudWxsOwogfQogCi0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3Mgc2hlbGwuIEZvciBhbGwgY29udHJvbHMgb3RoZXIgdGhhbgotICogc2hlbGxzLCB0aGlzIHNpbXBseSByZXR1cm5zIHRoZSBjb250cm9sJ3MgbmVhcmVzdCBhbmNlc3RvcgotICogc2hlbGwuIFNoZWxscyByZXR1cm4gdGhlbXNlbHZlcywgZXZlbiBpZiB0aGV5IGFyZSBjaGlsZHJlbgotICogb2Ygb3RoZXIgc2hlbGxzLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3Mgc2hlbGwKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjZ2V0UGFyZW50Ci0gKi8KIHB1YmxpYyBTaGVsbCBnZXRTaGVsbCAoKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJcmV0dXJuIHBhcmVudC5nZXRTaGVsbCAoKTsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSByZWNlaXZlciBpcyB2aXNpYmxlLCBhbmQKLSAqIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gKiA8cD4KLSAqIElmIG9uZSBvZiB0aGUgcmVjZWl2ZXIncyBhbmNlc3RvcnMgaXMgbm90IHZpc2libGUgb3Igc29tZQotICogb3RoZXIgY29uZGl0aW9uIG1ha2VzIHRoZSByZWNlaXZlciBub3QgdmlzaWJsZSwgdGhpcyBtZXRob2QKLSAqIG1heSBzdGlsbCBpbmRpY2F0ZSB0aGF0IGl0IGlzIGNvbnNpZGVyZWQgdmlzaWJsZSBldmVuIHRob3VnaAotICogaXQgbWF5IG5vdCBhY3R1YWxseSBiZSBzaG93aW5nLgotICogPC9wPgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgdmlzaWJpbGl0eSBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIGJvb2xlYW4gZ2V0VmlzaWJsZSAoKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJaWYgKChzdHlsZSAmIFNXVC5CQVIpICE9IDApIHsKIAkJcmV0dXJuIHRoaXMgPT0gcGFyZW50Lm1lbnVTaGVsbCAoKS5tZW51QmFyOwogCX0KLQlyZXR1cm4gKHN0YXRlICYgSElEREVOKSA9PSAwOworCWlmICgoc3R5bGUgJiBTV1QuUE9QX1VQKSAhPSAwKSB7CisJCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisJCU1lbnUgW10gcG9wdXBzID0gZGlzcGxheS5wb3B1cHM7CisJCWlmIChwb3B1cHMgPT0gbnVsbCkgcmV0dXJuIGZhbHNlOworCQlmb3IgKGludCBpPTA7IGk8cG9wdXBzLmxlbmd0aDsgaSsrKSB7CisJCQlpZiAocG9wdXBzIFtpXSA9PSB0aGlzKSByZXR1cm4gdHJ1ZTsKKwkJfQorCX0KKwlNZW51VHJhY2tpbmdEYXRhIG91dERhdGEgPSBuZXcgTWVudVRyYWNraW5nRGF0YSAoKTsKKwlyZXR1cm4gT1MuR2V0TWVudVRyYWNraW5nRGF0YSAoaGFuZGxlLCBvdXREYXRhKSA9PSBPUy5ub0VycjsKIH0KIAotLyoqCi0gKiBTZWFyY2hlcyB0aGUgcmVjZWl2ZXIncyBsaXN0IHN0YXJ0aW5nIGF0IHRoZSBmaXJzdCBpdGVtCi0gKiAoaW5kZXggMCkgdW50aWwgYW4gaXRlbSBpcyBmb3VuZCB0aGF0IGlzIGVxdWFsIHRvIHRoZSAKLSAqIGFyZ3VtZW50LCBhbmQgcmV0dXJucyB0aGUgaW5kZXggb2YgdGhhdCBpdGVtLiBJZiBubyBpdGVtCi0gKiBpcyBmb3VuZCwgcmV0dXJucyAtMS4KLSAqCi0gKiBAcGFyYW0gaXRlbSB0aGUgc2VhcmNoIGl0ZW0KLSAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBpdGVtCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgc3RyaW5nIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwordm9pZCBob29rRXZlbnRzICgpIHsKKwlzdXBlci5ob29rRXZlbnRzICgpOworCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisJaW50IG1lbnVQcm9jID0gZGlzcGxheS5tZW51UHJvYzsKKwlpbnQgW10gbWFzayA9IG5ldyBpbnQgW10geworCQlPUy5rRXZlbnRDbGFzc01lbnUsIE9TLmtFdmVudE1lbnVPcGVuaW5nLAorCQlPUy5rRXZlbnRDbGFzc01lbnUsIE9TLmtFdmVudE1lbnVDbG9zZWQsCisJfTsKKwlpbnQgbWVudVRhcmdldCA9IE9TLkdldE1lbnVFdmVudFRhcmdldCAoaGFuZGxlKTsKKwlPUy5JbnN0YWxsRXZlbnRIYW5kbGVyIChtZW51VGFyZ2V0LCBtZW51UHJvYywgbWFzay5sZW5ndGggLyAyLCBtYXNrLCAwLCBudWxsKTsKK30KKworaW50IGtFdmVudE1lbnVDbG9zZWQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlzZW5kRXZlbnQgKFNXVC5IaWRlKTsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50TWVudU9wZW5pbmcgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlzZW5kRXZlbnQgKFNXVC5TaG93KTsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCiBwdWJsaWMgaW50IGluZGV4T2YgKE1lbnVJdGVtIGl0ZW0pIHsKIAljaGVja1dpZGdldCAoKTsKIAlpZiAoaXRlbSA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCQotCS8qIEFXCi0JaW50IGluZGV4ID0gMDsKLQlNRU5VSVRFTUlORk8gaW5mbyA9IG5ldyBNRU5VSVRFTUlORk8gKCk7Ci0JaW5mby5jYlNpemUgPSBNRU5VSVRFTUlORk8uc2l6ZW9mOwotCWluZm8uZk1hc2sgPSBPUy5NSUlNX0lEOwotCXdoaWxlIChPUy5HZXRNZW51SXRlbUluZm8gKGhhbmRsZSwgaW5kZXgsIHRydWUsIGluZm8pKSB7Ci0JCWlmIChpbmZvLndJRCA9PSBpdGVtLmlkKSByZXR1cm4gaW5kZXg7Ci0JCWluZGV4Kys7Ci0JfQotCSovCi0JCi0JaW50W10gbWVudT0gbmV3IGludFsxXTsKLQlzaG9ydFtdIGluZGV4PSBuZXcgc2hvcnRbMV07Ci0JaWYgKE9TLkdldEluZE1lbnVJdGVtV2l0aENvbW1hbmRJRChoYW5kbGUsIGl0ZW0uaWQsIDEsIG1lbnUsIGluZGV4KSA9PSBPUy5rTm9FcnIpIHsKLQkJaWYgKGhhbmRsZSA9PSBtZW51WzBdKQkvLyBlbnN1cmUgdGhhdCB3ZSBmb3VuZCBpdGVtIG5vdCBpbiBzdWJtZW51Ci0JCQlyZXR1cm4gaW5kZXhbMF07Ci0JfQorCWludCBbXSBvdXRNZW51ID0gbmV3IGludCBbMV07CisJc2hvcnQgW10gb3V0SW5kZXggPSBuZXcgc2hvcnQgWzFdOworCWlmIChPUy5HZXRJbmRNZW51SXRlbVdpdGhDb21tYW5kSUQgKGhhbmRsZSwgaXRlbS5pZCwgMSwgb3V0TWVudSwgb3V0SW5kZXgpID09IE9TLm5vRXJyKSB7CisJCXJldHVybiBoYW5kbGUgPT0gb3V0TWVudSBbMF0gPyBvdXRJbmRleCBbMF0gLSAxIDogMDsKKwl9CQogCXJldHVybiAtMTsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSByZWNlaXZlciBpcyBlbmFibGVkIGFuZCBhbGwKLSAqIG9mIHRoZSByZWNlaXZlcidzIGFuY2VzdG9ycyBhcmUgZW5hYmxlZCwgYW5kIDxjb2RlPmZhbHNlPC9jb2RlPgotICogb3RoZXJ3aXNlLiBBIGRpc2FibGVkIGNvbnRyb2wgaXMgdHlwaWNhbGx5IG5vdCBzZWxlY3RhYmxlIGZyb20gdGhlCi0gKiB1c2VyIGludGVyZmFjZSBhbmQgZHJhd3Mgd2l0aCBhbiBpbmFjdGl2ZSBvciAiZ3JheWVkIiBsb29rLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgZW5hYmxlZCBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqIAotICogQHNlZSAjZ2V0RW5hYmxlZAotICovCiBwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWQgKCkgewogCWNoZWNrV2lkZ2V0ICgpOwogCU1lbnUgcGFyZW50TWVudSA9IGdldFBhcmVudE1lbnUgKCk7CkBAIC02MTEsNzIgKzI4NCwxMSBAQAogCXJldHVybiBnZXRFbmFibGVkICgpICYmIHBhcmVudE1lbnUuaXNFbmFibGVkICgpOwogfQogCi0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGlzIHZpc2libGUgYW5kIGFsbAotICogb2YgdGhlIHJlY2VpdmVyJ3MgYW5jZXN0b3JzIGFyZSB2aXNpYmxlIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4KLSAqIG90aGVyd2lzZS4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIHZpc2liaWxpdHkgc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjZ2V0VmlzaWJsZQotICovCiBwdWJsaWMgYm9vbGVhbiBpc1Zpc2libGUgKCkgewogCWNoZWNrV2lkZ2V0ICgpOwogCXJldHVybiBnZXRWaXNpYmxlICgpOwogfQogCi1pbnQgcHJvY2Vzc0hpZGUgKE9iamVjdCBjYWxsRGF0YSkgewotCS8vc2VuZEV2ZW50IChTV1QuSGlkZSk7Ci0Jc3RhdGUgfD0gSElEREVOOwotCXBvc3RFdmVudCAoU1dULkhpZGUpOwkvLyBmaXggZm9yICMyMzk0NwotCXJldHVybiAwOwotfQotCi1pbnQgcHJvY2Vzc1Nob3cgKE9iamVjdCBjYWxsRGF0YSkgewotCXN0YXRlICY9IH5ISURERU47Ci0Jc2VuZEV2ZW50IChTV1QuU2hvdyk7Ci0JcmV0dXJuIDA7Ci19Ci0KLXZvaWQgcmVkcmF3ICgpIHsKLQlpZiAoKHN0eWxlICYgU1dULkJBUikgIT0gMCkgewotCQkvL0FXIE9TLkRyYXdNZW51QmFyIChwYXJlbnQuaGFuZGxlKTsKLQkJcmV0dXJuOwotCX0KLQkvKiBBVwotCWlmICgoT1MuV0lOMzJfTUFKT1IgPDwgMTYgfCBPUy5XSU4zMl9NSU5PUikgPCAoNCA8PCAxNiB8IDEwKSkgewotCQlyZXR1cm47Ci0JfQotCWJvb2xlYW4gaGFzQ2hlY2sgPSBmYWxzZSwgaGFzSW1hZ2UgPSBmYWxzZTsKLQlNZW51SXRlbSBbXSBpdGVtcyA9IGdldEl0ZW1zICgpOwotCWZvciAoaW50IGk9MDsgaTxpdGVtcy5sZW5ndGg7IGkrKykgewotCQlNZW51SXRlbSBpdGVtID0gaXRlbXMgW2ldOwotCQlpZiAoaXRlbS5nZXRJbWFnZSAoKSAhPSBudWxsKSB7Ci0JCQlpZiAoKGhhc0ltYWdlID0gdHJ1ZSkgJiYgaGFzQ2hlY2spIGJyZWFrOwotCQl9Ci0JCWlmICgoaXRlbS5nZXRTdHlsZSAoKSAmIChTV1QuQ0hFQ0sgfCBTV1QuUkFESU8pKSAhPSAwKSB7Ci0JCQlpZiAoKGhhc0NoZWNrID0gdHJ1ZSkgJiYgaGFzSW1hZ2UpIGJyZWFrOwotCQl9Ci0JfQotCWlmIChPUy5Jc1dpbkNFKSByZXR1cm47Ci0JTUVOVUlORk8gbHBjbWkgPSBuZXcgTUVOVUlORk8gKCk7Ci0JbHBjbWkuY2JTaXplID0gTUVOVUlORk8uc2l6ZW9mOwotCWxwY21pLmZNYXNrID0gT1MuTUlNX1NUWUxFOwotCU9TLkdldE1lbnVJbmZvIChoYW5kbGUsIGxwY21pKTsKLQlpZiAoaGFzSW1hZ2UgJiYgIWhhc0NoZWNrKSB7Ci0JCWxwY21pLmR3U3R5bGUgfD0gT1MuTU5TX0NIRUNLT1JCTVA7Ci0JfSBlbHNlIHsKLQkJbHBjbWkuZHdTdHlsZSAmPSB+T1MuTU5TX0NIRUNLT1JCTVA7Ci0JfQotCU9TLlNldE1lbnVJbmZvIChoYW5kbGUsIGxwY21pKTsKLQkqLwotfQotCiB2b2lkIHJlbGVhc2VDaGlsZCAoKSB7CiAJc3VwZXIucmVsZWFzZUNoaWxkICgpOwogCWlmIChjYXNjYWRlICE9IG51bGwpIGNhc2NhZGUuc2V0TWVudSAobnVsbCk7CkBAIC02ODksMzQgKzMwMSwxNSBAQAogCU1lbnVJdGVtIFtdIGl0ZW1zID0gZ2V0SXRlbXMgKCk7CiAJZm9yIChpbnQgaT0wOyBpPGl0ZW1zLmxlbmd0aDsgaSsrKSB7CiAJCU1lbnVJdGVtIGl0ZW0gPSBpdGVtcyBbaV07Ci0JCWlmICghaXRlbS5pc0Rpc3Bvc2VkICgpKSB7Ci0JCQlpdGVtLnJlbGVhc2VXaWRnZXQgKCk7Ci0JCQlpdGVtLnJlbGVhc2VIYW5kbGUgKCk7Ci0JCX0KKwkJaWYgKCFpdGVtLmlzRGlzcG9zZWQgKCkpIGl0ZW0ucmVsZWFzZVJlc291cmNlcyAoKTsKIAl9CiAJc3VwZXIucmVsZWFzZVdpZGdldCAoKTsKLQlpZiAocGFyZW50ICE9IG51bGwpIHBhcmVudC5yZW1vdmUgKHRoaXMpOworCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisJZGlzcGxheS5yZW1vdmVNZW51ICh0aGlzKTsKIAlwYXJlbnQgPSBudWxsOwogCWNhc2NhZGUgPSBudWxsOwogfQogCi0vKioKLSAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSBoZWxwIGV2ZW50cyBhcmUgZ2VuZXJhdGVkIGZvciB0aGUgY29udHJvbC4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIEhlbHBMaXN0ZW5lcgotICogQHNlZSAjYWRkSGVscExpc3RlbmVyCi0gKi8KIHB1YmxpYyB2b2lkIHJlbW92ZUhlbHBMaXN0ZW5lciAoSGVscExpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC03MjQsMjMgKzMxNyw2IEBACiAJZXZlbnRUYWJsZS51bmhvb2sgKFNXVC5IZWxwLCBsaXN0ZW5lcik7CiB9CiAKLS8qKgotICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIG1lbnUgZXZlbnRzIGFyZSBnZW5lcmF0ZWQgZm9yIHRoZSBjb250cm9sLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgTWVudUxpc3RlbmVyCi0gKiBAc2VlICNhZGRNZW51TGlzdGVuZXIKLSAqLwogcHVibGljIHZvaWQgcmVtb3ZlTWVudUxpc3RlbmVyIChNZW51TGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCAoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTc0OSwxMTcgKzMyNSw0MCBAQAogCWV2ZW50VGFibGUudW5ob29rIChTV1QuU2hvdywgbGlzdGVuZXIpOwogfQogCi0vKioKLSAqIFNldHMgdGhlIGRlZmF1bHQgbWVudSBpdGVtIHRvIHRoZSBhcmd1bWVudCBvciByZW1vdmVzCi0gKiB0aGUgZGVmYXVsdCBlbXBoYXNpcyB3aGVuIHRoZSBhcmd1bWVudCBpcyA8Y29kZT5udWxsPC9jb2RlPi4KLSAqIAotICogQHBhcmFtIGl0ZW0gdGhlIGRlZmF1bHQgbWVudSBpdGVtIG9yIG51bGwKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9BUkdVTUVOVCAtIGlmIHRoZSBtZW51IGl0ZW0gaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPiAKLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyB2b2lkIHNldERlZmF1bHRJdGVtIChNZW51SXRlbSBpdGVtKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoaXRlbSAhPSBudWxsICYmIGl0ZW0uaXNEaXNwb3NlZCgpKSBlcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CiAJZGVmYXVsdEl0ZW0gPSBpdGVtOwogfQogCi0vKioKLSAqIEVuYWJsZXMgdGhlIHJlY2VpdmVyIGlmIHRoZSBhcmd1bWVudCBpcyA8Y29kZT50cnVlPC9jb2RlPiwKLSAqIGFuZCBkaXNhYmxlcyBpdCBvdGhlcndpc2UuIEEgZGlzYWJsZWQgY29udHJvbCBpcyB0eXBpY2FsbHkKLSAqIG5vdCBzZWxlY3RhYmxlIGZyb20gdGhlIHVzZXIgaW50ZXJmYWNlIGFuZCBkcmF3cyB3aXRoIGFuCi0gKiBpbmFjdGl2ZSBvciAiZ3JheWVkIiBsb29rLgotICoKLSAqIEBwYXJhbSBlbmFibGVkIHRoZSBuZXcgZW5hYmxlZCBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIHZvaWQgc2V0RW5hYmxlZCAoYm9vbGVhbiBlbmFibGVkKSB7Ci0JY2hlY2tXaWRnZXQgKCk7Ci0JLyogQVcKLQlzdGF0ZSAmPSB+RElTQUJMRUQ7Ci0JaWYgKCFlbmFibGVkKSBzdGF0ZSB8PSBESVNBQkxFRDsKLQkqLwotCWlmIChlbmFibGVkKQotCQlPUy5FbmFibGVNZW51SXRlbShoYW5kbGUsIChzaG9ydCkwKTsKLQllbHNlCi0JCU9TLkRpc2FibGVNZW51SXRlbShoYW5kbGUsIChzaG9ydCkwKTsKKwljaGVja1dpZGdldCgpOworCWlmIChlbmFibGVkKSB7CisJCXN0YXRlICY9IH5ESVNBQkxFRDsKKwkJT1MuRW5hYmxlTWVudUl0ZW0gKGhhbmRsZSwgKHNob3J0KTApOworCX0gZWxzZSB7CisJCXN0YXRlIHw9IERJU0FCTEVEOworCQlPUy5EaXNhYmxlTWVudUl0ZW0gKGhhbmRsZSwgKHNob3J0KTApOworCX0KIH0KIAotLyoqCi0gKiBTZXRzIHRoZSByZWNlaXZlcidzIGxvY2F0aW9uIHRvIHRoZSBwb2ludCBzcGVjaWZpZWQgYnkKLSAqIHRoZSBhcmd1bWVudHMgd2hpY2ggYXJlIHJlbGF0aXZlIHRvIHRoZSBkaXNwbGF5LgotICogPHA+Ci0gKiBOb3RlOiAgVGhpcyBpcyBkaWZmZXJlbnQgZnJvbSBtb3N0IHdpZGdldHMgd2hlcmUgdGhlCi0gKiBsb2NhdGlvbiBvZiB0aGUgd2lkZ2V0IGlzIHJlbGF0aXZlIHRvIHRoZSBwYXJlbnQuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHggdGhlIG5ldyB4IGNvb3JkaW5hdGUgZm9yIHRoZSByZWNlaXZlcgotICogQHBhcmFtIHkgdGhlIG5ldyB5IGNvb3JkaW5hdGUgZm9yIHRoZSByZWNlaXZlcgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIHZvaWQgc2V0TG9jYXRpb24gKGludCB4LCBpbnQgeSkgewogCWNoZWNrV2lkZ2V0ICgpOwotCXRoaXMueCA9IHg7ICB0aGlzLnkgPSB5OworCXRoaXMueCA9IHg7CisJdGhpcy55ID0geTsKIAloYXNMb2NhdGlvbiA9IHRydWU7CiB9CiAKLS8qKgotICogTWFya3MgdGhlIHJlY2VpdmVyIGFzIHZpc2libGUgaWYgdGhlIGFyZ3VtZW50IGlzIDxjb2RlPnRydWU8L2NvZGU+LAotICogYW5kIG1hcmtzIGl0IGludmlzaWJsZSBvdGhlcndpc2UuIAotICogPHA+Ci0gKiBJZiBvbmUgb2YgdGhlIHJlY2VpdmVyJ3MgYW5jZXN0b3JzIGlzIG5vdCB2aXNpYmxlIG9yIHNvbWUKLSAqIG90aGVyIGNvbmRpdGlvbiBtYWtlcyB0aGUgcmVjZWl2ZXIgbm90IHZpc2libGUsIG1hcmtpbmcKLSAqIGl0IHZpc2libGUgbWF5IG5vdCBhY3R1YWxseSBjYXVzZSBpdCB0byBiZSBkaXNwbGF5ZWQuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHZpc2libGUgdGhlIG5ldyB2aXNpYmlsaXR5IHN0YXRlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCiBwdWJsaWMgdm9pZCBzZXRWaXNpYmxlIChib29sZWFuIHZpc2libGUpIHsKIAljaGVja1dpZGdldCAoKTsKIAlpZiAoKHN0eWxlICYgKFNXVC5CQVIgfCBTV1QuRFJPUF9ET1dOKSkgIT0gMCkgcmV0dXJuOwotCWlmICghdmlzaWJsZSkgcmV0dXJuOwotCWludCBuWCA9IHgsIG5ZID0geTsKLQlpZiAoIWhhc0xvY2F0aW9uKSB7Ci0JCU1hY1BvaW50IHdoZXJlPSBuZXcgTWFjUG9pbnQoKTsKLQkJT1MuR2V0R2xvYmFsTW91c2UgKHdoZXJlLmdldERhdGEoKSk7Ci0JCW5YID0gd2hlcmUuZ2V0WCgpOyBuWSA9IHdoZXJlLmdldFkoKTsKKwlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCWlmICh2aXNpYmxlKSB7CisJCWRpc3BsYXkuYWRkUG9wdXAgKHRoaXMpOworCX0gZWxzZSB7CisJCWRpc3BsYXkucmVtb3ZlUG9wdXAgKHRoaXMpOworCQlfc2V0VmlzaWJsZSAoZmFsc2UpOwogCX0KLQlpbnQgaW5kZXggPSBkZWZhdWx0SXRlbSAhPSBudWxsID8gaW5kZXhPZiAoZGVmYXVsdEl0ZW0pICsgMSA6IGxhc3RJbmRleDsKLQlEaXNwbGF5IGQ9IGdldERpc3BsYXkoKTsKLQlkLmZJbkNvbnRleHRNZW51PSB0cnVlOwotCWludCByZXN1bHQgPSBPUy5Qb3BVcE1lbnVTZWxlY3QgKGhhbmRsZSwgKHNob3J0KW5ZLCAoc2hvcnQpblgsIChzaG9ydCkoaW5kZXgpKTsKLQlkLmZJbkNvbnRleHRNZW51PSBmYWxzZTsKLQlsYXN0SW5kZXggPSBPUy5Mb1dvcmQgKHJlc3VsdCk7CiB9Ci0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLS8vIE1hYyBzdHVmZgotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLQl2b2lkIGhhbmRsZU1lbnUoaW50IG1lbnVSZXN1bHQpIHsKLQkJaW50IGluZGV4PSBPUy5Mb1dvcmQobWVudVJlc3VsdCktMTsJCi0JCWlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgZ2V0SXRlbUNvdW50KCkpIHsKLQkJCU1lbnVJdGVtIGl0ZW09IGdldEl0ZW0oaW5kZXgpOwotCQkJaWYgKGl0ZW0gIT0gbnVsbCkKLQkJCQlpdGVtLmhhbmRsZU1lbnVTZWxlY3QoKTsKLQkJfQotCX0KIAkKIH0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9NZW51SXRlbS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL01lbnVJdGVtLmphdmEKaW5kZXggNGExNmEyMC4uMWJmYmE3NDAgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9NZW51SXRlbS5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9NZW51SXRlbS5qYXZhCkBAIC0xMiwxMjcgKzEyLDM2IEBACiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKIAotLyoqCi0gKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyByZXByZXNlbnQgYSBzZWxlY3RhYmxlIHVzZXIgaW50ZXJmYWNlIG9iamVjdAotICogdGhhdCBpc3N1ZXMgbm90aWZpY2F0aW9uIHdoZW4gcHJlc3NlZCBhbmQgcmVsZWFzZWQuIAotICogPGRsPgotICogPGR0PjxiPlN0eWxlczo8L2I+PC9kdD4KLSAqIDxkZD5DSEVDSywgQ0FTQ0FERSwgUFVTSCwgUkFESU8sIFNFUEFSQVRPUjwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPkFybSwgSGVscCwgU2VsZWN0aW9uPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cD4KLSAqIE5vdGU6IE9ubHkgb25lIG9mIHRoZSBzdHlsZXMgQ0hFQ0ssIENBU0NBREUsIFBVU0gsIFJBRElPIGFuZCBTRVBBUkFUT1IKLSAqIG1heSBiZSBzcGVjaWZpZWQuCi0gKiA8L3A+PHA+Ci0gKiBJTVBPUlRBTlQ6IFRoaXMgY2xhc3MgaXMgPGVtPm5vdDwvZW0+IGludGVuZGVkIHRvIGJlIHN1YmNsYXNzZWQuCi0gKiA8L3A+Ci0gKi8KIHB1YmxpYyBjbGFzcyBNZW51SXRlbSBleHRlbmRzIEl0ZW0gewogCU1lbnUgcGFyZW50LCBtZW51OwogCWludCBpZCwgYWNjZWxlcmF0b3I7Ci0JaW50IGNJY29uSGFuZGxlOwogCi0vKioKLSAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50Ci0gKiAod2hpY2ggbXVzdCBiZSBhIDxjb2RlPk1lbnU8L2NvZGU+KSBhbmQgYSBzdHlsZSB2YWx1ZQotICogZGVzY3JpYmluZyBpdHMgYmVoYXZpb3IgYW5kIGFwcGVhcmFuY2UuIFRoZSBpdGVtIGlzIGFkZGVkCi0gKiB0byB0aGUgZW5kIG9mIHRoZSBpdGVtcyBtYWludGFpbmVkIGJ5IGl0cyBwYXJlbnQuCi0gKiA8cD4KLSAqIFRoZSBzdHlsZSB2YWx1ZSBpcyBlaXRoZXIgb25lIG9mIHRoZSBzdHlsZSBjb25zdGFudHMgZGVmaW5lZCBpbgotICogY2xhc3MgPGNvZGU+U1dUPC9jb2RlPiB3aGljaCBpcyBhcHBsaWNhYmxlIHRvIGluc3RhbmNlcyBvZiB0aGlzCi0gKiBjbGFzcywgb3IgbXVzdCBiZSBidWlsdCBieSA8ZW0+Yml0d2lzZSBPUjwvZW0+J2luZyB0b2dldGhlciAKLSAqICh0aGF0IGlzLCB1c2luZyB0aGUgPGNvZGU+aW50PC9jb2RlPiAifCIgb3BlcmF0b3IpIHR3byBvciBtb3JlCi0gKiBvZiB0aG9zZSA8Y29kZT5TV1Q8L2NvZGU+IHN0eWxlIGNvbnN0YW50cy4gVGhlIGNsYXNzIGRlc2NyaXB0aW9uCi0gKiBsaXN0cyB0aGUgc3R5bGUgY29uc3RhbnRzIHRoYXQgYXJlIGFwcGxpY2FibGUgdG8gdGhlIGNsYXNzLgotICogU3R5bGUgYml0cyBhcmUgYWxzbyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIG1lbnUgY29udHJvbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZSAoY2Fubm90IGJlIG51bGwpCi0gKiBAcGFyYW0gc3R5bGUgdGhlIHN0eWxlIG9mIGNvbnRyb2wgdG8gY29uc3RydWN0Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcGFyZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHBhcmVudDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNXVCNDSEVDSwotICogQHNlZSBTV1QjQ0FTQ0FERQotICogQHNlZSBTV1QjUFVTSAotICogQHNlZSBTV1QjUkFESU8KLSAqIEBzZWUgU1dUI1NFUEFSQVRPUgotICogQHNlZSBXaWRnZXQjY2hlY2tTdWJjbGFzcwotICogQHNlZSBXaWRnZXQjZ2V0U3R5bGUKLSAqLwogcHVibGljIE1lbnVJdGVtIChNZW51IHBhcmVudCwgaW50IHN0eWxlKSB7CiAJc3VwZXIgKHBhcmVudCwgY2hlY2tTdHlsZSAoc3R5bGUpKTsKIAl0aGlzLnBhcmVudCA9IHBhcmVudDsKIAlwYXJlbnQuY3JlYXRlSXRlbSAodGhpcywgcGFyZW50LmdldEl0ZW1Db3VudCAoKSk7CiB9CiAKLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIGl0cyBwYXJlbnQKLSAqICh3aGljaCBtdXN0IGJlIGEgPGNvZGU+TWVudTwvY29kZT4pLCBhIHN0eWxlIHZhbHVlCi0gKiBkZXNjcmliaW5nIGl0cyBiZWhhdmlvciBhbmQgYXBwZWFyYW5jZSwgYW5kIHRoZSBpbmRleAotICogYXQgd2hpY2ggdG8gcGxhY2UgaXQgaW4gdGhlIGl0ZW1zIG1haW50YWluZWQgYnkgaXRzIHBhcmVudC4KLSAqIDxwPgotICogVGhlIHN0eWxlIHZhbHVlIGlzIGVpdGhlciBvbmUgb2YgdGhlIHN0eWxlIGNvbnN0YW50cyBkZWZpbmVkIGluCi0gKiBjbGFzcyA8Y29kZT5TV1Q8L2NvZGU+IHdoaWNoIGlzIGFwcGxpY2FibGUgdG8gaW5zdGFuY2VzIG9mIHRoaXMKLSAqIGNsYXNzLCBvciBtdXN0IGJlIGJ1aWx0IGJ5IDxlbT5iaXR3aXNlIE9SPC9lbT4naW5nIHRvZ2V0aGVyIAotICogKHRoYXQgaXMsIHVzaW5nIHRoZSA8Y29kZT5pbnQ8L2NvZGU+ICJ8IiBvcGVyYXRvcikgdHdvIG9yIG1vcmUKLSAqIG9mIHRob3NlIDxjb2RlPlNXVDwvY29kZT4gc3R5bGUgY29uc3RhbnRzLiBUaGUgY2xhc3MgZGVzY3JpcHRpb24KLSAqIGxpc3RzIHRoZSBzdHlsZSBjb25zdGFudHMgdGhhdCBhcmUgYXBwbGljYWJsZSB0byB0aGUgY2xhc3MuCi0gKiBTdHlsZSBiaXRzIGFyZSBhbHNvIGluaGVyaXRlZCBmcm9tIHN1cGVyY2xhc3Nlcy4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gcGFyZW50IGEgbWVudSBjb250cm9sIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqIEBwYXJhbSBzdHlsZSB0aGUgc3R5bGUgb2YgY29udHJvbCB0byBjb25zdHJ1Y3QKLSAqIEBwYXJhbSBpbmRleCB0aGUgaW5kZXggdG8gc3RvcmUgdGhlIHJlY2VpdmVyIGluIGl0cyBwYXJlbnQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU1dUI0NIRUNLCi0gKiBAc2VlIFNXVCNDQVNDQURFCi0gKiBAc2VlIFNXVCNQVVNICi0gKiBAc2VlIFNXVCNSQURJTwotICogQHNlZSBTV1QjU0VQQVJBVE9SCi0gKiBAc2VlIFdpZGdldCNjaGVja1N1YmNsYXNzCi0gKiBAc2VlIFdpZGdldCNnZXRTdHlsZQotICovCiBwdWJsaWMgTWVudUl0ZW0gKE1lbnUgcGFyZW50LCBpbnQgc3R5bGUsIGludCBpbmRleCkgewogCXN1cGVyIChwYXJlbnQsIGNoZWNrU3R5bGUgKHN0eWxlKSk7CiAJdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CiAJcGFyZW50LmNyZWF0ZUl0ZW0gKHRoaXMsIGluZGV4KTsKIH0KIAotLyoqCi0gKiBBZGRzIHRoZSBsaXN0ZW5lciB0byB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGFybSBldmVudHMgYXJlIGdlbmVyYXRlZCBmb3IgdGhlIGNvbnRyb2wsIGJ5IHNlbmRpbmcKLSAqIGl0IG9uZSBvZiB0aGUgbWVzc2FnZXMgZGVmaW5lZCBpbiB0aGUgPGNvZGU+QXJtTGlzdGVuZXI8L2NvZGU+Ci0gKiBpbnRlcmZhY2UuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBBcm1MaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlQXJtTGlzdGVuZXIKLSAqLworcHVibGljIHZvaWQgX3NldEVuYWJsZWQgKGJvb2xlYW4gZW5hYmxlZCkgeworCXNob3J0IFtdIG91dEluZGV4ID0gbmV3IHNob3J0IFsxXTsKKwlPUy5HZXRJbmRNZW51SXRlbVdpdGhDb21tYW5kSUQgKHBhcmVudC5oYW5kbGUsIGlkLCAxLCBudWxsLCBvdXRJbmRleCk7CisJaW50IG91dE1lbnVSZWYgW10gPSBuZXcgaW50IFsxXTsKKwlPUy5HZXRNZW51SXRlbUhpZXJhcmNoaWNhbE1lbnUgKHBhcmVudC5oYW5kbGUsIG91dEluZGV4IFswXSwgb3V0TWVudVJlZik7CisJaWYgKGVuYWJsZWQpIHsKKwkJaWYgKG91dE1lbnVSZWYgWzBdICE9IDApIE9TLkVuYWJsZU1lbnVJdGVtIChvdXRNZW51UmVmIFswXSwgKHNob3J0KSAwKTsKKwkJT1MuRW5hYmxlTWVudUNvbW1hbmQgKHBhcmVudC5oYW5kbGUsIGlkKTsKKwl9IGVsc2UgeworCQlpZiAob3V0TWVudVJlZiBbMF0gIT0gMCkgT1MuRGlzYWJsZU1lbnVJdGVtIChvdXRNZW51UmVmIFswXSwgKHNob3J0KSAwKTsKKwkJT1MuRGlzYWJsZU1lbnVDb21tYW5kIChwYXJlbnQuaGFuZGxlLCBpZCk7CisJfQorfQorCiBwdWJsaWMgdm9pZCBhZGRBcm1MaXN0ZW5lciAoQXJtTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCAoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTE0MCwyNSArNDksNiBAQAogCWFkZExpc3RlbmVyIChTV1QuQXJtLCB0eXBlZExpc3RlbmVyKTsKIH0KIAotLyoqCi0gKiBBZGRzIHRoZSBsaXN0ZW5lciB0byB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGhlbHAgZXZlbnRzIGFyZSBnZW5lcmF0ZWQgZm9yIHRoZSBjb250cm9sLCBieSBzZW5kaW5nCi0gKiBpdCBvbmUgb2YgdGhlIG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhlIDxjb2RlPkhlbHBMaXN0ZW5lcjwvY29kZT4KLSAqIGludGVyZmFjZS4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIEhlbHBMaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlSGVscExpc3RlbmVyCi0gKi8KIHB1YmxpYyB2b2lkIGFkZEhlbHBMaXN0ZW5lciAoSGVscExpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC0xNjYsMzAgKzU2LDYgQEAKIAlhZGRMaXN0ZW5lciAoU1dULkhlbHAsIHR5cGVkTGlzdGVuZXIpOwogfQogCi0vKioKLSAqIEFkZHMgdGhlIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgY29udHJvbCBpcyBzZWxlY3RlZCwgYnkgc2VuZGluZwotICogaXQgb25lIG9mIHRoZSBtZXNzYWdlcyBkZWZpbmVkIGluIHRoZSA8Y29kZT5TZWxlY3Rpb25MaXN0ZW5lcjwvY29kZT4KLSAqIGludGVyZmFjZS4KLSAqIDxwPgotICogV2hlbiA8Y29kZT53aWRnZXRTZWxlY3RlZDwvY29kZT4gaXMgY2FsbGVkLCB0aGUgc3RhdGVNYXNrIGZpZWxkIG9mIHRoZSBldmVudCBvYmplY3QgaXMgdmFsaWQuCi0gKiA8Y29kZT53aWRnZXREZWZhdWx0U2VsZWN0ZWQ8L2NvZGU+IGlzIG5vdCBjYWxsZWQuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTZWxlY3Rpb25MaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlU2VsZWN0aW9uTGlzdGVuZXIKLSAqIEBzZWUgU2VsZWN0aW9uRXZlbnQKLSAqLwogcHVibGljIHZvaWQgYWRkU2VsZWN0aW9uTGlzdGVuZXIgKFNlbGVjdGlvbkxpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC0yMDYsMTkgKzcyLDYgQEAKIAlyZXR1cm4gY2hlY2tCaXRzIChzdHlsZSwgU1dULlBVU0gsIFNXVC5DSEVDSywgU1dULlJBRElPLCBTV1QuU0VQQVJBVE9SLCBTV1QuQ0FTQ0FERSwgMCk7CiB9CiAKLS8qKgotICogUmV0dXJuIHRoZSB3aWRnZXQgYWNjZWxlcmF0b3IuICBBbiBhY2NlbGVyYXRvciBpcyB0aGUgYml0LXdpc2UKLSAqIE9SIG9mIHplcm8gb3IgbW9yZSBtb2RpZmllciBtYXNrcyBhbmQgYSBrZXkuIEV4YW1wbGVzOgotICogPGNvZGU+U1dULkNPTlRST0wgfCBTV1QuU0hJRlQgfCAnVCcsIFNXVC5BTFQgfCBTV1QuRjI8L2NvZGU+LgotICoKLSAqIEByZXR1cm4gdGhlIGFjY2VsZXJhdG9yCi0gKgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIGludCBnZXRBY2NlbGVyYXRvciAoKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJcmV0dXJuIGFjY2VsZXJhdG9yOwpAQCAtMjMwLDM4ICs4MywxMSBAQAogCXJldHVybiBwYXJlbnQuZ2V0RGlzcGxheSAoKTsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSByZWNlaXZlciBpcyBlbmFibGVkLCBhbmQKLSAqIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuIEEgZGlzYWJsZWQgY29udHJvbCBpcyB0eXBpY2FsbHkKLSAqIG5vdCBzZWxlY3RhYmxlIGZyb20gdGhlIHVzZXIgaW50ZXJmYWNlIGFuZCBkcmF3cyB3aXRoIGFuCi0gKiBpbmFjdGl2ZSBvciAiZ3JheWVkIiBsb29rLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgZW5hYmxlZCBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIGJvb2xlYW4gZ2V0RW5hYmxlZCAoKSB7Ci0JY2hlY2tXaWRnZXQgKCk7Ci0JcmV0dXJuIE9TLklzTWVudUNvbW1hbmRFbmFibGVkIChwYXJlbnQuaGFuZGxlLCBpZCk7CisJY2hlY2tXaWRnZXQoKTsKKwlyZXR1cm4gKHN0YXRlICYgRElTQUJMRUQpID09IDA7CiB9CiAKLS8qKgotICogUmV0dXJucyB0aGUgcmVjZWl2ZXIncyBjYXNjYWRlIG1lbnUgaWYgaXQgaGFzIG9uZSBvciBudWxsCi0gKiBpZiBpdCBkb2VzIG5vdC4gT25seSA8Y29kZT5DQVNDQURFPC9jb2RlPiBtZW51IGl0ZW1zIGNhbiBoYXZlCi0gKiBhIHB1bGwgZG93biBtZW51LiBUaGUgc2VxdWVuY2Ugb2Yga2V5IHN0cm9rZXMsIGJ1dHRvbiBwcmVzc2VzIAotICogYW5kL29yIGJ1dHRvbiByZWxlYXNlcyB0aGF0IGFyZSB1c2VkIHRvIHJlcXVlc3QgYSBwdWxsIGRvd24KLSAqIG1lbnUgaXMgcGxhdGZvcm0gc3BlY2lmaWMuCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBtZW51Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCiBwdWJsaWMgTWVudSBnZXRNZW51ICgpIHsKIAljaGVja1dpZGdldCAoKTsKIAlyZXR1cm4gbWVudTsKQEAgLTI3Miw0NiArOTgsMjIgQEAKIAlyZXR1cm4gc3VwZXIuZ2V0TmFtZVRleHQgKCk7CiB9CiAKLS8qKgotICogUmV0dXJucyB0aGUgcmVjZWl2ZXIncyBwYXJlbnQsIHdoaWNoIG11c3QgYmUgYSA8Y29kZT5NZW51PC9jb2RlPi4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIHBhcmVudAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIE1lbnUgZ2V0UGFyZW50ICgpIHsKIAljaGVja1dpZGdldCAoKTsKIAlyZXR1cm4gcGFyZW50OwogfQogCi0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGlzIHNlbGVjdGVkLAotICogYW5kIGZhbHNlIG90aGVyd2lzZS4KLSAqIDxwPgotICogV2hlbiB0aGUgcmVjZWl2ZXIgaXMgb2YgdHlwZSA8Y29kZT5DSEVDSzwvY29kZT4gb3IgPGNvZGU+UkFESU88L2NvZGU+LAotICogaXQgaXMgc2VsZWN0ZWQgd2hlbiBpdCBpcyBjaGVja2VkLgotICoKLSAqIEByZXR1cm4gdGhlIHNlbGVjdGlvbiBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIGJvb2xlYW4gZ2V0U2VsZWN0aW9uICgpIHsKIAljaGVja1dpZGdldCAoKTsKIAlpZiAoKHN0eWxlICYgKFNXVC5DSEVDSyB8IFNXVC5SQURJTykpID09IDApIHJldHVybiBmYWxzZTsKIAljaGFyIFtdIG91dE1hcmsgPSBuZXcgY2hhciBbMV07Ci0JaWYgKE9TLkdldE1lbnVDb21tYW5kTWFyayAocGFyZW50LmhhbmRsZSwgaWQsIG91dE1hcmspICE9IE9TLmtOb0VycikgeworCWlmIChPUy5HZXRNZW51Q29tbWFuZE1hcmsgKHBhcmVudC5oYW5kbGUsIGlkLCBvdXRNYXJrKSAhPSBPUy5ub0VycikgewogCQllcnJvciAoU1dULkVSUk9SX0NBTk5PVF9HRVRfU0VMRUNUSU9OKTsKIAl9CiAJcmV0dXJuIG91dE1hcmsgWzBdICE9IDA7CiB9CiAKLXZvaWQgaGFuZGxlTWVudVNlbGVjdCAoKSB7CitpbnQga0V2ZW50UHJvY2Vzc0NvbW1hbmQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKIAlpZiAoKHN0eWxlICYgU1dULkNIRUNLKSAhPSAwKSB7CiAJCXNldFNlbGVjdGlvbiAoIWdldFNlbGVjdGlvbiAoKSk7CiAJfSBlbHNlIHsKQEAgLTMyMywzMyArMTI1LDE0IEBACiAJCQl9CiAJCX0KIAl9CisJaW50IFtdIG1vZGlmaWVycyA9IG5ldyBpbnQgWzFdOworCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1LZXlNb2RpZmllcnMsIE9TLnR5cGVVSW50MzIsIG51bGwsIDQsIG51bGwsIG1vZGlmaWVycyk7CiAJRXZlbnQgZXZlbnQgPSBuZXcgRXZlbnQgKCk7Ci0JLyogQVcKLQlpZiAoT1MuR2V0S2V5U3RhdGUgKE9TLlZLX01FTlUpIDwgMCkgZXZlbnQuc3RhdGVNYXNrIHw9IFNXVC5BTFQ7Ci0JaWYgKE9TLkdldEtleVN0YXRlIChPUy5WS19TSElGVCkgPCAwKSBldmVudC5zdGF0ZU1hc2sgfD0gU1dULlNISUZUOwotCWlmIChPUy5HZXRLZXlTdGF0ZSAoT1MuVktfQ09OVFJPTCkgPCAwKSBldmVudC5zdGF0ZU1hc2sgfD0gU1dULkNPTlRST0w7Ci0JaWYgKE9TLkdldEtleVN0YXRlIChPUy5WS19MQlVUVE9OKSA8IDApIGV2ZW50LnN0YXRlTWFzayB8PSBTV1QuQlVUVE9OMTsKLQlpZiAoT1MuR2V0S2V5U3RhdGUgKE9TLlZLX01CVVRUT04pIDwgMCkgZXZlbnQuc3RhdGVNYXNrIHw9IFNXVC5CVVRUT04yOwotCWlmIChPUy5HZXRLZXlTdGF0ZSAoT1MuVktfUkJVVFRPTikgPCAwKSBldmVudC5zdGF0ZU1hc2sgfD0gU1dULkJVVFRPTjM7Ci0JKi8KKwlzZXRJbnB1dFN0YXRlIChldmVudCwgKHNob3J0KSAwLCBPUy5HZXRDdXJyZW50RXZlbnRCdXR0b25TdGF0ZSAoKSwgbW9kaWZpZXJzIFswXSk7CiAJcG9zdEV2ZW50IChTV1QuU2VsZWN0aW9uLCBldmVudCk7CisJcmV0dXJuIE9TLm5vRXJyOwogfQogCi0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGlzIGVuYWJsZWQgYW5kIGFsbAotICogb2YgdGhlIHJlY2VpdmVyJ3MgYW5jZXN0b3JzIGFyZSBlbmFibGVkLCBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+Ci0gKiBvdGhlcndpc2UuIEEgZGlzYWJsZWQgY29udHJvbCBpcyB0eXBpY2FsbHkgbm90IHNlbGVjdGFibGUgZnJvbSB0aGUKLSAqIHVzZXIgaW50ZXJmYWNlIGFuZCBkcmF3cyB3aXRoIGFuIGluYWN0aXZlIG9yICJncmF5ZWQiIGxvb2suCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBlbmFibGVkIHN0YXRlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogCi0gKiBAc2VlICNnZXRFbmFibGVkCi0gKi8KIHB1YmxpYyBib29sZWFuIGlzRW5hYmxlZCAoKSB7CiAJcmV0dXJuIGdldEVuYWJsZWQgKCkgJiYgcGFyZW50LmlzRW5hYmxlZCAoKTsKIH0KQEAgLTQwMCw0MCArMTgzLDI5IEBACiB2b2lkIHJlbGVhc2VXaWRnZXQgKCkgewogCWlmIChtZW51ICE9IG51bGwpIHsKIAkJbWVudS5yZWxlYXNlV2lkZ2V0ICgpOwotCQltZW51LnJlbGVhc2VIYW5kbGUgKCk7CisJCW1lbnUuZGVzdHJveVdpZGdldCAoKTsKKwl9IGVsc2UgeworCQlpZiAoKHBhcmVudC5zdHlsZSAmIFNXVC5CQVIpICE9IDApIHsKKy8vCQkJc2hvcnQgW10gb3V0SW5kZXggPSBuZXcgc2hvcnQgWzFdOworLy8JCQlpZiAoT1MuR2V0SW5kTWVudUl0ZW1XaXRoQ29tbWFuZElEIChwYXJlbnQuaGFuZGxlLCBpZCwgMSwgbnVsbCwgb3V0SW5kZXgpID09IE9TLm5vRXJyKSB7CisvLwkJCQlpbnQgW10gb3V0TWVudVJlZiA9IG5ldyBpbnQgWzFdOworLy8JCQkJT1MuR2V0TWVudUl0ZW1IaWVyYXJjaGljYWxNZW51IChwYXJlbnQuaGFuZGxlLCBvdXRJbmRleCBbMF0sIG91dE1lbnVSZWYpOworLy8JCQkJaWYgKG91dE1lbnVSZWYgWzBdICE9IDApIHsKKy8vCQkJCQlPUy5EZWxldGVNZW51IChPUy5HZXRNZW51SUQgKG91dE1lbnVSZWYgWzBdKSk7CisvLwkJCQkJT1MuRGlzcG9zZU1lbnUgKG91dE1lbnVSZWYgWzBdKTsKKy8vCQkJCX0KKy8vCQkJfQorCQl9CiAJfQogCW1lbnUgPSBudWxsOwogCXN1cGVyLnJlbGVhc2VXaWRnZXQgKCk7CiAJYWNjZWxlcmF0b3IgPSAwOwotCWlmICh0aGlzID09IHBhcmVudC5kZWZhdWx0SXRlbSkgewotCQlwYXJlbnQuZGVmYXVsdEl0ZW0gPSBudWxsOwotCX0KLQlEZWNvcmF0aW9ucyBzaGVsbCA9IHBhcmVudC5wYXJlbnQ7Ci0Jc2hlbGwucmVtb3ZlICh0aGlzKTsKKwlpZiAodGhpcyA9PSBwYXJlbnQuZGVmYXVsdEl0ZW0pIHBhcmVudC5kZWZhdWx0SXRlbSA9IG51bGw7CisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlkaXNwbGF5LnJlbW92ZU1lbnVJdGVtICh0aGlzKTsKIAlwYXJlbnQgPSBudWxsOwotCWlmIChjSWNvbkhhbmRsZSAhPSAwKSB7Ci0JCUltYWdlLmRpc3Bvc2VDSWNvbiAoY0ljb25IYW5kbGUpOwotCQljSWNvbkhhbmRsZSA9IDA7Ci0gICAgfQogfQogCi0vKioKLSAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSBhcm0gZXZlbnRzIGFyZSBnZW5lcmF0ZWQgZm9yIHRoZSBjb250cm9sLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgQXJtTGlzdGVuZXIKLSAqIEBzZWUgI2FkZEFybUxpc3RlbmVyCi0gKi8KIHB1YmxpYyB2b2lkIHJlbW92ZUFybUxpc3RlbmVyIChBcm1MaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0ICgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwpAQCAtNDQxLDIzICsyMTMsNiBAQAogCWV2ZW50VGFibGUudW5ob29rIChTV1QuQXJtLCBsaXN0ZW5lcik7CiB9CiAKLS8qKgotICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGhlbHAgZXZlbnRzIGFyZSBnZW5lcmF0ZWQgZm9yIHRoZSBjb250cm9sLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgSGVscExpc3RlbmVyCi0gKiBAc2VlICNhZGRIZWxwTGlzdGVuZXIKLSAqLwogcHVibGljIHZvaWQgcmVtb3ZlSGVscExpc3RlbmVyIChIZWxwTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCAoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTQ2NSwyMyArMjIwLDYgQEAKIAlldmVudFRhYmxlLnVuaG9vayAoU1dULkhlbHAsIGxpc3RlbmVyKTsKIH0KIAotLyoqCi0gKiBSZW1vdmVzIHRoZSBsaXN0ZW5lciBmcm9tIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgY29udHJvbCBpcyBzZWxlY3RlZC4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNlbGVjdGlvbkxpc3RlbmVyCi0gKiBAc2VlICNhZGRTZWxlY3Rpb25MaXN0ZW5lcgotICovCiBwdWJsaWMgdm9pZCByZW1vdmVTZWxlY3Rpb25MaXN0ZW5lciAoU2VsZWN0aW9uTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCAoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTUwMSwyMyArMjM5LDEwIEBACiAJc2V0U2VsZWN0aW9uICh0cnVlKTsKIH0KIAotLyoqCi0gKiBTZXRzIHRoZSB3aWRnZXQgYWNjZWxlcmF0b3IuICBBbiBhY2NlbGVyYXRvciBpcyB0aGUgYml0LXdpc2UKLSAqIE9SIG9mIHplcm8gb3IgbW9yZSBtb2RpZmllciBtYXNrcyBhbmQgYSBrZXkuIEV4YW1wbGVzOgotICogPGNvZGU+U1dULkNPTlRST0wgfCBTV1QuU0hJRlQgfCAnVCcsIFNXVC5BTFQgfCBTV1QuRjI8L2NvZGU+LgotICoKLSAqIEBwYXJhbSBhY2NlbGVyYXRvciBhbiBpbnRlZ2VyIHRoYXQgaXMgdGhlIGJpdC13aXNlIE9SIG9mIG1hc2tzIGFuZCBhIGtleQotICoKLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyB2b2lkIHNldEFjY2VsZXJhdG9yIChpbnQgYWNjZWxlcmF0b3IpIHsKIAljaGVja1dpZGdldCAoKTsKIAlzaG9ydCBbXSBvdXRJbmRleCA9IG5ldyBzaG9ydCBbMV07Ci0JaWYgKE9TLkdldEluZE1lbnVJdGVtV2l0aENvbW1hbmRJRCAocGFyZW50LmhhbmRsZSwgaWQsIDEsIG51bGwsIG91dEluZGV4KSAhPSBPUy5rTm9FcnIpIHsKKwlpZiAoT1MuR2V0SW5kTWVudUl0ZW1XaXRoQ29tbWFuZElEIChwYXJlbnQuaGFuZGxlLCBpZCwgMSwgbnVsbCwgb3V0SW5kZXgpICE9IE9TLm5vRXJyKSB7CiAJCXJldHVybjsKIAl9CiAJYm9vbGVhbiB1cGRhdGUgPSAodGhpcy5hY2NlbGVyYXRvciA9PSAwICYmIGFjY2VsZXJhdG9yICE9IDApIHx8ICh0aGlzLmFjY2VsZXJhdG9yICE9IDAgJiYgYWNjZWxlcmF0b3IgPT0gMCk7CkBAIC01MjYsMTAgKzI1MSw2IEBACiAJaW50IGluTW9kaWZpZXJzID0gT1Mua01lbnVOb01vZGlmaWVycywgaW5HbHlwaCA9IE9TLmtNZW51TnVsbEdseXBoLCBpbktleSA9IDA7CiAJaWYgKGFjY2VsZXJhdG9yICE9IDApIHsKIAkJaW5LZXkgPSBhY2NlbGVyYXRvciAmIH4oU1dULlNISUZUIHwgU1dULkNPTlRST0wgfCBTV1QuQUxUIHwgU1dULkNPTU1BTkQpOwotCQlpZiAoTWFjVXRpbC5LRUVQX01BQ19TSE9SVENVVFMpIHsKLQkJCWlmICgoYWNjZWxlcmF0b3IgJiBTV1QuQ09NTUFORCkgIT0gMCkKLQkJCQlpZiAoaW5LZXkgPT0gJ0gnIHx8IGluS2V5ID09ICdRJykgcmV0dXJuOwotCQl9CiAJCWluR2x5cGggPSBrZXlHbHlwaCAoaW5LZXkpOwogCQlpbnQgdmlydHVhbEtleSA9IERpc3BsYXkudW50cmFuc2xhdGVLZXkgKGluS2V5KTsKIAkJaWYgKGluS2V5ID09ICcgJykgdmlydHVhbEtleSA9IDQ5OwpAQCAtNTUxLDgxICsyNzIsMjcgQEAKIAlpZiAodXBkYXRlKSB1cGRhdGVUZXh0ICgpOwogfQogCi0vKioKLSAqIEVuYWJsZXMgdGhlIHJlY2VpdmVyIGlmIHRoZSBhcmd1bWVudCBpcyA8Y29kZT50cnVlPC9jb2RlPiwKLSAqIGFuZCBkaXNhYmxlcyBpdCBvdGhlcndpc2UuIEEgZGlzYWJsZWQgY29udHJvbCBpcyB0eXBpY2FsbHkKLSAqIG5vdCBzZWxlY3RhYmxlIGZyb20gdGhlIHVzZXIgaW50ZXJmYWNlIGFuZCBkcmF3cyB3aXRoIGFuCi0gKiBpbmFjdGl2ZSBvciAiZ3JheWVkIiBsb29rLgotICoKLSAqIEBwYXJhbSBlbmFibGVkIHRoZSBuZXcgZW5hYmxlZCBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIHZvaWQgc2V0RW5hYmxlZCAoYm9vbGVhbiBlbmFibGVkKSB7CiAJY2hlY2tXaWRnZXQgKCk7Ci0Jc2hvcnQgW10gb3V0SW5kZXggPSBuZXcgc2hvcnQgWzFdOwotCU9TLkdldEluZE1lbnVJdGVtV2l0aENvbW1hbmRJRCAocGFyZW50LmhhbmRsZSwgaWQsIDEsIG51bGwsIG91dEluZGV4KTsKLQlpbnQgb3V0TWVudVJlZiBbXSA9IG5ldyBpbnQgWzFdOwotCU9TLkdldE1lbnVJdGVtSGllcmFyY2hpY2FsTWVudSAocGFyZW50LmhhbmRsZSwgb3V0SW5kZXggWzBdLCBvdXRNZW51UmVmKTsKIAlpZiAoZW5hYmxlZCkgewotCQlpZiAob3V0TWVudVJlZiBbMF0gIT0gMCkgT1MuRW5hYmxlTWVudUl0ZW0gKG91dE1lbnVSZWYgWzBdLCAoc2hvcnQpIDApOwotCQlPUy5FbmFibGVNZW51Q29tbWFuZCAocGFyZW50LmhhbmRsZSwgaWQpOworCQlzdGF0ZSAmPSB+RElTQUJMRUQ7CiAJfSBlbHNlIHsKLQkJaWYgKG91dE1lbnVSZWYgWzBdICE9IDApIE9TLkRpc2FibGVNZW51SXRlbSAob3V0TWVudVJlZiBbMF0sIChzaG9ydCkgMCk7Ci0JCU9TLkRpc2FibGVNZW51Q29tbWFuZCAocGFyZW50LmhhbmRsZSwgaWQpOworCQlzdGF0ZSB8PSBESVNBQkxFRDsKIAl9CisJX3NldEVuYWJsZWQgKGVuYWJsZWQpOwogfQogCi0vKioKLSAqIFNldHMgdGhlIGltYWdlIHRoZSByZWNlaXZlciB3aWxsIGRpc3BsYXkgdG8gdGhlIGFyZ3VtZW50LgotICogPHA+Ci0gKiBOb3RlOiBUaGlzIGZlYXR1cmUgaXMgbm90IGF2YWlsYWJsZSBvbiBhbGwgd2luZG93IHN5c3RlbXMgKGZvciBleGFtcGxlLCBXaW5kb3cgTlQpLAotICogaW4gd2hpY2ggY2FzZSwgY2FsbGluZyB0aGlzIG1ldGhvZCB3aWxsIHNpbGVudGx5IGRvIG5vdGhpbmcuCi0gKgotICogQHBhcmFtIG1lbnUgdGhlIGltYWdlIHRvIGRpc3BsYXkKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyB2b2lkIHNldEltYWdlIChJbWFnZSBpbWFnZSkgewogCWNoZWNrV2lkZ2V0ICgpOwogCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSByZXR1cm47CiAJc3VwZXIuc2V0SW1hZ2UgKGltYWdlKTsKLQlpZiAoY0ljb25IYW5kbGUgIT0gMCkgSW1hZ2UuZGlzcG9zZUNJY29uIChjSWNvbkhhbmRsZSk7Ci0JY0ljb25IYW5kbGUgPSBJbWFnZS5jYXJib25fY3JlYXRlQ0ljb24gKGltYWdlKTsKLQlpZiAoY0ljb25IYW5kbGUgIT0gMCkgewotCQlzaG9ydCBbXSBvdXRJbmRleCA9IG5ldyBzaG9ydFsxXTsKLQkJaWYgKE9TLkdldEluZE1lbnVJdGVtV2l0aENvbW1hbmRJRCAocGFyZW50LmhhbmRsZSwgaWQsIDEsIG51bGwsIG91dEluZGV4KSA9PSBPUy5rTm9FcnIpIHsKLQkJCU9TLlNldE1lbnVJdGVtSWNvbkhhbmRsZSAocGFyZW50LmhhbmRsZSwgb3V0SW5kZXggWzBdLCAoYnl0ZSk0LCBjSWNvbkhhbmRsZSk7Ci0JCX0KLQl9CisJc2hvcnQgW10gb3V0SW5kZXggPSBuZXcgc2hvcnQgWzFdOworCWlmIChPUy5HZXRJbmRNZW51SXRlbVdpdGhDb21tYW5kSUQgKHBhcmVudC5oYW5kbGUsIGlkLCAxLCBudWxsLCBvdXRJbmRleCkgIT0gT1Mubm9FcnIpIHJldHVybjsKKwlpbnQgaW1hZ2VIYW5kbGUgPSBpbWFnZSAhPSBudWxsID8gaW1hZ2UuaGFuZGxlIDogMDsKKwlieXRlIHR5cGUgPSBpbWFnZSAhPSBudWxsID8gKGJ5dGUpT1Mua01lbnVDR0ltYWdlUmVmVHlwZSA6IChieXRlKU9TLmtNZW51Tm9JY29uOworCU9TLlNldE1lbnVJdGVtSWNvbkhhbmRsZSAocGFyZW50LmhhbmRsZSwgb3V0SW5kZXggWzBdLCB0eXBlLCBpbWFnZUhhbmRsZSk7CiB9CiAKLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBwdWxsIGRvd24gbWVudSB0byB0aGUgYXJndW1lbnQuCi0gKiBPbmx5IDxjb2RlPkNBU0NBREU8L2NvZGU+IG1lbnUgaXRlbXMgY2FuIGhhdmUgYQotICogcHVsbCBkb3duIG1lbnUuIFRoZSBzZXF1ZW5jZSBvZiBrZXkgc3Ryb2tlcywgYnV0dG9uIHByZXNzZXMKLSAqIGFuZC9vciBidXR0b24gcmVsZWFzZXMgdGhhdCBhcmUgdXNlZCB0byByZXF1ZXN0IGEgcHVsbCBkb3duCi0gKiBtZW51IGlzIHBsYXRmb3JtIHNwZWNpZmljLgotICoKLSAqIEBwYXJhbSBtZW51IHRoZSBuZXcgcHVsbCBkb3duIG1lbnUKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTUVOVV9OT1RfRFJPUF9ET1dOIC0gaWYgdGhlIG1lbnUgaXMgbm90IGEgZHJvcCBkb3duIG1lbnU8L2xpPgotICogICAgPGxpPkVSUk9SX01FTlVJVEVNX05PVF9DQVNDQURFIC0gaWYgdGhlIG1lbnUgaXRlbSBpcyBub3QgYSA8Y29kZT5DQVNDQURFPC9jb2RlPjwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9BUkdVTUVOVCAtIGlmIHRoZSBtZW51IGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1BBUkVOVCAtIGlmIHRoZSBtZW51IGlzIG5vdCBpbiB0aGUgc2FtZSB3aWRnZXQgdHJlZTwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCiBwdWJsaWMgdm9pZCBzZXRNZW51IChNZW51IG1lbnUpIHsKIAljaGVja1dpZGdldCAoKTsKIApAQCAtNjQ0LDI1ICszMTEsNDcgQEAKIAl9CiAJCiAJLyogQXNzaWduIHRoZSBuZXcgbWVudSAqLwotCWlmICh0aGlzLm1lbnUgPT0gbWVudSkgcmV0dXJuOwotCWlmICh0aGlzLm1lbnUgIT0gbnVsbCkgdGhpcy5tZW51LmNhc2NhZGUgPSBudWxsOworCU1lbnUgb2xkTWVudSA9IHRoaXMubWVudTsKKwlpZiAob2xkTWVudSA9PSBtZW51KSByZXR1cm47CisJaWYgKG9sZE1lbnUgIT0gbnVsbCkgb2xkTWVudS5jYXNjYWRlID0gbnVsbDsKKwl0aGlzLm1lbnUgPSBtZW51OworCQorCS8qIFVwZGF0ZSB0aGUgbWVudSBpbiB0aGUgT1MgKi8KIAlzaG9ydCBbXSBvdXRJbmRleCA9IG5ldyBzaG9ydCBbMV07Ci0JaWYgKE9TLkdldEluZE1lbnVJdGVtV2l0aENvbW1hbmRJRCAocGFyZW50LmhhbmRsZSwgaWQsIDEsIG51bGwsIG91dEluZGV4KSAhPSBPUy5rTm9FcnIpIHsKKwlpZiAoT1MuR2V0SW5kTWVudUl0ZW1XaXRoQ29tbWFuZElEIChwYXJlbnQuaGFuZGxlLCBpZCwgMSwgbnVsbCwgb3V0SW5kZXgpICE9IE9TLm5vRXJyKSB7CiAJCWVycm9yIChTV1QuRVJST1JfQ0FOTk9UX1NFVF9NRU5VKTsKIAl9Ci0JaW50IGluSGllck1lbnUgPSBtZW51ICE9IG51bGwgPyBtZW51LmhhbmRsZSA6IDA7Ci0JaWYgKE9TLlNldE1lbnVJdGVtSGllcmFyY2hpY2FsTWVudSAocGFyZW50LmhhbmRsZSwgb3V0SW5kZXggWzBdLCBpbkhpZXJNZW51KSAhPSBPUy5rTm9FcnIpIHsKLQkJZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfU0VUX01FTlUpOwotCX0KLQlpZiAoKHRoaXMubWVudSA9IG1lbnUpICE9IG51bGwpIHsKKwlpbnQgb3V0TWVudVJlZiBbXSA9IG5ldyBpbnQgWzFdOworCWlmIChtZW51ID09IG51bGwpIHsKKwkJaWYgKChwYXJlbnQuc3R5bGUgJiBTV1QuQkFSKSAhPSAwKSB7CisvLwkJCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisvLwkJCXNob3J0IG1lbnVJRCA9IGRpc3BsYXkubmV4dE1lbnVJZCAoKTsKKy8vCQkJaWYgKE9TLkNyZWF0ZU5ld01lbnUgKG1lbnVJRCwgMCwgb3V0TWVudVJlZikgIT0gT1Mubm9FcnIpIHsKKy8vCQkJCWVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7CisvLwkJCX0KKwkJfQorCX0gZWxzZSB7CiAJCW1lbnUuY2FzY2FkZSA9IHRoaXM7CisJCWlmICgocGFyZW50LnN0eWxlICYgU1dULkJBUikgIT0gMCkgeworCQkJaWYgKG9sZE1lbnUgPT0gbnVsbCkgeworLy8JCQkJT1MuR2V0TWVudUl0ZW1IaWVyYXJjaGljYWxNZW51IChwYXJlbnQuaGFuZGxlLCBvdXRJbmRleCBbMF0sIG91dE1lbnVSZWYpOworLy8JCQkJaWYgKG91dE1lbnVSZWYgWzBdICE9IDApIHsKKy8vCQkJCQlPUy5EZWxldGVNZW51IChPUy5HZXRNZW51SUQgKG91dE1lbnVSZWYgWzBdKSk7CisvLwkJCQkJT1MuRGlzcG9zZU1lbnUgKG91dE1lbnVSZWYgWzBdKTsKKy8vCQkJCX0KKwkJCX0KKwkJfQorCQlvdXRNZW51UmVmIFswXSA9IG1lbnUuaGFuZGxlOwogCQlpbnQgW10gb3V0U3RyaW5nID0gbmV3IGludCBbMV07Ci0JCWlmIChPUy5Db3B5TWVudUl0ZW1UZXh0QXNDRlN0cmluZyAocGFyZW50LmhhbmRsZSwgb3V0SW5kZXggWzBdLCBvdXRTdHJpbmcpICE9IE9TLmtOb0VycikgeworCQlpZiAoT1MuQ29weU1lbnVJdGVtVGV4dEFzQ0ZTdHJpbmcgKHBhcmVudC5oYW5kbGUsIG91dEluZGV4IFswXSwgb3V0U3RyaW5nKSAhPSBPUy5ub0VycikgewogCQkJZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfU0VUX01FTlUpOwogCQl9Ci0JCU9TLlNldE1lbnVUaXRsZVdpdGhDRlN0cmluZyAoaW5IaWVyTWVudSwgb3V0U3RyaW5nIFswXSk7CisJCU9TLlNldE1lbnVUaXRsZVdpdGhDRlN0cmluZyAob3V0TWVudVJlZiBbMF0sIG91dFN0cmluZyBbMF0pOwogCQlPUy5DRlJlbGVhc2UgKG91dFN0cmluZyBbMF0pOwogCX0KKwlpZiAoT1MuU2V0TWVudUl0ZW1IaWVyYXJjaGljYWxNZW51IChwYXJlbnQuaGFuZGxlLCBvdXRJbmRleCBbMF0sIG91dE1lbnVSZWYgWzBdKSAhPSBPUy5ub0VycikgeworCQllcnJvciAoU1dULkVSUk9SX0NBTk5PVF9TRVRfTUVOVSk7CisJfQogfQogCiBib29sZWFuIHNldFJhZGlvU2VsZWN0aW9uIChib29sZWFuIHZhbHVlKSB7CkBAIC02NzQsMjQgKzM2MywxMSBAQAogCXJldHVybiB0cnVlOwogfQogCi0vKioKLSAqIFNldHMgdGhlIHNlbGVjdGlvbiBzdGF0ZSBvZiB0aGUgcmVjZWl2ZXIuCi0gKiA8cD4KLSAqIFdoZW4gdGhlIHJlY2VpdmVyIGlzIG9mIHR5cGUgPGNvZGU+Q0hFQ0s8L2NvZGU+IG9yIDxjb2RlPlJBRElPPC9jb2RlPiwKLSAqIGl0IGlzIHNlbGVjdGVkIHdoZW4gaXQgaXMgY2hlY2tlZC4KLSAqCi0gKiBAcGFyYW0gc2VsZWN0ZWQgdGhlIG5ldyBzZWxlY3Rpb24gc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyB2b2lkIHNldFNlbGVjdGlvbiAoYm9vbGVhbiBzZWxlY3RlZCkgewogCWNoZWNrV2lkZ2V0ICgpOwogCWlmICgoc3R5bGUgJiAoU1dULkNIRUNLIHwgU1dULlJBRElPKSkgPT0gMCkgcmV0dXJuOwogCWludCBpbk1hcmsgPSBzZWxlY3RlZCA/ICgoc3R5bGUgJiBTV1QuUkFESU8pICE9IDApID8gT1MuZGlhbW9uZE1hcmsgOiBPUy5jaGVja01hcmsgOiAwOwotCWlmIChPUy5TZXRNZW51Q29tbWFuZE1hcmsgKHBhcmVudC5oYW5kbGUsIGlkLCAoY2hhcikgaW5NYXJrKSAhPSBPUy5rTm9FcnIpIHsKKwlpZiAoT1MuU2V0TWVudUNvbW1hbmRNYXJrIChwYXJlbnQuaGFuZGxlLCBpZCwgKGNoYXIpIGluTWFyaykgIT0gT1Mubm9FcnIpIHsKIAkJZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfU0VUX1NFTEVDVElPTik7CiAJfQogfQpAQCAtNzA3LDcgKzM4Myw3IEBACiB2b2lkIHVwZGF0ZVRleHQgKCkgewogCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSByZXR1cm47CiAJc2hvcnQgW10gb3V0SW5kZXggPSBuZXcgc2hvcnQgWzFdOwotCWlmIChPUy5HZXRJbmRNZW51SXRlbVdpdGhDb21tYW5kSUQgKHBhcmVudC5oYW5kbGUsIGlkLCAxLCBudWxsLCBvdXRJbmRleCkgIT0gT1Mua05vRXJyKSB7CisJaWYgKE9TLkdldEluZE1lbnVJdGVtV2l0aENvbW1hbmRJRCAocGFyZW50LmhhbmRsZSwgaWQsIDEsIG51bGwsIG91dEluZGV4KSAhPSBPUy5ub0VycikgewogCQllcnJvciAoU1dULkVSUk9SX0NBTk5PVF9TRVRfVEVYVCk7CiAJfQogCWNoYXIgW10gYnVmZmVyID0gbmV3IGNoYXIgW3RleHQubGVuZ3RoICgpXTsKQEAgLTcyMSw4ICszOTcsNyBAQAogCQkJai0tOwogCQl9CiAJfQotCS8vaW50IHN0ciA9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMgKE9TLmtDRkFsbG9jYXRvckRlZmF1bHQsIGJ1ZmZlciwgaik7Ci0JaW50IHN0ciA9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMgKG5ldyBTdHJpbmcoYnVmZmVyLCAwLCBqKSk7CisJaW50IHN0ciA9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMgKE9TLmtDRkFsbG9jYXRvckRlZmF1bHQsIGJ1ZmZlciwgaik7CiAJaWYgKHN0ciA9PSAwKSBlcnJvciAoU1dULkVSUk9SX0NBTk5PVF9TRVRfVEVYVCk7CiAJT1MuU2V0TWVudUl0ZW1UZXh0V2l0aENGU3RyaW5nIChwYXJlbnQuaGFuZGxlLCBvdXRJbmRleCBbMF0sIHN0cik7CiAJaW50IFtdIG91dEhpZXJNZW51ID0gbmV3IGludCBbMV07CkBAIC03MzEsMyArNDA2LDQgQEAKIAlPUy5DRlJlbGVhc2UgKHN0cik7CiB9CiB9CisKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9NZXNzYWdlQm94LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvTWVzc2FnZUJveC5qYXZhCmluZGV4IDE1ZTJmMzAuLjFmZTdmNDEgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9NZXNzYWdlQm94LmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL01lc3NhZ2VCb3guamF2YQpAQCAtMTEsODcgKzExLDE3IEBACiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CiAKLS8qKgotICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgYXJlIHVzZWQgdXNlZCB0byBpbmZvcm0gb3Igd2FybiB0aGUgdXNlci4KLSAqIDxkbD4KLSAqIDxkdD48Yj5TdHlsZXM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+SUNPTl9FUlJPUiwgSUNPTl9JTkZPUk1BVElPTiwgSUNPTl9RVUVTVElPTiwgSUNPTl9XQVJOSU5HLCBJQ09OX1dPUktJTkc8L2RkPgotICogPGRkPk9LLCBPSyB8IENBTkNFTDwvZGQ+Ci0gKiA8ZGQ+WUVTIHwgTk8sIFlFUyB8IE5PIHwgQ0FOQ0VMPC9kZD4KLSAqIDxkZD5SRVRSWSB8IENBTkNFTDwvZGQ+Ci0gKiA8ZGQ+QUJPUlQgfCBSRVRSWSB8IElHTk9SRTwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPihub25lKTwvZGQ+Ci0gKiA8L2RsPgotICogPHA+Ci0gKiBOb3RlOiBPbmx5IG9uZSBvZiB0aGUgc3R5bGVzIElDT05fRVJST1IsIElDT05fSU5GT1JNQVRJT04sIElDT05fUVVFU1RJT04sCi0gKiBJQ09OX1dBUk5JTkcgYW5kIElDT05fV09SS0lORyBtYXkgYmUgc3BlY2lmaWVkLgotICogPC9wPjxwPgotICogSU1QT1JUQU5UOiBUaGlzIGNsYXNzIGlzIGludGVuZGVkIHRvIGJlIHN1YmNsYXNzZWQgPGVtPm9ubHk8L2VtPgotICogd2l0aGluIHRoZSBTV1QgaW1wbGVtZW50YXRpb24uCi0gKiA8L3A+Ci0gKi8KIHB1YmxpYyAgY2xhc3MgTWVzc2FnZUJveCBleHRlbmRzIERpYWxvZyB7CiAJU3RyaW5nIG1lc3NhZ2UgPSAiIjsKIAkKLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIG9ubHkgaXRzCi0gKiBwYXJlbnQuCi0gKiA8cD4KLSAqIE5vdGU6IEN1cnJlbnRseSwgbnVsbCBjYW4gYmUgcGFzc2VkIGluIGZvciB0aGUgcGFyZW50LgotICogVGhpcyBoYXMgdGhlIGVmZmVjdCBvZiBjcmVhdGluZyB0aGUgZGlhbG9nIG9uIHRoZSBjdXJyZW50bHkgYWN0aXZlCi0gKiBkaXNwbGF5IGlmIHRoZXJlIGlzIG9uZS4gSWYgdGhlcmUgaXMgbm8gY3VycmVudCBkaXNwbGF5LCB0aGUgCi0gKiBkaWFsb2cgaXMgY3JlYXRlZCBvbiBhICJkZWZhdWx0IiBkaXNwbGF5LiA8Yj5QYXNzaW5nIGluIG51bGwgYXMKLSAqIHRoZSBwYXJlbnQgaXMgbm90IGNvbnNpZGVyZWQgdG8gYmUgZ29vZCBjb2Rpbmcgc3R5bGUsCi0gKiBhbmQgbWF5IG5vdCBiZSBzdXBwb3J0ZWQgaW4gYSBmdXR1cmUgcmVsZWFzZSBvZiBTV1QuPC9iPgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBzaGVsbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIE1lc3NhZ2VCb3ggKFNoZWxsIHBhcmVudCkgewogCXRoaXMgKHBhcmVudCwgU1dULk9LIHwgU1dULklDT05fSU5GT1JNQVRJT04gfCBTV1QuQVBQTElDQVRJT05fTU9EQUwpOwogfQogCi0vKioKLSAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50Ci0gKiBhbmQgYSBzdHlsZSB2YWx1ZSBkZXNjcmliaW5nIGl0cyBiZWhhdmlvciBhbmQgYXBwZWFyYW5jZS4KLSAqIDxwPgotICogVGhlIHN0eWxlIHZhbHVlIGlzIGVpdGhlciBvbmUgb2YgdGhlIHN0eWxlIGNvbnN0YW50cyBkZWZpbmVkIGluCi0gKiBjbGFzcyA8Y29kZT5TV1Q8L2NvZGU+IHdoaWNoIGlzIGFwcGxpY2FibGUgdG8gaW5zdGFuY2VzIG9mIHRoaXMKLSAqIGNsYXNzLCBvciBtdXN0IGJlIGJ1aWx0IGJ5IDxlbT5iaXR3aXNlIE9SPC9lbT4naW5nIHRvZ2V0aGVyIAotICogKHRoYXQgaXMsIHVzaW5nIHRoZSA8Y29kZT5pbnQ8L2NvZGU+ICJ8IiBvcGVyYXRvcikgdHdvIG9yIG1vcmUKLSAqIG9mIHRob3NlIDxjb2RlPlNXVDwvY29kZT4gc3R5bGUgY29uc3RhbnRzLiBUaGUgY2xhc3MgZGVzY3JpcHRpb24KLSAqIGxpc3RzIHRoZSBzdHlsZSBjb25zdGFudHMgdGhhdCBhcmUgYXBwbGljYWJsZSB0byB0aGUgY2xhc3MuCi0gKiBTdHlsZSBiaXRzIGFyZSBhbHNvIGluaGVyaXRlZCBmcm9tIHN1cGVyY2xhc3Nlcy4KLSAqIDwvcD4KLSAqIE5vdGU6IEN1cnJlbnRseSwgbnVsbCBjYW4gYmUgcGFzc2VkIGluIGZvciB0aGUgcGFyZW50LgotICogVGhpcyBoYXMgdGhlIGVmZmVjdCBvZiBjcmVhdGluZyB0aGUgZGlhbG9nIG9uIHRoZSBjdXJyZW50bHkgYWN0aXZlCi0gKiBkaXNwbGF5IGlmIHRoZXJlIGlzIG9uZS4gSWYgdGhlcmUgaXMgbm8gY3VycmVudCBkaXNwbGF5LCB0aGUgCi0gKiBkaWFsb2cgaXMgY3JlYXRlZCBvbiBhICJkZWZhdWx0IiBkaXNwbGF5LiA8Yj5QYXNzaW5nIGluIG51bGwgYXMKLSAqIHRoZSBwYXJlbnQgaXMgbm90IGNvbnNpZGVyZWQgdG8gYmUgZ29vZCBjb2Rpbmcgc3R5bGUsCi0gKiBhbmQgbWF5IG5vdCBiZSBzdXBwb3J0ZWQgaW4gYSBmdXR1cmUgcmVsZWFzZSBvZiBTV1QuPC9iPgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBzaGVsbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyBNZXNzYWdlQm94IChTaGVsbCBwYXJlbnQsIGludCBzdHlsZSkgewogCXN1cGVyIChwYXJlbnQsIGNoZWNrU3R5bGUgKHN0eWxlKSk7CisJY2hlY2tTdWJjbGFzcyAoKTsKIH0KIAogc3RhdGljIGludCBjaGVja1N0eWxlIChpbnQgc3R5bGUpIHsKQEAgLTEwNSwxNzkgKzM1LDE0MSBAQAogCXJldHVybiBzdHlsZTsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIHRoZSBkaWFsb2cncyBtZXNzYWdlLCB3aGljaCBpcyBhIGRlc2NyaXB0aW9uIG9mCi0gKiB0aGUgcHVycG9zZSBmb3Igd2hpY2ggaXQgd2FzIG9wZW5lZC4gVGhpcyBtZXNzYWdlIHdpbGwgYmUKLSAqIHZpc2libGUgb24gdGhlIGRpYWxvZyB3aGlsZSBpdCBpcyBvcGVuLgotICoKLSAqIEByZXR1cm4gdGhlIG1lc3NhZ2UKLSAqLwogcHVibGljIFN0cmluZyBnZXRNZXNzYWdlICgpIHsKIAlyZXR1cm4gbWVzc2FnZTsKIH0KIAotLyoqCi0gKiBNYWtlcyB0aGUgZGlhbG9nIHZpc2libGUgYW5kIGJyaW5ncyBpdCB0byB0aGUgZnJvbnQKLSAqIG9mIHRoZSBkaXNwbGF5LgotICoKLSAqIEByZXR1cm4gdGhlIElEIG9mIHRoZSBidXR0b24gdGhhdCB3YXMgc2VsZWN0ZWQgdG8gZGlzbWlzcyB0aGUKLSAqICAgICAgICAgbWVzc2FnZSBib3ggKGUuZy4gU1dULk9LLCBTV1QuQ0FOQ0VMLCBldGMuLi4pCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSBkaWFsb2cgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgZGlhbG9nPC9saT4KLSAqIDwvdWw+Ci0gKi8KK2ludCBnZXRDRlN0cmluZyAoU3RyaW5nIGlkKSB7CisJU3RyaW5nIHN0cmluZyA9IFNXVC5nZXRNZXNzYWdlKGlkKTsKKwljaGFyIFtdIGJ1ZmZlciA9IG5ldyBjaGFyIFtzdHJpbmcubGVuZ3RoICgpXTsKKwlzdHJpbmcuZ2V0Q2hhcnMgKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlciwgMCk7CisJcmV0dXJuIE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMgKE9TLmtDRkFsbG9jYXRvckRlZmF1bHQsIGJ1ZmZlciwgYnVmZmVyLmxlbmd0aCk7Cit9CisKIHB1YmxpYyBpbnQgb3BlbiAoKSB7Ci0KLQkvKiBDb21wdXRlIHRoZSBNZXNzYWdlQm94IHN0eWxlICovCi0JLyogQVcKLQlpbnQgYnV0dG9uQml0cyA9IDA7Ci0JaWYgKChzdHlsZSAmIFNXVC5PSykgPT0gU1dULk9LKSBidXR0b25CaXRzID0gT1MuTUJfT0s7Ci0JaWYgKChzdHlsZSAmIChTV1QuT0sgfCBTV1QuQ0FOQ0VMKSkgPT0gKFNXVC5PSyB8IFNXVC5DQU5DRUwpKSBidXR0b25CaXRzID0gT1MuTUJfT0tDQU5DRUw7Ci0JaWYgKChzdHlsZSAmIChTV1QuWUVTIHwgU1dULk5PKSkgPT0gKFNXVC5ZRVMgfCBTV1QuTk8pKSBidXR0b25CaXRzID0gT1MuTUJfWUVTTk87Ci0JaWYgKChzdHlsZSAmIChTV1QuWUVTIHwgU1dULk5PIHwgU1dULkNBTkNFTCkpID09IChTV1QuWUVTIHwgU1dULk5PIHwgU1dULkNBTkNFTCkpIGJ1dHRvbkJpdHMgPSBPUy5NQl9ZRVNOT0NBTkNFTDsKLQlpZiAoKHN0eWxlICYgKFNXVC5SRVRSWSB8IFNXVC5DQU5DRUwpKSA9PSAoU1dULlJFVFJZIHwgU1dULkNBTkNFTCkpIGJ1dHRvbkJpdHMgPSBPUy5NQl9SRVRSWUNBTkNFTDsKLQlpZiAoKHN0eWxlICYgKFNXVC5BQk9SVCB8IFNXVC5SRVRSWSB8IFNXVC5JR05PUkUpKSA9PSAoU1dULkFCT1JUIHwgU1dULlJFVFJZIHwgU1dULklHTk9SRSkpIGJ1dHRvbkJpdHMgPSBPUy5NQl9BQk9SVFJFVFJZSUdOT1JFOwotCWlmIChidXR0b25CaXRzID09IDApIGJ1dHRvbkJpdHMgPSBPUy5NQl9PSzsKLQotCWludCBpY29uQml0cyA9IDA7Ci0JaWYgKChzdHlsZSAmIFNXVC5JQ09OX0VSUk9SKSAhPSAwKSBpY29uQml0cyA9IE9TLk1CX0lDT05FUlJPUjsKLQlpZiAoKHN0eWxlICYgU1dULklDT05fSU5GT1JNQVRJT04pICE9IDApIGljb25CaXRzID0gT1MuTUJfSUNPTklORk9STUFUSU9OOwotCWlmICgoc3R5bGUgJiBTV1QuSUNPTl9RVUVTVElPTikgIT0gMCkgaWNvbkJpdHMgPSBPUy5NQl9JQ09OUVVFU1RJT047Ci0JaWYgKChzdHlsZSAmIFNXVC5JQ09OX1dBUk5JTkcpICE9IDApIGljb25CaXRzID0gT1MuTUJfSUNPTldBUk5JTkc7Ci0JaWYgKChzdHlsZSAmIFNXVC5JQ09OX1dPUktJTkcpICE9IDApIGljb25CaXRzID0gT1MuTUJfSUNPTklORk9STUFUSU9OOwotCi0JaW50IG1vZGFsQml0cyA9IDA7Ci0JaWYgKChzdHlsZSAmIFNXVC5QUklNQVJZX01PREFMKSAhPSAwKSBtb2RhbEJpdHMgPSBPUy5NQl9BUFBMTU9EQUw7Ci0JaWYgKChzdHlsZSAmIFNXVC5BUFBMSUNBVElPTl9NT0RBTCkgIT0gMCkgbW9kYWxCaXRzID0gT1MuTUJfVEFTS01PREFMOwotCWlmICgoc3R5bGUgJiBTV1QuU1lTVEVNX01PREFMKSAhPSAwKSBtb2RhbEJpdHMgPSBPUy5NQl9TWVNURU1NT0RBTDsKLQotCWludCBiaXRzID0gYnV0dG9uQml0cyB8IGljb25CaXRzIHwgbW9kYWxCaXRzOwotCSovCi0JCQotCXNob3J0IGFsZXJ0VHlwZTsKLQlpZiAoKHN0eWxlICYgU1dULklDT05fRVJST1IpICE9IDApCi0JCWFsZXJ0VHlwZT0gT1Mua0FsZXJ0U3RvcEFsZXJ0OwotCWVsc2UgaWYgKChzdHlsZSAmIFNXVC5JQ09OX0lORk9STUFUSU9OKSAhPSAwKQotCQlhbGVydFR5cGU9IE9TLmtBbGVydE5vdGVBbGVydDsKLQllbHNlIGlmICgoc3R5bGUgJiBTV1QuSUNPTl9RVUVTVElPTikgIT0gMCkKLQkJYWxlcnRUeXBlPSBPUy5rQWxlcnROb3RlQWxlcnQ7Ci0JZWxzZSBpZiAoKHN0eWxlICYgU1dULklDT05fV0FSTklORykgIT0gMCkKLQkJYWxlcnRUeXBlPSBPUy5rQWxlcnRDYXV0aW9uQWxlcnQ7Ci0JZWxzZSBpZiAoKHN0eWxlICYgU1dULklDT05fV09SS0lORykgIT0gMCkKLQkJYWxlcnRUeXBlPSBPUy5rQWxlcnROb3RlQWxlcnQ7Ci0JZWxzZQotCQlhbGVydFR5cGU9IE9TLmtBbGVydFBsYWluQWxlcnQ7Ci0KKwlzaG9ydCBhbGVydFR5cGUgPSBPUy5rQWxlcnRQbGFpbkFsZXJ0OworCWlmICgoc3R5bGUgJiBTV1QuSUNPTl9FUlJPUikgIT0gMCkgYWxlcnRUeXBlID0gT1Mua0FsZXJ0U3RvcEFsZXJ0OworCWlmICgoc3R5bGUgJiBTV1QuSUNPTl9JTkZPUk1BVElPTikgIT0gMCkgYWxlcnRUeXBlID0gT1Mua0FsZXJ0Tm90ZUFsZXJ0OworCWlmICgoc3R5bGUgJiBTV1QuSUNPTl9RVUVTVElPTikgIT0gMCkgYWxlcnRUeXBlID0gT1Mua0FsZXJ0Tm90ZUFsZXJ0OworCWlmICgoc3R5bGUgJiBTV1QuSUNPTl9XQVJOSU5HKSAhPSAwKSBhbGVydFR5cGUgPSBPUy5rQWxlcnRDYXV0aW9uQWxlcnQ7CisJaWYgKChzdHlsZSAmIFNXVC5JQ09OX1dPUktJTkcpICE9IDApIGFsZXJ0VHlwZSA9IE9TLmtBbGVydE5vdGVBbGVydDsKIAkKLQkvKgotCSogRmVhdHVyZSBpbiBXaW5kb3dzLiAgU3lzdGVtIG1vZGFsIGlzIG5vdCBzdXBwb3J0ZWQKLQkqIG9uIFdpbmRvd3MgOTUgYW5kIE5ULiAgVGhlIGZpeCBpcyB0byBjb252ZXJ0IHN5c3RlbQotCSogbW9kYWwgdG8gdGFzayBtb2RhbC4KLQkqLwotCS8qIEFXCi0JaWYgKChiaXRzICYgT1MuTUJfU1lTVEVNTU9EQUwpICE9IDApIHsKLQkJYml0cyB8PSBPUy5NQl9UQVNLTU9EQUw7Ci0JCWJpdHMgJj0gfk9TLk1CX1NZU1RFTU1PREFMOwotCX0KLQkqLwotCi0JLyoKLQkqIEJ1ZyBpbiBXaW5kb3dzLiAgSW4gb3JkZXIgZm9yIE1CX1RBU0tNT0RBTCB0byB3b3JrLAotCSogdGhlIHBhcmVudCBIV05EIG9mIHRoZSBNZXNzYWdlQm94ICgpIGNhbGwgbXVzdCBiZSBOVUxMLgotCSogVGhlIGZpeCBpcyB0byBmb3JjZSB0aGUgcGFyZW50IHRvIGJlIE5VTEwgd2hlbiB0aGlzCi0JKiBzdHlsZSBpcyBzZXQuCi0JKi8KLQkvKiBBVwotCWludCBod25kT3duZXIgPSAwOwotCWlmIChwYXJlbnQgIT0gbnVsbCAmJiAoYml0cyAmIE9TLk1CX1RBU0tNT0RBTCkgPT0gMCkgewotCQlod25kT3duZXIgPSBwYXJlbnQuaGFuZGxlOwotCX0KLQkqLwotCi0JLyoKLQkqIEZlYXR1cmUgaW4gV2luZG93cy4gIFRoZSBmb2N1cyB3aW5kb3cgaXMgbm90IHNhdmVkIGFuZAotCSogYW5kIHJlc3RvcmVkIGF1dG9tYXRpY2FsbHkgYnkgdGhlIGNhbGwgdG8gTWVzc2FnZUJveCgpLgotCSogVGhlIGZpeCBpcyB0byBzYXZlIGFuZCByZXN0b3JlIHRoZSBmb2N1cyB3aW5kb3cuCi0JKi8KLQkvKiBBVwotCWludCBod25kRm9jdXMgPSBPUy5HZXRGb2N1cyAoKTsKLQkqLwotCi0JLyogT3BlbiB0aGUgbWVzc2FnZSBib3ggKi8KLQkvKiBVc2UgdGhlIGNoYXJhY3RlciBlbmNvZGluZyBmb3IgdGhlIGRlZmF1bHQgbG9jYWxlICovCi0JLyogQVcKLQlUQ0hBUiBidWZmZXIxID0gbmV3IFRDSEFSICgwLCBtZXNzYWdlLCB0cnVlKTsKLQlUQ0hBUiBidWZmZXIyID0gbmV3IFRDSEFSICgwLCB0aXRsZSwgdHJ1ZSk7Ci0JaW50IGNvZGUgPSBPUy5NZXNzYWdlQm94IChod25kT3duZXIsIGJ1ZmZlcjEsIGJ1ZmZlcjIsIGJpdHMpOwotCSovCi0JCi0JaW50IGVycm9yTWVzc2FnZT0gMDsKLQlpbnRbXSBkaWFsb2dSZWY9IG5ldyBpbnRbMV07Ci0JdHJ5IHsKLQkJZXJyb3JNZXNzYWdlPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzKG1lc3NhZ2UpOwotCQlPUy5DcmVhdGVTdGFuZGFyZEFsZXJ0KGFsZXJ0VHlwZSwgZXJyb3JNZXNzYWdlLCAwLCAwLCBkaWFsb2dSZWYpOwotCX0gZmluYWxseSB7Ci0JCWlmIChlcnJvck1lc3NhZ2UgIT0gMCkKLQkJCU9TLkNGUmVsZWFzZShlcnJvck1lc3NhZ2UpOworCWludCBlcnJvciA9IDA7CisJaW50IGV4cGxhbmF0aW9uID0gMDsKKwlTdHJpbmcgZXJyb3JTdHJpbmcgPSAodGl0bGUgIT0gIiIpID8gdGl0bGUgOiAoKG1lc3NhZ2UgIT0gIiIpID8gbWVzc2FnZSA6IG51bGwpOworCVN0cmluZyBleHBsYW5hdGlvblN0cmluZyA9ICh0aXRsZSA9PSAiIikgPyBudWxsIDogKChtZXNzYWdlICE9ICIiKSA/IG1lc3NhZ2UgOiBudWxsKTsKKwlpZiAoZXJyb3JTdHJpbmcgIT0gbnVsbCkgeworCQljaGFyIFtdIGJ1ZmZlciA9IG5ldyBjaGFyIFtlcnJvclN0cmluZy5sZW5ndGggKCldOworCQllcnJvclN0cmluZy5nZXRDaGFycyAoMCwgYnVmZmVyLmxlbmd0aCwgYnVmZmVyLCAwKTsKKwkJZXJyb3IgPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzIChPUy5rQ0ZBbGxvY2F0b3JEZWZhdWx0LCBidWZmZXIsIGJ1ZmZlci5sZW5ndGgpOworCX0gCisJaWYgKGV4cGxhbmF0aW9uU3RyaW5nICE9IG51bGwpIHsKKwkJY2hhciBbXSBidWZmZXIgPSBuZXcgY2hhciBbZXhwbGFuYXRpb25TdHJpbmcubGVuZ3RoICgpXTsKKwkJZXhwbGFuYXRpb25TdHJpbmcuZ2V0Q2hhcnMgKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlciwgMCk7CisJCWV4cGxhbmF0aW9uID0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgYnVmZmVyLCBidWZmZXIubGVuZ3RoKTsJCQogCX0KIAkKLQlzaG9ydFtdIGl0ZW1IaXQ9IG5ldyBzaG9ydFsxXTsKLQlpZiAoZGlhbG9nUmVmWzBdICE9IDApCi0JCU9TLlJ1blN0YW5kYXJkQWxlcnQoZGlhbG9nUmVmWzBdLCAwLCBpdGVtSGl0KTsKKwlBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlYyBwYXJhbSA9IG5ldyBBbGVydFN0ZENGU3RyaW5nQWxlcnRQYXJhbVJlYyAoKTsKKwlwYXJhbS52ZXJzaW9uID0gT1Mua1N0ZENGU3RyaW5nQWxlcnRWZXJzaW9uT25lOworCXBhcmFtLnBvc2l0aW9uID0gKHNob3J0KU9TLmtXaW5kb3dBbGVydFBvc2l0aW9uUGFyZW50V2luZG93U2NyZWVuOworCWludCBkZWZhdWx0U3RyID0gMCwgY2FuY2VsU3RyID0gMCwgb3RoZXJTdHIgPSAwOworCWludCBtYXNrID0gKFNXVC5ZRVMgfCBTV1QuTk8gfCBTV1QuT0sgfCBTV1QuQ0FOQ0VMIHwgU1dULkFCT1JUIHwgU1dULlJFVFJZIHwgU1dULklHTk9SRSk7CisJaW50IGJpdHMgPSBzdHlsZSAmIG1hc2s7CisJc3dpdGNoIChiaXRzKSB7CisJCWNhc2UgU1dULk9LOgorCQkJcGFyYW0uZGVmYXVsdEJ1dHRvbiA9IChzaG9ydClPUy5rQWxlcnRTdGRBbGVydE9LQnV0dG9uOworCQkJcGFyYW0uZGVmYXVsdFRleHQgPSBPUy5rQWxlcnREZWZhdWx0T0tUZXh0OworCQkJYnJlYWs7CisJCWNhc2UgU1dULkNBTkNFTDoKKwkJCXBhcmFtLmRlZmF1bHRCdXR0b24gPSAoc2hvcnQpT1Mua0FsZXJ0U3RkQWxlcnRPS0J1dHRvbjsKKwkJCXBhcmFtLmRlZmF1bHRUZXh0ID0gZGVmYXVsdFN0ciA9IGdldENGU3RyaW5nICgiU1dUX0NhbmNlbCIpOworCQkJYnJlYWs7CisJCWNhc2UgU1dULk9LIHwgU1dULkNBTkNFTDoKKwkJCXBhcmFtLmRlZmF1bHRCdXR0b24gPSAoc2hvcnQpT1Mua0FsZXJ0U3RkQWxlcnRPS0J1dHRvbjsKKwkJCXBhcmFtLmRlZmF1bHRUZXh0ID0gT1Mua0FsZXJ0RGVmYXVsdE9LVGV4dDsKKwkJCXBhcmFtLmNhbmNlbEJ1dHRvbiA9IChzaG9ydClPUy5rQWxlcnRTdGRBbGVydENhbmNlbEJ1dHRvbjsKKwkJCXBhcmFtLmNhbmNlbFRleHQgPSBPUy5rQWxlcnREZWZhdWx0Q2FuY2VsVGV4dDsKKwkJCWJyZWFrOworCQljYXNlIFNXVC5ZRVM6CisJCQlwYXJhbS5kZWZhdWx0QnV0dG9uID0gKHNob3J0KU9TLmtBbGVydFN0ZEFsZXJ0T0tCdXR0b247CisJCQlwYXJhbS5kZWZhdWx0VGV4dCA9IGRlZmF1bHRTdHIgPSBnZXRDRlN0cmluZyAoIlNXVF9ZZXMiKTsKKwkJCWJyZWFrOworCQljYXNlIFNXVC5OTzoKKwkJCXBhcmFtLmNhbmNlbEJ1dHRvbiA9IChzaG9ydClPUy5rQWxlcnRTdGRBbGVydE9LQnV0dG9uOworCQkJcGFyYW0uY2FuY2VsVGV4dCA9IGRlZmF1bHRTdHIgPSBnZXRDRlN0cmluZyAoIlNXVF9ObyIpOworCQkJYnJlYWs7CisJCWNhc2UgU1dULllFUyB8IFNXVC5OTzoKKwkJCXBhcmFtLmRlZmF1bHRCdXR0b24gPSAoc2hvcnQpT1Mua0FsZXJ0U3RkQWxlcnRPS0J1dHRvbjsKKwkJCXBhcmFtLmRlZmF1bHRUZXh0ID0gZGVmYXVsdFN0ciA9IGdldENGU3RyaW5nICgiU1dUX1llcyIpOworCQkJcGFyYW0uY2FuY2VsQnV0dG9uID0gKHNob3J0KU9TLmtBbGVydFN0ZEFsZXJ0Q2FuY2VsQnV0dG9uOworCQkJcGFyYW0uY2FuY2VsVGV4dCA9IGNhbmNlbFN0ciA9IGdldENGU3RyaW5nICgiU1dUX05vIik7CisJCQlicmVhazsKKwkJY2FzZSBTV1QuWUVTIHwgU1dULk5PIHwgU1dULkNBTkNFTDoJCQkJCisJCQlwYXJhbS5kZWZhdWx0QnV0dG9uID0gKHNob3J0KU9TLmtBbGVydFN0ZEFsZXJ0T0tCdXR0b247CisJCQlwYXJhbS5kZWZhdWx0VGV4dCA9IGRlZmF1bHRTdHIgPSBnZXRDRlN0cmluZyAoIlNXVF9ZZXMiKTsKKwkJCXBhcmFtLm90aGVyVGV4dCA9IGNhbmNlbFN0ciA9IGdldENGU3RyaW5nICgiU1dUX05vIik7CisJCQlwYXJhbS5jYW5jZWxCdXR0b24gPSAoc2hvcnQpT1Mua0FsZXJ0U3RkQWxlcnRDYW5jZWxCdXR0b247CisJCQlwYXJhbS5jYW5jZWxUZXh0ID0gT1Mua0FsZXJ0RGVmYXVsdENhbmNlbFRleHQ7CisJCQlicmVhazsKKwkJY2FzZSBTV1QuUkVUUlkgfCBTV1QuQ0FOQ0VMOgorCQkJcGFyYW0uZGVmYXVsdEJ1dHRvbiA9IChzaG9ydClPUy5rQWxlcnRTdGRBbGVydE9LQnV0dG9uOworCQkJcGFyYW0uZGVmYXVsdFRleHQgPSBkZWZhdWx0U3RyID0gZ2V0Q0ZTdHJpbmcgKCJTV1RfUmV0cnkiKTsKKwkJCXBhcmFtLmNhbmNlbEJ1dHRvbiA9IChzaG9ydClPUy5rQWxlcnRTdGRBbGVydENhbmNlbEJ1dHRvbjsKKwkJCXBhcmFtLmNhbmNlbFRleHQgPSBPUy5rQWxlcnREZWZhdWx0Q2FuY2VsVGV4dDsKKwkJCWJyZWFrOworCQljYXNlIFNXVC5BQk9SVCB8IFNXVC5SRVRSWSB8IFNXVC5JR05PUkU6CisJCQlwYXJhbS5kZWZhdWx0QnV0dG9uID0gKHNob3J0KU9TLmtBbGVydFN0ZEFsZXJ0T0tCdXR0b247CisJCQlwYXJhbS5kZWZhdWx0VGV4dCA9IGRlZmF1bHRTdHIgPSBnZXRDRlN0cmluZyAoIlNXVF9BYm9ydCIpOworCQkJcGFyYW0ub3RoZXJUZXh0ID0gY2FuY2VsU3RyID0gZ2V0Q0ZTdHJpbmcgKCJTV1RfUmV0cnkiKTsKKwkJCXBhcmFtLmNhbmNlbEJ1dHRvbiA9IChzaG9ydClPUy5rQWxlcnRTdGRBbGVydENhbmNlbEJ1dHRvbjsKKwkJCXBhcmFtLmNhbmNlbFRleHQgPSBvdGhlclN0ciA9IGdldENGU3RyaW5nICgiU1dUX0lnbm9yZSIpOworCQkJYnJlYWs7CisJfQogCQotCVN5c3RlbS5vdXQucHJpbnRsbigiQWxlcnQgY29kZTogIiArIGl0ZW1IaXRbMF0pOworCWludCBbXSBkaWFsb2dSZWY9IG5ldyBpbnQgWzFdOworCWludCByZXN1bHQgPSBPUy5DcmVhdGVTdGFuZGFyZEFsZXJ0IChhbGVydFR5cGUsIGVycm9yLCBleHBsYW5hdGlvbiwgcGFyYW0sIGRpYWxvZ1JlZik7CisJaWYgKGVycm9yICE9IDApIE9TLkNGUmVsZWFzZShlcnJvcik7CisJaWYgKGV4cGxhbmF0aW9uICE9IDApIE9TLkNGUmVsZWFzZShleHBsYW5hdGlvbik7CisJaWYgKGRlZmF1bHRTdHIgIT0gMCkgT1MuQ0ZSZWxlYXNlKGRlZmF1bHRTdHIpOworCWlmIChjYW5jZWxTdHIgIT0gMCkgT1MuQ0ZSZWxlYXNlKGNhbmNlbFN0cik7CisJaWYgKG90aGVyU3RyICE9IDApIE9TLkNGUmVsZWFzZShvdGhlclN0cik7CiAJCi0JLyogUmVzdG9yZSBmb2N1cyAqLwotCS8qIEFXCi0JT1MuU2V0Rm9jdXMgKGh3bmRGb2N1cyk7Ci0JKi8KLQkKLQkvKgotCSogVGhpcyBjb2RlIGlzIGludGVudGlvbmFsbHkgY29tbWVudGVkLiAgT24gc29tZQotCSogcGxhdGZvcm1zLCB0aGUgb3duZXIgd2luZG93IGlzIHJlcGFpbnRlZCByaWdodAotCSogYXdheSB3aGVuIGEgZGlhbG9nIHdpbmRvdyBleGl0cy4gIFRoaXMgYmVoYXZpb3IKLQkqIGlzIGN1cnJlbnRseSB1bnNwZWNpZmllZC4KLQkqLwotLy8JaWYgKGh3bmRPd25lciAhPSAwKSBPUy5VcGRhdGVXaW5kb3cgKGh3bmRPd25lcik7Ci0JCi0JLyogQ29tcHV0ZSBhbmQgcmV0dXJuIHRoZSByZXN1bHQgKi8KLQkvKiBBVwotCWlmIChjb2RlICE9IDApIHsKLQkJaW50IHR5cGUgPSBiaXRzICYgMHgwRjsKLQkJaWYgKHR5cGUgPT0gT1MuTUJfT0spIHJldHVybiBTV1QuT0s7Ci0JCWlmICh0eXBlID09IE9TLk1CX09LQ0FOQ0VMKSB7Ci0JCQlyZXR1cm4gKGNvZGUgPT0gT1MuSURPSykgPyBTV1QuT0sgOiBTV1QuQ0FOQ0VMOwotCQl9Ci0JCWlmICh0eXBlID09IE9TLk1CX1lFU05PKSB7Ci0JCQlyZXR1cm4gKGNvZGUgPT0gT1MuSURZRVMpID8gU1dULllFUyA6IFNXVC5OTzsKLQkJfQotCQlpZiAodHlwZSA9PSBPUy5NQl9ZRVNOT0NBTkNFTCkgewotCQkJaWYgKGNvZGUgPT0gT1MuSURZRVMpIHJldHVybiBTV1QuWUVTOwotCQkJaWYgKGNvZGUgPT0gT1MuSUROTykgcmV0dXJuIFNXVC5OTzsKLQkJCXJldHVybiBTV1QuQ0FOQ0VMOwotCQl9Ci0JCWlmICh0eXBlID09IE9TLk1CX1JFVFJZQ0FOQ0VMKSB7Ci0JCQlyZXR1cm4gKGNvZGUgPT0gT1MuSURSRVRSWSkgPyBTV1QuUkVUUlkgOiBTV1QuQ0FOQ0VMOwotCQl9Ci0JCWlmICh0eXBlID09IE9TLk1CX0FCT1JUUkVUUllJR05PUkUpIHsKLQkJCWlmIChjb2RlID09IE9TLklEUkVUUlkpIHJldHVybiBTV1QuUkVUUlk7Ci0JCQlpZiAoY29kZSA9PSBPUy5JREFCT1JUKSByZXR1cm4gU1dULkFCT1JUOwotCQkJcmV0dXJuIFNXVC5JR05PUkU7CisJaWYgKGRpYWxvZ1JlZlswXSAhPSAwKSB7CisJCXNob3J0IFtdIG91dEl0ZW1IaXQgPSBuZXcgc2hvcnQgWzFdOworCQlPUy5SdW5TdGFuZGFyZEFsZXJ0KGRpYWxvZ1JlZlswXSwgMCwgb3V0SXRlbUhpdCk7CisJCWlmIChvdXRJdGVtSGl0IFswXSAhPSAwKSB7CisJCQlzd2l0Y2ggKGJpdHMpIHsKKwkJCQljYXNlIFNXVC5PSzoKKwkJCQkJcmV0dXJuIFNXVC5PSzsKKwkJCQljYXNlIFNXVC5DQU5DRUw6CisJCQkJCXJldHVybiBTV1QuQ0FOQ0VMOworCQkJCWNhc2UgU1dULk9LIHwgU1dULkNBTkNFTDoKKwkJCQkJaWYgKG91dEl0ZW1IaXQgWzBdID09IE9TLmtBbGVydFN0ZEFsZXJ0T0tCdXR0b24pIHJldHVybiBTV1QuT0s7CisJCQkJCXJldHVybiBTV1QuQ0FOQ0VMOworCQkJCWNhc2UgU1dULllFUzoKKwkJCQkJcmV0dXJuIFNXVC5ZRVM7CisJCQkJY2FzZSBTV1QuTk86CisJCQkJCXJldHVybiBTV1QuTk87CisJCQkJY2FzZSBTV1QuWUVTIHwgU1dULk5POgorCQkJCQlpZiAob3V0SXRlbUhpdCBbMF0gPT0gT1Mua0FsZXJ0U3RkQWxlcnRPS0J1dHRvbikgcmV0dXJuIFNXVC5ZRVM7CisJCQkJCXJldHVybiBTV1QuTk87CisJCQkJY2FzZSBTV1QuWUVTIHwgU1dULk5PIHwgU1dULkNBTkNFTDoKKwkJCQkJaWYgKG91dEl0ZW1IaXQgWzBdID09IE9TLmtBbGVydFN0ZEFsZXJ0T0tCdXR0b24pIHJldHVybiBTV1QuWUVTOworCQkJCQlpZiAob3V0SXRlbUhpdCBbMF0gPT0gT1Mua0FsZXJ0U3RkQWxlcnRPdGhlckJ1dHRvbikgcmV0dXJuIFNXVC5OTzsKKwkJCQkJcmV0dXJuIFNXVC5DQU5DRUw7CisJCQkJY2FzZSBTV1QuUkVUUlkgfCBTV1QuQ0FOQ0VMOgorCQkJCQlpZiAob3V0SXRlbUhpdCBbMF0gPT0gT1Mua0FsZXJ0U3RkQWxlcnRPS0J1dHRvbikgcmV0dXJuIFNXVC5SRVRSWTsKKwkJCQkJcmV0dXJuIFNXVC5DQU5DRUw7CisJCQkJY2FzZSBTV1QuQUJPUlQgfCBTV1QuUkVUUlkgfCBTV1QuSUdOT1JFOgorCQkJCQlpZiAob3V0SXRlbUhpdCBbMF0gPT0gT1Mua0FsZXJ0U3RkQWxlcnRPS0J1dHRvbikgcmV0dXJuIFNXVC5BQk9SVDsKKwkJCQkJaWYgKG91dEl0ZW1IaXQgWzBdID09IE9TLmtBbGVydFN0ZEFsZXJ0T3RoZXJCdXR0b24pIHJldHVybiBTV1QuUkVUUlk7CisJCQkJCXJldHVybiBTV1QuSUdOT1JFOworCQkJfQogCQl9CiAJfQotCSovCiAJcmV0dXJuIFNXVC5DQU5DRUw7CiB9CiAKLS8qKgotICogU2V0cyB0aGUgZGlhbG9nJ3MgbWVzc2FnZSwgd2hpY2ggaXMgYSBkZXNjcmlwdGlvbiBvZgotICogdGhlIHB1cnBvc2UgZm9yIHdoaWNoIGl0IHdhcyBvcGVuZWQuIFRoaXMgbWVzc2FnZSB3aWxsIGJlCi0gKiB2aXNpYmxlIG9uIHRoZSBkaWFsb2cgd2hpbGUgaXQgaXMgb3Blbi4KLSAqCi0gKiBAcGFyYW0gc3RyaW5nIHRoZSBtZXNzYWdlCi0gKi8KIHB1YmxpYyB2b2lkIHNldE1lc3NhZ2UgKFN0cmluZyBzdHJpbmcpIHsKIAltZXNzYWdlID0gc3RyaW5nOwogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1Byb2dyZXNzQmFyLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvUHJvZ3Jlc3NCYXIuamF2YQppbmRleCBiYmM1ZTQxLi5hNTEyMGM3IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvUHJvZ3Jlc3NCYXIuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvUHJvZ3Jlc3NCYXIuamF2YQpAQCAtNywyNTEgKzcsNzggQEAKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAgKi8KIAotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUG9pbnQ7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlJlY3Q7CisKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuKjsKIAotLyoqCi0gKiBJbnN0YW5jZXMgb2YgdGhlIHJlY2VpdmVyIHJlcHJlc2VudCBpcyBhbiB1bnNlbGVjdGFibGUKLSAqIHVzZXIgaW50ZXJmYWNlIG9iamVjdCB0aGF0IGlzIHVzZWQgdG8gZGlzcGxheSBwcm9ncmVzcywKLSAqIHR5cGljYWxseSBpbiB0aGUgZm9ybSBvZiBhIGJhci4KLSAqIDxkbD4KLSAqIDxkdD48Yj5TdHlsZXM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+U01PT1RILCBIT1JJWk9OVEFMLCBWRVJUSUNBTDwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPihub25lKTwvZGQ+Ci0gKiA8L2RsPgotICogPHA+Ci0gKiBOb3RlOiBPbmx5IG9uZSBvZiB0aGUgc3R5bGVzIEhPUklaT05UQUwgYW5kIFZFUlRJQ0FMIG1heSBiZSBzcGVjaWZpZWQuCi0gKiA8L3A+PHA+Ci0gKiBJTVBPUlRBTlQ6IFRoaXMgY2xhc3MgaXMgaW50ZW5kZWQgdG8gYmUgc3ViY2xhc3NlZCA8ZW0+b25seTwvZW0+Ci0gKiB3aXRoaW4gdGhlIFNXVCBpbXBsZW1lbnRhdGlvbi4KLSAqIDwvcD4KLSAqLwotcHVibGljIC8qZmluYWwqLyBjbGFzcyBQcm9ncmVzc0JhciBleHRlbmRzIENvbnRyb2wgeworcHVibGljIGNsYXNzIFByb2dyZXNzQmFyIGV4dGVuZHMgQ29udHJvbCB7CiAJCi0JLy8gQVcKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0laRT0gMTY7Ci0JcHJpdmF0ZSBpbnQgZlRvcE1hcmdpbjsKLQlwcml2YXRlIGludCBmQm90dG9tTWFyZ2luOwotCS8vIEFXCi0KLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIGl0cyBwYXJlbnQKLSAqIGFuZCBhIHN0eWxlIHZhbHVlIGRlc2NyaWJpbmcgaXRzIGJlaGF2aW9yIGFuZCBhcHBlYXJhbmNlLgotICogPHA+Ci0gKiBUaGUgc3R5bGUgdmFsdWUgaXMgZWl0aGVyIG9uZSBvZiB0aGUgc3R5bGUgY29uc3RhbnRzIGRlZmluZWQgaW4KLSAqIGNsYXNzIDxjb2RlPlNXVDwvY29kZT4gd2hpY2ggaXMgYXBwbGljYWJsZSB0byBpbnN0YW5jZXMgb2YgdGhpcwotICogY2xhc3MsIG9yIG11c3QgYmUgYnVpbHQgYnkgPGVtPmJpdHdpc2UgT1I8L2VtPidpbmcgdG9nZXRoZXIgCi0gKiAodGhhdCBpcywgdXNpbmcgdGhlIDxjb2RlPmludDwvY29kZT4gInwiIG9wZXJhdG9yKSB0d28gb3IgbW9yZQotICogb2YgdGhvc2UgPGNvZGU+U1dUPC9jb2RlPiBzdHlsZSBjb25zdGFudHMuIFRoZSBjbGFzcyBkZXNjcmlwdGlvbgotICogbGlzdHMgdGhlIHN0eWxlIGNvbnN0YW50cyB0aGF0IGFyZSBhcHBsaWNhYmxlIHRvIHRoZSBjbGFzcy4KLSAqIFN0eWxlIGJpdHMgYXJlIGFsc28gaW5oZXJpdGVkIGZyb20gc3VwZXJjbGFzc2VzLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBjb21wb3NpdGUgY29udHJvbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZSAoY2Fubm90IGJlIG51bGwpCi0gKiBAcGFyYW0gc3R5bGUgdGhlIHN0eWxlIG9mIGNvbnRyb2wgdG8gY29uc3RydWN0Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcGFyZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHBhcmVudDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNXVCNTTU9PVEgKLSAqIEBzZWUgU1dUI0hPUklaT05UQUwKLSAqIEBzZWUgU1dUI1ZFUlRJQ0FMCi0gKiBAc2VlIFdpZGdldCNjaGVja1N1YmNsYXNzCi0gKiBAc2VlIFdpZGdldCNnZXRTdHlsZQotICovCiBwdWJsaWMgUHJvZ3Jlc3NCYXIgKENvbXBvc2l0ZSBwYXJlbnQsIGludCBzdHlsZSkgewogCXN1cGVyIChwYXJlbnQsIGNoZWNrU3R5bGUgKHN0eWxlKSk7CiB9CisKIHN0YXRpYyBpbnQgY2hlY2tTdHlsZSAoaW50IHN0eWxlKSB7CiAJcmV0dXJuIGNoZWNrQml0cyAoc3R5bGUsIFNXVC5IT1JJWk9OVEFMLCBTV1QuVkVSVElDQUwsIDAsIDAsIDAsIDApOwogfQorCiBwdWJsaWMgUG9pbnQgY29tcHV0ZVNpemUgKGludCB3SGludCwgaW50IGhIaW50LCBib29sZWFuIGNoYW5nZWQpIHsKIAljaGVja1dpZGdldCgpOwotCWludCBib3JkZXIgPSBnZXRCb3JkZXJXaWR0aCAoKTsKLQlpbnQgd2lkdGggPSBib3JkZXIgKiAyLCBoZWlnaHQgPSBib3JkZXIgKiAyOworCWludCBbXSBvdXRNZXRyaWMgPSBuZXcgaW50IFsxXTsKKwlPUy5HZXRUaGVtZU1ldHJpYyAoT1Mua1RoZW1lTWV0cmljTm9ybWFsUHJvZ3Jlc3NCYXJUaGlja25lc3MsIG91dE1ldHJpYyk7CisJaW50IHdpZHRoID0gMCwgaGVpZ2h0ID0gMDsKIAlpZiAoKHN0eWxlICYgU1dULkhPUklaT05UQUwpICE9IDApIHsKLQkJd2lkdGggKz0gU0laRSAqIDEwOwotCQloZWlnaHQgKz0gU0laRTsKKwkJaGVpZ2h0ID0gb3V0TWV0cmljIFswXTsKKwkJd2lkdGggPSBoZWlnaHQgKiAxMDsKIAl9IGVsc2UgewotCQl3aWR0aCArPSBTSVpFOwotCQloZWlnaHQgKz0gU0laRSAqIDEwOworCQl3aWR0aCA9IG91dE1ldHJpYyBbMF07CisJCWhlaWdodCA9IHdpZHRoICogMTA7CiAJfQotCWlmICh3SGludCAhPSBTV1QuREVGQVVMVCkgd2lkdGggPSB3SGludCArIChib3JkZXIgKiAyKTsKLQlpZiAoaEhpbnQgIT0gU1dULkRFRkFVTFQpIGhlaWdodCA9IGhIaW50ICsgKGJvcmRlciAqIDIpOworCWlmICh3SGludCAhPSBTV1QuREVGQVVMVCkgd2lkdGggPSB3SGludDsKKwlpZiAoaEhpbnQgIT0gU1dULkRFRkFVTFQpIGhlaWdodCA9IGhIaW50OwogCXJldHVybiBuZXcgUG9pbnQgKHdpZHRoLCBoZWlnaHQpOwogfQotdm9pZCBjcmVhdGVIYW5kbGUgKGludCBpbmRleCkgewotCXN0YXRlIHw9IEhBTkRMRTsKLQlpbnQgcGFyZW50SGFuZGxlID0gcGFyZW50LmhhbmRsZTsKLQloYW5kbGUgPSBNYWNVdGlsLm5ld0NvbnRyb2wocGFyZW50SGFuZGxlLCAoc2hvcnQpMCwgKHNob3J0KTAsIChzaG9ydCkxMDAsIE9TLmtDb250cm9sUHJvZ3Jlc3NCYXJQcm9jKTsKLQlpZiAoaGFuZGxlID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7Ci0JaWYgKChzdHlsZSAmIFNXVC5JTkRFVEVSTUlOQVRFKSAhPSAwKQotCQlPUy5TZXRDb250cm9sRGF0YShoYW5kbGUsIChzaG9ydCkwLCBPUy5rQ29udHJvbFByb2dyZXNzQmFySW5kZXRlcm1pbmF0ZVRhZywgLTEpOworCit2b2lkIGNyZWF0ZUhhbmRsZSAoKSB7CisJaW50IFtdIG91dENvbnRyb2wgPSBuZXcgaW50IFsxXTsKKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChwYXJlbnQuaGFuZGxlKTsKKwlPUy5DcmVhdGVQcm9ncmVzc0JhckNvbnRyb2wgKHdpbmRvdywgbnVsbCwgMCwgMCwgMTAwLCAoc3R5bGUgJiBTV1QuSU5ERVRFUk1JTkFURSkgIT0gMCwgb3V0Q29udHJvbCk7CisJaWYgKG91dENvbnRyb2wgWzBdID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7CisJaGFuZGxlID0gb3V0Q29udHJvbCBbMF07CiB9Ci0vKiBBVwotdm9pZCBkaXNhYmxlQnV0dG9uUHJlc3MgKCkgewotCWludCB4V2luZG93ID0gT1MuWHRXaW5kb3cgKGhhbmRsZSk7Ci0JaWYgKHhXaW5kb3cgPT0gMCkgcmV0dXJuOwotCWludCB4RGlzcGxheSA9IE9TLlh0RGlzcGxheSAoaGFuZGxlKTsKLQlpZiAoeERpc3BsYXkgPT0gMCkgcmV0dXJuOwotCWludCBldmVudF9tYXNrID0gT1MuWHRCdWlsZEV2ZW50TWFzayAoaGFuZGxlKTsKLQlYU2V0V2luZG93QXR0cmlidXRlcyBhdHRyaWJ1dGVzID0gbmV3IFhTZXRXaW5kb3dBdHRyaWJ1dGVzICgpOwotCWF0dHJpYnV0ZXMuZXZlbnRfbWFzayA9IGV2ZW50X21hc2sgJiB+T1MuQnV0dG9uUHJlc3NNYXNrOwotCU9TLlhDaGFuZ2VXaW5kb3dBdHRyaWJ1dGVzICh4RGlzcGxheSwgeFdpbmRvdywgT1MuQ1dFdmVudE1hc2ssIGF0dHJpYnV0ZXMpOwotfQotdm9pZCBkaXNhYmxlVHJhdmVyc2FsICgpIHsKLQlpbnQgW10gYXJnTGlzdCA9IHtPUy5YbU50cmF2ZXJzYWxPbiwgMH07Ci0JT1MuWHRTZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLX0KLSovCi0vKioKLSAqIFJldHVybnMgdGhlIG1heGltdW0gdmFsdWUgd2hpY2ggdGhlIHJlY2VpdmVyIHdpbGwgYWxsb3cuCi0gKgotICogQHJldHVybiB0aGUgbWF4aW11bQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldE1heGltdW0gKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0gICAgcmV0dXJuIE9TLkdldENvbnRyb2wzMkJpdE1heGltdW0oaGFuZGxlKTsKKyAgICByZXR1cm4gT1MuR2V0Q29udHJvbDMyQml0TWF4aW11bSAoaGFuZGxlKTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgbWluaW11bSB2YWx1ZSB3aGljaCB0aGUgcmVjZWl2ZXIgd2lsbCBhbGxvdy4KLSAqCi0gKiBAcmV0dXJuIHRoZSBtaW5pbXVtCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBpbnQgZ2V0TWluaW11bSAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLSAgICByZXR1cm4gT1MuR2V0Q29udHJvbDMyQml0TWluaW11bShoYW5kbGUpOworICAgIHJldHVybiBPUy5HZXRDb250cm9sMzJCaXRNaW5pbXVtIChoYW5kbGUpOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBzaW5nbGUgPGVtPnNlbGVjdGlvbjwvZW0+IHRoYXQgaXMgdGhlIHJlY2VpdmVyJ3MgcG9zaXRpb24uCi0gKgotICogQHJldHVybiB0aGUgc2VsZWN0aW9uCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBpbnQgZ2V0U2VsZWN0aW9uICgpIHsKIAljaGVja1dpZGdldCgpOwotICAgIHJldHVybiBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUpOworICAgIHJldHVybiBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZSAoaGFuZGxlKTsKIH0KLS8qIEFXCi12b2lkIHByb3BhZ2F0ZVdpZGdldCAoYm9vbGVhbiBlbmFibGVkKSB7Ci0Jc3VwZXIucHJvcGFnYXRlV2lkZ2V0IChlbmFibGVkKTsKLQkvKgotCSogUHJvZ3Jlc3NCYXJzIG5ldmVyIHBhcnRpY2lwYXRlIGluIGZvY3VzIHRyYXZlcnNhbCB3aGVuCi0JKiBlaXRoZXIgZW5hYmxlZCBvciBkaXNhYmxlZC4KLQkqLwotCS8qIEFXCi0JaWYgKGVuYWJsZWQpIHsKLQkJZGlzYWJsZVRyYXZlcnNhbCAoKTsKLQkJZGlzYWJsZUJ1dHRvblByZXNzICgpOwotCX0KLX0KLXZvaWQgcmVhbGl6ZUNoaWxkcmVuICgpIHsKLQlzdXBlci5yZWFsaXplQ2hpbGRyZW4gKCk7Ci0JZGlzYWJsZUJ1dHRvblByZXNzICgpOwotfQotKi8KLS8qKgotICogU2V0cyB0aGUgbWF4aW11bSB2YWx1ZSB3aGljaCB0aGUgcmVjZWl2ZXIgd2lsbCBhbGxvdwotICogdG8gYmUgdGhlIGFyZ3VtZW50IHdoaWNoIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yCi0gKiBlcXVhbCB0byB6ZXJvLgotICoKLSAqIEBwYXJhbSB2YWx1ZSB0aGUgbmV3IG1heGltdW0gKG11c3QgYmUgemVybyBvciBncmVhdGVyKQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRNYXhpbXVtIChpbnQgdmFsdWUpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICh2YWx1ZSA8IDApIHJldHVybjsKLSAgICBPUy5TZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSwgdmFsdWUpOworICAgIE9TLlNldENvbnRyb2wzMkJpdE1heGltdW0gKGhhbmRsZSwgdmFsdWUpOwogfQotLyoqCi0gKiBTZXRzIHRoZSBtaW5pbXVtIHZhbHVlIHdoaWNoIHRoZSByZWNlaXZlciB3aWxsIGFsbG93Ci0gKiB0byBiZSB0aGUgYXJndW1lbnQgd2hpY2ggbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IKLSAqIGVxdWFsIHRvIHplcm8uCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgbWluaW11bSAobXVzdCBiZSB6ZXJvIG9yIGdyZWF0ZXIpCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldE1pbmltdW0gKGludCB2YWx1ZSkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHZhbHVlIDwgMCkgcmV0dXJuOwotICAgIE9TLlNldENvbnRyb2wzMkJpdE1pbmltdW0oaGFuZGxlLCB2YWx1ZSk7CisgICAgT1MuU2V0Q29udHJvbDMyQml0TWluaW11bSAoaGFuZGxlLCB2YWx1ZSk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHNpbmdsZSA8ZW0+c2VsZWN0aW9uPC9lbT4gdGhhdCBpcyB0aGUgcmVjZWl2ZXIncwotICogcG9zaXRpb24gdG8gdGhlIGFyZ3VtZW50IHdoaWNoIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsCi0gKiB0byB6ZXJvLgotICoKLSAqIEBwYXJhbSB2YWx1ZSB0aGUgbmV3IHNlbGVjdGlvbiAobXVzdCBiZSB6ZXJvIG9yIGdyZWF0ZXIpCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldFNlbGVjdGlvbiAoaW50IHZhbHVlKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAodmFsdWUgPCAwKSByZXR1cm47Ci0gICAgT1MuU2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlLCB2YWx1ZSk7Ci19Ci0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0vLyBNYWMgc3R1ZmYKLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0KLS8qKgotICogT3ZlcnJpZGRlbiBmcm9tIENvbnRyb2wgc2luY2Ugd2Ugd2FudCB0byBjZW50ZXIgdGhlIGJhciB3aXRoaW4gaXRzIGFyZWEuIAotICovCi12b2lkIGhhbmRsZVJlc2l6ZShpbnQgaG5kbCwgTWFjUmVjdCBib3VuZHMpIHsJCi0JaWYgKChzdHlsZSAmIFNXVC5IT1JJWk9OVEFMKSAhPSAwKSB7IAkvLyBob3Jpem9udGFsCi0JCWludCBkaWZmPSBib3VuZHMuZ2V0SGVpZ2h0KCktU0laRTsKLQkJZlRvcE1hcmdpbj0gZGlmZi8yOwotCQlmQm90dG9tTWFyZ2luPSBkaWZmLWZUb3BNYXJnaW47Ci0JCWJvdW5kcy5pbnNldCgwLCBmVG9wTWFyZ2luLCAwLCBmQm90dG9tTWFyZ2luKTsKLQl9IGVsc2UgewkvLyB2ZXJ0aWNhbAotCQlpbnQgZGlmZj0gYm91bmRzLmdldFdpZHRoKCktU0laRTsKLQkJZlRvcE1hcmdpbj0gZGlmZi8yOwotCQlmQm90dG9tTWFyZ2luPSBkaWZmLWZUb3BNYXJnaW47Ci0JCWJvdW5kcy5pbnNldChmVG9wTWFyZ2luLCAwLCBmQm90dG9tTWFyZ2luLCAwKTsKLQl9Ci0Jc3VwZXIuaGFuZGxlUmVzaXplKGhuZGwsIGJvdW5kcyk7Ci19Ci0KLXZvaWQgaW50ZXJuYWxHZXRDb250cm9sQm91bmRzKGludCBobmRsLCBNYWNSZWN0IGJvdW5kcykgewotCXN1cGVyLmludGVybmFsR2V0Q29udHJvbEJvdW5kcyhobmRsLCBib3VuZHMpOwotCWlmICgoc3R5bGUgJiBTV1QuSE9SSVpPTlRBTCkgIT0gMCkgeyAJLy8gaG9yaXpvbnRhbAotCQlib3VuZHMuaW5zZXQoMCwgLWZUb3BNYXJnaW4sIDAsIC1mQm90dG9tTWFyZ2luKTsKLQl9IGVsc2UgewkvLyB2ZXJ0aWNhbAotCQlib3VuZHMuaW5zZXQoLWZUb3BNYXJnaW4sIDAsIC1mQm90dG9tTWFyZ2luLCAwKTsKLQl9CisgICAgT1MuU2V0Q29udHJvbDMyQml0VmFsdWUgKGhhbmRsZSwgdmFsdWUpOwogfQogCiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvU2FzaC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1Nhc2guamF2YQppbmRleCA1YjVjMDAzLi5mYzEyODc3IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvU2FzaC5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9TYXNoLmphdmEKQEAgLTcsMTM1ICs3LDI0IEBACiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCiAKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkNHUG9pbnQ7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5SZWN0OworCiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7CiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOwogCi0vKioKLSAqIEluc3RhbmNlcyBvZiB0aGUgcmVjZWl2ZXIgcmVwcmVzZW50IGEgc2VsZWN0YWJsZSB1c2VyIGludGVyZmFjZSBvYmplY3QKLSAqIHRoYXQgYWxsb3dzIHRoZSB1c2VyIHRvIGRyYWcgYSBydWJiZXIgYmFuZGVkIG91dGxpbmUgb2YgdGhlIHNhc2ggd2l0aGluCi0gKiB0aGUgcGFyZW50IGNvbnRyb2wuCi0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPkhPUklaT05UQUwsIFZFUlRJQ0FMPC9kZD4KLSAqIDxkdD48Yj5FdmVudHM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+U2VsZWN0aW9uPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cD4KLSAqIE5vdGU6IE9ubHkgb25lIG9mIHRoZSBzdHlsZXMgSE9SSVpPTlRBTCBhbmQgVkVSVElDQUwgbWF5IGJlIHNwZWNpZmllZC4KLSAqIDwvcD48cD4KLSAqIElNUE9SVEFOVDogVGhpcyBjbGFzcyBpcyBpbnRlbmRlZCB0byBiZSBzdWJjbGFzc2VkIDxlbT5vbmx5PC9lbT4KLSAqIHdpdGhpbiB0aGUgU1dUIGltcGxlbWVudGF0aW9uLgotICogPC9wPgotICovCi1wdWJsaWMgLypmaW5hbCovIGNsYXNzIFNhc2ggZXh0ZW5kcyBDb250cm9sIHsKLQlib29sZWFuIGRyYWdnaW5nOwotCWludCBzdGFydFgsIHN0YXJ0WSwgbGFzdFgsIGxhc3RZOworcHVibGljIGNsYXNzIFNhc2ggZXh0ZW5kcyBDb250cm9sIHsKIAotCXByaXZhdGUgc3RhdGljIGludCBIX0FSUk9XOwotCXByaXZhdGUgc3RhdGljIGludCBWX0FSUk9XOwotCQotCXN0YXRpYyB7Ci0JCXNob3J0W10gaD0gbmV3IHNob3J0W10gewotCQkJCShzaG9ydCkgMHgwMzAwLAotCQkJIAkoc2hvcnQpIDB4MDMwMCwKLQkJCQkoc2hvcnQpIDB4MDMwMCwKLQkJCSAJKHNob3J0KSAweDAzMDAsCi0JCQkgCShzaG9ydCkgMHgwMzAwLAotCQkJIAkoc2hvcnQpIDB4MjMxMCwKLQkJCSAJKHNob3J0KSAweDYzMTgsCi0JCQkgCShzaG9ydCkgMHhGQjdDLAotCQkJIAkoc2hvcnQpIDB4NjMxOCwKLQkJCSAJKHNob3J0KSAweDIzMTAsCi0JCQkgCShzaG9ydCkgMHgwMzAwLAotCQkJIAkoc2hvcnQpIDB4MDMwMCwKLQkJCSAJKHNob3J0KSAweDAzMDAsCi0JCQkgCShzaG9ydCkgMHgwMzAwLAotCQkJIAkoc2hvcnQpIDB4MDMwMCwKLQkJCSAJKHNob3J0KSAweDAwMDAKLQkJCX07Ci0JCUhfQVJST1c9IE9TLk5ld0N1cnNvcigoc2hvcnQpNiwgKHNob3J0KTcsIGgsIGgpOwotCQkKLQkJaD0gbmV3IHNob3J0W10gewotCQkJCShzaG9ydCkgMHgwMTAwLAotCQkJIAkoc2hvcnQpIDB4MDM4MCwKLQkJCQkoc2hvcnQpIDB4MDdDMCwKLQkJCSAJKHNob3J0KSAweDAxMDAsCi0JCQkgCShzaG9ydCkgMHgwMTAwLAotCQkJIAkoc2hvcnQpIDB4MDAwMCwKLQkJCSAJKHNob3J0KSAweEZGRkUsCi0JCQkgCShzaG9ydCkgMHhGRkZFLAotCQkJIAkoc2hvcnQpIDB4MDAwMCwKLQkJCSAJKHNob3J0KSAweDAxMDAsCi0JCQkgCShzaG9ydCkgMHgwMTAwLAotCQkJIAkoc2hvcnQpIDB4MDdDMCwKLQkJCSAJKHNob3J0KSAweDAzODAsCi0JCQkgCShzaG9ydCkgMHgwMTAwLAotCQkJIAkoc2hvcnQpIDB4MDAwMCwKLQkJCSAJKHNob3J0KSAweDAwMDAKLQkJCX07Ci0JCVZfQVJST1c9IE9TLk5ld0N1cnNvcigoc2hvcnQpNywgKHNob3J0KTYsIGgsIGgpOwotCX0KKwlDdXJzb3Igc2l6ZUN1cnNvcjsKIAotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gaXRzIHBhcmVudAotICogYW5kIGEgc3R5bGUgdmFsdWUgZGVzY3JpYmluZyBpdHMgYmVoYXZpb3IgYW5kIGFwcGVhcmFuY2UuCi0gKiA8cD4KLSAqIFRoZSBzdHlsZSB2YWx1ZSBpcyBlaXRoZXIgb25lIG9mIHRoZSBzdHlsZSBjb25zdGFudHMgZGVmaW5lZCBpbgotICogY2xhc3MgPGNvZGU+U1dUPC9jb2RlPiB3aGljaCBpcyBhcHBsaWNhYmxlIHRvIGluc3RhbmNlcyBvZiB0aGlzCi0gKiBjbGFzcywgb3IgbXVzdCBiZSBidWlsdCBieSA8ZW0+Yml0d2lzZSBPUjwvZW0+J2luZyB0b2dldGhlciAKLSAqICh0aGF0IGlzLCB1c2luZyB0aGUgPGNvZGU+aW50PC9jb2RlPiAifCIgb3BlcmF0b3IpIHR3byBvciBtb3JlCi0gKiBvZiB0aG9zZSA8Y29kZT5TV1Q8L2NvZGU+IHN0eWxlIGNvbnN0YW50cy4gVGhlIGNsYXNzIGRlc2NyaXB0aW9uCi0gKiBsaXN0cyB0aGUgc3R5bGUgY29uc3RhbnRzIHRoYXQgYXJlIGFwcGxpY2FibGUgdG8gdGhlIGNsYXNzLgotICogU3R5bGUgYml0cyBhcmUgYWxzbyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIGNvbXBvc2l0ZSBjb250cm9sIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqIEBwYXJhbSBzdHlsZSB0aGUgc3R5bGUgb2YgY29udHJvbCB0byBjb25zdHJ1Y3QKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU1dUI0hPUklaT05UQUwKLSAqIEBzZWUgU1dUI1ZFUlRJQ0FMCi0gKiBAc2VlIFdpZGdldCNjaGVja1N1YmNsYXNzCi0gKiBAc2VlIFdpZGdldCNnZXRTdHlsZQotICovCiBwdWJsaWMgU2FzaCAoQ29tcG9zaXRlIHBhcmVudCwgaW50IHN0eWxlKSB7CiAJc3VwZXIgKHBhcmVudCwgY2hlY2tTdHlsZSAoc3R5bGUpKTsKKwlpbnQgY3Vyc29yU3R5bGUgPSAoc3R5bGUgJiBTV1QuVkVSVElDQUwpICE9IDAgPyBTV1QuQ1VSU09SX1NJWkVXRSA6IFNXVC5DVVJTT1JfU0laRU5TOworCXNpemVDdXJzb3IgPSBuZXcgQ3Vyc29yIChnZXREaXNwbGF5ICgpLCBjdXJzb3JTdHlsZSk7CiB9CiAKLS8qKgotICogQWRkcyB0aGUgbGlzdGVuZXIgdG8gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSBjb250cm9sIGlzIHNlbGVjdGVkLCBieSBzZW5kaW5nCi0gKiBpdCBvbmUgb2YgdGhlIG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhlIDxjb2RlPlNlbGVjdGlvbkxpc3RlbmVyPC9jb2RlPgotICogaW50ZXJmYWNlLgotICogPHA+Ci0gKiBXaGVuIDxjb2RlPndpZGdldFNlbGVjdGVkPC9jb2RlPiBpcyBjYWxsZWQsIHRoZSB4LCB5LCB3aWR0aCwgYW5kIGhlaWdodCBmaWVsZHMgb2YgdGhlIGV2ZW50IG9iamVjdCBhcmUgdmFsaWQuCi0gKiBJZiB0aGUgcmVjaWV2ZXIgaXMgYmVpbmcgZHJhZ2dlZCwgdGhlIGV2ZW50IG9iamVjdCBkZXRhaWwgZmllbGQgY29udGFpbnMgdGhlIHZhbHVlIDxjb2RlPlNXVC5EUkFHPC9jb2RlPi4KLSAqIDxjb2RlPndpZGdldERlZmF1bHRTZWxlY3RlZDwvY29kZT4gaXMgbm90IGNhbGxlZC4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNlbGVjdGlvbkxpc3RlbmVyCi0gKiBAc2VlICNyZW1vdmVTZWxlY3Rpb25MaXN0ZW5lcgotICogQHNlZSBTZWxlY3Rpb25FdmVudAotICovCiBwdWJsaWMgdm9pZCBhZGRTZWxlY3Rpb25MaXN0ZW5lcihTZWxlY3Rpb25MaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC0xNDMsMTg1ICszMiwxMjAgQEAKIAlhZGRMaXN0ZW5lcihTV1QuU2VsZWN0aW9uLHR5cGVkTGlzdGVuZXIpOwogCWFkZExpc3RlbmVyKFNXVC5EZWZhdWx0U2VsZWN0aW9uLHR5cGVkTGlzdGVuZXIpOwogfQorCiBzdGF0aWMgaW50IGNoZWNrU3R5bGUgKGludCBzdHlsZSkgewogCXJldHVybiBjaGVja0JpdHMgKHN0eWxlLCBTV1QuSE9SSVpPTlRBTCwgU1dULlZFUlRJQ0FMLCAwLCAwLCAwLCAwKTsKIH0KKwogcHVibGljIFBvaW50IGNvbXB1dGVTaXplIChpbnQgd0hpbnQsIGludCBoSGludCwgYm9vbGVhbiBjaGFuZ2VkKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpbnQgYm9yZGVyID0gZ2V0Qm9yZGVyV2lkdGggKCk7Ci0JaW50IHdpZHRoID0gYm9yZGVyICogMiwgaGVpZ2h0ID0gYm9yZGVyICogMjsKKwlpbnQgd2lkdGggPSAwLCBoZWlnaHQgPSAwOwogCWlmICgoc3R5bGUgJiBTV1QuSE9SSVpPTlRBTCkgIT0gMCkgewotCQl3aWR0aCArPSBERUZBVUxUX1dJRFRIOyAgaGVpZ2h0ICs9IDM7CisJCXdpZHRoICs9IERFRkFVTFRfV0lEVEg7ICBoZWlnaHQgKz0gNTsKIAl9IGVsc2UgewotCQl3aWR0aCArPSAzOyBoZWlnaHQgKz0gREVGQVVMVF9IRUlHSFQ7CisJCXdpZHRoICs9IDU7IGhlaWdodCArPSBERUZBVUxUX0hFSUdIVDsKIAl9Ci0JaWYgKHdIaW50ICE9IFNXVC5ERUZBVUxUKSB3aWR0aCA9IHdIaW50ICsgKGJvcmRlciAqIDIpOwotCWlmIChoSGludCAhPSBTV1QuREVGQVVMVCkgaGVpZ2h0ID0gaEhpbnQgKyAoYm9yZGVyICogMik7CisJaWYgKHdIaW50ICE9IFNXVC5ERUZBVUxUKSB3aWR0aCA9IHdIaW50OworCWlmIChoSGludCAhPSBTV1QuREVGQVVMVCkgaGVpZ2h0ID0gaEhpbnQ7CiAJcmV0dXJuIG5ldyBQb2ludCAod2lkdGgsIGhlaWdodCk7CiB9Ci12b2lkIGNyZWF0ZUhhbmRsZSAoaW50IGluZGV4KSB7Ci0Jc3RhdGUgfD0gSEFORExFOwotCWludCBib3JkZXIgPSAoc3R5bGUgJiBTV1QuQk9SREVSKSAhPSAwID8gMSA6IDA7Ci0gICAgLyogQVcKLQlpbnQgW10gYXJnTGlzdCA9IHsKLQkJT1MuWG1OYm9yZGVyV2lkdGgsIGJvcmRlciwKLQkJT1MuWG1ObWFyZ2luV2lkdGgsIDAsCi0JCU9TLlhtTm1hcmdpbkhlaWdodCwgMCwKLQkJT1MuWG1OcmVzaXplUG9saWN5LCBPUy5YbVJFU0laRV9OT05FLAotCQlPUy5YbU5hbmNlc3RvclNlbnNpdGl2ZSwgMSwKLQl9OwotCSovCi0JaGFuZGxlID0gTWFjVXRpbC5jcmVhdGVEcmF3aW5nQXJlYShwYXJlbnQuaGFuZGxlLCAtMSwgdHJ1ZSwgMCwgMCwgYm9yZGVyKTsKLQlpZiAoaGFuZGxlID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7Ci19Ci1pbnQgZGVmYXVsdEJhY2tncm91bmQgKCkgewotCXJldHVybiBnZXREaXNwbGF5ICgpLmxhYmVsQmFja2dyb3VuZDsKLX0KLXZvaWQgZHJhd0JhbmQgKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CiAKLQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQlPUy5HZXRDb250cm9sQm91bmRzKHBhcmVudC5oYW5kbGUsIGJvdW5kcy5nZXREYXRhKCkpOwotCXgrPSBib3VuZHMuZ2V0WCgpOwotCXkrPSBib3VuZHMuZ2V0WSgpOwotCi0JaW50IHBvcnQ9IE9TLkdldFBvcnQoKTsKLQlPUy5TZXRQb3J0V2luZG93UG9ydChPUy5HZXRDb250cm9sT3duZXIoaGFuZGxlKSk7Ci0JT1MuSW52ZXJ0UmVjdCgoc2hvcnQpeCwgKHNob3J0KXksIChzaG9ydCl3aWR0aCwgKHNob3J0KWhlaWdodCk7Ci0JT1MuU2V0UG9ydChwb3J0KTsKLX0KLXZvaWQgaG9va0V2ZW50cyAoKSB7Ci0Jc3VwZXIuaG9va0V2ZW50cyAoKTsKLQlEaXNwbGF5IGRpc3BsYXk9IGdldERpc3BsYXkoKTsJCQotCU9TLlNldENvbnRyb2xEYXRhKGhhbmRsZSwgT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbFVzZXJQYW5lRHJhd1Byb2NUYWcsIGRpc3BsYXkuZlVzZXJQYW5lRHJhd1Byb2MpOwotCU9TLlNldENvbnRyb2xEYXRhKGhhbmRsZSwgT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbFVzZXJQYW5lSGl0VGVzdFByb2NUYWcsIGRpc3BsYXkuZlVzZXJQYW5lSGl0VGVzdFByb2MpOwordm9pZCBjcmVhdGVIYW5kbGUgKCkgeworCWludCBmZWF0dXJlcyA9IE9TLmtDb250cm9sU3VwcG9ydHNFbWJlZGRpbmcgfCBPUy5rQ29udHJvbFN1cHBvcnRzRm9jdXMgfCBPUy5rQ29udHJvbEdldHNGb2N1c09uQ2xpY2s7CisJaW50IFtdIG91dENvbnRyb2wgPSBuZXcgaW50IFsxXTsKKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChwYXJlbnQuaGFuZGxlKTsKKwlPUy5DcmVhdGVVc2VyUGFuZUNvbnRyb2wgKHdpbmRvdywgbnVsbCwgZmVhdHVyZXMsIG91dENvbnRyb2wpOworCWlmIChvdXRDb250cm9sIFswXSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCWhhbmRsZSA9IG91dENvbnRyb2wgWzBdOwogfQogCi1pbnQgcHJvY2Vzc01vdXNlRG93biAoTWFjTW91c2VFdmVudCBtbUV2ZW50KSB7Ci0Jc3VwZXIucHJvY2Vzc01vdXNlRG93biAobW1FdmVudCk7Cit2b2lkIGRyYXdXaWRnZXQgKGludCBjb250cm9sKSB7CisJZHJhd0JhY2tncm91bmQgKGhhbmRsZSwgYmFja2dyb3VuZCk7Cit9CiAKLQlQb2ludCBtcD0gTWFjVXRpbC50b0NvbnRyb2wocGFyZW50LmhhbmRsZSwgbW1FdmVudC5nZXRXaGVyZSgpKTsKLQlzdGFydFggPSBtcC54OyAgc3RhcnRZID0gbXAueTsKK2ludCBrRXZlbnRDb250cm9sU2V0Q3Vyc29yIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IHJlc3VsdCA9IHN1cGVyLmtFdmVudENvbnRyb2xTZXRDdXJzb3IgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCWlmIChyZXN1bHQgPT0gT1Mubm9FcnIpIHJldHVybiByZXN1bHQ7CisJc2V0Q3Vyc29yIChzaXplQ3Vyc29yLmhhbmRsZSk7CisJcmV0dXJuIE9TLm5vRXJyOworfQogCi0JTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JT1MuR2V0Q29udHJvbEJvdW5kcyhoYW5kbGUsIGJvdW5kcy5nZXREYXRhKCkpOwotCWludCB3aWR0aCA9IGJvdW5kcy5nZXRXaWR0aCgpLCBoZWlnaHQgPSBib3VuZHMuZ2V0SGVpZ2h0KCk7CitpbnQga0V2ZW50TW91c2VEb3duIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IHJlc3VsdCA9IHN1cGVyLmtFdmVudE1vdXNlRG93biAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKHJlc3VsdCA9PSBPUy5ub0VycikgcmV0dXJuIHJlc3VsdDsKIAkKLQlNYWNSZWN0IHBhcmVudEJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQlPUy5HZXRDb250cm9sQm91bmRzKHBhcmVudC5oYW5kbGUsIHBhcmVudEJvdW5kcy5nZXREYXRhKCkpOwotCQotCWxhc3RYID0gYm91bmRzLmdldFgoKS1wYXJlbnRCb3VuZHMuZ2V0WCgpOwotCWxhc3RZID0gYm91bmRzLmdldFkoKS1wYXJlbnRCb3VuZHMuZ2V0WSgpOwotCQorCVJlY3QgcmVjdCA9IG5ldyBSZWN0ICgpOworCU9TLkdldENvbnRyb2xCb3VuZHMgKGhhbmRsZSwgcmVjdCk7CisJaW50IHN0YXJ0WCA9IHJlY3QubGVmdDsKKwlpbnQgc3RhcnRZID0gcmVjdC50b3A7CQkJCisJaW50IHdpZHRoID0gcmVjdC5yaWdodCAtIHJlY3QubGVmdDsKKwlpbnQgaGVpZ2h0ID0gcmVjdC5ib3R0b20gLSByZWN0LnRvcDsKKwlPUy5HZXRDb250cm9sQm91bmRzIChwYXJlbnQuaGFuZGxlLCByZWN0KTsKIAlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKLQlldmVudC5kZXRhaWwgPSBTV1QuRFJBRzsKLQkvL2V2ZW50LnRpbWUgPSB4RXZlbnQudGltZTsKLQlldmVudC54ID0gbGFzdFg7ICBldmVudC55ID0gbGFzdFk7Ci0JZXZlbnQud2lkdGggPSB3aWR0aDsgIGV2ZW50LmhlaWdodCA9IGhlaWdodDsKKwlldmVudC54ID0gc3RhcnRYIC09IHJlY3QubGVmdDsKKwlldmVudC55ID0gc3RhcnRZIC09IHJlY3QudG9wOworCWV2ZW50LndpZHRoID0gd2lkdGg7CisJZXZlbnQuaGVpZ2h0ID0gaGVpZ2h0OwogCXNlbmRFdmVudCAoU1dULlNlbGVjdGlvbiwgZXZlbnQpOwotCWlmIChldmVudC5kb2l0KSB7Ci0JCWRyYWdnaW5nID0gdHJ1ZTsKLQkJZHJhd0JhbmQgKGxhc3RYID0gZXZlbnQueCwgbGFzdFkgPSBldmVudC55LCB3aWR0aCwgaGVpZ2h0KTsKLQl9Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc01vdXNlTW92ZSAoTWFjTW91c2VFdmVudCBtbUV2ZW50KSB7Ci0Jc3VwZXIucHJvY2Vzc01vdXNlTW92ZSAobW1FdmVudCk7CisJdXBkYXRlICgpOworCWlmICghZXZlbnQuZG9pdCkgcmV0dXJuIHJlc3VsdDsKIAkKLQlnZXREaXNwbGF5KCkuc2V0Q3Vyc29yKChzdHlsZSAmIFNXVC5WRVJUSUNBTCkgIT0gMCA/IEhfQVJST1cgOiBWX0FSUk9XKTsKLQotCWlmICghZHJhZ2dpbmcgfHwgKG1tRXZlbnQuZ2V0QnV0dG9uKCkgIT0gMSkpIHJldHVybiAwOwotCVBvaW50IG1wPSBNYWNVdGlsLnRvQ29udHJvbChwYXJlbnQuaGFuZGxlLCBtbUV2ZW50LmdldFdoZXJlKCkpOwotCi0JTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JT1MuR2V0Q29udHJvbEJvdW5kcyhoYW5kbGUsIGJvdW5kcy5nZXREYXRhKCkpOwotCWludCB3aWR0aCA9IGJvdW5kcy5nZXRXaWR0aCgpLCBoZWlnaHQgPSBib3VuZHMuZ2V0SGVpZ2h0KCk7CisJb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCBwdCA9IG5ldyBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBvaW50ICgpOworCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1Nb3VzZUxvY2F0aW9uLCBPUy50eXBlUURQb2ludCwgbnVsbCwgcHQuc2l6ZW9mLCBudWxsLCBwdCk7CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAoaGFuZGxlKTsKKwlPUy5HZXRXaW5kb3dCb3VuZHMgKHdpbmRvdywgKHNob3J0KSBPUy5rV2luZG93Q29udGVudFJnbiwgcmVjdCk7CisJaW50IG9mZnNldFggPSBwdC5oIC0gcmVjdC5sZWZ0OworCWludCBvZmZzZXRZID0gcHQudiAtIHJlY3QudG9wOworCU9TLkdldENvbnRyb2xCb3VuZHMgKGhhbmRsZSwgcmVjdCk7CisJb2Zmc2V0WCAtPSByZWN0LmxlZnQ7CisJb2Zmc2V0WSAtPSByZWN0LnRvcDsKIAkKLQlNYWNSZWN0IHBhcmVudEJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQlPUy5HZXRDb250cm9sQm91bmRzKHBhcmVudC5oYW5kbGUsIHBhcmVudEJvdW5kcy5nZXREYXRhKCkpOwotCi0JaW50IHggPSBib3VuZHMuZ2V0WCgpLXBhcmVudEJvdW5kcy5nZXRYKCksIHkgPSBib3VuZHMuZ2V0WSgpLXBhcmVudEJvdW5kcy5nZXRZKCk7Ci0KLQlpbnQgbmV3WCA9IGxhc3RYLCBuZXdZID0gbGFzdFk7Ci0JaWYgKChzdHlsZSAmIFNXVC5WRVJUSUNBTCkgIT0gMCkgewotCQluZXdYID0gTWF0aC5taW4gKE1hdGgubWF4ICgwLCB4ICsgKG1wLnggLSBzdGFydFgpKSwgcGFyZW50Qm91bmRzLmdldFdpZHRoKCkgLSB3aWR0aCk7Ci0JfSBlbHNlIHsKLQkJbmV3WSA9IE1hdGgubWluIChNYXRoLm1heCAoMCwgeSArIChtcC55IC0gc3RhcnRZKSksIHBhcmVudEJvdW5kcy5nZXRIZWlnaHQoKSAtIGhlaWdodCk7Ci0JfQotCWlmIChuZXdYID09IGxhc3RYICYmIG5ld1kgPT0gbGFzdFkpIHJldHVybiAwOwotCWRyYXdCYW5kIChsYXN0WCwgbGFzdFksIHdpZHRoLCBoZWlnaHQpOwotCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOwotCWV2ZW50LmRldGFpbCA9IFNXVC5EUkFHOwotCS8vZXZlbnQudGltZSA9IHhFdmVudC50aW1lOwotCWV2ZW50LnggPSBuZXdYOyAgZXZlbnQueSA9IG5ld1k7Ci0JZXZlbnQud2lkdGggPSB3aWR0aDsgIGV2ZW50LmhlaWdodCA9IGhlaWdodDsKLQlzZW5kRXZlbnQgKFNXVC5TZWxlY3Rpb24sIGV2ZW50KTsKLQlpZiAoZXZlbnQuZG9pdCkgewotCQlsYXN0WCA9IGV2ZW50Lng7ICBsYXN0WSA9IGV2ZW50Lnk7Ci0JCWRyYXdCYW5kIChsYXN0WCwgbGFzdFksIHdpZHRoLCBoZWlnaHQpOwotCX0KLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzTW91c2VVcCAoTWFjTW91c2VFdmVudCBtbUV2ZW50KSB7Ci0Jc3VwZXIucHJvY2Vzc01vdXNlVXAgKG1tRXZlbnQpOwotCi0JaWYgKG1tRXZlbnQuZ2V0QnV0dG9uKCkgIT0gMSkgcmV0dXJuIDA7Ci0JaWYgKCFkcmFnZ2luZykgcmV0dXJuIDA7Ci0JZHJhZ2dpbmcgPSBmYWxzZTsKLQotCU1hY1JlY3QgYm91bmRzPSBuZXcgTWFjUmVjdCgpOwotCU9TLkdldENvbnRyb2xCb3VuZHMoaGFuZGxlLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQlpbnQgd2lkdGggPSBib3VuZHMuZ2V0V2lkdGgoKSwgaGVpZ2h0ID0gYm91bmRzLmdldEhlaWdodCgpOwotCi0JRXZlbnQgZXZlbnQgPSBuZXcgRXZlbnQgKCk7Ci0JLy9ldmVudC50aW1lID0geEV2ZW50LnRpbWU7Ci0JZXZlbnQueCA9IGxhc3RYOyAgZXZlbnQueSA9IGxhc3RZOwotCWV2ZW50LndpZHRoID0gd2lkdGg7ICBldmVudC5oZWlnaHQgPSBoZWlnaHQ7Ci0JZHJhd0JhbmQgKGxhc3RYLCBsYXN0WSwgd2lkdGgsIGhlaWdodCk7Ci0Jc2VuZEV2ZW50IChTV1QuU2VsZWN0aW9uLCBldmVudCk7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc1BhaW50IChPYmplY3QgY2FsbERhdGEpIHsKLQkKLQlHQyBnYz0gbmV3IEdDKHRoaXMpOwotCU1hY0NvbnRyb2xFdmVudCBtZT0gKE1hY0NvbnRyb2xFdmVudCkgY2FsbERhdGE7Ci0JUmVjdGFuZ2xlIHI9IGdjLmNhcmJvbl9mb2N1cyhtZS5nZXREYW1hZ2VSZWdpb25IYW5kbGUoKSk7Ci0JCi0JaWYgKCEgci5pc0VtcHR5KCkpIHsKLQkJUG9pbnQgZT0gZ2V0U2l6ZSgpOwotCQkKLQkJLy8gZXJhc2UgYmFja2dyb3VuZAotCQlnYy5maWxsUmVjdGFuZ2xlKDAsIDAsIGUueCwgZS55KTsKLQkJCi0JCWdjLnNldEJhY2tncm91bmQoZ2V0RGlzcGxheSgpLmdldFN5c3RlbUNvbG9yKFNXVC5DT0xPUl9HUkFZKSk7Ci0JCWlmIChlLnggPCBlLnkpIHsJLy8gdmVydGljYWwKLQkJCWdjLmZpbGxSZWN0YW5nbGUgKChlLngtMSkvMiwgKGUueS0yMCkvMiwgMSwgMjApOwotCQl9IGVsc2UgewkJCS8vIGhvcml6b250YWwKLQkJCWdjLmZpbGxSZWN0YW5nbGUgKChlLngtMjApLzIsIChlLnktMSkvMiwgMjAsIDEpOworCWludCBwb3J0ID0gT1MuR2V0V2luZG93UG9ydCAod2luZG93KTsKKwlpbnQgW10gb3V0TW9kaWZpZXJzID0gbmV3IGludCBbMV07CisJc2hvcnQgW10gb3V0UmVzdWx0ID0gbmV3IHNob3J0IFsxXTsKKwlvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBvaW50IG91dFB0ID0gbmV3IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgKCk7CisJd2hpbGUgKG91dFJlc3VsdCBbMF0gIT0gT1Mua01vdXNlVHJhY2tpbmdNb3VzZVVwKSB7CisJCU9TLlRyYWNrTW91c2VMb2NhdGlvbldpdGhPcHRpb25zIChwb3J0LCAwLCBPUy5rRXZlbnREdXJhdGlvbkZvcmV2ZXIsIG91dFB0LCBvdXRNb2RpZmllcnMsIG91dFJlc3VsdCk7CisJCXN3aXRjaCAob3V0UmVzdWx0IFswXSkgeworCQkJY2FzZSBPUy5rTW91c2VUcmFja2luZ01vdXNlRG93bjoKKwkJCWNhc2UgT1Mua01vdXNlVHJhY2tpbmdNb3VzZVVwOgorCQkJY2FzZSBPUy5rTW91c2VUcmFja2luZ01vdXNlRHJhZ2dlZDogeworCQkJCU9TLkdldENvbnRyb2xCb3VuZHMgKHBhcmVudC5oYW5kbGUsIHJlY3QpOworCQkJCWludCB4ID0gb3V0UHQuaCAtIHJlY3QubGVmdDsKKwkJCQlpbnQgeSA9IG91dFB0LnYgLSByZWN0LnRvcDsJCQkJCisJCQkJaW50IG5ld1ggPSBzdGFydFgsIG5ld1kgPSBzdGFydFk7CisJCQkJaWYgKChzdHlsZSAmIFNXVC5WRVJUSUNBTCkgIT0gMCkgeworCQkJCQlpbnQgY2xpZW50V2lkdGggPSByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0OworCQkJCQluZXdYID0gTWF0aC5taW4gKE1hdGgubWF4ICgwLCB4IC0gb2Zmc2V0WCksIGNsaWVudFdpZHRoIC0gd2lkdGgpOworCQkJCX0gZWxzZSB7CisJCQkJCWludCBjbGllbnRIZWlnaHQgPSByZWN0LmJvdHRvbSAtIHJlY3QudG9wOworCQkJCQluZXdZID0gTWF0aC5taW4gKE1hdGgubWF4ICgwLCB5IC0gb2Zmc2V0WSksIGNsaWVudEhlaWdodCAtIGhlaWdodCk7CisJCQkJfQorCQkJCWV2ZW50ID0gbmV3IEV2ZW50ICgpOworCQkJCWV2ZW50LnggPSBuZXdYOworCQkJCWV2ZW50LnkgPSBuZXdZOworCQkJCWV2ZW50LndpZHRoID0gd2lkdGg7CisJCQkJZXZlbnQuaGVpZ2h0ID0gaGVpZ2h0OworCQkJCWV2ZW50LmRldGFpbCA9IDA7IC8vb3V0UmVzdWx0IFswXSA9PSBPUy5rTW91c2VUcmFja2luZ01vdXNlRHJhZ2dlZCA/IFNXVC5EUkFHIDogMDsKKwkJCQlzZW5kRXZlbnQgKFNXVC5TZWxlY3Rpb24sIGV2ZW50KTsKKwkJCQlpZiAoZXZlbnQuZG9pdCkgc2V0Qm91bmRzIChuZXdYLCBuZXdZLCB3aWR0aCwgaGVpZ2h0KTsKKwkJCQl1cGRhdGUgKCk7CisJCQkJYnJlYWs7CisJCQl9CisJCQlkZWZhdWx0OgorCQkJCW91dFJlc3VsdCBbMF0gPSBPUy5rTW91c2VUcmFja2luZ01vdXNlVXA7CisJCQkJYnJlYWs7CiAJCX0KIAl9Ci0JCi0JZ2MuY2FyYm9uX3VuZm9jdXMoKTsKLQlnYy5kaXNwb3NlKCk7Ci0JCi0JcmV0dXJuIDA7CisJcmV0dXJuIHJlc3VsdDsKIH0KLS8qKgotICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGNvbnRyb2wgaXMgc2VsZWN0ZWQuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTZWxlY3Rpb25MaXN0ZW5lcgotICogQHNlZSAjYWRkU2VsZWN0aW9uTGlzdGVuZXIKLSAqLworCit2b2lkIHJlbGVhc2VXaWRnZXQgKCkgeworCXN1cGVyLnJlbGVhc2VXaWRnZXQgKCk7CisJaWYgKHNpemVDdXJzb3IgIT0gbnVsbCkgc2l6ZUN1cnNvci5kaXNwb3NlICgpOworCXNpemVDdXJzb3IgPSBudWxsOworfQorCiBwdWJsaWMgdm9pZCByZW1vdmVTZWxlY3Rpb25MaXN0ZW5lcihTZWxlY3Rpb25MaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvU2NhbGUuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9TY2FsZS5qYXZhCmluZGV4IDQ2NmU2NzkuLjI2YTViOTIgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9TY2FsZS5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9TY2FsZS5qYXZhCkBAIC03LDg2ICs3LDI5IEBACiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCiAKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlJlY3Q7CisKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7CiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7CiAKLS8qKgotICogSW5zdGFuY2VzIG9mIHRoZSByZWNlaXZlciByZXByZXNlbnQgYSBzZWxlY3RhYmxlIHVzZXIKLSAqIGludGVyZmFjZSBvYmplY3QgdGhhdCBwcmVzZW50IGEgcmFuZ2Ugb2YgY29udGludW91cwotICogbnVtZXJpYyB2YWx1ZXMuCi0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPkhPUklaT05UQUwsIFZFUlRJQ0FMPC9kZD4KLSAqIDxkdD48Yj5FdmVudHM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+U2VsZWN0aW9uPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cD4KLSAqIE5vdGU6IE9ubHkgb25lIG9mIHRoZSBzdHlsZXMgSE9SSVpPTlRBTCBhbmQgVkVSVElDQUwgbWF5IGJlIHNwZWNpZmllZC4KLSAqIDwvcD48cD4KLSAqIDxwPgotICogSU1QT1JUQU5UOiBUaGlzIGNsYXNzIGlzIGludGVuZGVkIHRvIGJlIHN1YmNsYXNzZWQgPGVtPm9ubHk8L2VtPgotICogd2l0aGluIHRoZSBTV1QgaW1wbGVtZW50YXRpb24uCi0gKiA8L3A+Ci0gKi8KLXB1YmxpYyAvKmZpbmFsKi8gY2xhc3MgU2NhbGUgZXh0ZW5kcyBDb250cm9sIHsKLQkKLQlwcml2YXRlIGludCBpbmNyZW1lbnQ9IDE7Ci0JcHJpdmF0ZSBpbnQgcGFnZUluY3JlbWVudD0gMTA7Ci0JCi0vKioKLSAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50Ci0gKiBhbmQgYSBzdHlsZSB2YWx1ZSBkZXNjcmliaW5nIGl0cyBiZWhhdmlvciBhbmQgYXBwZWFyYW5jZS4KLSAqIDxwPgotICogVGhlIHN0eWxlIHZhbHVlIGlzIGVpdGhlciBvbmUgb2YgdGhlIHN0eWxlIGNvbnN0YW50cyBkZWZpbmVkIGluCi0gKiBjbGFzcyA8Y29kZT5TV1Q8L2NvZGU+IHdoaWNoIGlzIGFwcGxpY2FibGUgdG8gaW5zdGFuY2VzIG9mIHRoaXMKLSAqIGNsYXNzLCBvciBtdXN0IGJlIGJ1aWx0IGJ5IDxlbT5iaXR3aXNlIE9SPC9lbT4naW5nIHRvZ2V0aGVyIAotICogKHRoYXQgaXMsIHVzaW5nIHRoZSA8Y29kZT5pbnQ8L2NvZGU+ICJ8IiBvcGVyYXRvcikgdHdvIG9yIG1vcmUKLSAqIG9mIHRob3NlIDxjb2RlPlNXVDwvY29kZT4gc3R5bGUgY29uc3RhbnRzLiBUaGUgY2xhc3MgZGVzY3JpcHRpb24KLSAqIGxpc3RzIHRoZSBzdHlsZSBjb25zdGFudHMgdGhhdCBhcmUgYXBwbGljYWJsZSB0byB0aGUgY2xhc3MuCi0gKiBTdHlsZSBiaXRzIGFyZSBhbHNvIGluaGVyaXRlZCBmcm9tIHN1cGVyY2xhc3Nlcy4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gcGFyZW50IGEgY29tcG9zaXRlIGNvbnRyb2wgd2hpY2ggd2lsbCBiZSB0aGUgcGFyZW50IG9mIHRoZSBuZXcgaW5zdGFuY2UgKGNhbm5vdCBiZSBudWxsKQotICogQHBhcmFtIHN0eWxlIHRoZSBzdHlsZSBvZiBjb250cm9sIHRvIGNvbnN0cnVjdAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTV1QjSE9SSVpPTlRBTAotICogQHNlZSBTV1QjVkVSVElDQUwKLSAqIEBzZWUgV2lkZ2V0I2NoZWNrU3ViY2xhc3MKLSAqIEBzZWUgV2lkZ2V0I2dldFN0eWxlCi0gKi8KK3B1YmxpYyBjbGFzcyBTY2FsZSBleHRlbmRzIENvbnRyb2wgeworCWludCBpbmNyZW1lbnQgPSAxOworCWludCBwYWdlSW5jcmVtZW50ID0gMTA7CisKIHB1YmxpYyBTY2FsZSAoQ29tcG9zaXRlIHBhcmVudCwgaW50IHN0eWxlKSB7CiAJc3VwZXIgKHBhcmVudCwgY2hlY2tTdHlsZSAoc3R5bGUpKTsKIH0KIAotLyoqCi0gKiBBZGRzIHRoZSBsaXN0ZW5lciB0byB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIHJlY2VpdmVyJ3MgdmFsdWUgY2hhbmdlcywgYnkgc2VuZGluZwotICogaXQgb25lIG9mIHRoZSBtZXNzYWdlcyBkZWZpbmVkIGluIHRoZSA8Y29kZT5TZWxlY3Rpb25MaXN0ZW5lcjwvY29kZT4KLSAqIGludGVyZmFjZS4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNlbGVjdGlvbkxpc3RlbmVyCi0gKiBAc2VlICNyZW1vdmVTZWxlY3Rpb25MaXN0ZW5lcgotICovCitpbnQgYWN0aW9uUHJvYyAoaW50IHRoZUNvbnRyb2wsIGludCBwYXJ0Q29kZSkgeworCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOworCXNlbmRFdmVudCAoU1dULlNlbGVjdGlvbik7CisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlkaXNwbGF5LnVwZGF0ZSAoKTsKKwlyZXR1cm4gMDsKK30KKwogcHVibGljIHZvaWQgYWRkU2VsZWN0aW9uTGlzdGVuZXIoU2VsZWN0aW9uTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwpAQCAtOTQsMTcyICszNyw2NSBAQAogCWFkZExpc3RlbmVyKFNXVC5TZWxlY3Rpb24sdHlwZWRMaXN0ZW5lcik7CiAJYWRkTGlzdGVuZXIoU1dULkRlZmF1bHRTZWxlY3Rpb24sdHlwZWRMaXN0ZW5lcik7CiB9CisKIHN0YXRpYyBpbnQgY2hlY2tTdHlsZSAoaW50IHN0eWxlKSB7CiAJcmV0dXJuIGNoZWNrQml0cyAoc3R5bGUsIFNXVC5IT1JJWk9OVEFMLCBTV1QuVkVSVElDQUwsIDAsIDAsIDAsIDApOwogfQorCiBwdWJsaWMgUG9pbnQgY29tcHV0ZVNpemUgKGludCB3SGludCwgaW50IGhIaW50LCBib29sZWFuIGNoYW5nZWQpIHsKIAljaGVja1dpZGdldCgpOwotCWludCBib3JkZXIgPSBnZXRCb3JkZXJXaWR0aCAoKTsKLQlpbnQgd2lkdGggPSBib3JkZXIgKiAyLCBoZWlnaHQgPSBib3JkZXIgKiAyOwotCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7Ci0JaW50IGhTY3JvbGwgPSBkaXNwbGF5LnNjcm9sbGVkTWFyZ2luWDsKLQlpbnQgdlNjcm9sbCA9IGRpc3BsYXkuc2Nyb2xsZWRNYXJnaW5ZOworCWludCB3aWR0aCA9IDAsIGhlaWdodCA9IDA7CiAJaWYgKChzdHlsZSAmIFNXVC5IT1JJWk9OVEFMKSAhPSAwKSB7Ci0JCXdpZHRoICs9IGhTY3JvbGwgKiAxMDsKLQkJaGVpZ2h0ICs9IHZTY3JvbGw7CisJCWludCBbXSBvdXRNZXRyaWMgPSBuZXcgaW50IFsxXTsKKwkJT1MuR2V0VGhlbWVNZXRyaWMgKE9TLmtUaGVtZU1ldHJpY0hTbGlkZXJIZWlnaHQsIG91dE1ldHJpYyk7CisJCWhlaWdodCA9IG91dE1ldHJpYyBbMF07CisJCXdpZHRoID0gaGVpZ2h0ICogMTA7CiAJfSBlbHNlIHsKLQkJd2lkdGggKz0gaFNjcm9sbDsKLQkJaGVpZ2h0ICs9IHZTY3JvbGwgKiAxMDsKKwkJaW50IFtdIG91dE1ldHJpYyA9IG5ldyBpbnQgWzFdOworCQlPUy5HZXRUaGVtZU1ldHJpYyAoT1Mua1RoZW1lTWV0cmljVlNsaWRlcldpZHRoLCBvdXRNZXRyaWMpOworCQl3aWR0aCA9IG91dE1ldHJpYyBbMF07CisJCWhlaWdodCA9IHdpZHRoICogMTA7CiAJfQotCWlmICh3SGludCAhPSBTV1QuREVGQVVMVCkgd2lkdGggPSB3SGludCArIChib3JkZXIgKiAyKTsKLQlpZiAoaEhpbnQgIT0gU1dULkRFRkFVTFQpIGhlaWdodCA9IGhIaW50ICsgKGJvcmRlciAqIDIpOworCWlmICh3SGludCAhPSBTV1QuREVGQVVMVCkgd2lkdGggPSB3SGludDsKKwlpZiAoaEhpbnQgIT0gU1dULkRFRkFVTFQpIGhlaWdodCA9IGhIaW50OwogCXJldHVybiBuZXcgUG9pbnQgKHdpZHRoLCBoZWlnaHQpOwogfQotdm9pZCBjcmVhdGVIYW5kbGUgKGludCBpbmRleCkgewotCXN0YXRlIHw9IEhBTkRMRTsKLSAgICAvKiBBVwotCWludCBbXSBhcmdMaXN0ID0gewotCQlPUy5YbU50aXRsZVN0cmluZywgMCwKLQkJT1MuWG1OYm9yZGVyV2lkdGgsIChzdHlsZSAmIFNXVC5CT1JERVIpICE9IDAgPyAxIDogMCwKLQkJT1MuWG1Ob3JpZW50YXRpb24sICgoc3R5bGUgJiBTV1QuSF9TQ1JPTEwpICE9IDApID8gT1MuWG1IT1JJWk9OVEFMIDogT1MuWG1WRVJUSUNBTCwKLQkJT1MuWG1OcHJvY2Vzc2luZ0RpcmVjdGlvbiwgKChzdHlsZSAmIFNXVC5IX1NDUk9MTCkgIT0gMCkgPyBPUy5YbU1BWF9PTl9SSUdIVCA6IE9TLlhtTUFYX09OX0JPVFRPTSwKLQkJT1MuWG1OYW5jZXN0b3JTZW5zaXRpdmUsIDEsCi0JfTsKLSAgICAqLwotCWludCBwYXJlbnRIYW5kbGUgPSBwYXJlbnQuaGFuZGxlOwotIAlzaG9ydCBwcm9jSUQ9IChzaG9ydCkoT1Mua0NvbnRyb2xTbGlkZXJQcm9jICsgT1Mua0NvbnRyb2xTbGlkZXJMaXZlRmVlZGJhY2sgKyBPUy5rQ29udHJvbFNsaWRlck5vbkRpcmVjdGlvbmFsKTsKLSAgICBoYW5kbGU9IE1hY1V0aWwubmV3Q29udHJvbChwYXJlbnRIYW5kbGUsIChzaG9ydCkwLCAoc2hvcnQpMCwgKHNob3J0KTEwMCwgcHJvY0lEKTsKLQlpZiAoaGFuZGxlID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7CisKK3ZvaWQgY3JlYXRlSGFuZGxlICgpIHsKKwlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCWludCBhY3Rpb25Qcm9jID0gZGlzcGxheS5hY3Rpb25Qcm9jOworCWludCBbXSBvdXRDb250cm9sID0gbmV3IGludCBbMV07CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAocGFyZW50LmhhbmRsZSk7CisJT1MuQ3JlYXRlU2xpZGVyQ29udHJvbCAod2luZG93LCBudWxsLCAwLCAwLCAxMDAsIE9TLmtDb250cm9sU2xpZGVyRG9lc05vdFBvaW50LCAoc2hvcnQpMCwgdHJ1ZSwgYWN0aW9uUHJvYywgb3V0Q29udHJvbCk7CisJaWYgKG91dENvbnRyb2wgWzBdID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7CisJaGFuZGxlID0gb3V0Q29udHJvbCBbMF07CiB9CiAKLS8qKgotICogUmV0dXJucyB0aGUgYW1vdW50IHRoYXQgdGhlIHJlY2VpdmVyJ3MgdmFsdWUgd2lsbCBiZQotICogbW9kaWZpZWQgYnkgd2hlbiB0aGUgdXAvZG93biAob3IgcmlnaHQvbGVmdCkgYXJyb3dzCi0gKiBhcmUgcHJlc3NlZC4KLSAqCi0gKiBAcmV0dXJuIHRoZSBpbmNyZW1lbnQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyBpbnQgZ2V0SW5jcmVtZW50ICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBpbmNyZW1lbnQ7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIG1heGltdW0gdmFsdWUgd2hpY2ggdGhlIHJlY2VpdmVyIHdpbGwgYWxsb3cuCi0gKgotICogQHJldHVybiB0aGUgbWF4aW11bQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldE1heGltdW0gKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0gICAgcmV0dXJuICBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSk7CisgICAgcmV0dXJuICBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtIChoYW5kbGUpOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBtaW5pbXVtIHZhbHVlIHdoaWNoIHRoZSByZWNlaXZlciB3aWxsIGFsbG93LgotICoKLSAqIEByZXR1cm4gdGhlIG1pbmltdW0KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGludCBnZXRNaW5pbXVtICgpIHsKIAljaGVja1dpZGdldCgpOwotICAgIHJldHVybiBPUy5HZXRDb250cm9sMzJCaXRNaW5pbXVtKGhhbmRsZSk7CisgICAgcmV0dXJuIE9TLkdldENvbnRyb2wzMkJpdE1pbmltdW0gKGhhbmRsZSk7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIGFtb3VudCB0aGF0IHRoZSByZWNlaXZlcidzIHZhbHVlIHdpbGwgYmUKLSAqIG1vZGlmaWVkIGJ5IHdoZW4gdGhlIHBhZ2UgaW5jcmVtZW50L2RlY3JlbWVudCBhcmVhcwotICogYXJlIHNlbGVjdGVkLgotICoKLSAqIEByZXR1cm4gdGhlIHBhZ2UgaW5jcmVtZW50Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBpbnQgZ2V0UGFnZUluY3JlbWVudCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKICAgICByZXR1cm4gcGFnZUluY3JlbWVudDsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgc2luZ2xlIDxlbT5zZWxlY3Rpb248L2VtPiB0aGF0IGlzIHRoZSByZWNlaXZlcidzIHBvc2l0aW9uLgotICoKLSAqIEByZXR1cm4gdGhlIHNlbGVjdGlvbgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldFNlbGVjdGlvbiAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKLSAgICByZXR1cm4gT1MuR2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlKTsKKyAgICByZXR1cm4gT1MuR2V0Q29udHJvbDMyQml0VmFsdWUgKGhhbmRsZSk7CiB9Ci12b2lkIGhvb2tFdmVudHMgKCkgewotCXN1cGVyLmhvb2tFdmVudHMgKCk7Ci0gICAgLyogQVcKLQlpbnQgd2luZG93UHJvYyA9IGdldERpc3BsYXkgKCkud2luZG93UHJvYzsKLQlPUy5YdEFkZENhbGxiYWNrIChoYW5kbGUsIE9TLlhtTnZhbHVlQ2hhbmdlZENhbGxiYWNrLCB3aW5kb3dQcm9jLCBTV1QuU2VsZWN0aW9uKTsKLQlPUy5YdEFkZENhbGxiYWNrIChoYW5kbGUsIE9TLlhtTmRyYWdDYWxsYmFjaywgd2luZG93UHJvYywgU1dULlNlbGVjdGlvbik7Ci0gICAgKi8KLQlPUy5TZXRDb250cm9sQWN0aW9uKGhhbmRsZSwgZ2V0RGlzcGxheSgpLmZDb250cm9sQWN0aW9uUHJvYyk7Ci19Ci1pbnQgcHJvY2Vzc1NlbGVjdGlvbiAoT2JqZWN0IGNhbGxEYXRhKSB7CiAKLQlNYWNDb250cm9sRXZlbnQgbWFjRXZlbnQ9IChNYWNDb250cm9sRXZlbnQpIGNhbGxEYXRhOwotCi0JRXZlbnQgZXZlbnQgPSBuZXcgRXZlbnQgKCk7Ci0gICAgaWYgKG1hY0V2ZW50LmdldFBhcnRDb2RlKCkgPT0gT1Mua0NvbnRyb2xJbmRpY2F0b3JQYXJ0KSB7CS8vIGVuZCBvZiBkcmFnIG9yIGNvbnRpbnVvcyBkcmFnCi0JCWlmIChtYWNFdmVudC5pc01vdXNlRG93bigpKSB7Ci0JCQlldmVudC5kZXRhaWwgPSBTV1QuRFJBRzsJLy8gY29udGludW9zIGRyYWcKLQkJfSBlbHNlIHsKLQkJCS8qCi0JCQkgKiBEbyBub3Qgc2V0IHRoZSBkZXRhaWwgZmllbGQgdG8gU1dULkRSQUcKLQkJCSAqIHRvIGluZGljYXRlIHRoYXQgdGhlIGRyYWdnaW5nIGhhcyBlbmRlZC4KLQkJCSAqLwotCQl9Ci0gICAgfQotCQotCXNlbmRFdmVudCAoU1dULlNlbGVjdGlvbiwgZXZlbnQpOwotCQotCS8qIEFXIEZJWE1FOiBtYXkgYmUgd2UgbmVlZCB0aGUgZm9sbG93aW5nIGhlcmUgdG9vLi4uCi0JaWYgKG1hY0V2ZW50LmlzTW91c2VEb3duKCkpIHsKLQkJaW50IHdIYW5kbGU9IE9TLkdldENvbnRyb2xPd25lcihoYW5kbGUpOwotCQlpZiAod0hhbmRsZSAhPSAwKSB7Ci0JCQlnZXREaXNwbGF5KCkudXBkYXRlV2luZG93KHdIYW5kbGUpOwotCQl9Ci0JfQotCSovCi0JcmV0dXJuIDA7Ci19Ci0vKioKLSAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSByZWNlaXZlcidzIHZhbHVlIGNoYW5nZXMuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgbm8gbG9uZ2VyIGJlIG5vdGlmaWVkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU2VsZWN0aW9uTGlzdGVuZXIKLSAqIEBzZWUgI2FkZFNlbGVjdGlvbkxpc3RlbmVyCi0gKi8KIHB1YmxpYyB2b2lkIHJlbW92ZVNlbGVjdGlvbkxpc3RlbmVyKFNlbGVjdGlvbkxpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTI2Nyw5NSArMTAzLDM5IEBACiAJZXZlbnRUYWJsZS51bmhvb2soU1dULlNlbGVjdGlvbiwgbGlzdGVuZXIpOwogCWV2ZW50VGFibGUudW5ob29rKFNXVC5EZWZhdWx0U2VsZWN0aW9uLGxpc3RlbmVyKTsKIH0KLS8qKgotICogU2V0cyB0aGUgYW1vdW50IHRoYXQgdGhlIHJlY2VpdmVyJ3MgdmFsdWUgd2lsbCBiZQotICogbW9kaWZpZWQgYnkgd2hlbiB0aGUgdXAvZG93biAob3IgcmlnaHQvbGVmdCkgYXJyb3dzCi0gKiBhcmUgcHJlc3NlZCB0byB0aGUgYXJndW1lbnQsIHdoaWNoIG11c3QgYmUgYXQgbGVhc3QgCi0gKiBvbmUuCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgaW5jcmVtZW50IChtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvKQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRJbmNyZW1lbnQgKGludCB2YWx1ZSkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHZhbHVlIDwgMSkgcmV0dXJuOwotCWluY3JlbWVudD0gdmFsdWU7CisJaW5jcmVtZW50ID0gdmFsdWU7CiB9Ci0vKioKLSAqIFNldHMgdGhlIG1heGltdW0gdmFsdWUgd2hpY2ggdGhlIHJlY2VpdmVyIHdpbGwgYWxsb3cKLSAqIHRvIGJlIHRoZSBhcmd1bWVudCB3aGljaCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvcgotICogZXF1YWwgdG8gemVyby4KLSAqCi0gKiBAcGFyYW0gdmFsdWUgdGhlIG5ldyBtYXhpbXVtIChtdXN0IGJlIHplcm8gb3IgZ3JlYXRlcikKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0TWF4aW11bSAoaW50IHZhbHVlKSB7CiAJY2hlY2tXaWRnZXQoKTsKLQlpZiAodmFsdWUgPCAwKSByZXR1cm47Ci0JaWYgKE9TLkdldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSkgPiB2YWx1ZSkKLQkJT1MuU2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlLCB2YWx1ZSk7Ci0JT1MuU2V0Q29udHJvbDMyQml0TWF4aW11bShoYW5kbGUsIHZhbHVlKTsKKwlpbnQgbWluaW11bSA9IE9TLkdldENvbnRyb2wzMkJpdE1pbmltdW0gKGhhbmRsZSk7CisJaWYgKDAgPD0gbWluaW11bSAmJiBtaW5pbXVtIDwgdmFsdWUpIHsKKwkJT1MuU2V0Q29udHJvbDMyQml0TWF4aW11bSAoaGFuZGxlLCB2YWx1ZSk7CisJfQogfQotLyoqCi0gKiBTZXRzIHRoZSBtaW5pbXVtIHZhbHVlIHdoaWNoIHRoZSByZWNlaXZlciB3aWxsIGFsbG93Ci0gKiB0byBiZSB0aGUgYXJndW1lbnQgd2hpY2ggbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IKLSAqIGVxdWFsIHRvIHplcm8uCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgbWluaW11bSAobXVzdCBiZSB6ZXJvIG9yIGdyZWF0ZXIpCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldE1pbmltdW0gKGludCB2YWx1ZSkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKHZhbHVlIDwgMCkgcmV0dXJuOwotCWlmIChPUy5HZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUpIDwgdmFsdWUpCi0JCU9TLlNldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSwgdmFsdWUpOwotCU9TLlNldENvbnRyb2wzMkJpdE1pbmltdW0oaGFuZGxlLCB2YWx1ZSk7CisJaW50IG1heGltdW0gPSBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtIChoYW5kbGUpOworCWlmICgwIDw9IG1heGltdW0gJiYgbWF4aW11bSA8IHZhbHVlKSB7CisJCU9TLlNldENvbnRyb2wzMkJpdE1pbmltdW0gKGhhbmRsZSwgdmFsdWUpOworCX0KIH0KLS8qKgotICogU2V0cyB0aGUgYW1vdW50IHRoYXQgdGhlIHJlY2VpdmVyJ3MgdmFsdWUgd2lsbCBiZQotICogbW9kaWZpZWQgYnkgd2hlbiB0aGUgcGFnZSBpbmNyZW1lbnQvZGVjcmVtZW50IGFyZWFzCi0gKiBhcmUgc2VsZWN0ZWQgdG8gdGhlIGFyZ3VtZW50LCB3aGljaCBtdXN0IGJlIGF0IGxlYXN0Ci0gKiBvbmUuCi0gKgotICogQHJldHVybiB0aGUgcGFnZSBpbmNyZW1lbnQgKG11c3QgYmUgZ3JlYXRlciB0aGFuIHplcm8pCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldFBhZ2VJbmNyZW1lbnQgKGludCB2YWx1ZSkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHZhbHVlIDwgMSkgcmV0dXJuOwotCXBhZ2VJbmNyZW1lbnQ9IHZhbHVlOworCXBhZ2VJbmNyZW1lbnQgPSB2YWx1ZTsKIH0KLS8qKgotICogU2V0cyB0aGUgc2luZ2xlIDxlbT5zZWxlY3Rpb248L2VtPiB0aGF0IGlzIHRoZSByZWNlaXZlcidzCi0gKiB2YWx1ZSB0byB0aGUgYXJndW1lbnQgd2hpY2ggbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwKLSAqIHRvIHplcm8uCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgc2VsZWN0aW9uIChtdXN0IGJlIHplcm8gb3IgZ3JlYXRlcikKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uIChpbnQgdmFsdWUpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICh2YWx1ZSA8IDApIHJldHVybjsKLQlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUsIHZhbHVlKTsKKwlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZSAoaGFuZGxlLCB2YWx1ZSk7CiB9CisKIH0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9TY3JvbGxCYXIuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9TY3JvbGxCYXIuamF2YQppbmRleCBiNDA1NWYxLi44MzliYTM0IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvU2Nyb2xsQmFyLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1Njcm9sbEJhci5qYXZhCkBAIC02LDEyMSArNiwzMSBAQAogICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAgKi8KKyAKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLk9TOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUmVjdDsKIAotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7CiAKLS8qKgotICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgYXJlIHNlbGVjdGFibGUgdXNlciBpbnRlcmZhY2UKLSAqIG9iamVjdHMgdGhhdCByZXByZXNlbnQgYSByYW5nZSBvZiBwb3NpdGl2ZSwgbnVtZXJpYyB2YWx1ZXMuIAotICogPHA+Ci0gKiBBdCBhbnkgZ2l2ZW4gbW9tZW50LCBhIGdpdmVuIHNjcm9sbCBiYXIgd2lsbCBoYXZlIGEgCi0gKiBzaW5nbGUgPGVtPnNlbGVjdGlvbjwvZW0+IHRoYXQgaXMgY29uc2lkZXJlZCB0byBiZSBpdHMKLSAqIHZhbHVlLCB3aGljaCBpcyBjb25zdHJhaW5lZCB0byBiZSB3aXRoaW4gdGhlIHJhbmdlIG9mCi0gKiB2YWx1ZXMgdGhlIHNjcm9sbCBiYXIgcmVwcmVzZW50cyAodGhhdCBpcywgYmV0d2VlbiBpdHMKLSAqIDxlbT5taW5pbXVtPC9lbT4gYW5kIDxlbT5tYXhpbXVtPC9lbT4gdmFsdWVzKS4KLSAqIDwvcD48cD4KLSAqIFR5cGljYWxseSwgc2Nyb2xsIGJhcnMgd2lsbCBiZSBtYWRlIHVwIG9mIGZpdmUgYXJlYXM6Ci0gKiA8b2w+Ci0gKiA8bGk+YW4gYXJyb3cgYnV0dG9uIGZvciBkZWNyZW1lbnRpbmcgdGhlIHZhbHVlPC9saT4KLSAqIDxsaT5hIHBhZ2UgZGVjcmVtZW50IGFyZWEgZm9yIGRlY3JlbWVudGluZyB0aGUgdmFsdWUgYnkgYSBsYXJnZXIgYW1vdW50PC9saT4KLSAqIDxsaT5hIDxlbT50aHVtYjwvZW0+IGZvciBtb2RpZnlpbmcgdGhlIHZhbHVlIGJ5IG1vdXNlIGRyYWdnaW5nPC9saT4KLSAqIDxsaT5hIHBhZ2UgaW5jcmVtZW50IGFyZWEgZm9yIGluY3JlbWVudGluZyB0aGUgdmFsdWUgYnkgYSBsYXJnZXIgYW1vdW50PC9saT4KLSAqIDxsaT5hbiBhcnJvdyBidXR0b24gZm9yIGluY3JlbWVudGluZyB0aGUgdmFsdWU8L2xpPgotICogPC9vbD4KLSAqIEJhc2VkIG9uIHRoZWlyIHN0eWxlLCBzY3JvbGwgYmFycyBhcmUgZWl0aGVyIDxjb2RlPkhPUklaT05UQUw8L2NvZGU+Ci0gKiAod2hpY2ggaGF2ZSBhIGxlZnQgZmFjaW5nIGJ1dHRvbiBmb3IgZGVjcmVtZW50aW5nIHRoZSB2YWx1ZSBhbmQgYQotICogcmlnaHQgZmFjaW5nIGJ1dHRvbiBmb3IgaW5jcmVtZW50aW5nIGl0KSBvciA8Y29kZT5WRVJUSUNBTDwvY29kZT4KLSAqICh3aGljaCBoYXZlIGFuIHVwd2FyZCBmYWNpbmcgYnV0dG9uIGZvciBkZWNyZW1lbnRpbmcgdGhlIHZhbHVlCi0gKiBhbmQgYSBkb3dud2FyZCBmYWNpbmcgYnV0dG9ucyBmb3IgaW5jcmVtZW50aW5nIGl0KS4KLSAqIDwvcD48cD4KLSAqIE9uIHNvbWUgcGxhdGZvcm1zLCB0aGUgc2l6ZSBvZiB0aGUgc2Nyb2xsIGJhcidzIHRodW1iIGNhbiBiZQotICogdmFyaWVkIHJlbGF0aXZlIHRvIHRoZSBtYWduaXR1ZGUgb2YgdGhlIHJhbmdlIG9mIHZhbHVlcyBpdAotICogcmVwcmVzZW50cyAodGhhdCBpcywgcmVsYXRpdmUgdG8gdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBpdHMKLSAqIG1heGltdW0gYW5kIG1pbmltdW0gdmFsdWVzKS4gVHlwaWNhbGx5LCB0aGlzIGlzIHVzZWQgdG8KLSAqIGluZGljYXRlIHNvbWUgcHJvcG9ydGlvbmFsIHZhbHVlIHN1Y2ggYXMgdGhlIHJhdGlvIG9mIHRoZQotICogdmlzaWJsZSBhcmVhIG9mIGEgZG9jdW1lbnQgdG8gdGhlIHRvdGFsIGFtb3VudCBvZiBzcGFjZSB0aGF0Ci0gKiBpdCB3b3VsZCB0YWtlIHRvIGRpc3BsYXkgaXQuIFNXVCBzdXBwb3J0cyBzZXR0aW5nIHRoZSB0aHVtYgotICogc2l6ZSBldmVuIGlmIHRoZSB1bmRlcmx5aW5nIHBsYXRmb3JtIGRvZXMgbm90LCBidXQgaW4gdGhpcwotICogY2FzZSB0aGUgYXBwZWFyYW5jZSBvZiB0aGUgc2Nyb2xsIGJhciB3aWxsIG5vdCBjaGFuZ2UuCi0gKiA8L3A+PHA+Ci0gKiBTY3JvbGwgYmFycyBhcmUgY3JlYXRlZCBieSBzcGVjaWZ5aW5nIGVpdGhlciA8Y29kZT5IX1NDUk9MTDwvY29kZT4sCi0gKiA8Y29kZT5WX1NDUk9MTDwvY29kZT4gb3IgYm90aCB3aGVuIGNyZWF0aW5nIGEgPGNvZGU+U2Nyb2xsYWJsZTwvY29kZT4uCi0gKiBUaGV5IGFyZSBhY2Nlc3NlZCBmcm9tIHRoZSA8Y29kZT5TY3JvbGxhYmxlPC9jb2RlPiB1c2luZwotICogPGNvZGU+Z2V0SG9yaXpvbnRhbEJhcjwvY29kZT4gYW5kIDxjb2RlPmdldFZlcnRpY2FsQmFyPC9jb2RlPi4KLSAqIDwvcD48cD4KLSAqIE5vdGU6IFNjcm9sbCBiYXJzIGFyZSBub3QgQ29udHJvbHMuICBPbiBzb21lIHBsYXRmb3Jtcywgc2Nyb2xsIGJhcnMKLSAqIHRoYXQgYXBwZWFyIGFzIHBhcnQgb2Ygc29tZSBzdGFuZGFyZCBjb250cm9scyBzdWNoIGFzIGEgdGV4dCBvciBsaXN0Ci0gKiBoYXZlIG5vIG9wZXJhdGluZyBzeXN0ZW0gcmVzb3VyY2VzIGFuZCBhcmUgbm90IGNoaWxkcmVuIG9mIHRoZSBjb250cm9sLgotICogRm9yIHRoaXMgcmVhc29uLCBzY3JvbGwgYmFycyBhcmUgdHJlYXRlZCBzcGVjaWFsbHkuICBUbyBjcmVhdGUgYSBjb250cm9sCi0gKiB0aGF0IGxvb2tzIGxpa2UgYSBzY3JvbGwgYmFyIGJ1dCBoYXMgb3BlcmF0aW5nIHN5c3RlbSByZXNvdXJjZXMsIHVzZQotICogPGNvZGU+U2xpZGVyPC9jb2RlPi4gCi0gKiA8L3A+Ci0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPkhPUklaT05UQUwsIFZFUlRJQ0FMPC9kZD4KLSAqIDxkdD48Yj5FdmVudHM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+U2VsZWN0aW9uPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cD4KLSAqIE5vdGU6IE9ubHkgb25lIG9mIHRoZSBzdHlsZXMgSE9SSVpPTlRBTCBhbmQgVkVSVElDQUwgbWF5IGJlIHNwZWNpZmllZC4KLSAqIDwvcD48cD4KLSAqIElNUE9SVEFOVDogVGhpcyBjbGFzcyBpcyA8ZW0+bm90PC9lbT4gaW50ZW5kZWQgdG8gYmUgc3ViY2xhc3NlZC4KLSAqIDwvcD4KLSAqCi0gKiBAc2VlIFNsaWRlcgotICogQHNlZSBTY3JvbGxhYmxlCi0gKiBAc2VlIFNjcm9sbGFibGUjZ2V0SG9yaXpvbnRhbEJhcgotICogQHNlZSBTY3JvbGxhYmxlI2dldFZlcnRpY2FsQmFyCi0gKi8KLXB1YmxpYyAvKmZpbmFsKi8gY2xhc3MgU2Nyb2xsQmFyIGV4dGVuZHMgV2lkZ2V0IHsKK3B1YmxpYyBjbGFzcyBTY3JvbGxCYXIgZXh0ZW5kcyBXaWRnZXQgeworCWludCBoYW5kbGU7CiAJU2Nyb2xsYWJsZSBwYXJlbnQ7Ci0JcHJpdmF0ZSBpbnQgaW5jcmVtZW50PSAxOwotCXByaXZhdGUgaW50IHBhZ2VJbmNyZW1lbnQ9IDEwOwotCWJvb2xlYW4gdmlzaWJsZT0gdHJ1ZTsKLQkKKwlib29sZWFuIGRyYWdnaW5nOworCWludCBpbmNyZW1lbnQgPSAxOworCWludCBwYWdlSW5jcmVtZW50ID0gMTA7CisKIFNjcm9sbEJhciAoKSB7Ci0JLyogRG8gTm90aGluZyAqLworCS8qIERvIG5vdGhpbmcgKi8KIH0KKwogU2Nyb2xsQmFyIChTY3JvbGxhYmxlIHBhcmVudCwgaW50IHN0eWxlKSB7CiAJc3VwZXIgKHBhcmVudCwgY2hlY2tTdHlsZSAoc3R5bGUpKTsKIAl0aGlzLnBhcmVudCA9IHBhcmVudDsKLQljcmVhdGVXaWRnZXQgKDApOworCWNyZWF0ZVdpZGdldCAoKTsKIH0KLS8qKgotICogQWRkcyB0aGUgbGlzdGVuZXIgdG8gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSByZWNlaXZlcidzIHZhbHVlIGNoYW5nZXMsIGJ5IHNlbmRpbmcKLSAqIGl0IG9uZSBvZiB0aGUgbWVzc2FnZXMgZGVmaW5lZCBpbiB0aGUgPGNvZGU+U2VsZWN0aW9uTGlzdGVuZXI8L2NvZGU+Ci0gKiBpbnRlcmZhY2UuCi0gKiA8cD4KLSAqIFdoZW4gPGNvZGU+d2lkZ2V0U2VsZWN0ZWQ8L2NvZGU+IGlzIGNhbGxlZCwgdGhlIGV2ZW50IG9iamVjdCBkZXRhaWwgZmllbGQgY29udGFpbnMgb25lIG9mIHRoZSBmb2xsb3dpbmcgdmFsdWVzOgotICogPGNvZGU+MDwvY29kZT4gLSBmb3IgdGhlIGVuZCBvZiBhIGRyYWcuCi0gKiA8Y29kZT5TV1QuRFJBRzwvY29kZT4uCi0gKiA8Y29kZT5TV1QuSE9NRTwvY29kZT4uCi0gKiA8Y29kZT5TV1QuRU5EPC9jb2RlPi4KLSAqIDxjb2RlPlNXVC5BUlJPV19ET1dOPC9jb2RlPi4KLSAqIDxjb2RlPlNXVC5BUlJPV19VUDwvY29kZT4uCi0gKiA8Y29kZT5TV1QuUEFHRV9ET1dOPC9jb2RlPi4KLSAqIDxjb2RlPlNXVC5QQUdFX1VQPC9jb2RlPi4KLSAqIDxjb2RlPndpZGdldERlZmF1bHRTZWxlY3RlZDwvY29kZT4gaXMgbm90IGNhbGxlZC4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNlbGVjdGlvbkxpc3RlbmVyCi0gKiBAc2VlICNyZW1vdmVTZWxlY3Rpb25MaXN0ZW5lcgotICogQHNlZSBTZWxlY3Rpb25FdmVudAotICovCisKIHB1YmxpYyB2b2lkIGFkZFNlbGVjdGlvbkxpc3RlbmVyKFNlbGVjdGlvbkxpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTEyOCwzMjYgKzM4LDE2OCBAQAogCWFkZExpc3RlbmVyKFNXVC5TZWxlY3Rpb24sdHlwZWRMaXN0ZW5lcik7CiAJYWRkTGlzdGVuZXIoU1dULkRlZmF1bHRTZWxlY3Rpb24sdHlwZWRMaXN0ZW5lcik7CiB9CisKIHN0YXRpYyBpbnQgY2hlY2tTdHlsZSAoaW50IHN0eWxlKSB7CiAJcmV0dXJuIGNoZWNrQml0cyAoc3R5bGUsIFNXVC5IT1JJWk9OVEFMLCBTV1QuVkVSVElDQUwsIDAsIDAsIDAsIDApOwogfQotdm9pZCBjcmVhdGVIYW5kbGUgKGludCBpbmRleCkgewotCXN0YXRlIHw9IEhBTkRMRTsKLQloYW5kbGU9IDA7Ci0JaWYgKChzdHlsZSAmIFNXVC5IX1NDUk9MTCkgIT0gMCkgewotCQloYW5kbGU9IHBhcmVudC5oU2Nyb2xsQmFyOwotCX0gZWxzZSBpZiAoKHN0eWxlICYgU1dULlZfU0NST0xMKSAhPSAwKSB7Ci0JCWhhbmRsZT0gcGFyZW50LnZTY3JvbGxCYXI7CisKK2ludCBhY3Rpb25Qcm9jIChpbnQgdGhlQ29udHJvbCwgaW50IHBhcnRDb2RlKSB7CisJRXZlbnQgZXZlbnQgPSBuZXcgRXZlbnQgKCk7CisJaW50IHZhbHVlID0gT1MuR2V0Q29udHJvbDMyQml0VmFsdWUgKGhhbmRsZSk7CisgICAgc3dpdGNoIChwYXJ0Q29kZSkgeworCSAgICBjYXNlIE9TLmtDb250cm9sVXBCdXR0b25QYXJ0OgorCQkJdmFsdWUgLT0gaW5jcmVtZW50OworCSAgICAgICAgZXZlbnQuZGV0YWlsID0gU1dULkFSUk9XX1VQOworCSAgICAgICAgYnJlYWs7CisJICAgIGNhc2UgT1Mua0NvbnRyb2xQYWdlVXBQYXJ0OgorCQkJdmFsdWUgLT0gcGFnZUluY3JlbWVudDsKKwkgICAgICAgIGV2ZW50LmRldGFpbCA9IFNXVC5QQUdFX1VQOworCSAgICAgICAgYnJlYWs7CisJICAgIGNhc2UgT1Mua0NvbnRyb2xQYWdlRG93blBhcnQ6CisJCQl2YWx1ZSArPSBwYWdlSW5jcmVtZW50OworCSAgICAgICAgZXZlbnQuZGV0YWlsID0gU1dULlBBR0VfRE9XTjsKKwkgICAgICAgIGJyZWFrOworCSAgICBjYXNlIE9TLmtDb250cm9sRG93bkJ1dHRvblBhcnQ6CisJCQl2YWx1ZSArPSBpbmNyZW1lbnQ7CisJICAgICAgICBldmVudC5kZXRhaWwgPSBTV1QuQVJST1dfRE9XTjsKKwkgICAgICAgIGJyZWFrOworCSAgICBjYXNlIE9TLmtDb250cm9sSW5kaWNhdG9yUGFydDoKKwkgICAgCWRyYWdnaW5nID0gdHJ1ZTsKKwkJCWV2ZW50LmRldGFpbCA9IFNXVC5EUkFHOworCSAgICAgICAgYnJlYWs7CisJCWRlZmF1bHQ6CisJCQlyZXR1cm4gMDsKIAl9Ci0JaWYgKGhhbmRsZSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCU9TLlNldENvbnRyb2wzMkJpdFZhbHVlIChoYW5kbGUsIHZhbHVlKTsKKwlzZW5kRXZlbnQgKFNXVC5TZWxlY3Rpb24sIGV2ZW50KTsKKwlpZiAoZHJhZ2dpbmcpIHsKKwkJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwkJZGlzcGxheS51cGRhdGUgKCk7CisJfQorCXJldHVybiAwOwogfQotLyoqCi0qIEdldHMgdGhlIERpc3BsYXkuCi0qLworCit2b2lkIGRlc3Ryb3lXaWRnZXQgKCkgeworCWludCB0aGVDb250cm9sID0gaGFuZGxlOworCXJlbGVhc2VIYW5kbGUgKCk7CisJaWYgKHRoZUNvbnRyb2wgIT0gMCkgeworCQlPUy5EaXNwb3NlQ29udHJvbCAodGhlQ29udHJvbCk7CisJfQorfQorCit2b2lkIGNyZWF0ZUhhbmRsZSAoKSB7CisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlpbnQgYWN0aW9uUHJvYyA9IGRpc3BsYXkuYWN0aW9uUHJvYzsKKwlpbnQgW10gb3V0Q29udHJvbCA9IG5ldyBpbnQgWzFdOworCWludCB3aW5kb3cgPSBPUy5HZXRDb250cm9sT3duZXIgKHBhcmVudC5zY3JvbGxlZEhhbmRsZSk7CisJT1MuQ3JlYXRlU2Nyb2xsQmFyQ29udHJvbCAod2luZG93LCBudWxsLCAwLCAwLCA5MCwgMTAsIHRydWUsIGFjdGlvblByb2MsIG91dENvbnRyb2wpOworCWlmIChvdXRDb250cm9sIFswXSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCWhhbmRsZSA9IG91dENvbnRyb2wgWzBdOworfQorCit2b2lkIGNyZWF0ZVdpZGdldCAoKSB7CisJc3VwZXIuY3JlYXRlV2lkZ2V0ICgpOworCXNldFpPcmRlciAoKTsKK30KKwordm9pZCBkZXJlZ2lzdGVyICgpIHsKKwlzdXBlci5kZXJlZ2lzdGVyICgpOworCVdpZGdldFRhYmxlLnJlbW92ZSAoaGFuZGxlKTsKK30KKwogcHVibGljIERpc3BsYXkgZ2V0RGlzcGxheSAoKSB7CiAJU2Nyb2xsYWJsZSBwYXJlbnQgPSB0aGlzLnBhcmVudDsKIAlpZiAocGFyZW50ID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfV0lER0VUX0RJU1BPU0VEKTsKIAlyZXR1cm4gcGFyZW50LmdldERpc3BsYXkgKCk7CiB9Ci0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGlzIGVuYWJsZWQsIGFuZAotICogPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4gQSBkaXNhYmxlZCBjb250cm9sIGlzIHR5cGljYWxseQotICogbm90IHNlbGVjdGFibGUgZnJvbSB0aGUgdXNlciBpbnRlcmZhY2UgYW5kIGRyYXdzIHdpdGggYW4KLSAqIGluYWN0aXZlIG9yICJncmF5ZWQiIGxvb2suCi0gKgotICogQHJldHVybiB0aGUgZW5hYmxlZCBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgYm9vbGVhbiBnZXRFbmFibGVkICgpIHsKIAljaGVja1dpZGdldCgpOwotCXJldHVybiBPUy5Jc0NvbnRyb2xFbmFibGVkKGhhbmRsZSk7CisJcmV0dXJuIChzdGF0ZSAmIERJU0FCTEVEKSA9PSAwOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBhbW91bnQgdGhhdCB0aGUgcmVjZWl2ZXIncyB2YWx1ZSB3aWxsIGJlCi0gKiBtb2RpZmllZCBieSB3aGVuIHRoZSB1cC9kb3duIChvciByaWdodC9sZWZ0KSBhcnJvd3MKLSAqIGFyZSBwcmVzc2VkLgotICoKLSAqIEByZXR1cm4gdGhlIGluY3JlbWVudAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldEluY3JlbWVudCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKICAgICByZXR1cm4gaW5jcmVtZW50OwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBtYXhpbXVtIHZhbHVlIHdoaWNoIHRoZSByZWNlaXZlciB3aWxsIGFsbG93LgotICoKLSAqIEByZXR1cm4gdGhlIG1heGltdW0KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGludCBnZXRNYXhpbXVtICgpIHsKIAljaGVja1dpZGdldCgpOwotICAgIHJldHVybiBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSkgKyBPUy5HZXRDb250cm9sVmlld1NpemUoaGFuZGxlKTsKKwlpbnQgbWF4aW11bSA9IE9TLkdldENvbnRyb2wzMkJpdE1heGltdW0gKGhhbmRsZSk7CisJaW50IHZpZXdTaXplID0gT1MuR2V0Q29udHJvbFZpZXdTaXplIChoYW5kbGUpOworICAgIHJldHVybiBtYXhpbXVtICsgdmlld1NpemU7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIG1pbmltdW0gdmFsdWUgd2hpY2ggdGhlIHJlY2VpdmVyIHdpbGwgYWxsb3cuCi0gKgotICogQHJldHVybiB0aGUgbWluaW11bQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldE1pbmltdW0gKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0gICAgcmV0dXJuIE9TLkdldENvbnRyb2wzMkJpdE1pbmltdW0oaGFuZGxlKTsKKyAgICByZXR1cm4gT1MuR2V0Q29udHJvbDMyQml0TWluaW11bSAoaGFuZGxlKTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgYW1vdW50IHRoYXQgdGhlIHJlY2VpdmVyJ3MgdmFsdWUgd2lsbCBiZQotICogbW9kaWZpZWQgYnkgd2hlbiB0aGUgcGFnZSBpbmNyZW1lbnQvZGVjcmVtZW50IGFyZWFzCi0gKiBhcmUgc2VsZWN0ZWQuCi0gKgotICogQHJldHVybiB0aGUgcGFnZSBpbmNyZW1lbnQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGludCBnZXRQYWdlSW5jcmVtZW50ICgpIHsKIAljaGVja1dpZGdldCgpOwogICAgIHJldHVybiBwYWdlSW5jcmVtZW50OwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSByZWNlaXZlcidzIHBhcmVudCwgd2hpY2ggbXVzdCBiZSBzY3JvbGxhYmxlLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgcGFyZW50Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBTY3JvbGxhYmxlIGdldFBhcmVudCAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKKwljaGVja1dpZGdldCAoKTsKIAlyZXR1cm4gcGFyZW50OwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBzaW5nbGUgPGVtPnNlbGVjdGlvbjwvZW0+IHRoYXQgaXMgdGhlIHJlY2VpdmVyJ3MgdmFsdWUuCi0gKgotICogQHJldHVybiB0aGUgc2VsZWN0aW9uCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBpbnQgZ2V0U2VsZWN0aW9uICgpIHsKIAljaGVja1dpZGdldCgpOwotCXJldHVybiBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUpOworICAgIHJldHVybiBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZSAoaGFuZGxlKTsKIH0KLS8qKgotICogUmV0dXJucyBhIHBvaW50IGRlc2NyaWJpbmcgdGhlIHJlY2VpdmVyJ3Mgc2l6ZS4gVGhlCi0gKiB4IGNvb3JkaW5hdGUgb2YgdGhlIHJlc3VsdCBpcyB0aGUgd2lkdGggb2YgdGhlIHJlY2VpdmVyLgotICogVGhlIHkgY29vcmRpbmF0ZSBvZiB0aGUgcmVzdWx0IGlzIHRoZSBoZWlnaHQgb2YgdGhlCi0gKiByZWNlaXZlci4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIHNpemUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIFBvaW50IGdldFNpemUgKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JT1MuR2V0Q29udHJvbEJvdW5kcyhoYW5kbGUsIGJvdW5kcy5nZXREYXRhKCkpOwotCXJldHVybiBib3VuZHMuZ2V0U2l6ZSgpOworCVJlY3QgcmVjdCA9IGdldENvbnRyb2xTaXplIChoYW5kbGUpOworCXJldHVybiBuZXcgUG9pbnQgKHJlY3QucmlnaHQgLSByZWN0LmxlZnQsIHJlY3QuYm90dG9tIC0gcmVjdC50b3ApOwogfQotLyoqCi0gKiBBbnN3ZXJzIHRoZSBzaXplIG9mIHRoZSByZWNlaXZlcidzIHRodW1iIHJlbGF0aXZlIHRvIHRoZQotICogZGlmZmVyZW5jZSBiZXR3ZWVuIGl0cyBtYXhpbXVtIGFuZCBtaW5pbXVtIHZhbHVlcy4KLSAqCi0gKiBAcmV0dXJuIHRoZSB0aHVtYiB2YWx1ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNjcm9sbEJhcgotICovCisKIHB1YmxpYyBpbnQgZ2V0VGh1bWIgKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0gICAgcmV0dXJuIE9TLkdldENvbnRyb2xWaWV3U2l6ZShoYW5kbGUpOworICAgIHJldHVybiBPUy5HZXRDb250cm9sVmlld1NpemUgKGhhbmRsZSk7CiB9Ci0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGlzIHZpc2libGUsIGFuZAotICogPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAqIDxwPgotICogSWYgb25lIG9mIHRoZSByZWNlaXZlcidzIGFuY2VzdG9ycyBpcyBub3QgdmlzaWJsZSBvciBzb21lCi0gKiBvdGhlciBjb25kaXRpb24gbWFrZXMgdGhlIHJlY2VpdmVyIG5vdCB2aXNpYmxlLCB0aGlzIG1ldGhvZAotICogbWF5IHN0aWxsIGluZGljYXRlIHRoYXQgaXQgaXMgY29uc2lkZXJlZCB2aXNpYmxlIGV2ZW4gdGhvdWdoCi0gKiBpdCBtYXkgbm90IGFjdHVhbGx5IGJlIHNob3dpbmcuCi0gKiA8L3A+Ci0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyB2aXNpYmlsaXR5IHN0YXRlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBib29sZWFuIGdldFZpc2libGUgKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JcmV0dXJuIE9TLklzQ29udHJvbFZpc2libGUoaGFuZGxlKTsKKwlyZXR1cm4gKHN0YXRlICYgSElEREVOKSA9PSAwOwogfQotLyogQVcKKwogdm9pZCBob29rRXZlbnRzICgpIHsKLQlpbnQgd2luZG93UHJvYyA9IHBhcmVudC5nZXREaXNwbGF5ICgpLndpbmRvd1Byb2M7Ci0JT1MuWHRBZGRDYWxsYmFjayAoaGFuZGxlLCBPUy5YbU52YWx1ZUNoYW5nZWRDYWxsYmFjaywgd2luZG93UHJvYywgU1dULlNlbGVjdGlvbik7Ci0JT1MuWHRBZGRDYWxsYmFjayAoaGFuZGxlLCBPUy5YbU5kcmFnQ2FsbGJhY2ssIHdpbmRvd1Byb2MsIFNXVC5TZWxlY3Rpb24pOwotCU9TLlh0QWRkQ2FsbGJhY2sgKGhhbmRsZSwgT1MuWG1OdG9Cb3R0b21DYWxsYmFjaywgd2luZG93UHJvYywgU1dULlNlbGVjdGlvbik7Ci0JT1MuWHRBZGRDYWxsYmFjayAoaGFuZGxlLCBPUy5YbU5pbmNyZW1lbnRDYWxsYmFjaywgd2luZG93UHJvYywgU1dULlNlbGVjdGlvbik7Ci0JT1MuWHRBZGRDYWxsYmFjayAoaGFuZGxlLCBPUy5YbU5kZWNyZW1lbnRDYWxsYmFjaywgd2luZG93UHJvYywgU1dULlNlbGVjdGlvbik7Ci0JT1MuWHRBZGRDYWxsYmFjayAoaGFuZGxlLCBPUy5YbU5wYWdlSW5jcmVtZW50Q2FsbGJhY2ssIHdpbmRvd1Byb2MsIFNXVC5TZWxlY3Rpb24pOwotCU9TLlh0QWRkQ2FsbGJhY2sgKGhhbmRsZSwgT1MuWG1OcGFnZURlY3JlbWVudENhbGxiYWNrLCB3aW5kb3dQcm9jLCBTV1QuU2VsZWN0aW9uKTsKLQlPUy5YdEFkZENhbGxiYWNrIChoYW5kbGUsIE9TLlhtTnRvVG9wQ2FsbGJhY2ssIHdpbmRvd1Byb2MsIFNXVC5TZWxlY3Rpb24pOworCXN1cGVyLmhvb2tFdmVudHMgKCk7CisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlpbnQgY29udHJvbFByb2MgPSBkaXNwbGF5LmNvbnRyb2xQcm9jOworCWludCBbXSBtYXNrID0gbmV3IGludCBbXSB7CisJCU9TLmtFdmVudENsYXNzQ29udHJvbCwgT1Mua0V2ZW50Q29udHJvbERyYXcsCisJfTsKKwlpbnQgY29udHJvbFRhcmdldCA9IE9TLkdldENvbnRyb2xFdmVudFRhcmdldCAoaGFuZGxlKTsKKwlPUy5JbnN0YWxsRXZlbnRIYW5kbGVyIChjb250cm9sVGFyZ2V0LCBjb250cm9sUHJvYywgbWFzay5sZW5ndGggLyAyLCBtYXNrLCBoYW5kbGUsIG51bGwpOwogfQotKi8KLS8qKgotICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVjZWl2ZXIgaXMgZW5hYmxlZCBhbmQgYWxsCi0gKiBvZiB0aGUgcmVjZWl2ZXIncyBhbmNlc3RvcnMgYXJlIGVuYWJsZWQsIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4KLSAqIG90aGVyd2lzZS4gQSBkaXNhYmxlZCBjb250cm9sIGlzIHR5cGljYWxseSBub3Qgc2VsZWN0YWJsZSBmcm9tIHRoZQotICogdXNlciBpbnRlcmZhY2UgYW5kIGRyYXdzIHdpdGggYW4gaW5hY3RpdmUgb3IgImdyYXllZCIgbG9vay4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGVuYWJsZWQgc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKiAKLSAqIEBzZWUgI2dldEVuYWJsZWQKLSAqLworCiBwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWQgKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JcmV0dXJuIGdldEVuYWJsZWQgKCkgJiYgcGFyZW50LmlzRW5hYmxlZCAoKTsKKwlyZXR1cm4gT1MuSXNDb250cm9sRW5hYmxlZCAoaGFuZGxlKTsKIH0KLS8qKgotICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVjZWl2ZXIgaXMgdmlzaWJsZSBhbmQgYWxsCi0gKiBvZiB0aGUgcmVjZWl2ZXIncyBhbmNlc3RvcnMgYXJlIHZpc2libGUgYW5kIDxjb2RlPmZhbHNlPC9jb2RlPgotICogb3RoZXJ3aXNlLgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgdmlzaWJpbGl0eSBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNnZXRWaXNpYmxlCi0gKi8KKwogcHVibGljIGJvb2xlYW4gaXNWaXNpYmxlICgpIHsKIAljaGVja1dpZGdldCgpOwotCXJldHVybiBnZXRWaXNpYmxlICgpICYmIHBhcmVudC5pc1Zpc2libGUgKCk7CisJcmV0dXJuIE9TLkhJVmlld0lzVmlzaWJsZSAoaGFuZGxlKTsKIH0KLS8qIEFXCi12b2lkIG1hbmFnZUNoaWxkcmVuICgpIHsKLQlPUy5YdE1hbmFnZUNoaWxkIChoYW5kbGUpOwotfQotKi8KLWludCBwcm9jZXNzU2VsZWN0aW9uIChPYmplY3QgY2FsbERhdGEpIHsKIAotCU1hY0NvbnRyb2xFdmVudCBtYWNFdmVudD0gKE1hY0NvbnRyb2xFdmVudCkgY2FsbERhdGE7Ci0JaW50IHBhcnRDb2RlPSBtYWNFdmVudC5nZXRQYXJ0Q29kZSgpOwotCWJvb2xlYW4gbW91c2VEb3duPSBtYWNFdmVudC5pc01vdXNlRG93bigpOwotCQotCWlmICgocGFydENvZGUgIT0gT1Mua0NvbnRyb2xJbmRpY2F0b3JQYXJ0KSAmJiAhbW91c2VEb3duKQotCQlyZXR1cm4gMDsKLQkKLQlFdmVudCBldmVudD0gbmV3IEV2ZW50ICgpOwotCQotICAgIHN3aXRjaCAocGFydENvZGUpIHsKLSAgICBjYXNlIE9TLmtDb250cm9sVXBCdXR0b25QYXJ0OgotCQlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUsIE9TLkdldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSkgLSBpbmNyZW1lbnQpOwotICAgICAgICBldmVudC5kZXRhaWwgPSBTV1QuQVJST1dfVVA7Ci0gICAgICAgIGJyZWFrOwotICAgIGNhc2UgT1Mua0NvbnRyb2xQYWdlVXBQYXJ0OgotCQlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUsIE9TLkdldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSkgLSBwYWdlSW5jcmVtZW50KTsKLSAgICAgICAgZXZlbnQuZGV0YWlsID0gU1dULlBBR0VfVVA7Ci0gICAgICAgIGJyZWFrOwotICAgIGNhc2UgT1Mua0NvbnRyb2xQYWdlRG93blBhcnQ6Ci0JCU9TLlNldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSwgT1MuR2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlKSArIHBhZ2VJbmNyZW1lbnQpOwotICAgICAgICBldmVudC5kZXRhaWwgPSBTV1QuUEFHRV9ET1dOOwotICAgICAgICBicmVhazsKLSAgICBjYXNlIE9TLmtDb250cm9sRG93bkJ1dHRvblBhcnQ6Ci0JCU9TLlNldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSwgT1MuR2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlKSArIGluY3JlbWVudCk7Ci0gICAgICAgIGV2ZW50LmRldGFpbCA9IFNXVC5BUlJPV19ET1dOOwotICAgICAgICBicmVhazsKLSAgICBjYXNlIE9TLmtDb250cm9sSW5kaWNhdG9yUGFydDoJLy8gZW5kIG9mIGRyYWcgb3IgY29udGludW9zIGRyYWcKLQkJaWYgKG1vdXNlRG93bikgewotCQkJZXZlbnQuZGV0YWlsID0gU1dULkRSQUc7CS8vIGNvbnRpbnVvcyBkcmFnCi0JCX0gZWxzZSB7Ci0JCQkvKgotCQkJKiBEbyBub3Qgc2V0IHRoZSBkZXRhaWwgZmllbGQgdG8gU1dULkRSQUcKLQkJCSogdG8gaW5kaWNhdGUgdGhhdCB0aGUgZHJhZ2dpbmcgaGFzIGVuZGVkLgotCQkJKi8KLQkJfQotICAgICAgICBicmVhazsKLSAgICB9CitpbnQga0V2ZW50TW91c2VEb3duIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IHN0YXR1cyA9IHN1cGVyLmtFdmVudE1vdXNlRG93biAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKHN0YXR1cyA9PSBPUy5ub0VycikgcmV0dXJuIHN0YXR1czsKKwlkcmFnZ2luZyA9IGZhbHNlOworCXN0YXR1cyA9IE9TLkNhbGxOZXh0RXZlbnRIYW5kbGVyIChuZXh0SGFuZGxlciwgdGhlRXZlbnQpOworCWlmIChkcmFnZ2luZykgeworCQlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKKwkJc2VuZEV2ZW50IChTV1QuU2VsZWN0aW9uLCBldmVudCk7CisJfQorCWRyYWdnaW5nID0gZmFsc2U7CisJcmV0dXJuIHN0YXR1czsKK30KIAotCXNlbmRFdmVudCAoU1dULlNlbGVjdGlvbiwgZXZlbnQpOwotCS8vIGZsdXNoIGRpc3BsYXkKLQlnZXREaXNwbGF5KCkudXBkYXRlKCk7Ci0KLQlyZXR1cm4gT1Mua05vRXJyOwotfQotaW50IHByb2Nlc3NXaGVlbChpbnQgZVJlZkhhbmRsZSkgewotCWludFtdIHQ9IG5ldyBpbnRbMV07Ci0JT1MuR2V0RXZlbnRQYXJhbWV0ZXIoZVJlZkhhbmRsZSwgT1Mua0V2ZW50UGFyYW1Nb3VzZVdoZWVsRGVsdGEsIE9TLnR5cGVTSW50MzIsIG51bGwsIG51bGwsIHQpOwotCU9TLlNldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSwgT1MuR2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlKSAtIChpbmNyZW1lbnQgKiB0WzBdKSk7Ci0JRXZlbnQgZXZlbnQ9IG5ldyBFdmVudCAoKTsKLSAgICBldmVudC5kZXRhaWw9IHRbMF0gPiAwID8gU1dULkFSUk9XX1VQIDogU1dULkFSUk9XX0RPV047CQotCXNlbmRFdmVudCAoU1dULlNlbGVjdGlvbiwgZXZlbnQpOwotCWdldERpc3BsYXkoKS51cGRhdGUoKTsKLQlyZXR1cm4gT1Mua05vRXJyOwotfQotdm9pZCByZWxlYXNlQ2hpbGQgKCkgewotCXN1cGVyLnJlbGVhc2VDaGlsZCAoKTsKLQlpZiAocGFyZW50Lmhvcml6b250YWxCYXIgPT0gdGhpcykgcGFyZW50Lmhvcml6b250YWxCYXIgPSBudWxsOwotCWlmIChwYXJlbnQudmVydGljYWxCYXIgPT0gdGhpcykgcGFyZW50LnZlcnRpY2FsQmFyID0gbnVsbDsKLX0KLXZvaWQgcmVsZWFzZVdpZGdldCAoKSB7Ci0Jc3VwZXIucmVsZWFzZVdpZGdldCAoKTsKLQlwYXJlbnQgPSBudWxsOwotfQotLyoqCi0gKiBSZW1vdmVzIHRoZSBsaXN0ZW5lciBmcm9tIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgcmVjZWl2ZXIncyB2YWx1ZSBjaGFuZ2VzLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIG5vIGxvbmdlciBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNlbGVjdGlvbkxpc3RlbmVyCi0gKiBAc2VlICNhZGRTZWxlY3Rpb25MaXN0ZW5lcgotICovCiBwdWJsaWMgdm9pZCByZW1vdmVTZWxlY3Rpb25MaXN0ZW5lcihTZWxlY3Rpb25MaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC00NTUsMTU1ICsyMDcsODIgQEAKIAlldmVudFRhYmxlLnVuaG9vayhTV1QuU2VsZWN0aW9uLCBsaXN0ZW5lcik7CiAJZXZlbnRUYWJsZS51bmhvb2soU1dULkRlZmF1bHRTZWxlY3Rpb24sbGlzdGVuZXIpOwogfQotLyoqCi0gKiBFbmFibGVzIHRoZSByZWNlaXZlciBpZiB0aGUgYXJndW1lbnQgaXMgPGNvZGU+dHJ1ZTwvY29kZT4sCi0gKiBhbmQgZGlzYWJsZXMgaXQgb3RoZXJ3aXNlLiBBIGRpc2FibGVkIGNvbnRyb2wgaXMgdHlwaWNhbGx5Ci0gKiBub3Qgc2VsZWN0YWJsZSBmcm9tIHRoZSB1c2VyIGludGVyZmFjZSBhbmQgZHJhd3Mgd2l0aCBhbgotICogaW5hY3RpdmUgb3IgImdyYXllZCIgbG9vay4KLSAqCi0gKiBAcGFyYW0gZW5hYmxlZCB0aGUgbmV3IGVuYWJsZWQgc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KLXB1YmxpYyB2b2lkIHNldEVuYWJsZWQgKGJvb2xlYW4gZW5hYmxlZCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKGVuYWJsZWQpCi0JCU9TLkVuYWJsZUNvbnRyb2woaGFuZGxlKTsKLQllbHNlCi0JCU9TLkRpc2FibGVDb250cm9sKGhhbmRsZSk7CisKK3ZvaWQgcmVnaXN0ZXIgKCkgeworCXN1cGVyLnJlZ2lzdGVyICgpOworCVdpZGdldFRhYmxlLnB1dCAoaGFuZGxlLCB0aGlzKTsKIH0KLS8qKgotICogU2V0cyB0aGUgYW1vdW50IHRoYXQgdGhlIHJlY2VpdmVyJ3MgdmFsdWUgd2lsbCBiZQotICogbW9kaWZpZWQgYnkgd2hlbiB0aGUgdXAvZG93biAob3IgcmlnaHQvbGVmdCkgYXJyb3dzCi0gKiBhcmUgcHJlc3NlZCB0byB0aGUgYXJndW1lbnQsIHdoaWNoIG11c3QgYmUgYXQgbGVhc3QgCi0gKiBvbmUuCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgaW5jcmVtZW50IChtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvKQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCit2b2lkIHJlbGVhc2VDaGlsZCAoKSB7CisJc3VwZXIucmVsZWFzZUNoaWxkICgpOworCS8vTk9UIERPTkUgLSBsYXlvdXQgcGFyZW50Cit9CisKK3ZvaWQgcmVsZWFzZUhhbmRsZSAoKSB7CisJc3VwZXIucmVsZWFzZUhhbmRsZSAoKTsKKwloYW5kbGUgPSAwOworfQorCit2b2lkIHJlbGVhc2VXaWRnZXQgKCkgeworCXN1cGVyLnJlbGVhc2VXaWRnZXQgKCk7CisJcGFyZW50ID0gbnVsbDsKK30KKwogcHVibGljIHZvaWQgc2V0SW5jcmVtZW50IChpbnQgdmFsdWUpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICh2YWx1ZSA8IDEpIHJldHVybjsKLQlpbmNyZW1lbnQ9IHZhbHVlOworCWluY3JlbWVudCA9IHZhbHVlOwogfQotLyoqCi0gKiBTZXRzIHRoZSBtYXhpbXVtIHZhbHVlIHdoaWNoIHRoZSByZWNlaXZlciB3aWxsIGFsbG93Ci0gKiB0byBiZSB0aGUgYXJndW1lbnQgd2hpY2ggbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IKLSAqIGVxdWFsIHRvIHplcm8uCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgbWF4aW11bSAobXVzdCBiZSB6ZXJvIG9yIGdyZWF0ZXIpCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKK3B1YmxpYyB2b2lkIHNldEVuYWJsZWQgKGJvb2xlYW4gZW5hYmxlZCkgeworCWNoZWNrV2lkZ2V0KCk7CisJaWYgKGVuYWJsZWQpIHsKKwkJaWYgKChzdGF0ZSAmIERJU0FCTEVEKSA9PSAwKSByZXR1cm47CisJCXN0YXRlICY9IH5ESVNBQkxFRDsKKwkJT1MuRW5hYmxlQ29udHJvbCAoaGFuZGxlKTsKKwl9IGVsc2UgeworCQlpZiAoKHN0YXRlICYgRElTQUJMRUQpICE9IDApIHJldHVybjsKKwkJc3RhdGUgfD0gRElTQUJMRUQ7CisJCU9TLkRpc2FibGVDb250cm9sIChoYW5kbGUpOworCX0KK30KKwogcHVibGljIHZvaWQgc2V0TWF4aW11bSAoaW50IHZhbHVlKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAodmFsdWUgPCAwKSByZXR1cm47Ci0gICAgT1MuU2V0Q29udHJvbDMyQml0TWF4aW11bShoYW5kbGUsIHZhbHVlLU9TLkdldENvbnRyb2xWaWV3U2l6ZShoYW5kbGUpKTsKKwlpbnQgbWluaW11bSA9IE9TLkdldENvbnRyb2wzMkJpdE1pbmltdW0gKGhhbmRsZSk7CisJaW50IHZpZXdTaXplID0gT1MuR2V0Q29udHJvbFZpZXdTaXplIChoYW5kbGUpOworCWlmICh2YWx1ZSAtIG1pbmltdW0gLSB2aWV3U2l6ZSA8IDApIHJldHVybjsKKwlPUy5TZXRDb250cm9sMzJCaXRNYXhpbXVtIChoYW5kbGUsIHZhbHVlIC0gdmlld1NpemUpOwogfQotLyoqCi0gKiBTZXRzIHRoZSBtaW5pbXVtIHZhbHVlIHdoaWNoIHRoZSByZWNlaXZlciB3aWxsIGFsbG93Ci0gKiB0byBiZSB0aGUgYXJndW1lbnQgd2hpY2ggbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IKLSAqIGVxdWFsIHRvIHplcm8uCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgbWluaW11bSAobXVzdCBiZSB6ZXJvIG9yIGdyZWF0ZXIpCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldE1pbmltdW0gKGludCB2YWx1ZSkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHZhbHVlIDwgMCkgcmV0dXJuOwotICAgIE9TLlNldENvbnRyb2wzMkJpdE1pbmltdW0oaGFuZGxlLCB2YWx1ZSk7CisJaW50IG1heGltdW0gPSBPUy5HZXRDb250cm9sMzJCaXRNaW5pbXVtIChoYW5kbGUpOworCWludCB2aWV3U2l6ZSA9IE9TLkdldENvbnRyb2xWaWV3U2l6ZSAoaGFuZGxlKTsKKwlpZiAobWF4aW11bSAtIHZhbHVlIC0gdmlld1NpemUgPCAwKSByZXR1cm47CisJT1MuU2V0Q29udHJvbDMyQml0TWluaW11bSAoaGFuZGxlLCB2YWx1ZSk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIGFtb3VudCB0aGF0IHRoZSByZWNlaXZlcidzIHZhbHVlIHdpbGwgYmUKLSAqIG1vZGlmaWVkIGJ5IHdoZW4gdGhlIHBhZ2UgaW5jcmVtZW50L2RlY3JlbWVudCBhcmVhcwotICogYXJlIHNlbGVjdGVkIHRvIHRoZSBhcmd1bWVudCwgd2hpY2ggbXVzdCBiZSBhdCBsZWFzdAotICogb25lLgotICoKLSAqIEByZXR1cm4gdGhlIHBhZ2UgaW5jcmVtZW50IChtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvKQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRQYWdlSW5jcmVtZW50IChpbnQgdmFsdWUpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICh2YWx1ZSA8IDEpIHJldHVybjsKLQlwYWdlSW5jcmVtZW50PSB2YWx1ZTsKKwlwYWdlSW5jcmVtZW50ID0gdmFsdWU7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHNpbmdsZSA8ZW0+c2VsZWN0aW9uPC9lbT4gdGhhdCBpcyB0aGUgcmVjZWl2ZXIncwotICogdmFsdWUgdG8gdGhlIGFyZ3VtZW50IHdoaWNoIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsCi0gKiB0byB6ZXJvLgotICoKLSAqIEBwYXJhbSB2YWx1ZSB0aGUgbmV3IHNlbGVjdGlvbiAobXVzdCBiZSB6ZXJvIG9yIGdyZWF0ZXIpCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCi1wdWJsaWMgdm9pZCBzZXRTZWxlY3Rpb24gKGludCBzZWxlY3Rpb24pIHsKKworcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uIChpbnQgdmFsdWUpIHsKIAljaGVja1dpZGdldCgpOwotCWlmIChzZWxlY3Rpb24gPCAwKSByZXR1cm47Ci0gICAgT1MuU2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlLCBzZWxlY3Rpb24pOworCWlmICh2YWx1ZSA8IDApIHJldHVybjsKKwlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZSAoaGFuZGxlLCB2YWx1ZSk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHNpemUgb2YgdGhlIHJlY2VpdmVyJ3MgdGh1bWIgcmVsYXRpdmUgdG8gdGhlCi0gKiBkaWZmZXJlbmNlIGJldHdlZW4gaXRzIG1heGltdW0gYW5kIG1pbmltdW0gdmFsdWVzIHRvIHRoZQotICogYXJndW1lbnQgd2hpY2ggbXVzdCBiZSBhdCBsZWFzdCBvbmUuCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdGh1bWIgdmFsdWUgKG11c3QgYmUgYXQgbGVhc3Qgb25lKQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNjcm9sbEJhcgotICovCisKIHB1YmxpYyB2b2lkIHNldFRodW1iIChpbnQgdmFsdWUpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICh2YWx1ZSA8IDEpIHJldHVybjsKLQlpbnQgb2xkTWF4aW11bT0gT1MuR2V0Q29udHJvbDMyQml0TWF4aW11bShoYW5kbGUpICsgT1MuR2V0Q29udHJvbFZpZXdTaXplKGhhbmRsZSk7Ci0gICAgT1MuU2V0Q29udHJvbFZpZXdTaXplKGhhbmRsZSwgdmFsdWUpOwotICAgIE9TLlNldENvbnRyb2wzMkJpdE1heGltdW0oaGFuZGxlLCBvbGRNYXhpbXVtLXZhbHVlKTsKKyAgICBPUy5TZXRDb250cm9sVmlld1NpemUgKGhhbmRsZSwgdmFsdWUpOwogfQotLyoqCi0gKiBTZXRzIHRoZSByZWNlaXZlcidzIHNlbGVjdGlvbiwgbWluaW11bSB2YWx1ZSwgbWF4aW11bQotICogdmFsdWUsIHRodW1iLCBpbmNyZW1lbnQgYW5kIHBhZ2UgaW5jcmVtZW50IGFsbCBhdCBvbmNlLgotICogPHA+Ci0gKiBOb3RlOiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gc2V0dGluZyB0aGUgdmFsdWVzIGluZGl2aWR1YWxseQotICogdXNpbmcgdGhlIGFwcHJvcHJpYXRlIG1ldGhvZHMsIGJ1dCBtYXkgYmUgaW1wbGVtZW50ZWQgaW4gYSAKLSAqIG1vcmUgZWZmaWNpZW50IGZhc2hpb24gb24gc29tZSBwbGF0Zm9ybXMuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHNlbGVjdGlvbiB0aGUgbmV3IHNlbGVjdGlvbiB2YWx1ZQotICogQHBhcmFtIG1pbmltdW0gdGhlIG5ldyBtaW5pbXVtIHZhbHVlCi0gKiBAcGFyYW0gbWF4aW11bSB0aGUgbmV3IG1heGltdW0gdmFsdWUKLSAqIEBwYXJhbSB0aHVtYiB0aGUgbmV3IHRodW1iIHZhbHVlCi0gKiBAcGFyYW0gaW5jcmVtZW50IHRoZSBuZXcgaW5jcmVtZW50IHZhbHVlCi0gKiBAcGFyYW0gcGFnZUluY3JlbWVudCB0aGUgbmV3IHBhZ2VJbmNyZW1lbnQgdmFsdWUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0VmFsdWVzIChpbnQgc2VsZWN0aW9uLCBpbnQgbWluaW11bSwgaW50IG1heGltdW0sIGludCB0aHVtYiwgaW50IGluY3JlbWVudCwgaW50IHBhZ2VJbmNyZW1lbnQpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChzZWxlY3Rpb24gPCAwKSByZXR1cm47CkBAIC02MTMsNTIgKzI5MiwzMCBAQAogCWlmIChtYXhpbXVtIC0gbWluaW11bSAtIHRodW1iIDwgMCkgcmV0dXJuOwogCWlmIChpbmNyZW1lbnQgPCAxKSByZXR1cm47CiAJaWYgKHBhZ2VJbmNyZW1lbnQgPCAxKSByZXR1cm47Ci0JT1MuU2V0Q29udHJvbDMyQml0TWluaW11bShoYW5kbGUsIG1pbmltdW0pOwotCU9TLlNldENvbnRyb2wzMkJpdE1heGltdW0oaGFuZGxlLCBtYXhpbXVtLXRodW1iKTsKLQlPUy5TZXRDb250cm9sVmlld1NpemUoaGFuZGxlLCB0aHVtYik7Ci0JT1MuU2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlLCBzZWxlY3Rpb24pOwotCXRoaXMuaW5jcmVtZW50PSBpbmNyZW1lbnQ7Ci0JdGhpcy5wYWdlSW5jcmVtZW50PSBwYWdlSW5jcmVtZW50OwotfQotLyoqCi0gKiBNYXJrcyB0aGUgcmVjZWl2ZXIgYXMgdmlzaWJsZSBpZiB0aGUgYXJndW1lbnQgaXMgPGNvZGU+dHJ1ZTwvY29kZT4sCi0gKiBhbmQgbWFya3MgaXQgaW52aXNpYmxlIG90aGVyd2lzZS4gCi0gKiA8cD4KLSAqIElmIG9uZSBvZiB0aGUgcmVjZWl2ZXIncyBhbmNlc3RvcnMgaXMgbm90IHZpc2libGUgb3Igc29tZQotICogb3RoZXIgY29uZGl0aW9uIG1ha2VzIHRoZSByZWNlaXZlciBub3QgdmlzaWJsZSwgbWFya2luZwotICogaXQgdmlzaWJsZSBtYXkgbm90IGFjdHVhbGx5IGNhdXNlIGl0IHRvIGJlIGRpc3BsYXllZC4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gdmlzaWJsZSB0aGUgbmV3IHZpc2liaWxpdHkgc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KLXB1YmxpYyB2b2lkIHNldFZpc2libGUgKGJvb2xlYW4gdmlzaWJsZSkgewotCWNoZWNrV2lkZ2V0KCk7Ci0JCi0vLwl0aGlzLnZpc2libGU9IHZpc2libGU7Ci0vLwlpZiAoT1MuSXNDb250cm9sVmlzaWJsZShoYW5kbGUpICE9IHZpc2libGUpIHsKLS8vCQlPUy5ISVZpZXdTZXRWaXNpYmxlKGhhbmRsZSwgdmlzaWJsZSk7CQkKLS8vCQlwYXJlbnQucmVsYXlvdXQxMjMoKTsKLS8vCQlzZW5kRXZlbnQodmlzaWJsZSA/IFNXVC5TaG93IDogU1dULkhpZGUpOwotLy8JfQotCQotICAgIGlmICh0aGlzLnZpc2libGUgIT0gdmlzaWJsZSkgewotCSAgICB0aGlzLnZpc2libGU9IHZpc2libGU7Ci0JCWludCB0b3BIYW5kbGUgPSB0b3BIYW5kbGUgKCk7Ci0JCWlmIChPUy5Jc0NvbnRyb2xWaXNpYmxlKHRvcEhhbmRsZSkgIT0gdmlzaWJsZSkgewotCQkJT1MuSElWaWV3U2V0VmlzaWJsZSh0b3BIYW5kbGUsIHZpc2libGUpOwotCQkJcGFyZW50LnJlbGF5b3V0MTIzKCk7Ci0JCQlzZW5kRXZlbnQgKHZpc2libGUgPyBTV1QuU2hvdyA6IFNXVC5IaWRlKTsKLQkJfQotICAgIH0KKwlPUy5TZXRDb250cm9sMzJCaXRNaW5pbXVtIChoYW5kbGUsIG1pbmltdW0pOworCU9TLlNldENvbnRyb2wzMkJpdE1heGltdW0gKGhhbmRsZSwgbWF4aW11bSAtIHRodW1iKTsKKwlPUy5TZXRDb250cm9sVmlld1NpemUgKGhhbmRsZSwgdGh1bWIpOworCU9TLlNldENvbnRyb2wzMkJpdFZhbHVlIChoYW5kbGUsIHNlbGVjdGlvbik7CisJdGhpcy5pbmNyZW1lbnQgPSBpbmNyZW1lbnQ7CisJdGhpcy5wYWdlSW5jcmVtZW50ID0gcGFnZUluY3JlbWVudDsKIH0KIAotdm9pZCBpbnRlcm5hbFNldEJvdW5kcyhNYWNSZWN0IGJvdW5kcykgewotCU9TLlNldENvbnRyb2xCb3VuZHMoaGFuZGxlLCBib3VuZHMuZ2V0RGF0YSgpKTsKK3B1YmxpYyB2b2lkIHNldFZpc2libGUgKGJvb2xlYW4gdmlzaWJsZSkgeworCWNoZWNrV2lkZ2V0KCk7CisJaWYgKHZpc2libGUpIHsKKwkJaWYgKChzdGF0ZSAmIEhJRERFTikgPT0gMCkgcmV0dXJuOworCQlzdGF0ZSAmPSB+SElEREVOOworCX0gZWxzZSB7CisJCWlmICgoc3RhdGUgJiBISURERU4pICE9IDApIHJldHVybjsKKwkJc3RhdGUgfD0gSElEREVOOworCX0KKwlPUy5ISVZpZXdTZXRWaXNpYmxlIChoYW5kbGUsIHZpc2libGUpOworCXNlbmRFdmVudCAodmlzaWJsZSA/IFNXVC5TaG93IDogU1dULkhpZGUpOworCXBhcmVudC5sYXlvdXRDb250cm9sKCk7Cit9CisKK3ZvaWQgc2V0Wk9yZGVyICgpIHsKKwlPUy5ISVZpZXdBZGRTdWJ2aWV3IChwYXJlbnQuc2Nyb2xsZWRIYW5kbGUsIGhhbmRsZSk7CiB9CiAKIH0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9TY3JvbGxhYmxlLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvU2Nyb2xsYWJsZS5qYXZhCmluZGV4IGY1MTVkYmQuLmM1OGZhZGEgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9TY3JvbGxhYmxlLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1Njcm9sbGFibGUuamF2YQpAQCAtNyw0OTggKzcsMTg4IEBACiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCiAKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlJlY3Q7CisKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuKjsKIAotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIHRoZSBhYnN0cmFjdCBzdXBlcmNsYXNzIG9mIGFsbCBjbGFzc2VzIHdoaWNoCi0gKiByZXByZXNlbnQgY29udHJvbHMgdGhhdCBoYXZlIHN0YW5kYXJkIHNjcm9sbCBiYXJzLgotICogPGRsPgotICogPGR0PjxiPlN0eWxlczo8L2I+PC9kdD4KLSAqIDxkZD5IX1NDUk9MTCwgVl9TQ1JPTEw8L2RkPgotICogPGR0PjxiPkV2ZW50czo8L2I+Ci0gKiA8ZGQ+KG5vbmUpPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cD4KLSAqIElNUE9SVEFOVDogVGhpcyBjbGFzcyBpcyBpbnRlbmRlZCB0byBiZSBzdWJjbGFzc2VkIDxlbT5vbmx5PC9lbT4KLSAqIHdpdGhpbiB0aGUgU1dUIGltcGxlbWVudGF0aW9uLgotICogPC9wPgotICovCiBwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2Nyb2xsYWJsZSBleHRlbmRzIENvbnRyb2wgewotIAlpbnQgc2Nyb2xsZWRIYW5kbGUgLyogZm9ybUhhbmRsZSAqLzsKKyAJaW50IHNjcm9sbGVkSGFuZGxlOwogCWludCBoU2Nyb2xsQmFyLCB2U2Nyb2xsQmFyOwogCVNjcm9sbEJhciBob3Jpem9udGFsQmFyLCB2ZXJ0aWNhbEJhcjsKKwkKIFNjcm9sbGFibGUgKCkgewogCS8qIERvIG5vdGhpbmcgKi8KIH0KLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIGl0cyBwYXJlbnQKLSAqIGFuZCBhIHN0eWxlIHZhbHVlIGRlc2NyaWJpbmcgaXRzIGJlaGF2aW9yIGFuZCBhcHBlYXJhbmNlLgotICogPHA+Ci0gKiBUaGUgc3R5bGUgdmFsdWUgaXMgZWl0aGVyIG9uZSBvZiB0aGUgc3R5bGUgY29uc3RhbnRzIGRlZmluZWQgaW4KLSAqIGNsYXNzIDxjb2RlPlNXVDwvY29kZT4gd2hpY2ggaXMgYXBwbGljYWJsZSB0byBpbnN0YW5jZXMgb2YgdGhpcwotICogY2xhc3MsIG9yIG11c3QgYmUgYnVpbHQgYnkgPGVtPmJpdHdpc2UgT1I8L2VtPidpbmcgdG9nZXRoZXIgCi0gKiAodGhhdCBpcywgdXNpbmcgdGhlIDxjb2RlPmludDwvY29kZT4gInwiIG9wZXJhdG9yKSB0d28gb3IgbW9yZQotICogb2YgdGhvc2UgPGNvZGU+U1dUPC9jb2RlPiBzdHlsZSBjb25zdGFudHMuIFRoZSBjbGFzcyBkZXNjcmlwdGlvbgotICogbGlzdHMgdGhlIHN0eWxlIGNvbnN0YW50cyB0aGF0IGFyZSBhcHBsaWNhYmxlIHRvIHRoZSBjbGFzcy4KLSAqIFN0eWxlIGJpdHMgYXJlIGFsc28gaW5oZXJpdGVkIGZyb20gc3VwZXJjbGFzc2VzLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBjb21wb3NpdGUgY29udHJvbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZSAoY2Fubm90IGJlIG51bGwpCi0gKiBAcGFyYW0gc3R5bGUgdGhlIHN0eWxlIG9mIGNvbnRyb2wgdG8gY29uc3RydWN0Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcGFyZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHBhcmVudDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNXVCNIX1NDUk9MTAotICogQHNlZSBTV1QjVl9TQ1JPTEwKLSAqIEBzZWUgV2lkZ2V0I2NoZWNrU3ViY2xhc3MKLSAqIEBzZWUgV2lkZ2V0I2dldFN0eWxlCi0gKi8KKwogcHVibGljIFNjcm9sbGFibGUgKENvbXBvc2l0ZSBwYXJlbnQsIGludCBzdHlsZSkgewogCXN1cGVyIChwYXJlbnQsIHN0eWxlKTsKIH0KLS8qKgotICogR2l2ZW4gYSBkZXNpcmVkIDxlbT5jbGllbnQgYXJlYTwvZW0+IGZvciB0aGUgcmVjZWl2ZXIKLSAqIChhcyBkZXNjcmliZWQgYnkgdGhlIGFyZ3VtZW50cyksIHJldHVybnMgdGhlIGJvdW5kaW5nCi0gKiByZWN0YW5nbGUgd2hpY2ggd291bGQgYmUgcmVxdWlyZWQgdG8gcHJvZHVjZSB0aGF0IGNsaWVudAotICogYXJlYS4KLSAqIDxwPgotICogSW4gb3RoZXIgd29yZHMsIGl0IHJldHVybnMgYSByZWN0YW5nbGUgc3VjaCB0aGF0LCBpZiB0aGUKLSAqIHJlY2VpdmVyJ3MgYm91bmRzIHdlcmUgc2V0IHRvIHRoYXQgcmVjdGFuZ2xlLCB0aGUgYXJlYQotICogb2YgdGhlIHJlY2VpdmVyIHdoaWNoIGlzIGNhcGFibGUgb2YgZGlzcGxheWluZyBkYXRhCi0gKiAodGhhdCBpcywgbm90IGNvdmVyZWQgYnkgdGhlICJ0cmltbWluZ3MiKSB3b3VsZCBiZSB0aGUKLSAqIHJlY3RhbmdsZSBkZXNjcmliZWQgYnkgdGhlIGFyZ3VtZW50cyAocmVsYXRpdmUgdG8gdGhlCi0gKiByZWNlaXZlcidzIHBhcmVudCkuCi0gKiA8L3A+Ci0gKiAKLSAqIEByZXR1cm4gdGhlIHJlcXVpcmVkIGJvdW5kcyB0byBwcm9kdWNlIHRoZSBnaXZlbiBjbGllbnQgYXJlYQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNnZXRDbGllbnRBcmVhCi0gKi8KKwogcHVibGljIFJlY3RhbmdsZSBjb21wdXRlVHJpbSAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKIAljaGVja1dpZGdldCgpOwotCWludCBib3JkZXIgPSBnZXRCb3JkZXJXaWR0aCAoKTsKLQlpbnQgdHJpbVggPSB4IC0gYm9yZGVyLCB0cmltWSA9IHkgLSBib3JkZXI7Ci0JaW50IHRyaW1XaWR0aCA9IHdpZHRoICsgKGJvcmRlciAqIDIpLCB0cmltSGVpZ2h0ID0gaGVpZ2h0ICsgKGJvcmRlciAqIDIpOwotCWlmIChob3Jpem9udGFsQmFyICE9IG51bGwpIHsKLQkJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKLQkJdHJpbVkgLT0gZGlzcGxheS5zY3JvbGxlZEluc2V0WTsKLQkJdHJpbUhlaWdodCArPSBkaXNwbGF5LnNjcm9sbGVkSW5zZXRZICsgZGlzcGxheS5zY3JvbGxlZE1hcmdpblk7Ci0JCWlmICh2ZXJ0aWNhbEJhciA9PSBudWxsKSB7Ci0JCQl0cmltWCAtPSBkaXNwbGF5LnNjcm9sbGVkSW5zZXRYOwotCQkJdHJpbVdpZHRoICs9IGRpc3BsYXkuc2Nyb2xsZWRJbnNldFggKiAyOwotCQkJdHJpbUhlaWdodCAtPSBkaXNwbGF5LnNjcm9sbGVkSW5zZXRZICogMjsKLQkJfQotCX0KLQlpZiAodmVydGljYWxCYXIgIT0gbnVsbCkgewotCQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOwotCQl0cmltWCAtPSBkaXNwbGF5LnNjcm9sbGVkSW5zZXRYOwotCQl0cmltV2lkdGggKz0gZGlzcGxheS5zY3JvbGxlZEluc2V0WCArIGRpc3BsYXkuc2Nyb2xsZWRNYXJnaW5YOwotCQlpZiAoaG9yaXpvbnRhbEJhciA9PSBudWxsKSB7Ci0JCQl0cmltWSAtPSBkaXNwbGF5LnNjcm9sbGVkSW5zZXRZOwotCQkJdHJpbUhlaWdodCArPSBkaXNwbGF5LnNjcm9sbGVkSW5zZXRZICogMjsKLQkJCXRyaW1XaWR0aCAtPSBkaXNwbGF5LnNjcm9sbGVkSW5zZXRYICogMjsKLQkJfQotCX0KLQlyZXR1cm4gbmV3IFJlY3RhbmdsZSAodHJpbVgsIHRyaW1ZLCB0cmltV2lkdGgsIHRyaW1IZWlnaHQpOworCWludCBbXSBvdXRNZXRyaWMgPSBuZXcgaW50IFsxXTsKKwlPUy5HZXRUaGVtZU1ldHJpYyAoT1Mua1RoZW1lTWV0cmljU2Nyb2xsQmFyV2lkdGgsIG91dE1ldHJpYyk7CisJaWYgKGhvcml6b250YWxCYXIgIT0gbnVsbCkgaGVpZ2h0ICs9IG91dE1ldHJpYyBbMF07CisJaWYgKHZlcnRpY2FsQmFyICE9IG51bGwpIHdpZHRoICs9IG91dE1ldHJpYyBbMF07CisJUmVjdCBpbnNldCA9IGluc2V0ICgpOworCXggLT0gaW5zZXQubGVmdDsKKwl5IC09IGluc2V0LnRvcDsKKwl3aWR0aCArPSBpbnNldC5sZWZ0ICsgaW5zZXQucmlnaHQ7CisJaGVpZ2h0ICs9IGluc2V0LnRvcCArIGluc2V0LmJvdHRvbTsKKwlyZXR1cm4gbmV3IFJlY3RhbmdsZSAoeCwgeSwgd2lkdGgsIGhlaWdodCk7CiB9CisKIFNjcm9sbEJhciBjcmVhdGVTY3JvbGxCYXIgKGludCB0eXBlKSB7CiAgICAgcmV0dXJuIG5ldyBTY3JvbGxCYXIgKHRoaXMsIHR5cGUpOwogfQorCiBTY3JvbGxCYXIgY3JlYXRlU3RhbmRhcmRCYXIgKGludCBzdHlsZSkgewotCWlmIChzY3JvbGxlZEhhbmRsZSA9PSAwKSByZXR1cm4gbnVsbDsKKwlzaG9ydCBbXSBjb3VudCA9IG5ldyBzaG9ydCBbMV07CisJT1MuQ291bnRTdWJDb250cm9scyAoaGFuZGxlLCBjb3VudCk7CisJaWYgKGNvdW50IFswXSA9PSAwKSByZXR1cm4gbnVsbDsKKwlpbnQgW10gb3V0Q29udHJvbCA9IG5ldyBpbnQgWzFdOworCWludCBpbmRleCA9IChzdHlsZSAmIFNXVC5IT1JJWk9OVEFMKSAhPSAwID8gMSA6IDI7CisJaW50IHN0YXR1cyA9IE9TLkdldEluZGV4ZWRTdWJDb250cm9sIChoYW5kbGUsIChzaG9ydClpbmRleCwgb3V0Q29udHJvbCk7CisJaWYgKHN0YXR1cyAhPSBPUy5ub0VycikgcmV0dXJuIG51bGw7CiAJU2Nyb2xsQmFyIGJhciA9IG5ldyBTY3JvbGxCYXIgKCk7CiAJYmFyLnBhcmVudCA9IHRoaXM7CiAJYmFyLnN0eWxlID0gc3R5bGU7Ci0JYmFyLnN0YXRlIHw9IEhBTkRMRTsKLQlTeXN0ZW0ub3V0LnByaW50bG4oIlNjcm9sbGFibGUuY3JlYXRlU3RhbmRhcmRCYXI6IG55aSIpOwotICAgIC8qIEFXCi0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1OaG9yaXpvbnRhbFNjcm9sbEJhciwgMCwgT1MuWG1OdmVydGljYWxTY3JvbGxCYXIsIDB9OwotCU9TLlh0R2V0VmFsdWVzIChzY3JvbGxlZEhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlpZiAoc3R5bGUgPT0gU1dULkhfU0NST0xMKSBiYXIuaGFuZGxlID0gYXJnTGlzdCBbMV07Ci0JaWYgKHN0eWxlID09IFNXVC5WX1NDUk9MTCkgYmFyLmhhbmRsZSA9IGFyZ0xpc3QgWzNdOwotICAgICovCi0JYmFyLmhvb2tFdmVudHMgKCk7CisJYmFyLmhhbmRsZSA9IG91dENvbnRyb2wgWzBdOwogCWJhci5yZWdpc3RlciAoKTsKKwliYXIuaG9va0V2ZW50cyAoKTsKIAlyZXR1cm4gYmFyOwogfQotdm9pZCBjcmVhdGVXaWRnZXQgKGludCBpbmRleCkgewotCXN1cGVyLmNyZWF0ZVdpZGdldCAoaW5kZXgpOworCit2b2lkIGNyZWF0ZVdpZGdldCAoKSB7CisJc3VwZXIuY3JlYXRlV2lkZ2V0ICgpOwogCWlmICgoc3R5bGUgJiBTV1QuSF9TQ1JPTEwpICE9IDApIGhvcml6b250YWxCYXIgPSBjcmVhdGVTY3JvbGxCYXIgKFNXVC5IX1NDUk9MTCk7CiAJaWYgKChzdHlsZSAmIFNXVC5WX1NDUk9MTCkgIT0gMCkgdmVydGljYWxCYXIgPSBjcmVhdGVTY3JvbGxCYXIgKFNXVC5WX1NDUk9MTCk7CiB9CisKIHZvaWQgZGVyZWdpc3RlciAoKSB7CiAJc3VwZXIuZGVyZWdpc3RlciAoKTsKLSAgICAvKiBBVwotCWlmIChmb3JtSGFuZGxlICE9IDApIFdpZGdldFRhYmxlLnJlbW92ZSAoZm9ybUhhbmRsZSk7Ci0gICAgKi8KIAlpZiAoc2Nyb2xsZWRIYW5kbGUgIT0gMCkgV2lkZ2V0VGFibGUucmVtb3ZlIChzY3JvbGxlZEhhbmRsZSk7CiB9Ci0vKiBBVwotdm9pZCBlbmFibGVXaWRnZXQgKGJvb2xlYW4gZW5hYmxlZCkgewotCXN1cGVyLmVuYWJsZVdpZGdldCAoZW5hYmxlZCk7Ci0JaWYgKGZvcm1IYW5kbGUgIT0gMCkgZW5hYmxlSGFuZGxlIChlbmFibGVkLCBmb3JtSGFuZGxlKTsKLQlpZiAoc2Nyb2xsZWRIYW5kbGUgIT0gMCkgewotCQllbmFibGVIYW5kbGUgKGVuYWJsZWQsIHNjcm9sbGVkSGFuZGxlKTsKLQkJaW50IFtdIGFyZ0xpc3QgPSB7Ci0JCQlPUy5YbU5ob3Jpem9udGFsU2Nyb2xsQmFyLCAwLAotCQkJT1MuWG1OdmVydGljYWxTY3JvbGxCYXIsIDAsCi0JCX07Ci0JCU9TLlh0R2V0VmFsdWVzIChzY3JvbGxlZEhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQkJaWYgKGFyZ0xpc3QgWzFdICE9IDApIGVuYWJsZUhhbmRsZSAoZW5hYmxlZCwgYXJnTGlzdCBbMV0pOwotCQlpZiAoYXJnTGlzdCBbM10gIT0gMCkgZW5hYmxlSGFuZGxlIChlbmFibGVkLCBhcmdMaXN0IFszXSk7Ci0JfQotfQotKi8KLS8qKgotICogUmV0dXJucyBhIHJlY3RhbmdsZSB3aGljaCBkZXNjcmliZXMgdGhlIGFyZWEgb2YgdGhlCi0gKiByZWNlaXZlciB3aGljaCBpcyBjYXBhYmxlIG9mIGRpc3BsYXlpbmcgZGF0YSAodGhhdCBpcywKLSAqIG5vdCBjb3ZlcmVkIGJ5IHRoZSAidHJpbW1pbmdzIikuCi0gKiAKLSAqIEByZXR1cm4gdGhlIGNsaWVudCBhcmVhCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI2NvbXB1dGVUcmltCi0gKi8KKwogcHVibGljIFJlY3RhbmdsZSBnZXRDbGllbnRBcmVhICgpIHsKIAljaGVja1dpZGdldCgpOwotICAgIC8qIEFXCi0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1Od2lkdGgsIDAsIE9TLlhtTmhlaWdodCwgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlyZXR1cm4gbmV3IFJlY3RhbmdsZSAoMCwgMCwgYXJnTGlzdCBbMV0sIGFyZ0xpc3QgWzNdKTsKLSAgICAqLwotCU1hY1JlY3QgYm91bmRzPSBuZXcgTWFjUmVjdCgpOwotCU9TLkdldENvbnRyb2xCb3VuZHMoaGFuZGxlLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQlSZWN0YW5nbGUgcj0gbmV3IFJlY3RhbmdsZSAoMCwgMCwgYm91bmRzLmdldFdpZHRoKCksIGJvdW5kcy5nZXRIZWlnaHQoKSk7Ci0JLyoKLQlpZiAoci5pc0VtcHR5KCkpIHsKLQkJU3lzdGVtLm91dC5wcmludGxuKCJTY3JvbGxhYmxlLmdldENsaWVudEFyZWEoIiArIHRoaXMgKyAiKTogIiArIHIpOwotCQkvL25ldyBFeGNlcHRpb24oKS5wcmludFN0YWNrVHJhY2UoKTsKLQl9Ci0JKi8KLQlyZXR1cm4gcjsKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChoYW5kbGUsIHJlY3QpOworCXJldHVybiBuZXcgUmVjdGFuZ2xlICgwLCAwLCByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0LCByZWN0LmJvdHRvbSAtIHJlY3QudG9wKTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgcmVjZWl2ZXIncyBob3Jpem9udGFsIHNjcm9sbCBiYXIgaWYgaXQgaGFzCi0gKiBvbmUsIGFuZCBudWxsIGlmIGl0IGRvZXMgbm90LgotICoKLSAqIEByZXR1cm4gdGhlIGhvcml6b250YWwgc2Nyb2xsIGJhciAob3IgbnVsbCkKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIFNjcm9sbEJhciBnZXRIb3Jpem9udGFsQmFyICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBob3Jpem9udGFsQmFyOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSByZWNlaXZlcidzIHZlcnRpY2FsIHNjcm9sbCBiYXIgaWYgaXQgaGFzCi0gKiBvbmUsIGFuZCBudWxsIGlmIGl0IGRvZXMgbm90LgotICoKLSAqIEByZXR1cm4gdGhlIHZlcnRpY2FsIHNjcm9sbCBiYXIgKG9yIG51bGwpCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBTY3JvbGxCYXIgZ2V0VmVydGljYWxCYXIgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIHZlcnRpY2FsQmFyOwogfQotYm9vbGVhbiBpc1RhYkdyb3VwICgpIHsKLQlpZiAoKHN0YXRlICYgQ0FOVkFTKSAhPSAwKSByZXR1cm4gdHJ1ZTsKLQlyZXR1cm4gc3VwZXIuaXNUYWJHcm91cCAoKTsKKworYm9vbGVhbiBoYXNCb3JkZXIgKCkgeworCXJldHVybiAoc3R5bGUgJiBTV1QuQk9SREVSKSAhPSAwOwogfQotdm9pZCBtYW5hZ2VDaGlsZHJlbiAoKSB7Ci0gICAgLyogQVcKLQlpZiAoc2Nyb2xsZWRIYW5kbGUgIT0gMCkgewotCQlPUy5YdFNldE1hcHBlZFdoZW5NYW5hZ2VkIChzY3JvbGxlZEhhbmRsZSwgZmFsc2UpOwotCQlPUy5YdE1hbmFnZUNoaWxkIChzY3JvbGxlZEhhbmRsZSk7Ci0JfQotCWlmIChmb3JtSGFuZGxlICE9IDApIHsKLQkJT1MuWHRTZXRNYXBwZWRXaGVuTWFuYWdlZCAoZm9ybUhhbmRsZSwgZmFsc2UpOwotCQlPUy5YdE1hbmFnZUNoaWxkIChmb3JtSGFuZGxlKTsKLQl9Ci0gICAgKi8KLQlzdXBlci5tYW5hZ2VDaGlsZHJlbiAoKTsKLSAgICAvKiBBVwotCWlmIChmb3JtSGFuZGxlICE9IDApIHsKLQkJaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1OYm9yZGVyV2lkdGgsIDB9OwotCQlPUy5YdEdldFZhbHVlcyAoZm9ybUhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQkJT1MuWHRSZXNpemVXaWRnZXQgKGZvcm1IYW5kbGUsIDEsIDEsIGFyZ0xpc3QgWzFdKTsKLQkJT1MuWHRTZXRNYXBwZWRXaGVuTWFuYWdlZCAoZm9ybUhhbmRsZSwgdHJ1ZSk7Ci0JfQotCWlmIChzY3JvbGxlZEhhbmRsZSAhPSAwKSB7Ci0JCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTmJvcmRlcldpZHRoLCAwfTsKLQkJT1MuWHRHZXRWYWx1ZXMgKHNjcm9sbGVkSGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCQlPUy5YdFJlc2l6ZVdpZGdldCAoc2Nyb2xsZWRIYW5kbGUsIDEsIDEsIGFyZ0xpc3QgWzFdKTsKLQkJT1MuWHRTZXRNYXBwZWRXaGVuTWFuYWdlZCAoc2Nyb2xsZWRIYW5kbGUsIHRydWUpOwotCX0KLSAgICAqLwotfQotLyogQVcKLXZvaWQgcHJvcGFnYXRlV2lkZ2V0IChib29sZWFuIGVuYWJsZWQpIHsKLQlzdXBlci5wcm9wYWdhdGVXaWRnZXQgKGVuYWJsZWQpOwotCWlmIChmb3JtSGFuZGxlICE9IDApIHByb3BhZ2F0ZUhhbmRsZSAoZW5hYmxlZCwgZm9ybUhhbmRsZSk7Ci0JaWYgKHNjcm9sbGVkSGFuZGxlICE9IDApIHsKLQkJcHJvcGFnYXRlSGFuZGxlIChlbmFibGVkLCBzY3JvbGxlZEhhbmRsZSk7Ci0JCWludCBbXSBhcmdMaXN0ID0gewotCQkJT1MuWG1OaG9yaXpvbnRhbFNjcm9sbEJhciwgMCwKLQkJCU9TLlhtTnZlcnRpY2FsU2Nyb2xsQmFyLCAwLAorCit2b2lkIGhvb2tFdmVudHMgKCkgeworCXN1cGVyLmhvb2tFdmVudHMgKCk7CisJaWYgKChzdGF0ZSAmIENBTlZBUykgIT0gMCAmJiBzY3JvbGxlZEhhbmRsZSAhPSAwKSB7CisJCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisJCWludCBjb250cm9sUHJvYyA9IGRpc3BsYXkuY29udHJvbFByb2M7CisJCWludCBbXSBtYXNrID0gbmV3IGludCBbXSB7CisJCQlPUy5rRXZlbnRDbGFzc0NvbnRyb2wsIE9TLmtFdmVudENvbnRyb2xEcmF3LAogCQl9OwotCQlPUy5YdEdldFZhbHVlcyAoc2Nyb2xsZWRIYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JCWlmIChhcmdMaXN0IFsxXSAhPSAwKSBwcm9wYWdhdGVIYW5kbGUgKGVuYWJsZWQsIGFyZ0xpc3QgWzFdKTsKLQkJaWYgKGFyZ0xpc3QgWzNdICE9IDApIHByb3BhZ2F0ZUhhbmRsZSAoZW5hYmxlZCwgYXJnTGlzdCBbM10pOworCQlpbnQgY29udHJvbFRhcmdldCA9IE9TLkdldENvbnRyb2xFdmVudFRhcmdldCAoc2Nyb2xsZWRIYW5kbGUpOworCQlPUy5JbnN0YWxsRXZlbnRIYW5kbGVyIChjb250cm9sVGFyZ2V0LCBjb250cm9sUHJvYywgbWFzay5sZW5ndGggLyAyLCBtYXNrLCBzY3JvbGxlZEhhbmRsZSwgbnVsbCk7CiAJfQogfQotKi8KKworYm9vbGVhbiBob29rc0tleXMgKCkgeworCXJldHVybiBob29rcyAoU1dULktleURvd24pIHx8IGhvb2tzIChTV1QuS2V5VXApIHx8IGhvb2tzIChTV1QuVHJhdmVyc2UpOworfQorCitSZWN0IGluc2V0ICgpIHsKKwlpZiAoKHN0YXRlICYgQ0FOVkFTKSAhPSAwKSB7CisJCVJlY3QgcmVjdCA9IG5ldyBSZWN0ICgpOworCQlpbnQgW10gb3V0TWV0cmljID0gbmV3IGludCBbMV07CisJCWlmICgoc3R5bGUgJiBTV1QuTk9fRk9DVVMpID09IDAgJiYgaG9va3NLZXlzICgpKSB7CisJCQlPUy5HZXRUaGVtZU1ldHJpYyAoT1Mua1RoZW1lTWV0cmljRm9jdXNSZWN0T3V0c2V0LCBvdXRNZXRyaWMpOworCQkJcmVjdC5sZWZ0ICs9IG91dE1ldHJpYyBbMF07CisJCQlyZWN0LnRvcCArPSBvdXRNZXRyaWMgWzBdOworCQkJcmVjdC5yaWdodCArPSBvdXRNZXRyaWMgWzBdOworCQkJcmVjdC5ib3R0b20gKz0gb3V0TWV0cmljIFswXTsKKwkJfQorCQlpZiAoaGFzQm9yZGVyICgpKSB7CisJCQlPUy5HZXRUaGVtZU1ldHJpYyAoT1Mua1RoZW1lTWV0cmljRWRpdFRleHRGcmFtZU91dHNldCwgb3V0TWV0cmljKTsKKwkJCXJlY3QubGVmdCArPSBvdXRNZXRyaWMgWzBdOworCQkJcmVjdC50b3AgKz0gb3V0TWV0cmljIFswXTsKKwkJCXJlY3QucmlnaHQgKz0gb3V0TWV0cmljIFswXTsKKwkJCXJlY3QuYm90dG9tICs9IG91dE1ldHJpYyBbMF07CisJCX0KKwkJcmV0dXJuIHJlY3Q7CisJfQorCXJldHVybiBFTVBUWV9SRUNUOworfSAKKwordm9pZCBsYXlvdXRDb250cm9sICgpIHsKKwlpZiAoc2Nyb2xsZWRIYW5kbGUgIT0gMCkgeworCQlpbnQgdldpZHRoID0gMCwgaEhlaWdodCA9IDA7CisJCWludCBbXSBvdXRNZXRyaWMgPSBuZXcgaW50IFsxXTsKKwkJT1MuR2V0VGhlbWVNZXRyaWMgKE9TLmtUaGVtZU1ldHJpY1Njcm9sbEJhcldpZHRoLCBvdXRNZXRyaWMpOworCQlib29sZWFuIGlzVmlzaWJsZUhCYXIgPSBob3Jpem9udGFsQmFyICE9IG51bGwgJiYgaG9yaXpvbnRhbEJhci5nZXRWaXNpYmxlICgpOworCQlib29sZWFuIGlzVmlzaWJsZVZCYXIgPSB2ZXJ0aWNhbEJhciAhPSBudWxsICYmIHZlcnRpY2FsQmFyLmdldFZpc2libGUgKCk7CisJCWlmIChpc1Zpc2libGVIQmFyKSBoSGVpZ2h0ID0gb3V0TWV0cmljIFswXTsKKwkJaWYgKGlzVmlzaWJsZVZCYXIpIHZXaWR0aCA9IG91dE1ldHJpYyBbMF07CisJCVJlY3QgcmVjdCA9IG5ldyBSZWN0ICgpOworCQlPUy5HZXRDb250cm9sQm91bmRzIChzY3JvbGxlZEhhbmRsZSwgcmVjdCk7CisJCVJlY3QgaW5zZXQgPSBpbnNldCAoKTsKKwkJaW50IHdpZHRoID0gTWF0aC5tYXggKDAsIHJlY3QucmlnaHQgLSByZWN0LmxlZnQgLSB2V2lkdGggLSBpbnNldC5sZWZ0IC0gaW5zZXQucmlnaHQpOworCQlpbnQgaGVpZ2h0ID0gTWF0aC5tYXggKDAsIHJlY3QuYm90dG9tIC0gcmVjdC50b3AgLSBoSGVpZ2h0IC0gaW5zZXQudG9wIC0gaW5zZXQuYm90dG9tKTsKKwkJaWYgKGlzVmlzaWJsZUhCYXIpIHsKKwkJCXNldEJvdW5kcyAoaG9yaXpvbnRhbEJhci5oYW5kbGUsIGluc2V0LmxlZnQsIGluc2V0LnRvcCArIGhlaWdodCwgd2lkdGgsIGhIZWlnaHQsIHRydWUsIHRydWUsIGZhbHNlKTsKKwkJfQorCQlpZiAoaXNWaXNpYmxlVkJhcikgeworCQkJc2V0Qm91bmRzICh2ZXJ0aWNhbEJhci5oYW5kbGUsIGluc2V0LmxlZnQgKyB3aWR0aCwgaW5zZXQudG9wLCB2V2lkdGgsIGhlaWdodCwgdHJ1ZSwgdHJ1ZSwgZmFsc2UpOworCQl9CisJCXNldEJvdW5kcyAoaGFuZGxlLCBpbnNldC5sZWZ0LCBpbnNldC50b3AsIHdpZHRoLCBoZWlnaHQsIHRydWUsIHRydWUsIGZhbHNlKTsKKwl9CQorfQorCiB2b2lkIHJlZ2lzdGVyICgpIHsKIAlzdXBlci5yZWdpc3RlciAoKTsKLSAgICAvKiBBVwotCWlmIChmb3JtSGFuZGxlICE9IDApIFdpZGdldFRhYmxlLnB1dCAoZm9ybUhhbmRsZSwgdGhpcyk7Ci0gICAgKi8KIAlpZiAoc2Nyb2xsZWRIYW5kbGUgIT0gMCkgV2lkZ2V0VGFibGUucHV0IChzY3JvbGxlZEhhbmRsZSwgdGhpcyk7CiB9CisKIHZvaWQgcmVsZWFzZUhhbmRsZSAoKSB7CiAJc3VwZXIucmVsZWFzZUhhbmRsZSAoKTsKLQlzY3JvbGxlZEhhbmRsZSA9IC8qIEFXIGZvcm1IYW5kbGUgPSAqLyAwOworCXNjcm9sbGVkSGFuZGxlID0gMDsKIH0KKwogdm9pZCByZWxlYXNlV2lkZ2V0ICgpIHsKLQlpZiAoaG9yaXpvbnRhbEJhciAhPSBudWxsKSB7Ci0JCWhvcml6b250YWxCYXIucmVsZWFzZVdpZGdldCAoKTsKLQkJaG9yaXpvbnRhbEJhci5yZWxlYXNlSGFuZGxlICgpOwotCX0KLQlpZiAodmVydGljYWxCYXIgIT0gbnVsbCkgewotCQl2ZXJ0aWNhbEJhci5yZWxlYXNlV2lkZ2V0ICgpOwotCQl2ZXJ0aWNhbEJhci5yZWxlYXNlSGFuZGxlICgpOwotCX0KKwlpZiAoaG9yaXpvbnRhbEJhciAhPSBudWxsKSBob3Jpem9udGFsQmFyLnJlbGVhc2VSZXNvdXJjZXMgKCk7CisJaWYgKHZlcnRpY2FsQmFyICE9IG51bGwpIHZlcnRpY2FsQmFyLnJlbGVhc2VSZXNvdXJjZXMgKCk7CiAJaG9yaXpvbnRhbEJhciA9IHZlcnRpY2FsQmFyID0gbnVsbDsKIAlzdXBlci5yZWxlYXNlV2lkZ2V0ICgpOwogfQotLyogQVcKLXZvaWQgc2V0QmFja2dyb3VuZFBpeGVsIChpbnQgcGl4ZWwpIHsKLQlzdXBlci5zZXRCYWNrZ3JvdW5kUGl4ZWwgKHBpeGVsKTsKLQlpZiAoc2Nyb2xsZWRIYW5kbGUgIT0gMCkgewotCQlpbnQgW10gYXJnTGlzdDEgPSB7Ci0JCQlPUy5YbU5ob3Jpem9udGFsU2Nyb2xsQmFyLCAwLAotCQkJT1MuWG1OdmVydGljYWxTY3JvbGxCYXIsIDAsCi0JCX07Ci0JCU9TLlh0R2V0VmFsdWVzIChzY3JvbGxlZEhhbmRsZSwgYXJnTGlzdDEsIGFyZ0xpc3QxLmxlbmd0aCAvIDIpOwotCQlpZiAoYXJnTGlzdDEgWzFdICE9IDApIE9TLlhtQ2hhbmdlQ29sb3IgKGFyZ0xpc3QxIFsxXSwgcGl4ZWwpOwotCQlpZiAoYXJnTGlzdDEgWzNdICE9IDApIE9TLlhtQ2hhbmdlQ29sb3IgKGFyZ0xpc3QxIFszXSwgcGl4ZWwpOworCitpbnQgc2V0Qm91bmRzIChpbnQgY29udHJvbCwgaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGJvb2xlYW4gbW92ZSwgYm9vbGVhbiByZXNpemUsIGJvb2xlYW4gZXZlbnRzKSB7CisJaW50IHJlc3VsdCA9IHN1cGVyLnNldEJvdW5kcyhjb250cm9sLCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCBtb3ZlLCByZXNpemUsIGZhbHNlKTsKKwlpZiAoKHJlc3VsdCAmIE1PVkVEKSAhPSAwKSB7CisJCWlmIChldmVudHMpIHNlbmRFdmVudCAoU1dULk1vdmUpOwogCX0KKwlpZiAoKHJlc3VsdCAmIFJFU0laRUQpICE9IDApIHsKKwkJaWYgKGNvbnRyb2wgPT0gc2Nyb2xsZWRIYW5kbGUpIGxheW91dENvbnRyb2wgKCk7CisJCWlmIChldmVudHMpIHNlbmRFdmVudCAoU1dULlJlc2l6ZSk7CisJfQorCXJldHVybiByZXN1bHQ7CiB9Ci0qLworCiBpbnQgdG9wSGFuZGxlICgpIHsKIAlpZiAoc2Nyb2xsZWRIYW5kbGUgIT0gMCkgcmV0dXJuIHNjcm9sbGVkSGFuZGxlOwotICAgIC8qIEFXCi0JaWYgKGZvcm1IYW5kbGUgIT0gMCkgcmV0dXJuIGZvcm1IYW5kbGU7Ci0gICAgKi8KIAlyZXR1cm4gaGFuZGxlOwogfQogCi0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi0vLyBNYWMgU3R1ZmYKLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotCWludCBjcmVhdGVTY3JvbGxWaWV3KGludCBwYXJlbnRDb250cm9sSGFuZGxlLCBpbnQgc3R5bGUpIHsKLQkKLQkJRGlzcGxheSBkaXNwbGF5PSBnZXREaXNwbGF5KCk7Ci0JCQotCQlpbnQgcG9zPSAtMTsKLQkKLQkJaWYgKE9TLklzVmFsaWRDb250cm9sSGFuZGxlKHBhcmVudENvbnRyb2xIYW5kbGUpKSB7Ci0JCX0gZWxzZSBpZiAoT1MuSXNWYWxpZFdpbmRvd1B0cihwYXJlbnRDb250cm9sSGFuZGxlKSkgewotCQkJaW50W10gcm9vdD0gbmV3IGludFsxXTsKLQkJCWlmIChPUy5DcmVhdGVSb290Q29udHJvbChwYXJlbnRDb250cm9sSGFuZGxlLCByb290KSA9PSBPUy5rTm9FcnIpIHsKLQkJCQkvL09TLkdldFJvb3RDb250cm9sKHBhcmVudENvbnRyb2xIYW5kbGUsIHJvb3QpOwotCQkJCXBhcmVudENvbnRyb2xIYW5kbGU9IHJvb3RbMF07Ci0JCQl9IGVsc2UgewotCQkJCU9TLkhJVmlld0ZpbmRCeUlEKE9TLkhJVmlld0dldFJvb3QocGFyZW50Q29udHJvbEhhbmRsZSksIDAsIHJvb3QpOwotCQkJCXBhcmVudENvbnRyb2xIYW5kbGU9IHJvb3RbMF07Ci0JCQkJcG9zPSAtMTsJLy8gYmVsb3cgZ3Jvd2JveAotCQkJfQotCQl9IGVsc2UKLQkJCVN5c3RlbS5vdXQucHJpbnRsbigiY3JlYXRlU2Nyb2xsVmlldzogc2hvdWxkbid0IGhhcHBlbiIpOwotCQotCQlpbnQgY29udHJvbEhhbmRsZSA9IE1hY1V0aWwuY3JlYXRlRHJhd2luZ0FyZWEocGFyZW50Q29udHJvbEhhbmRsZSwgcG9zLCB0cnVlLCAwLCAwLCAwKTsKLQkJCi0JCS8qCi0JCU9TLkluc3RhbGxFdmVudEhhbmRsZXIoT1MuR2V0Q29udHJvbEV2ZW50VGFyZ2V0KGNvbnRyb2xIYW5kbGUpLCBkaXNwbGF5LmZDb250cm9sUHJvYywgCi0JCQluZXcgaW50W10gewotCQkJCU9TLmtFdmVudENsYXNzQ29udHJvbCwgT1Mua0V2ZW50Q29udHJvbEJvdW5kc0NoYW5nZWQKLQkJCX0sCi0JCQljb250cm9sSGFuZGxlCi0JCSk7Ci0JCSovCi0JCi0JCWlmICgoc3R5bGUgJiBTV1QuSF9TQ1JPTEwpICE9IDApIHsKLQkJCWludCBocz0gTWFjVXRpbC5uZXdDb250cm9sKGNvbnRyb2xIYW5kbGUsIChzaG9ydCkwLCAoc2hvcnQpMCwgKHNob3J0KTEwMCwgT1Mua0NvbnRyb2xTY3JvbGxCYXJMaXZlUHJvYyk7Ci0JCQlPUy5TZXRDb250cm9sQWN0aW9uKGhzLCBkaXNwbGF5LmZDb250cm9sQWN0aW9uUHJvYyk7Ci0JCQloU2Nyb2xsQmFyPSBoczsKLQkJfQotCi0JCWlmICgoc3R5bGUgJiBTV1QuVl9TQ1JPTEwpICE9IDApIHsKLQkJCWludCB2cz0gTWFjVXRpbC5uZXdDb250cm9sKGNvbnRyb2xIYW5kbGUsIChzaG9ydCkwLCAoc2hvcnQpMCwgKHNob3J0KTEwMCwgT1Mua0NvbnRyb2xTY3JvbGxCYXJMaXZlUHJvYyk7Ci0JCQlPUy5TZXRDb250cm9sQWN0aW9uKHZzLCBkaXNwbGF5LmZDb250cm9sQWN0aW9uUHJvYyk7Ci0JCQl2U2Nyb2xsQmFyPSB2czsKLQkJfQotCQkJCQotCQlyZXR1cm4gY29udHJvbEhhbmRsZTsKLQl9Ci0KLQkvKioKLQkgKiBPdmVycmlkZGVuIGZyb20gQ29udHJvbC4KLQkgKiB4IGFuZCB5IGFyZSByZWxhdGl2ZSB0byB3aW5kb3chCi0JICovCi0Jdm9pZCBoYW5kbGVSZXNpemUoaW50IGhhbmRsZSwgTWFjUmVjdCBib3VuZHMpIHsKLQkJc3VwZXIuaGFuZGxlUmVzaXplKGhhbmRsZSwgYm91bmRzKTsKLQkJcmVsYXlvdXQxMjMoKTsKLQl9Ci0JCi0Jdm9pZCByZWxheW91dDEyMygpIHsKLQkJaWYgKE1hY1V0aWwuSElWSUVXKQotCQkJbmV3UmVsYXlvdXQoKTsKLQkJZWxzZQotCQkJb2xkUmVsYXlvdXQoKTsKLQl9Ci0JCi0JcHJpdmF0ZSB2b2lkIG5ld1JlbGF5b3V0KCkgewotCQkKLQkJaW50IGhuZGw9IHNjcm9sbGVkSGFuZGxlOwotCQlpZiAoaG5kbCA9PSAwKQotCQkJcmV0dXJuOwotCQkKLQkJTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JCU9TLkdldENvbnRyb2xCb3VuZHMoaG5kbCwgYm91bmRzLmdldERhdGEoKSk7Ci0JCQotCQlib29sZWFuIHZpc2libGU9IE9TLklzQ29udHJvbFZpc2libGUoaG5kbCk7Ci0JCQotCQlpbnQgeD0gMDsgLy8gYm91bmRzLmdldFgoKTsKLQkJaW50IHk9IDA7IC8vIGJvdW5kcy5nZXRZKCk7Ci0JCWludCB3PSBib3VuZHMuZ2V0V2lkdGgoKTsKLQkJaW50IGg9IGJvdW5kcy5nZXRIZWlnaHQoKTsKLQkKLQkJaW50IHM9IDE1OwotCQlpbnQgd3c9IHc7Ci0JCWludCBoaD0gaDsKLQkJaW50IHN0eWxlPSBnZXRTdHlsZSgpOwotCi0JCWlmICh3dyA8IDAgfHwgaGggPCAwKSB7Ci0JCQlTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqKiogU2Nyb2xsYWJsZS5uZXdSZWxheW91dDogIiArIHd3ICsgIiAiICsgaGgpOwotCQkJcmV0dXJuOwotCQl9Ci0JCQotCQlTY3JvbGxCYXIgaHNiPSBudWxsOwotCQlpZiAoKHN0eWxlICYgU1dULkhfU0NST0xMKSAhPSAwKSB7Ci0JCQloc2I9IGdldEhvcml6b250YWxCYXIoKTsKLQkJCWlmIChoc2IgIT0gbnVsbCkgewotCQkJCWlmICh2aXNpYmxlICYmICFPUy5Jc0NvbnRyb2xWaXNpYmxlKGhzYi5oYW5kbGUpKQotCQkJCQk7Ci0JCQkJZWxzZQotCQkJCQloaC09IHM7Ci0JCQl9Ci0JCX0KLQotCQlTY3JvbGxCYXIgdnNiPSBudWxsOwotCQlpZiAoKHN0eWxlICYgU1dULlZfU0NST0xMKSAhPSAwKSB7Ci0JCQl2c2I9IGdldFZlcnRpY2FsQmFyKCk7Ci0JCQlpZiAodnNiICE9IG51bGwpIHsKLQkJCQlpZiAodmlzaWJsZSAmJiAhT1MuSXNDb250cm9sVmlzaWJsZSh2c2IuaGFuZGxlKSkKLQkJCQkJOwotCQkJCWVsc2UKLQkJCQkJd3ctPSBzOwotCQkJfQotCQl9Ci0KLQkJaWYgKGhzYiAhPSBudWxsKQotCQkJT1MuSElWaWV3U2V0RnJhbWUoaHNiLmhhbmRsZSwgeCwgeStoLXMsIHd3LCBzKTsKLQkJCQotCQlpZiAodnNiICE9IG51bGwpCi0JCQlPUy5ISVZpZXdTZXRGcmFtZSh2c2IuaGFuZGxlLCB4K3ctcywgeSwgcywgaGgpOwotCQkKLQkJT1MuSElWaWV3U2V0RnJhbWUoaGFuZGxlLCB4LCB5LCB3dywgaGgpOwotCQkKLQkJLy9pZiAod3cgIT0gdyAmJiBoaCAhPSBoKQotCQkvLwlPUy5JbnZhbFdpbmRvd1JlY3QoT1MuR2V0Q29udHJvbE93bmVyKGhhbmRsZSksIG5ldyBNYWNSZWN0KHgrdy1zLCB5K2gtcywgcywgcykuZ2V0RGF0YSgpKTsKLQl9Ci0JCi0JcHJpdmF0ZSB2b2lkIG9sZFJlbGF5b3V0KCkgewotCQkKLQkJaW50IGhuZGw9IHNjcm9sbGVkSGFuZGxlOwotCQlpZiAoaG5kbCA9PSAwKQotCQkJcmV0dXJuOwotCQkKLQkJTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JCU9TLkdldENvbnRyb2xCb3VuZHMoaG5kbCwgYm91bmRzLmdldERhdGEoKSk7Ci0JCQotCQlib29sZWFuIHZpc2libGU9IE9TLklzQ29udHJvbFZpc2libGUoaG5kbCk7Ci0JCQotCQlpbnQgeD0gYm91bmRzLmdldFgoKTsKLQkJaW50IHk9IGJvdW5kcy5nZXRZKCk7Ci0JCWludCB3PSBib3VuZHMuZ2V0V2lkdGgoKTsKLQkJaW50IGg9IGJvdW5kcy5nZXRIZWlnaHQoKTsKLQkKLQkJaW50IHM9IDE1OwotCQlpbnQgd3c9IHc7Ci0JCWludCBoaD0gaDsKLQkJaW50IHN0eWxlPSBnZXRTdHlsZSgpOwotCi0JCWlmICh3dyA8IDAgfHwgaGggPCAwKSB7Ci0JCQlTeXN0ZW0ub3V0LnByaW50bG4oIioqKioqKiogU2Nyb2xsYWJsZS5vbGRSZWxheW91dDogIiArIHd3ICsgIiAiICsgaGgpOwotCQkJcmV0dXJuOwotCQl9Ci0JCQotCQlTY3JvbGxCYXIgaHNiPSBudWxsOwotCQlpZiAoKHN0eWxlICYgU1dULkhfU0NST0xMKSAhPSAwKSB7Ci0JCQloc2I9IGdldEhvcml6b250YWxCYXIoKTsKLQkJCWlmIChoc2IgIT0gbnVsbCkgewotCQkJCWlmICh2aXNpYmxlICYmICFPUy5Jc0NvbnRyb2xWaXNpYmxlKGhzYi5oYW5kbGUpKQotCQkJCQk7Ci0JCQkJZWxzZQotCQkJCQloaC09IHM7Ci0JCQl9Ci0JCX0KLQotCQlTY3JvbGxCYXIgdnNiPSBudWxsOwotCQlpZiAoKHN0eWxlICYgU1dULlZfU0NST0xMKSAhPSAwKSB7Ci0JCQl2c2I9IGdldFZlcnRpY2FsQmFyKCk7Ci0JCQlpZiAodnNiICE9IG51bGwpIHsKLQkJCQlpZiAodmlzaWJsZSAmJiAhT1MuSXNDb250cm9sVmlzaWJsZSh2c2IuaGFuZGxlKSkKLQkJCQkJOwotCQkJCWVsc2UKLQkJCQkJd3ctPSBzOwotCQkJfQotCQl9Ci0KLQkJaWYgKGhzYiAhPSBudWxsKQotCQkJaHNiLmludGVybmFsU2V0Qm91bmRzKG5ldyBNYWNSZWN0KHgsIHkraC1zLCB3dywgcykpOwotCQkJCi0JCWlmICh2c2IgIT0gbnVsbCkKLQkJCXZzYi5pbnRlcm5hbFNldEJvdW5kcyhuZXcgTWFjUmVjdCh4K3ctcywgeSwgcywgaGgpKTsKLQkJCi0JCU9TLlNldENvbnRyb2xCb3VuZHMoaGFuZGxlLCBuZXcgTWFjUmVjdCh4LCB5LCB3dywgaGgpLmdldERhdGEoKSk7Ci0JCQotCQlpZiAod3cgIT0gdyAmJiBoaCAhPSBoKQotCQkJT1MuSW52YWxXaW5kb3dSZWN0KE9TLkdldENvbnRyb2xPd25lcihoYW5kbGUpLCBuZXcgTWFjUmVjdCh4K3ctcywgeStoLXMsIHMsIHMpLmdldERhdGEoKSk7Ci0JfQogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1NoZWxsLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvU2hlbGwuamF2YQppbmRleCBlZWY2Nzc2Li4yZGIxMGNmIDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvU2hlbGwuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvU2hlbGwuamF2YQpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvU2xpZGVyLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvU2xpZGVyLmphdmEKaW5kZXggOTQyODBiNi4uZDY3ZjBiZCAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1NsaWRlci5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9TbGlkZXIuamF2YQpAQCAtNiwxMjcgKzYsMjMgQEAKICAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCisgCitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlJlY3Q7CiAKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7CiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi4qOwogCi0vKioKLSAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGFyZSBzZWxlY3RhYmxlIHVzZXIgaW50ZXJmYWNlCi0gKiBvYmplY3RzIHRoYXQgcmVwcmVzZW50IGEgcmFuZ2Ugb2YgcG9zaXRpdmUsIG51bWVyaWMgdmFsdWVzLiAKLSAqIDxwPgotICogQXQgYW55IGdpdmVuIG1vbWVudCwgYSBnaXZlbiBzbGlkZXIgd2lsbCBoYXZlIGEgCi0gKiBzaW5nbGUgPGVtPnNlbGVjdGlvbjwvZW0+IHRoYXQgaXMgY29uc2lkZXJlZCB0byBiZSBpdHMKLSAqIHZhbHVlLCB3aGljaCBpcyBjb25zdHJhaW5lZCB0byBiZSB3aXRoaW4gdGhlIHJhbmdlIG9mCi0gKiB2YWx1ZXMgdGhlIHNsaWRlciByZXByZXNlbnRzICh0aGF0IGlzLCBiZXR3ZWVuIGl0cwotICogPGVtPm1pbmltdW08L2VtPiBhbmQgPGVtPm1heGltdW08L2VtPiB2YWx1ZXMpLgotICogPC9wPjxwPgotICogVHlwaWNhbGx5LCBzbGlkZXJzIHdpbGwgYmUgbWFkZSB1cCBvZiBmaXZlIGFyZWFzOgotICogPG9sPgotICogPGxpPmFuIGFycm93IGJ1dHRvbiBmb3IgZGVjcmVtZW50aW5nIHRoZSB2YWx1ZTwvbGk+Ci0gKiA8bGk+YSBwYWdlIGRlY3JlbWVudCBhcmVhIGZvciBkZWNyZW1lbnRpbmcgdGhlIHZhbHVlIGJ5IGEgbGFyZ2VyIGFtb3VudDwvbGk+Ci0gKiA8bGk+YSA8ZW0+dGh1bWI8L2VtPiBmb3IgbW9kaWZ5aW5nIHRoZSB2YWx1ZSBieSBtb3VzZSBkcmFnZ2luZzwvbGk+Ci0gKiA8bGk+YSBwYWdlIGluY3JlbWVudCBhcmVhIGZvciBpbmNyZW1lbnRpbmcgdGhlIHZhbHVlIGJ5IGEgbGFyZ2VyIGFtb3VudDwvbGk+Ci0gKiA8bGk+YW4gYXJyb3cgYnV0dG9uIGZvciBpbmNyZW1lbnRpbmcgdGhlIHZhbHVlPC9saT4KLSAqIDwvb2w+Ci0gKiBCYXNlZCBvbiB0aGVpciBzdHlsZSwgc2xpZGVycyBhcmUgZWl0aGVyIDxjb2RlPkhPUklaT05UQUw8L2NvZGU+Ci0gKiAod2hpY2ggaGF2ZSBhIGxlZnQgZmFjaW5nIGJ1dHRvbiBmb3IgZGVjcmVtZW50aW5nIHRoZSB2YWx1ZSBhbmQgYQotICogcmlnaHQgZmFjaW5nIGJ1dHRvbiBmb3IgaW5jcmVtZW50aW5nIGl0KSBvciA8Y29kZT5WRVJUSUNBTDwvY29kZT4KLSAqICh3aGljaCBoYXZlIGFuIHVwd2FyZCBmYWNpbmcgYnV0dG9uIGZvciBkZWNyZW1lbnRpbmcgdGhlIHZhbHVlCi0gKiBhbmQgYSBkb3dud2FyZCBmYWNpbmcgYnV0dG9ucyBmb3IgaW5jcmVtZW50aW5nIGl0KS4KLSAqIDwvcD48cD4KLSAqIE9uIHNvbWUgcGxhdGZvcm1zLCB0aGUgc2l6ZSBvZiB0aGUgc2xpZGVyJ3MgdGh1bWIgY2FuIGJlCi0gKiB2YXJpZWQgcmVsYXRpdmUgdG8gdGhlIG1hZ25pdHVkZSBvZiB0aGUgcmFuZ2Ugb2YgdmFsdWVzIGl0Ci0gKiByZXByZXNlbnRzICh0aGF0IGlzLCByZWxhdGl2ZSB0byB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGl0cwotICogbWF4aW11bSBhbmQgbWluaW11bSB2YWx1ZXMpLiBUeXBpY2FsbHksIHRoaXMgaXMgdXNlZCB0bwotICogaW5kaWNhdGUgc29tZSBwcm9wb3J0aW9uYWwgdmFsdWUgc3VjaCBhcyB0aGUgcmF0aW8gb2YgdGhlCi0gKiB2aXNpYmxlIGFyZWEgb2YgYSBkb2N1bWVudCB0byB0aGUgdG90YWwgYW1vdW50IG9mIHNwYWNlIHRoYXQKLSAqIGl0IHdvdWxkIHRha2UgdG8gZGlzcGxheSBpdC4gU1dUIHN1cHBvcnRzIHNldHRpbmcgdGhlIHRodW1iCi0gKiBzaXplIGV2ZW4gaWYgdGhlIHVuZGVybHlpbmcgcGxhdGZvcm0gZG9lcyBub3QsIGJ1dCBpbiB0aGlzCi0gKiBjYXNlIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBzbGlkZXIgd2lsbCBub3QgY2hhbmdlLgotICogPC9wPgotICogPGRsPgotICogPGR0PjxiPlN0eWxlczo8L2I+PC9kdD4KLSAqIDxkZD5IT1JJWk9OVEFMLCBWRVJUSUNBTDwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPlNlbGVjdGlvbjwvZGQ+Ci0gKiA8L2RsPgotICogPHA+Ci0gKiBOb3RlOiBPbmx5IG9uZSBvZiB0aGUgc3R5bGVzIEhPUklaT05UQUwgYW5kIFZFUlRJQ0FMIG1heSBiZSBzcGVjaWZpZWQuCi0gKiA8L3A+PHA+Ci0gKiBJTVBPUlRBTlQ6IFRoaXMgY2xhc3MgaXMgPGVtPm5vdDwvZW0+IGludGVuZGVkIHRvIGJlIHN1YmNsYXNzZWQuCi0gKiA8L3A+Ci0gKgotICogQHNlZSBTY3JvbGxCYXIKLSAqLwotcHVibGljIC8qZmluYWwqLyBjbGFzcyBTbGlkZXIgZXh0ZW5kcyBDb250cm9sIHsKLQlwcml2YXRlIGludCBmSW5jcmVtZW50PSAxOwkvLyBBVwotCXByaXZhdGUgaW50IGZQYWdlSW5jcmVtZW50PSAxMDsJLy8gQVcKLS8qKgotICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGdpdmVuIGl0cyBwYXJlbnQKLSAqIGFuZCBhIHN0eWxlIHZhbHVlIGRlc2NyaWJpbmcgaXRzIGJlaGF2aW9yIGFuZCBhcHBlYXJhbmNlLgotICogPHA+Ci0gKiBUaGUgc3R5bGUgdmFsdWUgaXMgZWl0aGVyIG9uZSBvZiB0aGUgc3R5bGUgY29uc3RhbnRzIGRlZmluZWQgaW4KLSAqIGNsYXNzIDxjb2RlPlNXVDwvY29kZT4gd2hpY2ggaXMgYXBwbGljYWJsZSB0byBpbnN0YW5jZXMgb2YgdGhpcwotICogY2xhc3MsIG9yIG11c3QgYmUgYnVpbHQgYnkgPGVtPmJpdHdpc2UgT1I8L2VtPidpbmcgdG9nZXRoZXIgCi0gKiAodGhhdCBpcywgdXNpbmcgdGhlIDxjb2RlPmludDwvY29kZT4gInwiIG9wZXJhdG9yKSB0d28gb3IgbW9yZQotICogb2YgdGhvc2UgPGNvZGU+U1dUPC9jb2RlPiBzdHlsZSBjb25zdGFudHMuIFRoZSBjbGFzcyBkZXNjcmlwdGlvbgotICogbGlzdHMgdGhlIHN0eWxlIGNvbnN0YW50cyB0aGF0IGFyZSBhcHBsaWNhYmxlIHRvIHRoZSBjbGFzcy4KLSAqIFN0eWxlIGJpdHMgYXJlIGFsc28gaW5oZXJpdGVkIGZyb20gc3VwZXJjbGFzc2VzLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBjb21wb3NpdGUgY29udHJvbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZSAoY2Fubm90IGJlIG51bGwpCi0gKiBAcGFyYW0gc3R5bGUgdGhlIHN0eWxlIG9mIGNvbnRyb2wgdG8gY29uc3RydWN0Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcGFyZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHBhcmVudDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNXVCNIT1JJWk9OVEFMCi0gKiBAc2VlIFNXVCNWRVJUSUNBTAotICogQHNlZSBXaWRnZXQjY2hlY2tTdWJjbGFzcwotICogQHNlZSBXaWRnZXQjZ2V0U3R5bGUKLSAqLworcHVibGljIGNsYXNzIFNsaWRlciBleHRlbmRzIENvbnRyb2wgeworCWJvb2xlYW4gZHJhZ2dpbmc7CisJaW50IGluY3JlbWVudCA9IDE7CisJaW50IHBhZ2VJbmNyZW1lbnQgPSAxMDsKKwogcHVibGljIFNsaWRlciAoQ29tcG9zaXRlIHBhcmVudCwgaW50IHN0eWxlKSB7CiAJc3VwZXIgKHBhcmVudCwgY2hlY2tTdHlsZSAoc3R5bGUpKTsKIH0KLS8qKgotICogQWRkcyB0aGUgbGlzdGVuZXIgdG8gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSByZWNlaXZlcidzIHZhbHVlIGNoYW5nZXMsIGJ5IHNlbmRpbmcKLSAqIGl0IG9uZSBvZiB0aGUgbWVzc2FnZXMgZGVmaW5lZCBpbiB0aGUgPGNvZGU+U2VsZWN0aW9uTGlzdGVuZXI8L2NvZGU+Ci0gKiBpbnRlcmZhY2UuCi0gKiA8cD4KLSAqIFdoZW4gPGNvZGU+d2lkZ2V0U2VsZWN0ZWQ8L2NvZGU+IGlzIGNhbGxlZCwgdGhlIGV2ZW50IG9iamVjdCBkZXRhaWwgZmllbGQgY29udGFpbnMgb25lIG9mIHRoZSBmb2xsb3dpbmcgdmFsdWVzOgotICogPGNvZGU+MDwvY29kZT4gLSBmb3IgdGhlIGVuZCBvZiBhIGRyYWcuCi0gKiA8Y29kZT5TV1QuRFJBRzwvY29kZT4uCi0gKiA8Y29kZT5TV1QuSE9NRTwvY29kZT4uCi0gKiA8Y29kZT5TV1QuRU5EPC9jb2RlPi4KLSAqIDxjb2RlPlNXVC5BUlJPV19ET1dOPC9jb2RlPi4KLSAqIDxjb2RlPlNXVC5BUlJPV19VUDwvY29kZT4uCi0gKiA8Y29kZT5TV1QuUEFHRV9ET1dOPC9jb2RlPi4KLSAqIDxjb2RlPlNXVC5QQUdFX1VQPC9jb2RlPi4KLSAqIDxjb2RlPndpZGdldERlZmF1bHRTZWxlY3RlZDwvY29kZT4gaXMgbm90IGNhbGxlZC4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNlbGVjdGlvbkxpc3RlbmVyCi0gKiBAc2VlICNyZW1vdmVTZWxlY3Rpb25MaXN0ZW5lcgotICogQHNlZSBTZWxlY3Rpb25FdmVudAotICovCisKIHB1YmxpYyB2b2lkIGFkZFNlbGVjdGlvbkxpc3RlbmVyKFNlbGVjdGlvbkxpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTEzNCwyMTAgKzMwLDExOSBAQAogCWFkZExpc3RlbmVyKFNXVC5TZWxlY3Rpb24sdHlwZWRMaXN0ZW5lcik7CiAJYWRkTGlzdGVuZXIoU1dULkRlZmF1bHRTZWxlY3Rpb24sdHlwZWRMaXN0ZW5lcik7CiB9CisKIHN0YXRpYyBpbnQgY2hlY2tTdHlsZSAoaW50IHN0eWxlKSB7CiAJcmV0dXJuIGNoZWNrQml0cyAoc3R5bGUsIFNXVC5IT1JJWk9OVEFMLCBTV1QuVkVSVElDQUwsIDAsIDAsIDAsIDApOwogfQotcHVibGljIFBvaW50IGNvbXB1dGVTaXplIChpbnQgd0hpbnQsIGludCBoSGludCwgYm9vbGVhbiBjaGFuZ2VkKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLQlpbnQgYm9yZGVyID0gZ2V0Qm9yZGVyV2lkdGggKCk7Ci0JaW50IHdpZHRoID0gYm9yZGVyICogMiwgaGVpZ2h0ID0gYm9yZGVyICogMjsKLQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOwotCWludCBoU2Nyb2xsID0gZGlzcGxheS5zY3JvbGxlZE1hcmdpblg7Ci0JaW50IHZTY3JvbGwgPSBkaXNwbGF5LnNjcm9sbGVkTWFyZ2luWTsKLQlpZiAoKHN0eWxlICYgU1dULkhPUklaT05UQUwpICE9IDApIHsKLQkJd2lkdGggKz0gaFNjcm9sbCAqIDEwOwotCQloZWlnaHQgKz0gdlNjcm9sbDsKLQl9IGVsc2UgewotCQl3aWR0aCArPSBoU2Nyb2xsOwotCQloZWlnaHQgKz0gdlNjcm9sbCAqIDEwOwotCX0KLQlpZiAod0hpbnQgIT0gU1dULkRFRkFVTFQpIHdpZHRoID0gd0hpbnQgKyAoYm9yZGVyICogMik7Ci0JaWYgKGhIaW50ICE9IFNXVC5ERUZBVUxUKSBoZWlnaHQgPSBoSGludCArIChib3JkZXIgKiAyKTsKLQlyZXR1cm4gbmV3IFBvaW50ICh3aWR0aCwgaGVpZ2h0KTsKLX0KLXZvaWQgY3JlYXRlSGFuZGxlIChpbnQgaW5kZXgpIHsKLQlzdGF0ZSB8PSBIQU5ETEU7Ci0gICAgLyogQVcKLQlpbnQgW10gYXJnTGlzdCA9IHsKLQkJT1MuWG1OYW5jZXN0b3JTZW5zaXRpdmUsIDEsCi0JCU9TLlhtTmJvcmRlcldpZHRoLCAoc3R5bGUgJiBTV1QuQk9SREVSKSAhPSAwID8gMSA6IDAsCi0JCU9TLlhtTm9yaWVudGF0aW9uLCAoKHN0eWxlICYgU1dULkhfU0NST0xMKSAhPSAwKSA/IE9TLlhtSE9SSVpPTlRBTCA6IE9TLlhtVkVSVElDQUwsCi0JfTsKLQloYW5kbGUgPSBPUy5YbUNyZWF0ZVNjcm9sbEJhciAocGFyZW50LmhhbmRsZSwgbnVsbCwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLSAgICAqLwotICAgIGhhbmRsZT0gTWFjVXRpbC5uZXdDb250cm9sKHBhcmVudC5oYW5kbGUsIChzaG9ydCkwLCAoc2hvcnQpMCwgKHNob3J0KTEwMCwgT1Mua0NvbnRyb2xTY3JvbGxCYXJMaXZlUHJvYyk7Ci0JaWYgKGhhbmRsZSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOwotfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBhbW91bnQgdGhhdCB0aGUgcmVjZWl2ZXIncyB2YWx1ZSB3aWxsIGJlCi0gKiBtb2RpZmllZCBieSB3aGVuIHRoZSB1cC9kb3duIChvciByaWdodC9sZWZ0KSBhcnJvd3MKLSAqIGFyZSBwcmVzc2VkLgotICoKLSAqIEByZXR1cm4gdGhlIGluY3JlbWVudAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwotcHVibGljIGludCBnZXRJbmNyZW1lbnQgKCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0gICAgcmV0dXJuIGZJbmNyZW1lbnQ7Ci19Ci0vKioKLSAqIFJldHVybnMgdGhlIG1heGltdW0gdmFsdWUgd2hpY2ggdGhlIHJlY2VpdmVyIHdpbGwgYWxsb3cuCi0gKgotICogQHJldHVybiB0aGUgbWF4aW11bQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwotcHVibGljIGludCBnZXRNYXhpbXVtICgpIHsKLQljaGVja1dpZGdldCgpOwotICAgIHJldHVybiBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSk7Ci19Ci0vKioKLSAqIFJldHVybnMgdGhlIG1pbmltdW0gdmFsdWUgd2hpY2ggdGhlIHJlY2VpdmVyIHdpbGwgYWxsb3cuCi0gKgotICogQHJldHVybiB0aGUgbWluaW11bQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwotcHVibGljIGludCBnZXRNaW5pbXVtICgpIHsKLQljaGVja1dpZGdldCgpOwotICAgIHJldHVybiBPUy5HZXRDb250cm9sMzJCaXRNaW5pbXVtKGhhbmRsZSk7Ci19Ci0vKioKLSAqIFJldHVybnMgdGhlIGFtb3VudCB0aGF0IHRoZSByZWNlaXZlcidzIHZhbHVlIHdpbGwgYmUKLSAqIG1vZGlmaWVkIGJ5IHdoZW4gdGhlIHBhZ2UgaW5jcmVtZW50L2RlY3JlbWVudCBhcmVhcwotICogYXJlIHNlbGVjdGVkLgotICoKLSAqIEByZXR1cm4gdGhlIHBhZ2UgaW5jcmVtZW50Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCi1wdWJsaWMgaW50IGdldFBhZ2VJbmNyZW1lbnQgKCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0gICAgcmV0dXJuIGZQYWdlSW5jcmVtZW50OwotfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBzaW5nbGUgPGVtPnNlbGVjdGlvbjwvZW0+IHRoYXQgaXMgdGhlIHJlY2VpdmVyJ3MgdmFsdWUuCi0gKgotICogQHJldHVybiB0aGUgc2VsZWN0aW9uCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCi1wdWJsaWMgaW50IGdldFNlbGVjdGlvbiAoKSB7Ci0JY2hlY2tXaWRnZXQoKTsKLSAgICByZXR1cm4gT1MuR2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlKTsKLX0KLS8qKgotICogUmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgcmVjZWl2ZXIncyB0aHVtYiByZWxhdGl2ZSB0byB0aGUKLSAqIGRpZmZlcmVuY2UgYmV0d2VlbiBpdHMgbWF4aW11bSBhbmQgbWluaW11bSB2YWx1ZXMuCi0gKgotICogQHJldHVybiB0aGUgdGh1bWIgdmFsdWUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KLXB1YmxpYyBpbnQgZ2V0VGh1bWIgKCkgewotCWNoZWNrV2lkZ2V0KCk7Ci0gICAgcmV0dXJuIE9TLkdldENvbnRyb2xWaWV3U2l6ZShoYW5kbGUpOwotfQotdm9pZCBob29rRXZlbnRzICgpIHsKLQlzdXBlci5ob29rRXZlbnRzICgpOwotICAgIC8qIEFXCi0JaW50IHdpbmRvd1Byb2MgPSBnZXREaXNwbGF5ICgpLndpbmRvd1Byb2M7Ci0JT1MuWHRBZGRDYWxsYmFjayAoaGFuZGxlLCBPUy5YbU52YWx1ZUNoYW5nZWRDYWxsYmFjaywgd2luZG93UHJvYywgU1dULlNlbGVjdGlvbik7Ci0JT1MuWHRBZGRDYWxsYmFjayAoaGFuZGxlLCBPUy5YbU5kcmFnQ2FsbGJhY2ssIHdpbmRvd1Byb2MsIFNXVC5TZWxlY3Rpb24pOwotCU9TLlh0QWRkQ2FsbGJhY2sgKGhhbmRsZSwgT1MuWG1OdG9Cb3R0b21DYWxsYmFjaywgd2luZG93UHJvYywgU1dULlNlbGVjdGlvbik7Ci0JT1MuWHRBZGRDYWxsYmFjayAoaGFuZGxlLCBPUy5YbU5pbmNyZW1lbnRDYWxsYmFjaywgd2luZG93UHJvYywgU1dULlNlbGVjdGlvbik7Ci0JT1MuWHRBZGRDYWxsYmFjayAoaGFuZGxlLCBPUy5YbU5kZWNyZW1lbnRDYWxsYmFjaywgd2luZG93UHJvYywgU1dULlNlbGVjdGlvbik7Ci0JT1MuWHRBZGRDYWxsYmFjayAoaGFuZGxlLCBPUy5YbU5wYWdlSW5jcmVtZW50Q2FsbGJhY2ssIHdpbmRvd1Byb2MsIFNXVC5TZWxlY3Rpb24pOwotCU9TLlh0QWRkQ2FsbGJhY2sgKGhhbmRsZSwgT1MuWG1OcGFnZURlY3JlbWVudENhbGxiYWNrLCB3aW5kb3dQcm9jLCBTV1QuU2VsZWN0aW9uKTsKLQlPUy5YdEFkZENhbGxiYWNrIChoYW5kbGUsIE9TLlhtTnRvVG9wQ2FsbGJhY2ssIHdpbmRvd1Byb2MsIFNXVC5TZWxlY3Rpb24pOwotICAgICovCi0JT1MuU2V0Q29udHJvbEFjdGlvbihoYW5kbGUsIGdldERpc3BsYXkoKS5mQ29udHJvbEFjdGlvblByb2MpOwotfQotaW50IHByb2Nlc3NTZWxlY3Rpb24gKE9iamVjdCBjYWxsRGF0YSkgewogCi0JTWFjQ29udHJvbEV2ZW50IG1hY0V2ZW50PSAoTWFjQ29udHJvbEV2ZW50KSBjYWxsRGF0YTsKLQlpZiAoISBtYWNFdmVudC5pc01vdXNlRG93bigpKQotCQlyZXR1cm4gMDsKLQoraW50IGFjdGlvblByb2MgKGludCB0aGVDb250cm9sLCBpbnQgcGFydENvZGUpIHsKIAlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKLSAgICBzd2l0Y2ggKG1hY0V2ZW50LmdldFBhcnRDb2RlKCkpIHsKLSAgICBjYXNlIE9TLmtDb250cm9sVXBCdXR0b25QYXJ0OgotCQlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUsIE9TLkdldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSkgLSBmSW5jcmVtZW50KTsKLSAgICAgICAgZXZlbnQuZGV0YWlsID0gU1dULkFSUk9XX1VQOwotICAgICAgICBicmVhazsKLSAgICBjYXNlIE9TLmtDb250cm9sUGFnZVVwUGFydDoKLQkJT1MuU2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlLCBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUpIC0gZlBhZ2VJbmNyZW1lbnQpOwotICAgICAgICBldmVudC5kZXRhaWwgPSBTV1QuUEFHRV9VUDsKLSAgICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPUy5rQ29udHJvbFBhZ2VEb3duUGFydDoKLQkJT1MuU2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlLCBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUpICsgZlBhZ2VJbmNyZW1lbnQpOwotICAgICAgICBldmVudC5kZXRhaWwgPSBTV1QuUEFHRV9ET1dOOwotICAgICAgICBicmVhazsKLSAgICBjYXNlIE9TLmtDb250cm9sRG93bkJ1dHRvblBhcnQ6Ci0JCU9TLlNldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSwgT1MuR2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlKSArIGZJbmNyZW1lbnQpOwotICAgICAgICBldmVudC5kZXRhaWwgPSBTV1QuQVJST1dfRE9XTjsKLSAgICAgICAgYnJlYWs7Ci0gICAgY2FzZSBPUy5rQ29udHJvbEluZGljYXRvclBhcnQ6CS8vIGVuZCBvZiBkcmFnIG9yIGNvbnRpbnVvcyBkcmFnCi0JCWlmIChtYWNFdmVudC5pc01vdXNlRG93bigpKQotCQkJZXZlbnQuZGV0YWlsID0gU1dULkRSQUc7CS8vIGNvbnRpbnVvcyBkcmFnCi0JCWVsc2UgewotCQkJLyoKLQkJCSogRG8gbm90IHNldCB0aGUgZGV0YWlsIGZpZWxkIHRvIFNXVC5EUkFHCi0JCQkqIHRvIGluZGljYXRlIHRoYXQgdGhlIGRyYWdnaW5nIGhhcyBlbmRlZC4KLQkJCSovCi0JCX0KLSAgICAgICAgYnJlYWs7Ci0gICAgfQotCQotCXNlbmRFdmVudCAoU1dULlNlbGVjdGlvbiwgZXZlbnQpOwotCQotCS8qIEFXIEZJWE1FOiBtYXkgYmUgd2UgbmVlZCB0aGUgZm9sbG93aW5nIGhlcmUgdG9vLi4uCi0JaWYgKG1hY0V2ZW50LmlzTW91c2VEb3duKCkpIHsKLQkJaW50IHdIYW5kbGU9IE9TLkdldENvbnRyb2xPd25lcihoYW5kbGUpOwotCQlpZiAod0hhbmRsZSAhPSAwKSB7Ci0JCQlnZXREaXNwbGF5KCkudXBkYXRlV2luZG93KHdIYW5kbGUpOwotCQl9CisJaW50IHZhbHVlID0gT1MuR2V0Q29udHJvbDMyQml0VmFsdWUgKGhhbmRsZSk7CisgICAgc3dpdGNoIChwYXJ0Q29kZSkgeworCSAgICBjYXNlIE9TLmtDb250cm9sVXBCdXR0b25QYXJ0OgorCQkJdmFsdWUgLT0gaW5jcmVtZW50OworCSAgICAgICAgZXZlbnQuZGV0YWlsID0gU1dULkFSUk9XX1VQOworCSAgICAgICAgYnJlYWs7CisJICAgIGNhc2UgT1Mua0NvbnRyb2xQYWdlVXBQYXJ0OgorCQkJdmFsdWUgLT0gcGFnZUluY3JlbWVudDsKKwkgICAgICAgIGV2ZW50LmRldGFpbCA9IFNXVC5QQUdFX1VQOworCSAgICAgICAgYnJlYWs7CisJICAgIGNhc2UgT1Mua0NvbnRyb2xQYWdlRG93blBhcnQ6CisJCQl2YWx1ZSArPSBwYWdlSW5jcmVtZW50OworCSAgICAgICAgZXZlbnQuZGV0YWlsID0gU1dULlBBR0VfRE9XTjsKKwkgICAgICAgIGJyZWFrOworCSAgICBjYXNlIE9TLmtDb250cm9sRG93bkJ1dHRvblBhcnQ6CisJCQl2YWx1ZSArPSBpbmNyZW1lbnQ7CisJICAgICAgICBldmVudC5kZXRhaWwgPSBTV1QuQVJST1dfRE9XTjsKKwkgICAgICAgIGJyZWFrOworCSAgICBjYXNlIE9TLmtDb250cm9sSW5kaWNhdG9yUGFydDoKKwkgICAgCWRyYWdnaW5nID0gdHJ1ZTsKKwkJCWV2ZW50LmRldGFpbCA9IFNXVC5EUkFHOworCSAgICAgICAgYnJlYWs7CisJCWRlZmF1bHQ6CisJCQlyZXR1cm4gMDsKIAl9Ci0JKi8KLQorCU9TLlNldENvbnRyb2wzMkJpdFZhbHVlIChoYW5kbGUsIHZhbHVlKTsKKwlzZW5kRXZlbnQgKFNXVC5TZWxlY3Rpb24sIGV2ZW50KTsKKwlpZiAoZHJhZ2dpbmcpIHsKKwkJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwkJZGlzcGxheS51cGRhdGUgKCk7CisJfQogCXJldHVybiAwOwogfQotLyoqCi0gKiBSZW1vdmVzIHRoZSBsaXN0ZW5lciBmcm9tIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgcmVjZWl2ZXIncyB2YWx1ZSBjaGFuZ2VzLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIG5vIGxvbmdlciBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNlbGVjdGlvbkxpc3RlbmVyCi0gKiBAc2VlICNhZGRTZWxlY3Rpb25MaXN0ZW5lcgotICovCisKK3B1YmxpYyBQb2ludCBjb21wdXRlU2l6ZSAoaW50IHdIaW50LCBpbnQgaEhpbnQsIGJvb2xlYW4gY2hhbmdlZCkgeworCWNoZWNrV2lkZ2V0KCk7CisJaW50IFtdIG91dE1ldHJpYyA9IG5ldyBpbnQgWzFdOworCU9TLkdldFRoZW1lTWV0cmljIChPUy5rVGhlbWVNZXRyaWNTY3JvbGxCYXJXaWR0aCwgb3V0TWV0cmljKTsKKwlpbnQgd2lkdGggPSAwLCBoZWlnaHQgPSAwOworCWlmICgoc3R5bGUgJiBTV1QuSE9SSVpPTlRBTCkgIT0gMCkgeworCQloZWlnaHQgPSBvdXRNZXRyaWMgWzBdOworCQl3aWR0aCA9IGhlaWdodCAqIDEwOworCX0gZWxzZSB7CisJCXdpZHRoID0gb3V0TWV0cmljIFswXTsKKwkJaGVpZ2h0ID0gd2lkdGggKiAxMDsKKwl9CisJaWYgKHdIaW50ICE9IFNXVC5ERUZBVUxUKSB3aWR0aCA9IHdIaW50OworCWlmIChoSGludCAhPSBTV1QuREVGQVVMVCkgaGVpZ2h0ID0gaEhpbnQ7CisJcmV0dXJuIG5ldyBQb2ludCAod2lkdGgsIGhlaWdodCk7Cit9CisKK3ZvaWQgY3JlYXRlSGFuZGxlICgpIHsKKwlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCWludCBhY3Rpb25Qcm9jID0gZGlzcGxheS5hY3Rpb25Qcm9jOworCWludCBbXSBvdXRDb250cm9sID0gbmV3IGludCBbMV07CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAocGFyZW50LmhhbmRsZSk7CisJT1MuQ3JlYXRlU2Nyb2xsQmFyQ29udHJvbCAod2luZG93LCBudWxsLCAwLCAwLCAxMDAsIDEwLCB0cnVlLCBhY3Rpb25Qcm9jLCBvdXRDb250cm9sKTsKKwlpZiAob3V0Q29udHJvbCBbMF0gPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwloYW5kbGUgPSBvdXRDb250cm9sIFswXTsKK30KKworcHVibGljIGludCBnZXRJbmNyZW1lbnQgKCkgeworCWNoZWNrV2lkZ2V0KCk7CisgICAgcmV0dXJuIGluY3JlbWVudDsKK30KKworcHVibGljIGludCBnZXRNYXhpbXVtICgpIHsKKwljaGVja1dpZGdldCgpOworCWludCBtYXhpbXVtID0gT1MuR2V0Q29udHJvbDMyQml0TWF4aW11bSAoaGFuZGxlKTsKKwlpbnQgdmlld1NpemUgPSBPUy5HZXRDb250cm9sVmlld1NpemUgKGhhbmRsZSk7CisgICAgcmV0dXJuIG1heGltdW0gKyB2aWV3U2l6ZTsKK30KKworcHVibGljIGludCBnZXRNaW5pbXVtICgpIHsKKwljaGVja1dpZGdldCgpOworICAgIHJldHVybiBPUy5HZXRDb250cm9sMzJCaXRNaW5pbXVtIChoYW5kbGUpOworfQorCitwdWJsaWMgaW50IGdldFBhZ2VJbmNyZW1lbnQgKCkgeworCWNoZWNrV2lkZ2V0KCk7CisgICAgcmV0dXJuIHBhZ2VJbmNyZW1lbnQ7Cit9CisKK3B1YmxpYyBpbnQgZ2V0U2VsZWN0aW9uICgpIHsKKwljaGVja1dpZGdldCgpOworICAgIHJldHVybiBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZSAoaGFuZGxlKTsKK30KKworcHVibGljIGludCBnZXRUaHVtYiAoKSB7CisJY2hlY2tXaWRnZXQoKTsKKyAgICByZXR1cm4gT1MuR2V0Q29udHJvbFZpZXdTaXplIChoYW5kbGUpOworfQorCitpbnQga0V2ZW50TW91c2VEb3duIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IHN0YXR1cyA9IHN1cGVyLmtFdmVudE1vdXNlRG93biAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKHN0YXR1cyA9PSBPUy5ub0VycikgcmV0dXJuIHN0YXR1czsKKwlkcmFnZ2luZyA9IGZhbHNlOworCXN0YXR1cyA9IE9TLkNhbGxOZXh0RXZlbnRIYW5kbGVyIChuZXh0SGFuZGxlciwgdGhlRXZlbnQpOworCWlmIChkcmFnZ2luZykgeworCQlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKKwkJc2VuZEV2ZW50IChTV1QuU2VsZWN0aW9uLCBldmVudCk7CisJfQorCWRyYWdnaW5nID0gZmFsc2U7CisJcmV0dXJuIHN0YXR1czsKK30KKwogcHVibGljIHZvaWQgcmVtb3ZlU2VsZWN0aW9uTGlzdGVuZXIoU2VsZWN0aW9uTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwpAQCAtMzQ1LDEzMyArMTUwLDQ5IEBACiAJZXZlbnRUYWJsZS51bmhvb2soU1dULlNlbGVjdGlvbiwgbGlzdGVuZXIpOwogCWV2ZW50VGFibGUudW5ob29rKFNXVC5EZWZhdWx0U2VsZWN0aW9uLGxpc3RlbmVyKTsKIH0KLS8qKgotICogU2V0cyB0aGUgYW1vdW50IHRoYXQgdGhlIHJlY2VpdmVyJ3MgdmFsdWUgd2lsbCBiZQotICogbW9kaWZpZWQgYnkgd2hlbiB0aGUgdXAvZG93biAob3IgcmlnaHQvbGVmdCkgYXJyb3dzCi0gKiBhcmUgcHJlc3NlZCB0byB0aGUgYXJndW1lbnQsIHdoaWNoIG11c3QgYmUgYXQgbGVhc3QgCi0gKiBvbmUuCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgaW5jcmVtZW50IChtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvKQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRJbmNyZW1lbnQgKGludCB2YWx1ZSkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHZhbHVlIDwgMSkgcmV0dXJuOwotCWZJbmNyZW1lbnQ9IHZhbHVlOworCWluY3JlbWVudCA9IHZhbHVlOwogfQotLyoqCi0gKiBTZXRzIHRoZSBtYXhpbXVtIHZhbHVlIHdoaWNoIHRoZSByZWNlaXZlciB3aWxsIGFsbG93Ci0gKiB0byBiZSB0aGUgYXJndW1lbnQgd2hpY2ggbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IKLSAqIGVxdWFsIHRvIHplcm8uCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgbWF4aW11bSAobXVzdCBiZSB6ZXJvIG9yIGdyZWF0ZXIpCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldE1heGltdW0gKGludCB2YWx1ZSkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHZhbHVlIDwgMCkgcmV0dXJuOwotCU9TLlNldENvbnRyb2wzMkJpdE1heGltdW0oaGFuZGxlLCB2YWx1ZSk7CisJaW50IG1pbmltdW0gPSBPUy5HZXRDb250cm9sMzJCaXRNaW5pbXVtIChoYW5kbGUpOworCWludCB2aWV3U2l6ZSA9IE9TLkdldENvbnRyb2xWaWV3U2l6ZSAoaGFuZGxlKTsKKwlpZiAodmFsdWUgLSBtaW5pbXVtIC0gdmlld1NpemUgPCAwKSByZXR1cm47CisJT1MuU2V0Q29udHJvbDMyQml0TWF4aW11bSAoaGFuZGxlLCB2YWx1ZSAtIHZpZXdTaXplKTsKIH0KLS8qKgotICogU2V0cyB0aGUgbWluaW11bSB2YWx1ZSB3aGljaCB0aGUgcmVjZWl2ZXIgd2lsbCBhbGxvdwotICogdG8gYmUgdGhlIGFyZ3VtZW50IHdoaWNoIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yCi0gKiBlcXVhbCB0byB6ZXJvLgotICoKLSAqIEBwYXJhbSB2YWx1ZSB0aGUgbmV3IG1pbmltdW0gKG11c3QgYmUgemVybyBvciBncmVhdGVyKQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRNaW5pbXVtIChpbnQgdmFsdWUpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICh2YWx1ZSA8IDApIHJldHVybjsKLQlPUy5TZXRDb250cm9sMzJCaXRNaW5pbXVtKGhhbmRsZSwgdmFsdWUpOworCWludCBtYXhpbXVtID0gT1MuR2V0Q29udHJvbDMyQml0TWluaW11bSAoaGFuZGxlKTsKKwlpbnQgdmlld1NpemUgPSBPUy5HZXRDb250cm9sVmlld1NpemUgKGhhbmRsZSk7CisJaWYgKG1heGltdW0gLSB2YWx1ZSAtIHZpZXdTaXplIDwgMCkgcmV0dXJuOworCU9TLlNldENvbnRyb2wzMkJpdE1pbmltdW0gKGhhbmRsZSwgdmFsdWUpOwogfQotLyoqCi0gKiBTZXRzIHRoZSBhbW91bnQgdGhhdCB0aGUgcmVjZWl2ZXIncyB2YWx1ZSB3aWxsIGJlCi0gKiBtb2RpZmllZCBieSB3aGVuIHRoZSBwYWdlIGluY3JlbWVudC9kZWNyZW1lbnQgYXJlYXMKLSAqIGFyZSBzZWxlY3RlZCB0byB0aGUgYXJndW1lbnQsIHdoaWNoIG11c3QgYmUgYXQgbGVhc3QKLSAqIG9uZS4KLSAqCi0gKiBAcmV0dXJuIHRoZSBwYWdlIGluY3JlbWVudCAobXVzdCBiZSBncmVhdGVyIHRoYW4gemVybykKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0UGFnZUluY3JlbWVudCAoaW50IHZhbHVlKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAodmFsdWUgPCAxKSByZXR1cm47Ci0JZlBhZ2VJbmNyZW1lbnQ9IHZhbHVlOworCXBhZ2VJbmNyZW1lbnQgPSB2YWx1ZTsKIH0KLS8qKgotICogU2V0cyB0aGUgc2luZ2xlIDxlbT5zZWxlY3Rpb248L2VtPiB0aGF0IGlzIHRoZSByZWNlaXZlcidzCi0gKiB2YWx1ZSB0byB0aGUgYXJndW1lbnQgd2hpY2ggbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwKLSAqIHRvIHplcm8uCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgc2VsZWN0aW9uIChtdXN0IGJlIHplcm8gb3IgZ3JlYXRlcikKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uIChpbnQgdmFsdWUpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICh2YWx1ZSA8IDApIHJldHVybjsKLQlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUsIHZhbHVlKTsKKwlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZSAoaGFuZGxlLCB2YWx1ZSk7CiB9Ci0vKioKLSAqIFNldHMgdGhlIHNpemUgb2YgdGhlIHJlY2VpdmVyJ3MgdGh1bWIgcmVsYXRpdmUgdG8gdGhlCi0gKiBkaWZmZXJlbmNlIGJldHdlZW4gaXRzIG1heGltdW0gYW5kIG1pbmltdW0gdmFsdWVzIHRvIHRoZQotICogYXJndW1lbnQgd2hpY2ggbXVzdCBiZSBhdCBsZWFzdCBvbmUuCi0gKgotICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdGh1bWIgdmFsdWUgKG11c3QgYmUgYXQgbGVhc3Qgb25lKQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNjcm9sbEJhcgotICovCisKIHB1YmxpYyB2b2lkIHNldFRodW1iIChpbnQgdmFsdWUpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICh2YWx1ZSA8IDEpIHJldHVybjsKLSAgICBPUy5TZXRDb250cm9sVmlld1NpemUoaGFuZGxlLCB2YWx1ZSk7CisgICAgT1MuU2V0Q29udHJvbFZpZXdTaXplIChoYW5kbGUsIHZhbHVlKTsKIH0KLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBzZWxlY3Rpb24sIG1pbmltdW0gdmFsdWUsIG1heGltdW0KLSAqIHZhbHVlLCB0aHVtYiwgaW5jcmVtZW50IGFuZCBwYWdlIGluY3JlbWVudCBhbGwgYXQgb25jZS4KLSAqIDxwPgotICogTm90ZTogVGhpcyBpcyBlcXVpdmFsZW50IHRvIHNldHRpbmcgdGhlIHZhbHVlcyBpbmRpdmlkdWFsbHkKLSAqIHVzaW5nIHRoZSBhcHByb3ByaWF0ZSBtZXRob2RzLCBidXQgbWF5IGJlIGltcGxlbWVudGVkIGluIGEgCi0gKiBtb3JlIGVmZmljaWVudCBmYXNoaW9uIG9uIHNvbWUgcGxhdGZvcm1zLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBzZWxlY3Rpb24gdGhlIG5ldyBzZWxlY3Rpb24gdmFsdWUKLSAqIEBwYXJhbSBtaW5pbXVtIHRoZSBuZXcgbWluaW11bSB2YWx1ZQotICogQHBhcmFtIG1heGltdW0gdGhlIG5ldyBtYXhpbXVtIHZhbHVlCi0gKiBAcGFyYW0gdGh1bWIgdGhlIG5ldyB0aHVtYiB2YWx1ZQotICogQHBhcmFtIGluY3JlbWVudCB0aGUgbmV3IGluY3JlbWVudCB2YWx1ZQotICogQHBhcmFtIHBhZ2VJbmNyZW1lbnQgdGhlIG5ldyBwYWdlSW5jcmVtZW50IHZhbHVlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldFZhbHVlcyAoaW50IHNlbGVjdGlvbiwgaW50IG1pbmltdW0sIGludCBtYXhpbXVtLCBpbnQgdGh1bWIsIGludCBpbmNyZW1lbnQsIGludCBwYWdlSW5jcmVtZW50KSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoc2VsZWN0aW9uIDwgMCkgcmV0dXJuOwpAQCAtNDgxLDExICsyMDIsMTIgQEAKIAlpZiAobWF4aW11bSAtIG1pbmltdW0gLSB0aHVtYiA8IDApIHJldHVybjsKIAlpZiAoaW5jcmVtZW50IDwgMSkgcmV0dXJuOwogCWlmIChwYWdlSW5jcmVtZW50IDwgMSkgcmV0dXJuOwotCU9TLlNldENvbnRyb2wzMkJpdE1pbmltdW0oaGFuZGxlLCBtaW5pbXVtKTsKLQlPUy5TZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSwgbWF4aW11bSk7Ci0JT1MuU2V0Q29udHJvbFZpZXdTaXplKGhhbmRsZSwgdGh1bWIpOwotCU9TLlNldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSwgc2VsZWN0aW9uKTsKLQlmSW5jcmVtZW50PSBpbmNyZW1lbnQ7Ci0JZlBhZ2VJbmNyZW1lbnQ9IHBhZ2VJbmNyZW1lbnQ7CisJT1MuU2V0Q29udHJvbDMyQml0TWluaW11bSAoaGFuZGxlLCBtaW5pbXVtKTsKKwlPUy5TZXRDb250cm9sMzJCaXRNYXhpbXVtIChoYW5kbGUsIG1heGltdW0gLSB0aHVtYik7CisJT1MuU2V0Q29udHJvbFZpZXdTaXplIChoYW5kbGUsIHRodW1iKTsKKwlPUy5TZXRDb250cm9sMzJCaXRWYWx1ZSAoaGFuZGxlLCBzZWxlY3Rpb24pOworCXRoaXMuaW5jcmVtZW50ID0gaW5jcmVtZW50OworCXRoaXMucGFnZUluY3JlbWVudCA9IHBhZ2VJbmNyZW1lbnQ7CiB9CisKIH0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UYWJGb2xkZXIuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UYWJGb2xkZXIuamF2YQppbmRleCAzNTFmYTNjLi42ODljZmE0IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVGFiRm9sZGVyLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1RhYkZvbGRlci5qYXZhCkBAIC03LDEwICs3LDEyIEBACiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCiAgCitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlJlY3Q7CisKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOwogCiAvKioKICAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGltcGxlbWVudCB0aGUgbm90ZWJvb2sgdXNlciBpbnRlcmZhY2UKQEAgLTM2LDEyICszOCw3IEBACiAgKiA8L3A+CiAgKi8KIHB1YmxpYyBjbGFzcyBUYWJGb2xkZXIgZXh0ZW5kcyBDb21wb3NpdGUgewotCQotCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUQUJfSEVJR0hUPSAzMjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFSR0lOPSA2OwotCQogCVRhYkl0ZW0gW10gaXRlbXM7Ci0JcHJpdmF0ZSBpbnQgb2xkVmFsdWU7CiAJCiAvKioKICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50CkBAIC0xMDIsOSArOTksOSBAQAogcHVibGljIHZvaWQgYWRkU2VsZWN0aW9uTGlzdGVuZXIoU2VsZWN0aW9uTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCAoKTsKIAlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQlUeXBlZExpc3RlbmVyIHR5cGVkTGlzdGVuZXIgPSBuZXcgVHlwZWRMaXN0ZW5lcihsaXN0ZW5lcik7Ci0JYWRkTGlzdGVuZXIoU1dULlNlbGVjdGlvbix0eXBlZExpc3RlbmVyKTsKLQlhZGRMaXN0ZW5lcihTV1QuRGVmYXVsdFNlbGVjdGlvbix0eXBlZExpc3RlbmVyKTsKKwlUeXBlZExpc3RlbmVyIHR5cGVkTGlzdGVuZXIgPSBuZXcgVHlwZWRMaXN0ZW5lciAobGlzdGVuZXIpOworCWFkZExpc3RlbmVyIChTV1QuU2VsZWN0aW9uLHR5cGVkTGlzdGVuZXIpOworCWFkZExpc3RlbmVyIChTV1QuRGVmYXVsdFNlbGVjdGlvbix0eXBlZExpc3RlbmVyKTsKIH0KIAogc3RhdGljIGludCBjaGVja1N0eWxlIChpbnQgc3R5bGUpIHsKQEAgLTEyNCwxOSArMTIxLDkgQEAKIAogcHVibGljIFBvaW50IGNvbXB1dGVTaXplIChpbnQgd0hpbnQsIGludCBoSGludCwgYm9vbGVhbiBjaGFuZ2VkKSB7CiAJY2hlY2tXaWRnZXQgKCk7Ci0JLyogQVcKLQlSRUNUIGluc2V0UmVjdCA9IG5ldyBSRUNUICgpLCBpdGVtUmVjdCA9IG5ldyBSRUNUICgpOwotCU9TLlNlbmRNZXNzYWdlIChoYW5kbGUsIE9TLlRDTV9BREpVU1RSRUNULCAwLCBpbnNldFJlY3QpOwotCWludCB3aWR0aCA9IGluc2V0UmVjdC5sZWZ0IC0gaW5zZXRSZWN0LnJpZ2h0LCBoZWlnaHQgPSAwOwotCWludCBjb3VudCA9IE9TLlNlbmRNZXNzYWdlIChoYW5kbGUsIE9TLlRDTV9HRVRJVEVNQ09VTlQsIDAsIDApOwotCWlmIChjb3VudCAhPSAwKSB7Ci0JCU9TLlNlbmRNZXNzYWdlIChoYW5kbGUsIE9TLlRDTV9HRVRJVEVNUkVDVCwgY291bnQgLSAxLCBpdGVtUmVjdCk7Ci0JCXdpZHRoID0gTWF0aC5tYXggKHdpZHRoLCBpdGVtUmVjdC5yaWdodCAtIGluc2V0UmVjdC5yaWdodCk7Ci0JfQotCSovCi0JaW50IHdpZHRoPSAxMDA7CQkvLyBBVyBhIGJvZ3VzIGd1ZXNzCi0JaW50IGhlaWdodD0gMDsKLQkKKwkvLyBORUVEUyBXT1JLCisJaW50IGNvdW50ID0gT1MuR2V0Q29udHJvbDMyQml0TWF4aW11bSAoaGFuZGxlKTsKKwlpbnQgd2lkdGggPSAxMDAgKiBjb3VudCwgaGVpZ2h0ID0gMDsKIAlQb2ludCBzaXplOwogCWlmIChsYXlvdXQgIT0gbnVsbCkgewogCQlzaXplID0gbGF5b3V0LmNvbXB1dGVTaXplICh0aGlzLCB3SGludCwgaEhpbnQsIGNoYW5nZWQpOwpAQCAtMTUzLDQxICsxNDAsNDIgQEAKIAl3aWR0aCA9IHRyaW0ud2lkdGg7ICBoZWlnaHQgPSB0cmltLmhlaWdodDsKIAlyZXR1cm4gbmV3IFBvaW50ICh3aWR0aCwgaGVpZ2h0KTsKIH0KKwogcHVibGljIFJlY3RhbmdsZSBjb21wdXRlVHJpbSAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKIAljaGVja1dpZGdldCAoKTsKLQkvKiBBVwotCVJFQ1QgcmVjdCA9IG5ldyBSRUNUICgpOwotCU9TLlNldFJlY3QgKHJlY3QsIHgsIHksIHggKyB3aWR0aCwgeSArIGhlaWdodCk7Ci0JT1MuU2VuZE1lc3NhZ2UgKGhhbmRsZSwgT1MuVENNX0FESlVTVFJFQ1QsIDEsIHJlY3QpOwotCSovCi0JLyogQVcKLQlpbnQgYm9yZGVyID0gZ2V0Qm9yZGVyV2lkdGggKCk7Ci0JcmVjdC5sZWZ0IC09IGJvcmRlcjsgIHJlY3QucmlnaHQgKz0gYm9yZGVyOwotCXJlY3QudG9wIC09IGJvcmRlcjsgIHJlY3QuYm90dG9tICs9IGJvcmRlcjsKLQlpbnQgbmV3V2lkdGggPSByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0OwotCWludCBuZXdIZWlnaHQgPSByZWN0LmJvdHRvbSAtIHJlY3QudG9wOwotCXJldHVybiBuZXcgUmVjdGFuZ2xlIChyZWN0LmxlZnQsIHJlY3QudG9wLCBuZXdXaWR0aCwgbmV3SGVpZ2h0KTsKLQkqLwotCXJldHVybiBuZXcgUmVjdGFuZ2xlICh4LU1BUkdJTiwgeS1UQUJfSEVJR0hULCB3aWR0aCsoMipNQVJHSU4pLCBoZWlnaHQrVEFCX0hFSUdIVCtNQVJHSU4pOworCVJlY3QgYm91bmRzID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAoaGFuZGxlLCBib3VuZHMpOworCVJlY3QgY2xpZW50ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0Q29udHJvbERhdGEgKGhhbmRsZSwgKHNob3J0KU9TLmtDb250cm9sRW50aXJlQ29udHJvbCwgT1Mua0NvbnRyb2xUYWJDb250ZW50UmVjdFRhZywgUmVjdC5zaXplb2YsIGNsaWVudCwgbnVsbCk7CisJeCAtPSBNYXRoLm1heCAoMywgY2xpZW50LmxlZnQgLSBib3VuZHMubGVmdCk7CisJeSAtPSBNYXRoLm1heCAoMzQsIGNsaWVudC50b3AgLSBib3VuZHMudG9wKTsKKwl3aWR0aCArPSBNYXRoLm1heCAoNiwgKGJvdW5kcy5yaWdodCAtIGJvdW5kcy5sZWZ0KSAtIChjbGllbnQucmlnaHQgLSBjbGllbnQubGVmdCkpOworCWhlaWdodCArPSBNYXRoLm1heCAoMzcsIChib3VuZHMuYm90dG9tIC0gYm91bmRzLnRvcCkgLSAoY2xpZW50LmJvdHRvbSAtIGNsaWVudC50b3ApKTsKKwlSZWN0IGluc2V0ID0gZ2V0SW5zZXQgKCk7CisJeCAtPSBpbnNldC5sZWZ0OworCXkgLT0gaW5zZXQudG9wOworCXdpZHRoICs9IGluc2V0LmxlZnQgKyBpbnNldC5yaWdodDsKKwloZWlnaHQgKz0gaW5zZXQudG9wICsgaW5zZXQuYm90dG9tOworCXJldHVybiBuZXcgUmVjdGFuZ2xlICh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKK30KKwordm9pZCBjcmVhdGVIYW5kbGUgKCkgeworCWludCBbXSBvdXRDb250cm9sID0gbmV3IGludCBbMV07CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAocGFyZW50LmhhbmRsZSk7CisJT1MuQ3JlYXRlVGFic0NvbnRyb2wgKHdpbmRvdywgbmV3IFJlY3QgKCksIChzaG9ydClPUy5rQ29udHJvbFRhYlNpemVMYXJnZSwgKHNob3J0KU9TLmtDb250cm9sVGFiRGlyZWN0aW9uTm9ydGgsIChzaG9ydCkgMCwgMCwgb3V0Q29udHJvbCk7CisJaWYgKG91dENvbnRyb2wgWzBdID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7CisJaGFuZGxlID0gb3V0Q29udHJvbCBbMF07CiB9CiAKIHZvaWQgY3JlYXRlSXRlbSAoVGFiSXRlbSBpdGVtLCBpbnQgaW5kZXgpIHsKLQlpbnQgY291bnQgPSBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSk7Ci0JCisJaW50IGNvdW50ID0gT1MuR2V0Q29udHJvbDMyQml0TWF4aW11bSAoaGFuZGxlKTsKIAlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDw9IGNvdW50KSkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1JBTkdFKTsKKwlPUy5TZXRDb250cm9sMzJCaXRNYXhpbXVtIChoYW5kbGUsIGNvdW50KzEpOwogCWlmIChjb3VudCA9PSBpdGVtcy5sZW5ndGgpIHsKIAkJVGFiSXRlbSBbXSBuZXdJdGVtcyA9IG5ldyBUYWJJdGVtIFtpdGVtcy5sZW5ndGggKyA0XTsKIAkJU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIDAsIG5ld0l0ZW1zLCAwLCBpdGVtcy5sZW5ndGgpOwogCQlpdGVtcyA9IG5ld0l0ZW1zOwogCX0KLQkvKiBBVwotCVRDSVRFTSB0Y0l0ZW0gPSBuZXcgVENJVEVNICgpOwotCWlmIChPUy5TZW5kTWVzc2FnZSAoaGFuZGxlLCBPUy5UQ01fSU5TRVJUSVRFTSwgaW5kZXgsIHRjSXRlbSkgPT0gLTEpIHsKLQkJZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9BRERFRCk7Ci0JfQotCSovCi0JT1MuU2V0Q29udHJvbDMyQml0TWF4aW11bShoYW5kbGUsIGNvdW50KzEpOwotCiAJU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIGluZGV4LCBpdGVtcywgaW5kZXggKyAxLCBjb3VudCAtIGluZGV4KTsKIAlpdGVtcyBbaW5kZXhdID0gaXRlbTsKIApAQCAtMTk3LDIyICsxODUsMTYgQEAKIAkqIGlzIGFkZGVkLgogCSovCiAJaWYgKGNvdW50ID09IDApIHsKKwkJT1MuU2V0Q29udHJvbDMyQml0VmFsdWUgKGhhbmRsZSwgMSk7CiAJCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOwogCQlldmVudC5pdGVtID0gaXRlbXMgWzBdOwogCQlzZW5kRXZlbnQgKFNXVC5TZWxlY3Rpb24sIGV2ZW50KTsKIAkJLy8gdGhlIHdpZGdldCBjb3VsZCBiZSBkZXN0cm95ZWQgYXQgdGhpcyBwb2ludAogCX0KIH0KLXZvaWQgY3JlYXRlSGFuZGxlIChpbnQgaW5kZXgpIHsKLQlzdGF0ZSB8PSBIQU5ETEU7Ci0Jc3RhdGUgJj0gfkNBTlZBUzsKLQkJCi0JaGFuZGxlPSBNYWNVdGlsLm5ld0NvbnRyb2wocGFyZW50LmhhbmRsZSwgT1Mua0NvbnRyb2xUYWJTbWFsbFByb2MpOwotCWlmIChoYW5kbGUgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKLX0KIAotdm9pZCBjcmVhdGVXaWRnZXQgKGludCBpbmRleCkgewotCXN1cGVyLmNyZWF0ZVdpZGdldCAoaW5kZXgpOwordm9pZCBjcmVhdGVXaWRnZXQgKCkgeworCXN1cGVyLmNyZWF0ZVdpZGdldCAoKTsKIAlpdGVtcyA9IG5ldyBUYWJJdGVtIFs0XTsKIH0KIApAQCAtMjI0LDMyICsyMDYsMTYgQEAKIAkJaW5kZXgrKzsKIAl9CiAJaWYgKGluZGV4ID09IGNvdW50KSByZXR1cm47CS8vIG5vdCBmb3VuZAotCWludCBzZWxlY3Rpb25JbmRleCA9IE9TLkdldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSktMTsKLQkKLQkvKiBBVwotCWlmIChPUy5TZW5kTWVzc2FnZSAoaGFuZGxlLCBPUy5UQ01fREVMRVRFSVRFTSwgaW5kZXgsIDApID09IDApIHsKLQkJZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9SRU1PVkVEKTsKLQl9Ci0JKi8KLQlPUy5TZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSwgY291bnQtMSk7Ci0JCi0JU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIGluZGV4ICsgMSwgaXRlbXMsIGluZGV4LCAtLWNvdW50IC0gaW5kZXgpOwotCWl0ZW1zIFtjb3VudF0gPSBudWxsOworCWludCBzZWxlY3Rpb25JbmRleCA9IE9TLkdldENvbnRyb2wzMkJpdFZhbHVlIChoYW5kbGUpIC0gMTsKKwktLWNvdW50OworCU9TLlNldENvbnRyb2wzMkJpdE1heGltdW0oaGFuZGxlLCBjb3VudCk7CiAJaWYgKGNvdW50ID09IDApIHsKLQkJLyogQVcKLQkJaWYgKGltYWdlTGlzdCAhPSBudWxsKSB7Ci0JCQlPUy5TZW5kTWVzc2FnZSAoaGFuZGxlLCBPUy5UQ01fU0VUSU1BR0VMSVNULCAwLCAwKTsKLQkJCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7Ci0JCQlkaXNwbGF5LnJlbGVhc2VJbWFnZUxpc3QgKGltYWdlTGlzdCk7Ci0JCX0KLQkJaW1hZ2VMaXN0ID0gbnVsbDsKLQkJKi8KIAkJaXRlbXMgPSBuZXcgVGFiSXRlbSBbNF07CisJCXJldHVybjsKIAl9Ci0JCi0JdXBkYXRlQ2FyYm9uKGluZGV4KTsKLQkKLQlpZiAoY291bnQgPiAwICYmIGluZGV4ID09IHNlbGVjdGlvbkluZGV4KSB7CisJU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIGluZGV4ICsgMSwgaXRlbXMsIGluZGV4LCBjb3VudCAtIGluZGV4KTsKKwlpdGVtcyBbY291bnRdID0gbnVsbDsKKwlpZiAoaW5kZXggPT0gc2VsZWN0aW9uSW5kZXgpIHsKIAkJc2V0U2VsZWN0aW9uIChNYXRoLm1heCAoMCwgc2VsZWN0aW9uSW5kZXggLSAxKSk7CiAJCXNlbGVjdGlvbkluZGV4ID0gZ2V0U2VsZWN0aW9uSW5kZXggKCk7CiAJCWlmIChzZWxlY3Rpb25JbmRleCAhPSAtMSkgewpAQCAtMjYzLDI5ICsyMjksMTUgQEAKIAogcHVibGljIFJlY3RhbmdsZSBnZXRDbGllbnRBcmVhICgpIHsKIAljaGVja1dpZGdldCAoKTsKLQkvKiBBVwotCWlmIChwYXJlbnQuaGR3cCAhPSAwKSB7Ci0JCWludCBvbGRIZHdwID0gcGFyZW50Lmhkd3A7Ci0JCXBhcmVudC5oZHdwID0gMDsKLQkJT1MuRW5kRGVmZXJXaW5kb3dQb3MgKG9sZEhkd3ApOwotCQlpbnQgY291bnQgPSBwYXJlbnQuZ2V0Q2hpbGRyZW5Db3VudCAoKTsKLQkJcGFyZW50Lmhkd3AgPSBPUy5CZWdpbkRlZmVyV2luZG93UG9zIChjb3VudCk7Ci0JfQotCVJFQ1QgcmVjdCA9IG5ldyBSRUNUICgpOwotCU9TLkdldENsaWVudFJlY3QgKGhhbmRsZSwgcmVjdCk7Ci0JT1MuU2VuZE1lc3NhZ2UgKGhhbmRsZSwgT1MuVENNX0FESlVTVFJFQ1QsIDAsIHJlY3QpOwotCWludCB3aWR0aCA9IHJlY3QucmlnaHQgLSByZWN0LmxlZnQ7Ci0JaW50IGhlaWdodCA9IHJlY3QuYm90dG9tIC0gcmVjdC50b3A7Ci0JcmV0dXJuIG5ldyBSZWN0YW5nbGUgKHJlY3QubGVmdCwgcmVjdC50b3AsIHdpZHRoLCBoZWlnaHQpOwotCSovCi0JCi0Jc2hvcnRbXSBvdXRlcj0gbmV3IHNob3J0WzRdOwotCU9TLkdldENvbnRyb2xCb3VuZHMoaGFuZGxlLCBvdXRlcik7Ci0KLQlzaG9ydFtdIGlubmVyPSBuZXcgc2hvcnRbNF07Ci0JT1MuR2V0Q29udHJvbERhdGEoaGFuZGxlLCBPUy5rQ29udHJvbEVudGlyZUNvbnRyb2wsIE9TLmtDb250cm9sVGFiQ29udGVudFJlY3RUYWcsIGlubmVyKTsKLQkKLQlyZXR1cm4gbmV3IFJlY3RhbmdsZShpbm5lclsxXS1vdXRlclsxXSwgaW5uZXJbMF0tb3V0ZXJbMF0sIGlubmVyWzNdLWlubmVyWzFdLCBpbm5lclsyXS1pbm5lclswXSk7CisJUmVjdCBib3VuZHMgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChoYW5kbGUsIGJvdW5kcyk7CisJUmVjdCBjbGllbnQgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRDb250cm9sRGF0YSAoaGFuZGxlLCAoc2hvcnQpT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbFRhYkNvbnRlbnRSZWN0VGFnLCBSZWN0LnNpemVvZiwgY2xpZW50LCBudWxsKTsKKwlpbnQgeCA9IE1hdGgubWF4ICgwLCBjbGllbnQubGVmdCAtIGJvdW5kcy5sZWZ0KTsKKwlpbnQgeSA9IE1hdGgubWF4ICgwLCBjbGllbnQudG9wIC0gYm91bmRzLnRvcCk7CisJaW50IHdpZHRoID0gTWF0aC5tYXggKDAsIGNsaWVudC5yaWdodCAtIGNsaWVudC5sZWZ0KTsKKwlpbnQgaGVpZ2h0ID0gTWF0aC5tYXggKDAsIGNsaWVudC5ib3R0b20gLSBjbGllbnQudG9wKTsKKwlyZXR1cm4gbmV3IFJlY3RhbmdsZSAoeCwgeSwgd2lkdGgsIGhlaWdodCk7CiB9CiAKIC8qKgpAQCAtMzA1LDcgKzI1Nyw3IEBACiAgKi8KIHB1YmxpYyBUYWJJdGVtIGdldEl0ZW0gKGludCBpbmRleCkgewogCWNoZWNrV2lkZ2V0ICgpOwotCWludCBjb3VudCA9IE9TLkdldENvbnRyb2wzMkJpdE1heGltdW0oaGFuZGxlKTsKKwlpbnQgY291bnQgPSBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtIChoYW5kbGUpOwogCWlmICghKDAgPD0gaW5kZXggJiYgaW5kZXggPCBjb3VudCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7CiAJcmV0dXJuIGl0ZW1zIFtpbmRleF07CiB9CkBAIC0zMjIsNyArMjc0LDcgQEAKICAqLwogcHVibGljIGludCBnZXRJdGVtQ291bnQgKCkgewogCWNoZWNrV2lkZ2V0ICgpOwotCXJldHVybiBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSk7CisJcmV0dXJuIE9TLkdldENvbnRyb2wzMkJpdE1heGltdW0gKGhhbmRsZSk7CiB9CiAKIC8qKgpAQCAtMzQzLDE4ICsyOTUsOSBAQAogICovCiBwdWJsaWMgVGFiSXRlbSBbXSBnZXRJdGVtcyAoKSB7CiAJY2hlY2tXaWRnZXQgKCk7Ci0JaW50IGNvdW50ID0gT1MuR2V0Q29udHJvbDMyQml0TWF4aW11bShoYW5kbGUpOwotCWludCBuPSAwOwotCWZvciAoaW50IGk9MDsgaSA8IGNvdW50OyBpKyspIAotCQlpZiAoaXRlbXNbaV0gIT0gbnVsbCkKLQkJCW4rKzsKLQlpZiAobiA8IGNvdW50KQotCQlTeXN0ZW0ub3V0LnByaW50bG4oIlRhYkZvbGRlci5nZXRJdGVtczogZm91bmQgbnVsbCBzbG90cyIpOwotCVRhYkl0ZW0gW10gcmVzdWx0ID0gbmV3IFRhYkl0ZW0gW25dOwotCWZvciAoaW50IGk9MDsgaSA8IG47IGkrKykgCi0JCWlmIChpdGVtc1tpXSAhPSBudWxsKQotCQkJcmVzdWx0W2ldPSBpdGVtc1tpXTsKLQkvL1N5c3RlbS5hcnJheWNvcHkgKGl0ZW1zLCAwLCByZXN1bHQsIDAsIGNvdW50KTsKKwlpbnQgY291bnQgPSBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtIChoYW5kbGUpOworCVRhYkl0ZW0gW10gcmVzdWx0ID0gbmV3IFRhYkl0ZW0gW2NvdW50XTsKKwlTeXN0ZW0uYXJyYXljb3B5IChpdGVtcywgMCwgcmVzdWx0LCAwLCBjb3VudCk7CiAJcmV0dXJuIHJlc3VsdDsKIH0KIApAQCAtMzc2LDcgKzMxOSw3IEBACiAgKi8KIHB1YmxpYyBUYWJJdGVtIFtdIGdldFNlbGVjdGlvbiAoKSB7CiAJY2hlY2tXaWRnZXQgKCk7Ci0JaW50IGluZGV4PSBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUpLTE7CisJaW50IGluZGV4ID0gT1MuR2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlKSAtIDE7CiAJaWYgKGluZGV4ID09IC0xKSByZXR1cm4gbmV3IFRhYkl0ZW0gWzBdOwogCXJldHVybiBuZXcgVGFiSXRlbSBbXSB7aXRlbXMgW2luZGV4XX07CiB9CkBAIC0zOTQsMTQgKzMzNyw5IEBACiAgKi8KIHB1YmxpYyBpbnQgZ2V0U2VsZWN0aW9uSW5kZXggKCkgewogCWNoZWNrV2lkZ2V0ICgpOwotCXJldHVybiBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUpLTE7CisJcmV0dXJuIE9TLkdldENvbnRyb2wzMkJpdFZhbHVlIChoYW5kbGUpIC0gMTsKIH0KLXZvaWQgaG9va0V2ZW50cyAoKSB7Ci0Jc3VwZXIuaG9va0V2ZW50cyAoKTsKLQkKLQlEaXNwbGF5IGRpc3BsYXk9IGdldERpc3BsYXkoKTsKLQlPUy5TZXRDb250cm9sQWN0aW9uKGhhbmRsZSwgZGlzcGxheS5mQ29udHJvbEFjdGlvblByb2MpOwotfQorCiAvKioKICAqIFNlYXJjaGVzIHRoZSByZWNlaXZlcidzIGxpc3Qgc3RhcnRpbmcgYXQgdGhlIGZpcnN0IGl0ZW0KICAqIChpbmRleCAwKSB1bnRpbCBhbiBpdGVtIGlzIGZvdW5kIHRoYXQgaXMgZXF1YWwgdG8gdGhlIApAQCAtNDIyLDU2ICszNjAsNTMgQEAKIHB1YmxpYyBpbnQgaW5kZXhPZiAoVGFiSXRlbSBpdGVtKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJaWYgKGl0ZW0gPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKLQlpbnQgY291bnQgPSBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSk7CisJaW50IGNvdW50ID0gT1MuR2V0Q29udHJvbDMyQml0TWF4aW11bSAoaGFuZGxlKTsKIAlmb3IgKGludCBpPTA7IGk8Y291bnQ7IGkrKykgewogCQlpZiAoaXRlbXMgW2ldID09IGl0ZW0pIHJldHVybiBpOwogCX0KIAlyZXR1cm4gLTE7CiB9Ci0vKiBBVwotYm9vbGVhbiBtbmVtb25pY0hpdCAoY2hhciBrZXkpIHsKLQlmb3IgKGludCBpPTA7IGk8aXRlbXMubGVuZ3RoOyBpKyspIHsKLQkJVGFiSXRlbSBpdGVtID0gaXRlbXMgW2ldOwotCQlpZiAoaXRlbSAhPSBudWxsKSB7Ci0JCQljaGFyIGNoID0gZmluZE1uZW1vbmljIChpdGVtLmdldFRleHQgKCkpOwotCQkJaWYgKENoYXJhY3Rlci50b1VwcGVyQ2FzZSAoa2V5KSA9PSBDaGFyYWN0ZXIudG9VcHBlckNhc2UgKGNoKSkgewkJCi0JCQkJaWYgKHNldEZvY3VzICgpKSB7Ci0JCQkJCXNldFNlbGVjdGlvbiAoaSwgdHJ1ZSk7Ci0JCQkJCXJldHVybiB0cnVlOwotCQkJCX0KLQkJCX0KKworUmVjdCBnZXRJbnNldCAoKSB7CisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlyZXR1cm4gZGlzcGxheS50YWJGb2xkZXJJbnNldDsKK30KKworaW50IGtFdmVudENvbnRyb2xIaXQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpbnQgcmVzdWx0ID0gc3VwZXIua0V2ZW50Q29udHJvbEhpdCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKHJlc3VsdCA9PSBPUy5ub0VycikgcmV0dXJuIHJlc3VsdDsKKwlpbnQgaW5kZXggPSBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZSAoaGFuZGxlKSAtIDE7CisJaW50IGNvdW50ID0gT1MuR2V0Q29udHJvbDMyQml0TWF4aW11bSAoaGFuZGxlKTsKKwlmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKKwkJaWYgKGkgIT0gaW5kZXgpIHsKKwkJCUNvbnRyb2wgY29udHJvbCA9IGl0ZW1zIFtpXS5jb250cm9sOworCQkJaWYgKGNvbnRyb2wgIT0gbnVsbCAmJiAhY29udHJvbC5pc0Rpc3Bvc2VkICgpKQorCQkJCWNvbnRyb2wuc2V0VmlzaWJsZSAoZmFsc2UpOwogCQl9CiAJfQotCXJldHVybiBmYWxzZTsKLX0KLWJvb2xlYW4gbW5lbW9uaWNNYXRjaCAoY2hhciBrZXkpIHsKLQlmb3IgKGludCBpPTA7IGk8aXRlbXMubGVuZ3RoOyBpKyspIHsKLQkJVGFiSXRlbSBpdGVtID0gaXRlbXMgW2ldOwotCQlpZiAoaXRlbSAhPSBudWxsKSB7Ci0JCQljaGFyIGNoID0gZmluZE1uZW1vbmljIChpdGVtLmdldFRleHQgKCkpOwotCQkJaWYgKENoYXJhY3Rlci50b1VwcGVyQ2FzZSAoa2V5KSA9PSBDaGFyYWN0ZXIudG9VcHBlckNhc2UgKGNoKSkgewkJCi0JCQkJcmV0dXJuIHRydWU7Ci0JCQl9CisJVGFiSXRlbSBpdGVtID0gbnVsbDsKKwlpZiAoaW5kZXggIT0gLTEpIGl0ZW0gPSBpdGVtcyBbaW5kZXhdOworCWlmIChpdGVtICE9IG51bGwpIHsKKwkJQ29udHJvbCBjb250cm9sID0gaXRlbS5jb250cm9sOworCQlpZiAoY29udHJvbCAhPSBudWxsICYmICFjb250cm9sLmlzRGlzcG9zZWQgKCkpIHsKKwkJCWNvbnRyb2wuc2V0Qm91bmRzIChnZXRDbGllbnRBcmVhICgpKTsKKwkJCWNvbnRyb2wuc2V0VmlzaWJsZSAodHJ1ZSk7CiAJCX0KIAl9Ci0JcmV0dXJuIGZhbHNlOworCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOworCWV2ZW50Lml0ZW0gPSBpdGVtOworCXBvc3RFdmVudCAoU1dULlNlbGVjdGlvbiwgZXZlbnQpOworCXJlZHJhdyAoKTsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOwogfQotKi8KKwogdm9pZCByZWxlYXNlV2lkZ2V0ICgpIHsKLQlpbnQgY291bnQgPSBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSk7Ci0JZm9yIChpbnQgaT0wOyBpPGNvdW50OyBpKyspIHsKKwlpbnQgY291bnQgPSBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtIChoYW5kbGUpOworCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewogCQlUYWJJdGVtIGl0ZW0gPSBpdGVtcyBbaV07Ci0JCWlmIChpdGVtICE9IG51bGwgJiYgIWl0ZW0uaXNEaXNwb3NlZCAoKSkgaXRlbS5yZWxlYXNlV2lkZ2V0ICgpOworCQlpZiAoaXRlbSAhPSBudWxsICYmICFpdGVtLmlzRGlzcG9zZWQgKCkpIGl0ZW0ucmVsZWFzZVJlc291cmNlcyAoKTsKIAl9CiAJaXRlbXMgPSBudWxsOwotCS8qIEFXCi0JaWYgKGltYWdlTGlzdCAhPSBudWxsKSB7Ci0JCU9TLlNlbmRNZXNzYWdlIChoYW5kbGUsIE9TLlRDTV9TRVRJTUFHRUxJU1QsIDAsIDApOwotCQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOwotCQlkaXNwbGF5LnJlbGVhc2VJbWFnZUxpc3QgKGltYWdlTGlzdCk7Ci0JfQotCWltYWdlTGlzdCA9IG51bGw7Ci0JKi8KIAlzdXBlci5yZWxlYXNlV2lkZ2V0ICgpOwogfQogCkBAIC01MDAsNiArNDM1LDIxIEBACiAJZXZlbnRUYWJsZS51bmhvb2sgKFNXVC5EZWZhdWx0U2VsZWN0aW9uLGxpc3RlbmVyKTsJCiB9CiAKK2ludCBzZXRCb3VuZHMgKGludCBjLCBpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwgYm9vbGVhbiBtb3ZlLCBib29sZWFuIHJlc2l6ZSwgYm9vbGVhbiBldmVudHMpIHsKKwlpbnQgcmVzdWx0ID0gc3VwZXIuc2V0Qm91bmRzKGMsIHgsIHksIHdpZHRoLCBoZWlnaHQsIG1vdmUsIHJlc2l6ZSwgZXZlbnRzKTsKKwlpZiAoKHJlc3VsdCAmIFJFU0laRUQpICE9IDApIHsKKwkJaW50IGluZGV4ID0gT1MuR2V0Q29udHJvbDMyQml0VmFsdWUgKGhhbmRsZSkgLSAxOworCQlpZiAoaW5kZXggIT0gLTEpIHsKKwkJCVRhYkl0ZW0gaXRlbSA9IGl0ZW1zIFtpbmRleF07CisJCQlDb250cm9sIGNvbnRyb2wgPSBpdGVtLmNvbnRyb2w7CisJCQlpZiAoY29udHJvbCAhPSBudWxsICYmICFjb250cm9sLmlzRGlzcG9zZWQgKCkpIHsKKwkJCQljb250cm9sLnNldEJvdW5kcyAoZ2V0Q2xpZW50QXJlYSAoKSk7CisJCQl9CisJCX0KKwl9CisJcmV0dXJuIHJlc3VsdDsKK30KKwogLyoqCiAgKiBTZXRzIHRoZSByZWNlaXZlcidzIHNlbGVjdGlvbiB0byBiZSB0aGUgZ2l2ZW4gYXJyYXkgb2YgaXRlbXMuCiAgKiBUaGUgY3VycmVudCBzZWxlY3RlZCBpcyBmaXJzdCBjbGVhcmVkLCB0aGVuIHRoZSBuZXcgaXRlbXMgYXJlCkBAIC01MTksNyArNDY5LDcgQEAKIAkJc2V0U2VsZWN0aW9uICgtMSk7CiAJCXJldHVybjsKIAl9Ci0JZm9yIChpbnQgaT1pdGVtcy5sZW5ndGgtMTsgaT49MDsgLS1pKSB7CisJZm9yIChpbnQgaT1pdGVtcy5sZW5ndGggLSAxOyBpPj0wOyAtLWkpIHsKIAkJaW50IGluZGV4ID0gaW5kZXhPZiAoaXRlbXMgW2ldKTsKIAkJaWYgKGluZGV4ICE9IC0xKSBzZXRTZWxlY3Rpb24gKGluZGV4KTsKIAl9CkBAIC01NDQsMTAgKzQ5NCw5IEBACiB9CiAKIHZvaWQgc2V0U2VsZWN0aW9uIChpbnQgaW5kZXgsIGJvb2xlYW4gbm90aWZ5KSB7Ci0JCi0JaW50IG9sZEluZGV4ID0gT1MuR2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlKSAtIDE7Ci0JaWYgKG9sZEluZGV4ICE9IC0xKSB7Ci0JCVRhYkl0ZW0gaXRlbSA9IGl0ZW1zIFtvbGRJbmRleF07CisJaW50IGN1cnJlbnRJbmRleCA9IE9TLkdldENvbnRyb2wzMkJpdFZhbHVlIChoYW5kbGUpIC0gMTsKKwlpZiAoY3VycmVudEluZGV4ICE9IC0xKSB7CisJCVRhYkl0ZW0gaXRlbSA9IGl0ZW1zIFtjdXJyZW50SW5kZXhdOwogCQlpZiAoaXRlbSAhPSBudWxsKSB7CiAJCQlDb250cm9sIGNvbnRyb2wgPSBpdGVtLmNvbnRyb2w7CiAJCQlpZiAoY29udHJvbCAhPSBudWxsICYmICFjb250cm9sLmlzRGlzcG9zZWQgKCkpIHsKQEAgLTU1NSwxMSArNTA0LDEwIEBACiAJCQl9CiAJCX0KIAl9Ci0JT1MuU2V0Q29udHJvbDMyQml0VmFsdWUoaGFuZGxlLCBpbmRleCsxKTsKLQotCWludCBuZXdJbmRleCA9IE9TLkdldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSkgLSAxOwotCWlmIChuZXdJbmRleCAhPSAtMSkgewotCQlUYWJJdGVtIGl0ZW0gPSBpdGVtcyBbbmV3SW5kZXhdOworCU9TLlNldENvbnRyb2wzMkJpdFZhbHVlIChoYW5kbGUsIGluZGV4KzEpOworCWluZGV4ID0gT1MuR2V0Q29udHJvbDMyQml0VmFsdWUgKGhhbmRsZSkgLSAxOworCWlmIChpbmRleCAhPSAtMSkgeworCQlUYWJJdGVtIGl0ZW0gPSBpdGVtcyBbaW5kZXhdOwogCQlpZiAoaXRlbSAhPSBudWxsKSB7CiAJCQlDb250cm9sIGNvbnRyb2wgPSBpdGVtLmNvbnRyb2w7CiAJCQlpZiAoY29udHJvbCAhPSBudWxsICYmICFjb250cm9sLmlzRGlzcG9zZWQgKCkpIHsKQEAgLTU3MSw4ICs1MTksOSBAQAogCQkJCWV2ZW50Lml0ZW0gPSBpdGVtOwogCQkJCXNlbmRFdmVudCAoU1dULlNlbGVjdGlvbiwgZXZlbnQpOwogCQkJfQotCQl9CQorCQl9CiAJfQorCXJlZHJhdyAoKTsKIH0KIAogYm9vbGVhbiB0cmF2ZXJzZVBhZ2UgKGJvb2xlYW4gbmV4dCkgewpAQCAtNTg4LDk2ICs1MzcsNCBAQAogCXNldFNlbGVjdGlvbiAoaW5kZXgsIHRydWUpOwogCXJldHVybiBpbmRleCA9PSBnZXRTZWxlY3Rpb25JbmRleCAoKTsKIH0KLQotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLS8vIE1hYyBzdHVmZgotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLQotaW50IHByb2Nlc3NTZWxlY3Rpb24gKE9iamVjdCBjYWxsRGF0YSkgewotCU1hY0NvbnRyb2xFdmVudCBtYWNFdmVudD0gKE1hY0NvbnRyb2xFdmVudCkgY2FsbERhdGE7Ci0JaWYgKCFtYWNFdmVudC5pc01vdXNlRG93bigpKQotCQloYW5kbGVTZWxlY3Rpb25DaGFuZ2UobWFjRXZlbnQuZ2V0UGFydENvZGUoKS0xKTsKLQllbHNlCi0JCW9sZFZhbHVlPSBPUy5HZXRDb250cm9sMzJCaXRWYWx1ZShoYW5kbGUpLTE7Ci0JcmV0dXJuIDA7Ci19Ci0KLXByaXZhdGUgdm9pZCBoYW5kbGVTZWxlY3Rpb25DaGFuZ2UoaW50IG5ld1ZhbHVlKSAgewotCi0JVGFiSXRlbSBpdGVtID0gbnVsbDsKLQlpbnQgaW5kZXg9IG9sZFZhbHVlOwotCi0JaWYgKGluZGV4ICE9IC0xKSBpdGVtID0gaXRlbXMgW2luZGV4XTsKLQlpZiAoaXRlbSAhPSBudWxsKSB7Ci0JCUNvbnRyb2wgY29udHJvbCA9IGl0ZW0uY29udHJvbDsKLQkJaWYgKGNvbnRyb2wgIT0gbnVsbCAmJiAhY29udHJvbC5pc0Rpc3Bvc2VkICgpKSB7Ci0JCQljb250cm9sLnNldFZpc2libGUgKGZhbHNlKTsKLQkJfQotCX0KLQkJCi0JaW5kZXg9IG5ld1ZhbHVlOwotCWlmIChpbmRleCAhPSAtMSkgaXRlbSA9IGl0ZW1zIFtpbmRleF07Ci0JaWYgKGl0ZW0gIT0gbnVsbCkgewotCQlDb250cm9sIGNvbnRyb2wgPSBpdGVtLmNvbnRyb2w7Ci0JCWlmIChjb250cm9sICE9IG51bGwgJiYgIWNvbnRyb2wuaXNEaXNwb3NlZCAoKSkgewotCQkJY29udHJvbC5zZXRCb3VuZHMgKGdldENsaWVudEFyZWEgKCkpOwotCQkJY29udHJvbC5zZXRWaXNpYmxlICh0cnVlKTsKLQkJfQotCX0KLQkKLQlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKLQlldmVudC5pdGVtID0gaXRlbTsKLQlwb3N0RXZlbnQgKFNXVC5TZWxlY3Rpb24sIGV2ZW50KTsKLX0KLQotcHJpdmF0ZSB2b2lkIHVwZGF0ZUNhcmJvbihpbnQgc3RhcnRJbmRleCkgewotCWludCBuPSBPUy5HZXRDb250cm9sMzJCaXRNYXhpbXVtKGhhbmRsZSk7Ci0JZm9yIChpbnQgaT0gc3RhcnRJbmRleDsgaSA8IG47IGkrKykgewotCQlUYWJJdGVtIGl0ZW09IGl0ZW1zW2ldOwotCQlpZiAoaXRlbSAhPSBudWxsKQotCQkJc2V0VGFiVGV4dChpLCBpdGVtLmdldFRleHQoKSk7Ci0JfQotfQotCi12b2lkIHNldFRhYlRleHQoaW50IGluZGV4LCBTdHJpbmcgc3RyaW5nKSB7Ci0JaW50IHNIYW5kbGU9IDA7Ci0JdHJ5IHsKLQkJU3RyaW5nIHQ9IE1hY1V0aWwucmVtb3ZlTW5lbW9uaWNzKHN0cmluZyk7Ci0JCXNIYW5kbGU9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnModCk7Ci0JCU9TLnNldFRhYlRleHQoaGFuZGxlLCBpbmRleCsxLCBzSGFuZGxlKTsKLQl9IGZpbmFsbHkgewotCQlpZiAoc0hhbmRsZSAhPSAwKQotCQkJT1MuQ0ZSZWxlYXNlKHNIYW5kbGUpOwotCX0KLX0KLQotdm9pZCBzZXRUYWJJbWFnZShpbnQgaW5kZXgsIEltYWdlIGltYWdlKSB7Ci0JLyogQVc6IGRvZXMgbm90IHdvcmsgeWV0Li4uCi0JaW50IGljb249IEltYWdlLmNhcmJvbl9jcmVhdGVDSWNvbihpbWFnZSk7Ci0JaWYgKGljb24gIT0gMCkKLQkJaWYgKE9TLnNldFRhYkljb24oaGFuZGxlLCBpbmRleCsxLCBpY29uKSAhPSBPUy5rTm9FcnIpCi0JCQlTeXN0ZW0uZXJyLnByaW50bG4oIlRhYkZvbGRlci5zZXRUYWJJbWFnZTogZXJyb3IiKTsKLQkqLwotfQotCi0vKioKLSAqIE92ZXJyaWRkZW4gZnJvbSBDb250cm9sLgotICogeCBhbmQgeSBhcmUgcmVsYXRpdmUgdG8gd2luZG93IQotICovCi12b2lkIGhhbmRsZVJlc2l6ZShpbnQgaG5kbCwgTWFjUmVjdCBib3VuZHMpIHsKLQotCWJvdW5kcy5pbnNldChNQVJHSU4sIDAsIE1BUkdJTiwgTUFSR0lOKTsKLQlzdXBlci5oYW5kbGVSZXNpemUoaG5kbCwgYm91bmRzKTsKLQkKLQlpZiAoaGFuZGxlICE9IDApIHsKLQkJaW50IHNlbGVjdGVkSW5kZXg9IE9TLkdldENvbnRyb2wzMkJpdFZhbHVlKGhhbmRsZSktMTsKLQkJaWYgKHNlbGVjdGVkSW5kZXggIT0gLTEpIHsKLQkJCUNvbnRyb2wgY29udHJvbCA9IGl0ZW1zW3NlbGVjdGVkSW5kZXhdLmdldENvbnRyb2woKTsKLQkJCWlmIChjb250cm9sICE9IG51bGwgJiYgIWNvbnRyb2wuaXNEaXNwb3NlZCgpKSB7Ci0JCQkJY29udHJvbC5zZXRCb3VuZHMoZ2V0Q2xpZW50QXJlYSgpKTsKLQkJCX0KLQkJfQotCX0KLX0KLQogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1RhYkl0ZW0uamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UYWJJdGVtLmphdmEKaW5kZXggYjBlMzRmMC4uZWNjNTY1NiAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1RhYkl0ZW0uamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVGFiSXRlbS5qYXZhCkBAIC05LDYgKzksOSBAQAogCiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CiBpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkNvbnRyb2xUYWJJbmZvUmVjVjE7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Db250cm9sQnV0dG9uQ29udGVudEluZm87CiAKIC8qKgogICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgcmVwcmVzZW50IGEgc2VsZWN0YWJsZSB1c2VyIGludGVyZmFjZSBvYmplY3QKQEAgLTI3LDYgKzMwLDcgQEAKIAlUYWJGb2xkZXIgcGFyZW50OwogCUNvbnRyb2wgY29udHJvbDsKIAlTdHJpbmcgdG9vbFRpcFRleHQ7CisJaW50IGNJY29uOwogCiAvKioKICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50CkBAIC0xMTgsNyArMTIyLDcgQEAKICAqIDwvdWw+CiAgKi8KIHB1YmxpYyBDb250cm9sIGdldENvbnRyb2wgKCkgewotCWNoZWNrV2lkZ2V0KCk7CisJY2hlY2tXaWRnZXQgKCk7CiAJcmV0dXJuIGNvbnRyb2w7CiB9CiAKQEAgLTEzOCw3ICsxNDIsNyBAQAogICogPC91bD4KICAqLwogcHVibGljIFRhYkZvbGRlciBnZXRQYXJlbnQgKCkgewotCWNoZWNrV2lkZ2V0KCk7CisJY2hlY2tXaWRnZXQgKCk7CiAJcmV0dXJuIHBhcmVudDsKIH0KIApAQCAtMTU0LDcgKzE1OCw3IEBACiAgKiA8L3VsPgogICovCiBwdWJsaWMgU3RyaW5nIGdldFRvb2xUaXBUZXh0ICgpIHsKLQljaGVja1dpZGdldCgpOworCWNoZWNrV2lkZ2V0ICgpOwogCXJldHVybiB0b29sVGlwVGV4dDsKIH0KIApAQCAtMTY5LDYgKzE3MywxMCBAQAogCiB2b2lkIHJlbGVhc2VXaWRnZXQgKCkgewogCXN1cGVyLnJlbGVhc2VXaWRnZXQgKCk7CisJaWYgKGNJY29uICE9IDApIHsKKwkJZGVzdHJveUNJY29uIChjSWNvbik7CisJCWNJY29uID0gMDsKKwl9CiAJY29udHJvbCA9IG51bGw7CiAJcGFyZW50ID0gbnVsbDsKIH0KQEAgLTE4OSw3ICsxOTcsNyBAQAogICogPC91bD4KICAqLwogcHVibGljIHZvaWQgc2V0Q29udHJvbCAoQ29udHJvbCBjb250cm9sKSB7Ci0JY2hlY2tXaWRnZXQoKTsKKwljaGVja1dpZGdldCAoKTsKIAlpZiAoY29udHJvbCAhPSBudWxsKSB7CiAJCWlmIChjb250cm9sLmlzRGlzcG9zZWQoKSkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKIAkJaWYgKGNvbnRyb2wucGFyZW50ICE9IHBhcmVudCkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1BBUkVOVCk7CkBAIC0yMTIsMjEgKzIyMCw1MSBAQAogfQogCiBwdWJsaWMgdm9pZCBzZXRJbWFnZSAoSW1hZ2UgaW1hZ2UpIHsKLQljaGVja1dpZGdldCgpOworCWNoZWNrV2lkZ2V0ICgpOwogCWludCBpbmRleCA9IHBhcmVudC5pbmRleE9mICh0aGlzKTsKIAlpZiAoaW5kZXggPT0gLTEpIHJldHVybjsKIAlzdXBlci5zZXRJbWFnZSAoaW1hZ2UpOwotCWdldFBhcmVudCgpLnNldFRhYkltYWdlKGluZGV4LCBpbWFnZSk7CisJaWYgKGNJY29uICE9IDApIHsKKwkJZGVzdHJveUNJY29uKGNJY29uKTsKKwkJY0ljb24gPSAwOworCX0KKwlDb250cm9sQnV0dG9uQ29udGVudEluZm8gaW5Db250ZW50ID0gbmV3IENvbnRyb2xCdXR0b25Db250ZW50SW5mbyAoKTsKKwlpZiAoaW1hZ2UgPT0gbnVsbCkgeworCQlpbkNvbnRlbnQuY29udGVudFR5cGUgPSAoc2hvcnQpT1Mua0NvbnRyb2xDb250ZW50VGV4dE9ubHk7CisJfSBlbHNlIHsKKwkJY0ljb24gPSBjcmVhdGVDSWNvbiAoaW1hZ2UpOworCQlpbkNvbnRlbnQuY29udGVudFR5cGUgPSAoc2hvcnQpT1Mua0NvbnRyb2xDb250ZW50Q0ljb25IYW5kbGU7CisJCWluQ29udGVudC5pY29uUmVmID0gY0ljb247CisJfQorCU9TLlNldENvbnRyb2xEYXRhIChwYXJlbnQuaGFuZGxlLCBpbmRleCsxLCBPUy5rQ29udHJvbFRhYkltYWdlQ29udGVudFRhZywgQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvLnNpemVvZiwgaW5Db250ZW50KTsKKwlwYXJlbnQucmVkcmF3ICgpOwogfQogCiBwdWJsaWMgdm9pZCBzZXRUZXh0IChTdHJpbmcgc3RyaW5nKSB7Ci0JY2hlY2tXaWRnZXQoKTsKKwljaGVja1dpZGdldCAoKTsKIAlpZiAoc3RyaW5nID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJaWYgKChzdHlsZSAmIFNXVC5BUlJPVykgIT0gMCkgcmV0dXJuOwogCWludCBpbmRleCA9IHBhcmVudC5pbmRleE9mICh0aGlzKTsKIAlpZiAoaW5kZXggPT0gLTEpIHJldHVybjsKIAlzdXBlci5zZXRUZXh0IChzdHJpbmcpOwotCS8vZ2V0UGFyZW50KCkudXBkYXRlQ2FyYm9uKGluZGV4KTsKLQlnZXRQYXJlbnQoKS5zZXRUYWJUZXh0KGluZGV4LCBzdHJpbmcpOworCWNoYXIgW10gYnVmZmVyID0gbmV3IGNoYXIgW3RleHQubGVuZ3RoICgpXTsKKwl0ZXh0LmdldENoYXJzICgwLCBidWZmZXIubGVuZ3RoLCBidWZmZXIsIDApOworCWludCBpPTAsIGo9MDsKKwl3aGlsZSAoaSA8IGJ1ZmZlci5sZW5ndGgpIHsKKwkJaWYgKChidWZmZXIgW2orK10gPSBidWZmZXIgW2krK10pID09IE1uZW1vbmljKSB7CisJCQlpZiAoaSA9PSBidWZmZXIubGVuZ3RoKSB7Y29udGludWU7fQorCQkJaWYgKGJ1ZmZlciBbaV0gPT0gTW5lbW9uaWMpIHtpKys7IGNvbnRpbnVlO30KKwkJCWotLTsKKwkJfQorCX0KKwlpbnQgcHRyID0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgYnVmZmVyLCBqKTsKKwlpZiAocHRyID09IDApIGVycm9yIChTV1QuRVJST1JfQ0FOTk9UX1NFVF9URVhUKTsJCisJQ29udHJvbFRhYkluZm9SZWNWMSB0YWIgPSBuZXcgQ29udHJvbFRhYkluZm9SZWNWMSAoKTsKKwl0YWIudmVyc2lvbj0gKHNob3J0KSBPUy5rQ29udHJvbFRhYkluZm9WZXJzaW9uT25lOworCXRhYi5pY29uU3VpdGVJRCA9IDA7CisJdGFiLm5hbWUgPSBwdHI7CisJT1MuU2V0Q29udHJvbERhdGEgKHBhcmVudC5oYW5kbGUsIGluZGV4KzEsIE9TLmtDb250cm9sVGFiSW5mb1RhZywgQ29udHJvbFRhYkluZm9SZWNWMS5zaXplb2YsIHRhYik7CisJT1MuQ0ZSZWxlYXNlIChwdHIpOwogfQogCiAvKioKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UYWJsZS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1RhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjhmYWMxMAotLS0gL2Rldi9udWxsCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UYWJsZS5qYXZhCkBAIC0wLDAgKzEsODgwIEBACitwYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworCitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkRhdGFCcm93c2VyQ2FsbGJhY2tzOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUmVjdDsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkRhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjOworCitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOworCitwdWJsaWMgY2xhc3MgVGFibGUgZXh0ZW5kcyBDb21wb3NpdGUgeworCVRhYmxlSXRlbSBbXSBpdGVtczsKKwlUYWJsZUNvbHVtbiBbXSBjb2x1bW5zOworCWludCBpdGVtQ291bnQsIGNvbHVtbkNvdW50LCBpZENvdW50LCBhbmNob3JGaXJzdCwgYW5jaG9yTGFzdCwgaGVhZGVySGVpZ2h0OworCWJvb2xlYW4gaWdub3JlU2VsZWN0OworCXN0YXRpYyBmaW5hbCBpbnQgQ0hFQ0tfQ09MVU1OX0lEID0gMTAyNDsKKwlzdGF0aWMgZmluYWwgaW50IENPTFVNTl9JRCA9IDEwMjU7CisKK3B1YmxpYyBUYWJsZSAoQ29tcG9zaXRlIHBhcmVudCwgaW50IHN0eWxlKSB7CisJc3VwZXIgKHBhcmVudCwgY2hlY2tTdHlsZSAoc3R5bGUpKTsKK30KKworcHVibGljIHZvaWQgYWRkU2VsZWN0aW9uTGlzdGVuZXIgKFNlbGVjdGlvbkxpc3RlbmVyIGxpc3RlbmVyKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJVHlwZWRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IFR5cGVkTGlzdGVuZXIgKGxpc3RlbmVyKTsKKwlhZGRMaXN0ZW5lciAoU1dULlNlbGVjdGlvbix0eXBlZExpc3RlbmVyKTsKKwlhZGRMaXN0ZW5lciAoU1dULkRlZmF1bHRTZWxlY3Rpb24sdHlwZWRMaXN0ZW5lcik7Cit9CisKK3N0YXRpYyBpbnQgY2hlY2tTdHlsZSAoaW50IHN0eWxlKSB7CisJLyoKKwkqIEZlYXR1cmUgaW4gV2luZG93cy4gIEl0IGlzIG5vdCBwb3NzaWJsZSB0byBjcmVhdGUKKwkqIGEgdGFibGUgdGhhdCBkb2VzIG5vdCBoYXZlIHNjcm9sbCBiYXJzLiAgVGhlcmVmb3JlLAorCSogbm8gbWF0dGVyIHdoYXQgc3R5bGUgYml0cyBhcmUgc3BlY2lmaWVkLCBzZXQgdGhlCisJKiBIX1NDUk9MTCBhbmQgVl9TQ1JPTEwgYml0cyBzbyB0aGF0IHRoZSBTV1Qgc3R5bGUKKwkqIHdpbGwgbWF0Y2ggdGhlIHdpZGdldCB0aGF0IFdpbmRvd3MgY3JlYXRlcy4KKwkqLworCXN0eWxlIHw9IFNXVC5IX1NDUk9MTCB8IFNXVC5WX1NDUk9MTDsKKwlyZXR1cm4gY2hlY2tCaXRzIChzdHlsZSwgU1dULlNJTkdMRSwgU1dULk1VTFRJLCAwLCAwLCAwLCAwKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY2hlY2tTdWJjbGFzcyAoKSB7CisJaWYgKCFpc1ZhbGlkU3ViY2xhc3MgKCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9TVUJDTEFTUyk7Cit9CisKK3B1YmxpYyBQb2ludCBjb21wdXRlU2l6ZSAoaW50IHdIaW50LCBpbnQgaEhpbnQsIGJvb2xlYW4gY2hhbmdlZCkgeworCWNoZWNrV2lkZ2V0KCk7CisJaW50IHdpZHRoID0gMDsKKwlpZiAod0hpbnQgPT0gU1dULkRFRkFVTFQpIHsKKwkJR0MgZ2MgPSBuZXcgR0MgKHRoaXMpOworCQlmb3IgKGludCBpPTA7IGk8aXRlbUNvdW50OyBpKyspIHsKKwkJCS8vTk9UIERPTkUgLSB0YWtlIGludG8gYWNjb3VudCB0aGUgaWNvbgorLy8JCQlSZWN0YW5nbGUgcmVjdCA9IGl0ZW1zIFtpXS5nZXRCb3VuZHMgKCk7CisvLwkJCXdpZHRoID0gTWF0aC5tYXggKHdpZHRoLCByZWN0LndpZHRoKTsKKwkJCVBvaW50IGV4dGVudCA9IGdjLnN0cmluZ0V4dGVudCAoaXRlbXMgW2ldLnRleHQpOworCQkJd2lkdGggPSBNYXRoLm1heCAod2lkdGgsIGV4dGVudC54KTsKKwkJfQorCQlnYy5kaXNwb3NlICgpOworCX0gZWxzZSB7CisJCXdpZHRoID0gd0hpbnQ7CisJfQorCWlmICh3aWR0aCA8PSAwKSB3aWR0aCA9IERFRkFVTFRfV0lEVEg7CisJaW50IGhlaWdodCA9IDA7CisJaWYgKGhIaW50ID09IFNXVC5ERUZBVUxUKSB7CisJCWhlaWdodCA9IGl0ZW1Db3VudCAqIGdldEl0ZW1IZWlnaHQgKCk7CisJfSBlbHNlIHsKKwkJaGVpZ2h0ID0gaEhpbnQ7CisJfQorCWlmIChoZWlnaHQgPD0gMCkgaGVpZ2h0ID0gREVGQVVMVF9IRUlHSFQ7CisJUmVjdGFuZ2xlIHJlY3QgPSBjb21wdXRlVHJpbSAoMCwgMCwgd2lkdGgsIGhlaWdodCk7CisJcmV0dXJuIG5ldyBQb2ludCAocmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpOworfQorCitwdWJsaWMgUmVjdGFuZ2xlIGNvbXB1dGVUcmltIChpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCkgeworCWNoZWNrV2lkZ2V0KCk7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0RGF0YUJyb3dzZXJTY3JvbGxCYXJJbnNldCAoaGFuZGxlLCByZWN0KTsKKwl4IC09IHJlY3QubGVmdDsKKwl5IC09IHJlY3QudG9wOworCXdpZHRoICs9IChyZWN0LmxlZnQgKyByZWN0LnJpZ2h0KSAqIDM7CisJaGVpZ2h0ICs9IHJlY3QudG9wICsgcmVjdC5ib3R0b207CisJcmV0dXJuIG5ldyBSZWN0YW5nbGUgKHgsIHksIHdpZHRoLCBoZWlnaHQpOworfQorCit2b2lkIGNyZWF0ZUhhbmRsZSAoKSB7CisJaW50IFtdIG91dENvbnRyb2wgPSBuZXcgaW50IFsxXTsKKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChwYXJlbnQuaGFuZGxlKTsKKwlPUy5DcmVhdGVEYXRhQnJvd3NlckNvbnRyb2wgKHdpbmRvdywgbnVsbCwgT1Mua0RhdGFCcm93c2VyTGlzdFZpZXcsIG91dENvbnRyb2wpOworCWlmIChvdXRDb250cm9sIFswXSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOworCWhhbmRsZSA9IG91dENvbnRyb2wgWzBdOworCWludCBzZWxlY3Rpb25GbGFncyA9IChzdHlsZSAmIFNXVC5TSU5HTEUpICE9IDAgPyBPUy5rRGF0YUJyb3dzZXJTZWxlY3RPbmx5T25lIDogT1Mua0RhdGFCcm93c2VyQ21kVG9nZ2xlc1NlbGVjdGlvbjsKKwlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGlvbkZsYWdzIChoYW5kbGUsIHNlbGVjdGlvbkZsYWdzKTsKKwlzaG9ydCBbXSBoZWlnaHQgPSBuZXcgc2hvcnQgWzFdOworCU9TLkdldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJCdG5IZWlnaHQgKGhhbmRsZSwgaGVpZ2h0KTsKKwloZWFkZXJIZWlnaHQgPSBoZWlnaHQgWzBdOworCU9TLlNldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJCdG5IZWlnaHQgKGhhbmRsZSwgKHNob3J0KSAwKTsKKwlPUy5TZXREYXRhQnJvd3Nlckhhc1Njcm9sbEJhcnMgKGhhbmRsZSwgKHN0eWxlICYgU1dULkhfU0NST0xMKSAhPSAwLCAoc3R5bGUgJiBTV1QuVl9TQ1JPTEwpICE9IDApOworCWlmICgoc3R5bGUgJiBTV1QuRlVMTF9TRUxFQ1RJT04pICE9IDApIHsKKwkJT1MuU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdIaWxpdGVTdHlsZSAoaGFuZGxlLCBPUy5rRGF0YUJyb3dzZXJUYWJsZVZpZXdGaWxsSGlsaXRlKTsKKwl9CisJLy9OT1QgRE9ORQorCWlmICgoc3R5bGUgJiBTV1QuSF9TQ1JPTEwpID09IDApIE9TLkF1dG9TaXplRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbnMgKGhhbmRsZSk7CisJaW50IHBvc2l0aW9uID0gMDsKKwlpZiAoKHN0eWxlICYgU1dULkNIRUNLKSAhPSAwKSB7CisJCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjIGNoZWNrQ29sdW1uID0gbmV3IERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjICgpOworCQljaGVja0NvbHVtbi5oZWFkZXJCdG5EZXNjX3ZlcnNpb24gPSBPUy5rRGF0YUJyb3dzZXJMaXN0Vmlld0xhdGVzdEhlYWRlckRlc2M7CisJCWNoZWNrQ29sdW1uLnByb3BlcnR5RGVzY19wcm9wZXJ0eUlEID0gQ0hFQ0tfQ09MVU1OX0lEOworCQljaGVja0NvbHVtbi5wcm9wZXJ0eURlc2NfcHJvcGVydHlUeXBlID0gT1Mua0RhdGFCcm93c2VyQ2hlY2tib3hUeXBlOworCQljaGVja0NvbHVtbi5wcm9wZXJ0eURlc2NfcHJvcGVydHlGbGFncyA9IE9TLmtEYXRhQnJvd3NlclByb3BlcnR5SXNNdXRhYmxlOworCQkvL05PVCBET05FCisJCWNoZWNrQ29sdW1uLmhlYWRlckJ0bkRlc2NfbWluaW11bVdpZHRoID0gNDA7CisJCWNoZWNrQ29sdW1uLmhlYWRlckJ0bkRlc2NfbWF4aW11bVdpZHRoID0gNDA7CisJCWNoZWNrQ29sdW1uLmhlYWRlckJ0bkRlc2NfaW5pdGlhbE9yZGVyID0gT1Mua0RhdGFCcm93c2VyT3JkZXJJbmNyZWFzaW5nOworCQlPUy5BZGREYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uIChoYW5kbGUsIGNoZWNrQ29sdW1uLCBwb3NpdGlvbisrKTsKKwl9CisJRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbkRlc2MgY29sdW1uID0gbmV3IERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjICgpOworCWNvbHVtbi5oZWFkZXJCdG5EZXNjX3ZlcnNpb24gPSBPUy5rRGF0YUJyb3dzZXJMaXN0Vmlld0xhdGVzdEhlYWRlckRlc2M7CisJY29sdW1uLnByb3BlcnR5RGVzY19wcm9wZXJ0eUlEID0gQ09MVU1OX0lEOworCWNvbHVtbi5wcm9wZXJ0eURlc2NfcHJvcGVydHlUeXBlID0gT1Mua0RhdGFCcm93c2VyVGV4dFR5cGU7IC8vIE9TLmtEYXRhQnJvd3Nlckljb25BbmRUZXh0VHlwZQorCWNvbHVtbi5wcm9wZXJ0eURlc2NfcHJvcGVydHlGbGFncyA9IE9TLmtEYXRhQnJvd3Nlckxpc3RWaWV3U2VsZWN0aW9uQ29sdW1uIHwgT1Mua0RhdGFCcm93c2VyRGVmYXVsdFByb3BlcnR5RmxhZ3M7CisJLy9OT1QgRE9ORQorCWNvbHVtbi5oZWFkZXJCdG5EZXNjX21heGltdW1XaWR0aCA9IDB4N0ZGRjsKKwljb2x1bW4uaGVhZGVyQnRuRGVzY19pbml0aWFsT3JkZXIgPSBPUy5rRGF0YUJyb3dzZXJPcmRlckluY3JlYXNpbmc7CisJT1MuQWRkRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbiAoaGFuZGxlLCBjb2x1bW4sIHBvc2l0aW9uKTsKKwkvL05PVCBET05FCisJT1MuU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdOYW1lZENvbHVtbldpZHRoIChoYW5kbGUsIENPTFVNTl9JRCwgKHNob3J0KTgwMCk7CisKKwkvKgorCSogRmVhdHVyZSBpbiB0aGUgTWFjaW50b3NoLiAgU2Nyb2xsIGJhcnMgYXJlIG5vdCBjcmVhdGVkIHVudGlsCisJKiB0aGUgd2lkZ2V0IGhhcyBhIG1pbmltdW0gc2l6ZS4gIFRoZSBmaXggaXMgdG8gZm9yY2UgdGhlIHNjcm9sbAorCSogYmFycyB0byBiZSBjcmVhdGVkIGJ5IHRlbXBvcmFyaWx5IGdpdmluZyB0aGUgd2lkZ2V0IGEgc2l6ZSBhbmQKKwkqIHRoZW4gcmVzdG9yaW5nIGl0IHRvIHplcm8uCisJKiAKKwkqIE5PVEU6IFRoZSB3aWRnZXQgbXVzdCBiZSB2aXNpYmxlIGFuZCBTaXplQ29udHJvbCgpIG11c3QgYmUgdXNlZAorCSogdG8gcmVzaXplIHRoZSB3aWRnZXQgdG8gYSBtaW5pbWltIHNpemUgb3IgdGhlIHdpZGdldCB3aWxsIG5vdAorCSogY3JlYXRlIHRoZSBzY3JvbGwgYmFycy4gIFRoaXMgd29yayBhcm91bmQgY3VycmVudGx5IGZsYXNoZXMuCisJKi8KKwlPUy5TaXplQ29udHJvbCAoaGFuZGxlLCAoc2hvcnQpIDB4RkYsIChzaG9ydCkgMHhGRik7CisJT1MuU2l6ZUNvbnRyb2wgKGhhbmRsZSwgKHNob3J0KSAwLCAoc2hvcnQpIDApOworfQorCit2b2lkIGNyZWF0ZUl0ZW0gKFRhYmxlQ29sdW1uIGNvbHVtbiwgaW50IGluZGV4KSB7CisJaWYgKCEoMCA8PSBpbmRleCAmJiBpbmRleCA8PSBjb2x1bW5Db3VudCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7CisJY29sdW1uLmlkID0gQ09MVU1OX0lEICsgaWRDb3VudCsrOworCWludCBwb3NpdGlvbiA9IGluZGV4ICsgKChzdHlsZSAmIFNXVC5DSEVDSykgIT0gMCA/IDEgOiAwKTsKKwlpZiAoY29sdW1uQ291bnQgIT0gMCkgeworCQlEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYyBkZXNjID0gbmV3IERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjICgpOworCQlkZXNjLmhlYWRlckJ0bkRlc2NfdmVyc2lvbiA9IE9TLmtEYXRhQnJvd3Nlckxpc3RWaWV3TGF0ZXN0SGVhZGVyRGVzYzsKKwkJZGVzYy5wcm9wZXJ0eURlc2NfcHJvcGVydHlJRCA9IGNvbHVtbi5pZDsKKwkJZGVzYy5wcm9wZXJ0eURlc2NfcHJvcGVydHlUeXBlID0gT1Mua0RhdGFCcm93c2VyVGV4dFR5cGU7IC8vIE9TLmtEYXRhQnJvd3Nlckljb25BbmRUZXh0VHlwZQorCQlkZXNjLnByb3BlcnR5RGVzY19wcm9wZXJ0eUZsYWdzID0gT1Mua0RhdGFCcm93c2VyRGVmYXVsdFByb3BlcnR5RmxhZ3M7CisJCS8vTk9UIERPTkUKKy8vCQlkZXNjLmhlYWRlckJ0bkRlc2NfbWluaW11bVdpZHRoID0gODA7CisJCWRlc2MuaGVhZGVyQnRuRGVzY19tYXhpbXVtV2lkdGggPSAweDdGRkY7CisJCWRlc2MuaGVhZGVyQnRuRGVzY19pbml0aWFsT3JkZXIgPSBPUy5rRGF0YUJyb3dzZXJPcmRlckluY3JlYXNpbmc7CisJCU9TLkFkZERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW4gKGhhbmRsZSwgZGVzYywgcG9zaXRpb24pOworCQkvL05PVCBET05FCisJCU9TLlNldERhdGFCcm93c2VyVGFibGVWaWV3TmFtZWRDb2x1bW5XaWR0aCAoaGFuZGxlLCBjb2x1bW4uaWQsIChzaG9ydCkwKTsKKwl9IAorCWlmIChjb2x1bW5Db3VudCA9PSBjb2x1bW5zLmxlbmd0aCkgeworCQlUYWJsZUNvbHVtbiBbXSBuZXdDb2x1bW5zID0gbmV3IFRhYmxlQ29sdW1uIFtjb2x1bW5Db3VudCArIDRdOworCQlTeXN0ZW0uYXJyYXljb3B5IChjb2x1bW5zLCAwLCBuZXdDb2x1bW5zLCAwLCBjb2x1bW5zLmxlbmd0aCk7CisJCWNvbHVtbnMgPSBuZXdDb2x1bW5zOworCX0KKwlTeXN0ZW0uYXJyYXljb3B5IChjb2x1bW5zLCBpbmRleCwgY29sdW1ucywgaW5kZXggKyAxLCBjb2x1bW5Db3VudCsrIC0gaW5kZXgpOworCWNvbHVtbnMgW2luZGV4XSA9IGNvbHVtbjsKKwkvL05PVCBET05FIC0gT1BUSU1JWkUKKwlmb3IgKGludCBpPTA7IGk8aXRlbUNvdW50OyBpKyspIHsKKwkJVGFibGVJdGVtIGl0ZW0gPSBpdGVtcyBbaV07CisJCWZvciAoaW50IGo9Y29sdW1uQ291bnQtMTsgaj5pbmRleDsgLS1qKSB7CisJCQlpdGVtLnNldFRleHQgKGosIGl0ZW0uZ2V0VGV4dCAoaiAtIDEpKTsKKwkJCWl0ZW0uc2V0SW1hZ2UgKGosIGl0ZW0uZ2V0SW1hZ2UgKGogLSAxKSk7CisJCX0KKwkJaXRlbS5zZXRUZXh0IChpbmRleCwgIiIpOworCQlpdGVtLnNldEltYWdlIChpbmRleCwgbnVsbCk7CisJfQorfQorCit2b2lkIGNyZWF0ZUl0ZW0gKFRhYmxlSXRlbSBpdGVtLCBpbnQgaW5kZXgpIHsKKwlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDw9IGl0ZW1Db3VudCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7CisJaW50IFtdIGlkID0gbmV3IGludCBbXSB7aXRlbUNvdW50ICsgMX07CisJaWYgKE9TLkFkZERhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCAxLCBpZCwgMCkgIT0gT1Mubm9FcnIpIHsKKwkJZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9BRERFRCk7CisJfQorCWlmIChpdGVtQ291bnQgPT0gaXRlbXMubGVuZ3RoKSB7CisJCVRhYmxlSXRlbSBbXSBuZXdJdGVtcyA9IG5ldyBUYWJsZUl0ZW0gW2l0ZW1Db3VudCArIDRdOworCQlTeXN0ZW0uYXJyYXljb3B5IChpdGVtcywgMCwgbmV3SXRlbXMsIDAsIGl0ZW1zLmxlbmd0aCk7CisJCWl0ZW1zID0gbmV3SXRlbXM7CisJfQorCVN5c3RlbS5hcnJheWNvcHkgKGl0ZW1zLCBpbmRleCwgaXRlbXMsIGluZGV4ICsgMSwgaXRlbUNvdW50KysgLSBpbmRleCk7CisJaXRlbXMgW2luZGV4XSA9IGl0ZW07CisJT1MuVXBkYXRlRGF0YUJyb3dzZXJJdGVtcyAoaGFuZGxlLCAwLCAwLCBudWxsLCBPUy5rRGF0YUJyb3dzZXJJdGVtTm9Qcm9wZXJ0eSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtKTsKK30KKworU2Nyb2xsQmFyIGNyZWF0ZVNjcm9sbEJhciAoaW50IHN0eWxlKSB7CisJcmV0dXJuIGNyZWF0ZVN0YW5kYXJkQmFyIChzdHlsZSk7Cit9CisKK3ZvaWQgY3JlYXRlV2lkZ2V0ICgpIHsKKwlzdXBlci5jcmVhdGVXaWRnZXQgKCk7CisJaXRlbXMgPSBuZXcgVGFibGVJdGVtIFs0XTsKKwljb2x1bW5zID0gbmV3IFRhYmxlQ29sdW1uIFs0XTsKK30KKworaW50IGRlZmF1bHRUaGVtZUZvbnQgKCkgewkKKwlyZXR1cm4gT1Mua1RoZW1lVmlld3NGb250OworfQorCitwdWJsaWMgdm9pZCBkZXNlbGVjdCAoaW50IGluZGV4KSB7CisJY2hlY2tXaWRnZXQoKTsKKwlpZiAoMCA8PSBpbmRleCAmJiBpbmRleCA8IGl0ZW1Db3VudCkgeworCQlpZ25vcmVTZWxlY3QgPSB0cnVlOworCQlpbnQgW10gaWQgPSBuZXcgaW50IFtdIHtpbmRleCArIDF9OworCQlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMgKGhhbmRsZSwgaWQubGVuZ3RoLCBpZCwgT1Mua0RhdGFCcm93c2VySXRlbXNSZW1vdmUpOworCQlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKKwl9Cit9CisKK3B1YmxpYyB2b2lkIGRlc2VsZWN0IChpbnQgc3RhcnQsIGludCBlbmQpIHsKKwljaGVja1dpZGdldCgpOworCS8vTk9UIERPTkUgLSBjaGVjayByYW5nZQorCWludCBsZW5ndGggPSBlbmQgLSBzdGFydCArIDE7CisJaWYgKGxlbmd0aCA8PSAwKSByZXR1cm47CisJaW50IFtdIGlkcyA9IG5ldyBpbnQgW2xlbmd0aF07CisJZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSBpZHMgW2ldID0gZW5kIC0gaSArIDE7CisJaWdub3JlU2VsZWN0ID0gdHJ1ZTsKKwlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMgKGhhbmRsZSwgbGVuZ3RoLCBpZHMsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zUmVtb3ZlKTsKKwlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKK30KKworcHVibGljIHZvaWQgZGVzZWxlY3QgKGludCBbXSBpbmRpY2VzKSB7CisJY2hlY2tXaWRnZXQoKTsKKwlpZiAoaW5kaWNlcyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCS8vTk9UIERPTkUgLSBjaGVjayByYW5nZQorCWludCBsZW5ndGggPSBpbmRpY2VzLmxlbmd0aDsKKwlpbnQgW10gaWRzID0gbmV3IGludCBbbGVuZ3RoXTsKKwlmb3IgKGludCBpPTA7IGk8bGVuZ3RoOyBpKyspIGlkcyBbaV0gPSBpbmRpY2VzIFtsZW5ndGggLSBpIC0gMV0gKyAxOworCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGxlbmd0aCwgaWRzLCBPUy5rRGF0YUJyb3dzZXJJdGVtc1JlbW92ZSk7CisJaWdub3JlU2VsZWN0ID0gZmFsc2U7Cit9CisKK3B1YmxpYyB2b2lkIGRlc2VsZWN0QWxsICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZ25vcmVTZWxlY3QgPSB0cnVlOworCU9TLlNldERhdGFCcm93c2VyU2VsZWN0ZWRJdGVtcyAoaGFuZGxlLCAwLCBudWxsLCBPUy5rRGF0YUJyb3dzZXJJdGVtc1JlbW92ZSk7CisJaWdub3JlU2VsZWN0ID0gZmFsc2U7Cit9CisKK3ZvaWQgZGVzdHJveUl0ZW0gKFRhYmxlQ29sdW1uIGNvbHVtbikgeworCWludCBpbmRleCA9IDA7CisJd2hpbGUgKGluZGV4IDwgY29sdW1uQ291bnQpIHsKKwkJaWYgKGNvbHVtbnMgW2luZGV4XSA9PSBjb2x1bW4pIGJyZWFrOworCQlpbmRleCsrOworCX0KKwkvL05PVCBET05FIC0gT1BUSU1JWkUKKwlmb3IgKGludCBpPTA7IGk8aXRlbUNvdW50OyBpKyspIHsKKwkJVGFibGVJdGVtIGl0ZW0gPSBpdGVtcyBbaV07CisJCWZvciAoaW50IGo9aW5kZXg7IGo8Y29sdW1uQ291bnQtMTsgaisrKSB7CisJCQlpdGVtLnNldFRleHQgKGosIGl0ZW0uZ2V0VGV4dCAoaiArIDEpKTsKKwkJCWl0ZW0uc2V0SW1hZ2UgKGosIGl0ZW0uZ2V0SW1hZ2UgKGogKyAxKSk7CisJCX0KKwkJaWYgKGNvbHVtbkNvdW50ID4gMSkgeworCQkJaXRlbS5zZXRUZXh0IChjb2x1bW5Db3VudCAtIDEsICIiKTsKKwkJCWl0ZW0uc2V0SW1hZ2UgKGNvbHVtbkNvdW50IC0gMSwgbnVsbCk7CisJCX0KKwl9CisJaWYgKGNvbHVtbkNvdW50ID09IDEpIHsKKwkJLy9OT1QgRE9ORSAtIHJlYXNzaWduIENPTFVNTl9JRCB3aGVuIGxhc3QgY29sdW1uIGRlbGV0ZWQKKwl9IGVsc2UgeworCQlpZiAoT1MuUmVtb3ZlRGF0YUJyb3dzZXJUYWJsZVZpZXdDb2x1bW4gKGhhbmRsZSwgY29sdW1uLmlkKSAhPSBPUy5ub0VycikgeworCQkJZXJyb3IgKFNXVC5FUlJPUl9JVEVNX05PVF9SRU1PVkVEKTsKKwkJfQorCX0KKwlTeXN0ZW0uYXJyYXljb3B5IChjb2x1bW5zLCBpbmRleCArIDEsIGNvbHVtbnMsIGluZGV4LCAtLWNvbHVtbkNvdW50IC0gaW5kZXgpOworCWNvbHVtbnMgW2NvbHVtbkNvdW50XSA9IG51bGw7Cit9CisKK3ZvaWQgZGVzdHJveUl0ZW0gKFRhYmxlSXRlbSBpdGVtKSB7CisJaW50IGluZGV4ID0gMDsKKwl3aGlsZSAoaW5kZXggPCBpdGVtQ291bnQpIHsKKwkJaWYgKGl0ZW1zIFtpbmRleF0gPT0gaXRlbSkgYnJlYWs7CisJCWluZGV4Kys7CisJfQorCWludCBbXSBpZCA9IG5ldyBpbnQgW10ge2l0ZW1Db3VudH07CisJaWYgKE9TLlJlbW92ZURhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCBpZC5sZW5ndGgsIGlkLCAwKSAhPSBPUy5ub0VycikgeworCQllcnJvciAoU1dULkVSUk9SX0lURU1fTk9UX1JFTU9WRUQpOworCX0KKwlTeXN0ZW0uYXJyYXljb3B5IChpdGVtcywgaW5kZXggKyAxLCBpdGVtcywgaW5kZXgsIC0taXRlbUNvdW50IC0gaW5kZXgpOworCWl0ZW1zIFtpdGVtQ291bnRdID0gbnVsbDsKKwlPUy5VcGRhdGVEYXRhQnJvd3Nlckl0ZW1zIChoYW5kbGUsIDAsIDAsIG51bGwsIE9TLmtEYXRhQnJvd3Nlckl0ZW1Ob1Byb3BlcnR5LCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0pOworfQorCitwdWJsaWMgUmVjdGFuZ2xlIGdldENsaWVudEFyZWEgKCkgeworCWNoZWNrV2lkZ2V0KCk7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCksIGluc2V0ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAoaGFuZGxlLCByZWN0KTsKKwlPUy5HZXREYXRhQnJvd3NlclNjcm9sbEJhckluc2V0IChoYW5kbGUsIGluc2V0KTsKKwlyZXR1cm4gbmV3IFJlY3RhbmdsZSAoaW5zZXQubGVmdCwgaW5zZXQudG9wLCByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0ICsgaW5zZXQucmlnaHQsIHJlY3QuYm90dG9tIC0gcmVjdC50b3AgKyBpbnNldC5ib3R0b20pOworfQorCitwdWJsaWMgVGFibGVDb2x1bW4gZ2V0Q29sdW1uIChpbnQgaW5kZXgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAoISgwIDw9aW5kZXggJiYgaW5kZXggPCBjb2x1bW5Db3VudCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7CisJcmV0dXJuIGNvbHVtbnMgW2luZGV4XTsKK30KKworcHVibGljIGludCBnZXRDb2x1bW5Db3VudCAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJcmV0dXJuIGNvbHVtbkNvdW50OworfQorCitwdWJsaWMgVGFibGVDb2x1bW4gW10gZ2V0Q29sdW1ucyAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJVGFibGVDb2x1bW4gW10gcmVzdWx0ID0gbmV3IFRhYmxlQ29sdW1uIFtjb2x1bW5Db3VudF07CisJU3lzdGVtLmFycmF5Y29weSAoY29sdW1ucywgMCwgcmVzdWx0LCAwLCBjb2x1bW5Db3VudCk7CisJcmV0dXJuIHJlc3VsdDsKK30KKworcHVibGljIGludCBnZXRHcmlkTGluZVdpZHRoICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlyZXR1cm4gMDsKK30KKworcHVibGljIGludCBnZXRIZWFkZXJIZWlnaHQgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCXNob3J0IFtdIGhlaWdodCA9IG5ldyBzaG9ydCBbMV07CisJT1MuR2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckJ0bkhlaWdodCAoaGFuZGxlLCBoZWlnaHQpOworCXJldHVybiBoZWlnaHQgWzBdOworfQorCitwdWJsaWMgYm9vbGVhbiBnZXRIZWFkZXJWaXNpYmxlICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlzaG9ydCBbXSBoZWlnaHQgPSBuZXcgc2hvcnQgWzFdOworCU9TLkdldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJCdG5IZWlnaHQgKGhhbmRsZSwgaGVpZ2h0KTsKKwlyZXR1cm4gaGVpZ2h0IFswXSAhPSAwOworfQorCitwdWJsaWMgVGFibGVJdGVtIGdldEl0ZW0gKGludCBpbmRleCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmICghKDAgPD0gaW5kZXggJiYgaW5kZXggPCBpdGVtQ291bnQpKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOworCXJldHVybiBpdGVtcyBbaW5kZXhdOworfQorCitwdWJsaWMgVGFibGVJdGVtIGdldEl0ZW0gKFBvaW50IHBvaW50KSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKHBvaW50ID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAoaGFuZGxlLCByZWN0KTsKKwlvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBvaW50IHB0ID0gbmV3IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgKCk7CisJT1MuU2V0UHQgKHB0LCAoc2hvcnQpIChwb2ludC54ICsgcmVjdC5sZWZ0KSwgKHNob3J0KSAocG9pbnQueSArIHJlY3QudG9wKSk7CisJLy9OT1QgRE9ORSAtIE9QVElNSVpFCisJZm9yIChpbnQgaT0wOyBpPGl0ZW1Db3VudDsgaSsrKSB7CisJCWlmIChPUy5HZXREYXRhQnJvd3Nlckl0ZW1QYXJ0Qm91bmRzIChoYW5kbGUsIGkgKyAxLCBDT0xVTU5fSUQsIE9TLmtEYXRhQnJvd3NlclByb3BlcnR5RW5jbG9zaW5nUGFydCwgcmVjdCkgPT0gT1Mubm9FcnIpIHsKKwkJCWlmIChPUy5QdEluUmVjdCAocHQsIHJlY3QpKSByZXR1cm4gaXRlbXMgW2ldOworCQl9CisJfQorCXJldHVybiBudWxsOworfQorCitwdWJsaWMgaW50IGdldEl0ZW1Db3VudCAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJcmV0dXJuIGl0ZW1Db3VudDsKK30KKworcHVibGljIGludCBnZXRJdGVtSGVpZ2h0ICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlzaG9ydCBbXSBoZWlnaHQgPSBuZXcgc2hvcnQgWzFdOworCWlmIChPUy5HZXREYXRhQnJvd3NlclRhYmxlVmlld1Jvd0hlaWdodCAoaGFuZGxlLCBoZWlnaHQpICE9IE9TLm5vRXJyKSB7CisJCWVycm9yIChTV1QuRVJST1JfQ0FOTk9UX0dFVF9JVEVNX0hFSUdIVCk7CisJfQorCXJldHVybiBoZWlnaHQgWzBdOworfQorCitwdWJsaWMgVGFibGVJdGVtIFtdIGdldEl0ZW1zICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlUYWJsZUl0ZW0gW10gcmVzdWx0ID0gbmV3IFRhYmxlSXRlbSBbaXRlbUNvdW50XTsKKwlTeXN0ZW0uYXJyYXljb3B5IChpdGVtcywgMCwgcmVzdWx0LCAwLCBpdGVtQ291bnQpOworCXJldHVybiByZXN1bHQ7Cit9CisKK3B1YmxpYyBib29sZWFuIGdldExpbmVzVmlzaWJsZSAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJcmV0dXJuIGZhbHNlOworfQorCitwdWJsaWMgVGFibGVJdGVtIFtdIGdldFNlbGVjdGlvbiAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaW50IHB0ciA9IE9TLk5ld0hhbmRsZSAoMCk7CisJaWYgKE9TLkdldERhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCB0cnVlLCBPUy5rRGF0YUJyb3dzZXJJdGVtSXNTZWxlY3RlZCwgcHRyKSAhPSBPUy5ub0VycikgeworCQllcnJvciAoU1dULkVSUk9SX0NBTk5PVF9HRVRfU0VMRUNUSU9OKTsKKwl9CisJaW50IGNvdW50ID0gT1MuR2V0SGFuZGxlU2l6ZSAocHRyKSAvIDQ7CisJVGFibGVJdGVtIFtdIHJlc3VsdCA9IG5ldyBUYWJsZUl0ZW0gW2NvdW50XTsKKwlPUy5ITG9jayAocHRyKTsKKwlpbnQgW10gc3RhcnQgPSBuZXcgaW50IFsxXTsKKwlPUy5tZW1jcHkgKHN0YXJ0LCBwdHIsIDQpOworCWludCBbXSBpZCA9IG5ldyBpbnQgWzFdOworCWZvciAoaW50IGk9MDsgaTxjb3VudDsgaSsrKSB7CisJCU9TLm1lbWNweSAoaWQsIHN0YXJ0IFswXSArIChpICogNCksIDQpOworCQlyZXN1bHQgW2ldID0gaXRlbXMgW2lkIFswXSAtIDFdOworCX0KKwlPUy5IVW5sb2NrIChwdHIpOworCU9TLkRpc3Bvc2VIYW5kbGUgKHB0cik7CisJcmV0dXJuIHJlc3VsdDsKK30KKworcHVibGljIGludCBnZXRTZWxlY3Rpb25Db3VudCAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaW50IFtdIGNvdW50ID0gbmV3IGludCBbMV07CisJaWYgKE9TLkdldERhdGFCcm93c2VySXRlbUNvdW50IChoYW5kbGUsIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSwgdHJ1ZSwgT1Mua0RhdGFCcm93c2VySXRlbUlzU2VsZWN0ZWQsIGNvdW50KSAhPSBPUy5ub0VycikgeworCQllcnJvciAoU1dULkVSUk9SX0NBTk5PVF9HRVRfQ09VTlQpOworCX0KKwlyZXR1cm4gY291bnQgWzBdOworfQorCitwdWJsaWMgaW50IGdldFNlbGVjdGlvbkluZGV4ICgpIHsKKwljaGVja1dpZGdldCgpOworCWludCBbXSBmaXJzdCA9IG5ldyBpbnQgWzFdLCBsYXN0ID0gbmV3IGludCBbMV07CisJaWYgKE9TLkdldERhdGFCcm93c2VyU2VsZWN0aW9uQW5jaG9yIChoYW5kbGUsIGZpcnN0LCBsYXN0KSAhPSBPUy5ub0VycikgcmV0dXJuIC0xOworICAgIHJldHVybiBmaXJzdCBbMF0gLSAxOworfQorCitwdWJsaWMgaW50IFtdIGdldFNlbGVjdGlvbkluZGljZXMgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWludCBwdHIgPSBPUy5OZXdIYW5kbGUgKDApOworCWlmIChPUy5HZXREYXRhQnJvd3Nlckl0ZW1zIChoYW5kbGUsIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSwgdHJ1ZSwgT1Mua0RhdGFCcm93c2VySXRlbUlzU2VsZWN0ZWQsIHB0cikgIT0gT1Mubm9FcnIpIHsKKwkJZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfR0VUX1NFTEVDVElPTik7CisJfQorCWludCBjb3VudCA9IE9TLkdldEhhbmRsZVNpemUgKHB0cikgLyA0OworCWludCBbXSByZXN1bHQgPSBuZXcgaW50IFtjb3VudF07CisJT1MuSExvY2sgKHB0cik7CisJaW50IFtdIHN0YXJ0ID0gbmV3IGludCBbMV07CisJT1MubWVtY3B5IChzdGFydCwgcHRyLCA0KTsKKwlpbnQgW10gaWQgPSBuZXcgaW50IFsxXTsKKwlmb3IgKGludCBpPTA7IGk8Y291bnQ7IGkrKykgeworCQlPUy5tZW1jcHkgKGlkLCBzdGFydCBbMF0gKyAoaSAqIDQpLCA0KTsKKwkJcmVzdWx0IFtpXSA9IGlkIFswXSAtIDE7CisJfQorCU9TLkhVbmxvY2sgKHB0cik7CisJT1MuRGlzcG9zZUhhbmRsZSAocHRyKTsKKwlyZXR1cm4gcmVzdWx0OworfQorCitwdWJsaWMgaW50IGdldFRvcEluZGV4ICgpIHsKKwljaGVja1dpZGdldCgpOworICAgIGludFtdIHRvcCA9IG5ldyBpbnQgWzFdLCBsZWZ0ID0gbmV3IGludCBbMV07CisgICAgT1MuR2V0RGF0YUJyb3dzZXJTY3JvbGxQb3NpdGlvbiAoaGFuZGxlLCB0b3AsIGxlZnQpOworICAgIHJldHVybiB0b3AgWzBdIC8gZ2V0SXRlbUhlaWdodCAoKTsKK30KKwordm9pZCBob29rRXZlbnRzICgpIHsKKwlzdXBlci5ob29rRXZlbnRzICgpOworCURpc3BsYXkgZGlzcGxheT0gZ2V0RGlzcGxheSgpOworCURhdGFCcm93c2VyQ2FsbGJhY2tzIGNhbGxiYWNrcyA9IG5ldyBEYXRhQnJvd3NlckNhbGxiYWNrcyAoKTsKKwljYWxsYmFja3MudmVyc2lvbiA9IE9TLmtEYXRhQnJvd3NlckxhdGVzdENhbGxiYWNrczsKKwlPUy5Jbml0RGF0YUJyb3dzZXJDYWxsYmFja3MgKGNhbGxiYWNrcyk7CisJY2FsbGJhY2tzLnYxX2l0ZW1EYXRhQ2FsbGJhY2sgPSBkaXNwbGF5Lml0ZW1EYXRhUHJvYzsKKwljYWxsYmFja3MudjFfaXRlbU5vdGlmaWNhdGlvbkNhbGxiYWNrID0gZGlzcGxheS5pdGVtTm90aWZpY2F0aW9uUHJvYzsKKwlPUy5TZXREYXRhQnJvd3NlckNhbGxiYWNrcyAoaGFuZGxlLCBjYWxsYmFja3MpOworfQorCitwdWJsaWMgaW50IGluZGV4T2YgKFRhYmxlQ29sdW1uIGNvbHVtbikgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmIChjb2x1bW4gPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlmb3IgKGludCBpPTA7IGk8Y29sdW1uQ291bnQ7IGkrKykgeworCQlpZiAoY29sdW1ucyBbaV0gPT0gY29sdW1uKSByZXR1cm4gaTsKKwl9CisJcmV0dXJuIC0xOworfQorCitwdWJsaWMgaW50IGluZGV4T2YgKFRhYmxlSXRlbSBpdGVtKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKGl0ZW0gPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlmb3IgKGludCBpPTA7IGk8aXRlbUNvdW50OyBpKyspIHsKKwkJaWYgKGl0ZW1zIFtpXSA9PSBpdGVtKSByZXR1cm4gaTsKKwl9CisJcmV0dXJuIC0xOworfQorCitwdWJsaWMgYm9vbGVhbiBpc1NlbGVjdGVkIChpbnQgaW5kZXgpIHsKKwljaGVja1dpZGdldCgpOworCXJldHVybiBPUy5Jc0RhdGFCcm93c2VySXRlbVNlbGVjdGVkIChoYW5kbGUsIGluZGV4ICsgMSk7Cit9CisKK2ludCBpdGVtRGF0YVByb2MgKGludCBicm93c2VyLCBpbnQgaWQsIGludCBwcm9wZXJ0eSwgaW50IGl0ZW1EYXRhLCBpbnQgc2V0VmFsdWUpIHsKKwlpbnQgcm93ID0gaWQgLSAxOworCWlmICghKDAgPD0gcm93ICYmIHJvdyA8IGl0ZW1zLmxlbmd0aCkpIHJldHVybiBPUy5ub0VycjsKKwlUYWJsZUl0ZW0gaXRlbSA9IGl0ZW1zIFtyb3ddOworCXN3aXRjaCAocHJvcGVydHkpIHsKKwkJY2FzZSBDSEVDS19DT0xVTU5fSUQ6IHsKKwkJCWlmIChzZXRWYWx1ZSAhPSAwKSB7CisJCQkJc2hvcnQgW10gdGhlRGF0YSA9IG5ldyBzaG9ydCBbMV07CisJCQkJT1MuR2V0RGF0YUJyb3dzZXJJdGVtRGF0YUJ1dHRvblZhbHVlIChpdGVtRGF0YSwgdGhlRGF0YSk7CisJCQkJaXRlbS5jaGVja2VkID0gdGhlRGF0YSBbMF0gPT0gT1Mua1RoZW1lQnV0dG9uT247CisJCQkJRXZlbnQgZXZlbnQgPSBuZXcgRXZlbnQgKCk7CisJCQkJZXZlbnQuaXRlbSA9IGl0ZW07CisJCQkJZXZlbnQuZGV0YWlsID0gU1dULkNIRUNLOworCQkJCXBvc3RFdmVudCAoU1dULlNlbGVjdGlvbiwgZXZlbnQpOworCQkJfSBlbHNlIHsKKwkJCQlzaG9ydCB0aGVEYXRhID0gKHNob3J0KShpdGVtLmNoZWNrZWQgPyBPUy5rVGhlbWVCdXR0b25PbiA6IE9TLmtUaGVtZUJ1dHRvbk9mZik7CisJCQkJT1MuU2V0RGF0YUJyb3dzZXJJdGVtRGF0YUJ1dHRvblZhbHVlIChpdGVtRGF0YSwgdGhlRGF0YSk7CisJCQl9CisJCQlicmVhazsKKwkJfQorCX0KKwlpZiAocHJvcGVydHkgPj0gQ09MVU1OX0lEKSB7CisJCWludCBjb2x1bW4gPSAwOworCQl3aGlsZSAoY29sdW1uIDwgY29sdW1uQ291bnQpIHsKKwkJCWlmIChjb2x1bW5zIFtjb2x1bW5dLmlkID09IHByb3BlcnR5KSBicmVhazsKKwkJCWNvbHVtbisrOworCQl9CisJCVN0cmluZyB0ZXh0ID0gaXRlbS5nZXRUZXh0IChjb2x1bW4pOworCQljaGFyIFtdIGJ1ZmZlciA9IG5ldyBjaGFyIFt0ZXh0Lmxlbmd0aCAoKV07CisJCXRleHQuZ2V0Q2hhcnMgKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlciwgMCk7CisJCWludCBwdHIgPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzIChPUy5rQ0ZBbGxvY2F0b3JEZWZhdWx0LCBidWZmZXIsIGJ1ZmZlci5sZW5ndGgpOworCQlpZiAocHRyID09IDApIGVycm9yIChTV1QuRVJST1JfQ0FOTk9UX1NFVF9URVhUKTsKKwkJT1MuU2V0RGF0YUJyb3dzZXJJdGVtRGF0YVRleHQgKGl0ZW1EYXRhLCBwdHIpOworCQlPUy5DRlJlbGVhc2UgKHB0cik7CisJfQorCXJldHVybiBPUy5ub0VycjsKK30KKworaW50IGl0ZW1Ob3RpZmljYXRpb25Qcm9jIChpbnQgYnJvd3NlciwgaW50IGlkLCBpbnQgbWVzc2FnZSkgeworCWludCBpbmRleCA9IGlkIC0gMTsKKwlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbXMubGVuZ3RoKSkgcmV0dXJuIE9TLm5vRXJyOworCVRhYmxlSXRlbSBpdGVtID0gaXRlbXMgW2luZGV4XTsKKwlzd2l0Y2ggKG1lc3NhZ2UpIHsKKwkJY2FzZSBPUy5rRGF0YUJyb3dzZXJJdGVtU2VsZWN0ZWQ6CisJCWNhc2UgT1Mua0RhdGFCcm93c2VySXRlbURlc2VsZWN0ZWQ6IHsKKwkJCWlmIChpZ25vcmVTZWxlY3QpIGJyZWFrOworCQkJaW50IFtdIGZpcnN0ID0gbmV3IGludCBbMV0sIGxhc3QgPSBuZXcgaW50IFsxXTsKKwkJCU9TLkdldERhdGFCcm93c2VyU2VsZWN0aW9uQW5jaG9yIChoYW5kbGUsIGZpcnN0LCBsYXN0KTsKKwkJCWJvb2xlYW4gc2VsZWN0ZWQgPSBmYWxzZTsKKwkJCWlmICgoc3R5bGUgJiBTV1QuTVVMVEkpICE9IDApIHsKKwkJCQlpbnQgbW9kaWZpZXJzID0gT1MuR2V0Q3VycmVudEV2ZW50S2V5TW9kaWZpZXJzICgpOworCQkJCWlmICgobW9kaWZpZXJzICYgT1Muc2hpZnRLZXkpICE9IDApIHsKKwkJCQkJaWYgKG1lc3NhZ2UgPT0gT1Mua0RhdGFCcm93c2VySXRlbVNlbGVjdGVkKSB7CisJCQkJCQlzZWxlY3RlZCA9IGZpcnN0IFswXSA9PSBpZCB8fCBsYXN0IFswXSA9PSBpZDsKKwkJCQkJfSBlbHNlIHsKKwkJCQkJCXNlbGVjdGVkID0gaWQgPT0gYW5jaG9yRmlyc3QgfHwgaWQgPT0gYW5jaG9yTGFzdDsKKwkJCQkJfQorCQkJCX0gZWxzZSB7CisJCQkJCWlmICgobW9kaWZpZXJzICYgT1MuY21kS2V5KSAhPSAwKSB7CisJCQkJCQlzZWxlY3RlZCA9IHRydWU7CisJCQkJCX0gZWxzZSB7CisJCQkJCQlzZWxlY3RlZCA9IGZpcnN0IFswXSA9PSBsYXN0IFswXTsKKwkJCQkJfQorCQkJCX0KKwkJCX0gZWxzZSB7CisJCQkJc2VsZWN0ZWQgPSBtZXNzYWdlID09IE9TLmtEYXRhQnJvd3Nlckl0ZW1TZWxlY3RlZDsKKwkJCX0KKwkJCWlmIChzZWxlY3RlZCkgeworCQkJCWFuY2hvckZpcnN0ID0gZmlyc3QgWzBdOworCQkJCWFuY2hvckxhc3QgPSBsYXN0IFswXTsKKwkJCQlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKKwkJCQlldmVudC5pdGVtID0gaXRlbTsKKwkJCQlwb3N0RXZlbnQgKFNXVC5TZWxlY3Rpb24sIGV2ZW50KTsKKwkJCX0KKwkJCWJyZWFrOworCQl9CQorCQljYXNlIE9TLmtEYXRhQnJvd3Nlckl0ZW1Eb3VibGVDbGlja2VkOiB7CisJCQlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKKwkJCWV2ZW50Lml0ZW0gPSBpdGVtOworCQkJcG9zdEV2ZW50IChTV1QuRGVmYXVsdFNlbGVjdGlvbiwgZXZlbnQpOworCQkJYnJlYWs7CisJCX0KKwl9CisJcmV0dXJuIE9TLm5vRXJyOworfQorCitpbnQga0V2ZW50TW91c2VEb3duIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IHJlc3VsdCA9IHN1cGVyLmtFdmVudE1vdXNlRG93biAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKHJlc3VsdCA9PSBPUy5ub0VycikgcmV0dXJuIHJlc3VsdDsKKwkvKgorCSogRmVhdHVyZSBpbiB0aGUgTWFjaW50b3NoLiAgRm9yIHNvbWUgcmVhc29uLCB3aGVuIHRoZSB1c2VyCisJKiBjbGlja3Mgb24gdGhlIGRhdGEgYnJvd3NlciwgZm9jdXMgaXMgYXNzaWduZWQsIHRoZW4gbG9zdAorCSogYW5kIHRoZW4gcmVhc3NpZ25lZCBjYXVzaW5nIGtFdmVuQ29udHJvbFNldEZvY3VzUGFydCBldmVudHMuCisJKiBUaGUgZml4IGlzIHRvIGlnbm9yZSBrRXZlbkNvbnRyb2xTZXRGb2N1c1BhcnQgd2hlbiB0aGUgdXNlcgorCSogY2xpY2tzIGFuZCBzZW5kIHRoZSBmb2N1cyBldmVudHMgZnJvbSBrRXZlbnRNb3VzZURvd24uCisJKi8KKwlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCUNvbnRyb2wgb2xkRm9jdXMgPSBkaXNwbGF5LmdldEZvY3VzQ29udHJvbCAoKTsKKwlkaXNwbGF5Lmlnbm9yZUZvY3VzID0gdHJ1ZTsKKwlyZXN1bHQgPSBPUy5DYWxsTmV4dEV2ZW50SGFuZGxlciAobmV4dEhhbmRsZXIsIHRoZUV2ZW50KTsKKwlkaXNwbGF5Lmlnbm9yZUZvY3VzID0gZmFsc2U7CisJaWYgKG9sZEZvY3VzICE9IHRoaXMpIHsKKwkJaWYgKG9sZEZvY3VzICE9IG51bGwpIG9sZEZvY3VzLnNlbmRGb2N1c0V2ZW50IChmYWxzZSk7CisJCWlmIChpc0VuYWJsZWQgKCkpIHNlbmRGb2N1c0V2ZW50ICh0cnVlKTsKKwl9CisJcmV0dXJuIHJlc3VsdDsKK30KKworaW50IGtFdmVudFJhd0tleURvd24gKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpbnQgcmVzdWx0ID0gc3VwZXIua0V2ZW50UmF3S2V5RG93biAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKHJlc3VsdCA9PSBPUy5ub0VycikgcmV0dXJuIHJlc3VsdDsKKwkvKgorCSogRmVhdHVyZSBpbiB0aGUgTWFjaW50b3NoLiAgRm9yIHNvbWUgcmVhc29uLCB3aGVuIHRoZSB1c2VyIGhpdHMgYW4KKwkqIHVwIG9yIGRvd24gYXJyb3cgdG8gdHJhdmVyc2UgdGhlIGl0ZW1zIGluIGEgRGF0YSBCcm93c2VyLCB0aGUgaXRlbQorCSogc2Nyb2xscyB0byB0aGUgbGVmdCBzdWNoIHRoYXQgdGhlIHdoaXRlIHNwYWNlIHRoYXQgaXMgbm9ybWFsbHkKKwkqIHZpc2libGUgdG8gdGhlIHJpZ2h0IG9mIHRoZSBldmVyeSBpdGVtIGlzIHNjcm9sbGVkIG91dCBvZiB2aWV3LgorCSogVGhlIGZpeCBpcyB0byBkbyB0aGUgYXJyb3cgdHJhdmVyc2FsIGluIEphdmEgYW5kIG5vdCBjYWxsIHRoZQorCSogZGVmYXVsdCBoYW5kbGVyLgorCSovCisJaW50IFtdIGtleUNvZGUgPSBuZXcgaW50IFsxXTsKKwlPUy5HZXRFdmVudFBhcmFtZXRlciAodGhlRXZlbnQsIE9TLmtFdmVudFBhcmFtS2V5Q29kZSwgT1MudHlwZVVJbnQzMiwgbnVsbCwga2V5Q29kZS5sZW5ndGggKiA0LCBudWxsLCBrZXlDb2RlKTsKKwlzd2l0Y2ggKGtleUNvZGUgWzBdKSB7CisJCWNhc2UgMTI1OiB7IC8qIERvd24gKi8KKwkJCWludCBpbmRleCA9IGdldFNlbGVjdGlvbkluZGV4ICgpOworCQkJc2V0U2VsZWN0aW9uIChNYXRoLm1pbiAoaXRlbUNvdW50IC0gMSwgaW5kZXggKyAxKSk7CisJCQlyZXR1cm4gT1Mubm9FcnI7CisJCX0KKwkJY2FzZSAxMjY6IHsgLyogVXAqLworCQkJaW50IGluZGV4ID0gZ2V0U2VsZWN0aW9uSW5kZXggKCk7CisJCQlzZXRTZWxlY3Rpb24gKE1hdGgubWF4ICgwLCBpbmRleCAtIDEpKTsKKwkJCXJldHVybiBPUy5ub0VycjsKKwkJfQorCX0KKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50UmF3S2V5UmVwZWF0IChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IHJlc3VsdCA9IHN1cGVyLmtFdmVudFJhd0tleVJlcGVhdCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKHJlc3VsdCA9PSBPUy5ub0VycikgcmV0dXJuIHJlc3VsdDsKKwkvKgorCSogRmVhdHVyZSBpbiB0aGUgTWFjaW50b3NoLiAgRm9yIHNvbWUgcmVhc29uLCB3aGVuIHRoZSB1c2VyIGhpdHMgYW4KKwkqIHVwIG9yIGRvd24gYXJyb3cgdG8gdHJhdmVyc2UgdGhlIGl0ZW1zIGluIGEgRGF0YSBCcm93c2VyLCB0aGUgaXRlbQorCSogc2Nyb2xscyB0byB0aGUgbGVmdCBzdWNoIHRoYXQgdGhlIHdoaXRlIHNwYWNlIHRoYXQgaXMgbm9ybWFsbHkKKwkqIHZpc2libGUgdG8gdGhlIHJpZ2h0IG9mIHRoZSBldmVyeSBpdGVtIGlzIHNjcm9sbGVkIG91dCBvZiB2aWV3LgorCSogVGhlIGZpeCBpcyB0byBkbyB0aGUgYXJyb3cgdHJhdmVyc2FsIGluIEphdmEgYW5kIG5vdCBjYWxsIHRoZQorCSogZGVmYXVsdCBoYW5kbGVyLgorCSovCisJaW50IFtdIGtleUNvZGUgPSBuZXcgaW50IFsxXTsKKwlPUy5HZXRFdmVudFBhcmFtZXRlciAodGhlRXZlbnQsIE9TLmtFdmVudFBhcmFtS2V5Q29kZSwgT1MudHlwZVVJbnQzMiwgbnVsbCwga2V5Q29kZS5sZW5ndGggKiA0LCBudWxsLCBrZXlDb2RlKTsKKwlzd2l0Y2ggKGtleUNvZGUgWzBdKSB7CisJCWNhc2UgMTI1OiB7IC8qIERvd24gKi8KKwkJCWludCBpbmRleCA9IGdldFNlbGVjdGlvbkluZGV4ICgpOworCQkJc2V0U2VsZWN0aW9uIChNYXRoLm1pbiAoaXRlbUNvdW50IC0gMSwgaW5kZXggKyAxKSk7CisJCQlyZXR1cm4gT1Mubm9FcnI7CisJCX0KKwkJY2FzZSAxMjY6IHsgLyogVXAqLworCQkJaW50IGluZGV4ID0gZ2V0U2VsZWN0aW9uSW5kZXggKCk7CisJCQlzZXRTZWxlY3Rpb24gKE1hdGgubWF4ICgwLCBpbmRleCAtIDEpKTsKKwkJCXJldHVybiBPUy5ub0VycjsKKwkJfQorCX0KKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCit2b2lkIHJlbGVhc2VXaWRnZXQgKCkgeworCWZvciAoaW50IGk9MDsgaTxjb2x1bW5Db3VudDsgaSsrKSB7CisJCVRhYmxlQ29sdW1uIGNvbHVtbiA9IGNvbHVtbnMgW2ldOworCQlpZiAoIWNvbHVtbi5pc0Rpc3Bvc2VkICgpKSBjb2x1bW4ucmVsZWFzZVJlc291cmNlcyAoKTsKKwl9CisJY29sdW1ucyA9IG51bGw7CisJZm9yIChpbnQgaT0wOyBpPGl0ZW1Db3VudDsgaSsrKSB7CisJCVRhYmxlSXRlbSBpdGVtID0gaXRlbXMgW2ldOworCQlpZiAoIWl0ZW0uaXNEaXNwb3NlZCAoKSkgaXRlbS5yZWxlYXNlUmVzb3VyY2VzICgpOworCX0KKwlpdGVtcyA9IG51bGw7CisJc3VwZXIucmVsZWFzZVdpZGdldCAoKTsKK30KKworcHVibGljIHZvaWQgcmVtb3ZlIChpbnQgaW5kZXgpIHsKKwljaGVja1dpZGdldCgpOworCWlmICghKDAgPD0gaW5kZXggJiYgaW5kZXggPCBpdGVtQ291bnQpKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOworCWludCBbXSBpZCA9IG5ldyBpbnQgW10ge2l0ZW1Db3VudH07CisJaWYgKE9TLlJlbW92ZURhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCBpZC5sZW5ndGgsIGlkLCAwKSAhPSBPUy5ub0VycikgeworCQllcnJvciAoU1dULkVSUk9SX0lURU1fTk9UX1JFTU9WRUQpOworCX0KKwlUYWJsZUl0ZW0gaXRlbSA9IGl0ZW1zIFtpbmRleF07CisJU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIGluZGV4ICsgMSwgaXRlbXMsIGluZGV4LCAtLWl0ZW1Db3VudCAtIGluZGV4KTsKKwlpdGVtcyBbaXRlbUNvdW50XSA9IG51bGw7CisJaXRlbS5yZWxlYXNlUmVzb3VyY2VzICgpOworCU9TLlVwZGF0ZURhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgMCwgMCwgbnVsbCwgT1Mua0RhdGFCcm93c2VySXRlbU5vUHJvcGVydHksIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSk7Cit9CisKK3B1YmxpYyB2b2lkIHJlbW92ZSAoaW50IHN0YXJ0LCBpbnQgZW5kKSB7CisJY2hlY2tXaWRnZXQoKTsKKwlpZiAoISgwIDw9IHN0YXJ0ICYmIHN0YXJ0IDw9IGVuZCAmJiBlbmQgPCBpdGVtQ291bnQpKSB7CisJCWVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7CisJfQorCWludCBsZW5ndGggPSBlbmQgLSBzdGFydCArIDE7CisJZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSByZW1vdmUgKHN0YXJ0KTsKK30KKworcHVibGljIHZvaWQgcmVtb3ZlIChpbnQgW10gaW5kaWNlcykgeworCWlmIChpbmRpY2VzID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJaW50IFtdIG5ld0luZGljZXMgPSBuZXcgaW50IFtpbmRpY2VzLmxlbmd0aF07CisJU3lzdGVtLmFycmF5Y29weSAoaW5kaWNlcywgMCwgbmV3SW5kaWNlcywgMCwgaW5kaWNlcy5sZW5ndGgpOworCXNvcnQgKG5ld0luZGljZXMpOworCWludCBsYXN0ID0gLTE7CisJZm9yIChpbnQgaT0wOyBpPG5ld0luZGljZXMubGVuZ3RoOyBpKyspIHsKKwkJaW50IGluZGV4ID0gbmV3SW5kaWNlcyBbaV07CisJCWlmIChpbmRleCAhPSBsYXN0IHx8IGkgPT0gMCkgcmVtb3ZlIChpbmRleCk7CisJCWxhc3QgPSBpbmRleDsKKwl9Cit9CisKK3B1YmxpYyB2b2lkIHJlbW92ZUFsbCAoKSB7CisJY2hlY2tXaWRnZXQoKTsKKwlPUy5SZW1vdmVEYXRhQnJvd3Nlckl0ZW1zIChoYW5kbGUsIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSwgMCwgbnVsbCwgMCk7CisJZm9yIChpbnQgaT0wOyBpPGl0ZW1Db3VudDsgaSsrKSB7CisJCVRhYmxlSXRlbSBpdGVtID0gaXRlbXMgW2ldOworCQlpZiAoIWl0ZW0uaXNEaXNwb3NlZCAoKSkgaXRlbS5yZWxlYXNlUmVzb3VyY2VzICgpOworCX0KKwlpdGVtcyA9IG5ldyBUYWJsZUl0ZW0gWzRdOworCWl0ZW1Db3VudCA9IGNvbHVtbkNvdW50ID0gaWRDb3VudCA9IGFuY2hvckZpcnN0ID0gYW5jaG9yTGFzdCA9IDA7Cit9CisKK3B1YmxpYyB2b2lkIHJlbW92ZVNlbGVjdGlvbkxpc3RlbmVyKFNlbGVjdGlvbkxpc3RlbmVyIGxpc3RlbmVyKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJaWYgKGV2ZW50VGFibGUgPT0gbnVsbCkgcmV0dXJuOworCWV2ZW50VGFibGUudW5ob29rIChTV1QuU2VsZWN0aW9uLCBsaXN0ZW5lcik7CisJZXZlbnRUYWJsZS51bmhvb2sgKFNXVC5EZWZhdWx0U2VsZWN0aW9uLGxpc3RlbmVyKTsJCit9CisKK3B1YmxpYyB2b2lkIHNlbGVjdCAoaW50IGluZGV4KSB7CisJY2hlY2tXaWRnZXQoKTsKKwlpZiAoMCA8LSBpbmRleCAmJiBpbmRleCA8IGl0ZW1Db3VudCkgeworCQlpbnQgW10gaWQgPSBuZXcgaW50IFtdIHtpbmRleCArIDF9OworCQlpZ25vcmVTZWxlY3QgPSB0cnVlOworCQlpbnQgb3BlcmF0aW9uID0gKHN0eWxlICYgU1dULlNJTkdMRSkgIT0gMCA/IE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduOiBPUy5rRGF0YUJyb3dzZXJJdGVtc0FkZDsKKwkJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGlkLmxlbmd0aCwgaWQsIG9wZXJhdGlvbik7CisJCWlnbm9yZVNlbGVjdCA9IGZhbHNlOworCX0KK30KKworcHVibGljIHZvaWQgc2VsZWN0IChpbnQgc3RhcnQsIGludCBlbmQpIHsKKwljaGVja1dpZGdldCgpOworCS8vTk9UIERPTkUgLSBjaGVjayByYW5nZQorCWludCBsZW5ndGggPSBlbmQgLSBzdGFydCArIDE7CisJaWYgKGxlbmd0aCA8PSAwKSByZXR1cm47CisJaW50IFtdIGlkcyA9IG5ldyBpbnQgW2xlbmd0aF07CisJZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSBpZHMgW2ldID0gZW5kIC0gaSArIDE7CisJaWdub3JlU2VsZWN0ID0gdHJ1ZTsKKwlpbnQgb3BlcmF0aW9uID0gKHN0eWxlICYgU1dULlNJTkdMRSkgIT0gMCA/IE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduOiBPUy5rRGF0YUJyb3dzZXJJdGVtc0FkZDsKKwlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMgKGhhbmRsZSwgbGVuZ3RoLCBpZHMsIG9wZXJhdGlvbik7CisJaWdub3JlU2VsZWN0ID0gZmFsc2U7Cit9CisKK3B1YmxpYyB2b2lkIHNlbGVjdCAoaW50IFtdIGluZGljZXMpIHsKKwljaGVja1dpZGdldCgpOworCWlmIChpbmRpY2VzID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJLy9OT1QgRE9ORSAtIGNoZWNrIHJhbmdlCisJaW50IGxlbmd0aCA9IGluZGljZXMubGVuZ3RoOworCWludCBbXSBpZHMgPSBuZXcgaW50IFtsZW5ndGhdOworCWZvciAoaW50IGk9MDsgaTxsZW5ndGg7IGkrKykgaWRzIFtpXSA9IGluZGljZXMgW2xlbmd0aCAtIGkgLSAxXSArIDE7CisJaWdub3JlU2VsZWN0ID0gdHJ1ZTsKKwlpbnQgb3BlcmF0aW9uID0gKHN0eWxlICYgU1dULlNJTkdMRSkgIT0gMCA/IE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduOiBPUy5rRGF0YUJyb3dzZXJJdGVtc0FkZDsKKwlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMgKGhhbmRsZSwgaWRzLmxlbmd0aCwgaWRzLCBvcGVyYXRpb24pOworCWlnbm9yZVNlbGVjdCA9IGZhbHNlOworfQorCitwdWJsaWMgdm9pZCBzZWxlY3RBbGwgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmICgoc3R5bGUgJiBTV1QuU0lOR0xFKSAhPSAwKSByZXR1cm47CisJaWdub3JlU2VsZWN0ID0gdHJ1ZTsKKwlPUy5TZXREYXRhQnJvd3NlclNlbGVjdGVkSXRlbXMgKGhhbmRsZSwgMCwgbnVsbCwgT1Mua0RhdGFCcm93c2VySXRlbXNBc3NpZ24pOworCWlnbm9yZVNlbGVjdCA9IGZhbHNlOworfQorCitwdWJsaWMgdm9pZCBzZXRIZWFkZXJWaXNpYmxlIChib29sZWFuIHNob3cpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpbnQgaGVpZ2h0ID0gc2hvdyA/IGhlYWRlckhlaWdodCA6IDA7CisJT1MuU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckJ0bkhlaWdodCAoaGFuZGxlLCAoc2hvcnQpaGVpZ2h0KTsKK30KKworcHVibGljIHZvaWQgc2V0TGluZXNWaXNpYmxlIChib29sZWFuIHNob3cpIHsKKwljaGVja1dpZGdldCAoKTsKK30KKworcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uIChpbnQgaW5kZXgpIHsKKwljaGVja1dpZGdldCgpOworCWlmICgwIDwgaW5kZXggJiYgaW5kZXggPCBpdGVtQ291bnQpIHsKKwkJaW50IFtdIGlkID0gbmV3IGludCBbXSB7aW5kZXggKyAxfTsKKwkJaWdub3JlU2VsZWN0ID0gdHJ1ZTsKKwkJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGlkLmxlbmd0aCwgaWQsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduKTsKKwkJaWdub3JlU2VsZWN0ID0gZmFsc2U7CisJCXNob3dJbmRleCAoaWQgWzBdIC0gMSk7CisJfQorfQorCitwdWJsaWMgdm9pZCBzZXRTZWxlY3Rpb24gKGludCBzdGFydCwgaW50IGVuZCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWludCBsZW5ndGggPSBlbmQgLSBzdGFydCArIDE7CisJaWYgKGxlbmd0aCA8PSAwKSByZXR1cm47CisJaW50IGNvdW50ID0gbGVuZ3RoOworCWludCBbXSBpZHMgPSBuZXcgaW50IFtsZW5ndGhdOworCWZvciAoaW50IGk9c3RhcnQ7IGk8PWVuZDsgaSsrKSB7CisJCWlmICgwIDw9IGkgJiYgaSA8IGl0ZW1Db3VudCkgaWRzIFstLWNvdW50XSA9IGkgKyAxOworCX0KKwlpZiAoY291bnQgIT0gMCkgcmV0dXJuOworCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGNvdW50LCBpZHMsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduKTsKKwlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKKwlzaG93SW5kZXggKGlkcyBbMF0gLSAxKTsKK30KKworcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uIChpbnQgW10gaW5kaWNlcykgeworCWlmIChpbmRpY2VzID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJaW50IGxlbmd0aCA9IGluZGljZXMubGVuZ3RoOworCWludCBjb3VudCA9IGxlbmd0aDsKKwlpbnQgW10gaWRzID0gbmV3IGludCBbbGVuZ3RoXTsKKwlmb3IgKGludCBpPTA7IGk8bGVuZ3RoOyBpKyspIHsKKwkJaW50IGluZGV4ID0gaW5kaWNlcyBbaV07CisJCWlmICgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbUNvdW50KSBpZHMgWy0tY291bnRdID0gaW5kZXggKyAxOworCX0KKwlpZiAoY291bnQgIT0gMCkgcmV0dXJuOworCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGNvdW50LCBpZHMsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduKTsKKwlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKKwlpZiAoaWRzLmxlbmd0aCA+IDApIHNob3dJbmRleCAoaWRzIFswXSAtIDEpOworfQorCitwdWJsaWMgdm9pZCBzZXRTZWxlY3Rpb24gKFRhYmxlSXRlbSBbXSBpdGVtcykgeworCWNoZWNrV2lkZ2V0KCk7CisJaWYgKGl0ZW1zID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJaW50IGxlbmd0aCA9IGl0ZW1zLmxlbmd0aDsKKwlpbnQgY291bnQgPSBsZW5ndGg7CisJaW50IFtdIGlkcyA9IG5ldyBpbnQgW2xlbmd0aF07CisJZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSB7CisJCWludCBpbmRleCA9IGluZGV4T2YgKGl0ZW1zIFtpXSk7CisJCWlmICgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbUNvdW50KSBpZHMgWy0tY291bnRdID0gaW5kZXggKyAxOworCX0KKwlpZiAoY291bnQgIT0gMCkgcmV0dXJuOworCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGNvdW50LCBpZHMsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduKTsKKwlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKKwlpZiAoaWRzLmxlbmd0aCA+IDApIHNob3dJbmRleCAoaWRzIFswXSAtIDEpOworfQorCitwdWJsaWMgdm9pZCBzZXRUb3BJbmRleCAoaW50IGluZGV4KSB7CisJY2hlY2tXaWRnZXQoKTsKKyAgICBpbnQgW10gdG9wID0gbmV3IGludCBbMV0sIGxlZnQgPSBuZXcgaW50IFsxXTsKKyAgICBPUy5HZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uIChoYW5kbGUsIHRvcCwgbGVmdCk7CisgICAgdG9wIFswXSA9IGluZGV4ICogZ2V0SXRlbUhlaWdodCAoKTsKKyAgICBPUy5TZXREYXRhQnJvd3NlclNjcm9sbFBvc2l0aW9uIChoYW5kbGUsIHRvcCBbMF0sIGxlZnQgWzBdKTsKK30KKwordm9pZCBzaG93SW5kZXggKGludCBpbmRleCkgeworCWlmICgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbUNvdW50KSB7CisJCS8vTk9UIERPTkUgLSBkb2Vzbid0IHdvcmsgZm9yIFNXVC5DSEVDSworCQlpbnQgaWQgPSBjb2x1bW5Db3VudCA9PSAwID8gQ09MVU1OX0lEIDogY29sdW1ucyBbMF0uaWQ7CisJCXNob3J0IFtdIHdpZHRoID0gbmV3IHNob3J0IFsxXTsKKwkJT1MuR2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdOYW1lZENvbHVtbldpZHRoIChoYW5kbGUsIGlkLCB3aWR0aCk7CisJCVJlY3QgcmVjdCA9IG5ldyBSZWN0ICgpLCBpbnNldCA9IG5ldyBSZWN0ICgpOworCQlPUy5HZXRDb250cm9sQm91bmRzIChoYW5kbGUsIHJlY3QpOworCQlPUy5HZXREYXRhQnJvd3NlclNjcm9sbEJhckluc2V0IChoYW5kbGUsIGluc2V0KTsKKwkJT1MuU2V0RGF0YUJyb3dzZXJUYWJsZVZpZXdOYW1lZENvbHVtbldpZHRoIChoYW5kbGUsIGlkLCAoc2hvcnQpKHJlY3QucmlnaHQgLSByZWN0LmxlZnQgLSBpbnNldC5sZWZ0IC0gaW5zZXQucmlnaHQpKTsKKwkJT1MuUmV2ZWFsRGF0YUJyb3dzZXJJdGVtIChoYW5kbGUsIGluZGV4ICsgMSwgQ09MVU1OX0lELCAoYnl0ZSkgT1Mua0RhdGFCcm93c2VyUmV2ZWFsV2l0aG91dFNlbGVjdGluZyk7CisJCU9TLlNldERhdGFCcm93c2VyVGFibGVWaWV3TmFtZWRDb2x1bW5XaWR0aCAoaGFuZGxlLCBpZCwgKHNob3J0KXdpZHRoIFswXSk7CisJfQorfQorCitwdWJsaWMgdm9pZCBzaG93SXRlbSAoVGFibGVJdGVtIGl0ZW0pIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAoaXRlbSA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWlmIChpdGVtLmlzRGlzcG9zZWQoKSkgZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCWludCBpbmRleCA9IGluZGV4T2YgKGl0ZW0pOworCWlmIChpbmRleCAhPSAtMSkgc2hvd0luZGV4IChpbmRleCk7Cit9CisKK3B1YmxpYyB2b2lkIHNob3dTZWxlY3Rpb24gKCkgeworCWNoZWNrV2lkZ2V0KCk7CisJaW50IGluZGV4ID0gZ2V0U2VsZWN0aW9uSW5kZXggKCk7CisJaWYgKGluZGV4ID49IDApIHNob3dJbmRleCAoaW5kZXgpOworfQorCit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVGFibGVDb2x1bW4uamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UYWJsZUNvbHVtbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU3YTc2ODQKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVGFibGVDb2x1bW4uamF2YQpAQCAtMCwwICsxLDE4MyBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0czsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKyAKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkRhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2M7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKKworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuKjsKKworcHVibGljIGNsYXNzIFRhYmxlQ29sdW1uIGV4dGVuZHMgSXRlbSB7CisJVGFibGUgcGFyZW50OworCWludCBpZDsKKwlib29sZWFuIHJlc2l6YWJsZTsKKworcHVibGljIFRhYmxlQ29sdW1uIChUYWJsZSBwYXJlbnQsIGludCBzdHlsZSkgeworCXN1cGVyIChwYXJlbnQsIGNoZWNrU3R5bGUgKHN0eWxlKSk7CisJcmVzaXphYmxlID0gdHJ1ZTsKKwl0aGlzLnBhcmVudCA9IHBhcmVudDsKKwlwYXJlbnQuY3JlYXRlSXRlbSAodGhpcywgcGFyZW50LmdldENvbHVtbkNvdW50ICgpKTsKK30KKworcHVibGljIFRhYmxlQ29sdW1uIChUYWJsZSBwYXJlbnQsIGludCBzdHlsZSwgaW50IGluZGV4KSB7CisJc3VwZXIgKHBhcmVudCwgY2hlY2tTdHlsZSAoc3R5bGUpKTsKKwlyZXNpemFibGUgPSB0cnVlOworCXRoaXMucGFyZW50ID0gcGFyZW50OworCXBhcmVudC5jcmVhdGVJdGVtICh0aGlzLCBpbmRleCk7Cit9CisKK3B1YmxpYyB2b2lkIGFkZENvbnRyb2xMaXN0ZW5lcihDb250cm9sTGlzdGVuZXIgbGlzdGVuZXIpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlUeXBlZExpc3RlbmVyIHR5cGVkTGlzdGVuZXIgPSBuZXcgVHlwZWRMaXN0ZW5lciAobGlzdGVuZXIpOworCWFkZExpc3RlbmVyIChTV1QuUmVzaXplLHR5cGVkTGlzdGVuZXIpOworCWFkZExpc3RlbmVyIChTV1QuTW92ZSx0eXBlZExpc3RlbmVyKTsKK30KKworcHVibGljIHZvaWQgYWRkU2VsZWN0aW9uTGlzdGVuZXIgKFNlbGVjdGlvbkxpc3RlbmVyIGxpc3RlbmVyKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJVHlwZWRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IFR5cGVkTGlzdGVuZXIgKGxpc3RlbmVyKTsKKwlhZGRMaXN0ZW5lciAoU1dULlNlbGVjdGlvbix0eXBlZExpc3RlbmVyKTsKKwlhZGRMaXN0ZW5lciAoU1dULkRlZmF1bHRTZWxlY3Rpb24sdHlwZWRMaXN0ZW5lcik7Cit9CisKK3N0YXRpYyBpbnQgY2hlY2tTdHlsZSAoaW50IHN0eWxlKSB7CisJcmV0dXJuIGNoZWNrQml0cyAoc3R5bGUsIFNXVC5MRUZULCBTV1QuQ0VOVEVSLCBTV1QuUklHSFQsIDAsIDAsIDApOworfQorCitwcm90ZWN0ZWQgdm9pZCBjaGVja1N1YmNsYXNzICgpIHsKKwlpZiAoIWlzVmFsaWRTdWJjbGFzcyAoKSkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1NVQkNMQVNTKTsKK30KKworcHVibGljIGludCBnZXRBbGlnbm1lbnQgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmICgoc3R5bGUgJiBTV1QuTEVGVCkgIT0gMCkgcmV0dXJuIFNXVC5MRUZUOworCWlmICgoc3R5bGUgJiBTV1QuQ0VOVEVSKSAhPSAwKSByZXR1cm4gU1dULkNFTlRFUjsKKwlpZiAoKHN0eWxlICYgU1dULlJJR0hUKSAhPSAwKSByZXR1cm4gU1dULlJJR0hUOworCXJldHVybiBTV1QuTEVGVDsKK30KKworcHVibGljIERpc3BsYXkgZ2V0RGlzcGxheSAoKSB7CisJVGFibGUgcGFyZW50ID0gdGhpcy5wYXJlbnQ7CisJaWYgKHBhcmVudCA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX1dJREdFVF9ESVNQT1NFRCk7CisJcmV0dXJuIHBhcmVudC5nZXREaXNwbGF5ICgpOworfQorCitTdHJpbmcgZ2V0TmFtZVRleHQgKCkgeworCXJldHVybiBnZXRUZXh0ICgpOworfQorCitwdWJsaWMgVGFibGUgZ2V0UGFyZW50ICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlyZXR1cm4gcGFyZW50OworfQorCitwdWJsaWMgYm9vbGVhbiBnZXRSZXNpemFibGUgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCXJldHVybiByZXNpemFibGU7Cit9CisKK3B1YmxpYyBpbnQgZ2V0V2lkdGggKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCXNob3J0IFtdIHdpZHRoID0gbmV3IHNob3J0IFsxXTsKKwlPUy5HZXREYXRhQnJvd3NlclRhYmxlVmlld05hbWVkQ29sdW1uV2lkdGggKHBhcmVudC5oYW5kbGUsIGlkLCB3aWR0aCk7CisJcmV0dXJuIHdpZHRoIFswXTsKK30KKworcHVibGljIHZvaWQgcGFjayAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJLy9OT1QgRE9ORQorCU9TLlNldERhdGFCcm93c2VyVGFibGVWaWV3TmFtZWRDb2x1bW5XaWR0aCAocGFyZW50LmhhbmRsZSwgaWQsIChzaG9ydCk2MCk7Cit9CisKK3ZvaWQgcmVsZWFzZUNoaWxkICgpIHsKKwlzdXBlci5yZWxlYXNlQ2hpbGQgKCk7CisJcGFyZW50LmRlc3Ryb3lJdGVtICh0aGlzKTsKK30KKwordm9pZCByZWxlYXNlV2lkZ2V0ICgpIHsKKwlzdXBlci5yZWxlYXNlV2lkZ2V0ICgpOworCXBhcmVudCA9IG51bGw7Cit9CisKK3B1YmxpYyB2b2lkIHJlbW92ZUNvbnRyb2xMaXN0ZW5lciAoQ29udHJvbExpc3RlbmVyIGxpc3RlbmVyKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJaWYgKGV2ZW50VGFibGUgPT0gbnVsbCkgcmV0dXJuOworCWV2ZW50VGFibGUudW5ob29rIChTV1QuTW92ZSwgbGlzdGVuZXIpOworCWV2ZW50VGFibGUudW5ob29rIChTV1QuUmVzaXplLCBsaXN0ZW5lcik7Cit9CisKK3B1YmxpYyB2b2lkIHJlbW92ZVNlbGVjdGlvbkxpc3RlbmVyKFNlbGVjdGlvbkxpc3RlbmVyIGxpc3RlbmVyKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJaWYgKGV2ZW50VGFibGUgPT0gbnVsbCkgcmV0dXJuOworCWV2ZW50VGFibGUudW5ob29rIChTV1QuU2VsZWN0aW9uLCBsaXN0ZW5lcik7CisJZXZlbnRUYWJsZS51bmhvb2sgKFNXVC5EZWZhdWx0U2VsZWN0aW9uLGxpc3RlbmVyKTsJCit9CisKK3B1YmxpYyB2b2lkIHNldEFsaWdubWVudCAoaW50IGFsaWdubWVudCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmICgoYWxpZ25tZW50ICYgKFNXVC5MRUZUIHwgU1dULlJJR0hUIHwgU1dULkNFTlRFUikpID09IDApIHJldHVybjsKKwlpbnQgaW5kZXggPSBwYXJlbnQuaW5kZXhPZiAodGhpcyk7CisJaWYgKGluZGV4ID09IC0xIHx8IGluZGV4ID09IDApIHJldHVybjsKKwlzdHlsZSAmPSB+KFNXVC5MRUZUIHwgU1dULlJJR0hUIHwgU1dULkNFTlRFUik7CisJc3R5bGUgfD0gYWxpZ25tZW50ICYgKFNXVC5MRUZUIHwgU1dULlJJR0hUIHwgU1dULkNFTlRFUik7Cit9CisKK3B1YmxpYyB2b2lkIHNldEltYWdlIChJbWFnZSBpbWFnZSkgeworCWNoZWNrV2lkZ2V0KCk7CisJaWYgKGltYWdlICE9IG51bGwgJiYgaW1hZ2UuaXNEaXNwb3NlZCAoKSkgeworCQllcnJvciAoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCX0KKwlpbnQgaW5kZXggPSBwYXJlbnQuaW5kZXhPZiAodGhpcyk7CisJaWYgKGluZGV4ID09IC0xKSByZXR1cm47CisJc3VwZXIuc2V0SW1hZ2UgKGltYWdlKTsKK30KKworcHVibGljIHZvaWQgc2V0UmVzaXphYmxlIChib29sZWFuIHJlc2l6YWJsZSkgeworCWNoZWNrV2lkZ2V0ICgpOworCXRoaXMucmVzaXphYmxlID0gcmVzaXphYmxlOworfQorCitwdWJsaWMgdm9pZCBzZXRUZXh0IChTdHJpbmcgc3RyaW5nKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKHN0cmluZyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCXN1cGVyLnNldFRleHQgKHN0cmluZyk7CisJY2hhciBbXSBidWZmZXIgPSBuZXcgY2hhciBbdGV4dC5sZW5ndGggKCldOworCXRleHQuZ2V0Q2hhcnMgKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlciwgMCk7CisJaW50IGk9MCwgaj0wOworCXdoaWxlIChpIDwgYnVmZmVyLmxlbmd0aCkgeworCQlpZiAoKGJ1ZmZlciBbaisrXSA9IGJ1ZmZlciBbaSsrXSkgPT0gTW5lbW9uaWMpIHsKKwkJCWlmIChpID09IGJ1ZmZlci5sZW5ndGgpIHtjb250aW51ZTt9CisJCQlpZiAoYnVmZmVyIFtpXSA9PSBNbmVtb25pYykge2krKzsgY29udGludWU7fQorCQkJai0tOworCQl9CisJfQorCWludCBzdHIgPSBPUy5DRlN0cmluZ0NyZWF0ZVdpdGhDaGFyYWN0ZXJzIChPUy5rQ0ZBbGxvY2F0b3JEZWZhdWx0LCBidWZmZXIsIGopOworCWlmIChzdHIgPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfU0VUX1RFWFQpOworCURhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjIGRlc2MgPSBuZXcgRGF0YUJyb3dzZXJMaXN0Vmlld0hlYWRlckRlc2MgKCk7CisJZGVzYy52ZXJzaW9uID0gT1Mua0RhdGFCcm93c2VyTGlzdFZpZXdMYXRlc3RIZWFkZXJEZXNjOworCS8vTk9UIERPTkUgLSBmb3Igc29tZSByZWFzb24gdGhpcyBjYWxsIEdQJ3MKKy8vCU9TLkdldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJEZXNjIChwYXJlbnQuaGFuZGxlLCBpZCwgZGVzYyk7CisJZGVzYy5tYXhpbXVtV2lkdGggPSAweDdGRkY7CisJZGVzYy50aXRsZVN0cmluZyA9IHN0cjsKKwlPUy5TZXREYXRhQnJvd3Nlckxpc3RWaWV3SGVhZGVyRGVzYyAocGFyZW50LmhhbmRsZSwgaWQsIGRlc2MpOworCU9TLkNGUmVsZWFzZSAoc3RyKTsKK30KKworcHVibGljIHZvaWQgc2V0V2lkdGggKGludCB3aWR0aCkgeworCWNoZWNrV2lkZ2V0ICgpOworCU9TLlNldERhdGFCcm93c2VyVGFibGVWaWV3TmFtZWRDb2x1bW5XaWR0aCAocGFyZW50LmhhbmRsZSwgaWQsIChzaG9ydCl3aWR0aCk7Cit9CisKK30KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UYWJsZUl0ZW0uamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UYWJsZUl0ZW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOGYxNWZiCi0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1RhYmxlSXRlbS5qYXZhCkBAIC0wLDAgKzEsMjIzIEBACitwYWNrYWdlIG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzOworCisvKgorICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIFRoaXMgZmlsZSBpcyBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCisgKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAorICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKKyAqLworIAoraW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uT1M7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuSXRlbTsKKyAKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuKjsKKworcHVibGljIGNsYXNzIFRhYmxlSXRlbSBleHRlbmRzIEl0ZW0geworCVRhYmxlIHBhcmVudDsKKwlTdHJpbmcgW10gc3RyaW5nczsKKwlJbWFnZSBbXSBpbWFnZXM7CisJYm9vbGVhbiBjaGVja2VkOworCQorcHVibGljIFRhYmxlSXRlbSAoVGFibGUgcGFyZW50LCBpbnQgc3R5bGUpIHsKKwlzdXBlciAocGFyZW50LCBzdHlsZSk7CisJdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CisJcGFyZW50LmNyZWF0ZUl0ZW0gKHRoaXMsIHBhcmVudC5nZXRJdGVtQ291bnQgKCkpOworfQorCitwdWJsaWMgVGFibGVJdGVtIChUYWJsZSBwYXJlbnQsIGludCBzdHlsZSwgaW50IGluZGV4KSB7CisJc3VwZXIgKHBhcmVudCwgc3R5bGUpOworCXRoaXMucGFyZW50ID0gcGFyZW50OworCXBhcmVudC5jcmVhdGVJdGVtICh0aGlzLCBpbmRleCk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNoZWNrU3ViY2xhc3MgKCkgeworCWlmICghaXNWYWxpZFN1YmNsYXNzICgpKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MpOworfQorCitwdWJsaWMgQ29sb3IgZ2V0QmFja2dyb3VuZCAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJLy9OT1QgRE9ORQorCXJldHVybiBnZXREaXNwbGF5ICgpLmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfV0hJVEUpOworfQorCitwdWJsaWMgUmVjdGFuZ2xlIGdldEJvdW5kcyAoaW50IGluZGV4KSB7CisJY2hlY2tXaWRnZXQoKTsKKwkvL05PVCBET05FCisJcmV0dXJuIG5ldyBSZWN0YW5nbGUgKDAsIDAsIDAsIDApOworfQorCitwdWJsaWMgYm9vbGVhbiBnZXRDaGVja2VkICgpIHsKKwljaGVja1dpZGdldCgpOworCWlmICgocGFyZW50LnN0eWxlICYgU1dULkNIRUNLKSA9PSAwKSByZXR1cm4gZmFsc2U7CisJcmV0dXJuIGNoZWNrZWQ7Cit9CisKK3B1YmxpYyBEaXNwbGF5IGdldERpc3BsYXkgKCkgeworCVRhYmxlIHBhcmVudCA9IHRoaXMucGFyZW50OworCWlmIChwYXJlbnQgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9XSURHRVRfRElTUE9TRUQpOworCXJldHVybiBwYXJlbnQuZ2V0RGlzcGxheSAoKTsKK30KKworcHVibGljIENvbG9yIGdldEZvcmVncm91bmQgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCS8vTk9UIERPTkUKKwlyZXR1cm4gZ2V0RGlzcGxheSAoKS5nZXRTeXN0ZW1Db2xvciAoU1dULkNPTE9SX0JMQUNLKTsKK30KKworcHVibGljIGJvb2xlYW4gZ2V0R3JheWVkICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAoKHBhcmVudC5zdHlsZSAmIFNXVC5DSEVDSykgPT0gMCkgcmV0dXJuIGZhbHNlOworCS8vTk9UIERPTkUKKwlyZXR1cm4gZmFsc2U7Cit9CisKK3B1YmxpYyBJbWFnZSBnZXRJbWFnZSAoaW50IGluZGV4KSB7CisJY2hlY2tXaWRnZXQoKTsKKwlpZiAoaW5kZXggPT0gMCkgcmV0dXJuIHN1cGVyLmdldEltYWdlICgpOworCWlmIChpbWFnZXMgIT0gbnVsbCkgeworCQlpZiAoMCA8PSBpbmRleCAmJiBpbmRleCA8IGltYWdlcy5sZW5ndGgpIHJldHVybiBpbWFnZXMgW2luZGV4XTsKKwl9CisJcmV0dXJuIG51bGw7Cit9CisKK3B1YmxpYyBSZWN0YW5nbGUgZ2V0SW1hZ2VCb3VuZHMgKGludCBpbmRleCkgeworCWNoZWNrV2lkZ2V0KCk7CisJLy9OT1QgRE9ORQorCXJldHVybiBuZXcgUmVjdGFuZ2xlICgwLCAwLCAwLCAwKTsKK30KKworcHVibGljIGludCBnZXRJbWFnZUluZGVudCAoKSB7CisJY2hlY2tXaWRnZXQoKTsKKwlyZXR1cm4gMDsKK30KKworcHVibGljIFRhYmxlIGdldFBhcmVudCAoKSB7CisJY2hlY2tXaWRnZXQoKTsKKwlyZXR1cm4gcGFyZW50OworfQorCitwdWJsaWMgU3RyaW5nIGdldFRleHQgKGludCBpbmRleCkgeworCWNoZWNrV2lkZ2V0KCk7CisJaWYgKGluZGV4ID09IDApIHJldHVybiBzdXBlci5nZXRUZXh0ICgpOworCWludCBpdGVtSW5kZXggPSBwYXJlbnQuaW5kZXhPZiAodGhpcyk7CisJaWYgKGl0ZW1JbmRleCA9PSAtMSkgZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfR0VUX1RFWFQpOworCWlmIChzdHJpbmdzICE9IG51bGwpIHsKKwkJaWYgKDAgPD0gaW5kZXggJiYgaW5kZXggPCBzdHJpbmdzLmxlbmd0aCkgeworCQkJU3RyaW5nIHN0cmluZyA9IHN0cmluZ3MgW2luZGV4XTsKKwkJCXJldHVybiBzdHJpbmcgIT0gbnVsbCA/IHN0cmluZyA6ICIiOworCQl9CisJfQorCXJldHVybiAiIjsKK30KKwordm9pZCByZWxlYXNlQ2hpbGQgKCkgeworCXN1cGVyLnJlbGVhc2VDaGlsZCAoKTsKKwlwYXJlbnQuZGVzdHJveUl0ZW0gKHRoaXMpOworfQorCit2b2lkIHJlbGVhc2VXaWRnZXQgKCkgeworCXN1cGVyLnJlbGVhc2VXaWRnZXQgKCk7CisJcGFyZW50ID0gbnVsbDsKK30KKworcHVibGljIHZvaWQgc2V0QmFja2dyb3VuZCAoQ29sb3IgY29sb3IpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAoY29sb3IgIT0gbnVsbCAmJiBjb2xvci5pc0Rpc3Bvc2VkICgpKSB7CisJCVNXVC5lcnJvciAoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCX0KKwkvL05PVCBET05FCit9CisKK3B1YmxpYyB2b2lkIHNldENoZWNrZWQgKGJvb2xlYW4gY2hlY2tlZCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmICgocGFyZW50LnN0eWxlICYgU1dULkNIRUNLKSA9PSAwKSByZXR1cm47CisJaW50IGl0ZW1JbmRleCA9IHBhcmVudC5pbmRleE9mICh0aGlzKTsKKwlpZiAoaXRlbUluZGV4ID09IC0xKSByZXR1cm47CisJdGhpcy5jaGVja2VkID0gY2hlY2tlZDsKKwlpbnQgW10gaWQgPSBuZXcgaW50IFtdIHtpdGVtSW5kZXggKyAxfTsKKwlPUy5VcGRhdGVEYXRhQnJvd3Nlckl0ZW1zIChwYXJlbnQuaGFuZGxlLCAwLCBpZC5sZW5ndGgsIGlkLCBPUy5rRGF0YUJyb3dzZXJJdGVtTm9Qcm9wZXJ0eSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtKTsKK30KKworcHVibGljIHZvaWQgc2V0Rm9yZWdyb3VuZCAoQ29sb3IgY29sb3IpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAoY29sb3IgIT0gbnVsbCAmJiBjb2xvci5pc0Rpc3Bvc2VkICgpKSB7CisJCVNXVC5lcnJvciAoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCX0KKwkvL05PVCBET05FCit9CisKK3B1YmxpYyB2b2lkIHNldEdyYXllZCAoYm9vbGVhbiBncmF5ZWQpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAoKHBhcmVudC5zdHlsZSAmIFNXVC5DSEVDSykgPT0gMCkgcmV0dXJuOworCS8vTk9UIERPTkUKK30KKworcHVibGljIHZvaWQgc2V0SW1hZ2UgKEltYWdlIFtdIGltYWdlcykgeworCWNoZWNrV2lkZ2V0KCk7CisJaWYgKGltYWdlcyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWZvciAoaW50IGk9MDsgaTxpbWFnZXMubGVuZ3RoOyBpKyspIHsKKwkJc2V0SW1hZ2UgKGksIGltYWdlcyBbaV0pOworCX0KK30KKworcHVibGljIHZvaWQgc2V0SW1hZ2UgKGludCBpbmRleCwgSW1hZ2UgaW1hZ2UpIHsKKwljaGVja1dpZGdldCgpOworCWlmIChpbWFnZSAhPSBudWxsICYmIGltYWdlLmlzRGlzcG9zZWQgKCkpIHsKKwkJZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCX0KKwlpbnQgaXRlbUluZGV4ID0gcGFyZW50LmluZGV4T2YgKHRoaXMpOworCWlmIChpdGVtSW5kZXggPT0gLTEpIHJldHVybjsKKwlpZiAoaW5kZXggPT0gMCkgeworCQlzdXBlci5zZXRJbWFnZSAoaW1hZ2UpOworCX0KKwkvL05PVCBET05FCit9CisKK3B1YmxpYyB2b2lkIHNldEltYWdlIChJbWFnZSBpbWFnZSkgeworCWNoZWNrV2lkZ2V0ICgpOworCXNldEltYWdlICgwLCBpbWFnZSk7Cit9CisKK3B1YmxpYyB2b2lkIHNldEltYWdlSW5kZW50IChpbnQgaW5kZW50KSB7CisJY2hlY2tXaWRnZXQoKTsKKwlpZiAoaW5kZW50IDwgMCkgcmV0dXJuOworfQorCitwdWJsaWMgdm9pZCBzZXRUZXh0IChTdHJpbmcgW10gc3RyaW5ncykgeworCWNoZWNrV2lkZ2V0KCk7CisJaWYgKHN0cmluZ3MgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlmb3IgKGludCBpPTA7IGk8c3RyaW5ncy5sZW5ndGg7IGkrKykgeworCQlTdHJpbmcgc3RyaW5nID0gc3RyaW5ncyBbaV07CisJCWlmIChzdHJpbmcgIT0gbnVsbCkgc2V0VGV4dCAoaSwgc3RyaW5nKTsKKwl9Cit9CisKK3B1YmxpYyB2b2lkIHNldFRleHQgKGludCBpbmRleCwgU3RyaW5nIHN0cmluZykgeworCWNoZWNrV2lkZ2V0KCk7CisJaWYgKHN0cmluZyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWludCBpdGVtSW5kZXggPSBwYXJlbnQuaW5kZXhPZiAodGhpcyk7CisJaWYgKGl0ZW1JbmRleCA9PSAtMSkgcmV0dXJuOworCWlmIChpbmRleCA9PSAwKSB7CisJCXN1cGVyLnNldFRleHQgKHN0cmluZyk7CisJfQorCWludCBjb2x1bW5Db3VudCA9IHBhcmVudC5jb2x1bW5Db3VudDsKKwlpZiAoMCA8PSBpbmRleCAmJiBpbmRleCA8IGNvbHVtbkNvdW50KSB7CisJCWlmIChzdHJpbmdzID09IG51bGwpIHN0cmluZ3MgPSBuZXcgU3RyaW5nIFtjb2x1bW5Db3VudF07CisJCWlmIChzdHJpbmdzLmxlbmd0aCA8IGNvbHVtbkNvdW50KSB7CisJCQlTdHJpbmcgW10gbmV3U3RyaW5ncyA9IG5ldyBTdHJpbmcgW2NvbHVtbkNvdW50XTsKKwkJCVN5c3RlbS5hcnJheWNvcHkgKHN0cmluZ3MsIDAsIG5ld1N0cmluZ3MsIDAsIHN0cmluZ3MubGVuZ3RoKTsKKwkJCXN0cmluZ3MgPSBuZXdTdHJpbmdzOworCQl9CisJCWlmICgwIDw9IGluZGV4ICYmIGluZGV4IDwgc3RyaW5ncy5sZW5ndGgpIHN0cmluZ3MgW2luZGV4XSA9IHN0cmluZzsKKwl9CisJaW50IFtdIGlkID0gbmV3IGludCBbXSB7aXRlbUluZGV4ICsgMX07CisJT1MuVXBkYXRlRGF0YUJyb3dzZXJJdGVtcyAocGFyZW50LmhhbmRsZSwgMCwgaWQubGVuZ3RoLCBpZCwgT1Mua0RhdGFCcm93c2VySXRlbU5vUHJvcGVydHksIE9TLmtEYXRhQnJvd3Nlck5vSXRlbSk7Cit9CisKK3B1YmxpYyB2b2lkIHNldFRleHQgKFN0cmluZyBzdHJpbmcpIHsKKwljaGVja1dpZGdldCgpOworCXNldFRleHQgKDAsIHN0cmluZyk7Cit9CisKK30KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UZXh0LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVGV4dC5qYXZhCmluZGV4IDEzY2EyMGEuLjI0OTBiNTIgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UZXh0LmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1RleHQuamF2YQpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVG9vbEJhci5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1Rvb2xCYXIuamF2YQppbmRleCAyZDgzMjE5Li5kMzFmYTEwIDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVG9vbEJhci5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Ub29sQmFyLmphdmEKQEAgLTcsNzAgKzcsMTYgQEAKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAgKi8KICAKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLk9TOworIAogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOwogCi0vKioKLSAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIHN1cHBvcnQgdGhlIGxheW91dCBvZiBzZWxlY3RhYmxlCi0gKiB0b29sIGJhciBpdGVtcy4KLSAqIDxwPgotICogVGhlIGl0ZW0gY2hpbGRyZW4gdGhhdCBtYXkgYmUgYWRkZWQgdG8gaW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MKLSAqIG11c3QgYmUgb2YgdHlwZSA8Y29kZT5Ub29sSXRlbTwvY29kZT4uCi0gKiA8L3A+PHA+Ci0gKiBOb3RlIHRoYXQgYWx0aG91Z2ggdGhpcyBjbGFzcyBpcyBhIHN1YmNsYXNzIG9mIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4sCi0gKiBpdCBkb2VzIG5vdCBtYWtlIHNlbnNlIHRvIGFkZCA8Y29kZT5Db250cm9sPC9jb2RlPiBjaGlsZHJlbiB0byBpdCwKLSAqIG9yIHNldCBhIGxheW91dCBvbiBpdC4KLSAqIDwvcD48cD4KLSAqIDxkbD4KLSAqIDxkdD48Yj5TdHlsZXM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+RkxBVCwgV1JBUCwgUklHSFQsIEhPUklaT05UQUwsIFZFUlRJQ0FMPC9kZD4KLSAqIDxkdD48Yj5FdmVudHM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+KG5vbmUpPC9kZD4KLSAqIDwvZGw+Ci0gKiA8cD4KLSAqIE5vdGU6IE9ubHkgb25lIG9mIHRoZSBzdHlsZXMgSE9SSVpPTlRBTCBhbmQgVkVSVElDQUwgbWF5IGJlIHNwZWNpZmllZC4KLSAqIDwvcD48cD4KLSAqIElNUE9SVEFOVDogVGhpcyBjbGFzcyBpcyA8ZW0+bm90PC9lbT4gaW50ZW5kZWQgdG8gYmUgc3ViY2xhc3NlZC4KLSAqIDwvcD4KLSAqLwogcHVibGljIGNsYXNzIFRvb2xCYXIgZXh0ZW5kcyBDb21wb3NpdGUgewogCWludCBpdGVtQ291bnQ7CiAJVG9vbEl0ZW0gW10gaXRlbXM7Ci0JLy8gQVcKLQlib29sZWFuIGZHb3RTaXplPSBmYWxzZTsKLQkvLyBBVwotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gaXRzIHBhcmVudAotICogYW5kIGEgc3R5bGUgdmFsdWUgZGVzY3JpYmluZyBpdHMgYmVoYXZpb3IgYW5kIGFwcGVhcmFuY2UuCi0gKiA8cD4KLSAqIFRoZSBzdHlsZSB2YWx1ZSBpcyBlaXRoZXIgb25lIG9mIHRoZSBzdHlsZSBjb25zdGFudHMgZGVmaW5lZCBpbgotICogY2xhc3MgPGNvZGU+U1dUPC9jb2RlPiB3aGljaCBpcyBhcHBsaWNhYmxlIHRvIGluc3RhbmNlcyBvZiB0aGlzCi0gKiBjbGFzcywgb3IgbXVzdCBiZSBidWlsdCBieSA8ZW0+Yml0d2lzZSBPUjwvZW0+J2luZyB0b2dldGhlciAKLSAqICh0aGF0IGlzLCB1c2luZyB0aGUgPGNvZGU+aW50PC9jb2RlPiAifCIgb3BlcmF0b3IpIHR3byBvciBtb3JlCi0gKiBvZiB0aG9zZSA8Y29kZT5TV1Q8L2NvZGU+IHN0eWxlIGNvbnN0YW50cy4gVGhlIGNsYXNzIGRlc2NyaXB0aW9uCi0gKiBsaXN0cyB0aGUgc3R5bGUgY29uc3RhbnRzIHRoYXQgYXJlIGFwcGxpY2FibGUgdG8gdGhlIGNsYXNzLgotICogU3R5bGUgYml0cyBhcmUgYWxzbyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIGNvbXBvc2l0ZSBjb250cm9sIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqIEBwYXJhbSBzdHlsZSB0aGUgc3R5bGUgb2YgY29udHJvbCB0byBjb25zdHJ1Y3QKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU1dUI0ZMQVQKLSAqIEBzZWUgU1dUI1dSQVAKLSAqIEBzZWUgU1dUI1JJR0hUCi0gKiBAc2VlIFNXVCNIT1JJWk9OVEFMCi0gKiBAc2VlIFNXVCNWRVJUSUNBTAotICogQHNlZSBXaWRnZXQjY2hlY2tTdWJjbGFzcwotICogQHNlZSBXaWRnZXQjZ2V0U3R5bGUKLSAqLworCisKIHB1YmxpYyBUb29sQmFyIChDb21wb3NpdGUgcGFyZW50LCBpbnQgc3R5bGUpIHsKIAlzdXBlciAocGFyZW50LCBjaGVja1N0eWxlIChzdHlsZSkpOwogCQpAQCAtODIsOCArMjgsMTMgQEAKIAkqIHRoZSBiaXRzIHVzaW5nIHRoZSBvcmlnaW5hbCBzdHlsZSBzdXBwbGllZCBieSB0aGUKIAkqIHByb2dyYW1tZXIuCiAJKi8KLQl0aGlzLnN0eWxlID0gY2hlY2tCaXRzIChzdHlsZSwgU1dULkhPUklaT05UQUwsIFNXVC5WRVJUSUNBTCwgMCwgMCwgMCwgMCk7CisJaWYgKChzdHlsZSAmIFNXVC5WRVJUSUNBTCkgIT0gMCkgeworCQl0aGlzLnN0eWxlIHw9IFNXVC5WRVJUSUNBTDsKKwl9IGVsc2UgeworCQl0aGlzLnN0eWxlIHw9IFNXVC5IT1JJWk9OVEFMOworCX0KIH0KKwogc3RhdGljIGludCBjaGVja1N0eWxlIChpbnQgc3R5bGUpIHsKIAkvKgogCSogRXZlbiB0aG91Z2ggaXQgaXMgbGVnYWwgdG8gY3JlYXRlIHRoaXMgd2lkZ2V0CkBAIC05NCwyNyArNDUsMjggQEAKIAkqLwogCXJldHVybiBzdHlsZSAmIH4oU1dULkhfU0NST0xMIHwgU1dULlZfU0NST0xMKTsKIH0KKwogcHJvdGVjdGVkIHZvaWQgY2hlY2tTdWJjbGFzcyAoKSB7CiAJaWYgKCFpc1ZhbGlkU3ViY2xhc3MgKCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9TVUJDTEFTUyk7CiB9CisKIHB1YmxpYyBQb2ludCBjb21wdXRlU2l6ZSAoaW50IHdIaW50LCBpbnQgaEhpbnQsIGJvb2xlYW4gY2hhbmdlZCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaW50IHdpZHRoID0gd0hpbnQsIGhlaWdodCA9IGhIaW50OwogCWlmICh3SGludCA9PSBTV1QuREVGQVVMVCkgd2lkdGggPSAweDdGRkZGRkZGOwogCWlmIChoSGludCA9PSBTV1QuREVGQVVMVCkgaGVpZ2h0ID0gMHg3RkZGRkZGRjsKIAlpbnQgW10gcmVzdWx0ID0gbGF5b3V0ICh3aWR0aCwgaGVpZ2h0LCBmYWxzZSk7Ci0JaW50IGJvcmRlciA9IGdldEJvcmRlcldpZHRoICgpICogMjsKIAlQb2ludCBleHRlbnQgPSBuZXcgUG9pbnQgKHJlc3VsdCBbMV0sIHJlc3VsdCBbMl0pOwogCWlmICh3SGludCAhPSBTV1QuREVGQVVMVCkgZXh0ZW50LnggPSB3SGludDsKIAlpZiAoaEhpbnQgIT0gU1dULkRFRkFVTFQpIGV4dGVudC55ID0gaEhpbnQ7Ci0JZXh0ZW50LnggKz0gYm9yZGVyOwotCWV4dGVudC55ICs9IGJvcmRlcjsKIAlyZXR1cm4gZXh0ZW50OwogfQotdm9pZCBjcmVhdGVIYW5kbGUgKGludCBpbmRleCkgewotCXN1cGVyLmNyZWF0ZUhhbmRsZSAoaW5kZXgpOwotCXN0YXRlICY9IH5DQU5WQVM7CisKK3ZvaWQgY3JlYXRlSGFuZGxlICgpIHsKKwlzdGF0ZSB8PSBHUkFCOworCXN1cGVyLmNyZWF0ZUhhbmRsZSAocGFyZW50LmhhbmRsZSk7CiB9CisKIHZvaWQgY3JlYXRlSXRlbSAoVG9vbEl0ZW0gaXRlbSwgaW50IGluZGV4KSB7CiAJaWYgKCEoMCA8PSBpbmRleCAmJiBpbmRleCA8PSBpdGVtQ291bnQpKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOwogCWlmIChpdGVtQ291bnQgPT0gaXRlbXMubGVuZ3RoKSB7CkBAIC0xMjIsMTUgKzc0LDIyIEBACiAJCVN5c3RlbS5hcnJheWNvcHkgKGl0ZW1zLCAwLCBuZXdJdGVtcywgMCwgaXRlbXMubGVuZ3RoKTsKIAkJaXRlbXMgPSBuZXdJdGVtczsKIAl9Ci0JaXRlbS5jcmVhdGVXaWRnZXQgKGluZGV4KTsKKwlpdGVtLmNyZWF0ZVdpZGdldCAoKTsKIAlTeXN0ZW0uYXJyYXljb3B5IChpdGVtcywgaW5kZXgsIGl0ZW1zLCBpbmRleCArIDEsIGl0ZW1Db3VudCsrIC0gaW5kZXgpOwogCWl0ZW1zIFtpbmRleF0gPSBpdGVtOworCWlmIChwYXJlbnQuZm9udCAhPSBudWxsKSBpdGVtLnNldEZvbnRTdHlsZSAocGFyZW50LmZvbnQpOwogfQotdm9pZCBjcmVhdGVXaWRnZXQgKGludCBpbmRleCkgewotCXN1cGVyLmNyZWF0ZVdpZGdldCAoaW5kZXgpOworCit2b2lkIGNyZWF0ZVdpZGdldCAoKSB7CisJc3VwZXIuY3JlYXRlV2lkZ2V0ICgpOwogCWl0ZW1zID0gbmV3IFRvb2xJdGVtIFs0XTsKIAlpdGVtQ291bnQgPSAwOwogfQorCitpbnQgZGVmYXVsdFRoZW1lRm9udCAoKSB7CQorCXJldHVybiBPUy5rVGhlbWVUb29sYmFyRm9udDsKK30KKwogdm9pZCBkZXN0cm95SXRlbSAoVG9vbEl0ZW0gaXRlbSkgewogCWludCBpbmRleCA9IDA7CiAJd2hpbGUgKGluZGV4IDwgaXRlbUNvdW50KSB7CkBAIC0xNDEsMTg3ICsxMDAsMTE2IEBACiAJU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIGluZGV4ICsgMSwgaXRlbXMsIGluZGV4LCAtLWl0ZW1Db3VudCAtIGluZGV4KTsKIAlpdGVtcyBbaXRlbUNvdW50XSA9IG51bGw7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIGl0ZW0gYXQgdGhlIGdpdmVuLCB6ZXJvLXJlbGF0aXZlIGluZGV4IGluIHRoZQotICogcmVjZWl2ZXIuIFRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIGluZGV4IGlzIG91dCBvZiByYW5nZS4KLSAqCi0gKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBpdGVtIHRvIHJldHVybgotICogQHJldHVybiB0aGUgaXRlbSBhdCB0aGUgZ2l2ZW4gaW5kZXgKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9SQU5HRSAtIGlmIHRoZSBpbmRleCBpcyBub3QgYmV0d2VlbiAwIGFuZCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBsaXN0IG1pbnVzIDEgKGluY2x1c2l2ZSk8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCit2b2lkIGRyYXdXaWRnZXQgKGludCBjb250cm9sKSB7CisJZHJhd0JhY2tncm91bmQgKGhhbmRsZSwgYmFja2dyb3VuZCk7Cit9CisKIHB1YmxpYyBUb29sSXRlbSBnZXRJdGVtIChpbnQgaW5kZXgpIHsKIAljaGVja1dpZGdldCgpOwotCVRvb2xJdGVtIFtdIGl0ZW1zID0gZ2V0SXRlbXMgKCk7Ci0JaWYgKDAgPD0gaW5kZXggJiYgaW5kZXggPCBpdGVtcy5sZW5ndGgpIHJldHVybiBpdGVtcyBbaW5kZXhdOworCWlmICgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbUNvdW50KSByZXR1cm4gaXRlbXMgW2luZGV4XTsKIAllcnJvciAoU1dULkVSUk9SX0lOVkFMSURfUkFOR0UpOwogCXJldHVybiBudWxsOwogfQogCi0vKioKLSAqIFJldHVybnMgdGhlIGl0ZW0gYXQgdGhlIGdpdmVuIHBvaW50IGluIHRoZSByZWNlaXZlcgotICogb3IgbnVsbCBpZiBubyBzdWNoIGl0ZW0gZXhpc3RzLiBUaGUgcG9pbnQgaXMgaW4gdGhlCi0gKiBjb29yZGluYXRlIHN5c3RlbSBvZiB0aGUgcmVjZWl2ZXIuCi0gKgotICogQHBhcmFtIHBvaW50IHRoZSBwb2ludCB1c2VkIHRvIGxvY2F0ZSB0aGUgaXRlbQotICogQHJldHVybiB0aGUgaXRlbSBhdCB0aGUgZ2l2ZW4gcG9pbnQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyBUb29sSXRlbSBnZXRJdGVtIChQb2ludCBwdCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JVG9vbEl0ZW0gW10gaXRlbXMgPSBnZXRJdGVtcyAoKTsKLQlmb3IgKGludCBpPTA7IGk8aXRlbXMubGVuZ3RoOyBpKyspIHsKKwlpZiAocHQgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlmb3IgKGludCBpPTA7IGk8aXRlbUNvdW50OyBpKyspIHsKIAkJUmVjdGFuZ2xlIHJlY3QgPSBpdGVtcyBbaV0uZ2V0Qm91bmRzICgpOwogCQlpZiAocmVjdC5jb250YWlucyAocHQpKSByZXR1cm4gaXRlbXMgW2ldOwogCX0KIAlyZXR1cm4gbnVsbDsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgaXRlbXMgY29udGFpbmVkIGluIHRoZSByZWNlaXZlci4KLSAqCi0gKiBAcmV0dXJuIHRoZSBudW1iZXIgb2YgaXRlbXMKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyBpbnQgZ2V0SXRlbUNvdW50ICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBpdGVtQ291bnQ7CiB9Ci0vKioKLSAqIFJldHVybnMgYW4gYXJyYXkgb2YgPGNvZGU+VGFiSXRlbTwvY29kZT5zIHdoaWNoIGFyZSB0aGUgaXRlbXMKLSAqIGluIHRoZSByZWNlaXZlci4gCi0gKiA8cD4KLSAqIE5vdGU6IFRoaXMgaXMgbm90IHRoZSBhY3R1YWwgc3RydWN0dXJlIHVzZWQgYnkgdGhlIHJlY2VpdmVyCi0gKiB0byBtYWludGFpbiBpdHMgbGlzdCBvZiBpdGVtcywgc28gbW9kaWZ5aW5nIHRoZSBhcnJheSB3aWxsCi0gKiBub3QgYWZmZWN0IHRoZSByZWNlaXZlci4gCi0gKiA8L3A+Ci0gKgotICogQHJldHVybiB0aGUgaXRlbXMgaW4gdGhlIHJlY2VpdmVyCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBUb29sSXRlbSBbXSBnZXRJdGVtcyAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlUb29sSXRlbSBbXSByZXN1bHQgPSBuZXcgVG9vbEl0ZW0gW2l0ZW1Db3VudF07CiAJU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIDAsIHJlc3VsdCwgMCwgaXRlbUNvdW50KTsKIAlyZXR1cm4gcmVzdWx0OwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBudW1iZXIgb2Ygcm93cyBpbiB0aGUgcmVjZWl2ZXIuIFdoZW4KLSAqIHRoZSByZWNlaXZlciBoYXMgdGhlIDxjb2RlPldSQVA8L2NvZGU+IHN0eWxlLCB0aGUKLSAqIG51bWJlciBvZiByb3dzIGNhbiBiZSBncmVhdGVyIHRoYW4gb25lLiAgT3RoZXJ3aXNlLAotICogdGhlIG51bWJlciBvZiByb3dzIGlzIGFsd2F5cyBvbmUuCi0gKgotICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGl0ZW1zCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBpbnQgZ2V0Um93Q291bnQgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJUmVjdGFuZ2xlIHJlY3QgPSBnZXRDbGllbnRBcmVhICgpOwogCXJldHVybiBsYXlvdXQgKHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0LCBmYWxzZSkgWzBdOwogfQotLyoqCi0gKiBTZWFyY2hlcyB0aGUgcmVjZWl2ZXIncyBsaXN0IHN0YXJ0aW5nIGF0IHRoZSBmaXJzdCBpdGVtCi0gKiAoaW5kZXggMCkgdW50aWwgYW4gaXRlbSBpcyBmb3VuZCB0aGF0IGlzIGVxdWFsIHRvIHRoZSAKLSAqIGFyZ3VtZW50LCBhbmQgcmV0dXJucyB0aGUgaW5kZXggb2YgdGhhdCBpdGVtLiBJZiBubyBpdGVtCi0gKiBpcyBmb3VuZCwgcmV0dXJucyAtMS4KLSAqCi0gKiBAcGFyYW0gaXRlbSB0aGUgc2VhcmNoIGl0ZW0KLSAqIEByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBpdGVtCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgdG9vbCBpdGVtIGlzIG51bGw8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfQVJHVU1FTlQgLSBpZiB0aGUgdG9vbCBpdGVtIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGludCBpbmRleE9mIChUb29sSXRlbSBpdGVtKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoaXRlbSA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWlmIChpdGVtLmlzRGlzcG9zZWQoKSkgZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwotCVRvb2xJdGVtIFtdIGl0ZW1zID0gZ2V0SXRlbXMgKCk7Ci0JZm9yIChpbnQgaT0wOyBpPGl0ZW1zLmxlbmd0aDsgaSsrKSB7CisJZm9yIChpbnQgaT0wOyBpPGl0ZW1Db3VudDsgaSsrKSB7CiAJCWlmIChpdGVtcyBbaV0gPT0gaXRlbSkgcmV0dXJuIGk7CiAJfQogCXJldHVybiAtMTsKIH0KLWludCBbXSBsYXlvdXRIb3Jpem9udGFsIChpbnQgbldpZHRoLCBpbnQgbkhlaWdodCwgYm9vbGVhbiByZXNpemUpIHsKLQlpbnQgeFNwYWNpbmcgPSAwLCB5U3BhY2luZyA9IChzdHlsZSAmIFNXVC5OT19GT0NVUykgIT0gMCA/IDQgOiAyOworCitpbnQgW10gbGF5b3V0SG9yaXpvbnRhbCAoaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBib29sZWFuIHJlc2l6ZSkgeworCWludCB4U3BhY2luZyA9IDAsIHlTcGFjaW5nID0gMjsKIAlpbnQgbWFyZ2luV2lkdGggPSAwLCBtYXJnaW5IZWlnaHQgPSAwOwotCVRvb2xJdGVtIFtdIGNoaWxkcmVuID0gZ2V0SXRlbXMgKCk7Ci0JaW50IGxlbmd0aCA9IGNoaWxkcmVuLmxlbmd0aDsKIAlpbnQgeCA9IG1hcmdpbldpZHRoLCB5ID0gbWFyZ2luSGVpZ2h0OwogCWludCBtYXhIZWlnaHQgPSAwLCBtYXhYID0gMCwgcm93cyA9IDE7CiAJYm9vbGVhbiB3cmFwID0gKHN0eWxlICYgU1dULldSQVApICE9IDA7Ci0JZm9yIChpbnQgaT0wOyBpPGxlbmd0aDsgaSsrKSB7Ci0JCVRvb2xJdGVtIGNoaWxkID0gY2hpbGRyZW4gW2ldOwotCQlSZWN0YW5nbGUgcmVjdCA9IGNoaWxkLmdldEJvdW5kcyAoKTsKLQkJaWYgKHdyYXAgJiYgaSAhPSAwICYmIHggKyByZWN0LndpZHRoID4gbldpZHRoKSB7CisJaW50IGl0ZW1IZWlnaHQgPSAwOworCWZvciAoaW50IGk9MDsgaTxpdGVtQ291bnQ7IGkrKykgeworCQlSZWN0YW5nbGUgcmVjdCA9IGl0ZW1zIFtpXS5nZXRCb3VuZHMgKCk7CisJCWl0ZW1IZWlnaHQgPSBNYXRoLm1heCAoaXRlbUhlaWdodCwgcmVjdC5oZWlnaHQpOworCX0KKwlmb3IgKGludCBpPTA7IGk8aXRlbUNvdW50OyBpKyspIHsKKwkJVG9vbEl0ZW0gaXRlbSA9IGl0ZW1zIFtpXTsKKwkJUmVjdGFuZ2xlIHJlY3QgPSBpdGVtLmdldEJvdW5kcyAoKTsKKwkJaWYgKHdyYXAgJiYgaSAhPSAwICYmIHggKyByZWN0LndpZHRoID4gd2lkdGgpIHsKIAkJCXJvd3MrKzsKLQkJCXggPSBtYXJnaW5XaWR0aDsgIHkgKz0geVNwYWNpbmcgKyBtYXhIZWlnaHQ7CisJCQl4ID0gbWFyZ2luV2lkdGg7CisJCQl5ICs9IHlTcGFjaW5nICsgbWF4SGVpZ2h0OwogCQkJbWF4SGVpZ2h0ID0gMDsKIAkJfQogCQltYXhIZWlnaHQgPSBNYXRoLm1heCAobWF4SGVpZ2h0LCByZWN0LmhlaWdodCk7CiAJCWlmIChyZXNpemUpIHsKLQkJCWNoaWxkLnNldEJvdW5kcyAoeCwgeSwgcmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpOworCQkJaXRlbS5zZXRCb3VuZHMgKHgsIHksIHJlY3Qud2lkdGgsIGl0ZW1IZWlnaHQpOwogCQl9CiAJCXggKz0geFNwYWNpbmcgKyByZWN0LndpZHRoOwogCQltYXhYID0gTWF0aC5tYXggKG1heFgsIHgpOwogCX0KIAlyZXR1cm4gbmV3IGludCBbXSB7cm93cywgbWF4WCwgeSArIG1heEhlaWdodH07CiB9Ci1pbnQgW10gbGF5b3V0VmVydGljYWwgKGludCBuV2lkdGgsIGludCBuSGVpZ2h0LCBib29sZWFuIHJlc2l6ZSkgewotCWludCB4U3BhY2luZyA9IChzdHlsZSAmIFNXVC5OT19GT0NVUykgIT0gMCA/IDQgOiAyLCB5U3BhY2luZyA9IDA7CisKK2ludCBbXSBsYXlvdXRWZXJ0aWNhbCAoaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBib29sZWFuIHJlc2l6ZSkgeworCWludCB4U3BhY2luZyA9IDIsIHlTcGFjaW5nID0gMDsKIAlpbnQgbWFyZ2luV2lkdGggPSAwLCBtYXJnaW5IZWlnaHQgPSAwOwotCVRvb2xJdGVtIFtdIGNoaWxkcmVuID0gZ2V0SXRlbXMgKCk7Ci0JaW50IGxlbmd0aCA9IGNoaWxkcmVuLmxlbmd0aDsKIAlpbnQgeCA9IG1hcmdpbldpZHRoLCB5ID0gbWFyZ2luSGVpZ2h0OwogCWludCBtYXhXaWR0aCA9IDAsIG1heFkgPSAwLCBjb2xzID0gMTsKIAlib29sZWFuIHdyYXAgPSAoc3R5bGUgJiBTV1QuV1JBUCkgIT0gMDsKLQlmb3IgKGludCBpPTA7IGk8bGVuZ3RoOyBpKyspIHsKLQkJVG9vbEl0ZW0gY2hpbGQgPSBjaGlsZHJlbiBbaV07Ci0JCVJlY3RhbmdsZSByZWN0ID0gY2hpbGQuZ2V0Qm91bmRzICgpOwotCQlpZiAod3JhcCAmJiBpICE9IDAgJiYgeSArIHJlY3QuaGVpZ2h0ID4gbkhlaWdodCkgeworCWludCBpdGVtV2lkdGggPSAwOworCWZvciAoaW50IGk9MDsgaTxpdGVtQ291bnQ7IGkrKykgeworCQlSZWN0YW5nbGUgcmVjdCA9IGl0ZW1zIFtpXS5nZXRCb3VuZHMgKCk7CisJCWl0ZW1XaWR0aCA9IE1hdGgubWF4IChpdGVtV2lkdGgsIHJlY3Qud2lkdGgpOworCX0KKwlmb3IgKGludCBpPTA7IGk8aXRlbUNvdW50OyBpKyspIHsKKwkJVG9vbEl0ZW0gaXRlbSA9IGl0ZW1zIFtpXTsKKwkJUmVjdGFuZ2xlIHJlY3QgPSBpdGVtLmdldEJvdW5kcyAoKTsKKwkJaWYgKHdyYXAgJiYgaSAhPSAwICYmIHkgKyByZWN0LmhlaWdodCA+IGhlaWdodCkgewogCQkJY29scysrOwotCQkJeCArPSB4U3BhY2luZyArIG1heFdpZHRoOyAgeSA9IG1hcmdpbkhlaWdodDsKKwkJCXggKz0geFNwYWNpbmcgKyBtYXhXaWR0aDsKKwkJCXkgPSBtYXJnaW5IZWlnaHQ7CiAJCQltYXhXaWR0aCA9IDA7CiAJCX0KIAkJbWF4V2lkdGggPSBNYXRoLm1heCAobWF4V2lkdGgsIHJlY3Qud2lkdGgpOwogCQlpZiAocmVzaXplKSB7Ci0JCQljaGlsZC5zZXRCb3VuZHMgKHgsIHksIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTsKKwkJCWl0ZW0uc2V0Qm91bmRzICh4LCB5LCBpdGVtV2lkdGgsIHJlY3QuaGVpZ2h0KTsKIAkJfQogCQl5ICs9IHlTcGFjaW5nICsgcmVjdC5oZWlnaHQ7CiAJCW1heFkgPSBNYXRoLm1heCAobWF4WSwgeSk7CiAJfQogCXJldHVybiBuZXcgaW50IFtdIHtjb2xzLCB4ICsgbWF4V2lkdGgsIG1heFl9OwogfQorCiBpbnQgW10gbGF5b3V0IChpbnQgbldpZHRoLCBpbnQgbkhlaWdodCwgYm9vbGVhbiByZXNpemUpIHsKIAlpZiAoKHN0eWxlICYgU1dULlZFUlRJQ0FMKSAhPSAwKSB7CiAJCXJldHVybiBsYXlvdXRWZXJ0aWNhbCAobldpZHRoLCBuSGVpZ2h0LCByZXNpemUpOwpAQCAtMzI5LDg3ICsyMTcsNTEgQEAKIAkJcmV0dXJuIGxheW91dEhvcml6b250YWwgKG5XaWR0aCwgbkhlaWdodCwgcmVzaXplKTsKIAl9CiB9Ci0vKiBBVwotYm9vbGVhbiBtbmVtb25pY0hpdCAoY2hhciBrZXkpIHsKLQlmb3IgKGludCBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgaSsrKSB7Ci0JCVRvb2xJdGVtIGl0ZW0gPSBpdGVtcyBbaV07Ci0JCWlmIChpdGVtICE9IG51bGwpIHsKLQkJCWNoYXIgbW5lbW9uaWMgPSBmaW5kTW5lbW9uaWMgKGl0ZW0uZ2V0VGV4dCAoKSk7Ci0JCQlpZiAobW5lbW9uaWMgIT0gJ1wwJykgewotCQkJCWlmIChDaGFyYWN0ZXIudG9VcHBlckNhc2UgKGtleSkgPT0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlIChtbmVtb25pYykpIHsKLQkJCQkJT1MuWG1Qcm9jZXNzVHJhdmVyc2FsIChpdGVtLmhhbmRsZSwgT1MuWG1UUkFWRVJTRV9DVVJSRU5UKTsKLQkJCQkJaXRlbS5jbGljayAoZmFsc2UsIG51bGwpOwotCQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCQl9Ci0JCQl9Ci0JCX0KLQl9Ci0JcmV0dXJuIGZhbHNlOwotfQotYm9vbGVhbiBtbmVtb25pY01hdGNoIChjaGFyIGtleSkgewotCWZvciAoaW50IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHsKLQkJVG9vbEl0ZW0gaXRlbSA9IGl0ZW1zIFtpXTsKLQkJaWYgKGl0ZW0gIT0gbnVsbCkgewotCQkJY2hhciBtbmVtb25pYyA9IGZpbmRNbmVtb25pYyAoaXRlbS5nZXRUZXh0ICgpKTsKLQkJCWlmIChtbmVtb25pYyAhPSAnXDAnKSB7Ci0JCQkJaWYgKENoYXJhY3Rlci50b1VwcGVyQ2FzZSAoa2V5KSA9PSBDaGFyYWN0ZXIudG9VcHBlckNhc2UgKG1uZW1vbmljKSkgewotCQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCQl9Ci0JCQl9Ci0JCX0KLQl9Ci0JcmV0dXJuIGZhbHNlOwotfQotKi8KLXZvaWQgcHJvcGFnYXRlV2lkZ2V0IChib29sZWFuIGVuYWJsZWQpIHsKLQlzdXBlci5wcm9wYWdhdGVXaWRnZXQgKGVuYWJsZWQpOwotCWZvciAoaW50IGk9MDsgaTxpdGVtQ291bnQ7IGkrKykgewotCQlpdGVtcyBbaV0ucHJvcGFnYXRlV2lkZ2V0IChlbmFibGVkKTsKLQl9Ci19CisKIHZvaWQgcmVsYXlvdXQgKCkgewogCWlmIChkcmF3Q291bnQgPiAwKSByZXR1cm47CiAJUmVjdGFuZ2xlIHJlY3QgPSBnZXRDbGllbnRBcmVhICgpOwogCWxheW91dCAocmVjdC53aWR0aCwgcmVjdC5oZWlnaHQsIHRydWUpOwogfQorCiB2b2lkIHJlbGF5b3V0IChpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKIAlpZiAoZHJhd0NvdW50ID4gMCkgcmV0dXJuOwogCWxheW91dCAod2lkdGgsIGhlaWdodCwgdHJ1ZSk7CiB9CisKIHZvaWQgcmVsZWFzZVdpZGdldCAoKSB7CiAJZm9yIChpbnQgaT0wOyBpPGl0ZW1Db3VudDsgaSsrKSB7CiAJCVRvb2xJdGVtIGl0ZW0gPSBpdGVtcyBbaV07Ci0JCWlmICghaXRlbS5pc0Rpc3Bvc2VkICgpKSB7Ci0JCQlpdGVtLnJlbGVhc2VXaWRnZXQgKCk7Ci0JCQlpdGVtLnJlbGVhc2VIYW5kbGUgKCk7Ci0JCX0KKwkJaWYgKCFpdGVtLmlzRGlzcG9zZWQgKCkpIGl0ZW0ucmVsZWFzZVJlc291cmNlcyAoKTsKIAl9CiAJaXRlbXMgPSBudWxsOwogCXN1cGVyLnJlbGVhc2VXaWRnZXQgKCk7CiB9Ci1wdWJsaWMgdm9pZCBzZXRCb3VuZHMgKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7Ci0JZkdvdFNpemU9IHRydWU7Ci0Jc3VwZXIuc2V0Qm91bmRzICh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKLQlSZWN0YW5nbGUgcmVjdCA9IGdldENsaWVudEFyZWEgKCk7Ci0JcmVsYXlvdXQgKHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTsKKworaW50IHNldEJvdW5kcyAoaW50IGNvbnRyb2wsIGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBib29sZWFuIG1vdmUsIGJvb2xlYW4gcmVzaXplLCBib29sZWFuIGV2ZW50cykgeworCWludCByZXN1bHQgPSBzdXBlci5zZXRCb3VuZHMgKGNvbnRyb2wsIHgsIHksIHdpZHRoLCBoZWlnaHQsIG1vdmUsIHJlc2l6ZSwgZXZlbnRzKTsKKwlpZiAoKHJlc3VsdCAmIFJFU0laRUQpICE9IDApIHsKKwkJUmVjdGFuZ2xlIHJlY3QgPSBnZXRDbGllbnRBcmVhICgpOworCQlyZWxheW91dCAocmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpOworCX0KKwlyZXR1cm4gcmVzdWx0OwogfQorCit2b2lkIHNldEZvbnRTdHlsZSAoRm9udCBmb250KSB7CisJc3VwZXIuc2V0Rm9udFN0eWxlIChmb250KTsKKwlmb3IgKGludCBpPTA7IGk8aXRlbUNvdW50OyBpKyspIHsKKwkJVG9vbEl0ZW0gaXRlbSA9IGl0ZW1zIFtpXTsKKwkJaXRlbS5zZXRGb250U3R5bGUgKGZvbnQpOworCQlQb2ludCBzaXplID0gaXRlbS5jb21wdXRlU2l6ZSAoKTsKKwkJaXRlbS5zZXRTaXplIChzaXplLngsIHNpemUueSwgZmFsc2UpOworCX0KKwlyZWxheW91dCAoKTsKK30KKwogcHVibGljIHZvaWQgc2V0UmVkcmF3IChib29sZWFuIHJlZHJhdykgewogCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKHJlZHJhdykgewotCQlpZiAoLS1kcmF3Q291bnQgPT0gMCkgcmVsYXlvdXQoKTsKLQl9IGVsc2UgewotCQlkcmF3Q291bnQrKzsKLQl9CisJc3VwZXIuc2V0UmVkcmF3IChyZWRyYXcpOworCWlmIChyZWRyYXcgJiYgZHJhd0NvdW50ID09IDApIHJlbGF5b3V0KCk7CiB9Ci1wdWJsaWMgdm9pZCBzZXRTaXplIChpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKLQlmR290U2l6ZT0gdHJ1ZTsKLQlzdXBlci5zZXRTaXplICh3aWR0aCwgaGVpZ2h0KTsKLQlSZWN0YW5nbGUgcmVjdCA9IGdldENsaWVudEFyZWEgKCk7Ci0JcmVsYXlvdXQgKHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTsKLX0KLS8qIEFXCi1pbnQgdHJhdmVyc2FsQ29kZSAoaW50IGtleSwgWEtleUV2ZW50IHhFdmVudCkgewotCXJldHVybiBzdXBlci50cmF2ZXJzYWxDb2RlIChrZXksIHhFdmVudCkgfCBTV1QuVFJBVkVSU0VfTU5FTU9OSUM7Ci19Ci0qLworCiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVG9vbEl0ZW0uamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Ub29sSXRlbS5qYXZhCmluZGV4IDY0MWIzMmIuLjJhZjBkZmYgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Ub29sSXRlbS5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9Ub29sSXRlbS5qYXZhCkBAIC03LDc4ICs3LDI4IEBACiAgKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAogICovCiAgCi1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uKjsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLk9TOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uQ29udHJvbEZvbnRTdHlsZVJlYzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkhNSGVscENvbnRlbnRSZWM7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5SZWN0OwogCi0vKioKLSAqIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIHJlcHJlc2VudCBhIHNlbGVjdGFibGUgdXNlciBpbnRlcmZhY2Ugb2JqZWN0Ci0gKiB0aGF0IHJlcHJlc2VudHMgYSBidXR0b24gaW4gYSB0b29sIGJhci4KLSAqIDxkbD4KLSAqIDxkdD48Yj5TdHlsZXM6PC9iPjwvZHQ+Ci0gKiA8ZGQ+UFVTSCwgQ0hFQ0ssIFJBRElPLCBTRVBBUkFUT1IsIERST1BfRE9XTjwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPlNlbGVjdGlvbjwvZGQ+Ci0gKiA8L2RsPgotICogPHA+Ci0gKiBOb3RlOiBPbmx5IG9uZSBvZiB0aGUgc3R5bGVzIENIRUNLLCBQVVNILCBSQURJTywgU0VQQVJBVE9SIGFuZCBEUk9QX0RPV04gCi0gKiBtYXkgYmUgc3BlY2lmaWVkLgotICogPC9wPjxwPgotICogSU1QT1JUQU5UOiBUaGlzIGNsYXNzIGlzIDxlbT5ub3Q8L2VtPiBpbnRlbmRlZCB0byBiZSBzdWJjbGFzc2VkLgotICogPC9wPgotICovCitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOworCiBwdWJsaWMgY2xhc3MgVG9vbEl0ZW0gZXh0ZW5kcyBJdGVtIHsKKwlpbnQgaGFuZGxlLCBpY29uSGFuZGxlLCBsYWJlbEhhbmRsZSwgYXJyb3dIYW5kbGU7CisJaW50IGNJY29uLCBsYWJlbENJY29uLCBhcnJvd0NJY29uOwogCVRvb2xCYXIgcGFyZW50OwogCUltYWdlIGhvdEltYWdlLCBkaXNhYmxlZEltYWdlOwogCVN0cmluZyB0b29sVGlwVGV4dDsKIAlDb250cm9sIGNvbnRyb2w7Ci0JYm9vbGVhbiBzZXQ7Ci0JCi0JLy8gQVcKLQlwcml2YXRlIGJvb2xlYW4gZlByZXNzZWQ7Ci0JcHJpdmF0ZSBzaG9ydFtdIGZQcmV2SW5mbzsKLQlwcml2YXRlIGludCBmQmFja2dyb3VuZDsKLQkvLyBBVwotCQorCiAJc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1dJRFRIID0gMjQ7CiAJc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0hFSUdIVCA9IDIyOwogCXN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9TRVBBUkFUT1JfV0lEVEggPSA4OwogCi0vKioKLSAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50Ci0gKiAod2hpY2ggbXVzdCBiZSBhIDxjb2RlPlRvb2xCYXI8L2NvZGU+KSBhbmQgYSBzdHlsZSB2YWx1ZQotICogZGVzY3JpYmluZyBpdHMgYmVoYXZpb3IgYW5kIGFwcGVhcmFuY2UuIFRoZSBpdGVtIGlzIGFkZGVkCi0gKiB0byB0aGUgZW5kIG9mIHRoZSBpdGVtcyBtYWludGFpbmVkIGJ5IGl0cyBwYXJlbnQuCi0gKiA8cD4KLSAqIFRoZSBzdHlsZSB2YWx1ZSBpcyBlaXRoZXIgb25lIG9mIHRoZSBzdHlsZSBjb25zdGFudHMgZGVmaW5lZCBpbgotICogY2xhc3MgPGNvZGU+U1dUPC9jb2RlPiB3aGljaCBpcyBhcHBsaWNhYmxlIHRvIGluc3RhbmNlcyBvZiB0aGlzCi0gKiBjbGFzcywgb3IgbXVzdCBiZSBidWlsdCBieSA8ZW0+Yml0d2lzZSBPUjwvZW0+J2luZyB0b2dldGhlciAKLSAqICh0aGF0IGlzLCB1c2luZyB0aGUgPGNvZGU+aW50PC9jb2RlPiAifCIgb3BlcmF0b3IpIHR3byBvciBtb3JlCi0gKiBvZiB0aG9zZSA8Y29kZT5TV1Q8L2NvZGU+IHN0eWxlIGNvbnN0YW50cy4gVGhlIGNsYXNzIGRlc2NyaXB0aW9uCi0gKiBsaXN0cyB0aGUgc3R5bGUgY29uc3RhbnRzIHRoYXQgYXJlIGFwcGxpY2FibGUgdG8gdGhlIGNsYXNzLgotICogU3R5bGUgYml0cyBhcmUgYWxzbyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIHBhcmVudCBhIGNvbXBvc2l0ZSBjb250cm9sIHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqIEBwYXJhbSBzdHlsZSB0aGUgc3R5bGUgb2YgY29udHJvbCB0byBjb25zdHJ1Y3QKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBwYXJlbnQgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgU1dUI1BVU0gKLSAqIEBzZWUgU1dUI0NIRUNLCi0gKiBAc2VlIFNXVCNSQURJTwotICogQHNlZSBTV1QjU0VQQVJBVE9SCi0gKiBAc2VlIFNXVCNEUk9QX0RPV04KLSAqIEBzZWUgV2lkZ2V0I2NoZWNrU3ViY2xhc3MKLSAqIEBzZWUgV2lkZ2V0I2dldFN0eWxlCi0gKi8KIHB1YmxpYyBUb29sSXRlbSAoVG9vbEJhciBwYXJlbnQsIGludCBzdHlsZSkgewogCXN1cGVyIChwYXJlbnQsIGNoZWNrU3R5bGUgKHN0eWxlKSk7CiAJdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CkBAIC04Niw0MSArMzYsNiBAQAogCXBhcmVudC5yZWxheW91dCAoKTsKIH0KIAotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gaXRzIHBhcmVudAotICogKHdoaWNoIG11c3QgYmUgYSA8Y29kZT5Ub29sQmFyPC9jb2RlPiksIGEgc3R5bGUgdmFsdWUKLSAqIGRlc2NyaWJpbmcgaXRzIGJlaGF2aW9yIGFuZCBhcHBlYXJhbmNlLCBhbmQgdGhlIGluZGV4Ci0gKiBhdCB3aGljaCB0byBwbGFjZSBpdCBpbiB0aGUgaXRlbXMgbWFpbnRhaW5lZCBieSBpdHMgcGFyZW50LgotICogPHA+Ci0gKiBUaGUgc3R5bGUgdmFsdWUgaXMgZWl0aGVyIG9uZSBvZiB0aGUgc3R5bGUgY29uc3RhbnRzIGRlZmluZWQgaW4KLSAqIGNsYXNzIDxjb2RlPlNXVDwvY29kZT4gd2hpY2ggaXMgYXBwbGljYWJsZSB0byBpbnN0YW5jZXMgb2YgdGhpcwotICogY2xhc3MsIG9yIG11c3QgYmUgYnVpbHQgYnkgPGVtPmJpdHdpc2UgT1I8L2VtPidpbmcgdG9nZXRoZXIgCi0gKiAodGhhdCBpcywgdXNpbmcgdGhlIDxjb2RlPmludDwvY29kZT4gInwiIG9wZXJhdG9yKSB0d28gb3IgbW9yZQotICogb2YgdGhvc2UgPGNvZGU+U1dUPC9jb2RlPiBzdHlsZSBjb25zdGFudHMuIFRoZSBjbGFzcyBkZXNjcmlwdGlvbgotICogbGlzdHMgdGhlIHN0eWxlIGNvbnN0YW50cyB0aGF0IGFyZSBhcHBsaWNhYmxlIHRvIHRoZSBjbGFzcy4KLSAqIFN0eWxlIGJpdHMgYXJlIGFsc28gaW5oZXJpdGVkIGZyb20gc3VwZXJjbGFzc2VzLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBwYXJlbnQgYSBjb21wb3NpdGUgY29udHJvbCB3aGljaCB3aWxsIGJlIHRoZSBwYXJlbnQgb2YgdGhlIG5ldyBpbnN0YW5jZSAoY2Fubm90IGJlIG51bGwpCi0gKiBAcGFyYW0gc3R5bGUgdGhlIHN0eWxlIG9mIGNvbnRyb2wgdG8gY29uc3RydWN0Ci0gKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IHRvIHN0b3JlIHRoZSByZWNlaXZlciBpbiBpdHMgcGFyZW50Ci0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgcGFyZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHBhcmVudDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9TVUJDTEFTUyAtIGlmIHRoaXMgY2xhc3MgaXMgbm90IGFuIGFsbG93ZWQgc3ViY2xhc3M8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIFNXVCNQVVNICi0gKiBAc2VlIFNXVCNDSEVDSwotICogQHNlZSBTV1QjUkFESU8KLSAqIEBzZWUgU1dUI1NFUEFSQVRPUgotICogQHNlZSBTV1QjRFJPUF9ET1dOCi0gKiBAc2VlIFdpZGdldCNjaGVja1N1YmNsYXNzCi0gKiBAc2VlIFdpZGdldCNnZXRTdHlsZQotICovCiBwdWJsaWMgVG9vbEl0ZW0gKFRvb2xCYXIgcGFyZW50LCBpbnQgc3R5bGUsIGludCBpbmRleCkgewogCXN1cGVyIChwYXJlbnQsIGNoZWNrU3R5bGUgKHN0eWxlKSk7CiAJdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CkBAIC0xMjgsMzEgKzQzLDYgQEAKIAlwYXJlbnQucmVsYXlvdXQgKCk7CiB9CiAKLS8qKgotICogQWRkcyB0aGUgbGlzdGVuZXIgdG8gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmllZCB3aGVuIHRoZSBjb250cm9sIGlzIHNlbGVjdGVkLCBieSBzZW5kaW5nCi0gKiBpdCBvbmUgb2YgdGhlIG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhlIDxjb2RlPlNlbGVjdGlvbkxpc3RlbmVyPC9jb2RlPgotICogaW50ZXJmYWNlLgotICogPHA+Ci0gKiBXaGVuIDxjb2RlPndpZGdldFNlbGVjdGVkPC9jb2RlPiBpcyBjYWxsZWQgd2hlbiB0aGUgbW91c2UgaXMgb3ZlciB0aGUgYXJyb3cgcG9ydGlvbiBvZiBhIGRyb3AtZG93biB0b29sLAotICogdGhlIGV2ZW50IG9iamVjdCBkZXRhaWwgZmllbGQgY29udGFpbnMgdGhlIHZhbHVlIDxjb2RlPlNXVC5BUlJPVzwvY29kZT4uCi0gKiA8Y29kZT53aWRnZXREZWZhdWx0U2VsZWN0ZWQ8L2NvZGU+IGlzIG5vdCBjYWxsZWQuCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTZWxlY3Rpb25MaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlU2VsZWN0aW9uTGlzdGVuZXIKLSAqIEBzZWUgU2VsZWN0aW9uRXZlbnQKLSAqLwogcHVibGljIHZvaWQgYWRkU2VsZWN0aW9uTGlzdGVuZXIoU2VsZWN0aW9uTGlzdGVuZXIgbGlzdGVuZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwpAQCAtMTYwLDM3OCArNTAsMzIzIEBACiAJYWRkTGlzdGVuZXIoU1dULlNlbGVjdGlvbix0eXBlZExpc3RlbmVyKTsKIAlhZGRMaXN0ZW5lcihTV1QuRGVmYXVsdFNlbGVjdGlvbix0eXBlZExpc3RlbmVyKTsKIH0KKwogc3RhdGljIGludCBjaGVja1N0eWxlIChpbnQgc3R5bGUpIHsKIAlyZXR1cm4gY2hlY2tCaXRzIChzdHlsZSwgU1dULlBVU0gsIFNXVC5DSEVDSywgU1dULlJBRElPLCBTV1QuU0VQQVJBVE9SLCBTV1QuRFJPUF9ET1dOLCAwKTsKIH0KKwogcHJvdGVjdGVkIHZvaWQgY2hlY2tTdWJjbGFzcyAoKSB7CiAJaWYgKCFpc1ZhbGlkU3ViY2xhc3MgKCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9TVUJDTEFTUyk7CiB9Ci12b2lkIGNyZWF0ZUhhbmRsZSAoaW50IGluZGV4KSB7Ci0Jc3RhdGUgfD0gSEFORExFOwotCWludCBwYXJlbnRIYW5kbGUgPSBwYXJlbnQuaGFuZGxlOwotCS8qIEFXCi0JaW50IFtdIGFyZ0xpc3QgPSB7Ci0JCU9TLlhtTndpZHRoLCBERUZBVUxUX1dJRFRILAotCQlPUy5YbU5oZWlnaHQsIERFRkFVTFRfSEVJR0hULAotCQlPUy5YbU5yZWNvbXB1dGVTaXplLCAwLAotCQlPUy5YbU5oaWdobGlnaHRUaGlja25lc3MsIChwYXJlbnQuc3R5bGUgJiBTV1QuTk9fRk9DVVMpICE9IDAgPyAwIDogMSwKLQkJT1MuWG1ObWFyZ2luV2lkdGgsIDIsCi0JCU9TLlhtTm1hcmdpbkhlaWdodCwgMSwKLQkJT1MuWG1OdHJhdmVyc2FsT24sIChwYXJlbnQuc3R5bGUgJiBTV1QuTk9fRk9DVVMpICE9IDAgPyAwIDogMSwKLQkJT1MuWG1OcG9zaXRpb25JbmRleCwgaW5kZXgsCi0JCU9TLlhtTnNoYWRvd1R5cGUsIE9TLlhtU0hBRE9XX09VVCwKLQkJT1MuWG1OYW5jZXN0b3JTZW5zaXRpdmUsIDEsCi0JfTsKLQloYW5kbGUgPSBPUy5YbUNyZWF0ZURyYXduQnV0dG9uIChwYXJlbnRIYW5kbGUsIG51bGwsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JKi8KLQlpbnQgd2lkdGg9IERFRkFVTFRfV0lEVEg7Ci0JaW50IGhlaWdodD0gREVGQVVMVF9IRUlHSFQ7Ci0JaWYgKChzdHlsZSAmIFNXVC5TRVBBUkFUT1IpICE9IDApIHsKLQkJaWYgKChwYXJlbnQuc3R5bGUgJiBTV1QuSE9SSVpPTlRBTCkgIT0gMCkKLQkJCXdpZHRoPSBERUZBVUxUX1NFUEFSQVRPUl9XSURUSDsKLQkJZWxzZQotCQkJaGVpZ2h0PSBERUZBVUxUX1NFUEFSQVRPUl9XSURUSDsKLQl9Ci0JaGFuZGxlID0gTWFjVXRpbC5jcmVhdGVEcmF3aW5nQXJlYShwYXJlbnRIYW5kbGUsIGluZGV4LCBmYWxzZSwgd2lkdGgsIGhlaWdodCwgMCk7Ci0JaWYgKGhhbmRsZSA9PSAwKSBlcnJvciAoU1dULkVSUk9SX05PX0hBTkRMRVMpOwotfQotdm9pZCBjbGljayAoYm9vbGVhbiBkcm9wRG93biwgTWFjTW91c2VFdmVudCBtbUV2ZW50KSB7Ci0JaWYgKChzdHlsZSAmIFNXVC5SQURJTykgIT0gMCkgewotCQlzZWxlY3RSYWRpbyAoKTsKLQl9IGVsc2UgewotCQlpZiAoKHN0eWxlICYgU1dULkNIRUNLKSAhPSAwKSBzZXRTZWxlY3Rpb24oIXNldCk7CQkJCi0JfQotCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOwotCWlmICgoc3R5bGUgJiBTV1QuRFJPUF9ET1dOKSAhPSAwKSB7Ci0JCWlmIChkcm9wRG93bikgZXZlbnQuZGV0YWlsID0gU1dULkFSUk9XOwotCX0KLQlpZiAobW1FdmVudCAhPSBudWxsKSB7Ci0JCS8vIEFXIHNldElucHV0U3RhdGUgKGV2ZW50LCBtRXZlbnQpOwotCQlldmVudC5zdGF0ZU1hc2s9IG1tRXZlbnQuZ2V0U3RhdGUoKTsKLQl9Ci0JcG9zdEV2ZW50IChTV1QuU2VsZWN0aW9uLCBldmVudCk7Ci19CisKIFBvaW50IGNvbXB1dGVTaXplICgpIHsKLQlpZiAoKHN0eWxlICYgU1dULlNFUEFSQVRPUikgIT0gMCkgewotCQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQkJT1MuR2V0Q29udHJvbEJvdW5kcyhoYW5kbGUsIGJvdW5kcy5nZXREYXRhKCkpOwotCQlyZXR1cm4gYm91bmRzLmdldFNpemUoKTsKLQl9Ci0JLyogQVcKLQlpbnQgW10gYXJnTGlzdCA9IHsKLQkJT1MuWG1ObWFyZ2luSGVpZ2h0LCAwLAotCQlPUy5YbU5tYXJnaW5XaWR0aCwgMCwKLQkJT1MuWG1Oc2hhZG93VGhpY2tuZXNzLCAwLAotCX07Ci0JT1MuWHRHZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlpbnQgbWFyZ2luSGVpZ2h0ID0gYXJnTGlzdCBbMV0sIG1hcmdpbldpZHRoID0gYXJnTGlzdCBbM107Ci0JaW50IHNoYWRvd1RoaWNrbmVzcyA9IGFyZ0xpc3QgWzVdOwotCSovCi0JaW50IG1hcmdpbkhlaWdodCA9IDIsIG1hcmdpbldpZHRoID0gMjsKLQlpbnQgc2hhZG93VGhpY2tuZXNzID0gMTsKLQlpZiAoKHBhcmVudC5zdHlsZSAmIFNXVC5GTEFUKSAhPSAwKSB7Ci0JCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7Ci0JCXNoYWRvd1RoaWNrbmVzcyA9IE1hdGgubWluICgyLCBkaXNwbGF5LmJ1dHRvblNoYWRvd1RoaWNrbmVzcyk7Ci0JfQotCWludCB0ZXh0V2lkdGggPSAwLCB0ZXh0SGVpZ2h0ID0gMDsKLQlpZiAodGV4dC5sZW5ndGggKCkgIT0gMCkgewotCQlHQyBnYyA9IG5ldyBHQyAocGFyZW50KTsKLQkJaW50IGZsYWdzID0gU1dULkRSQVdfREVMSU1JVEVSIHwgU1dULkRSQVdfVEFCIHwgU1dULkRSQVdfTU5FTU9OSUM7Ci0JCVBvaW50IHRleHRFeHRlbnQgPSBnYy50ZXh0RXh0ZW50ICh0ZXh0LCBmbGFncyk7Ci0JCXRleHRXaWR0aCA9IHRleHRFeHRlbnQueDsKLQkJdGV4dEhlaWdodCA9IHRleHRFeHRlbnQueTsKLQkJZ2MuZGlzcG9zZSAoKTsKLQl9Ci0JaW50IGltYWdlV2lkdGggPSAwLCBpbWFnZUhlaWdodCA9IDA7Ci0JaWYgKGltYWdlICE9IG51bGwpIHsKLQkJUmVjdGFuZ2xlIHJlY3QgPSBpbWFnZS5nZXRCb3VuZHMgKCk7Ci0JCWltYWdlV2lkdGggPSByZWN0LndpZHRoOwotCQlpbWFnZUhlaWdodCA9IHJlY3QuaGVpZ2h0OwotCX0KKwljaGVja1dpZGdldCgpOwogCWludCB3aWR0aCA9IDAsIGhlaWdodCA9IDA7Ci0JaWYgKChwYXJlbnQuc3R5bGUgJiBTV1QuUklHSFQpICE9IDApIHsKLQkJd2lkdGggPSBpbWFnZVdpZHRoICsgdGV4dFdpZHRoOwotCQloZWlnaHQgPSBNYXRoLm1heCAoaW1hZ2VIZWlnaHQsIHRleHRIZWlnaHQpOwotCQlpZiAoaW1hZ2VXaWR0aCAhPSAwICYmIHRleHRXaWR0aCAhPSAwKSB3aWR0aCArPSAyOworCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSB7CisJCWlmICgoc3R5bGUgJiBTV1QuSE9SSVpPTlRBTCkgIT0gMCkgeworCQkJd2lkdGggPSBnZXRXaWR0aCAoKTsKKwkJCWhlaWdodCA9IERFRkFVTFRfSEVJR0hUOworCQl9IGVsc2UgeworCQkJd2lkdGggPSBERUZBVUxUX1dJRFRIOworCQkJaGVpZ2h0ID0gZ2V0V2lkdGggKCk7CisJCX0KIAl9IGVsc2UgewotCQloZWlnaHQgPSBpbWFnZUhlaWdodCArIHRleHRIZWlnaHQ7Ci0JCWlmIChpbWFnZUhlaWdodCAhPSAwICYmIHRleHRIZWlnaHQgIT0gMCkgaGVpZ2h0ICs9IDI7Ci0JCXdpZHRoID0gTWF0aC5tYXggKGltYWdlV2lkdGgsIHRleHRXaWR0aCk7Ci0JfQotCWlmICgoc3R5bGUgJiBTV1QuRFJPUF9ET1dOKSAhPSAwKSB3aWR0aCArPSAxMjsKLQkKLQlpZiAod2lkdGggIT0gMCkgewotCQl3aWR0aCArPSAobWFyZ2luV2lkdGggKyBzaGFkb3dUaGlja25lc3MpICogMiArIDI7Ci0JfSBlbHNlIHsKLQkJd2lkdGggPSBERUZBVUxUX1dJRFRIOwotCX0KLQlpZiAoaGVpZ2h0ICE9IDApIHsKLQkJaGVpZ2h0ICs9IChtYXJnaW5IZWlnaHQgKyBzaGFkb3dUaGlja25lc3MpICogMiArIDI7Ci0JfSBlbHNlIHsKLQkJaGVpZ2h0ID0gREVGQVVMVF9IRUlHSFQ7CisJCWludCBzcGFjZSA9IDA7CisJCWludCBzdHJpbmdXaWR0aCA9IDAsIHN0cmluZ0hlaWdodCA9IDA7CisJCWlmICh0ZXh0Lmxlbmd0aCAoKSAhPSAwKSB7CisJCQlHQyBnYyA9IG5ldyBHQyAocGFyZW50KTsKKwkJCVBvaW50IHNpemUgPSBnYy5zdHJpbmdFeHRlbnQgKHRleHQpOworCQkJc3RyaW5nV2lkdGggPSBzaXplLng7CisJCQlzdHJpbmdIZWlnaHQgPSBzaXplLnk7CisJCQlnYy5kaXNwb3NlICgpOworCQl9CisJCWludCBpbWFnZVdpZHRoID0gMCwgaW1hZ2VIZWlnaHQgPSAwOworCQlpZiAoaW1hZ2UgIT0gbnVsbCkgeworCQkJaWYgKHRleHQubGVuZ3RoICgpICE9IDApIHNwYWNlID0gMjsKKwkJCVJlY3RhbmdsZSByZWN0ID0gaW1hZ2UuZ2V0Qm91bmRzICgpOworCQkJaW1hZ2VXaWR0aCA9IHJlY3Qud2lkdGg7CisJCQlpbWFnZUhlaWdodCA9IHJlY3QuaGVpZ2h0OworCQl9CisJCWlmICgocGFyZW50LnN0eWxlICYgU1dULlJJR0hUKSAhPSAwKSB7CisJCQl3aWR0aCA9IHN0cmluZ1dpZHRoICsgaW1hZ2VXaWR0aDsKKwkJCWhlaWdodCA9IE1hdGgubWF4IChzdHJpbmdIZWlnaHQsIGltYWdlSGVpZ2h0KTsKKwkJfSBlbHNlIHsKKwkJCXdpZHRoID0gTWF0aC5tYXggKHN0cmluZ1dpZHRoLCBpbWFnZVdpZHRoKTsKKwkJCWhlaWdodCA9IHN0cmluZ0hlaWdodCArIGltYWdlSGVpZ2h0OworCQl9CisJCWlmICgoc3R5bGUgJiBTV1QuRFJPUF9ET1dOKSAhPSAwKSB7CisJCQlpbnQgYXJyb3dXaWR0aCA9IDY7IC8vTk9UIERPTkUKKwkJCXdpZHRoICs9IDMgKyBhcnJvd1dpZHRoOworCQl9CisJCWludCBpbnNldCA9IDM7CisJCXdpZHRoICs9IHNwYWNlICsgaW5zZXQgKiAyOworCQloZWlnaHQgKz0gc3BhY2UgKyBpbnNldCAqIDI7CiAJfQogCXJldHVybiBuZXcgUG9pbnQgKHdpZHRoLCBoZWlnaHQpOwogfQotdm9pZCBjcmVhdGVXaWRnZXQgKGludCBpbmRleCkgewotCXN1cGVyLmNyZWF0ZVdpZGdldCAoaW5kZXgpOwotCXRvb2xUaXBUZXh0ID0gIiI7CisKK3ZvaWQgY3JlYXRlSGFuZGxlICgpIHsKKwlpbnQgW10gb3V0Q29udHJvbCA9IG5ldyBpbnQgWzFdOworCWludCB3aW5kb3cgPSBPUy5HZXRDb250cm9sT3duZXIgKHBhcmVudC5oYW5kbGUpOworCWludCBmZWF0dXJlcyA9IE9TLmtDb250cm9sU3VwcG9ydHNFbWJlZGRpbmcgfCAxIDw8IDQ7CisJT1MuQ3JlYXRlVXNlclBhbmVDb250cm9sICh3aW5kb3csIG51bGwsIGZlYXR1cmVzLCBvdXRDb250cm9sKTsKKwlpZiAob3V0Q29udHJvbCBbMF0gPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwloYW5kbGUgPSBvdXRDb250cm9sIFswXTsKKwlpbnQgd2lkdGggPSBERUZBVUxUX1dJRFRILCBoZWlnaHQgPSBERUZBVUxUX0hFSUdIVDsKKwlpZiAoKHN0eWxlICYgU1dULlNFUEFSQVRPUikgPT0gMCkgeworCQlDb250cm9sQnV0dG9uQ29udGVudEluZm8gaW5Db250ZW50ID0gbmV3IENvbnRyb2xCdXR0b25Db250ZW50SW5mbyAoKTsKKwkJaWYgKChzdHlsZSAmIFNXVC5EUk9QX0RPV04pICE9IDApIHsKKwkJCU9TLkNyZWF0ZUljb25Db250cm9sKHdpbmRvdywgbnVsbCwgaW5Db250ZW50LCBmYWxzZSwgb3V0Q29udHJvbCk7CisJCQlpZiAob3V0Q29udHJvbCBbMF0gPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwkJCWFycm93SGFuZGxlID0gb3V0Q29udHJvbCBbMF07CisJCQl1cGRhdGVBcnJvdyAoKTsKKwkJfQorCQlPUy5DcmVhdGVJY29uQ29udHJvbCh3aW5kb3csIG51bGwsIGluQ29udGVudCwgZmFsc2UsIG91dENvbnRyb2wpOworCQlpZiAob3V0Q29udHJvbCBbMF0gPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwkJaWNvbkhhbmRsZSA9IG91dENvbnRyb2wgWzBdOworCQlPUy5DcmVhdGVJY29uQ29udHJvbCh3aW5kb3csIG51bGwsIGluQ29udGVudCwgZmFsc2UsIG91dENvbnRyb2wpOworCQlpZiAob3V0Q29udHJvbCBbMF0gPT0gMCkgZXJyb3IgKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwkJbGFiZWxIYW5kbGUgPSBvdXRDb250cm9sIFswXTsKKwl9IGVsc2UgeworCQlpZiAoKHBhcmVudC5zdHlsZSAmIFNXVC5IT1JJWk9OVEFMKSAhPSAwKSB7CisJCQl3aWR0aCA9IERFRkFVTFRfU0VQQVJBVE9SX1dJRFRIOworCQl9IGVsc2UgeworCQkJaGVpZ2h0ID0gREVGQVVMVF9TRVBBUkFUT1JfV0lEVEg7CisJCX0KKwl9CQorCXNldEJvdW5kcyAoMCwgMCwgd2lkdGgsIGhlaWdodCk7CiAJcGFyZW50LnJlbGF5b3V0ICgpOwogfQorCit2b2lkIGNyZWF0ZVdpZGdldCAoKSB7CisJc3VwZXIuY3JlYXRlV2lkZ2V0ICgpOworCXNldFpPcmRlciAoKTsKKwl0b29sVGlwVGV4dCA9ICIiOworfQorCitpbnQgZGVmYXVsdFRoZW1lRm9udCAoKSB7CQorCXJldHVybiBPUy5rVGhlbWVUb29sYmFyRm9udDsKK30KKwordm9pZCBkZXJlZ2lzdGVyICgpIHsKKwlzdXBlci5kZXJlZ2lzdGVyICgpOworCVdpZGdldFRhYmxlLnJlbW92ZSAoaGFuZGxlKTsKKwlpZiAoaWNvbkhhbmRsZSAhPSAwKSBXaWRnZXRUYWJsZS5yZW1vdmUgKGljb25IYW5kbGUpOworCWlmIChsYWJlbEhhbmRsZSAhPSAwKSBXaWRnZXRUYWJsZS5yZW1vdmUgKGxhYmVsSGFuZGxlKTsKKwlpZiAoYXJyb3dIYW5kbGUgIT0gMCkgV2lkZ2V0VGFibGUucmVtb3ZlIChhcnJvd0hhbmRsZSk7Cit9CisKK3ZvaWQgZGVzdHJveVdpZGdldCAoKSB7CisJaW50IHRoZUNvbnRyb2wgPSBoYW5kbGU7CisJcmVsZWFzZUhhbmRsZSAoKTsKKwlpZiAodGhlQ29udHJvbCAhPSAwKSB7CisJCU9TLkRpc3Bvc2VDb250cm9sICh0aGVDb250cm9sKTsKKwl9Cit9CisKIHB1YmxpYyB2b2lkIGRpc3Bvc2UgKCkgewogCWlmIChpc0Rpc3Bvc2VkKCkpIHJldHVybjsKIAlUb29sQmFyIHBhcmVudCA9IHRoaXMucGFyZW50OwotCXBhcmVudC5yZWRyYXcoKTsJLy8gQVcgd29ya2Fyb3VuZCBmb3IgVG9vbGJhciB1cGRhdGUgcHJvYmxlbQogCXN1cGVyLmRpc3Bvc2UgKCk7CiAJcGFyZW50LnJlbGF5b3V0ICgpOwogfQotLyoqCi0gKiBSZXR1cm5zIGEgcmVjdGFuZ2xlIGRlc2NyaWJpbmcgdGhlIHJlY2VpdmVyJ3Mgc2l6ZSBhbmQgbG9jYXRpb24KLSAqIHJlbGF0aXZlIHRvIGl0cyBwYXJlbnQuCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBib3VuZGluZyByZWN0YW5nbGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KLXB1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRzICgpIHsKLQljaGVja1dpZGdldCgpOwotCWlmIChNYWNVdGlsLlVTRV9GUkFNRSkgewotCQlmbG9hdFtdIGY9IG5ldyBmbG9hdFs0XTsKLQkJT1MuSElWaWV3R2V0RnJhbWUoaGFuZGxlLCBmKTsKLQkJcmV0dXJuIG5ldyBSZWN0YW5nbGUoKGludClmWzBdLCAoaW50KWZbMV0sIChpbnQpZlsyXSwgKGludClmWzNdKTsKLQl9IGVsc2UgewotCQlzaG9ydFtdIGJvdW5kcz0gbmV3IHNob3J0WzRdOwotCQlzaG9ydFtdIHBib3VuZHM9IG5ldyBzaG9ydFs0XTsKLQkJT1MuR2V0Q29udHJvbEJvdW5kcyhoYW5kbGUsIGJvdW5kcyk7Ci0JCU9TLkdldENvbnRyb2xCb3VuZHMocGFyZW50LmhhbmRsZSwgcGJvdW5kcyk7Ci0JCXJldHVybiBuZXcgUmVjdGFuZ2xlKGJvdW5kc1sxXS1wYm91bmRzWzFdLCBib3VuZHNbMF0tcGJvdW5kc1swXSwgYm91bmRzWzNdLWJvdW5kc1sxXSwgYm91bmRzWzJdLWJvdW5kc1swXSk7CisKK3ZvaWQgZHJhd1dpZGdldCAoaW50IGNvbnRyb2wpIHsKKwlkcmF3QmFja2dyb3VuZCAoY29udHJvbCwgbnVsbCk7CisJaWYgKChzdHlsZSAmIFNXVC5TRVBBUkFUT1IpICE9IDApIHsKKwkJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisJCU9TLkdldENvbnRyb2xCb3VuZHMgKGhhbmRsZSwgcmVjdCk7CisJCXJlY3QudG9wICs9IDI7CisJCXJlY3QuYm90dG9tIC09IDI7CisJCU9TLkRyYXdUaGVtZVNlcGFyYXRvciAocmVjdCwgMCk7CiAJfQogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSBjb250cm9sIHRoYXQgaXMgdXNlZCB0byBmaWxsIHRoZSBib3VuZHMgb2YKLSAqIHRoZSBpdGVtIHdoZW4gdGhlIGl0ZW1zIGlzIGEgPGNvZGU+U0VQQVJBVE9SPC9jb2RlPi4KLSAqCi0gKiBAcmV0dXJuIHRoZSBjb250cm9sCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKK3B1YmxpYyBSZWN0YW5nbGUgZ2V0Qm91bmRzICgpIHsKKwljaGVja1dpZGdldCgpOworCVJlY3QgcmVjdCA9IGdldENvbnRyb2xCb3VuZHMgKGhhbmRsZSk7CisJcmV0dXJuIG5ldyBSZWN0YW5nbGUgKHJlY3QubGVmdCwgcmVjdC50b3AsIHJlY3QucmlnaHQgLSByZWN0LmxlZnQsIHJlY3QuYm90dG9tIC0gcmVjdC50b3ApOworfQorCiBwdWJsaWMgQ29udHJvbCBnZXRDb250cm9sICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBjb250cm9sOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSByZWNlaXZlcidzIGRpc2FibGVkIGltYWdlIGlmIGl0IGhhcyBvbmUsIG9yIG51bGwKLSAqIGlmIGl0IGRvZXMgbm90LgotICogPHA+Ci0gKiBUaGUgZGlzYWJsZWQgaW1hZ2UgaXMgZGlzcGxheWVkIHdoZW4gdGhlIHJlY2VpdmVyIGlzIGRpc2FibGVkLgotICogPC9wPgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgZGlzYWJsZWQgaW1hZ2UKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIEltYWdlIGdldERpc2FibGVkSW1hZ2UgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIGRpc2FibGVkSW1hZ2U7CiB9Ci0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGlzIGVuYWJsZWQsIGFuZAotICogPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KLSAqIDxwPgotICogQSBkaXNhYmxlZCBjb250cm9sIGlzIHR5cGljYWxseSBub3Qgc2VsZWN0YWJsZSBmcm9tIHRoZQotICogdXNlciBpbnRlcmZhY2UgYW5kIGRyYXdzIHdpdGggYW4gaW5hY3RpdmUgb3IgImdyYXllZCIgbG9vay4KLSAqIDwvcD4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGVuYWJsZWQgc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGJvb2xlYW4gZ2V0RW5hYmxlZCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlyZXR1cm4gT1MuSXNDb250cm9sRW5hYmxlZChoYW5kbGUpOwogfQorCiBwdWJsaWMgRGlzcGxheSBnZXREaXNwbGF5ICgpIHsKIAlDb21wb3NpdGUgcGFyZW50ID0gdGhpcy5wYXJlbnQ7CiAJaWYgKHBhcmVudCA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX1dJREdFVF9ESVNQT1NFRCk7CiAJcmV0dXJuIHBhcmVudC5nZXREaXNwbGF5ICgpOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSByZWNlaXZlcidzIGhvdCBpbWFnZSBpZiBpdCBoYXMgb25lLCBvciBudWxsCi0gKiBpZiBpdCBkb2VzIG5vdC4KLSAqIDxwPgotICogVGhlIGhvdCBpbWFnZSBpcyBkaXNwbGF5ZWQgd2hlbiB0aGUgbW91c2UgZW50ZXJzIHRoZSByZWNlaXZlci4KLSAqIDwvcD4KLSAqCi0gKiBAcmV0dXJuIHRoZSByZWNlaXZlcidzIGhvdCBpbWFnZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgSW1hZ2UgZ2V0SG90SW1hZ2UgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIGhvdEltYWdlOwogfQotLyoqCi0gKiBSZXR1cm5zIHRoZSByZWNlaXZlcidzIHBhcmVudCwgd2hpY2ggbXVzdCBiZSBhIDxjb2RlPlRvb2xCYXI8L2NvZGU+LgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgcGFyZW50Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBUb29sQmFyIGdldFBhcmVudCAoKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlyZXR1cm4gcGFyZW50OwogfQotLyoqCi0gKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSByZWNlaXZlciBpcyBzZWxlY3RlZCwKLSAqIGFuZCBmYWxzZSBvdGhlcndpc2UuCi0gKiA8cD4KLSAqIFdoZW4gdGhlIHJlY2VpdmVyIGlzIG9mIHR5cGUgPGNvZGU+Q0hFQ0s8L2NvZGU+IG9yIDxjb2RlPlJBRElPPC9jb2RlPiwKLSAqIGl0IGlzIHNlbGVjdGVkIHdoZW4gaXQgaXMgY2hlY2tlZCAod2hpY2ggc29tZSBwbGF0Zm9ybXMgZHJhdyBhcyBhCi0gKiBwdXNoZWQgaW4gYnV0dG9uKS4gSWYgdGhlIHJlY2VpdmVyIGlzIG9mIGFueSBvdGhlciB0eXBlLCB0aGlzIG1ldGhvZAotICogcmV0dXJucyBmYWxzZS4KLSAqIDwvcD4KLSAqCi0gKiBAcmV0dXJuIHRoZSBzZWxlY3Rpb24gc3RhdGUKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIGJvb2xlYW4gZ2V0U2VsZWN0aW9uICgpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICgoc3R5bGUgJiAoU1dULkNIRUNLIHwgU1dULlJBRElPKSkgPT0gMCkgcmV0dXJuIGZhbHNlOwotCXJldHVybiBzZXQ7CisJc2hvcnQgW10gdHJhbnNmb3JtID0gbmV3IHNob3J0IFsxXTsKKyAJT1MuR2V0Q29udHJvbERhdGEgKGljb25IYW5kbGUsIChzaG9ydCkgT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbEljb25UcmFuc2Zvcm1UYWcsIDIsIHRyYW5zZm9ybSwgbnVsbCk7CisgIAlyZXR1cm4gKHRyYW5zZm9ybSBbMF0gJiBPUy5rVHJhbnNmb3JtU2VsZWN0ZWQpICE9IDA7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3MgdG9vbCB0aXAgdGV4dCwgb3IgbnVsbCBpZiBpdCBoYXMgbm90IGJlZW4gc2V0LgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgdG9vbCB0aXAgdGV4dAotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgU3RyaW5nIGdldFRvb2xUaXBUZXh0ICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiB0b29sVGlwVGV4dDsKIH0KLS8qKgotICogR2V0cyB0aGUgd2lkdGggb2YgdGhlIHJlY2VpdmVyLgotICoKLSAqIEByZXR1cm4gdGhlIHdpZHRoCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBpbnQgZ2V0V2lkdGggKCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JTWFjUmVjdCBib3VuZHM9IG5ldyBNYWNSZWN0KCk7Ci0JT1MuR2V0Q29udHJvbEJvdW5kcyhoYW5kbGUsIGJvdW5kcy5nZXREYXRhKCkpOwotCXJldHVybiBib3VuZHMuZ2V0V2lkdGgoKTsKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChoYW5kbGUsIHJlY3QpOworCXJldHVybiByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0OwogfQotYm9vbGVhbiBoYXNDdXJzb3IgKCkgewotCU1hY1BvaW50IG1wPSBuZXcgTWFjUG9pbnQoKTsKLQlPUy5HZXRNb3VzZShtcC5nZXREYXRhKCkpOwotCU1hY1JlY3QgYm91bmRzPSBuZXcgTWFjUmVjdCgpOwotCU9TLkdldENvbnRyb2xCb3VuZHMoaGFuZGxlLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQlyZXR1cm4gYm91bmRzLnRvUmVjdGFuZ2xlKCkuY29udGFpbnMobXAudG9Qb2ludCgpKTsKKworaW50IGhlbHBQcm9jIChpbnQgaW5Db250cm9sLCBpbnQgaW5HbG9iYWxNb3VzZSwgaW50IGluUmVxdWVzdCwgaW50IG91dENvbnRlbnRQcm92aWRlZCwgaW50IGlvSGVscENvbnRlbnQpIHsKKwlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworICAgIHN3aXRjaCAoaW5SZXF1ZXN0KSB7CisJCWNhc2UgT1Mua0hNU3VwcGx5Q29udGVudDogeworCQkJaW50IFtdIGNvbnRlbnRQcm92aWRlZCA9IG5ldyBpbnQgW10ge09TLmtITUNvbnRlbnROb3RQcm92aWRlZH07CisJCQlpZiAodG9vbFRpcFRleHQgIT0gbnVsbCAmJiB0b29sVGlwVGV4dC5sZW5ndGggKCkgIT0gMCkgeworCQkJCWNoYXIgW10gYnVmZmVyID0gbmV3IGNoYXIgW3Rvb2xUaXBUZXh0Lmxlbmd0aCAoKV07CisJCQkJdG9vbFRpcFRleHQuZ2V0Q2hhcnMgKDAsIGJ1ZmZlci5sZW5ndGgsIGJ1ZmZlciwgMCk7CisJCQkJaW50IGk9MCwgaj0wOworCQkJCXdoaWxlIChpIDwgYnVmZmVyLmxlbmd0aCkgeworCQkJCQlpZiAoKGJ1ZmZlciBbaisrXSA9IGJ1ZmZlciBbaSsrXSkgPT0gTW5lbW9uaWMpIHsKKwkJCQkJCWlmIChpID09IGJ1ZmZlci5sZW5ndGgpIHtjb250aW51ZTt9CisJCQkJCQlpZiAoYnVmZmVyIFtpXSA9PSBNbmVtb25pYykge2krKzsgY29udGludWU7fQorCQkJCQkJai0tOworCQkJCQl9CisJCQkJfQorCQkJCWlmIChkaXNwbGF5LmhlbHBTdHJpbmcgIT0gMCkgT1MuQ0ZSZWxlYXNlIChkaXNwbGF5LmhlbHBTdHJpbmcpOworCQkgICAgCWRpc3BsYXkuaGVscFN0cmluZyA9IE9TLkNGU3RyaW5nQ3JlYXRlV2l0aENoYXJhY3RlcnMgKE9TLmtDRkFsbG9jYXRvckRlZmF1bHQsIGJ1ZmZlciwgaik7CisJCQkJSE1IZWxwQ29udGVudFJlYyBoZWxwQ29udGVudCA9IG5ldyBITUhlbHBDb250ZW50UmVjICgpOworCQkJCU9TLm1lbWNweSAoaGVscENvbnRlbnQsIGlvSGVscENvbnRlbnQsIEhNSGVscENvbnRlbnRSZWMuc2l6ZW9mKTsKKwkJICAgICAgICBoZWxwQ29udGVudC52ZXJzaW9uID0gT1Mua01hY0hlbHBWZXJzaW9uOworCQkgICAgICAgIGhlbHBDb250ZW50LnRhZ1NpZGUgPSBPUy5rSE1EZWZhdWx0U2lkZTsKKwkJCQlkaXNwbGF5LmhlbHBDb250cm9sID0gbnVsbDsKKwkJICAgICAgICBoZWxwQ29udGVudC5hYnNIb3RSZWN0X2xlZnQgPSAoc2hvcnQpIDA7CisJCSAgICAgCWhlbHBDb250ZW50LmFic0hvdFJlY3RfdG9wID0gKHNob3J0KSAwOworCQkgICAgICAgIGhlbHBDb250ZW50LmFic0hvdFJlY3RfcmlnaHQgPSAoc2hvcnQpIDA7CisJCSAgICAgICAgaGVscENvbnRlbnQuYWJzSG90UmVjdF9ib3R0b20gPSAoc2hvcnQpIDA7CisJCSAgICAgICAgaGVscENvbnRlbnQuY29udGVudDBfY29udGVudFR5cGUgPSBPUy5rSE1DRlN0cmluZ0NvbnRlbnQ7CisJCSAgICAgICAgaGVscENvbnRlbnQuY29udGVudDBfdGFnQ0ZTdHJpbmcgPSBkaXNwbGF5LmhlbHBTdHJpbmc7CisJCSAgICAgICAgaGVscENvbnRlbnQuY29udGVudDFfY29udGVudFR5cGUgPSBPUy5rSE1DRlN0cmluZ0NvbnRlbnQ7CisJCSAgICAgICAgaGVscENvbnRlbnQuY29udGVudDFfdGFnQ0ZTdHJpbmcgPSBkaXNwbGF5LmhlbHBTdHJpbmc7CisJCQkJT1MubWVtY3B5IChpb0hlbHBDb250ZW50LCBoZWxwQ29udGVudCwgSE1IZWxwQ29udGVudFJlYy5zaXplb2YpOworCQkJCWNvbnRlbnRQcm92aWRlZCBbMF0gPSBPUy5rSE1Db250ZW50UHJvdmlkZWQ7CisJCQl9CisJCQlPUy5tZW1jcHkgKG91dENvbnRlbnRQcm92aWRlZCwgY29udGVudFByb3ZpZGVkLCA0KTsKKwkJCWJyZWFrOworCQl9CisJCWNhc2UgT1Mua0hNRGlzcG9zZUNvbnRlbnQ6IHsKKwkJCWlmIChkaXNwbGF5LmhlbHBTdHJpbmcgIT0gMCkgT1MuQ0ZSZWxlYXNlIChkaXNwbGF5LmhlbHBTdHJpbmcpOworCQkJZGlzcGxheS5oZWxwU3RyaW5nID0gMDsKKwkJCWJyZWFrOworCQl9CisJfQorCXJldHVybiBPUy5ub0VycjsKIH0KIHZvaWQgaG9va0V2ZW50cyAoKSB7CiAJc3VwZXIuaG9va0V2ZW50cyAoKTsKLQkvKiBBVwotCWludCB3aW5kb3dQcm9jID0gZ2V0RGlzcGxheSAoKS53aW5kb3dQcm9jOwotCU9TLlh0QWRkRXZlbnRIYW5kbGVyIChoYW5kbGUsIE9TLktleVByZXNzTWFzaywgZmFsc2UsIHdpbmRvd1Byb2MsIFNXVC5LZXlEb3duKTsKLQlPUy5YdEFkZEV2ZW50SGFuZGxlciAoaGFuZGxlLCBPUy5LZXlSZWxlYXNlTWFzaywgZmFsc2UsIHdpbmRvd1Byb2MsIFNXVC5LZXlVcCk7Ci0JT1MuWHRBZGRFdmVudEhhbmRsZXIgKGhhbmRsZSwgT1MuQnV0dG9uUHJlc3NNYXNrLCBmYWxzZSwgd2luZG93UHJvYywgU1dULk1vdXNlRG93bik7Ci0JT1MuWHRBZGRFdmVudEhhbmRsZXIgKGhhbmRsZSwgT1MuQnV0dG9uUmVsZWFzZU1hc2ssIGZhbHNlLCB3aW5kb3dQcm9jLCBTV1QuTW91c2VVcCk7Ci0JT1MuWHRBZGRFdmVudEhhbmRsZXIgKGhhbmRsZSwgT1MuUG9pbnRlck1vdGlvbk1hc2ssIGZhbHNlLCB3aW5kb3dQcm9jLCBTV1QuTW91c2VNb3ZlKTsKLQlPUy5YdEFkZEV2ZW50SGFuZGxlciAoaGFuZGxlLCBPUy5FbnRlcldpbmRvd01hc2ssIGZhbHNlLCB3aW5kb3dQcm9jLCBTV1QuTW91c2VFbnRlcik7Ci0JT1MuWHRBZGRFdmVudEhhbmRsZXIgKGhhbmRsZSwgT1MuTGVhdmVXaW5kb3dNYXNrLCBmYWxzZSwgd2luZG93UHJvYywgU1dULk1vdXNlRXhpdCk7Ci0JT1MuWHRBZGRDYWxsYmFjayAoaGFuZGxlLCBPUy5YbU5leHBvc2VDYWxsYmFjaywgd2luZG93UHJvYywgU1dULlBhaW50KTsKLQkqLwotCURpc3BsYXkgZGlzcGxheT0gZ2V0RGlzcGxheSgpOwkJCi0JT1MuU2V0Q29udHJvbERhdGEoaGFuZGxlLCBPUy5rQ29udHJvbEVudGlyZUNvbnRyb2wsIE9TLmtDb250cm9sVXNlclBhbmVEcmF3UHJvY1RhZywgZGlzcGxheS5mVXNlclBhbmVEcmF3UHJvYyk7Ci0JaWYgKChzdHlsZSAmIFNXVC5TRVBBUkFUT1IpICE9IDApIHJldHVybjsKLQlPUy5TZXRDb250cm9sRGF0YShoYW5kbGUsIE9TLmtDb250cm9sRW50aXJlQ29udHJvbCwgT1Mua0NvbnRyb2xVc2VyUGFuZUhpdFRlc3RQcm9jVGFnLCBkaXNwbGF5LmZVc2VyUGFuZUhpdFRlc3RQcm9jKTsKKwlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCWludCBjb250cm9sUHJvYyA9IGRpc3BsYXkuY29udHJvbFByb2M7CisJaW50IFtdIG1hc2sxID0gbmV3IGludCBbXSB7CisJCU9TLmtFdmVudENsYXNzQ29udHJvbCwgT1Mua0V2ZW50Q29udHJvbERyYXcsCisJCU9TLmtFdmVudENsYXNzQ29udHJvbCwgT1Mua0V2ZW50Q29udHJvbEhpdCwKKwl9OworCWludCBjb250cm9sVGFyZ2V0ID0gT1MuR2V0Q29udHJvbEV2ZW50VGFyZ2V0IChoYW5kbGUpOworCU9TLkluc3RhbGxFdmVudEhhbmRsZXIgKGNvbnRyb2xUYXJnZXQsIGNvbnRyb2xQcm9jLCBtYXNrMS5sZW5ndGggLyAyLCBtYXNrMSwgaGFuZGxlLCBudWxsKTsKKwlpbnQgW10gbWFzazIgPSBuZXcgaW50IFtdIHsKKwkJT1Mua0V2ZW50Q2xhc3NDb250cm9sLCBPUy5rRXZlbnRDb250cm9sRHJhdywKKwl9OworCWlmIChpY29uSGFuZGxlICE9IDApIHsKKwkJY29udHJvbFRhcmdldCA9IE9TLkdldENvbnRyb2xFdmVudFRhcmdldCAoaWNvbkhhbmRsZSk7CisJCU9TLkluc3RhbGxFdmVudEhhbmRsZXIgKGNvbnRyb2xUYXJnZXQsIGNvbnRyb2xQcm9jLCBtYXNrMi5sZW5ndGggLyAyLCBtYXNrMiwgaWNvbkhhbmRsZSwgbnVsbCk7CisJfQorCWlmIChsYWJlbEhhbmRsZSAhPSAwKSB7CisJCWNvbnRyb2xUYXJnZXQgPSBPUy5HZXRDb250cm9sRXZlbnRUYXJnZXQgKGxhYmVsSGFuZGxlKTsKKwkJT1MuSW5zdGFsbEV2ZW50SGFuZGxlciAoY29udHJvbFRhcmdldCwgY29udHJvbFByb2MsIG1hc2syLmxlbmd0aCAvIDIsIG1hc2syLCBsYWJlbEhhbmRsZSwgbnVsbCk7CisJfQorCWlmIChhcnJvd0hhbmRsZSAhPSAwKSB7CisJCWNvbnRyb2xUYXJnZXQgPSBPUy5HZXRDb250cm9sRXZlbnRUYXJnZXQgKGFycm93SGFuZGxlKTsKKwkJT1MuSW5zdGFsbEV2ZW50SGFuZGxlciAoY29udHJvbFRhcmdldCwgY29udHJvbFByb2MsIG1hc2syLmxlbmd0aCAvIDIsIG1hc2syLCBhcnJvd0hhbmRsZSwgbnVsbCk7CisJfQorCWludCBoZWxwUHJvYyA9IGRpc3BsYXkuaGVscFByb2M7CisJT1MuSE1JbnN0YWxsQ29udHJvbENvbnRlbnRDYWxsYmFjayAoaGFuZGxlLCBoZWxwUHJvYyk7CiB9Ci0vKioKLSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlY2VpdmVyIGlzIGVuYWJsZWQgYW5kIGFsbAotICogb2YgdGhlIHJlY2VpdmVyJ3MgYW5jZXN0b3JzIGFyZSBlbmFibGVkLCBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+Ci0gKiBvdGhlcndpc2UuIEEgZGlzYWJsZWQgY29udHJvbCBpcyB0eXBpY2FsbHkgbm90IHNlbGVjdGFibGUgZnJvbSB0aGUKLSAqIHVzZXIgaW50ZXJmYWNlIGFuZCBkcmF3cyB3aXRoIGFuIGluYWN0aXZlIG9yICJncmF5ZWQiIGxvb2suCi0gKgotICogQHJldHVybiB0aGUgcmVjZWl2ZXIncyBlbmFibGVkIHN0YXRlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICogCi0gKiBAc2VlICNnZXRFbmFibGVkCi0gKi8KKwogcHVibGljIGJvb2xlYW4gaXNFbmFibGVkICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBnZXRFbmFibGVkICgpICYmIHBhcmVudC5pc0VuYWJsZWQgKCk7CiB9Ci0vKiBBVwotdm9pZCBtYW5hZ2VDaGlsZHJlbiAoKSB7Ci0JT1MuWHRNYW5hZ2VDaGlsZCAoaGFuZGxlKTsKKworaW50IGtFdmVudENvbnRyb2xIaXQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpbnQgcmVzdWx0ID0gc3VwZXIua0V2ZW50Q29udHJvbEhpdCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJaWYgKHJlc3VsdCA9PSBPUy5ub0VycikgcmV0dXJuIHJlc3VsdDsKKwlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKKwlpZiAoKHN0eWxlICYgU1dULlJBRElPKSAhPSAwKSB7CisJCWlmICgocGFyZW50LmdldFN0eWxlICgpICYgU1dULk5PX1JBRElPX0dST1VQKSA9PSAwKSB7CisJCQlzZWxlY3RSYWRpbyAoKTsKKwkJfQorCX0KKwlpZiAoKHN0eWxlICYgU1dULkNIRUNLKSAhPSAwKSBzZXRTZWxlY3Rpb24gKCFnZXRTZWxlY3Rpb24gKCkpOworCWlmICgoc3R5bGUgJiBTV1QuRFJPUF9ET1dOKSAhPSAwKSB7CisJCWludCBbXSB0aGVDb250cm9sID0gbmV3IGludCBbMV07CisJCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1EaXJlY3RPYmplY3QsIE9TLnR5cGVDb250cm9sUmVmLCBudWxsLCA0LCBudWxsLCB0aGVDb250cm9sKTsKKwkJaWYgKHRoZUNvbnRyb2wgWzBdID09IGFycm93SGFuZGxlKSBldmVudC5kZXRhaWwgPSBTV1QuQVJST1c7CisJfQorCXBvc3RFdmVudCAoU1dULlNlbGVjdGlvbiwgZXZlbnQpOworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7CiB9Ci0qLwotdm9pZCByZWRyYXcgKCkgewotCXJlZHJhd0hhbmRsZSAoMCwgMCwgMCwgMCwgaGFuZGxlLCB0cnVlKTsKKwordm9pZCByZWdpc3RlciAoKSB7CisJc3VwZXIucmVnaXN0ZXIgKCk7CisJV2lkZ2V0VGFibGUucHV0IChoYW5kbGUsIHRoaXMpOworCWlmIChpY29uSGFuZGxlICE9IDApIFdpZGdldFRhYmxlLnB1dCAoaWNvbkhhbmRsZSwgdGhpcyk7CisJaWYgKGxhYmVsSGFuZGxlICE9IDApIFdpZGdldFRhYmxlLnB1dCAobGFiZWxIYW5kbGUsIHRoaXMpOworCWlmIChhcnJvd0hhbmRsZSAhPSAwKSBXaWRnZXRUYWJsZS5wdXQgKGFycm93SGFuZGxlLCB0aGlzKTsKIH0KKwogdm9pZCByZWxlYXNlQ2hpbGQgKCkgewogCXN1cGVyLnJlbGVhc2VDaGlsZCAoKTsKIAlwYXJlbnQuZGVzdHJveUl0ZW0gKHRoaXMpOwogfQorCit2b2lkIHJlbGVhc2VIYW5kbGUgKCkgeworCXN1cGVyLnJlbGVhc2VIYW5kbGUgKCk7CisJaGFuZGxlID0gaWNvbkhhbmRsZSA9IGxhYmVsSGFuZGxlID0gYXJyb3dIYW5kbGUgPSAwOworfQorCiB2b2lkIHJlbGVhc2VXaWRnZXQgKCkgewotCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7Ci0JZGlzcGxheS5yZWxlYXNlVG9vbFRpcEhhbmRsZSAoaGFuZGxlKTsKIAlzdXBlci5yZWxlYXNlV2lkZ2V0ICgpOworCWlmIChjSWNvbiAhPSAwKSBkZXN0cm95Q0ljb24gKGNJY29uKTsKKwlpZiAobGFiZWxDSWNvbiAhPSAwKSBkZXN0cm95Q0ljb24gKGxhYmVsQ0ljb24pOworCWlmIChhcnJvd0NJY29uICE9IDApIGRlc3Ryb3lDSWNvbiAoYXJyb3dDSWNvbik7CisJY0ljb24gPSBsYWJlbENJY29uID0gYXJyb3dDSWNvbiA9IDA7CiAJcGFyZW50ID0gbnVsbDsKIAljb250cm9sID0gbnVsbDsKIAl0b29sVGlwVGV4dCA9IG51bGw7CiAJaW1hZ2UgPSBkaXNhYmxlZEltYWdlID0gaG90SW1hZ2UgPSBudWxsOyAKIH0KLS8qKgotICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGNvbnRyb2wgaXMgc2VsZWN0ZWQuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgYmUgbm90aWZpZWQKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTZWxlY3Rpb25MaXN0ZW5lcgotICogQHNlZSAjYWRkU2VsZWN0aW9uTGlzdGVuZXIKLSAqLworCiBwdWJsaWMgdm9pZCByZW1vdmVTZWxlY3Rpb25MaXN0ZW5lcihTZWxlY3Rpb25MaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC01MzksNjcgKzM3NCw2NiBAQAogCWV2ZW50VGFibGUudW5ob29rKFNXVC5TZWxlY3Rpb24sIGxpc3RlbmVyKTsKIAlldmVudFRhYmxlLnVuaG9vayhTV1QuRGVmYXVsdFNlbGVjdGlvbixsaXN0ZW5lcik7CQogfQorCiB2b2lkIHNlbGVjdFJhZGlvICgpIHsKLQl0aGlzLnNldFNlbGVjdGlvbiAodHJ1ZSk7Ci0JVG9vbEl0ZW0gW10gaXRlbXMgPSBwYXJlbnQuZ2V0SXRlbXMgKCk7CiAJaW50IGluZGV4ID0gMDsKKwlUb29sSXRlbSBbXSBpdGVtcyA9IHBhcmVudC5nZXRJdGVtcyAoKTsKIAl3aGlsZSAoaW5kZXggPCBpdGVtcy5sZW5ndGggJiYgaXRlbXMgW2luZGV4XSAhPSB0aGlzKSBpbmRleCsrOwotCVRvb2xJdGVtIGl0ZW07Ci0JaW50IGkgPSBpbmRleDsKLQl3aGlsZSAoLS1pID49IDAgJiYgKChpdGVtID0gaXRlbXMgW2ldKS5zdHlsZSAmIFNXVC5SQURJTykgIT0gMCkgewotCQlpdGVtLnNldFNlbGVjdGlvbiAoZmFsc2UpOwotCX0KLQlpID0gaW5kZXg7Ci0Jd2hpbGUgKCsraSA8IGl0ZW1zLmxlbmd0aCAmJiAoKGl0ZW0gPSBpdGVtcyBbaV0pLnN0eWxlICYgU1dULlJBRElPKSAhPSAwKSB7Ci0JCWl0ZW0uc2V0U2VsZWN0aW9uIChmYWxzZSk7Ci0JfQorCWludCBpID0gaW5kZXggLSAxOworCXdoaWxlIChpID49IDAgJiYgaXRlbXMgW2ldLnNldFJhZGlvU2VsZWN0aW9uIChmYWxzZSkpIC0taTsKKwlpbnQgaiA9IGluZGV4ICsgMTsKKwl3aGlsZSAoaiA8IGl0ZW1zLmxlbmd0aCAmJiBpdGVtcyBbal0uc2V0UmFkaW9TZWxlY3Rpb24gKGZhbHNlKSkgaisrOworCXNldFNlbGVjdGlvbiAodHJ1ZSk7CiB9Ci0vKgotICogVGhpcyBzZXRCb3VuZHMgaXMgb25seSBjYWxsZWQgZnJvbSBUb29sQmFyLnJlbGF5b3V0KCkKLSAqLworCiB2b2lkIHNldEJvdW5kcyAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKLQotCWlmIChjb250cm9sICE9IG51bGwpCi0JCWNvbnRyb2wuc2V0Qm91bmRzKHgsIHksIHdpZHRoLCBoZWlnaHQpOwotCQotCXdpZHRoID0gTWF0aC5tYXgod2lkdGgsIDApOwotCWhlaWdodCA9IE1hdGgubWF4KGhlaWdodCwgMCk7Ci0JCi0JaWYgKE1hY1V0aWwuVVNFX0ZSQU1FKSB7Ci0JCWZsb2F0W10gZj0gbmV3IGZsb2F0WzRdOwotCQlPUy5ISVZpZXdHZXRGcmFtZShoYW5kbGUsIGYpOwotCQlpZiAoZlswXSAhPSB4IHx8IGZbMV0gIT0geSB8fCBmWzJdICE9IHdpZHRoIHx8IGZbM10gIT0gaGVpZ2h0KQotCQkJT1MuSElWaWV3U2V0RnJhbWUoaGFuZGxlLCB4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKLQl9IGVsc2UgewotCQlzaG9ydFtdIGJvdW5kcz0gbmV3IHNob3J0WzRdOwotCQlzaG9ydFtdIHBib3VuZHM9IG5ldyBzaG9ydFs0XTsKLQkJT1MuR2V0Q29udHJvbEJvdW5kcyhoYW5kbGUsIGJvdW5kcyk7Ci0JCU9TLkdldENvbnRyb2xCb3VuZHMocGFyZW50LmhhbmRsZSwgcGJvdW5kcyk7Ci0JCQkKLQkJYm9vbGVhbiBzYW1lT3JpZ2luID0gKGJvdW5kc1sxXS1wYm91bmRzWzFdKSA9PSB4ICYmIChib3VuZHNbMF0tcGJvdW5kc1swXSkgPT0geTsKLQkJYm9vbGVhbiBzYW1lRXh0ZW50ID0gKGJvdW5kc1szXS1ib3VuZHNbMV0pID09IHdpZHRoICYmIChib3VuZHNbMl0tYm91bmRzWzBdKSA9PSBoZWlnaHQ7Ci0JCWlmICghc2FtZU9yaWdpbiB8fCAhc2FtZUV4dGVudCkKLQkJCU9TLlNldENvbnRyb2xCb3VuZHMoaGFuZGxlLCBuZXcgTWFjUmVjdChwYm91bmRzWzFdK3gsIHBib3VuZHNbMF0reSwgd2lkdGgsIGhlaWdodCkuZ2V0RGF0YSgpKTsKKwlpZiAoY29udHJvbCAhPSBudWxsKSBjb250cm9sLnNldEJvdW5kcyAoeCwgeSwgd2lkdGgsIGhlaWdodCk7CisJc2V0Qm91bmRzIChoYW5kbGUsIHgsIHksIHdpZHRoLCBoZWlnaHQsIHRydWUsIHRydWUsIGZhbHNlKTsKKwlpZiAoKHN0eWxlICYgU1dULlNFUEFSQVRPUikgIT0gMCkgcmV0dXJuOworCWludCBzcGFjZSA9IDA7CisJaW50IGluc2V0ID0gMzsKKwlpbnQgc3RyaW5nV2lkdGggPSAwLCBzdHJpbmdIZWlnaHQgPSAwOworCWlmICh0ZXh0Lmxlbmd0aCAoKSAhPSAwKSB7CisJCUdDIGdjID0gbmV3IEdDIChwYXJlbnQpOworCQlQb2ludCBzaXplID0gZ2Muc3RyaW5nRXh0ZW50ICh0ZXh0KTsKKwkJc3RyaW5nV2lkdGggPSBzaXplLng7CisJCXN0cmluZ0hlaWdodCA9IHNpemUueTsKKwkJZ2MuZGlzcG9zZSAoKTsKIAl9Ci0KLQlpZiAocGFyZW50LmZHb3RTaXplKQotCQlPUy5ISVZpZXdTZXRWaXNpYmxlKGhhbmRsZSwgdHJ1ZSk7CisJaW50IGltYWdlV2lkdGggPSAwLCBpbWFnZUhlaWdodCA9IDA7CisJaWYgKGltYWdlICE9IG51bGwpIHsKKwkJaWYgKHRleHQubGVuZ3RoICgpICE9IDApIHNwYWNlID0gMjsKKwkJUmVjdGFuZ2xlIHJlY3QgPSBpbWFnZS5nZXRCb3VuZHMgKCk7CisJCWltYWdlV2lkdGggPSByZWN0LndpZHRoOworCQlpbWFnZUhlaWdodCA9IHJlY3QuaGVpZ2h0OworCX0KKwlpbnQgYXJyb3dXaWR0aCA9IDAsIGFycm93SGVpZ2h0ID0gMDsKKwlpZiAoKHN0eWxlICYgU1dULkRST1BfRE9XTikgIT0gMCkgeworCQlhcnJvd1dpZHRoID0gNjsKKwkJYXJyb3dIZWlnaHQgPSA0OyAvL05PVCBET05FCisJfQorCWlmICgocGFyZW50LnN0eWxlICYgU1dULlJJR0hUKSAhPSAwKSB7CisJCWludCBpbWFnZVggPSBpbnNldDsKKwkJaW50IGltYWdlWSA9IGluc2V0ICsgKGhlaWdodCAtIChpbnNldCAqIDIpIC0gaW1hZ2VIZWlnaHQpIC8gMjsKKwkJc2V0Qm91bmRzIChpY29uSGFuZGxlLCBpbWFnZVgsIGltYWdlWSwgaW1hZ2VXaWR0aCwgaW1hZ2VIZWlnaHQsIHRydWUsIHRydWUsIGZhbHNlKTsKKwkJaW50IGxhYmVsWCA9IGltYWdlWCArIGltYWdlV2lkdGggKyBzcGFjZTsKKwkJaW50IGxhYmVsWSA9IGluc2V0ICsgKGhlaWdodCAtIChpbnNldCAqIDIpIC0gc3RyaW5nSGVpZ2h0KSAvIDI7CisJCXNldEJvdW5kcyAobGFiZWxIYW5kbGUsIGxhYmVsWCwgbGFiZWxZLCBzdHJpbmdXaWR0aCwgc3RyaW5nSGVpZ2h0LCB0cnVlLCB0cnVlLCBmYWxzZSk7CisJfSBlbHNlIHsKKwkJaW50IGltYWdlWCA9IGluc2V0ICsgKHdpZHRoIC0gKGluc2V0ICogMikgLSAoYXJyb3dXaWR0aCArIDMpIC0gaW1hZ2VXaWR0aCkgLyAyOworCQlpbnQgaW1hZ2VZID0gaW5zZXQ7CisJCXNldEJvdW5kcyAoaWNvbkhhbmRsZSwgaW1hZ2VYLCBpbWFnZVksIGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0LCB0cnVlLCB0cnVlLCBmYWxzZSk7CisJCWludCBsYWJlbFggPSBpbnNldCArICh3aWR0aCAtIChpbnNldCAqIDIpIC0gKGFycm93V2lkdGggKyAzKSAtIHN0cmluZ1dpZHRoKSAvIDI7CisJCWludCBsYWJlbFkgPSBpbWFnZVkgKyBpbWFnZUhlaWdodCArIHNwYWNlOworCQlzZXRCb3VuZHMgKGxhYmVsSGFuZGxlLCBsYWJlbFgsIGxhYmVsWSwgc3RyaW5nV2lkdGgsIHN0cmluZ0hlaWdodCwgdHJ1ZSwgdHJ1ZSwgZmFsc2UpOworCX0KKwlpZiAoKHN0eWxlICYgU1dULkRST1BfRE9XTikgIT0gMCkgeworCQlpbnQgYXJyb3dYID0gd2lkdGggLSBpbnNldCAtIGFycm93V2lkdGg7CisJCWludCBhcnJvd1kgPSBpbnNldCArIChoZWlnaHQgLSAoaW5zZXQgKiAyKSAtIGFycm93SGVpZ2h0KSAvIDI7CisJCXNldEJvdW5kcyAoYXJyb3dIYW5kbGUsIGFycm93WCwgYXJyb3dZLCBhcnJvd1dpZHRoLCBhcnJvd0hlaWdodCwgdHJ1ZSwgdHJ1ZSwgZmFsc2UpOworCX0KIH0KLS8qKgotICogU2V0cyB0aGUgY29udHJvbCB0aGF0IGlzIHVzZWQgdG8gZmlsbCB0aGUgYm91bmRzIG9mCi0gKiB0aGUgaXRlbSB3aGVuIHRoZSBpdGVtcyBpcyBhIDxjb2RlPlNFUEFSQVRPUjwvY29kZT4uCi0gKgotICogQHBhcmFtIGNvbnRyb2wgdGhlIG5ldyBjb250cm9sCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfQVJHVU1FTlQgLSBpZiB0aGUgY29udHJvbCBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+IAotICogICAgPGxpPkVSUk9SX0lOVkFMSURfUEFSRU5UIC0gaWYgdGhlIGNvbnRyb2wgaXMgbm90IGluIHRoZSBzYW1lIHdpZGdldCB0cmVlPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0Q29udHJvbCAoQ29udHJvbCBjb250cm9sKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoY29udHJvbCAhPSBudWxsKSB7CkBAIC02MTIsNTMwICs0NDYsMjAyIEBACiAJCWNvbnRyb2wuc2V0Qm91bmRzIChnZXRCb3VuZHMgKCkpOwogCX0KIH0KLS8qKgotICogRW5hYmxlcyB0aGUgcmVjZWl2ZXIgaWYgdGhlIGFyZ3VtZW50IGlzIDxjb2RlPnRydWU8L2NvZGU+LAotICogYW5kIGRpc2FibGVzIGl0IG90aGVyd2lzZS4KLSAqIDxwPgotICogQSBkaXNhYmxlZCBjb250cm9sIGlzIHR5cGljYWxseQotICogbm90IHNlbGVjdGFibGUgZnJvbSB0aGUgdXNlciBpbnRlcmZhY2UgYW5kIGRyYXdzIHdpdGggYW4KLSAqIGluYWN0aXZlIG9yICJncmF5ZWQiIGxvb2suCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIGVuYWJsZWQgdGhlIG5ldyBlbmFibGVkIHN0YXRlCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldEVuYWJsZWQgKGJvb2xlYW4gZW5hYmxlZCkgewogCWNoZWNrV2lkZ2V0KCk7Ci0JaWYgKGVuYWJsZWQpCi0JCU9TLkVuYWJsZUNvbnRyb2woaGFuZGxlKTsKLQllbHNlCi0JCU9TLkRpc2FibGVDb250cm9sKGhhbmRsZSk7CisJaWYgKGVuYWJsZWQpIHsKKwkJT1MuRW5hYmxlQ29udHJvbCAoaGFuZGxlKTsKKwl9IGVsc2UgeworCQlPUy5EaXNhYmxlQ29udHJvbCAoaGFuZGxlKTsKKwl9CiB9Ci0vKioKLSAqIFNldHMgdGhlIHJlY2VpdmVyJ3MgZGlzYWJsZWQgaW1hZ2UgdG8gdGhlIGFyZ3VtZW50LCB3aGljaCBtYXkgYmUKLSAqIG51bGwgaW5kaWNhdGluZyB0aGF0IG5vIGRpc2FibGVkIGltYWdlIHNob3VsZCBiZSBkaXNwbGF5ZWQuCi0gKiA8cD4KLSAqIFRoZSBkaXNibGVkIGltYWdlIGlzIGRpc3BsYXllZCB3aGVuIHRoZSByZWNlaXZlciBpcyBkaXNhYmxlZC4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gaW1hZ2UgdGhlIGRpc2FibGVkIGltYWdlIHRvIGRpc3BsYXkgb24gdGhlIHJlY2VpdmVyIChtYXkgYmUgbnVsbCkKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9BUkdVTUVOVCAtIGlmIHRoZSBpbWFnZSBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+IAotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCit2b2lkIHNldEZvbnRTdHlsZSAoRm9udCBmb250KSB7CisJLyogVGhpcyBjb2RlIGlzIGludGVudGlvbmFseSBjb21tZW50ZWQuICovCisvLwlDb250cm9sRm9udFN0eWxlUmVjIGZvbnRTdHlsZSA9IG5ldyBDb250cm9sRm9udFN0eWxlUmVjICgpOworLy8JaWYgKGZvbnQgIT0gbnVsbCkgeworLy8JCWZvbnRTdHlsZS5mbGFncyB8PSBPUy5rQ29udHJvbFVzZUZvbnRNYXNrIHwgT1Mua0NvbnRyb2xVc2VTaXplTWFzayB8IE9TLmtDb250cm9sVXNlRmFjZU1hc2s7CisvLwkJZm9udFN0eWxlLmZvbnQgPSBmb250LmlkOworLy8JCWZvbnRTdHlsZS5zdHlsZSA9IGZvbnQuc3R5bGU7CisvLwkJZm9udFN0eWxlLnNpemUgPSBmb250LnNpemU7CisvLwl9IGVsc2UgeworLy8JCWZvbnRTdHlsZS5mbGFncyB8PSBPUy5rQ29udHJvbFVzZVRoZW1lRm9udElETWFzazsKKy8vCQlmb250U3R5bGUuZm9udCA9IChzaG9ydCkgZGVmYXVsdFRoZW1lRm9udCAoKTsKKy8vCX0KKy8vCU9TLlNldENvbnRyb2xGb250U3R5bGUgKGxhYmVsSGFuZGxlLCBmb250U3R5bGUpOworCXVwZGF0ZVRleHQgKCk7Cit9CisKIHB1YmxpYyB2b2lkIHNldERpc2FibGVkSW1hZ2UgKEltYWdlIGltYWdlKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoaW1hZ2UgIT0gbnVsbCAmJiBpbWFnZS5pc0Rpc3Bvc2VkKCkpIGVycm9yKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKIAlpZiAoKHN0eWxlICYgU1dULlNFUEFSQVRPUikgIT0gMCkgcmV0dXJuOwogCWRpc2FibGVkSW1hZ2UgPSBpbWFnZTsKLQlpZiAoIWdldEVuYWJsZWQgKCkpIHJlZHJhdyAoKTsKKwl1cGRhdGVJbWFnZSAoKTsKIH0KLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyBob3QgaW1hZ2UgdG8gdGhlIGFyZ3VtZW50LCB3aGljaCBtYXkgYmUKLSAqIG51bGwgaW5kaWNhdGluZyB0aGF0IG5vIGhvdCBpbWFnZSBzaG91bGQgYmUgZGlzcGxheWVkLgotICogPHA+Ci0gKiBUaGUgaG90IGltYWdlIGlzIGRpc3BsYXllZCB3aGVuIHRoZSBtb3VzZSBlbnRlcnMgdGhlIHJlY2VpdmVyLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBpbWFnZSB0aGUgaG90IGltYWdlIHRvIGRpc3BsYXkgb24gdGhlIHJlY2VpdmVyIChtYXkgYmUgbnVsbCkKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfSU5WQUxJRF9BUkdVTUVOVCAtIGlmIHRoZSBpbWFnZSBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+IAotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRIb3RJbWFnZSAoSW1hZ2UgaW1hZ2UpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChpbWFnZSAhPSBudWxsICYmIGltYWdlLmlzRGlzcG9zZWQoKSkgZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOwogCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSByZXR1cm47CiAJaG90SW1hZ2UgPSBpbWFnZTsKLQlpZiAoKHBhcmVudC5zdHlsZSAmIFNXVC5GTEFUKSAhPSAwKSByZWRyYXcgKCk7CisJdXBkYXRlSW1hZ2UgKCk7CiB9CisKIHB1YmxpYyB2b2lkIHNldEltYWdlIChJbWFnZSBpbWFnZSkgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGltYWdlICE9IG51bGwgJiYgaW1hZ2UuaXNEaXNwb3NlZCgpKSBlcnJvcihTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CiAJaWYgKChzdHlsZSAmIFNXVC5TRVBBUkFUT1IpICE9IDApIHJldHVybjsKIAlzdXBlci5zZXRJbWFnZSAoaW1hZ2UpOwotCVBvaW50IHNpemUgPSBjb21wdXRlU2l6ZSAoKTsKLQlzZXRTaXplIChzaXplLngsIHNpemUueSk7Ci0JLy9yZWRyYXcgKCk7CisJdXBkYXRlSW1hZ2UgKCk7CiB9CiAKLS8qKgotICogU2V0cyB0aGUgc2VsZWN0aW9uIHN0YXRlIG9mIHRoZSByZWNlaXZlci4KLSAqIDxwPgotICogV2hlbiB0aGUgcmVjZWl2ZXIgaXMgb2YgdHlwZSA8Y29kZT5DSEVDSzwvY29kZT4gb3IgPGNvZGU+UkFESU88L2NvZGU+LAotICogaXQgaXMgc2VsZWN0ZWQgd2hlbiBpdCBpcyBjaGVja2VkICh3aGljaCBzb21lIHBsYXRmb3JtcyBkcmF3IGFzIGEKLSAqIHB1c2hlZCBpbiBidXR0b24pLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBzZWxlY3RlZCB0aGUgbmV3IHNlbGVjdGlvbiBzdGF0ZQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworYm9vbGVhbiBzZXRSYWRpb1NlbGVjdGlvbiAoYm9vbGVhbiB2YWx1ZSkgeworCWlmICgoc3R5bGUgJiBTV1QuUkFESU8pID09IDApIHJldHVybiBmYWxzZTsKKwlpZiAoZ2V0U2VsZWN0aW9uICgpICE9IHZhbHVlKSB7CisJCXNldFNlbGVjdGlvbiAodmFsdWUpOworCQlwb3N0RXZlbnQgKFNXVC5TZWxlY3Rpb24pOworCX0KKwlyZXR1cm4gdHJ1ZTsKK30KKwogcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uIChib29sZWFuIHNlbGVjdGVkKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoKHN0eWxlICYgKFNXVC5DSEVDSyB8IFNXVC5SQURJTykpID09IDApIHJldHVybjsKLQlpZiAoc2VsZWN0ZWQgPT0gc2V0KSByZXR1cm47Ci0Jc2V0ID0gc2VsZWN0ZWQ7Ci0Jc2V0RHJhd1ByZXNzZWQgKHNldCk7CisJaW50IHRyYW5zZm9ybSA9IHNlbGVjdGVkID8gT1Mua1RyYW5zZm9ybVNlbGVjdGVkIDogMDsKKwlPUy5TZXRDb250cm9sRGF0YSAoaWNvbkhhbmRsZSwgT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbEljb25UcmFuc2Zvcm1UYWcsIDIsIG5ldyBzaG9ydCBbXSB7KHNob3J0KXRyYW5zZm9ybX0pOworCU9TLlNldENvbnRyb2xEYXRhIChsYWJlbEhhbmRsZSwgT1Mua0NvbnRyb2xFbnRpcmVDb250cm9sLCBPUy5rQ29udHJvbEljb25UcmFuc2Zvcm1UYWcsIDIsIG5ldyBzaG9ydCBbXSB7KHNob3J0KXRyYW5zZm9ybX0pOworCXJlZHJhd1dpZGdldCAoaGFuZGxlKTsKIH0KIAotdm9pZCBzZXRTaXplIChpbnQgd2lkdGgsIGludCBoZWlnaHQpIHsKLQlNYWNSZWN0IGJvdW5kcz0gbmV3IE1hY1JlY3QoKTsKLQlPUy5HZXRDb250cm9sQm91bmRzKGhhbmRsZSwgYm91bmRzLmdldERhdGEoKSk7Ci0JaWYgKGJvdW5kcy5nZXRXaWR0aCgpICE9IHdpZHRoIHx8IGJvdW5kcy5nZXRIZWlnaHQoKSAhPSBoZWlnaHQpIHsKLQkJT1MuU2l6ZUNvbnRyb2woaGFuZGxlLCAoc2hvcnQpIHdpZHRoLCAoc2hvcnQpIGhlaWdodCk7Ci0JCXBhcmVudC5yZWxheW91dCgpOwordm9pZCBzZXRTaXplIChpbnQgd2lkdGgsIGludCBoZWlnaHQsIGJvb2xlYW4gbGF5b3V0KSB7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChoYW5kbGUsIHJlY3QpOworCWlmICgocmVjdC5yaWdodCAtIHJlY3QubGVmdCkgIT0gd2lkdGggfHwgKHJlY3QuYm90dG9tIC0gcmVjdC50b3ApICE9IGhlaWdodCkgeworCQlzZXRCb3VuZHMgKGhhbmRsZSwgMCwgMCwgd2lkdGgsIGhlaWdodCwgZmFsc2UsIHRydWUsIGZhbHNlKTsKKwkJaWYgKGxheW91dCkgcGFyZW50LnJlbGF5b3V0ICgpOwogCX0KIH0KKwogcHVibGljIHZvaWQgc2V0VGV4dCAoU3RyaW5nIHN0cmluZykgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKHN0cmluZyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSByZXR1cm47CiAJc3VwZXIuc2V0VGV4dCAoc3RyaW5nKTsKLQlQb2ludCBzaXplID0gY29tcHV0ZVNpemUgKCk7Ci0Jc2V0U2l6ZSAoc2l6ZS54LCBzaXplLnkpOworCXVwZGF0ZVRleHQgKCk7CiB9CiAKLS8qKgotICogU2V0cyB0aGUgcmVjZWl2ZXIncyB0b29sIHRpcCB0ZXh0IHRvIHRoZSBhcmd1bWVudCwgd2hpY2gKLSAqIG1heSBiZSBudWxsIGluZGljYXRpbmcgdGhhdCBubyB0b29sIHRpcCB0ZXh0IHNob3VsZCBiZSBzaG93bi4KLSAqCi0gKiBAcGFyYW0gc3RyaW5nIHRoZSBuZXcgdG9vbCB0aXAgdGV4dCAob3IgbnVsbCkKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyB2b2lkIHNldFRvb2xUaXBUZXh0IChTdHJpbmcgc3RyaW5nKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAl0b29sVGlwVGV4dCA9IHN0cmluZzsKIH0KLS8qKgotICogU2V0cyB0aGUgd2lkdGggb2YgdGhlIHJlY2VpdmVyLgotICoKLSAqIEBwYXJhbSB3aWR0aCB0aGUgbmV3IHdpZHRoCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyB2b2lkIHNldFdpZHRoIChpbnQgd2lkdGgpIHsKIAljaGVja1dpZGdldCgpOwogCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSA9PSAwKSByZXR1cm47CiAJaWYgKHdpZHRoIDwgMCkgcmV0dXJuOwotCU1hY1JlY3QgYm91bmRzPSBuZXcgTWFjUmVjdCgpOwotCU9TLkdldENvbnRyb2xCb3VuZHMoaGFuZGxlLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQlzZXRTaXplICh3aWR0aCwgYm91bmRzLmdldEhlaWdodCgpKTsKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChoYW5kbGUsIHJlY3QpOworCXNldFNpemUgKHdpZHRoLCByZWN0LmJvdHRvbSAtIHJlY3QudG9wLCB0cnVlKTsKIAlpZiAoY29udHJvbCAhPSBudWxsICYmICFjb250cm9sLmlzRGlzcG9zZWQgKCkpIHsKIAkJY29udHJvbC5zZXRCb3VuZHMgKGdldEJvdW5kcyAoKSk7CiAJfQogfQotdm9pZCBzZXREcmF3UHJlc3NlZCAoYm9vbGVhbiB2YWx1ZSkgewotCS8qIEFXCi0JaW50IHNoYWRvd1R5cGUgPSB2YWx1ZSA/IE9TLlhtU0hBRE9XX0lOIDogT1MuWG1TSEFET1dfT1VUOwotCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTnNoYWRvd1R5cGUsIHNoYWRvd1R5cGV9OwotCU9TLlh0U2V0VmFsdWVzKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQkqLwotCWlmIChmUHJlc3NlZCAhPSB2YWx1ZSkgewotCQlmUHJlc3NlZD0gdmFsdWU7Ci0JCXJlZHJhdygpOwotCX0KLX0KLWludCBwcm9jZXNzS2V5RG93biAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0JLyogQVcKLQlYS2V5RXZlbnQgeEV2ZW50ID0gbmV3IFhLZXlFdmVudCAoKTsKLQlPUy5tZW1tb3ZlICh4RXZlbnQsIGNhbGxEYXRhLCBYS2V5RXZlbnQuc2l6ZW9mKTsKLQkqLwotCS8qCi0JKiBGb3J3YXJkIHRoZSBrZXkgZXZlbnQgdG8gdGhlIHBhcmVudC4KLQkqIFRoaXMgaXMgbmVjZXNzYXJ5IHNvIHRoYXQgbW91c2UgbGlzdGVuZXJzCi0JKiBpbiB0aGUgcGFyZW50IHdpbGwgYmUgY2FsbGVkLCBkZXNwaXRlIHRoZQotCSogZmFjdCB0aGF0IHRoZSBldmVudCBkaWQgbm90IHJlYWxseSBvY2N1cgotCSogaW4gWCBpbiB0aGUgcGFyZW50LiAgVGhpcyBpcyBkb25lIHRvIGJlCi0JKiBjb21wYXRpYmxlIHdpdGggV2luZG93cy4KLQkqLwotCS8qIEFXCi0JeEV2ZW50LndpbmRvdyA9IE9TLlh0V2luZG93IChwYXJlbnQuaGFuZGxlKTsKLS8vCU9TLm1lbW1vdmUgKGNhbGxEYXRhLCB4RXZlbnQsIFhLZXlFdmVudC5zaXplb2YpOwotCSovCi0JcGFyZW50LnByb2Nlc3NLZXlEb3duIChjYWxsRGF0YSk7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc0tleVVwIChPYmplY3QgY2FsbERhdGEpIHsKLQkvKiBBVwotCVhLZXlFdmVudCB4RXZlbnQgPSBuZXcgWEtleUV2ZW50ICgpOwotCU9TLm1lbW1vdmUgKHhFdmVudCwgY2FsbERhdGEsIFhLZXlFdmVudC5zaXplb2YpOwotCWludCBbXSBrZXlzeW0gPSBuZXcgaW50IFsxXTsKLQlPUy5YTG9va3VwU3RyaW5nICh4RXZlbnQsIG51bGwsIDAsIGtleXN5bSwgbnVsbCk7Ci0Ja2V5c3ltIFswXSAmPSAweEZGRkY7Ci0Jc3dpdGNoIChrZXlzeW0gWzBdKSB7Ci0JCWNhc2UgT1MuWEtfc3BhY2U6Ci0JCWNhc2UgT1MuWEtfUmV0dXJuOgotCQkJY2xpY2sgKGtleXN5bSBbMF0gPT0gT1MuWEtfUmV0dXJuLCB4RXZlbnQpOwotCQkJYnJlYWs7Ci0JfQotCSovCi0JLyoKLQkqIEZvcndhcmQgdGhlIGtleSBldmVudCB0byB0aGUgcGFyZW50LgotCSogVGhpcyBpcyBuZWNlc3Nhcnkgc28gdGhhdCBtb3VzZSBsaXN0ZW5lcnMKLQkqIGluIHRoZSBwYXJlbnQgd2lsbCBiZSBjYWxsZWQsIGRlc3BpdGUgdGhlCi0JKiBmYWN0IHRoYXQgdGhlIGV2ZW50IGRpZCBub3QgcmVhbGx5IG9jY3VyCi0JKiBpbiBYIGluIHRoZSBwYXJlbnQuICBUaGlzIGlzIGRvbmUgdG8gYmUKLQkqIGNvbXBhdGlibGUgd2l0aCBXaW5kb3dzLgotCSovCi0JLyogQVcKLQl4RXZlbnQud2luZG93ID0gT1MuWHRXaW5kb3cgKHBhcmVudC5oYW5kbGUpOwotLy8JT1MubWVtbW92ZSAoY2FsbERhdGEsIHhFdmVudCwgWEtleUV2ZW50LnNpemVvZik7Ci0JKi8KLQlwYXJlbnQucHJvY2Vzc0tleVVwIChjYWxsRGF0YSk7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc01vdXNlRG93biAoTWFjTW91c2VFdmVudCBtbUV2ZW50KSB7Ci0JRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKLS8vCVNoZWxsIHNoZWxsID0gcGFyZW50LmdldFNoZWxsICgpOwotCWRpc3BsYXkuaGlkZVRvb2xUaXAgKCk7Ci0JCi0JLyogQVcKLQlYQnV0dG9uRXZlbnQgeEV2ZW50ID0gbmV3IFhCdXR0b25FdmVudCAoKTsKLQlPUy5tZW1tb3ZlICh4RXZlbnQsIGNhbGxEYXRhLCBYQnV0dG9uRXZlbnQuc2l6ZW9mKTsKLQkqLwotCWlmIChtbUV2ZW50LmdldEJ1dHRvbigpID09IDEpIHsKLQkJaWYgKCFzZXQgJiYgKHN0eWxlICYgU1dULlJBRElPKSA9PSAwKSB7Ci0JCQlzZXREcmF3UHJlc3NlZCAoIXNldCk7Ci0JCX0KLQl9Ci0JCi0JLyoKLQkqIEZvcndhcmQgdGhlIG1vdXNlIGV2ZW50IHRvIHRoZSBwYXJlbnQuCi0JKiBUaGlzIGlzIG5lY2Vzc2FyeSBzbyB0aGF0IG1vdXNlIGxpc3RlbmVycwotCSogaW4gdGhlIHBhcmVudCB3aWxsIGJlIGNhbGxlZCwgZGVzcGl0ZSB0aGUKLQkqIGZhY3QgdGhhdCB0aGUgZXZlbnQgZGlkIG5vdCByZWFsbHkgb2NjdXIKLQkqIGluIFggaW4gdGhlIHBhcmVudC4gIFRoaXMgaXMgZG9uZSB0byBiZQotCSogY29tcGF0aWJsZSB3aXRoIFdpbmRvd3MuCi0JKi8KLQkvKiBBVwotCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTngsIDAsIE9TLlhtTnksIDB9OwotCU9TLlh0R2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JeEV2ZW50LndpbmRvdyA9IE9TLlh0V2luZG93IChwYXJlbnQuaGFuZGxlKTsKLQl4RXZlbnQueCArPSBhcmdMaXN0IFsxXTsgIHhFdmVudC55ICs9IGFyZ0xpc3QgWzNdOwotCU9TLm1lbW1vdmUgKGNhbGxEYXRhLCB4RXZlbnQsIFhCdXR0b25FdmVudC5zaXplb2YpOwotCSovCi0JcGFyZW50LnByb2Nlc3NNb3VzZURvd24gKG1tRXZlbnQpOwotCS8qCi0JKiBJdCBpcyBwb3NzaWJsZSB0aGF0IHRoZSBzaGVsbCBtYXkgYmUKLQkqIGRpc3Bvc2VkIGF0IHRoaXMgcG9pbnQuICBJZiB0aGlzIGhhcHBlbnMKLQkqIGRvbid0IHNlbmQgdGhlIGFjdGl2YXRlIGFuZCBkZWFjdGl2YXRlCi0JKiBldmVudHMuCi0JKi8JCi0vLwlpZiAoIXNoZWxsLmlzRGlzcG9zZWQoKSkgewotLy8JCXNoZWxsLnNldEFjdGl2ZUNvbnRyb2wgKHBhcmVudCk7Ci0vLwl9Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc01vdXNlRW50ZXIgKE1hY01vdXNlRXZlbnQgbW1lKSB7Ci0JaWYgKG1tZS5nZXRCdXR0b24oKSA9PSAxKSBzZXREcmF3UHJlc3NlZCAoIXNldCk7Ci0JZWxzZSBpZiAoKHBhcmVudC5zdHlsZSAmIFNXVC5GTEFUKSAhPSAwKSByZWRyYXcgKCk7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc01vdXNlRXhpdCAoTWFjTW91c2VFdmVudCBtbWUpIHsKLQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOwotCWRpc3BsYXkucmVtb3ZlTW91c2VIb3ZlclRpbWVPdXQgKCk7Ci0JZGlzcGxheS5oaWRlVG9vbFRpcCAoKTsKLQlpZiAobW1lLmdldEJ1dHRvbigpID09IDEpIHNldERyYXdQcmVzc2VkIChzZXQpOwotCWVsc2UgaWYgKChwYXJlbnQuc3R5bGUgJiBTV1QuRkxBVCkgIT0gMCkgcmVkcmF3ICgpOwotCXJldHVybiAwOwotfQotUG9pbnQgdG9Db250cm9sIChQb2ludCBwb2ludCkgewotCXJldHVybiBNYWNVdGlsLnRvQ29udHJvbChoYW5kbGUsIHBvaW50KTsKLX0KLS8qIEFXCi1ib29sZWFuIHRyYW5zbGF0ZVRyYXZlcnNhbCAoaW50IGtleSwgWEtleUV2ZW50IHhFdmVudCkgewotCXJldHVybiBwYXJlbnQudHJhbnNsYXRlVHJhdmVyc2FsIChrZXksIHhFdmVudCk7Ci19Ci0qLwotaW50IHByb2Nlc3NNb3VzZUhvdmVyIChNYWNNb3VzZUV2ZW50IG1tZSkgewotCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7Ci0JZGlzcGxheS5zaG93VG9vbFRpcCAoaGFuZGxlLCB0b29sVGlwVGV4dCk7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc01vdXNlTW92ZSAoTWFjTW91c2VFdmVudCBtbUV2ZW50KSB7Ci0JRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKLQlkaXNwbGF5LmFkZE1vdXNlSG92ZXJUaW1lT3V0IChoYW5kbGUpOwogCi0JLyoKLQkqIEZvcndhcmQgdGhlIG1vdXNlIGV2ZW50IHRvIHRoZSBwYXJlbnQuCi0JKiBUaGlzIGlzIG5lY2Vzc2FyeSBzbyB0aGF0IG1vdXNlIGxpc3RlbmVycwotCSogaW4gdGhlIHBhcmVudCB3aWxsIGJlIGNhbGxlZCwgZGVzcGl0ZSB0aGUKLQkqIGZhY3QgdGhhdCB0aGUgZXZlbnQgZGlkIG5vdCByZWFsbHkgb2NjdXIKLQkqIGluIFggaW4gdGhlIHBhcmVudC4gIFRoaXMgaXMgZG9uZSB0byBiZQotCSogY29tcGF0aWJsZSB3aXRoIFdpbmRvd3MuCi0JKi8KLQkvKiBBVwotCVhCdXR0b25FdmVudCB4RXZlbnQgPSBuZXcgWEJ1dHRvbkV2ZW50ICgpOwotCU9TLm1lbW1vdmUgKHhFdmVudCwgY2FsbERhdGEsIFhCdXR0b25FdmVudC5zaXplb2YpOwotCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTngsIDAsIE9TLlhtTnksIDB9OwotCU9TLlh0R2V0VmFsdWVzIChoYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JeEV2ZW50LndpbmRvdyA9IE9TLlh0V2luZG93IChwYXJlbnQuaGFuZGxlKTsKLQl4RXZlbnQueCArPSBhcmdMaXN0IFsxXTsgIHhFdmVudC55ICs9IGFyZ0xpc3QgWzNdOwotCSovCi0JLyoKLQkqIFRoaXMgY29kZSBpcyBpbnRlbnRpb25hbGx5IGNvbW1lbnRlZC4KLQkqIEN1cnJlbnRseSwgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZQotCSogbW91c2UgbW92ZSBjb2RlIGluIHRoZSBwYXJlbnQgaW50ZXJmZXJlcwotCSogd2l0aCB0b29sIHRpcHMgZm9yIHRvb2wgaXRlbXMuCi0JKi8KLS8vCU9TLm1lbW1vdmUgKGNhbGxEYXRhLCB4RXZlbnQsIFhCdXR0b25FdmVudC5zaXplb2YpOwotLy8JcGFyZW50LnByb2Nlc3NNb3VzZU1vdmUgKGNhbGxEYXRhKTsKLQotCXBhcmVudC5zZW5kTW91c2VFdmVudCAoU1dULk1vdXNlTW92ZSwgMCwgbW1FdmVudCk7Ci0KLQlyZXR1cm4gMDsKK3ZvaWQgc2V0Wk9yZGVyICgpIHsKKwlPUy5ISVZpZXdBZGRTdWJ2aWV3IChwYXJlbnQuaGFuZGxlLCBoYW5kbGUpOworCWlmIChpY29uSGFuZGxlICE9IDApIE9TLkhJVmlld0FkZFN1YnZpZXcgKGhhbmRsZSwgaWNvbkhhbmRsZSk7CisJaWYgKGxhYmVsSGFuZGxlICE9IDApIE9TLkhJVmlld0FkZFN1YnZpZXcgKGhhbmRsZSwgbGFiZWxIYW5kbGUpOworCWlmIChhcnJvd0hhbmRsZSAhPSAwKSBPUy5ISVZpZXdBZGRTdWJ2aWV3IChoYW5kbGUsIGFycm93SGFuZGxlKTsKIH0KLWludCBwcm9jZXNzTW91c2VVcCAoTWFjTW91c2VFdmVudCBtbUV2ZW50KSB7Ci0JRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKLQlkaXNwbGF5LmhpZGVUb29sVGlwKCk7IAotCQkKLQlpZiAobW1FdmVudC5nZXRCdXR0b24oKSA9PSAxKSB7Ci0JCS8qIEFXCi0JCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTndpZHRoLCAwLCBPUy5YbU5oZWlnaHQsIDB9OwotCQlPUy5YdEdldFZhbHVlcyAoaGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotCQlpbnQgd2lkdGggPSBhcmdMaXN0IFsxXSwgaGVpZ2h0ID0gYXJnTGlzdCBbM107Ci0JCSovCi0JCU1hY1JlY3QgYm91bmRzPSBuZXcgTWFjUmVjdCgpOwotCQlPUy5HZXRDb250cm9sQm91bmRzKGhhbmRsZSwgYm91bmRzLmdldERhdGEoKSk7Ci0JCWludCB3aWR0aCA9IGJvdW5kcy5nZXRXaWR0aCgpLCBoZWlnaHQgPSBib3VuZHMuZ2V0SGVpZ2h0KCk7Ci0JCQkJCi0JCVBvaW50IG1wPSBNYWNVdGlsLnRvQ29udHJvbChoYW5kbGUsIG1tRXZlbnQuZ2V0V2hlcmUoKSk7Ci0JCS8vU3lzdGVtLm91dC5wcmludGxuKCJUb29sSXRlbS5wcm9jZXNzTW91c2VVcDogIiArIG1wKTsKIAotCQlpZiAoMCA8PSBtcC54ICYmIG1wLnggPCB3aWR0aCAmJiAwIDw9IG1wLnkgJiYgbXAueSA8IGhlaWdodCkgewotCQkJY2xpY2sgKG1wLnggPiB3aWR0aCAtIDEyLCBtbUV2ZW50KTsKLQkJfQotCQlzZXREcmF3UHJlc3NlZChzZXQpOwotCX0KLQkvKgotCSogRm9yd2FyZCB0aGUgbW91c2UgZXZlbnQgdG8gdGhlIHBhcmVudC4KLQkqIFRoaXMgaXMgbmVjZXNzYXJ5IHNvIHRoYXQgbW91c2UgbGlzdGVuZXJzCi0JKiBpbiB0aGUgcGFyZW50IHdpbGwgYmUgY2FsbGVkLCBkZXNwaXRlIHRoZQotCSogZmFjdCB0aGF0IHRoZSBldmVudCBkaWQgbm90IHJlYWxseSBvY2N1cgotCSogaW4gWCBpbiB0aGUgcGFyZW50LiAgVGhpcyBpcyBkb25lIHRvIGJlCi0JKiBjb21wYXRpYmxlIHdpdGggV2luZG93cy4KLQkqLwotCS8qIEFXCi0JaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1OeCwgMCwgT1MuWG1OeSwgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQl4RXZlbnQud2luZG93ID0gT1MuWHRXaW5kb3cgKHBhcmVudC5oYW5kbGUpOwotCXhFdmVudC54ICs9IGFyZ0xpc3QgWzFdOyAgeEV2ZW50LnkgKz0gYXJnTGlzdCBbM107Ci0JT1MubWVtbW92ZSAoY2FsbERhdGEsIHhFdmVudCwgWEJ1dHRvbkV2ZW50LnNpemVvZik7Ci0JKi8KLQlwYXJlbnQucHJvY2Vzc01vdXNlVXAgKG1tRXZlbnQpOwotCi0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc1BhaW50IChPYmplY3QgY2FsbERhdGEpIHsKLQotCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwICYmIGNvbnRyb2wgIT0gbnVsbCkKLQkJcmV0dXJuIDA7Ci0JCQotCU1hY1JlY3QgYm91bmRzPSBuZXcgTWFjUmVjdCgpOwotCU9TLkdldENvbnRyb2xCb3VuZHMoaGFuZGxlLCBib3VuZHMuZ2V0RGF0YSgpKTsKLQlib3VuZHMuc2V0TG9jYXRpb24oMCwgMCk7Ci0JCi0JaW50IHdpZHRoPSBib3VuZHMuZ2V0V2lkdGgoKTsKLQlpbnQgaGVpZ2h0PSBib3VuZHMuZ2V0SGVpZ2h0KCk7Ci0JCi0JZmluYWwgRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKLQotCURyYXdhYmxlIGRyYXdhYmxlPSBuZXcgRHJhd2FibGUoKSB7Ci0JCXB1YmxpYyBpbnQgaW50ZXJuYWxfbmV3X0dDIChHQ0RhdGEgZGF0YSkgewotCQkJZGF0YS5kZXZpY2UgPSBkaXNwbGF5OwotCQkJZGF0YS5mb3JlZ3JvdW5kID0gcGFyZW50LmdldEZvcmVncm91bmRQaXhlbCgpOwotCQkJZGF0YS5iYWNrZ3JvdW5kID0gcGFyZW50LmdldEJhY2tncm91bmRQaXhlbCgpOwotCQkJZGF0YS5mb250ID0gcGFyZW50LmZvbnQuaGFuZGxlOwotCQkJZGF0YS5jb250cm9sSGFuZGxlID0gaGFuZGxlOwotCQkJcmV0dXJuIE9TLkdldFdpbmRvd1BvcnQoT1MuR2V0Q29udHJvbE93bmVyKGhhbmRsZSkpOwotCQl9Ci0JCXB1YmxpYyB2b2lkIGludGVybmFsX2Rpc3Bvc2VfR0MgKGludCB4R0MsIEdDRGF0YSBkYXRhKSB7Ci0JCX0KLQl9OwotCQotCWJvb2xlYW4gaGFzQ3Vyc29yPSBoYXNDdXJzb3IgKCk7Ci0KLQlHQyBnYz0gbmV3IEdDKGRyYXdhYmxlKTsKLQkKLQlNYWNDb250cm9sRXZlbnQgbWU9IChNYWNDb250cm9sRXZlbnQpIGNhbGxEYXRhOwotCVJlY3RhbmdsZSByPSBnYy5jYXJib25fZm9jdXMobWUuZ2V0RGFtYWdlUmVnaW9uSGFuZGxlKCkpOwotCWlmICghci5pc0VtcHR5KCkpIHsKLQkJCi0JCS8vIGVyYXNlIGJhY2tncm91bmQKLQkJZ2MuZmlsbFJlY3RhbmdsZSgwLCAwLCB3aWR0aCwgaGVpZ2h0KTsKLQkJCi0JCWlmICgoc3R5bGUgJiBTV1QuU0VQQVJBVE9SKSAhPSAwKSB7Ci0JCQotCQkJT1MuRHJhd1RoZW1lU2VwYXJhdG9yKGJvdW5kcy5nZXREYXRhKCksIE9TLmtUaGVtZVN0YXRlQWN0aXZlKTsKLQkJCQordm9pZCB1cGRhdGVJbWFnZSAoKSB7CisJaWYgKGNJY29uICE9IDApIGRlc3Ryb3lDSWNvbiAoY0ljb24pOworCWNJY29uID0gMDsKKwlJbWFnZSBpbWFnZSA9IG51bGw7CisJaWYgKGhvdEltYWdlICE9IG51bGwpIHsKKwkJaW1hZ2UgPSBob3RJbWFnZTsKKwl9IGVsc2UgeworCQlpZiAodGhpcy5pbWFnZSAhPSBudWxsKSB7CisJCQlpbWFnZSA9IHRoaXMuaW1hZ2U7CiAJCX0gZWxzZSB7Ci0JCQkJCQotCQkJaWYgKChwYXJlbnQuc3R5bGUgJiBTV1QuRkxBVCkgIT0gMCAmJiBzZXQpIHsKLQkJCQlnYy5zZXRCYWNrZ3JvdW5kKENvbG9yLmNhcmJvbl9uZXcoZGlzcGxheSwgMHhFMEUwRTAsIGZhbHNlKSk7Ci0JCQkJZ2MuZmlsbFJvdW5kUmVjdGFuZ2xlKDEsIDEsIHdpZHRoLTIsIGhlaWdodC0yLCA4LCA4KTsKLQkJCQlnYy5zZXRGb3JlZ3JvdW5kKGRpc3BsYXkuZ2V0U3lzdGVtQ29sb3IoU1dULkNPTE9SX0dSQVkpKTsKLQkJCQlnYy5kcmF3Um91bmRSZWN0YW5nbGUoMSwgMSwgd2lkdGgtMywgaGVpZ2h0LTMsIDgsIDgpOwotCQkJfQotCQkKLQkJCUltYWdlIGN1cnJlbnRJbWFnZSA9IGltYWdlOwotCQkJYm9vbGVhbiBlbmFibGVkID0gZ2V0RW5hYmxlZCgpOwotCQkKLQkJCXNob3J0W10gbmV3SW5mbz0gbmV3IHNob3J0WzNdOwotCQkJCQkKLQkJCW5ld0luZm9bMV09IHNldCA/IE9TLmtUaGVtZUJ1dHRvbk9uIDogT1Mua1RoZW1lQnV0dG9uT2ZmOwotCQkJCi0JCQlpZiAoKHBhcmVudC5zdHlsZSAmIFNXVC5GTEFUKSAhPSAwKSB7Ci0JCQkJCi0JCQkJaWYgKGhhc0N1cnNvciAmJiBlbmFibGVkKSB7Ci0JCQkJCWlmIChPUy5TdGlsbERvd24oKSkKLQkJCQkJCW5ld0luZm9bMF09IE9TLmtUaGVtZVN0YXRlUHJlc3NlZDsKLQkJCQkJZWxzZQotCQkJCQkJbmV3SW5mb1swXT0gT1Mua1RoZW1lU3RhdGVBY3RpdmU7Ci0JCQkJfSBlbHNlCi0JCQkJCW5ld0luZm89IG51bGw7Ci0JCQkJCi0JCQkJLyogRGV0ZXJtaW5lIGlmIGhvdCBpbWFnZSBzaG91bGQgYmUgdXNlZCAqLwotCQkJCWlmIChlbmFibGVkICYmIGhhc0N1cnNvciAmJiBob3RJbWFnZSAhPSBudWxsKSB7Ci0JCQkJCWN1cnJlbnRJbWFnZSA9IGhvdEltYWdlOwotCQkJCX0KLQkJCX0gZWxzZSB7Ci0JCQkJbmV3SW5mb1swXT0gKGhhc0N1cnNvciAmJiBPUy5TdGlsbERvd24oKSkgPyBPUy5rVGhlbWVTdGF0ZVByZXNzZWQgOiBPUy5rVGhlbWVTdGF0ZUFjdGl2ZTsKLQkJCX0KLQkKLQkJCWlmIChuZXdJbmZvICE9IG51bGwpIHsKLQkJCQlNYWNSZWN0IGI9IG5ldyBNYWNSZWN0KDEsIDEsIHdpZHRoLTIsIGhlaWdodC0yKTsKLQkJCQlPUy5EcmF3VGhlbWVCdXR0b24oYi5nZXREYXRhKCksIE9TLmtUaGVtZVNtYWxsQmV2ZWxCdXR0b24sIG5ld0luZm8sIGZQcmV2SW5mbywgMCwgMCwgMCk7Ci0JCQl9Ci0JCQlmUHJldkluZm89IG5ld0luZm87Ci0JCQkJCi0JCQlpZiAoZW5hYmxlZCkgewotCQkJCWdjLnNldEZvcmVncm91bmQgKHBhcmVudC5nZXRGb3JlZ3JvdW5kKCkpOwotCQkJfSBlbHNlIHsKLQkJCQljdXJyZW50SW1hZ2UgPSBkaXNhYmxlZEltYWdlOwotCQkJCWlmIChjdXJyZW50SW1hZ2UgPT0gbnVsbCAmJiBpbWFnZSAhPSBudWxsKSB7Ci0JCQkJCWN1cnJlbnRJbWFnZSA9IG5ldyBJbWFnZSAoZGlzcGxheSwgaW1hZ2UsIFNXVC5JTUFHRV9ESVNBQkxFKTsKLQkJCQl9Ci0JCQkJQ29sb3IgZGlzYWJsZWRDb2xvciA9IGRpc3BsYXkuZ2V0U3lzdGVtQ29sb3IgKFNXVC5DT0xPUl9XSURHRVRfTk9STUFMX1NIQURPVyk7Ci0JCQkJZ2Muc2V0Rm9yZWdyb3VuZCAoZGlzYWJsZWRDb2xvcik7Ci0JCQl9Ci0JCQkKLQkJCWludCB0ZXh0WCA9IDAsIHRleHRZID0gMCwgdGV4dFdpZHRoID0gMCwgdGV4dEhlaWdodCA9IDA7Ci0JCQlpZiAodGV4dC5sZW5ndGgoKSA+IDApIHsKLQkJCQlpbnQgZmxhZ3MgPSBTV1QuRFJBV19ERUxJTUlURVIgfCBTV1QuRFJBV19UQUIgfCBTV1QuRFJBV19NTkVNT05JQzsKLQkJCQlQb2ludCB0ZXh0RXh0ZW50ID0gZ2MudGV4dEV4dGVudCAodGV4dCwgZmxhZ3MpOwotCQkJCXRleHRXaWR0aCA9IHRleHRFeHRlbnQueDsKLQkJCQl0ZXh0SGVpZ2h0ID0gdGV4dEV4dGVudC55OwotCQkJfQkKLQkJCWludCBpbWFnZVggPSAwLCBpbWFnZVkgPSAwLCBpbWFnZVdpZHRoID0gMCwgaW1hZ2VIZWlnaHQgPSAwOwotCQkJaWYgKGN1cnJlbnRJbWFnZSAhPSBudWxsKSB7Ci0JCQkJdHJ5IHsgLy8gQVcgRklYTUUKLQkJCQkJUmVjdGFuZ2xlIGltYWdlQm91bmRzID0gY3VycmVudEltYWdlLmdldEJvdW5kcyAoKTsKLQkJCQkJaW1hZ2VXaWR0aCA9IGltYWdlQm91bmRzLndpZHRoOwotCQkJCQlpbWFnZUhlaWdodCA9IGltYWdlQm91bmRzLmhlaWdodDsKLQkJCQl9IGNhdGNoIChTV1RFcnJvciBlKSB7Ci0JCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiVG9vbEl0ZW0ucHJvY2Vzc1BhaW50OiBlcnJvciBpbiBpbWFnZS5nZXRCb3VuZHM6ICIgKyBlKTsKLQkJCQl9Ci0JCQl9Ci0JCQkKLQkJCWludCBzcGFjaW5nID0gMDsKLQkJCWlmICh0ZXh0V2lkdGggIT0gMCAmJiBpbWFnZVdpZHRoICE9IDApIHNwYWNpbmcgPSAyOwotCQkJaWYgKChwYXJlbnQuc3R5bGUgJiBTV1QuUklHSFQpICE9IDApIHsKLQkJCQlpbWFnZVggPSAod2lkdGggLSBpbWFnZVdpZHRoIC0gdGV4dFdpZHRoIC0gc3BhY2luZykgLyAyOwotCQkJCWltYWdlWSA9IChoZWlnaHQgLSBpbWFnZUhlaWdodCkgLyAyOwotCQkJCXRleHRYID0gc3BhY2luZyArIGltYWdlWCArIGltYWdlV2lkdGg7Ci0JCQkJdGV4dFkgPSAoaGVpZ2h0IC0gdGV4dEhlaWdodCkgLyAyOwotCQkJfSBlbHNlIHsJCQotCQkJCWltYWdlWCA9ICh3aWR0aCAtIGltYWdlV2lkdGgpIC8gMjsKLQkJCQlpbWFnZVkgPSAoaGVpZ2h0IC0gaW1hZ2VIZWlnaHQgLSB0ZXh0SGVpZ2h0IC0gc3BhY2luZykgLyAyOwotCQkJCXRleHRYID0gKHdpZHRoIC0gdGV4dFdpZHRoKSAvIDI7Ci0JCQkJdGV4dFkgPSBzcGFjaW5nICsgaW1hZ2VZICsgaW1hZ2VIZWlnaHQ7Ci0JCQl9Ci0JCQkKLQkJCWlmICgoc3R5bGUgJiBTV1QuRFJPUF9ET1dOKSAhPSAwKSB7Ci0JCQkJdGV4dFggLT0gNjsgIGltYWdlWCAtPTY7Ci0JCQl9Ci0JCQlpZiAodGV4dFdpZHRoID4gMCkgewotCQkJCWludCBmbGFncyA9IFNXVC5EUkFXX0RFTElNSVRFUiB8IFNXVC5EUkFXX1RBQiB8IFNXVC5EUkFXX01ORU1PTklDIHwgU1dULkRSQVdfVFJBTlNQQVJFTlQ7Ci0JCQkJZ2MuZHJhd1RleHQodGV4dCwgdGV4dFgsIHRleHRZLCBmbGFncyk7Ci0JCQl9Ci0JCQlpZiAoaW1hZ2VXaWR0aCA+IDApCi0JCQkJZ2MuZHJhd0ltYWdlKGN1cnJlbnRJbWFnZSwgaW1hZ2VYLCBpbWFnZVkpOwotCQkJCQotCQkJaWYgKChzdHlsZSAmIFNXVC5EUk9QX0RPV04pICE9IDApIHsKLQkJCQlpbnQgc3RhcnRYID0gd2lkdGggLSAxMiwgc3RhcnRZID0gKGhlaWdodCAtIDIpIC8gMjsKLQkJCQlpbnQgW10gYXJyb3cgPSB7c3RhcnRYLCBzdGFydFksIHN0YXJ0WCArIDMsIHN0YXJ0WSArIDMsIHN0YXJ0WCArIDYsIHN0YXJ0WX07Ci0JCQkJZ2Muc2V0QmFja2dyb3VuZCAoZ2MuZ2V0Rm9yZWdyb3VuZCAoKSk7Ci0JCQkJZ2MuZmlsbFBvbHlnb24gKGFycm93KTsKLQkJCQlnYy5kcmF3UG9seWdvbiAoYXJyb3cpOwotCQkJfQotCQkJaWYgKCFlbmFibGVkICYmIGRpc2FibGVkSW1hZ2UgPT0gbnVsbCkgewotCQkJCWlmIChjdXJyZW50SW1hZ2UgIT0gbnVsbCkgY3VycmVudEltYWdlLmRpc3Bvc2UgKCk7Ci0JCQl9CisJCQlpbWFnZSA9IGRpc2FibGVkSW1hZ2U7CiAJCX0KIAl9Ci0JZ2MuY2FyYm9uX3VuZm9jdXMoKTsKKwlDb250cm9sQnV0dG9uQ29udGVudEluZm8gaW5Db250ZW50ID0gbmV3IENvbnRyb2xCdXR0b25Db250ZW50SW5mbyAoKTsKKwlpZiAoaW1hZ2UgIT0gbnVsbCkgeworCQljSWNvbiA9IGNyZWF0ZUNJY29uIChpbWFnZSk7CisJCWluQ29udGVudC5jb250ZW50VHlwZSA9IChzaG9ydCkgT1Mua0NvbnRyb2xDb250ZW50Q0ljb25IYW5kbGU7CisJCWluQ29udGVudC5pY29uUmVmID0gY0ljb247CisJfQorCU9TLlNldEJldmVsQnV0dG9uQ29udGVudEluZm8gKGljb25IYW5kbGUsIGluQ29udGVudCk7CisJcmVkcmF3V2lkZ2V0IChpY29uSGFuZGxlKTsKKwlQb2ludCBzaXplID0gY29tcHV0ZVNpemUgKCk7CisJc2V0U2l6ZSAoc2l6ZS54LCBzaXplLnksIHRydWUpOworfQorCit2b2lkIHVwZGF0ZUFycm93ICgpIHsKKwlpZiAoYXJyb3dDSWNvbiAhPSAwKSBkZXN0cm95Q0ljb24gKGFycm93Q0ljb24pOworCWFycm93Q0ljb24gPSAwOworCURpc3BsYXkgZGlzcGxheSA9IGdldERpc3BsYXkgKCk7CisJSW1hZ2UgaW1hZ2UgPSBuZXcgSW1hZ2UgKGRpc3BsYXksIDYsIDQpOworCUdDIGdjID0gbmV3IEdDIChpbWFnZSk7CisJaW50IHN0YXJ0WCA9IDAsIHN0YXJ0WSA9IDA7CisJaW50IFtdIGFycm93ID0ge3N0YXJ0WCwgc3RhcnRZLCBzdGFydFggKyAzLCBzdGFydFkgKyAzLCBzdGFydFggKyA2LCBzdGFydFl9OworCWdjLnNldEJhY2tncm91bmQgKHBhcmVudC5nZXRGb3JlZ3JvdW5kICgpKTsKKwlnYy5maWxsUG9seWdvbiAoYXJyb3cpOworCWdjLmRyYXdQb2x5Z29uIChhcnJvdyk7CiAJZ2MuZGlzcG9zZSAoKTsKLQkKLQlyZXR1cm4gMDsKKwlJbWFnZURhdGEgZGF0YSA9IGltYWdlLmdldEltYWdlRGF0YSAoKTsKKwlkYXRhLnRyYW5zcGFyZW50UGl4ZWwgPSAweEZGRkZGRkZGOworCWltYWdlLmRpc3Bvc2UgKCk7CisJaW1hZ2UgPSBuZXcgSW1hZ2UgKGdldERpc3BsYXkgKCksIGRhdGEsIGRhdGEuZ2V0VHJhbnNwYXJlbmN5TWFzaygpKTsKKwlhcnJvd0NJY29uID0gY3JlYXRlQ0ljb24gKGltYWdlKTsKKwlpbWFnZS5kaXNwb3NlICgpOworCUNvbnRyb2xCdXR0b25Db250ZW50SW5mbyBpbkNvbnRlbnQgPSBuZXcgQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvICgpOworCWluQ29udGVudC5jb250ZW50VHlwZSA9IChzaG9ydCkgT1Mua0NvbnRyb2xDb250ZW50Q0ljb25IYW5kbGU7CisJaW5Db250ZW50Lmljb25SZWYgPSBhcnJvd0NJY29uOworCU9TLlNldEJldmVsQnV0dG9uQ29udGVudEluZm8gKGFycm93SGFuZGxlLCBpbkNvbnRlbnQpOwkKIH0KLXZvaWQgcHJvcGFnYXRlV2lkZ2V0IChib29sZWFuIGVuYWJsZWQpIHsKLQlwcm9wYWdhdGVIYW5kbGUgKGVuYWJsZWQsIGhhbmRsZSk7Ci0JLyoKLQkqIFRvb2wgaXRlbXMgcGFydGljaXBhdGUgaW4gZm9jdXMgdHJhdmVyc2FsIG9ubHkgd2hlbgotCSogdGhlIHRvb2wgYmFyIHRha2VzIGZvY3VzLgotCSovCi0JLyogQVcKLQlpZiAoKHBhcmVudC5zdHlsZSAmIFNXVC5OT19GT0NVUykgIT0gMCkgewotCQlpZiAoZW5hYmxlZCkgewotCQkJaW50IFtdIGFyZ0xpc3QgPSB7T1MuWG1OdHJhdmVyc2FsT24sIDB9OwotCQkJT1MuWHRTZXRWYWx1ZXMgKGhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKKwordm9pZCB1cGRhdGVUZXh0ICgpIHsKKwlpZiAobGFiZWxDSWNvbiAhPSAwKSBkZXN0cm95Q0ljb24gKGxhYmVsQ0ljb24pOworCWxhYmVsQ0ljb24gPSAwOworCUNvbnRyb2xCdXR0b25Db250ZW50SW5mbyBpbkNvbnRlbnQgPSBuZXcgQ29udHJvbEJ1dHRvbkNvbnRlbnRJbmZvICgpOworCWlmICh0ZXh0Lmxlbmd0aCAoKSA+IDApIHsKKwkJY2hhciBbXSBidWZmZXIgPSBuZXcgY2hhciBbdGV4dC5sZW5ndGggKCldOworCQl0ZXh0LmdldENoYXJzICgwLCBidWZmZXIubGVuZ3RoLCBidWZmZXIsIDApOworCQlpbnQgaT0wLCBqPTA7CisJCXdoaWxlIChpIDwgYnVmZmVyLmxlbmd0aCkgeworCQkJaWYgKChidWZmZXIgW2orK10gPSBidWZmZXIgW2krK10pID09IE1uZW1vbmljKSB7CisJCQkJaWYgKGkgPT0gYnVmZmVyLmxlbmd0aCkge2NvbnRpbnVlO30KKwkJCQlpZiAoYnVmZmVyIFtpXSA9PSBNbmVtb25pYykge2krKzsgY29udGludWU7fQorCQkJCWotLTsKKwkJCX0KIAkJfQorCQlGb250IGZvbnQgPSBwYXJlbnQuZ2V0Rm9udCAoKTsKKwkJR0MgZ2MgPSBuZXcgR0MgKHBhcmVudCk7CisJCVBvaW50IHNpemUgPSBnYy5zdHJpbmdFeHRlbnQgKHRleHQpOworCQlnYy5kaXNwb3NlICgpOworCQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCQlJbWFnZSBpbWFnZSA9IG5ldyBJbWFnZSAoZGlzcGxheSwgc2l6ZS54LCBzaXplLnkpOworCQlnYyA9IG5ldyBHQyAoaW1hZ2UpOworCQlnYy5zZXRGb250IChmb250KTsKKwkJZ2MuZHJhd1N0cmluZyAodGV4dCwgMCwgMCk7CisJCWdjLmRpc3Bvc2UgKCk7CisJCUltYWdlRGF0YSBkYXRhID0gaW1hZ2UuZ2V0SW1hZ2VEYXRhICgpOworCQlkYXRhLnRyYW5zcGFyZW50UGl4ZWwgPSAweEZGRkZGRkZGOworCQlpbWFnZS5kaXNwb3NlICgpOworCQlpbWFnZSA9IG5ldyBJbWFnZSAoZGlzcGxheSwgZGF0YSwgZGF0YS5nZXRUcmFuc3BhcmVuY3lNYXNrKCkpOworCQlsYWJlbENJY29uID0gY3JlYXRlQ0ljb24gKGltYWdlKTsKKwkJaW1hZ2UuZGlzcG9zZSAoKTsKKwkJaW5Db250ZW50LmNvbnRlbnRUeXBlID0gKHNob3J0KSBPUy5rQ29udHJvbENvbnRlbnRDSWNvbkhhbmRsZTsKKwkJaW5Db250ZW50Lmljb25SZWYgPSBsYWJlbENJY29uOwogCX0KLQkqLworCU9TLlNldEJldmVsQnV0dG9uQ29udGVudEluZm8gKGxhYmVsSGFuZGxlLCBpbkNvbnRlbnQpOwkKKwlyZWRyYXdXaWRnZXQgKGxhYmVsSGFuZGxlKTsKKwlQb2ludCBzaXplID0gY29tcHV0ZVNpemUgKCk7CisJc2V0U2l6ZSAoc2l6ZS54LCBzaXplLnksIHRydWUpOwogfQorCiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVHJhY2tlci5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1RyYWNrZXIuamF2YQppbmRleCBhNGVlYjhjLi5jZjUwNTAxIDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVHJhY2tlci5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UcmFja2VyLmphdmEKQEAgLTExLDEwOCArMTEsMTkgQEAKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuKjsKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7CiAKLS8qKgotICogIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGltcGxlbWVudCBydWJiZXIgYmFuZGluZyByZWN0YW5nbGVzIHRoYXQgYXJlCi0gKiAgZHJhd24gb250byBhIHBhcmVudCA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IG9yIDxjb2RlPkRpc3BsYXk8L2NvZGU+LgotICogIFRoZXNlIHJlY3RhbmdsZXMgY2FuIGJlIHNwZWNpZmllZCB0byByZXNwb25kIHRvIG1vdXNlIGFuZCBrZXkgZXZlbnRzCi0gKiAgYnkgZWl0aGVyIG1vdmluZyBvciByZXNpemluZyB0aGVtc2VsdmVzIGFjY29yZGluZ2x5LiAgVHJhY2tlcnMgYXJlCi0gKiAgdHlwaWNhbGx5IHVzZWQgdG8gcmVwcmVzZW50IHdpbmRvdyBnZW9tZXRyaWVzIGluIGEgbGlnaHR3ZWlnaHQgbWFubmVyLgotICogIAotICogPGRsPgotICogPGR0PjxiPlN0eWxlczo8L2I+PC9kdD4KLSAqIDxkZD5MRUZULCBSSUdIVCwgVVAsIERPV04sIFJFU0laRTwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPk1vdmUsIFJlc2l6ZTwvZGQ+Ci0gKiA8L2RsPgotICogPHA+Ci0gKiBOb3RlOiBSZWN0YW5nbGUgbW92ZSBiZWhhdmlvciBpcyBhc3N1bWVkIHVubGVzcyBSRVNJWkUgaXMgc3BlY2lmaWVkLgotICogPC9wPjxwPgotICogSU1QT1JUQU5UOiBUaGlzIGNsYXNzIGlzIDxlbT5ub3Q8L2VtPiBpbnRlbmRlZCB0byBiZSBzdWJjbGFzc2VkLgotICogPC9wPgotICovCiBwdWJsaWMgY2xhc3MgVHJhY2tlciBleHRlbmRzIFdpZGdldCB7Ci0JQ29tcG9zaXRlIHBhcmVudDsKLQlEaXNwbGF5IGRpc3BsYXk7Ci0JYm9vbGVhbiB0cmFja2luZywgc3RpcHBsZWQ7Ci0JUmVjdGFuZ2xlIFtdIHJlY3RhbmdsZXMsIHByb3BvcnRpb25zOwotCWludCBjdXJzb3JPcmllbnRhdGlvbiA9IFNXVC5OT05FOwotCWludCBjdXJzb3I7Ci0JZmluYWwgc3RhdGljIGludCBTVEVQU0laRV9TTUFMTCA9IDE7Ci0JZmluYWwgc3RhdGljIGludCBTVEVQU0laRV9MQVJHRSA9IDk7CisJCUNvbnRyb2wgcGFyZW50OworCQlEaXNwbGF5IGRpc3BsYXk7CisJCWJvb2xlYW4gdHJhY2tpbmcsIHN0aXBwbGVkOworCQlSZWN0YW5nbGUgW10gcmVjdGFuZ2xlcywgcHJvcG9ydGlvbnM7CisJCWludCBjdXJzb3JPcmllbnRhdGlvbiA9IFNXVC5OT05FOwogCi0vKioKLSAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50Ci0gKiBhbmQgYSBzdHlsZSB2YWx1ZSBkZXNjcmliaW5nIGl0cyBiZWhhdmlvciBhbmQgYXBwZWFyYW5jZS4KLSAqIDxwPgotICogVGhlIHN0eWxlIHZhbHVlIGlzIGVpdGhlciBvbmUgb2YgdGhlIHN0eWxlIGNvbnN0YW50cyBkZWZpbmVkIGluCi0gKiBjbGFzcyA8Y29kZT5TV1Q8L2NvZGU+IHdoaWNoIGlzIGFwcGxpY2FibGUgdG8gaW5zdGFuY2VzIG9mIHRoaXMKLSAqIGNsYXNzLCBvciBtdXN0IGJlIGJ1aWx0IGJ5IDxlbT5iaXR3aXNlIE9SPC9lbT4naW5nIHRvZ2V0aGVyIAotICogKHRoYXQgaXMsIHVzaW5nIHRoZSA8Y29kZT5pbnQ8L2NvZGU+ICJ8IiBvcGVyYXRvcikgdHdvIG9yIG1vcmUKLSAqIG9mIHRob3NlIDxjb2RlPlNXVDwvY29kZT4gc3R5bGUgY29uc3RhbnRzLiBUaGUgY2xhc3MgZGVzY3JpcHRpb24KLSAqIGxpc3RzIHRoZSBzdHlsZSBjb25zdGFudHMgdGhhdCBhcmUgYXBwbGljYWJsZSB0byB0aGUgY2xhc3MuCi0gKiBTdHlsZSBiaXRzIGFyZSBhbHNvIGluaGVyaXRlZCBmcm9tIHN1cGVyY2xhc3Nlcy4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gcGFyZW50IGEgd2lkZ2V0IHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqIEBwYXJhbSBzdHlsZSB0aGUgc3R5bGUgb2Ygd2lkZ2V0IHRvIGNvbnN0cnVjdAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTV1QjTEVGVAotICogQHNlZSBTV1QjUklHSFQKLSAqIEBzZWUgU1dUI1VQCi0gKiBAc2VlIFNXVCNET1dOCi0gKiBAc2VlIFNXVCNSRVNJWkUKLSAqIEBzZWUgV2lkZ2V0I2NoZWNrU3ViY2xhc3MKLSAqIEBzZWUgV2lkZ2V0I2dldFN0eWxlCi0gKi8KIHB1YmxpYyBUcmFja2VyIChDb21wb3NpdGUgcGFyZW50LCBpbnQgc3R5bGUpIHsKIAlzdXBlciAocGFyZW50LCBjaGVja1N0eWxlIChzdHlsZSkpOwogCXRoaXMucGFyZW50ID0gcGFyZW50OwogCWRpc3BsYXkgPSBwYXJlbnQuZ2V0RGlzcGxheSAoKTsKIH0KIAotLyoqCi0gKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZ2l2ZW4gdGhlIGRpc3BsYXkKLSAqIHRvIGNyZWF0ZSBpdCBvbiBhbmQgYSBzdHlsZSB2YWx1ZSBkZXNjcmliaW5nIGl0cyBiZWhhdmlvcgotICogYW5kIGFwcGVhcmFuY2UuCi0gKiA8cD4KLSAqIFRoZSBzdHlsZSB2YWx1ZSBpcyBlaXRoZXIgb25lIG9mIHRoZSBzdHlsZSBjb25zdGFudHMgZGVmaW5lZCBpbgotICogY2xhc3MgPGNvZGU+U1dUPC9jb2RlPiB3aGljaCBpcyBhcHBsaWNhYmxlIHRvIGluc3RhbmNlcyBvZiB0aGlzCi0gKiBjbGFzcywgb3IgbXVzdCBiZSBidWlsdCBieSA8ZW0+Yml0d2lzZSBPUjwvZW0+J2luZyB0b2dldGhlciAKLSAqICh0aGF0IGlzLCB1c2luZyB0aGUgPGNvZGU+aW50PC9jb2RlPiAifCIgb3BlcmF0b3IpIHR3byBvciBtb3JlCi0gKiBvZiB0aG9zZSA8Y29kZT5TV1Q8L2NvZGU+IHN0eWxlIGNvbnN0YW50cy4gVGhlIGNsYXNzIGRlc2NyaXB0aW9uCi0gKiBsaXN0cyB0aGUgc3R5bGUgY29uc3RhbnRzIHRoYXQgYXJlIGFwcGxpY2FibGUgdG8gdGhlIGNsYXNzLgotICogU3R5bGUgYml0cyBhcmUgYWxzbyBpbmhlcml0ZWQgZnJvbSBzdXBlcmNsYXNzZXMuCi0gKiA8L3A+PHA+Ci0gKiBOb3RlOiBDdXJyZW50bHksIG51bGwgY2FuIGJlIHBhc3NlZCBpbiBmb3IgdGhlIGRpc3BsYXkgYXJndW1lbnQuCi0gKiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGNyZWF0aW5nIHRoZSB0cmFja2VyIG9uIHRoZSBjdXJyZW50bHkgYWN0aXZlCi0gKiBkaXNwbGF5IGlmIHRoZXJlIGlzIG9uZS4gSWYgdGhlcmUgaXMgbm8gY3VycmVudCBkaXNwbGF5LCB0aGUgCi0gKiB0cmFja2VyIGlzIGNyZWF0ZWQgb24gYSAiZGVmYXVsdCIgZGlzcGxheS4gPGI+UGFzc2luZyBpbiBudWxsIGFzCi0gKiB0aGUgZGlzcGxheSBhcmd1bWVudCBpcyBub3QgY29uc2lkZXJlZCB0byBiZSBnb29kIGNvZGluZyBzdHlsZSwKLSAqIGFuZCBtYXkgbm90IGJlIHN1cHBvcnRlZCBpbiBhIGZ1dHVyZSByZWxlYXNlIG9mIFNXVC48L2I+Ci0gKiA8L3A+Ci0gKgotICogQHBhcmFtIGRpc3BsYXkgdGhlIGRpc3BsYXkgdG8gY3JlYXRlIHRoZSB0cmFja2VyIG9uCi0gKiBAcGFyYW0gc3R5bGUgdGhlIHN0eWxlIG9mIGNvbnRyb2wgdG8gY29uc3RydWN0Ci0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcGFyZW50PC9saT4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICogCi0gKiBAc2VlIFNXVCNMRUZUCi0gKiBAc2VlIFNXVCNSSUdIVAotICogQHNlZSBTV1QjVVAKLSAqIEBzZWUgU1dUI0RPV04KLSAqIEBzZWUgU1dUI1JFU0laRQotICovCiBwdWJsaWMgVHJhY2tlciAoRGlzcGxheSBkaXNwbGF5LCBpbnQgc3R5bGUpIHsKIAlpZiAoZGlzcGxheSA9PSBudWxsKSBkaXNwbGF5ID0gRGlzcGxheS5nZXRDdXJyZW50ICgpOwogCWlmIChkaXNwbGF5ID09IG51bGwpIGRpc3BsYXkgPSBEaXNwbGF5LmdldERlZmF1bHQgKCk7CkBAIC0xMjMsMjUgKzM0LDYgQEAKIAl0aGlzLmRpc3BsYXkgPSBkaXNwbGF5OwogfQogCi0vKioKLSAqIEFkZHMgdGhlIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgY29udHJvbCBpcyBtb3ZlZCBvciByZXNpemVkLCBieSBzZW5kaW5nCi0gKiBpdCBvbmUgb2YgdGhlIG1lc3NhZ2VzIGRlZmluZWQgaW4gdGhlIDxjb2RlPkNvbnRyb2xMaXN0ZW5lcjwvY29kZT4KLSAqIGludGVyZmFjZS4KLSAqCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIENvbnRyb2xMaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlQ29udHJvbExpc3RlbmVyCi0gKi8KIHB1YmxpYyB2b2lkIGFkZENvbnRyb2xMaXN0ZW5lciAoQ29udHJvbExpc3RlbmVyIGxpc3RlbmVyKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC0xNTAsODAgKzQyLDIwIEBACiB9CiAKIFBvaW50IGFkanVzdE1vdmVDdXJzb3IgKGludCB4RGlzcGxheSwgaW50IHhXaW5kb3cpIHsKLQlpbnQgYWN0dWFsWFtdID0gbmV3IGludFsxXTsKLQlpbnQgYWN0dWFsWVtdID0gbmV3IGludFsxXTsKLQkKLQkvKiBBVwotCVJlY3RhbmdsZSBib3VuZHMgPSBjb21wdXRlQm91bmRzICgpOwotCWludCBuZXdYID0gYm91bmRzLnggKyBib3VuZHMud2lkdGggLyAyOwotCWludCBuZXdZID0gYm91bmRzLnk7Ci0JKi8KLQkKLQkvKiBBVwotCU9TLlhXYXJwUG9pbnRlciAoeERpc3BsYXksIE9TLk5vbmUsIHhXaW5kb3csIDAsIDAsIDAsIDAsIG5ld1gsIG5ld1kpOwotCSovCi0JLyoKLQkgKiBUaGUgY2FsbCB0byBYV2FycFBvaW50ZXIgZG9lcyBub3QgYWx3YXlzIHBsYWNlIHRoZSBwb2ludGVyIG9uIHRoZQotCSAqIGV4YWN0IGxvY2F0aW9uIHRoYXQgaXMgc3BlY2lmaWVkLCBzbyBkbyBhIHF1ZXJ5IChiZWxvdykgdG8gZ2V0IHRoZQotCSAqIGFjdHVhbCBsb2NhdGlvbiBvZiB0aGUgcG9pbnRlciBhZnRlciBpdCBoYXMgYmVlbiBtb3ZlZC4KLQkgKi8KLQkvKiBBVwotCU9TLlhRdWVyeVBvaW50ZXIgKHhEaXNwbGF5LCB4V2luZG93LCB1bnVzZWQsIHVudXNlZCwgYWN0dWFsWCwgYWN0dWFsWSwgdW51c2VkLCB1bnVzZWQsIHVudXNlZCk7Ci0JKi8KLQlyZXR1cm4gbmV3IFBvaW50IChhY3R1YWxYWzBdLCBhY3R1YWxZWzBdKTsKKwlyZXR1cm4gbmV3IFBvaW50ICgwLCAwKTsKIH0KLVBvaW50IGFkanVzdFJlc2l6ZUN1cnNvciAoaW50IHhEaXNwbGF5LCBpbnQgeFdpbmRvdykgewotCS8qIEFXCi0JaW50IG5ld1gsIG5ld1k7Ci0JUmVjdGFuZ2xlIGJvdW5kcyA9IGNvbXB1dGVCb3VuZHMgKCk7CiAKLQlpZiAoKGN1cnNvck9yaWVudGF0aW9uICYgU1dULkxFRlQpICE9IDApIHsKLQkJbmV3WCA9IGJvdW5kcy54OwotCX0gZWxzZSBpZiAoKGN1cnNvck9yaWVudGF0aW9uICYgU1dULlJJR0hUKSAhPSAwKSB7Ci0JCW5ld1ggPSBib3VuZHMueCArIGJvdW5kcy53aWR0aDsKLQl9IGVsc2UgewotCQluZXdYID0gYm91bmRzLnggKyBib3VuZHMud2lkdGggLyAyOwotCX0KLQkKLQlpZiAoKGN1cnNvck9yaWVudGF0aW9uICYgU1dULlVQKSAhPSAwKSB7Ci0JCW5ld1kgPSBib3VuZHMueTsKLQl9IGVsc2UgaWYgKChjdXJzb3JPcmllbnRhdGlvbiAmIFNXVC5ET1dOKSAhPSAwKSB7Ci0JCW5ld1kgPSBib3VuZHMueSArIGJvdW5kcy5oZWlnaHQ7Ci0JfSBlbHNlIHsKLQkJbmV3WSA9IGJvdW5kcy55ICsgYm91bmRzLmhlaWdodCAvIDI7Ci0JfQotCSovCi0JCi0JaW50IGFjdHVhbFhbXSA9IG5ldyBpbnRbMV07Ci0JaW50IGFjdHVhbFlbXSA9IG5ldyBpbnRbMV07Ci0JLyogQVcKLQlPUy5YV2FycFBvaW50ZXIgKHhEaXNwbGF5LCBTV1QuTk9ORSwgeFdpbmRvdywgMCwgMCwgMCwgMCwgbmV3WCwgbmV3WSk7Ci0JKi8KLQkvKgotCSAqIFRoZSBjYWxsIHRvIFhXYXJwUG9pbnRlciBkb2VzIG5vdCBhbHdheXMgcGxhY2UgdGhlIHBvaW50ZXIgb24gdGhlCi0JICogZXhhY3QgbG9jYXRpb24gdGhhdCBpcyBzcGVjaWZpZWQsIHNvIGRvIGEgcXVlcnkgKGJlbG93KSB0byBnZXQgdGhlCi0JICogYWN0dWFsIGxvY2F0aW9uIG9mIHRoZSBwb2ludGVyIGFmdGVyIGl0IGhhcyBiZWVuIG1vdmVkLgotCSAqLwotCS8qIEFXCi0JT1MuWFF1ZXJ5UG9pbnRlciAoeERpc3BsYXksIHhXaW5kb3csIHVudXNlZCwgdW51c2VkLCBhY3R1YWxYLCBhY3R1YWxZLCB1bnVzZWQsIHVudXNlZCwgdW51c2VkKTsKLQkqLwotCXJldHVybiBuZXcgUG9pbnQgKGFjdHVhbFhbMF0sIGFjdHVhbFlbMF0pOworUG9pbnQgYWRqdXN0UmVzaXplQ3Vyc29yIChpbnQgeERpc3BsYXksIGludCB4V2luZG93KSB7CisJcmV0dXJuIG5ldyBQb2ludCAoMCwgMCk7CiB9CisKIHN0YXRpYyBpbnQgY2hlY2tTdHlsZSAoaW50IHN0eWxlKSB7CiAJaWYgKChzdHlsZSAmIChTV1QuTEVGVCB8IFNXVC5SSUdIVCB8IFNXVC5VUCB8IFNXVC5ET1dOKSkgPT0gMCkgewogCQlzdHlsZSB8PSBTV1QuTEVGVCB8IFNXVC5SSUdIVCB8IFNXVC5VUCB8IFNXVC5ET1dOOwogCX0KIAlyZXR1cm4gc3R5bGU7CiB9Ci0vKioKLSAqIFN0b3BzIGRpc3BsYXlpbmcgdGhlIHRyYWNrZXIgcmVjdGFuZ2xlcy4gIE5vdGUgdGhhdCB0aGlzIGlzIG5vdCBjb25zaWRlcmVkCi0gKiB0byBiZSBhIGNhbmNlbGF0aW9uIGJ5IHRoZSB1c2VyLgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBjbG9zZSAoKSB7CiAJY2hlY2tXaWRnZXQgKCk7CiAJdHJhY2tpbmcgPSBmYWxzZTsKQEAgLTI2Niw2OCArOTgsMTcgQEAKIAl9IGVsc2UgewogCQlkaXNwbGF5LnVwZGF0ZSAoKTsKIAl9Ci0JLyogQVcKLQlpbnQgeERpc3BsYXkgPSBkaXNwbGF5LnhEaXNwbGF5OwotCWludCBjb2xvciA9IE9TLlhXaGl0ZVBpeGVsICh4RGlzcGxheSwgMCk7Ci0JaW50IHhXaW5kb3cgPSBPUy5YRGVmYXVsdFJvb3RXaW5kb3cgKHhEaXNwbGF5KTsKLQlpZiAocGFyZW50ICE9IG51bGwpIHsKLQkJeFdpbmRvdyA9IE9TLlh0V2luZG93IChwYXJlbnQuaGFuZGxlKTsKLQkJaWYgKHhXaW5kb3cgPT0gMCkgcmV0dXJuOwotCQlpbnQgW10gYXJnTGlzdCA9IHtPUy5YbU5mb3JlZ3JvdW5kLCAwLCBPUy5YbU5iYWNrZ3JvdW5kLCAwfTsKLQkJT1MuWHRHZXRWYWx1ZXMgKHBhcmVudC5oYW5kbGUsIGFyZ0xpc3QsIGFyZ0xpc3QubGVuZ3RoIC8gMik7Ci0JCWNvbG9yID0gYXJnTGlzdCBbMV0gXiBhcmdMaXN0IFszXTsKLQl9Ci0JaW50IGdjID0gT1MuWENyZWF0ZUdDICh4RGlzcGxheSwgeFdpbmRvdywgMCwgbnVsbCk7Ci0JT1MuWFNldEZvcmVncm91bmQgKHhEaXNwbGF5LCBnYywgY29sb3IpOwotCU9TLlhTZXRTdWJ3aW5kb3dNb2RlICh4RGlzcGxheSwgZ2MsIE9TLkluY2x1ZGVJbmZlcmlvcnMpOwotCU9TLlhTZXRGdW5jdGlvbiAoeERpc3BsYXksIGdjLCBPUy5HWHhvcik7Ci0JaW50IHN0aXBwbGVQaXhtYXAgPSAwOwotCWlmIChzdGlwcGxlZCkgewotCQlieXRlIFtdIGJpdHMgPSB7LTg2LCAwLCA4NSwgMCwgLTg2LCAwLCA4NSwgMCwgLTg2LCAwLCA4NSwgMCwgLTg2LCAwLCA4NSwgMH07Ci0JCXN0aXBwbGVQaXhtYXAgPSBPUy5YQ3JlYXRlQml0bWFwRnJvbURhdGEgKHhEaXNwbGF5LCB4V2luZG93LCBiaXRzLCA4LCA4KTsKLQkJT1MuWFNldFN0aXBwbGUgKHhEaXNwbGF5LCBnYywgc3RpcHBsZVBpeG1hcCk7Ci0JCU9TLlhTZXRGaWxsU3R5bGUgKHhEaXNwbGF5LCBnYywgT1MuRmlsbFN0aXBwbGVkKTsKLQkJT1MuWFNldExpbmVBdHRyaWJ1dGVzICh4RGlzcGxheSwgZ2MsIDMsIE9TLkxpbmVTb2xpZCwgT1MuQ2FwQnV0dCwgT1MuSm9pbk1pdGVyKTsKLQl9Ci0JZm9yIChpbnQgaT0wOyBpPHJlY3RhbmdsZXMubGVuZ3RoOyBpKyspIHsKLQkJUmVjdGFuZ2xlIHJlY3QgPSByZWN0YW5nbGVzIFtpXTsKLQkJT1MuWERyYXdSZWN0YW5nbGUgKHhEaXNwbGF5LCB4V2luZG93LCBnYywgcmVjdC54LCByZWN0LnksIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTsKLQl9Ci0JaWYgKHN0aXBwbGVkKSB7Ci0JCU9TLlhGcmVlUGl4bWFwICh4RGlzcGxheSwgc3RpcHBsZVBpeG1hcCk7Ci0JfQotCU9TLlhGcmVlR0MgKHhEaXNwbGF5LCBnYyk7Ci0JKi8KIH0KKwogcHVibGljIERpc3BsYXkgZ2V0RGlzcGxheSAoKSB7CiAJcmV0dXJuIGRpc3BsYXk7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIGJvdW5kcyB0aGF0IGFyZSBiZWluZyBkcmF3biwgZXhwcmVzc2VkIHJlbGF0aXZlIHRvIHRoZSBwYXJlbnQKLSAqIHdpZGdldC4gIElmIHRoZSBwYXJlbnQgaXMgYSA8Y29kZT5EaXNwbGF5PC9jb2RlPiB0aGVuIHRoZXNlIGFyZSBzY3JlZW4KLSAqIGNvb3JkaW5hdGVzLgotICoKLSAqIEByZXR1cm4gdGhlIGJvdW5kcyBvZiB0aGUgUmVjdGFuZ2xlcyBiZWluZyBkcmF3bgotICogCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIFJlY3RhbmdsZSBbXSBnZXRSZWN0YW5nbGVzICgpIHsKIAljaGVja1dpZGdldCAoKTsKIAlyZXR1cm4gcmVjdGFuZ2xlczsKIH0KLS8qKgotICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcmVjdGFuZ2xlcyBhcmUgZHJhd24gd2l0aCBhIHN0aXBwbGVkIGxpbmUsIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gKgotICogQHJldHVybiB0aGUgc3RpcHBsZWQgZWZmZWN0IG9mIHRoZSByZWN0YW5nbGVzCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICovCisKIHB1YmxpYyBib29sZWFuIGdldFN0aXBwbGVkICgpIHsKIAljaGVja1dpZGdldCAoKTsKIAlyZXR1cm4gc3RpcHBsZWQ7CkBAIC0zNDQsMjM3ICsxMjUsMTkgQEAKIAl9CiB9CiAKLS8qKgotICogRGlzcGxheXMgdGhlIFRyYWNrZXIgcmVjdGFuZ2xlcyBmb3IgbWFuaXB1bGF0aW9uIGJ5IHRoZSB1c2VyLiAgUmV0dXJucyB3aGVuCi0gKiB0aGUgdXNlciBoYXMgZWl0aGVyIGZpbmlzaGVkIG1hbmlwdWxhdGluZyB0aGUgcmVjdGFuZ2xlcyBvciBoYXMgY2FuY2VsbGVkIHRoZQotICogVHJhY2tlci4KLSAqIAotICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgdXNlciBkaWQgbm90IGNhbmNlbCB0aGUgVHJhY2tlciwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZQotICogCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyBib29sZWFuIG9wZW4gKCkgewogCWNoZWNrV2lkZ2V0ICgpOwogCWlmIChyZWN0YW5nbGVzID09IG51bGwpIHJldHVybiBmYWxzZTsKLQkvKiBBVwotCWludCB4RGlzcGxheSA9IGRpc3BsYXkueERpc3BsYXk7Ci0JaW50IGNvbG9yID0gT1MuWFdoaXRlUGl4ZWwgKHhEaXNwbGF5LCAwKTsKLQlpbnQgeFdpbmRvdyA9IE9TLlhEZWZhdWx0Um9vdFdpbmRvdyAoeERpc3BsYXkpOwotCWlmIChwYXJlbnQgIT0gbnVsbCkgewotCQl4V2luZG93ID0gT1MuWHRXaW5kb3cgKHBhcmVudC5oYW5kbGUpOwotCQlpZiAoeFdpbmRvdyA9PSAwKSByZXR1cm4gZmFsc2U7Ci0JfQotCWJvb2xlYW4gY2FuY2VsbGVkID0gZmFsc2U7Ci0JdHJhY2tpbmcgPSB0cnVlOwotCWRyYXdSZWN0YW5nbGVzICgpOwotCWludCBbXSBvbGRYID0gbmV3IGludCBbMV0sIG9sZFkgPSBuZXcgaW50IFsxXTsKLQlpbnQgW10gdW51c2VkID0gbmV3IGludCBbMV07Ci0JUG9pbnQgY3Vyc29yUG9zOwotCWlmICgoc3R5bGUgJiBTV1QuTUVOVSkgIT0gMCkgewotCQlpZiAoKHN0eWxlICYgU1dULlJFU0laRSkgIT0gMCkgewotCQkJY3Vyc29yUG9zID0gYWRqdXN0UmVzaXplQ3Vyc29yICh4RGlzcGxheSwgeFdpbmRvdyk7Ci0JCX0gZWxzZSB7Ci0JCQljdXJzb3JQb3MgPSBhZGp1c3RNb3ZlQ3Vyc29yICh4RGlzcGxheSwgeFdpbmRvdyk7Ci0JCX0KLQkJb2xkWCBbMF0gPSBjdXJzb3JQb3MueDsgIG9sZFkgWzBdID0gY3Vyc29yUG9zLnk7Ci0JfSBlbHNlIHsKLQkJT1MuWFF1ZXJ5UG9pbnRlciAoeERpc3BsYXksIHhXaW5kb3csIHVudXNlZCwgdW51c2VkLCBvbGRYLCBvbGRZLCB1bnVzZWQsIHVudXNlZCwgdW51c2VkKTsKLQl9Ci0JCQotCVhBbnlFdmVudCB4RXZlbnQgPSBuZXcgWEFueUV2ZW50ICgpOwotCWludCBbXSBuZXdYID0gbmV3IGludCBbMV0sIG5ld1kgPSBuZXcgaW50IFsxXTsKLQlpbnQgeHRDb250ZXh0ID0gT1MuWHREaXNwbGF5VG9BcHBsaWNhdGlvbkNvbnRleHQgKHhEaXNwbGF5KTsKLQkKLQlpbnQgcHRyR3JhYlJlc3VsdCA9IE9TLlhHcmFiUG9pbnRlciAoCi0JCXhEaXNwbGF5LAotCQl4V2luZG93LAotCQkwLAotCQlPUy5CdXR0b25QcmVzc01hc2sgfCBPUy5CdXR0b25SZWxlYXNlTWFzayB8IE9TLlBvaW50ZXJNb3Rpb25NYXNrLAotCQlPUy5HcmFiTW9kZUFzeW5jLAotCQlPUy5HcmFiTW9kZUFzeW5jLAotCQlPUy5Ob25lLAotCQlPUy5Ob25lLAotCQlPUy5DdXJyZW50VGltZSk7Ci0JaW50IGtiZEdyYWJSZXN1bHQgPSBPUy5YR3JhYktleWJvYXJkICgKLQkJeERpc3BsYXksCi0JCXhXaW5kb3csCi0JCTAsCi0JCU9TLkdyYWJNb2RlQXN5bmMsCi0JCU9TLkdyYWJNb2RlQXN5bmMsCi0JCU9TLkN1cnJlbnRUaW1lKTsKLQkqLwotCS8qCi0JICogIFRyYWNrZXIgYmVoYXZlcyBsaWtlIGEgRGlhbG9nIHdpdGggaXRzIG93biBPUyBldmVudCBsb29wLgotCSAqLwotCS8qIEFXCi0Jd2hpbGUgKHRyYWNraW5nKSB7Ci0JCWlmIChwYXJlbnQgIT0gbnVsbCAmJiBwYXJlbnQuaXNEaXNwb3NlZCAoKSkgYnJlYWs7Ci0JCU9TLlh0QXBwTmV4dEV2ZW50ICh4dENvbnRleHQsIHhFdmVudCk7Ci0JCXN3aXRjaCAoeEV2ZW50LnR5cGUpIHsKLQkJCWNhc2UgT1MuTW90aW9uTm90aWZ5OgotCQkJCWlmIChjdXJzb3IgIT0gMCkgewotCQkJCQlPUy5YQ2hhbmdlQWN0aXZlUG9pbnRlckdyYWIgKAotCQkJCQkJeERpc3BsYXksCi0JCQkJCQlPUy5CdXR0b25QcmVzc01hc2sgfCBPUy5CdXR0b25SZWxlYXNlTWFzayB8IE9TLlBvaW50ZXJNb3Rpb25NYXNrLAotCQkJCQkJY3Vyc29yLAotCQkJCQkJT1MuQ3VycmVudFRpbWUpOwotCQkJCX0KLQkJCQkvLyBmYWxsIHRocm91Z2gKLQkJCWNhc2UgT1MuQnV0dG9uUmVsZWFzZToKLQkJCQlPUy5YUXVlcnlQb2ludGVyICh4RGlzcGxheSwgeFdpbmRvdywgdW51c2VkLCB1bnVzZWQsIG5ld1gsIG5ld1ksIHVudXNlZCwgdW51c2VkLCB1bnVzZWQpOwotCQkJCWlmIChvbGRYIFswXSAhPSBuZXdYIFswXSB8fCBvbGRZIFswXSAhPSBuZXdZIFswXSkgewotCQkJCQlkcmF3UmVjdGFuZ2xlcyAoKTsKLQkJCQkJRXZlbnQgZXZlbnQgPSBuZXcgRXZlbnQgKCk7Ci0JCQkJCWV2ZW50LnggPSBuZXdYIFswXTsKLQkJCQkJZXZlbnQueSA9IG5ld1kgWzBdOwotCQkJCQlpZiAoKHN0eWxlICYgU1dULlJFU0laRSkgIT0gMCkgewotCQkJCQkJcmVzaXplUmVjdGFuZ2xlcyAobmV3WCBbMF0gLSBvbGRYIFswXSwgbmV3WSBbMF0gLSBvbGRZIFswXSk7Ci0JCQkJCQlzZW5kRXZlbnQgKFNXVC5SZXNpemUsIGV2ZW50KTsKLQkJCQkJCWN1cnNvclBvcyA9IGFkanVzdFJlc2l6ZUN1cnNvciAoeERpc3BsYXksIHhXaW5kb3cpOwotCQkJCQkJbmV3WCBbMF0gPSBjdXJzb3JQb3MueDsgbmV3WSBbMF0gPSBjdXJzb3JQb3MueTsKLQkJCQkJfSBlbHNlIHsKLQkJCQkJCW1vdmVSZWN0YW5nbGVzIChuZXdYIFswXSAtIG9sZFggWzBdLCBuZXdZIFswXSAtIG9sZFkgWzBdKTsKLQkJCQkJCXNlbmRFdmVudCAoU1dULk1vdmUsIGV2ZW50KTsKLQkJCQkJfQotCQkJCQkqLwotCQkJCQkvKgotCQkJCQkgKiBJdCBpcyBwb3NzaWJsZSAoYnV0IHVubGlrZWx5KSB0aGF0IGFwcGxpY2F0aW9uIGNvZGUKLQkJCQkJICogY291bGQgaGF2ZSBkaXNwb3NlZCB0aGUgd2lkZ2V0IGluIHRoZSBtb3ZlIGV2ZW50LgotCQkJCQkgKiBJZiB0aGlzIGhhcHBlbnMgdGhlbiByZXR1cm4gZmFsc2UgdG8gaW5kaWNhdGUgdGhhdAotCQkJCQkgKiB0aGUgbW92ZSBmYWlsZWQuCi0JCQkJCSAqLwotCQkJCQkvKiBBVwotCQkJCQlpZiAoaXNEaXNwb3NlZCAoKSkgewotCQkJCQkJaWYgKHB0ckdyYWJSZXN1bHQgPT0gT1MuR3JhYlN1Y2Nlc3MpIE9TLlhVbmdyYWJQb2ludGVyICh4RGlzcGxheSwgT1MuQ3VycmVudFRpbWUpOwotCQkJCQkJaWYgKGtiZEdyYWJSZXN1bHQgPT0gT1MuR3JhYlN1Y2Nlc3MpIE9TLlhVbmdyYWJLZXlib2FyZCAoeERpc3BsYXksIE9TLkN1cnJlbnRUaW1lKTsKLQkJCQkJCXJldHVybiBmYWxzZTsKLQkJCQkJfQotCQkJCQlkcmF3UmVjdGFuZ2xlcyAoKTsKLQkJCQkJb2xkWCBbMF0gPSBuZXdYIFswXTsgIG9sZFkgWzBdID0gbmV3WSBbMF07Ci0JCQkJfQotCQkJCXRyYWNraW5nID0geEV2ZW50LnR5cGUgIT0gT1MuQnV0dG9uUmVsZWFzZTsKLQkJCQlicmVhazsKLQkJCWNhc2UgT1MuS2V5UHJlc3M6Ci0JCQkJWEtleUV2ZW50IGtleUV2ZW50ID0gbmV3IFhLZXlFdmVudCAoKTsKLQkJCQlPUy5tZW1tb3ZlIChrZXlFdmVudCwgeEV2ZW50LCBYS2V5RXZlbnQuc2l6ZW9mKTsKLQkJCQlpZiAoa2V5RXZlbnQua2V5Y29kZSAhPSAwKSB7Ci0JCQkJCWludCBbXSBrZXlzeW0gPSBuZXcgaW50IFsxXTsKLQkJCQkJT1MuWExvb2t1cFN0cmluZyAoa2V5RXZlbnQsIG51bGwsIDAsIGtleXN5bSwgbnVsbCk7Ci0JCQkJCWtleXN5bSBbMF0gJj0gMHhGRkZGOwotCQkJCQlpbnQgeENoYW5nZSA9IDAsIHlDaGFuZ2UgPSAwOwotCQkJCQlpbnQgc3RlcFNpemUgPSAoKGtleUV2ZW50LnN0YXRlICYgT1MuQ29udHJvbE1hc2spICE9IDApID8gU1RFUFNJWkVfU01BTEwgOiBTVEVQU0laRV9MQVJHRTsKLQkJCQkJc3dpdGNoIChrZXlzeW0gWzBdKSB7Ci0JCQkJCQljYXNlIE9TLlhLX1JldHVybjoKLQkJCQkJCQl0cmFja2luZyA9IGZhbHNlOwotCQkJCQkJCSovCi0JCQkJCQkJLyoKLQkJCQkJCQkgKiBFYXQgdGhlIHN1YnNlcXVlbnQgS2V5UmVsZWFzZSBldmVudAotCQkJCQkJCSAqLwotCQkJCQkJCSAvKiBBVwotCQkJCQkJCU9TLlh0QXBwTmV4dEV2ZW50ICh4dENvbnRleHQsIHhFdmVudCk7Ci0JCQkJCQkJYnJlYWs7Ci0JCQkJCQljYXNlIE9TLlhLX0VzY2FwZToKLQkJCQkJCWNhc2UgT1MuWEtfQ2FuY2VsOgotCQkJCQkJCXRyYWNraW5nID0gZmFsc2U7Ci0JCQkJCQkJY2FuY2VsbGVkID0gdHJ1ZTsKLQkJCQkJCQkqLwotCQkJCQkJCS8qCi0JCQkJCQkJICogRWF0IHRoZSBzdWJzZXF1ZW50IEtleVJlbGVhc2UgZXZlbnQKLQkJCQkJCQkgKi8KLQkJCQkJCQkvKiBBVwotCQkJCQkJCU9TLlh0QXBwTmV4dEV2ZW50ICh4dENvbnRleHQsIHhFdmVudCk7Ci0JCQkJCQkJYnJlYWs7Ci0JCQkJCQljYXNlIE9TLlhLX0xlZnQ6Ci0JCQkJCQkJeENoYW5nZSA9IC1zdGVwU2l6ZTsKLQkJCQkJCQlicmVhazsKLQkJCQkJCWNhc2UgT1MuWEtfUmlnaHQ6Ci0JCQkJCQkJeENoYW5nZSA9IHN0ZXBTaXplOwotCQkJCQkJCWJyZWFrOwotCQkJCQkJY2FzZSBPUy5YS19VcDoKLQkJCQkJCQl5Q2hhbmdlID0gLXN0ZXBTaXplOwotCQkJCQkJCWJyZWFrOwotCQkJCQkJY2FzZSBPUy5YS19Eb3duOgotCQkJCQkJCXlDaGFuZ2UgPSBzdGVwU2l6ZTsKLQkJCQkJCQlicmVhazsKLQkJCQkJfQotCQkJCQlpZiAoeENoYW5nZSAhPSAwIHx8IHlDaGFuZ2UgIT0gMCkgewotCQkJCQkJZHJhd1JlY3RhbmdsZXMgKCk7Ci0JCQkJCQlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKLQkJCQkJCWV2ZW50LnggPSBvbGRYWzBdICsgeENoYW5nZTsKLQkJCQkJCWV2ZW50LnkgPSBvbGRZWzBdICsgeUNoYW5nZTsKLQkJCQkJCWlmICgoc3R5bGUgJiBTV1QuUkVTSVpFKSAhPSAwKSB7Ci0JCQkJCQkJcmVzaXplUmVjdGFuZ2xlcyAoeENoYW5nZSwgeUNoYW5nZSk7Ci0JCQkJCQkJc2VuZEV2ZW50IChTV1QuUmVzaXplLCBldmVudCk7Ci0JCQkJCQkJY3Vyc29yUG9zID0gYWRqdXN0UmVzaXplQ3Vyc29yICh4RGlzcGxheSwgeFdpbmRvdyk7Ci0JCQkJCQl9IGVsc2UgewotCQkJCQkJCW1vdmVSZWN0YW5nbGVzICh4Q2hhbmdlLCB5Q2hhbmdlKTsKLQkJCQkJCQlzZW5kRXZlbnQgKFNXVC5Nb3ZlLCBldmVudCk7Ci0JCQkJCQkJY3Vyc29yUG9zID0gYWRqdXN0TW92ZUN1cnNvciAoeERpc3BsYXksIHhXaW5kb3cpOwotCQkJCQkJfQotCQkJCQkJKi8KLQkJCQkJCS8qCi0JCQkJCQkgKiBJdCBpcyBwb3NzaWJsZSAoYnV0IHVubGlrZWx5KSB0aGF0IGFwcGxpY2F0aW9uIGNvZGUKLQkJCQkJCSAqIGNvdWxkIGhhdmUgZGlzcG9zZWQgdGhlIHdpZGdldCBpbiB0aGUgbW92ZSBldmVudC4KLQkJCQkJCSAqIElmIHRoaXMgaGFwcGVucyB0aGVuIHJldHVybiBmYWxzZSB0byBpbmRpY2F0ZSB0aGF0Ci0JCQkJCQkgKiB0aGUgbW92ZSBmYWlsZWQuCi0JCQkJCQkgKi8KLQkJCQkJCS8qIEFXCi0JCQkJCQlpZiAoaXNEaXNwb3NlZCAoKSkgewotCQkJCQkJCWlmIChwdHJHcmFiUmVzdWx0ID09IE9TLkdyYWJTdWNjZXNzKSBPUy5YVW5ncmFiUG9pbnRlciAoeERpc3BsYXksIE9TLkN1cnJlbnRUaW1lKTsKLQkJCQkJCQlpZiAoa2JkR3JhYlJlc3VsdCA9PSBPUy5HcmFiU3VjY2VzcykgT1MuWFVuZ3JhYktleWJvYXJkICh4RGlzcGxheSwgT1MuQ3VycmVudFRpbWUpOwotCQkJCQkJCXJldHVybiBmYWxzZTsKLQkJCQkJCX0KLQkJCQkJCWRyYXdSZWN0YW5nbGVzICgpOwotCQkJCQkJb2xkWFswXSA9IGN1cnNvclBvcy54OyAgb2xkWVswXSA9IGN1cnNvclBvcy55OwotCQkJCQl9Ci0JCQkJfQotCQkJCWJyZWFrOwotCQkJY2FzZSBPUy5FbnRlck5vdGlmeToKLQkJCWNhc2UgT1MuTGVhdmVOb3RpZnk6Ci0JCQkqLwotCQkJCS8qCi0JCQkJICogRG8gbm90IGRpc3BhdGNoIHRoZXNlCi0JCQkJICovCi0JCQkJIC8qIEFXCi0JCQkJYnJlYWs7Ci0JCQlkZWZhdWx0OgotCQkJCU9TLlh0RGlzcGF0Y2hFdmVudCAoeEV2ZW50KTsKLQkJfQotCX0KLQlkcmF3UmVjdGFuZ2xlcyAoKTsKLQl0cmFja2luZyA9IGZhbHNlOwotCWlmIChwdHJHcmFiUmVzdWx0ID09IE9TLkdyYWJTdWNjZXNzKSBPUy5YVW5ncmFiUG9pbnRlciAoeERpc3BsYXksIE9TLkN1cnJlbnRUaW1lKTsKLQlpZiAoa2JkR3JhYlJlc3VsdCA9PSBPUy5HcmFiU3VjY2VzcykgT1MuWFVuZ3JhYktleWJvYXJkICh4RGlzcGxheSwgT1MuQ3VycmVudFRpbWUpOwotCXJldHVybiAhY2FuY2VsbGVkOwotCSovCiAJcmV0dXJuIGZhbHNlOwogfQotLyoqCi0gKiBSZW1vdmVzIHRoZSBsaXN0ZW5lciBmcm9tIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZpZWQgd2hlbiB0aGUgY29udHJvbCBpcyBtb3ZlZCBvciByZXNpemVkLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgQ29udHJvbExpc3RlbmVyCi0gKiBAc2VlICNhZGRDb250cm9sTGlzdGVuZXIKLSAqLworCiBwdWJsaWMgdm9pZCByZW1vdmVDb250cm9sTGlzdGVuZXIgKENvbnRyb2xMaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0ICgpOwogCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWlmIChldmVudFRhYmxlID09IG51bGwpIHJldHVybjsKIAlldmVudFRhYmxlLnVuaG9vayAoU1dULk1vdmUsIGxpc3RlbmVyKTsKIH0KKwogdm9pZCByZXNpemVSZWN0YW5nbGVzIChpbnQgeENoYW5nZSwgaW50IHlDaGFuZ2UpIHsKIAkvKgogCSogSWYgdGhlIGN1cnNvciBvcmllbnRhdGlvbiBoYXMgbm90IGJlZW4gc2V0IGluIHRoZSBvcmllbnRhdGlvbiBvZgpAQCAtNjE5LDQ4ICsxODIsMTYgQEAKIAlyZWN0YW5nbGVzID0gbmV3UmVjdHM7CQogfQogCi0vKioKLSAqIFNldHMgdGhlIDxjb2RlPkN1cnNvcjwvY29kZT4gb2YgdGhlIFRyYWNrZXIuICBJZiB0aGlzIGN1cnNvciBpcyA8Y29kZT5udWxsPC9jb2RlPgotICogdGhlbiB0aGUgY3Vyc29yIHJldmVydHMgdG8gdGhlIGRlZmF1bHQuCi0gKgotICogQHBhcmFtIG5ld0N1cnNvciB0aGUgbmV3IDxjb2RlPkN1cnNvcjwvY29kZT4gdG8gZGlzcGxheQotICogCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KIHB1YmxpYyB2b2lkIHNldEN1cnNvciAoQ3Vyc29yIHZhbHVlKSB7CiAJY2hlY2tXaWRnZXQgKCk7Ci0JY3Vyc29yID0gMDsKLQlpZiAodmFsdWUgIT0gbnVsbCkgY3Vyc29yID0gdmFsdWUuaGFuZGxlOwogfQotLyoqCi0gKiBTcGVjaWZpZXMgdGhlIHJlY3RhbmdsZXMgdGhhdCBzaG91bGQgYmUgZHJhd24sIGV4cHJlc3NlZCByZWxhdGl2ZSB0byB0aGUgcGFyZW50Ci0gKiB3aWRnZXQuICBJZiB0aGUgcGFyZW50IGlzIGEgRGlzcGxheSB0aGVuIHRoZXNlIGFyZSBzY3JlZW4gY29vcmRpbmF0ZXMuCi0gKgotICogQHBhcmFtIHJlY3RhbmdsZXMgdGhlIGJvdW5kcyBvZiB0aGUgcmVjdGFuZ2xlcyB0byBiZSBkcmF3bgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgdm9pZCBzZXRSZWN0YW5nbGVzIChSZWN0YW5nbGUgW10gcmVjdGFuZ2xlcykgewogCWNoZWNrV2lkZ2V0ICgpOwogCXRoaXMucmVjdGFuZ2xlcyA9IHJlY3RhbmdsZXM7CiAJcHJvcG9ydGlvbnMgPSBjb21wdXRlUHJvcG9ydGlvbnMgKHJlY3RhbmdsZXMpOwogfQotLyoqCi0gKiBDaGFuZ2VzIHRoZSBhcHBlYXJhbmNlIG9mIHRoZSBsaW5lIHVzZWQgdG8gZHJhdyB0aGUgcmVjdGFuZ2xlcy4KLSAqCi0gKiBAcGFyYW0gc3RpcHBsZWQgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgcmVjdGFuZ2xlIHNob3VsZCBhcHBlYXIgc3RpcHBsZWQKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKi8KKwogcHVibGljIHZvaWQgc2V0U3RpcHBsZWQgKGJvb2xlYW4gc3RpcHBsZWQpIHsKIAljaGVja1dpZGdldCAoKTsKIAl0aGlzLnN0aXBwbGVkID0gc3RpcHBsZWQ7CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVHJlZS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1RyZWUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZGE4ZWY5Ci0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1RyZWUuamF2YQpAQCAtMCwwICsxLDczMSBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0czsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKyAKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLk9TOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uRGF0YUJyb3dzZXJDYWxsYmFja3M7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5EYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrczsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkRhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUkdCQ29sb3I7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5SZWN0OworCitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOworCitwdWJsaWMgY2xhc3MgVHJlZSBleHRlbmRzIENvbXBvc2l0ZSB7CisJVHJlZUl0ZW0gW10gaXRlbXM7CisJR0MgcGFpbnRHQzsKKwlpbnQgYW5jaG9yRmlyc3QsIGFuY2hvckxhc3Q7CisJYm9vbGVhbiBpZ25vcmVTZWxlY3QsIGlnbm9yZUV4cGFuZDsKKwlzdGF0aWMgZmluYWwgaW50IENIRUNLX0NPTFVNTl9JRCA9IDEwMjQ7CisJc3RhdGljIGZpbmFsIGludCBDT0xVTU5fSUQgPSAxMDI1OworCitwdWJsaWMgVHJlZSAoQ29tcG9zaXRlIHBhcmVudCwgaW50IHN0eWxlKSB7CisJc3VwZXIgKHBhcmVudCwgY2hlY2tTdHlsZSAoc3R5bGUpKTsKK30KKworcHVibGljIHZvaWQgYWRkU2VsZWN0aW9uTGlzdGVuZXIoU2VsZWN0aW9uTGlzdGVuZXIgbGlzdGVuZXIpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlUeXBlZExpc3RlbmVyIHR5cGVkTGlzdGVuZXIgPSBuZXcgVHlwZWRMaXN0ZW5lciAobGlzdGVuZXIpOworCWFkZExpc3RlbmVyIChTV1QuU2VsZWN0aW9uLCB0eXBlZExpc3RlbmVyKTsKKwlhZGRMaXN0ZW5lciAoU1dULkRlZmF1bHRTZWxlY3Rpb24sIHR5cGVkTGlzdGVuZXIpOworfQorCitwdWJsaWMgdm9pZCBhZGRUcmVlTGlzdGVuZXIoVHJlZUxpc3RlbmVyIGxpc3RlbmVyKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJVHlwZWRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IFR5cGVkTGlzdGVuZXIgKGxpc3RlbmVyKTsKKwlhZGRMaXN0ZW5lciAoU1dULkV4cGFuZCwgdHlwZWRMaXN0ZW5lcik7CisJYWRkTGlzdGVuZXIgKFNXVC5Db2xsYXBzZSwgdHlwZWRMaXN0ZW5lcik7Cit9IAorCitzdGF0aWMgaW50IGNoZWNrU3R5bGUgKGludCBzdHlsZSkgeworCS8qCisJKiBGZWF0dXJlIGluIFdpbmRvd3MuICBJdCBpcyBub3QgcG9zc2libGUgdG8gY3JlYXRlCisJKiBhIHRyZWUgdGhhdCBzY3JvbGxzIGFuZCBkb2VzIG5vdCBoYXZlIHNjcm9sbCBiYXJzLgorCSogVGhlIFRWU19OT1NDUk9MTCBzdHlsZSB3aWxsIHJlbW92ZSB0aGUgc2Nyb2xsIGJhcnMKKwkqIGJ1dCB0aGUgdHJlZSB3aWxsIG5ldmVyIHNjcm9sbC4gIFRoZXJlZm9yZSwgbm8gbWF0dGVyCisJKiB3aGF0IHN0eWxlIGJpdHMgYXJlIHNwZWNpZmllZCwgc2V0IHRoZSBIX1NDUk9MTCBhbmQKKwkqIFZfU0NST0xMIGJpdHMgc28gdGhhdCB0aGUgU1dUIHN0eWxlIHdpbGwgbWF0Y2ggdGhlCisJKiB3aWRnZXQgdGhhdCBXaW5kb3dzIGNyZWF0ZXMuCisJKi8KKwlzdHlsZSB8PSBTV1QuSF9TQ1JPTEwgfCBTV1QuVl9TQ1JPTEw7CisJcmV0dXJuIGNoZWNrQml0cyAoc3R5bGUsIFNXVC5TSU5HTEUsIFNXVC5NVUxUSSwgMCwgMCwgMCwgMCk7Cit9CisKK3B1YmxpYyBQb2ludCBjb21wdXRlU2l6ZSAoaW50IHdIaW50LCBpbnQgaEhpbnQsIGJvb2xlYW4gY2hhbmdlZCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWludCB3aWR0aCA9IDA7CisJaWYgKHdIaW50ID09IFNXVC5ERUZBVUxUKSB7CisJCVRyZWVJdGVtIFtdIGl0ZW1zID0gZ2V0SXRlbXMgKCk7CisJCUdDIGdjID0gbmV3IEdDICh0aGlzKTsKKwkJZm9yIChpbnQgaT0wOyBpPGl0ZW1zLmxlbmd0aDsgaSsrKSB7CisJCQlSZWN0YW5nbGUgcmVjdCA9IGl0ZW1zIFtpXS5nZXRCb3VuZHMgKCk7CisJCQl3aWR0aCA9IE1hdGgubWF4ICh3aWR0aCwgcmVjdC53aWR0aCk7CisJCX0KKwkJZ2MuZGlzcG9zZSAoKTsKKwkJd2lkdGggPSB3aWR0aCAqIDI7CisJfSBlbHNlIHsKKwkJd2lkdGggPSB3SGludDsKKwl9CisJaWYgKHdpZHRoIDw9IDApIHdpZHRoID0gREVGQVVMVF9XSURUSDsKKwlpbnQgaGVpZ2h0ID0gMDsKKwlpZiAoaEhpbnQgPT0gU1dULkRFRkFVTFQpIHsKKwkJaGVpZ2h0ID0gZ2V0SXRlbUNvdW50ICgpICogZ2V0SXRlbUhlaWdodCAoKTsKKwl9IGVsc2UgeworCQloZWlnaHQgPSBoSGludDsKKwl9CisJaWYgKGhlaWdodCA8PSAwKSBoZWlnaHQgPSBERUZBVUxUX0hFSUdIVDsKKwlSZWN0YW5nbGUgcmVjdCA9IGNvbXB1dGVUcmltICgwLCAwLCB3aWR0aCwgaGVpZ2h0KTsKKwlyZXR1cm4gbmV3IFBvaW50IChyZWN0LndpZHRoLCByZWN0LmhlaWdodCk7Cit9CisKK3B1YmxpYyBSZWN0YW5nbGUgY29tcHV0ZVRyaW0gKGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CisJY2hlY2tXaWRnZXQoKTsKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXREYXRhQnJvd3NlclNjcm9sbEJhckluc2V0IChoYW5kbGUsIHJlY3QpOworCXggLT0gcmVjdC5sZWZ0OworCXkgLT0gcmVjdC50b3A7CisJd2lkdGggKz0gKHJlY3QubGVmdCArIHJlY3QucmlnaHQpICogMzsKKwloZWlnaHQgKz0gcmVjdC50b3AgKyByZWN0LmJvdHRvbTsKKwlyZXR1cm4gbmV3IFJlY3RhbmdsZSAoeCwgeSwgd2lkdGgsIGhlaWdodCk7Cit9CisKK3ZvaWQgY3JlYXRlSGFuZGxlICgpIHsKKwlpbnQgW10gb3V0Q29udHJvbCA9IG5ldyBpbnQgWzFdOworCWludCB3aW5kb3cgPSBPUy5HZXRDb250cm9sT3duZXIgKHBhcmVudC5oYW5kbGUpOworCU9TLkNyZWF0ZURhdGFCcm93c2VyQ29udHJvbCAod2luZG93LCBudWxsLCBPUy5rRGF0YUJyb3dzZXJMaXN0Vmlldywgb3V0Q29udHJvbCk7CisJaWYgKG91dENvbnRyb2wgWzBdID09IDApIGVycm9yIChTV1QuRVJST1JfTk9fSEFORExFUyk7CisJaGFuZGxlID0gb3V0Q29udHJvbCBbMF07CisJaW50IHNlbGVjdGlvbkZsYWdzID0gKHN0eWxlICYgU1dULlNJTkdMRSkgIT0gMCA/IE9TLmtEYXRhQnJvd3NlclNlbGVjdE9ubHlPbmUgOiBPUy5rRGF0YUJyb3dzZXJDbWRUb2dnbGVzU2VsZWN0aW9uOworCU9TLlNldERhdGFCcm93c2VyU2VsZWN0aW9uRmxhZ3MgKGhhbmRsZSwgc2VsZWN0aW9uRmxhZ3MpOworCU9TLlNldERhdGFCcm93c2VyTGlzdFZpZXdIZWFkZXJCdG5IZWlnaHQgKGhhbmRsZSwgKHNob3J0KSAwKTsKKwlPUy5TZXREYXRhQnJvd3Nlckhhc1Njcm9sbEJhcnMgKGhhbmRsZSwgKHN0eWxlICYgU1dULkhfU0NST0xMKSAhPSAwLCAoc3R5bGUgJiBTV1QuVl9TQ1JPTEwpICE9IDApOworCS8vTk9UIERPTkUKKwlpZiAoKHN0eWxlICYgU1dULkhfU0NST0xMKSA9PSAwKSBPUy5BdXRvU2l6ZURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5zIChoYW5kbGUpOworCWludCBwb3NpdGlvbiA9IDA7CisJaWYgKChzdHlsZSAmIFNXVC5DSEVDSykgIT0gMCkgeworCQlEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYyBjaGVja0NvbHVtbiA9IG5ldyBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYyAoKTsKKwkJY2hlY2tDb2x1bW4uaGVhZGVyQnRuRGVzY192ZXJzaW9uID0gT1Mua0RhdGFCcm93c2VyTGlzdFZpZXdMYXRlc3RIZWFkZXJEZXNjOworCQljaGVja0NvbHVtbi5wcm9wZXJ0eURlc2NfcHJvcGVydHlJRCA9IENIRUNLX0NPTFVNTl9JRDsKKwkJY2hlY2tDb2x1bW4ucHJvcGVydHlEZXNjX3Byb3BlcnR5VHlwZSA9IE9TLmtEYXRhQnJvd3NlckNoZWNrYm94VHlwZTsKKwkJY2hlY2tDb2x1bW4ucHJvcGVydHlEZXNjX3Byb3BlcnR5RmxhZ3MgPSBPUy5rRGF0YUJyb3dzZXJQcm9wZXJ0eUlzTXV0YWJsZTsKKwkJLy9OT1QgRE9ORQorCQljaGVja0NvbHVtbi5oZWFkZXJCdG5EZXNjX21pbmltdW1XaWR0aCA9IDQwOworCQljaGVja0NvbHVtbi5oZWFkZXJCdG5EZXNjX21heGltdW1XaWR0aCA9IDQwOworCQljaGVja0NvbHVtbi5oZWFkZXJCdG5EZXNjX2luaXRpYWxPcmRlciA9IE9TLmtEYXRhQnJvd3Nlck9yZGVySW5jcmVhc2luZzsKKwkJT1MuQWRkRGF0YUJyb3dzZXJMaXN0Vmlld0NvbHVtbiAoaGFuZGxlLCBjaGVja0NvbHVtbiwgcG9zaXRpb24rKyk7CisJfQorCURhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW5EZXNjIGNvbHVtbiA9IG5ldyBEYXRhQnJvd3Nlckxpc3RWaWV3Q29sdW1uRGVzYyAoKTsKKwljb2x1bW4uaGVhZGVyQnRuRGVzY192ZXJzaW9uID0gT1Mua0RhdGFCcm93c2VyTGlzdFZpZXdMYXRlc3RIZWFkZXJEZXNjOworCWNvbHVtbi5wcm9wZXJ0eURlc2NfcHJvcGVydHlJRCA9IENPTFVNTl9JRDsKKy8vCWNvbHVtbi5wcm9wZXJ0eURlc2NfcHJvcGVydHlUeXBlID0gT1Mua0RhdGFCcm93c2VyVGV4dFR5cGU7IC8vIE9TLmtEYXRhQnJvd3Nlckljb25BbmRUZXh0VHlwZQorCWNvbHVtbi5wcm9wZXJ0eURlc2NfcHJvcGVydHlUeXBlID0gT1Mua0RhdGFCcm93c2VyQ3VzdG9tVHlwZTsKKwljb2x1bW4ucHJvcGVydHlEZXNjX3Byb3BlcnR5RmxhZ3MgPSBPUy5rRGF0YUJyb3dzZXJMaXN0Vmlld1NlbGVjdGlvbkNvbHVtbiB8IE9TLmtEYXRhQnJvd3NlckRlZmF1bHRQcm9wZXJ0eUZsYWdzOworCS8vTk9UIERPTkUKKwljb2x1bW4uaGVhZGVyQnRuRGVzY19tYXhpbXVtV2lkdGggPSAweDdGRkY7CisJY29sdW1uLmhlYWRlckJ0bkRlc2NfaW5pdGlhbE9yZGVyID0gT1Mua0RhdGFCcm93c2VyT3JkZXJJbmNyZWFzaW5nOworCU9TLkFkZERhdGFCcm93c2VyTGlzdFZpZXdDb2x1bW4gKGhhbmRsZSwgY29sdW1uLCBwb3NpdGlvbik7CisJT1MuU2V0RGF0YUJyb3dzZXJMaXN0Vmlld0Rpc2Nsb3N1cmVDb2x1bW4gKGhhbmRsZSwgQ09MVU1OX0lELCB0cnVlKTsKKwlPUy5TZXREYXRhQnJvd3NlclRhYmxlVmlld05hbWVkQ29sdW1uV2lkdGggKGhhbmRsZSwgQ09MVU1OX0lELCAoc2hvcnQpODAwKTsKKworCS8qCisJKiBGZWF0dXJlIGluIHRoZSBNYWNpbnRvc2guICBTY3JvbGwgYmFycyBhcmUgbm90IGNyZWF0ZWQgdW50aWwKKwkqIHRoZSB3aWRnZXQgaGFzIGEgbWluaW11bSBzaXplLiAgVGhlIGZpeCBpcyB0byBmb3JjZSB0aGUgc2Nyb2xsCisJKiBiYXJzIHRvIGJlIGNyZWF0ZWQgYnkgdGVtcG9yYXJpbHkgZ2l2aW5nIHRoZSB3aWRnZXQgYSBzaXplIGFuZAorCSogdGhlbiByZXN0b3JpbmcgaXQgdG8gemVyby4KKwkqIAorCSogTk9URTogVGhlIHdpZGdldCBtdXN0IGJlIHZpc2libGUgYW5kIFNpemVDb250cm9sKCkgbXVzdCBiZSB1c2VkCisJKiB0byByZXNpemUgdGhlIHdpZGdldCB0byBhIG1pbmltaW0gc2l6ZSBvciB0aGUgd2lkZ2V0IHdpbGwgbm90CisJKiBjcmVhdGUgdGhlIHNjcm9sbCBiYXJzLiAgVGhpcyB3b3JrIGFyb3VuZCBjdXJyZW50bHkgZmxhc2hlcy4KKwkqLworCU9TLlNpemVDb250cm9sIChoYW5kbGUsIChzaG9ydCkgMHhGRiwgKHNob3J0KSAweEZGKTsKKwlPUy5TaXplQ29udHJvbCAoaGFuZGxlLCAoc2hvcnQpIDAsIChzaG9ydCkgMCk7Cit9CisKK3ZvaWQgY3JlYXRlSXRlbSAoVHJlZUl0ZW0gaXRlbSwgVHJlZUl0ZW0gcGFyZW50SXRlbSwgaW50IGluZGV4KSB7CisJaW50IGNvdW50ID0gMDsKKwlmb3IgKGludCBpPTA7IGk8aXRlbXMubGVuZ3RoOyBpKyspIHsKKwkJaWYgKGl0ZW1zIFtpXSAhPSBudWxsICYmIGl0ZW1zIFtpXS5wYXJlbnRJdGVtID09IHBhcmVudEl0ZW0pIGNvdW50Kys7CisJfQorCWlmIChpbmRleCA9PSAtMSkgaW5kZXggPSBjb3VudDsKKwlpdGVtLmluZGV4ID0gaW5kZXg7CisJZm9yIChpbnQgaT0wOyBpPGl0ZW1zLmxlbmd0aDsgaSsrKSB7CisJCWlmIChpdGVtcyBbaV0gIT0gbnVsbCAmJiBpdGVtcyBbaV0ucGFyZW50SXRlbSA9PSBwYXJlbnRJdGVtKSB7CisJCQlpZiAoaXRlbXMgW2ldLmluZGV4ID49IGl0ZW0uaW5kZXgpIGl0ZW1zIFtpXS5pbmRleCsrOworCQl9CisJfQorCWludCBpZCA9IDA7CisJd2hpbGUgKGlkIDwgaXRlbXMubGVuZ3RoICYmIGl0ZW1zIFtpZF0gIT0gbnVsbCkgaWQrKzsKKwlpZiAoaWQgPT0gaXRlbXMubGVuZ3RoKSB7CisJCVRyZWVJdGVtIFtdIG5ld0l0ZW1zID0gbmV3IFRyZWVJdGVtIFtpdGVtcy5sZW5ndGggKyA0XTsKKwkJU3lzdGVtLmFycmF5Y29weSAoaXRlbXMsIDAsIG5ld0l0ZW1zLCAwLCBpdGVtcy5sZW5ndGgpOworCQlpdGVtcyA9IG5ld0l0ZW1zOworCX0KKwlpdGVtcyBbaWRdID0gaXRlbTsKKwlpdGVtLmlkID0gaWQgKyAxOworCWludCBwYXJlbnRJRCA9IE9TLmtEYXRhQnJvd3Nlck5vSXRlbTsKKwlib29sZWFuIGV4cGFuZGVkID0gdHJ1ZTsKKwlpZiAocGFyZW50SXRlbSAhPSBudWxsKSB7CisJCXBhcmVudElEID0gcGFyZW50SXRlbS5pZDsKKwkJZXhwYW5kZWQgPSBwYXJlbnRJdGVtLmdldEV4cGFuZGVkICgpOworCX0KKwlpZiAoZXhwYW5kZWQpIHsKKwkJaWYgKE9TLkFkZERhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgcGFyZW50SUQsIDEsIG5ldyBpbnRbXSB7aXRlbS5pZH0sIDApICE9IE9TLm5vRXJyKSB7CisJCQlpdGVtcyBbaWRdID0gbnVsbDsKKwkJCWVycm9yIChTV1QuRVJST1JfSVRFTV9OT1RfQURERUQpOworCQl9CisJfQorfQorCitTY3JvbGxCYXIgY3JlYXRlU2Nyb2xsQmFyIChpbnQgc3R5bGUpIHsKKwlyZXR1cm4gY3JlYXRlU3RhbmRhcmRCYXIgKHN0eWxlKTsKK30KKwordm9pZCBjcmVhdGVXaWRnZXQgKCkgeworCXN1cGVyLmNyZWF0ZVdpZGdldCAoKTsKKwlpdGVtcyA9IG5ldyBUcmVlSXRlbSBbNF07Cit9CisKK2ludCBkZWZhdWx0VGhlbWVGb250ICgpIHsJCisJcmV0dXJuIE9TLmtUaGVtZVZpZXdzRm9udDsKK30KKworcHVibGljIHZvaWQgZGVzZWxlY3RBbGwgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIDAsIG51bGwsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zUmVtb3ZlKTsKKwlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKK30KKwordm9pZCBkZXN0cm95SXRlbSAoVHJlZUl0ZW0gaXRlbSkgeworCWludCBwYXJlbnRJRCA9IGl0ZW0ucGFyZW50SXRlbSA9PSBudWxsID8gT1Mua0RhdGFCcm93c2VyTm9JdGVtIDogaXRlbS5wYXJlbnRJdGVtLmlkOworCWlmIChPUy5SZW1vdmVEYXRhQnJvd3Nlckl0ZW1zIChoYW5kbGUsIHBhcmVudElELCAxLCBuZXcgaW50W10ge2l0ZW0uaWR9LCAwKSAhPSBPUy5ub0VycikgeworCQllcnJvciAoU1dULkVSUk9SX0lURU1fTk9UX1JFTU9WRUQpOworCX0KKwlmb3IgKGludCBpPTA7IGk8aXRlbXMubGVuZ3RoOyBpKyspIHsKKwkJaWYgKGl0ZW1zIFtpXSAhPSBudWxsKSB7CisJCQlUcmVlSXRlbSBwYXJlbnRJdGVtID0gaXRlbXMgW2ldLnBhcmVudEl0ZW07CisJCQl3aGlsZSAocGFyZW50SXRlbSAhPSBudWxsICYmIHBhcmVudEl0ZW0gIT0gaXRlbSkgeworCQkJCXBhcmVudEl0ZW0gPSBwYXJlbnRJdGVtLnBhcmVudEl0ZW07CisJCQl9CisJCQlpZiAocGFyZW50SXRlbSA9PSBpdGVtKSB7CisJCQkJVHJlZUl0ZW0gb2xkSXRlbSA9IGl0ZW1zIFtpXTsKKwkJCQlpdGVtcyBbaV0uaWQgPSAwOworCQkJCWl0ZW1zIFtpXS5pbmRleCA9IC0xOwkKKwkJCQlpdGVtcyBbaV0gPSBudWxsOworCQkJCW9sZEl0ZW0ucmVsZWFzZVJlc291cmNlcyAoKTsKKwkJCX0KKwkJfQorCX0KKwlUcmVlSXRlbSBwYXJlbnRJdGVtID0gaXRlbS5wYXJlbnRJdGVtOworCWZvciAoaW50IGk9MDsgaTxpdGVtcy5sZW5ndGg7IGkrKykgeworCQlpZiAoaXRlbXMgW2ldICE9IG51bGwgJiYgaXRlbXMgW2ldLnBhcmVudEl0ZW0gPT0gcGFyZW50SXRlbSkgeworCQkJaWYgKGl0ZW1zIFtpXS5pbmRleCA+PSBpdGVtLmluZGV4KSAtLWl0ZW1zIFtpXS5pbmRleDsKKwkJfQorCX0KKwlpdGVtcyBbaXRlbS5pZCAtIDFdID0gbnVsbDsKKwlpdGVtLmlkID0gMDsKKwlpdGVtLmluZGV4ID0gLTE7Cit9CisKK2ludCBkcmF3SXRlbVByb2MgKGludCBicm93c2VyLCBpbnQgaWQsIGludCBwcm9wZXJ0eSwgaW50IGl0ZW1TdGF0ZSwgaW50IHRoZVJlY3QsIGludCBnZERlcHRoLCBpbnQgY29sb3JEZXZpY2UpIHsKKwlpbnQgaW5kZXggPSBpZCAtIDE7CisJaWYgKCEoMCA8PSBpbmRleCAmJiBpbmRleCA8IGl0ZW1zLmxlbmd0aCkpIHJldHVybiBPUy5ub0VycjsKKwlUcmVlSXRlbSBpdGVtID0gaXRlbXMgW2luZGV4XTsKKworLy8JaWYgKGZhbHNlKSB7CisvLwkJaW50IFtdIHBvcnQgPSBuZXcgaW50IFsxXSwgZ2RoID0gbmV3IGludCBbMV07CisvLwkJT1MuR2V0R1dvcmxkIChwb3J0LCBnZGgpOworLy8JCWJ5dGUgW10gYnVmZmVyID0gaXRlbS50ZXh0LmdldEJ5dGVzKCk7CisvLwkJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisvLwkJT1MubWVtY3B5IChyZWN0LCB0aGVSZWN0LCBSZWN0LnNpemVvZik7CisvLwkJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKy8vCQlDb2xvciBmb3JlZ3JvdW5kID0gbnVsbCwgYmFja2dyb3VuZCA9IG51bGw7CisvLwkJaWYgKChpdGVtU3RhdGUgJiBPUy5rRGF0YUJyb3dzZXJJdGVtSXNTZWxlY3RlZCkgIT0gMCkgIHsKKy8vCQkJZm9yZWdyb3VuZCA9IGRpc3BsYXkuZ2V0U3lzdGVtQ29sb3IgKFNXVC5DT0xPUl9MSVNUX1NFTEVDVElPTl9URVhUKTsKKy8vCQkJYmFja2dyb3VuZCA9IGRpc3BsYXkuZ2V0U3lzdGVtQ29sb3IgKFNXVC5DT0xPUl9MSVNUX1NFTEVDVElPTik7CisvLwkJfSBlbHNlIHsKKy8vCQkJZm9yZWdyb3VuZCA9IGRpc3BsYXkuZ2V0U3lzdGVtQ29sb3IgKFNXVC5DT0xPUl9MSVNUX0ZPUkVHUk9VTkQpOworLy8JCQliYWNrZ3JvdW5kID0gZGlzcGxheS5nZXRTeXN0ZW1Db2xvciAoU1dULkNPTE9SX0xJU1RfQkFDS0dST1VORCk7CisvLwkJfQorLy8JCWludCByZWQgPSAoc2hvcnQpIChiYWNrZ3JvdW5kLmhhbmRsZSBbMF0gKiAyNTUpOworLy8JCWludCBncmVlbiA9IChzaG9ydCkgKGJhY2tncm91bmQuaGFuZGxlIFsxXSAqIDI1NSk7CisvLwkJaW50IGJsdWUgPSAoc2hvcnQpIChiYWNrZ3JvdW5kLmhhbmRsZSBbMl0gKiAyNTUpOworLy8JCVJHQkNvbG9yIGNvbG9yID0gbmV3IFJHQkNvbG9yICgpOworLy8JCWNvbG9yLnJlZCA9IChzaG9ydCkgKHJlZCA8PCA4IHwgcmVkKTsKKy8vCQljb2xvci5ncmVlbiA9IChzaG9ydCkgKGdyZWVuIDw8IDggfCBncmVlbik7CisvLwkJY29sb3IuYmx1ZSA9IChzaG9ydCkgKGJsdWUgPDwgOCB8IGJsdWUpOworLy8JCU9TLlJHQkZvcmVDb2xvciAoY29sb3IpOworLy8JCU9TLlBhaW50UmVjdCAocmVjdCk7CisvLwkJcmVkID0gKHNob3J0KSAoZm9yZWdyb3VuZC5oYW5kbGUgWzBdICogMjU1KTsKKy8vCQlncmVlbiA9IChzaG9ydCkgKGZvcmVncm91bmQuaGFuZGxlIFsxXSAqIDI1NSk7CisvLwkJYmx1ZSA9IChzaG9ydCkgKGZvcmVncm91bmQuaGFuZGxlIFsyXSAqIDI1NSk7CisvLwkJY29sb3IucmVkID0gKHNob3J0KSAocmVkIDw8IDggfCByZWQpOworLy8JCWNvbG9yLmdyZWVuID0gKHNob3J0KSAoZ3JlZW4gPDwgOCB8IGdyZWVuKTsKKy8vCQljb2xvci5ibHVlID0gKHNob3J0KSAoYmx1ZSA8PCA4IHwgYmx1ZSk7CisvLwkJT1MuUkdCRm9yZUNvbG9yIChjb2xvcik7CisvLwkJT1MuTW92ZVRvIChyZWN0LmxlZnQsIChzaG9ydCkocmVjdC50b3AgKyAxMykpOworLy8JCU9TLkRyYXdUZXh0IChidWZmZXIsIChzaG9ydCkgMCwgKHNob3J0KSBidWZmZXIubGVuZ3RoKTsKKy8vCQlPUy5TZXRHV29ybGQgKHBvcnQgWzBdLCBnZGggWzBdKTsKKy8vLy8JCVN5c3RlbS5vdXQucHJpbnRsbigieD0iICsgcmVjdC5sZWZ0ICsgIiB5PSIgKyByZWN0LnRvcCArICIgd2lkdGg9IiArIChyZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0KSArICIgaGVpZ2h0PSIgKyAocmVjdC5ib3R0b20gLSByZWN0LnRvcCkpOworLy8JCXJldHVybiBPUy5ub0VycjsKKy8vCX0gCisKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKTsKKwlPUy5tZW1jcHkgKHJlY3QsIHRoZVJlY3QsIFJlY3Quc2l6ZW9mKTsKKy8vCVN5c3RlbS5vdXQucHJpbnRsbigieD0iICsgcmVjdC5sZWZ0ICsgIiB5PSIgKyByZWN0LnRvcCArICIgd2lkdGg9IiArIChyZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0KSArICIgaGVpZ2h0PSIgKyAocmVjdC5ib3R0b20gLSByZWN0LnRvcCkpOworCWludCB4ID0gcmVjdC5sZWZ0OworCWludCB5ID0gcmVjdC50b3A7CisJaW50IHdpZHRoID0gcmVjdC5yaWdodCAtIHJlY3QubGVmdDsKKwlpbnQgaGVpZ2h0ID0gcmVjdC5ib3R0b20gLSByZWN0LnRvcDsKKwlSZWN0IGNvbnRyb2xSZWN0ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAoaGFuZGxlLCBjb250cm9sUmVjdCk7CisJeCAtPSBjb250cm9sUmVjdC5sZWZ0OworCXkgLT0gY29udHJvbFJlY3QudG9wOworCUdDIGdjID0gcGFpbnRHQyA9PSBudWxsID8gbmV3IEdDICh0aGlzKSA6ICBwYWludEdDOworCWludCBjbGlwID0gT1MuTmV3UmduICgpOworCU9TLkdldENsaXAgKGNsaXApOworCU9TLk9mZnNldFJnbiAoY2xpcCwgKHNob3J0KS1jb250cm9sUmVjdC5sZWZ0LCAoc2hvcnQpLWNvbnRyb2xSZWN0LnRvcCk7CisJZ2Muc2V0Q2xpcHBpbmcgKFJlZ2lvbi5jYXJib25fbmV3IChjbGlwKSk7CisJT1MuRGlzcG9zZVJnbiAoY2xpcCk7CisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlDb2xvciBmb3JlZ3JvdW5kID0gaXRlbS5mb3JlZ3JvdW5kICE9IG51bGwgPyBpdGVtLmZvcmVncm91bmQgOiBkaXNwbGF5LmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfTElTVF9GT1JFR1JPVU5EKTsKKwlDb2xvciBiYWNrZ3JvdW5kID0gaXRlbS5iYWNrZ3JvdW5kICE9IG51bGwgPyBpdGVtLmJhY2tncm91bmQgOiBkaXNwbGF5LmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfTElTVF9CQUNLR1JPVU5EKTsKKwlnYy5zZXRGb3JlZ3JvdW5kIChmb3JlZ3JvdW5kKTsKKwlnYy5zZXRCYWNrZ3JvdW5kIChiYWNrZ3JvdW5kKTsKKwlnYy5maWxsUmVjdGFuZ2xlICh4LCB5LCB3aWR0aCwgaGVpZ2h0KTsKKwlJbWFnZSBpbWFnZSA9IGl0ZW0uaW1hZ2U7CisJaWYgKGltYWdlICE9IG51bGwpIHsKKwkJUmVjdGFuZ2xlIGJvdW5kcyA9IGltYWdlLmdldEJvdW5kcyAoKTsKKwkJZ2MuZHJhd0ltYWdlIChpbWFnZSwgMCwgMCwgYm91bmRzLndpZHRoLCBib3VuZHMuaGVpZ2h0LCB4LCB5LCBib3VuZHMud2lkdGgsIGhlaWdodCk7CisJCXggKz0gYm91bmRzLndpZHRoICsgMjsKKwl9CisJUG9pbnQgZXh0ZW50ID0gZ2Muc3RyaW5nRXh0ZW50IChpdGVtLnRleHQpOworCWlmICgoaXRlbVN0YXRlICYgT1Mua0RhdGFCcm93c2VySXRlbUlzU2VsZWN0ZWQpICE9IDApIHsKKwkJZ2Muc2V0Rm9yZWdyb3VuZCAoZGlzcGxheS5nZXRTeXN0ZW1Db2xvciAoU1dULkNPTE9SX0xJU1RfU0VMRUNUSU9OX1RFWFQpKTsKKwkJZ2Muc2V0QmFja2dyb3VuZCAoZGlzcGxheS5nZXRTeXN0ZW1Db2xvciAoU1dULkNPTE9SX0xJU1RfU0VMRUNUSU9OKSk7CisJCWdjLmZpbGxSZWN0YW5nbGUgKHgsIHksIGV4dGVudC54LCBoZWlnaHQpOworCX0KKwlnYy5kcmF3U3RyaW5nIChpdGVtLnRleHQsIHgsIHkgKyAoTWF0aC5tYXggKDAsIChoZWlnaHQgLSBleHRlbnQueSkgLyAyKSkpOworCWlmIChwYWludEdDID09IG51bGwpIGdjLmRpc3Bvc2UgKCk7CisJcmV0dXJuIE9TLm5vRXJyOworfQorCitwdWJsaWMgUmVjdGFuZ2xlIGdldENsaWVudEFyZWEgKCkgeworCWNoZWNrV2lkZ2V0KCk7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCksIGluc2V0ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAoaGFuZGxlLCByZWN0KTsKKwlPUy5HZXREYXRhQnJvd3NlclNjcm9sbEJhckluc2V0IChoYW5kbGUsIGluc2V0KTsKKwlyZXR1cm4gbmV3IFJlY3RhbmdsZSAoaW5zZXQubGVmdCwgaW5zZXQudG9wLCByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0ICsgaW5zZXQucmlnaHQsIHJlY3QuYm90dG9tIC0gcmVjdC50b3AgKyBpbnNldC5ib3R0b20pOworfQorCitwdWJsaWMgVHJlZUl0ZW0gZ2V0SXRlbSAoUG9pbnQgcG9pbnQpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAocG9pbnQgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChoYW5kbGUsIHJlY3QpOworCW9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUG9pbnQgcHQgPSBuZXcgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5Qb2ludCAoKTsKKwlPUy5TZXRQdCAocHQsIChzaG9ydCkgKHBvaW50LnggKyByZWN0LmxlZnQpLCAoc2hvcnQpIChwb2ludC55ICsgcmVjdC50b3ApKTsKKwkvL09QVElNSVpFCisJZm9yIChpbnQgaT0wOyBpPGl0ZW1zLmxlbmd0aDsgaSsrKSB7CisJCVRyZWVJdGVtIGl0ZW0gPSBpdGVtcyBbaV07CisJCWlmIChpdGVtICE9IG51bGwpIHsKKwkJCU9TLkdldERhdGFCcm93c2VySXRlbVBhcnRCb3VuZHMgKGhhbmRsZSwgaXRlbS5pZCwgQ09MVU1OX0lELCBPUy5rRGF0YUJyb3dzZXJQcm9wZXJ0eUVuY2xvc2luZ1BhcnQsIHJlY3QpOworCQkJaWYgKE9TLlB0SW5SZWN0IChwdCwgcmVjdCkpIHJldHVybiBpdGVtOworCQl9CisJfQorCXJldHVybiBudWxsOworfQorCitwdWJsaWMgaW50IGdldEl0ZW1Db3VudCAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJcmV0dXJuIGdldEl0ZW1Db3VudCAobnVsbCk7Cit9CisKK2ludCBnZXRJdGVtQ291bnQgKFRyZWVJdGVtIGl0ZW0pIHsKKwljaGVja1dpZGdldCAoKTsKKwlpbnQgY291bnQgPSAwOworCWZvciAoaW50IGk9MDsgaTxpdGVtcy5sZW5ndGg7IGkrKykgeworCQlpZiAoaXRlbXMgW2ldICE9IG51bGwgJiYgaXRlbXMgW2ldLnBhcmVudEl0ZW0gPT0gaXRlbSkgY291bnQrKzsKKwl9CisJcmV0dXJuIGNvdW50OworfQorCitwdWJsaWMgaW50IGdldEl0ZW1IZWlnaHQgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCXNob3J0IFtdIGhlaWdodCA9IG5ldyBzaG9ydCBbMV07CisJaWYgKE9TLkdldERhdGFCcm93c2VyVGFibGVWaWV3Um93SGVpZ2h0IChoYW5kbGUsIGhlaWdodCkgIT0gT1Mubm9FcnIpIHsKKwkJZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfR0VUX0lURU1fSEVJR0hUKTsKKwl9CisJcmV0dXJuIGhlaWdodCBbMF07Cit9CisKK3B1YmxpYyBUcmVlSXRlbSBbXSBnZXRJdGVtcyAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJcmV0dXJuIGdldEl0ZW1zIChudWxsKTsKK30KKworcHVibGljIFRyZWVJdGVtIFtdIGdldEl0ZW1zIChUcmVlSXRlbSBpdGVtKSB7CisJaW50IGNvdW50ID0gMDsKKwlmb3IgKGludCBpPTA7IGk8aXRlbXMubGVuZ3RoOyBpKyspIHsKKwkJaWYgKGl0ZW1zIFtpXSAhPSBudWxsICYmIGl0ZW1zIFtpXS5wYXJlbnRJdGVtID09IGl0ZW0pIGNvdW50Kys7CisJfQorCVRyZWVJdGVtIFtdIHJlc3VsdCA9IG5ldyBUcmVlSXRlbSBbY291bnRdOworCWZvciAoaW50IGk9MDsgaTxpdGVtcy5sZW5ndGg7IGkrKykgeworCQlpZiAoaXRlbXMgW2ldICE9IG51bGwgJiYgaXRlbXMgW2ldLnBhcmVudEl0ZW0gPT0gaXRlbSkgeworCQkJcmVzdWx0IFtpdGVtcyBbaV0uaW5kZXhdID0gaXRlbXMgW2ldOworCQl9CisJfQorCXJldHVybiByZXN1bHQ7Cit9CisKK3B1YmxpYyBUcmVlSXRlbSBnZXRQYXJlbnRJdGVtICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlyZXR1cm4gbnVsbDsKK30KKworcHVibGljIFRyZWVJdGVtIFtdIGdldFNlbGVjdGlvbiAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaW50IHB0ciA9IE9TLk5ld0hhbmRsZSAoMCk7CisJaWYgKE9TLkdldERhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCB0cnVlLCBPUy5rRGF0YUJyb3dzZXJJdGVtSXNTZWxlY3RlZCwgcHRyKSAhPSBPUy5ub0VycikgeworCQllcnJvciAoU1dULkVSUk9SX0NBTk5PVF9HRVRfU0VMRUNUSU9OKTsKKwl9CisJaW50IGNvdW50ID0gT1MuR2V0SGFuZGxlU2l6ZSAocHRyKSAvIDQ7CisJVHJlZUl0ZW0gW10gcmVzdWx0ID0gbmV3IFRyZWVJdGVtIFtjb3VudF07CisJT1MuSExvY2sgKHB0cik7CisJaW50IFtdIHN0YXJ0ID0gbmV3IGludCBbMV07CisJT1MubWVtY3B5IChzdGFydCwgcHRyLCA0KTsKKwlpbnQgW10gaWQgPSBuZXcgaW50IFsxXTsKKwlmb3IgKGludCBpPTA7IGk8Y291bnQ7IGkrKykgeworCQlPUy5tZW1jcHkgKGlkLCBzdGFydCBbMF0gKyAoaSAqIDQpLCA0KTsKKwkJcmVzdWx0IFtpXSA9IGl0ZW1zIFtpZCBbMF0gLSAxXTsKKwl9CisJT1MuSFVubG9jayAocHRyKTsKKwlPUy5EaXNwb3NlSGFuZGxlIChwdHIpOworCXJldHVybiByZXN1bHQ7Cit9CisKK3B1YmxpYyBpbnQgZ2V0U2VsZWN0aW9uQ291bnQgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWludCBbXSBjb3VudCA9IG5ldyBpbnQgWzFdOworCWlmIChPUy5HZXREYXRhQnJvd3Nlckl0ZW1Db3VudCAoaGFuZGxlLCBPUy5rRGF0YUJyb3dzZXJOb0l0ZW0sIHRydWUsIE9TLmtEYXRhQnJvd3Nlckl0ZW1Jc1NlbGVjdGVkLCBjb3VudCkgIT0gT1Mubm9FcnIpIHsKKwkJZXJyb3IgKFNXVC5FUlJPUl9DQU5OT1RfR0VUX0NPVU5UKTsKKwl9CisJcmV0dXJuIGNvdW50IFswXTsKK30KKworaW50IGhpdFRlc3RQcm9jIChpbnQgYnJvd3NlciwgaW50IGlkLCBpbnQgcHJvcGVydHksIGludCB0aGVSZWN0LCBpbnQgbW91c2VSZWN0KSB7CisvLwlpbnQgaW5kZXggPSBpZCAtIDE7CisvLwlpZiAoISgwIDw9IGluZGV4ICYmIGluZGV4IDwgaXRlbXMubGVuZ3RoKSkgcmV0dXJuIDA7CisvLwlUcmVlSXRlbSBpdGVtID0gaXRlbXMgW2luZGV4XTsKKwlyZXR1cm4gMTsKK30KKwordm9pZCBob29rRXZlbnRzICgpIHsKKwlzdXBlci5ob29rRXZlbnRzICgpOworCURpc3BsYXkgZGlzcGxheT0gZ2V0RGlzcGxheSgpOworCURhdGFCcm93c2VyQ2FsbGJhY2tzIGNhbGxiYWNrcyA9IG5ldyBEYXRhQnJvd3NlckNhbGxiYWNrcyAoKTsKKwljYWxsYmFja3MudmVyc2lvbiA9IE9TLmtEYXRhQnJvd3NlckxhdGVzdENhbGxiYWNrczsKKwlPUy5Jbml0RGF0YUJyb3dzZXJDYWxsYmFja3MgKGNhbGxiYWNrcyk7CisJY2FsbGJhY2tzLnYxX2l0ZW1EYXRhQ2FsbGJhY2sgPSBkaXNwbGF5Lml0ZW1EYXRhUHJvYzsKKwljYWxsYmFja3MudjFfaXRlbU5vdGlmaWNhdGlvbkNhbGxiYWNrID0gZGlzcGxheS5pdGVtTm90aWZpY2F0aW9uUHJvYzsKKwlPUy5TZXREYXRhQnJvd3NlckNhbGxiYWNrcyAoaGFuZGxlLCBjYWxsYmFja3MpOworCURhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzIGN1c3RvbSA9IG5ldyBEYXRhQnJvd3NlckN1c3RvbUNhbGxiYWNrcyAoKTsKKwljdXN0b20udmVyc2lvbiA9IE9TLmtEYXRhQnJvd3NlckxhdGVzdEN1c3RvbUNhbGxiYWNrczsKKwlPUy5Jbml0RGF0YUJyb3dzZXJDdXN0b21DYWxsYmFja3MgKGN1c3RvbSk7CisJY3VzdG9tLnYxX2RyYXdJdGVtQ2FsbGJhY2sgPSBkaXNwbGF5LmRyYXdJdGVtUHJvYzsKKwljdXN0b20udjFfaGl0VGVzdENhbGxiYWNrID0gZGlzcGxheS5oaXRUZXN0UHJvYzsKKwljdXN0b20udjFfdHJhY2tpbmdDYWxsYmFjayA9IGRpc3BsYXkudHJhY2tpbmdQcm9jOworCU9TLlNldERhdGFCcm93c2VyQ3VzdG9tQ2FsbGJhY2tzIChoYW5kbGUsIGN1c3RvbSk7Cit9CisKK2ludCBpdGVtRGF0YVByb2MgKGludCBicm93c2VyLCBpbnQgaWQsIGludCBwcm9wZXJ0eSwgaW50IGl0ZW1EYXRhLCBpbnQgc2V0VmFsdWUpIHsKKwlpbnQgaW5kZXggPSBpZCAtIDE7CisJaWYgKCEoMCA8PSBpbmRleCAmJiBpbmRleCA8IGl0ZW1zLmxlbmd0aCkpIHJldHVybiBPUy5ub0VycjsKKwlUcmVlSXRlbSBpdGVtID0gaXRlbXMgW2luZGV4XTsKKwlzd2l0Y2ggKHByb3BlcnR5KSB7CisJCWNhc2UgQ0hFQ0tfQ09MVU1OX0lEOiB7CisJCQlpZiAoc2V0VmFsdWUgIT0gMCkgeworCQkJCXNob3J0IFtdIHRoZURhdGEgPSBuZXcgc2hvcnQgWzFdOworCQkJCU9TLkdldERhdGFCcm93c2VySXRlbURhdGFCdXR0b25WYWx1ZSAoaXRlbURhdGEsIHRoZURhdGEpOworCQkJCWl0ZW0uY2hlY2tlZCA9IHRoZURhdGEgWzBdID09IE9TLmtUaGVtZUJ1dHRvbk9uOworCQkJCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOworCQkJCWV2ZW50Lml0ZW0gPSBpdGVtOworCQkJCWV2ZW50LmRldGFpbCA9IFNXVC5DSEVDSzsKKwkJCQlwb3N0RXZlbnQgKFNXVC5TZWxlY3Rpb24sIGV2ZW50KTsKKwkJCX0gZWxzZSB7CisJCQkJc2hvcnQgdGhlRGF0YSA9IChzaG9ydCkoaXRlbS5jaGVja2VkID8gT1Mua1RoZW1lQnV0dG9uT24gOiBPUy5rVGhlbWVCdXR0b25PZmYpOworCQkJCU9TLlNldERhdGFCcm93c2VySXRlbURhdGFCdXR0b25WYWx1ZSAoaXRlbURhdGEsIHRoZURhdGEpOworCQkJfQorCQkJYnJlYWs7CisJCX0KKy8vCQljYXNlIENPTFVNTl9JRDogeworLy8JCQlTdHJpbmcgdGV4dCA9IGl0ZW0udGV4dDsKKy8vCQkJY2hhciBbXSBidWZmZXIgPSBuZXcgY2hhciBbdGV4dC5sZW5ndGggKCldOworLy8JCQl0ZXh0LmdldENoYXJzICgwLCBidWZmZXIubGVuZ3RoLCBidWZmZXIsIDApOworLy8JCQlpbnQgcHRyID0gT1MuQ0ZTdHJpbmdDcmVhdGVXaXRoQ2hhcmFjdGVycyAoT1Mua0NGQWxsb2NhdG9yRGVmYXVsdCwgYnVmZmVyLCBidWZmZXIubGVuZ3RoKTsKKy8vCQkJaWYgKHB0ciA9PSAwKSBlcnJvciAoU1dULkVSUk9SX0NBTk5PVF9TRVRfVEVYVCk7CisvLwkJCU9TLlNldERhdGFCcm93c2VySXRlbURhdGFUZXh0IChpdGVtRGF0YSwgcHRyKTsKKy8vCQkJT1MuQ0ZSZWxlYXNlIChwdHIpOworLy8JCQlicmVhazsKKy8vCQl9CisJCWNhc2UgT1Mua0RhdGFCcm93c2VySXRlbUlzQ29udGFpbmVyUHJvcGVydHk6IHsKKwkJCWZvciAoaW50IGk9MDsgaTxpdGVtcy5sZW5ndGg7IGkrKykgeworCQkJCWlmIChpdGVtcyBbaV0gIT0gbnVsbCAmJiBpdGVtcyBbaV0ucGFyZW50SXRlbSA9PSBpdGVtKSB7CisJCQkJCU9TLlNldERhdGFCcm93c2VySXRlbURhdGFCb29sZWFuVmFsdWUgKGl0ZW1EYXRhLCB0cnVlKTsKKwkJCQl9CisJCQl9CisJCQlicmVhazsKKwkJfQorCX0KKwlyZXR1cm4gT1Mubm9FcnI7Cit9CisKK2ludCBpdGVtTm90aWZpY2F0aW9uUHJvYyAoaW50IGJyb3dzZXIsIGludCBpZCwgaW50IG1lc3NhZ2UpIHsKKwlpbnQgaW5kZXggPSBpZCAtIDE7CisJaWYgKCEoMCA8PSBpbmRleCAmJiBpbmRleCA8IGl0ZW1zLmxlbmd0aCkpIHJldHVybiBPUy5ub0VycjsKKwlUcmVlSXRlbSBpdGVtID0gaXRlbXMgW2luZGV4XTsKKwlzd2l0Y2ggKG1lc3NhZ2UpIHsKKwkJY2FzZSBPUy5rRGF0YUJyb3dzZXJJdGVtU2VsZWN0ZWQ6CisJCWNhc2UgT1Mua0RhdGFCcm93c2VySXRlbURlc2VsZWN0ZWQ6IHsKKwkJCWlmIChpZ25vcmVTZWxlY3QpIGJyZWFrOworCQkJaW50IFtdIGZpcnN0ID0gbmV3IGludCBbMV0sIGxhc3QgPSBuZXcgaW50IFsxXTsKKwkJCU9TLkdldERhdGFCcm93c2VyU2VsZWN0aW9uQW5jaG9yIChoYW5kbGUsIGZpcnN0LCBsYXN0KTsKKwkJCWJvb2xlYW4gc2VsZWN0ZWQgPSBmYWxzZTsKKwkJCWlmICgoc3R5bGUgJiBTV1QuTVVMVEkpICE9IDApIHsKKwkJCQlpbnQgbW9kaWZpZXJzID0gT1MuR2V0Q3VycmVudEV2ZW50S2V5TW9kaWZpZXJzICgpOworCQkJCWlmICgobW9kaWZpZXJzICYgT1Muc2hpZnRLZXkpICE9IDApIHsKKwkJCQkJaWYgKG1lc3NhZ2UgPT0gT1Mua0RhdGFCcm93c2VySXRlbVNlbGVjdGVkKSB7CisJCQkJCQlzZWxlY3RlZCA9IGZpcnN0IFswXSA9PSBpZCB8fCBsYXN0IFswXSA9PSBpZDsKKwkJCQkJfSBlbHNlIHsKKwkJCQkJCXNlbGVjdGVkID0gaWQgPT0gYW5jaG9yRmlyc3QgfHwgaWQgPT0gYW5jaG9yTGFzdDsKKwkJCQkJfQorCQkJCX0gZWxzZSB7CisJCQkJCWlmICgobW9kaWZpZXJzICYgT1MuY21kS2V5KSAhPSAwKSB7CisJCQkJCQlzZWxlY3RlZCA9IHRydWU7CisJCQkJCX0gZWxzZSB7CisJCQkJCQlzZWxlY3RlZCA9IGZpcnN0IFswXSA9PSBsYXN0IFswXTsKKwkJCQkJfQorCQkJCX0KKwkJCX0gZWxzZSB7CisJCQkJc2VsZWN0ZWQgPSBtZXNzYWdlID09IE9TLmtEYXRhQnJvd3Nlckl0ZW1TZWxlY3RlZDsKKwkJCX0KKwkJCWlmIChzZWxlY3RlZCkgeworCQkJCWFuY2hvckZpcnN0ID0gZmlyc3QgWzBdOworCQkJCWFuY2hvckxhc3QgPSBsYXN0IFswXTsKKwkJCQlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKKwkJCQlldmVudC5pdGVtID0gaXRlbTsKKwkJCQlwb3N0RXZlbnQgKFNXVC5TZWxlY3Rpb24sIGV2ZW50KTsKKwkJCX0KKwkJCWJyZWFrOworCQl9CQorCQljYXNlIE9TLmtEYXRhQnJvd3Nlckl0ZW1Eb3VibGVDbGlja2VkOiB7CisJCQlFdmVudCBldmVudCA9IG5ldyBFdmVudCAoKTsKKwkJCWV2ZW50Lml0ZW0gPSBpdGVtOworCQkJcG9zdEV2ZW50IChTV1QuRGVmYXVsdFNlbGVjdGlvbiwgZXZlbnQpOworCQkJYnJlYWs7CisJCX0KKwkJY2FzZSBPUy5rRGF0YUJyb3dzZXJDb250YWluZXJDbG9zZWQ6IHsKKwkJCWlmIChpZ25vcmVFeHBhbmQpIGJyZWFrOwkKKwkJCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOworCQkJZXZlbnQuaXRlbSA9IGl0ZW07CisJCQlzZW5kRXZlbnQgKFNXVC5Db2xsYXBzZSwgZXZlbnQpOworCQkJYnJlYWs7CisJCX0KKwkJY2FzZSBPUy5rRGF0YUJyb3dzZXJDb250YWluZXJPcGVuZWQ6IHsJCisJCQlpZiAoIWlnbm9yZUV4cGFuZCkgeworCQkJCUV2ZW50IGV2ZW50ID0gbmV3IEV2ZW50ICgpOworCQkJCWV2ZW50Lml0ZW0gPSBpdGVtOworCQkJCXNlbmRFdmVudCAoU1dULkV4cGFuZCwgZXZlbnQpOworCQkJfQorCQkJaW50IGNvdW50ID0gMDsKKwkJCWZvciAoaW50IGk9MDsgaTxpdGVtcy5sZW5ndGg7IGkrKykgeworCQkJCWlmIChpdGVtcyBbaV0gIT0gbnVsbCAmJiBpdGVtcyBbaV0ucGFyZW50SXRlbSA9PSBpdGVtKSBjb3VudCsrOworCQkJfQorCQkJaW50IFtdIGlkcyA9IG5ldyBpbnQgW2NvdW50XTsKKwkJCWZvciAoaW50IGk9MDsgaTxpdGVtcy5sZW5ndGg7IGkrKykgeworCQkJCWlmIChpdGVtcyBbaV0gIT0gbnVsbCAmJiBpdGVtcyBbaV0ucGFyZW50SXRlbSA9PSBpdGVtKSB7CisJCQkJCWlkcyBbaXRlbXMgW2ldLmluZGV4XSA9IGl0ZW1zIFtpXS5pZDsKKwkJCQl9CisJCQl9CisJCQlPUy5BZGREYXRhQnJvd3Nlckl0ZW1zIChoYW5kbGUsIGlkLCBpZHMubGVuZ3RoLCBpZHMsIDApOworCQkJYnJlYWs7CisJCX0KKwl9CisJcmV0dXJuIE9TLm5vRXJyOworfQorCitpbnQga0V2ZW50Q29udHJvbERyYXcgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlHQyBjdXJyZW50R0MgPSBwYWludEdDOworCWlmIChjdXJyZW50R0MgPT0gbnVsbCkgcGFpbnRHQyA9IG5ldyBHQyAodGhpcyk7CisJaW50IHJlc3VsdCA9IHN1cGVyLmtFdmVudENvbnRyb2xEcmF3IChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwlpZiAoY3VycmVudEdDID09IG51bGwpIHsKKwkJcGFpbnRHQy5kaXNwb3NlICgpOworCQlwYWludEdDID0gbnVsbDsKKwl9CisJcmV0dXJuIHJlc3VsdDsKK30KKworaW50IGtFdmVudE1vdXNlRG93biAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWludCByZXN1bHQgPSBzdXBlci5rRXZlbnRNb3VzZURvd24gKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCWlmIChyZXN1bHQgPT0gT1Mubm9FcnIpIHJldHVybiByZXN1bHQ7CisJLyoKKwkqIEZlYXR1cmUgaW4gdGhlIE1hY2ludG9zaC4gIEZvciBzb21lIHJlYXNvbiwgd2hlbiB0aGUgdXNlcgorCSogY2xpY2tzIG9uIHRoZSBkYXRhIGJyb3dzZXIsIGZvY3VzIGlzIGFzc2lnbmVkLCB0aGVuIGxvc3QKKwkqIGFuZCB0aGVuIHJlYXNzaWduZWQgY2F1c2luZyBrRXZlbkNvbnRyb2xTZXRGb2N1c1BhcnQgZXZlbnRzLgorCSogVGhlIGZpeCBpcyB0byBpZ25vcmUga0V2ZW5Db250cm9sU2V0Rm9jdXNQYXJ0IHdoZW4gdGhlIHVzZXIKKwkqIGNsaWNrcyBhbmQgc2VuZCB0aGUgZm9jdXMgZXZlbnRzIGZyb20ga0V2ZW50TW91c2VEb3duLgorCSovCisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlDb250cm9sIG9sZEZvY3VzID0gZGlzcGxheS5nZXRGb2N1c0NvbnRyb2wgKCk7CisJZGlzcGxheS5pZ25vcmVGb2N1cyA9IHRydWU7CisJcmVzdWx0ID0gT1MuQ2FsbE5leHRFdmVudEhhbmRsZXIgKG5leHRIYW5kbGVyLCB0aGVFdmVudCk7CisJZGlzcGxheS5pZ25vcmVGb2N1cyA9IGZhbHNlOworCWlmIChvbGRGb2N1cyAhPSB0aGlzKSB7CisJCWlmIChvbGRGb2N1cyAhPSBudWxsKSBvbGRGb2N1cy5zZW5kRm9jdXNFdmVudCAoZmFsc2UpOworCQlpZiAoaXNFbmFibGVkICgpKSBzZW5kRm9jdXNFdmVudCAodHJ1ZSk7CisJfQorCXJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQgcmVsZWFzZVdpZGdldCAoKSB7CisJZm9yIChpbnQgaT0wOyBpPGl0ZW1zLmxlbmd0aDsgaSsrKSB7CisJCVRyZWVJdGVtIGl0ZW0gPSBpdGVtcyBbaV07CisJCWlmIChpdGVtICE9IG51bGwgJiYgIWl0ZW0uaXNEaXNwb3NlZCAoKSkgeworCQkJaXRlbS5yZWxlYXNlUmVzb3VyY2VzICgpOworCQl9CisJfQorCXN1cGVyLnJlbGVhc2VXaWRnZXQgKCk7Cit9CisKK3B1YmxpYyB2b2lkIHJlbW92ZUFsbCAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKE9TLlJlbW92ZURhdGFCcm93c2VySXRlbXMgKGhhbmRsZSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtLCAwLCBudWxsLCAwKSAhPSBPUy5ub0VycikgeworCQllcnJvciAoU1dULkVSUk9SX0lURU1fTk9UX1JFTU9WRUQpOworCX0KKwlmb3IgKGludCBpPTA7IGk8aXRlbXMubGVuZ3RoOyBpKyspIHsKKwkJVHJlZUl0ZW0gaXRlbSA9IGl0ZW1zIFtpXTsKKwkJaWYgKGl0ZW0gIT0gbnVsbCAmJiAhaXRlbS5pc0Rpc3Bvc2VkICgpKSBpdGVtLnJlbGVhc2VSZXNvdXJjZXMgKCk7CisJfQorCWl0ZW1zID0gbmV3IFRyZWVJdGVtIFs0XTsKKwlhbmNob3JGaXJzdCA9IGFuY2hvckxhc3QgPSAwOworfQorCitwdWJsaWMgdm9pZCByZW1vdmVTZWxlY3Rpb25MaXN0ZW5lciAoU2VsZWN0aW9uTGlzdGVuZXIgbGlzdGVuZXIpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAobGlzdGVuZXIgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlldmVudFRhYmxlLnVuaG9vayAoU1dULlNlbGVjdGlvbiwgbGlzdGVuZXIpOworCWV2ZW50VGFibGUudW5ob29rIChTV1QuRGVmYXVsdFNlbGVjdGlvbiwgbGlzdGVuZXIpOwkKK30KKworcHVibGljIHZvaWQgcmVtb3ZlVHJlZUxpc3RlbmVyKFRyZWVMaXN0ZW5lciBsaXN0ZW5lcikgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmIChsaXN0ZW5lciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWlmIChldmVudFRhYmxlID09IG51bGwpIHJldHVybjsKKwlldmVudFRhYmxlLnVuaG9vayAoU1dULkV4cGFuZCwgbGlzdGVuZXIpOworCWV2ZW50VGFibGUudW5ob29rIChTV1QuQ29sbGFwc2UsIGxpc3RlbmVyKTsKK30KKworcHVibGljIHZvaWQgc2V0SW5zZXJ0TWFyayAoVHJlZUl0ZW0gaXRlbSwgYm9vbGVhbiBiZWZvcmUpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAoaXRlbSAhPSBudWxsKSB7CisJCWlmIChpdGVtLmlzRGlzcG9zZWQoKSkgZXJyb3IoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCX0KK30KKworcHVibGljIHZvaWQgc2VsZWN0QWxsICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAoKHN0eWxlICYgU1dULlNJTkdMRSkgIT0gMCkgcmV0dXJuOworCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIDAsIG51bGwsIE9TLmtEYXRhQnJvd3Nlckl0ZW1zQXNzaWduKTsKKwlpZ25vcmVTZWxlY3QgPSBmYWxzZTsKK30KKworcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uIChUcmVlSXRlbSBbXSBpdGVtcykgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmIChpdGVtcyA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWludFtdIGlkcyA9IG5ldyBpbnQgW2l0ZW1zLmxlbmd0aF07CisJZm9yIChpbnQgaT0wOyBpPGl0ZW1zLmxlbmd0aDsgaSsrKSB7CisJCWlmIChpdGVtcyBbaV0gPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKKwkJaWYgKGl0ZW1zIFtpXS5pc0Rpc3Bvc2VkICgpKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfQVJHVU1FTlQpOworCQlpZHMgW2ldID0gaXRlbXMgW2ldLmlkOworCQlzaG93SXRlbSAoaXRlbXMgW2ldLCBmYWxzZSk7CisJfQorCWlnbm9yZVNlbGVjdCA9IHRydWU7CisJT1MuU2V0RGF0YUJyb3dzZXJTZWxlY3RlZEl0ZW1zIChoYW5kbGUsIGlkcy5sZW5ndGgsIGlkcywgT1Mua0RhdGFCcm93c2VySXRlbXNBc3NpZ24pOworCWlnbm9yZVNlbGVjdCA9IGZhbHNlOworCWlmIChpdGVtcy5sZW5ndGggPiAwKSBzaG93SXRlbSAoaXRlbXMgWzBdLCB0cnVlKTsKK30KKworcHVibGljIHZvaWQgc2hvd0l0ZW0gKFRyZWVJdGVtIGl0ZW0pIHsKKwljaGVja1dpZGdldCAoKTsKKwlpZiAoaXRlbSA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOworCWlmIChpdGVtLmlzRGlzcG9zZWQgKCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CisJc2hvd0l0ZW0gKGl0ZW0sIHRydWUpOworfQorCit2b2lkIHNob3dJdGVtIChUcmVlSXRlbSBpdGVtLCBib29sZWFuIHNjcm9sbCkgeworCWludCBjb3VudCA9IDA7CisJVHJlZUl0ZW0gcGFyZW50SXRlbSA9IGl0ZW0ucGFyZW50SXRlbTsKKwl3aGlsZSAocGFyZW50SXRlbSAhPSBudWxsICYmICFwYXJlbnRJdGVtLmdldEV4cGFuZGVkICgpKSB7CisJCWNvdW50Kys7CisJCXBhcmVudEl0ZW0gPSBwYXJlbnRJdGVtLnBhcmVudEl0ZW07CisJfQorCWludCBpbmRleCA9IDA7CisJcGFyZW50SXRlbSA9IGl0ZW0ucGFyZW50SXRlbTsKKwlUcmVlSXRlbSBbXSBwYXRoID0gbmV3IFRyZWVJdGVtIFtjb3VudF07CisJd2hpbGUgKHBhcmVudEl0ZW0gIT0gbnVsbCAmJiAhcGFyZW50SXRlbS5nZXRFeHBhbmRlZCAoKSkgeworCQlwYXRoIFtpbmRleCsrXSA9IHBhcmVudEl0ZW07CisJCXBhcmVudEl0ZW0gPSBwYXJlbnRJdGVtLnBhcmVudEl0ZW07CisJfQorCWZvciAoaW50IGk9cGF0aC5sZW5ndGgtMTsgaT49MDsgLS1pKSB7CisJCXBhdGggW2ldLnNldEV4cGFuZGVkICh0cnVlKTsKKwl9CisvLwlpZiAoc2Nyb2xsKSB7CisvLwkJc2hvcnQgW10gd2lkdGggPSBuZXcgc2hvcnQgWzFdOworLy8JCU9TLkdldERhdGFCcm93c2VyVGFibGVWaWV3TmFtZWRDb2x1bW5XaWR0aCAoaGFuZGxlLCBDT0xVTU5fSUQsIHdpZHRoKTsKKy8vCQlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKSwgaW5zZXQgPSBuZXcgUmVjdCAoKTsKKy8vCQlPUy5HZXRDb250cm9sQm91bmRzIChoYW5kbGUsIHJlY3QpOworLy8JCU9TLkdldERhdGFCcm93c2VyU2Nyb2xsQmFySW5zZXQgKGhhbmRsZSwgaW5zZXQpOworLy8JCU9TLlNldERhdGFCcm93c2VyVGFibGVWaWV3TmFtZWRDb2x1bW5XaWR0aCAoaGFuZGxlLCBDT0xVTU5fSUQsIChzaG9ydCkocmVjdC5yaWdodCAtIHJlY3QubGVmdCAtIGluc2V0LmxlZnQgLSBpbnNldC5yaWdodCkpOworLy8JCU9TLlJldmVhbERhdGFCcm93c2VySXRlbSAoaGFuZGxlLCBpdGVtLmlkLCBDT0xVTU5fSUQsIChieXRlKSBPUy5rRGF0YUJyb3dzZXJSZXZlYWxXaXRob3V0U2VsZWN0aW5nKTsKKy8vCQlPUy5TZXREYXRhQnJvd3NlclRhYmxlVmlld05hbWVkQ29sdW1uV2lkdGggKGhhbmRsZSwgQ09MVU1OX0lELCAoc2hvcnQpd2lkdGggWzBdKTsKKy8vCX0KKwlpZiAoc2Nyb2xsKSB7CisJCVJlY3RhbmdsZSB0cmVlUmVjdCA9IGdldENsaWVudEFyZWEgKCk7CisJCVJlY3RhbmdsZSBpdGVtUmVjdCA9IGl0ZW0uZ2V0Qm91bmRzICgpOworCQlpZiAodHJlZVJlY3QuY29udGFpbnMgKGl0ZW1SZWN0LngsIGl0ZW1SZWN0LnkpKSByZXR1cm47CisJCU9TLlJldmVhbERhdGFCcm93c2VySXRlbSAoaGFuZGxlLCBpdGVtLmlkLCBDT0xVTU5fSUQsIChieXRlKSBPUy5rRGF0YUJyb3dzZXJSZXZlYWxXaXRob3V0U2VsZWN0aW5nKTsKKwkJaW50IFtdIHRvcCA9IG5ldyBpbnQgWzFdLCBsZWZ0ID0gbmV3IGludCBbMV07CisJCU9TLkdldERhdGFCcm93c2VyU2Nyb2xsUG9zaXRpb24gKGhhbmRsZSwgdG9wLCBsZWZ0KTsKKwkJT1MuU2V0RGF0YUJyb3dzZXJTY3JvbGxQb3NpdGlvbiAoaGFuZGxlLCB0b3AgWzBdLCAwKTsKKwkJaXRlbVJlY3QgPSBpdGVtLmdldEJvdW5kcyAoKTsKKwkJaWYgKCF0cmVlUmVjdC5jb250YWlucyAoaXRlbVJlY3QueCwgaXRlbVJlY3QueSkpIHsKKwkJCU9TLlJldmVhbERhdGFCcm93c2VySXRlbSAoaGFuZGxlLCBpdGVtLmlkLCBDT0xVTU5fSUQsIChieXRlKSBPUy5rRGF0YUJyb3dzZXJSZXZlYWxXaXRob3V0U2VsZWN0aW5nKTsKKwkJfQorCX0KK30KKworcHVibGljIHZvaWQgc2hvd1NlbGVjdGlvbiAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJLy9PUFRJTUlaRQorCVRyZWVJdGVtIFtdIHNlbGVjdGlvbiA9IGdldFNlbGVjdGlvbiAoKTsKKwlpZiAoc2VsZWN0aW9uLmxlbmd0aCA+IDApIHNob3dJdGVtIChzZWxlY3Rpb24gWzBdLCB0cnVlKTsKK30KKworaW50IHRyYWNraW5nUHJvYyAoaW50IGJyb3dzZXIsIGludCBpZCwgaW50IHByb3BlcnR5LCBpbnQgdGhlUmVjdCwgaW50IHN0YXJ0UHQsIGludCBtb2RpZmllcnMpIHsKKy8vCWludCBpbmRleCA9IGlkIC0gMTsKKy8vCWlmICghKDAgPD0gaW5kZXggJiYgaW5kZXggPCBpdGVtcy5sZW5ndGgpKSByZXR1cm4gMDsKKy8vCVRyZWVJdGVtIGl0ZW0gPSBpdGVtcyBbaW5kZXhdOworCXJldHVybiAxOworfQorCit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVHJlZUl0ZW0uamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9UcmVlSXRlbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4OWNiOTEKLS0tIC9kZXYvbnVsbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvVHJlZUl0ZW0uamF2YQpAQCAtMCwwICsxLDIxMSBAQAorcGFja2FnZSBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0czsKKworLyoKKyAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwMiBJQk0gQ29ycC4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBUaGlzIGZpbGUgaXMgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAorICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKKyAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCisgKi8KKworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uT1M7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5SZWN0OworCitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0Lio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLio7CisKK3B1YmxpYyBjbGFzcyBUcmVlSXRlbSBleHRlbmRzIEl0ZW0geworCVRyZWUgcGFyZW50OworCVRyZWVJdGVtIHBhcmVudEl0ZW07CisJaW50IGlkLCBpbmRleCA9IC0xOworCWJvb2xlYW4gY2hlY2tlZDsKKwlDb2xvciBmb3JlZ3JvdW5kLCBiYWNrZ3JvdW5kOworCitwdWJsaWMgVHJlZUl0ZW0gKFRyZWUgcGFyZW50LCBpbnQgc3R5bGUpIHsKKwlzdXBlciAocGFyZW50LCBzdHlsZSk7CisJdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CisJcGFyZW50LmNyZWF0ZUl0ZW0gKHRoaXMsIG51bGwsIC0xKTsKK30KKworcHVibGljIFRyZWVJdGVtIChUcmVlIHBhcmVudCwgaW50IHN0eWxlLCBpbnQgaW5kZXgpIHsKKwlzdXBlciAocGFyZW50LCBzdHlsZSk7CisJaWYgKGluZGV4IDwgMCkgZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX1JBTkdFKTsKKwl0aGlzLnBhcmVudCA9IHBhcmVudDsKKwlwYXJlbnQuY3JlYXRlSXRlbSAodGhpcywgbnVsbCwgaW5kZXgpOworfQorCitwdWJsaWMgVHJlZUl0ZW0gKFRyZWVJdGVtIHBhcmVudEl0ZW0sIGludCBzdHlsZSkgeworCXN1cGVyIChjaGVja051bGwgKHBhcmVudEl0ZW0pLnBhcmVudCwgc3R5bGUpOworCXBhcmVudCA9IHBhcmVudEl0ZW0ucGFyZW50OworCXRoaXMucGFyZW50SXRlbSA9IHBhcmVudEl0ZW07CisJcGFyZW50LmNyZWF0ZUl0ZW0gKHRoaXMsIHBhcmVudEl0ZW0sIC0xKTsKK30KKworcHVibGljIFRyZWVJdGVtIChUcmVlSXRlbSBwYXJlbnRJdGVtLCBpbnQgc3R5bGUsIGludCBpbmRleCkgeworCXN1cGVyIChjaGVja051bGwgKHBhcmVudEl0ZW0pLnBhcmVudCwgc3R5bGUpOworCWlmIChpbmRleCA8IDApIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9SQU5HRSk7CisJcGFyZW50ID0gcGFyZW50SXRlbS5wYXJlbnQ7CisJdGhpcy5wYXJlbnRJdGVtID0gcGFyZW50SXRlbTsKKwlwYXJlbnQuY3JlYXRlSXRlbSAodGhpcywgcGFyZW50SXRlbSwgaW5kZXgpOworfQorCitzdGF0aWMgVHJlZUl0ZW0gY2hlY2tOdWxsIChUcmVlSXRlbSBpdGVtKSB7CisJaWYgKGl0ZW0gPT0gbnVsbCkgU1dULmVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CisJcmV0dXJuIGl0ZW07Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNoZWNrU3ViY2xhc3MgKCkgeworCWlmICghaXNWYWxpZFN1YmNsYXNzICgpKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MpOworfQorCitwdWJsaWMgQ29sb3IgZ2V0QmFja2dyb3VuZCAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJcmV0dXJuIGJhY2tncm91bmQgIT0gbnVsbCA/IGJhY2tncm91bmQgOiBnZXREaXNwbGF5ICgpLmdldFN5c3RlbUNvbG9yIChTV1QuQ09MT1JfTElTVF9CQUNLR1JPVU5EKTsKK30KKworcHVibGljIFJlY3RhbmdsZSBnZXRCb3VuZHMgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCVJlY3QgcmVjdCA9IG5ldyBSZWN0KCk7CisJT1MuR2V0RGF0YUJyb3dzZXJJdGVtUGFydEJvdW5kcyAocGFyZW50LmhhbmRsZSwgaWQsIFRyZWUuQ09MVU1OX0lELCBPUy5rRGF0YUJyb3dzZXJQcm9wZXJ0eUVuY2xvc2luZ1BhcnQsIHJlY3QpOworCWludCB4ID0gcmVjdC5sZWZ0LCB5ID0gcmVjdC50b3A7CisJaW50IHdpZHRoID0gMDsKKwlpZiAoaW1hZ2UgIT0gbnVsbCkgeworCQlSZWN0YW5nbGUgYm91bmRzID0gaW1hZ2UuZ2V0Qm91bmRzICgpOworCQl3aWR0aCArPSBib3VuZHMud2lkdGggKyAyOworCX0KKwlHQyBnYyA9IG5ldyBHQyAocGFyZW50KTsKKwlQb2ludCBleHRlbnQgPSBnYy5zdHJpbmdFeHRlbnQgKHRleHQpOworCWdjLmRpc3Bvc2UgKCk7CisJd2lkdGggKz0gZXh0ZW50Lng7CisJaW50IGhlaWdodCA9IHJlY3QuYm90dG9tIC0gcmVjdC50b3A7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAocGFyZW50LmhhbmRsZSwgcmVjdCk7CisJeCAtPSByZWN0LmxlZnQ7CisJeSAtPSByZWN0LnRvcDsKKwlyZXR1cm4gbmV3IFJlY3RhbmdsZSAoeCwgeSwgd2lkdGgsIGhlaWdodCk7Cit9CisKK3B1YmxpYyBib29sZWFuIGdldENoZWNrZWQgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmICgocGFyZW50LnN0eWxlICYgU1dULkNIRUNLKSA9PSAwKSByZXR1cm4gZmFsc2U7CisJcmV0dXJuIGNoZWNrZWQ7Cit9CisKK3B1YmxpYyBEaXNwbGF5IGdldERpc3BsYXkgKCkgeworCVRyZWUgcGFyZW50ID0gdGhpcy5wYXJlbnQ7CisJaWYgKHBhcmVudCA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX1dJREdFVF9ESVNQT1NFRCk7CisJcmV0dXJuIHBhcmVudC5nZXREaXNwbGF5ICgpOworfQorCitwdWJsaWMgYm9vbGVhbiBnZXRFeHBhbmRlZCAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaW50IFtdIHN0YXRlID0gbmV3IGludCBbMV07CisJT1MuR2V0RGF0YUJyb3dzZXJJdGVtU3RhdGUgKHBhcmVudC5oYW5kbGUsIGlkLCBzdGF0ZSk7CisJcmV0dXJuIChzdGF0ZSBbMF0gJiBPUy5rRGF0YUJyb3dzZXJDb250YWluZXJJc09wZW4pICE9IDA7Cit9CisKK3B1YmxpYyBDb2xvciBnZXRGb3JlZ3JvdW5kICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlyZXR1cm4gZm9yZWdyb3VuZCAhPSBudWxsID8gZm9yZWdyb3VuZCA6IGdldERpc3BsYXkgKCkuZ2V0U3lzdGVtQ29sb3IgKFNXVC5DT0xPUl9MSVNUX0ZPUkVHUk9VTkQpOworfQorCitwdWJsaWMgYm9vbGVhbiBnZXRHcmF5ZWQgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmICgocGFyZW50LnN0eWxlICYgU1dULkNIRUNLKSA9PSAwKSByZXR1cm4gZmFsc2U7CisJLy9OT1QgRE9ORQorCXJldHVybiBmYWxzZTsKK30KKworcHVibGljIGludCBnZXRJdGVtQ291bnQgKCkgeworCWNoZWNrV2lkZ2V0ICgpOworCXJldHVybiBwYXJlbnQuZ2V0SXRlbUNvdW50ICh0aGlzKTsKK30KKworcHVibGljIFRyZWVJdGVtIFtdIGdldEl0ZW1zICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlyZXR1cm4gcGFyZW50LmdldEl0ZW1zICh0aGlzKTsKK30KKworcHVibGljIFRyZWUgZ2V0UGFyZW50ICgpIHsKKwljaGVja1dpZGdldCAoKTsKKwlyZXR1cm4gcGFyZW50OworfQorCitwdWJsaWMgVHJlZUl0ZW0gZ2V0UGFyZW50SXRlbSAoKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJcmV0dXJuIHBhcmVudEl0ZW07Cit9CisKK3ZvaWQgcmVsZWFzZUNoaWxkICgpIHsKKwlzdXBlci5yZWxlYXNlQ2hpbGQgKCk7CisJcGFyZW50LmRlc3Ryb3lJdGVtICh0aGlzKTsKK30KKwordm9pZCByZWxlYXNlV2lkZ2V0ICgpIHsKKwlzdXBlci5yZWxlYXNlV2lkZ2V0ICgpOworCXBhcmVudEl0ZW0gPSBudWxsOworCXBhcmVudCA9IG51bGw7CisJaWQgPSAwOworCWluZGV4ID0gLTE7Cit9CisKK3B1YmxpYyB2b2lkIHNldEJhY2tncm91bmQgKENvbG9yIGNvbG9yKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKGNvbG9yICE9IG51bGwgJiYgY29sb3IuaXNEaXNwb3NlZCAoKSkgeworCQlTV1QuZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKKwl9CisJYmFja2dyb3VuZCA9IGNvbG9yOworCXJlZHJhdyAoKTsKK30KKworcHVibGljIHZvaWQgc2V0Q2hlY2tlZCAoYm9vbGVhbiBjaGVja2VkKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKChwYXJlbnQuc3R5bGUgJiBTV1QuQ0hFQ0spID09IDApIHJldHVybjsKKwl0aGlzLmNoZWNrZWQgPSBjaGVja2VkOworCXJlZHJhdyAoKTsKK30KKworcHVibGljIHZvaWQgc2V0RXhwYW5kZWQgKGJvb2xlYW4gZXhwYW5kZWQpIHsKKwljaGVja1dpZGdldCAoKTsKKwlwYXJlbnQuaWdub3JlRXhwYW5kID0gdHJ1ZTsKKwlpZiAoZXhwYW5kZWQpIHsKKwkJT1MuT3BlbkRhdGFCcm93c2VyQ29udGFpbmVyIChwYXJlbnQuaGFuZGxlLCBpZCk7CisJfSBlbHNlIHsKKwkJT1MuQ2xvc2VEYXRhQnJvd3NlckNvbnRhaW5lciAocGFyZW50LmhhbmRsZSwgaWQpOworCX0KKwlwYXJlbnQuaWdub3JlRXhwYW5kID0gZmFsc2U7Cit9CisKK3B1YmxpYyB2b2lkIHNldEZvcmVncm91bmQgKENvbG9yIGNvbG9yKSB7CisJY2hlY2tXaWRnZXQgKCk7CisJaWYgKGNvbG9yICE9IG51bGwgJiYgY29sb3IuaXNEaXNwb3NlZCAoKSkgeworCQlTV1QuZXJyb3IgKFNXVC5FUlJPUl9JTlZBTElEX0FSR1VNRU5UKTsKKwl9CisJZm9yZWdyb3VuZCA9IGNvbG9yOworCXJlZHJhdyAoKTsKK30KKworcHVibGljIHZvaWQgc2V0R3JheWVkIChib29sZWFuIGdyYXllZCkgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmICgocGFyZW50LnN0eWxlICYgU1dULkNIRUNLKSA9PSAwKSByZXR1cm47CisJLy9OT1QgRE9ORQorfQorCitwdWJsaWMgdm9pZCBzZXRJbWFnZSAoSW1hZ2UgaW1hZ2UpIHsKKwljaGVja1dpZGdldCAoKTsKKwlzdXBlci5zZXRJbWFnZSAoaW1hZ2UpOworCXJlZHJhdyAoKTsKK30KKworcHVibGljIHZvaWQgc2V0VGV4dCAoU3RyaW5nIHN0cmluZykgeworCWNoZWNrV2lkZ2V0ICgpOworCWlmIChzdHJpbmcgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKKwlzdXBlci5zZXRUZXh0IChzdHJpbmcpOworCXJlZHJhdyAoKTsKK30KKwordm9pZCByZWRyYXcgKCkgeworCWludCBwYXJlbnRJRCA9IHBhcmVudEl0ZW0gPT0gbnVsbCA/IE9TLmtEYXRhQnJvd3Nlck5vSXRlbSA6IHBhcmVudEl0ZW0uaWQ7CisJT1MuVXBkYXRlRGF0YUJyb3dzZXJJdGVtcyAocGFyZW50LmhhbmRsZSwgcGFyZW50SUQsIDEsIG5ldyBpbnRbXSB7aWR9LCBPUy5rRGF0YUJyb3dzZXJJdGVtTm9Qcm9wZXJ0eSwgT1Mua0RhdGFCcm93c2VyTm9JdGVtKTsKKworfQorCit9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvV2lkZ2V0LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvV2lkZ2V0LmphdmEKaW5kZXggZDk0NGY1My4uMzVkYzkwYSAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1dpZGdldC5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2Uuc3d0L0VjbGlwc2UgU1dUL2NhcmJvbi9vcmcvZWNsaXBzZS9zd3Qvd2lkZ2V0cy9XaWRnZXQuamF2YQpAQCAtOCwzOSArOCwxNyBAQAogICovCiAKIGltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CitpbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmludGVybmFsLmNhcmJvbi5PUzsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlJHQkNvbG9yOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uUmVjdDsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLlBpeE1hcDsKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLkJpdE1hcDsKKwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC4qOworaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy4qOwogaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuKjsKIAotLyoqCi0gKiBUaGlzIGNsYXNzIGlzIHRoZSBhYnN0cmFjdCBzdXBlcmNsYXNzIG9mIGFsbCB1c2VyIGludGVyZmFjZSBvYmplY3RzLiAgCi0gKiBXaWRnZXRzIGFyZSBjcmVhdGVkLCBkaXNwb3NlZCBhbmQgaXNzdWUgbm90aWZpY2F0aW9uIHRvIGxpc3RlbmVycwotICogd2hlbiBldmVudHMgb2NjdXIgd2hpY2ggYWZmZWN0IHRoZW0uCi0gKiA8ZGw+Ci0gKiA8ZHQ+PGI+U3R5bGVzOjwvYj48L2R0PgotICogPGRkPihub25lKTwvZGQ+Ci0gKiA8ZHQ+PGI+RXZlbnRzOjwvYj48L2R0PgotICogPGRkPkRpc3Bvc2U8L2RkPgotICogPC9kbD4KLSAqIDxwPgotICogSU1QT1JUQU5UOiBUaGlzIGNsYXNzIGlzIGludGVuZGVkIHRvIGJlIHN1YmNsYXNzZWQgPGVtPm9ubHk8L2VtPgotICogd2l0aGluIHRoZSBTV1QgaW1wbGVtZW50YXRpb24uIEhvd2V2ZXIsIGl0IGhhcyBub3QgYmVlbiBtYXJrZWQKLSAqIGZpbmFsIHRvIGFsbG93IHRob3NlIG91dHNpZGUgb2YgdGhlIFNXVCBkZXZlbG9wbWVudCB0ZWFtIHRvIGltcGxlbWVudAotICogcGF0Y2hlZCB2ZXJzaW9ucyBvZiB0aGUgY2xhc3MgaW4gb3JkZXIgdG8gZ2V0IGFyb3VuZCBzcGVjaWZpYwotICogbGltaXRhdGlvbnMgaW4gYWR2YW5jZSBvZiB3aGVuIHRob3NlIGxpbWl0YXRpb25zIGNhbiBiZSBhZGRyZXNzZWQKLSAqIGJ5IHRoZSB0ZWFtLiAgQW55IGNsYXNzIGJ1aWx0IHVzaW5nIHN1YmNsYXNzaW5nIHRvIGFjY2VzcyB0aGUgaW50ZXJuYWxzCi0gKiBvZiB0aGlzIGNsYXNzIHdpbGwgbGlrZWx5IGZhaWwgdG8gY29tcGlsZSBvciBydW4gYmV0d2VlbiByZWxlYXNlcyBhbmQKLSAqIG1heSBiZSBzdHJvbmdseSBwbGF0Zm9ybSBzcGVjaWZpYy4gU3ViY2xhc3Npbmcgc2hvdWxkIG5vdCBiZSBhdHRlbXB0ZWQKLSAqIHdpdGhvdXQgYW4gaW50aW1hdGUgYW5kIGRldGFpbGVkIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHdvcmtpbmdzIG9mIHRoZQotICogaGllcmFyY2h5LiBObyBzdXBwb3J0IGlzIHByb3ZpZGVkIGZvciB1c2VyLXdyaXR0ZW4gY2xhc3NlcyB3aGljaCBhcmUKLSAqIGltcGxlbWVudGVkIGFzIHN1YmNsYXNzZXMgb2YgdGhpcyBjbGFzcy4KLSAqIDwvcD4KLSAqCi0gKiBAc2VlICNjaGVja1N1YmNsYXNzCi0gKi8KIHB1YmxpYyBhYnN0cmFjdCBjbGFzcyBXaWRnZXQgewotCi0JcHVibGljIGludCBoYW5kbGU7CiAJaW50IHN0eWxlLCBzdGF0ZTsKIAlFdmVudFRhYmxlIGV2ZW50VGFibGU7CiAJT2JqZWN0IGRhdGE7CkBAIC00OCwxMTMgKzI2LDU2IEBACiAJT2JqZWN0IFtdIHZhbHVlczsKIAogCS8qIEdsb2JhbCBzdGF0ZSBmbGFncyAqLwotLy8Jc3RhdGljIGZpbmFsIGludCBBVVRPTUFUSUMJCT0gMHgwMDAwMDAwMTsKLS8vCXN0YXRpYyBmaW5hbCBpbnQgQUNUSVZFCQkJPSAweDAwMDAwMDAyOwotLy8Jc3RhdGljIGZpbmFsIGludCBBVVRPR1JBQgkJPSAweDAwMDAwMDA0OwotLy8Jc3RhdGljIGZpbmFsIGludCBNVUxUSUVYUE9TRQk9IDB4MDAwMDAwMDg7Ci0vLwlzdGF0aWMgZmluYWwgaW50IFJFU0laRVJFRFJBVwk9IDB4MDAwMDAwMTA7Ci0vLwlzdGF0aWMgZmluYWwgaW50IFdSQVAJCQk9IDB4MDAwMDAwMjA7Ci0vLwlzdGF0aWMgZmluYWwgaW50IERJU0FCTEVECQk9IDB4MDAwMDAwNDA7Ci0Jc3RhdGljIGZpbmFsIGludCBISURERU4JCQk9IDB4MDAwMDAwODA7Ci0vLwlzdGF0aWMgZmluYWwgaW50IEZPUkVHUk9VTkQJCT0gMHgwMDAwMDEwMDsKLS8vCXN0YXRpYyBmaW5hbCBpbnQgQkFDS0dST1VORAkJPSAweDAwMDAwMjAwOwotCXN0YXRpYyBmaW5hbCBpbnQgRElTUE9TRUQJCT0gMHgwMDAwMDQwMDsKLQlzdGF0aWMgZmluYWwgaW50IEhBTkRMRQkJCT0gMHgwMDAwMDgwMDsKLQlzdGF0aWMgZmluYWwgaW50IENBTlZBUwkJCT0gMHgwMDAwMTAwMDsKKy8vCXN0YXRpYyBmaW5hbCBpbnQgQVVUT01BVElDCQk9IDEgPDwgMDsKKy8vCXN0YXRpYyBmaW5hbCBpbnQgQUNUSVZFCQkJPSAxIDw8IDE7CisJc3RhdGljIGZpbmFsIGludCBHUkFCCQk9IDEgPDwgMjsKKy8vCXN0YXRpYyBmaW5hbCBpbnQgTVVMVElFWFBPU0UJPSAxIDw8IDM7CisvLwlzdGF0aWMgZmluYWwgaW50IFJFU0laRVJFRFJBVwk9IDEgPDwgNDsKKy8vCXN0YXRpYyBmaW5hbCBpbnQgV1JBUAkJCT0gMSA8PCA1OworCXN0YXRpYyBmaW5hbCBpbnQgRElTQUJMRUQJPSAxIDw8IDY7CisJc3RhdGljIGZpbmFsIGludCBISURERU4JCT0gMSA8PCA3OworLy8Jc3RhdGljIGZpbmFsIGludCBGT1JFR1JPVU5ECQk9IDEgPDwgODsKKy8vCXN0YXRpYyBmaW5hbCBpbnQgQkFDS0dST1VORAkJPSAxIDw8IDk7CisJc3RhdGljIGZpbmFsIGludCBESVNQT1NFRAk9IDEgPDwgMTA7CisvLwlzdGF0aWMgZmluYWwgaW50IEhBTkRMRQkJPSAxIDw8IDExOworCXN0YXRpYyBmaW5hbCBpbnQgQ0FOVkFTCQk9IDEgPDwgMTI7CisJc3RhdGljIGZpbmFsIGludCBNT1ZFRAkJPSAxIDw8IDEzOworCXN0YXRpYyBmaW5hbCBpbnQgUkVTSVpFRAk9IDEgPDwgMTQ7CiAKIAlzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfV0lEVEgJPSA2NDsKIAlzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfSEVJR0hUCT0gNjQ7Ci0KLQkvKiBHbG9iYWwgd2lkZ2V0IHZhcmlhYmxlcyAqLwogCXN0YXRpYyBmaW5hbCBjaGFyIE1uZW1vbmljID0gJyYnOworCQorCXN0YXRpYyBmaW5hbCBSZWN0IEVNUFRZX1JFQ1QgPSBuZXcgUmVjdCAoKTsKIAogV2lkZ2V0ICgpIHsKIAkvKiBEbyBub3RoaW5nICovCiB9Ci0vKioKLSAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBnaXZlbiBpdHMgcGFyZW50Ci0gKiBhbmQgYSBzdHlsZSB2YWx1ZSBkZXNjcmliaW5nIGl0cyBiZWhhdmlvciBhbmQgYXBwZWFyYW5jZS4KLSAqIDxwPgotICogVGhlIHN0eWxlIHZhbHVlIGlzIGVpdGhlciBvbmUgb2YgdGhlIHN0eWxlIGNvbnN0YW50cyBkZWZpbmVkIGluCi0gKiBjbGFzcyA8Y29kZT5TV1Q8L2NvZGU+IHdoaWNoIGlzIGFwcGxpY2FibGUgdG8gaW5zdGFuY2VzIG9mIHRoaXMKLSAqIGNsYXNzLCBvciBtdXN0IGJlIGJ1aWx0IGJ5IDxlbT5iaXR3aXNlIE9SPC9lbT4naW5nIHRvZ2V0aGVyIAotICogKHRoYXQgaXMsIHVzaW5nIHRoZSA8Y29kZT5pbnQ8L2NvZGU+ICJ8IiBvcGVyYXRvcikgdHdvIG9yIG1vcmUKLSAqIG9mIHRob3NlIDxjb2RlPlNXVDwvY29kZT4gc3R5bGUgY29uc3RhbnRzLiBUaGUgY2xhc3MgZGVzY3JpcHRpb24KLSAqIGxpc3RzIHRoZSBzdHlsZSBjb25zdGFudHMgdGhhdCBhcmUgYXBwbGljYWJsZSB0byB0aGUgY2xhc3MuCi0gKiBTdHlsZSBiaXRzIGFyZSBhbHNvIGluaGVyaXRlZCBmcm9tIHN1cGVyY2xhc3Nlcy4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gcGFyZW50IGEgd2lkZ2V0IHdoaWNoIHdpbGwgYmUgdGhlIHBhcmVudCBvZiB0aGUgbmV3IGluc3RhbmNlIChjYW5ub3QgYmUgbnVsbCkKLSAqIEBwYXJhbSBzdHlsZSB0aGUgc3R5bGUgb2Ygd2lkZ2V0IHRvIGNvbnN0cnVjdAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIHBhcmVudCBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSBwYXJlbnQ8L2xpPgotICogICAgPGxpPkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MgLSBpZiB0aGlzIGNsYXNzIGlzIG5vdCBhbiBhbGxvd2VkIHN1YmNsYXNzPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBTV1QKLSAqIEBzZWUgI2NoZWNrU3ViY2xhc3MKLSAqIEBzZWUgI2dldFN0eWxlCi0gKi8KKwogcHVibGljIFdpZGdldCAoV2lkZ2V0IHBhcmVudCwgaW50IHN0eWxlKSB7Ci0JaWYgKHBhcmVudCA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwotCWlmICghcGFyZW50LmlzVmFsaWRUaHJlYWQgKCkpIGVycm9yIChTV1QuRVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTKTsKKwljaGVja1N1YmNsYXNzICgpOworCWNoZWNrUGFyZW50IChwYXJlbnQpOwogCXRoaXMuc3R5bGUgPSBzdHlsZTsKIH0KLS8qKgotICogQWRkcyB0aGUgbGlzdGVuZXIgdG8gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmVkIHdoZW4gYW4gZXZlbnQgb2YgdGhlIGdpdmVuIHR5cGUgb2NjdXJzLiBXaGVuIHRoZQotICogZXZlbnQgZG9lcyBvY2N1ciBpbiB0aGUgd2lkZ2V0LCB0aGUgbGlzdGVuZXIgaXMgbm90aWZpZWQgYnkKLSAqIHNlbmRpbmcgaXQgdGhlIDxjb2RlPmhhbmRsZUV2ZW50KCk8L2NvZGU+IG1lc3NhZ2UuCi0gKgotICogQHBhcmFtIGV2ZW50VHlwZSB0aGUgdHlwZSBvZiBldmVudCB0byBsaXN0ZW4gZm9yCi0gKiBAcGFyYW0gbGlzdGVuZXIgdGhlIGxpc3RlbmVyIHdoaWNoIHNob3VsZCBiZSBub3RpZmllZCB3aGVuIHRoZSBldmVudCBvY2N1cnMKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBsaXN0ZW5lciBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSBMaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlTGlzdGVuZXIKLSAqLworCitpbnQgYWN0aW9uUHJvYyAoaW50IHRoZUNvbnRyb2wsIGludCBwYXJ0Q29kZSkgeworCXJldHVybiBPUy5ub0VycjsKK30KKwogcHVibGljIHZvaWQgYWRkTGlzdGVuZXIgKGludCBldmVudFR5cGUsIExpc3RlbmVyIGhhbmRsZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChoYW5kbGVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaWYgKGV2ZW50VGFibGUgPT0gbnVsbCkgZXZlbnRUYWJsZSA9IG5ldyBFdmVudFRhYmxlICgpOwogCWV2ZW50VGFibGUuaG9vayAoZXZlbnRUeXBlLCBoYW5kbGVyKTsKIH0KLS8qKgotICogQWRkcyB0aGUgbGlzdGVuZXIgdG8gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmVkIHdoZW4gdGhlIHdpZGdldCBpcyBkaXNwb3NlZC4gV2hlbiB0aGUgd2lkZ2V0IGlzCi0gKiBkaXNwb3NlZCwgdGhlIGxpc3RlbmVyIGlzIG5vdGlmaWVkIGJ5IHNlbmRpbmcgaXQgdGhlCi0gKiA8Y29kZT53aWRnZXREaXNwb3NlZCgpPC9jb2RlPiBtZXNzYWdlLgotICoKLSAqIEBwYXJhbSBsaXN0ZW5lciB0aGUgbGlzdGVuZXIgd2hpY2ggc2hvdWxkIGJlIG5vdGlmaWVkIHdoZW4gdGhlIHJlY2VpdmVyIGlzIGRpc3Bvc2VkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgRGlzcG9zZUxpc3RlbmVyCi0gKiBAc2VlICNyZW1vdmVEaXNwb3NlTGlzdGVuZXIKLSAqLworCiBwdWJsaWMgdm9pZCBhZGREaXNwb3NlTGlzdGVuZXIgKERpc3Bvc2VMaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJVHlwZWRMaXN0ZW5lciB0eXBlZExpc3RlbmVyID0gbmV3IFR5cGVkTGlzdGVuZXIgKGxpc3RlbmVyKTsKIAlhZGRMaXN0ZW5lciAoU1dULkRpc3Bvc2UsIHR5cGVkTGlzdGVuZXIpOwogfQorCiBzdGF0aWMgaW50IGNoZWNrQml0cyAoaW50IHN0eWxlLCBpbnQgaW50MCwgaW50IGludDEsIGludCBpbnQyLCBpbnQgaW50MywgaW50IGludDQsIGludCBpbnQ1KSB7CiAJaW50IG1hc2sgPSBpbnQwIHwgaW50MSB8IGludDIgfCBpbnQzIHwgaW50NCB8IGludDU7CiAJaWYgKChzdHlsZSAmIG1hc2spID09IDApIHN0eWxlIHw9IGludDA7CkBAIC0xNjYsMTE4ICs4NywxNjUgQEAKIAlpZiAoKHN0eWxlICYgaW50NSkgIT0gMCkgc3R5bGUgPSAoc3R5bGUgJiB+bWFzaykgfCBpbnQ1OwogCXJldHVybiBzdHlsZTsKIH0KKwogdm9pZCBjaGVja1BhcmVudCAoV2lkZ2V0IHBhcmVudCkgewogCWlmIChwYXJlbnQgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKIAlpZiAoIXBhcmVudC5pc1ZhbGlkVGhyZWFkICgpKSBlcnJvciAoU1dULkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyk7CiAJaWYgKHBhcmVudC5pc0Rpc3Bvc2VkKCkpIGVycm9yIChTV1QuRVJST1JfSU5WQUxJRF9BUkdVTUVOVCk7CiB9Ci0vKioKLSAqIENoZWNrcyB0aGF0IHRoaXMgY2xhc3MgY2FuIGJlIHN1YmNsYXNzZWQuCi0gKiA8cD4KLSAqIFRoZSBTV1QgY2xhc3MgbGlicmFyeSBpcyBpbnRlbmRlZCB0byBiZSBzdWJjbGFzc2VkIAotICogb25seSBhdCBzcGVjaWZpYywgY29udHJvbGxlZCBwb2ludHMgKG1vc3Qgbm90YWJseSwgCi0gKiA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IGFuZCA8Y29kZT5DYW52YXM8L2NvZGU+IHdoZW4KLSAqIGltcGxlbWVudGluZyBuZXcgd2lkZ2V0cykuIFRoaXMgbWV0aG9kIGVuZm9yY2VzIHRoaXMKLSAqIHJ1bGUgdW5sZXNzIGl0IGlzIG92ZXJyaWRkZW4uCi0gKiA8L3A+PHA+Ci0gKiA8ZW0+SU1QT1JUQU5UOjwvZW0+IEJ5IHByb3ZpZGluZyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzCi0gKiBtZXRob2QgdGhhdCBhbGxvd3MgYSBzdWJjbGFzcyBvZiBhIGNsYXNzIHdoaWNoIGRvZXMgbm90IAotICogbm9ybWFsbHkgYWxsb3cgc3ViY2xhc3NpbmcgdG8gYmUgY3JlYXRlZCwgdGhlIGltcGxlbWVudGVyCi0gKiBhZ3JlZXMgdG8gYmUgZnVsbHkgcmVzcG9uc2libGUgZm9yIHRoZSBmYWN0IHRoYXQgYW55IHN1Y2gKLSAqIHN1YmNsYXNzIHdpbGwgbGlrZWx5IGZhaWwgYmV0d2VlbiBTV1QgcmVsZWFzZXMgYW5kIHdpbGwgYmUKLSAqIHN0cm9uZ2x5IHBsYXRmb3JtIHNwZWNpZmljLiBObyBzdXBwb3J0IGlzIHByb3ZpZGVkIGZvcgotICogdXNlci13cml0dGVuIGNsYXNzZXMgd2hpY2ggYXJlIGltcGxlbWVudGVkIGluIHRoaXMgZmFzaGlvbi4KLSAqIDwvcD48cD4KLSAqIFRoZSBhYmlsaXR5IHRvIHN1YmNsYXNzIG91dHNpZGUgb2YgdGhlIGFsbG93ZWQgU1dUIGNsYXNzZXMKLSAqIGlzIGludGVuZGVkIHB1cmVseSB0byBlbmFibGUgdGhvc2Ugbm90IG9uIHRoZSBTV1QgZGV2ZWxvcG1lbnQKLSAqIHRlYW0gdG8gaW1wbGVtZW50IHBhdGNoZXMgaW4gb3JkZXIgdG8gZ2V0IGFyb3VuZCBzcGVjaWZpYwotICogbGltaXRhdGlvbnMgaW4gYWR2YW5jZSBvZiB3aGVuIHRob3NlIGxpbWl0YXRpb25zIGNhbiBiZQotICogYWRkcmVzc2VkIGJ5IHRoZSB0ZWFtLiBTdWJjbGFzc2luZyBzaG91bGQgbm90IGJlIGF0dGVtcHRlZAotICogd2l0aG91dCBhbiBpbnRpbWF0ZSBhbmQgZGV0YWlsZWQgdW5kZXJzdGFuZGluZyBvZiB0aGUgaGllcmFyY2h5LgotICogPC9wPgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9JTlZBTElEX1NVQkNMQVNTIC0gaWYgdGhpcyBjbGFzcyBpcyBub3QgYW4gYWxsb3dlZCBzdWJjbGFzczwvbGk+Ci0gKiA8L3VsPgotICovCisKIHByb3RlY3RlZCB2b2lkIGNoZWNrU3ViY2xhc3MgKCkgewogCWlmICghaXNWYWxpZFN1YmNsYXNzICgpKSBlcnJvciAoU1dULkVSUk9SX0lOVkFMSURfU1VCQ0xBU1MpOwogfQotLyoqCi0gKiBUaHJvd3MgYW4gPGNvZGU+U1dURXhjZXB0aW9uPC9jb2RlPiBpZiB0aGUgcmVjZWl2ZXIgY2FuIG5vdAotICogYmUgYWNjZXNzZWQgYnkgdGhlIGNhbGxlci4gVGhpcyBtYXkgaW5jbHVkZSBib3RoIGNoZWNrcyBvbgotICogdGhlIHN0YXRlIG9mIHRoZSByZWNlaXZlciBhbmQgbW9yZSBnZW5lcmFsbHkgb24gdGhlIGVudGlyZQotICogZXhlY3V0aW9uIGNvbnRleHQuIFRoaXMgbWV0aG9kIDxlbT5zaG91bGQ8L2VtPiBiZSBjYWxsZWQgYnkKLSAqIHdpZGdldCBpbXBsZW1lbnRvcnMgdG8gZW5mb3JjZSB0aGUgc3RhbmRhcmQgU1dUIGludmFyaWFudHMuCi0gKiA8cD4KLSAqIEN1cnJlbnRseSwgaXQgaXMgYW4gZXJyb3IgdG8gaW52b2tlIGFueSBtZXRob2QgKG90aGVyIHRoYW4KLSAqIDxjb2RlPmlzRGlzcG9zZWQoKTwvY29kZT4pIG9uIGEgd2lkZ2V0IHRoYXQgaGFzIGhhZCBpdHMgCi0gKiA8Y29kZT5kaXNwb3NlKCk8L2NvZGU+IG1ldGhvZCBjYWxsZWQuIEl0IGlzIGFsc28gYW4gZXJyb3IKLSAqIHRvIGNhbGwgd2lkZ2V0IG1ldGhvZHMgZnJvbSBhbnkgdGhyZWFkIHRoYXQgaXMgZGlmZmVyZW50Ci0gKiBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSB3aWRnZXQuCi0gKiA8L3A+PHA+Ci0gKiBJbiBmdXR1cmUgcmVsZWFzZXMgb2YgU1dULCB0aGVyZSBtYXkgYmUgbW9yZSBvciBmZXdlciBlcnJvcgotICogY2hlY2tzIGFuZCBleGNlcHRpb25zIG1heSBiZSB0aHJvd24gZm9yIGRpZmZlcmVudCByZWFzb25zLgotICogPC9wPgotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwcm90ZWN0ZWQgdm9pZCBjaGVja1dpZGdldCAoKSB7CiAJaWYgKCFpc1ZhbGlkVGhyZWFkICgpKSBlcnJvciAoU1dULkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyk7CiAJaWYgKGlzRGlzcG9zZWQgKCkpIGVycm9yIChTV1QuRVJST1JfV0lER0VUX0RJU1BPU0VEKTsKIH0KLXZvaWQgY3JlYXRlSGFuZGxlIChpbnQgaW5kZXgpIHsKLQkvKiBEbyBub3RoaW5nICovCi19Ci12b2lkIGNyZWF0ZVdpZGdldCAoaW50IGluZGV4KSB7Ci0JY3JlYXRlSGFuZGxlIChpbmRleCk7Ci0JaG9va0V2ZW50cyAoKTsKLQlyZWdpc3RlciAoKTsKLQltYW5hZ2VDaGlsZHJlbiAoKTsKLX0KLXZvaWQgZGVyZWdpc3RlciAoKSB7Ci0JaWYgKGhhbmRsZSA9PSAwKSByZXR1cm47Ci0JV2lkZ2V0VGFibGUucmVtb3ZlIChoYW5kbGUpOwotfQotdm9pZCBkZXN0cm95V2lkZ2V0ICgpIHsKLQlpbnQgdG9wSGFuZGxlID0gdG9wSGFuZGxlICgpOwotCXJlbGVhc2VIYW5kbGUgKCk7Ci0JaWYgKHRvcEhhbmRsZSAhPSAwKSB7Ci0JCWlmIChPUy5Jc1ZhbGlkQ29udHJvbEhhbmRsZSh0b3BIYW5kbGUpKSB7Ci0JCQlPUy5EaXNwb3NlQ29udHJvbCh0b3BIYW5kbGUpOwotCQl9IGVsc2UgaWYgKE9TLklzVmFsaWRXaW5kb3dQdHIodG9wSGFuZGxlKSkgewotCQkJT1MuRGlzcG9zZVdpbmRvdyh0b3BIYW5kbGUpOwotCQl9IGVsc2UgewotCQkJU3lzdGVtLm91dC5wcmludGxuKCJXaWRnZXQuZGVzdHJveVdpZGdldDogd3JvbmcgaGFuZGxlIik7Ci0JCX0KKworaW50IGNvbnRyb2xQcm9jIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IGV2ZW50S2luZCA9IE9TLkdldEV2ZW50S2luZCAodGhlRXZlbnQpOworCXN3aXRjaCAoZXZlbnRLaW5kKSB7CisJCWNhc2UgT1Mua0V2ZW50Q29udHJvbEFjdGl2YXRlOgkJCQlyZXR1cm4ga0V2ZW50Q29udHJvbEFjdGl2YXRlIChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwkJY2FzZSBPUy5rRXZlbnRDb250cm9sQm91bmRzQ2hhbmdlZDoJCQkJcmV0dXJuIGtFdmVudENvbnRyb2xCb3VuZHNDaGFuZ2VkIChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwkJY2FzZSBPUy5rRXZlbnRDb250cm9sQ2xpY2s6CQkJCXJldHVybiBrRXZlbnRDb250cm9sQ2xpY2sgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCQljYXNlIE9TLmtFdmVudENvbnRyb2xDb250ZXh0dWFsTWVudUNsaWNrOglyZXR1cm4ga0V2ZW50Q29udHJvbENvbnRleHR1YWxNZW51Q2xpY2sgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCQljYXNlIE9TLmtFdmVudENvbnRyb2xEZWFjdGl2YXRlOgkJCXJldHVybiBrRXZlbnRDb250cm9sRGVhY3RpdmF0ZSAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJCWNhc2UgT1Mua0V2ZW50Q29udHJvbERyYXc6CQkJCQlyZXR1cm4ga0V2ZW50Q29udHJvbERyYXcgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCQljYXNlIE9TLmtFdmVudENvbnRyb2xIaXQ6CQkJCQlyZXR1cm4ga0V2ZW50Q29udHJvbEhpdCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJCWNhc2UgT1Mua0V2ZW50Q29udHJvbFNldEN1cnNvcjoJCQlyZXR1cm4ga0V2ZW50Q29udHJvbFNldEN1cnNvciAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJCWNhc2UgT1Mua0V2ZW50Q29udHJvbFNldEZvY3VzUGFydDoJCQlyZXR1cm4ga0V2ZW50Q29udHJvbFNldEZvY3VzUGFydCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CiAJfQorCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7CiB9Ci0vKioKLSAqIERpc3Bvc2VzIG9mIHRoZSBvcGVyYXRpbmcgc3lzdGVtIHJlc291cmNlcyBhc3NvY2lhdGVkIHdpdGgKLSAqIHRoZSByZWNlaXZlciBhbmQgYWxsIGl0cyBkZXNjZW5kZW50cy4gQWZ0ZXIgdGhpcyBtZXRob2QgaGFzCi0gKiBiZWVuIGludm9rZWQsIHRoZSByZWNlaXZlciBhbmQgYWxsIGRlc2NlbmRlbnRzIHdpbGwgYW5zd2VyCi0gKiA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHNlbnQgdGhlIG1lc3NhZ2UgPGNvZGU+aXNEaXNwb3NlZCgpPC9jb2RlPi4KLSAqIEFueSBpbnRlcm5hbCBjb25uZWN0aW9ucyBiZXR3ZWVuIHRoZSB3aWRnZXRzIGluIHRoZSB0cmVlIHdpbGwKLSAqIGhhdmUgYmVlbiByZW1vdmVkIHRvIGZhY2lsaXRhdGUgZ2FyYmFnZSBjb2xsZWN0aW9uLgotICogPHA+Ci0gKiBOT1RFOiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIHJlY3Vyc2l2ZWx5IG9uIHRoZSBkZXNjZW5kZW50cwotICogb2YgdGhlIHJlY2VpdmVyLiBUaGlzIG1lYW5zIHRoYXQsIHdpZGdldCBpbXBsZW1lbnRlcnMgY2FuIG5vdAotICogZGV0ZWN0IHdoZW4gYSB3aWRnZXQgaXMgYmVpbmcgZGlzcG9zZWQgb2YgYnkgcmUtaW1wbGVtZW50aW5nCi0gKiB0aGlzIG1ldGhvZCwgYnV0IHNob3VsZCBpbnN0ZWFkIGxpc3RlbiBmb3IgdGhlIDxjb2RlPkRpc3Bvc2U8L2NvZGU+Ci0gKiBldmVudC4KLSAqIDwvcD4KLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI2FkZERpc3Bvc2VMaXN0ZW5lcgotICogQHNlZSAjcmVtb3ZlRGlzcG9zZUxpc3RlbmVyCi0gKiBAc2VlICNjaGVja1dpZGdldAotICovCisKK2ludCBjcmVhdGVDSWNvbiAoSW1hZ2UgaW1hZ2UpIHsKKwlpbnQgaW1hZ2VIYW5kbGUgPSBpbWFnZS5oYW5kbGU7CisJaW50IHdpZHRoID0gT1MuQ0dJbWFnZUdldFdpZHRoKGltYWdlSGFuZGxlKTsKKwlpbnQgaGVpZ2h0ID0gT1MuQ0dJbWFnZUdldEhlaWdodChpbWFnZUhhbmRsZSk7CisJaW50IGJwciA9IE9TLkNHSW1hZ2VHZXRCeXRlc1BlclJvdyhpbWFnZUhhbmRsZSk7CisJaW50IGJwcCA9IE9TLkNHSW1hZ2VHZXRCaXRzUGVyUGl4ZWwoaW1hZ2VIYW5kbGUpOworCWludCBicGMgPSBPUy5DR0ltYWdlR2V0Qml0c1BlckNvbXBvbmVudChpbWFnZUhhbmRsZSk7CisJaW50IGFscGhhSW5mbyA9IE9TLkNHSW1hZ2VHZXRBbHBoYUluZm8oaW1hZ2VIYW5kbGUpOworCQorCWludCBtYXNrQnBsID0gKCgod2lkdGggKyA3KSAvIDgpICsgMykgLyA0ICogNDsKKwlpbnQgbWFza1NpemUgPSBoZWlnaHQgKiBtYXNrQnBsOworCWludCBwaXhtYXBTaXplID0gaGVpZ2h0ICogYnByOworCQorCS8qIENyZWF0ZSB0aGUgaWNvbiAqLworCWludCBpY29uU2l6ZSA9IFBpeE1hcC5zaXplb2YgKyBCaXRNYXAuc2l6ZW9mICogMiArIDQgKyBtYXNrU2l6ZTsKKwlpbnQgaWNvbkhhbmRsZSA9IE9TLk5ld0hhbmRsZShpY29uU2l6ZSk7CisJaWYgKGljb25IYW5kbGUgPT0gMCkgU1dULmVycm9yKFNXVC5FUlJPUl9OT19IQU5ETEVTKTsKKwlPUy5ITG9jayhpY29uSGFuZGxlKTsKKwlpbnRbXSBpY29uUHRyID0gbmV3IGludFsxXTsKKwlPUy5tZW1jcHkoaWNvblB0ciwgaWNvbkhhbmRsZSwgNCk7CisKKwkvKiBJbml0aWFsaXplIHRoZSBwaXhtYXAgKi8KKwlQaXhNYXAgaWNvblBNYXAgPSBuZXcgUGl4TWFwKCk7CisJaWNvblBNYXAucm93Qnl0ZXMgPSAoc2hvcnQpKGJwciB8IDB4ODAwMCk7CisJaWNvblBNYXAucmlnaHQgPSAoc2hvcnQpd2lkdGg7CisJaWNvblBNYXAuYm90dG9tID0gKHNob3J0KWhlaWdodDsKKwlpY29uUE1hcC5jbXBDb3VudCA9IDM7CisJaWNvblBNYXAuY21wU2l6ZSA9IChzaG9ydClicGM7CisJaWNvblBNYXAucG1UYWJsZSA9IE9TLk5ld0hhbmRsZSgwKTsKKwlpY29uUE1hcC5oUmVzID0gNzIgPDwgMTY7CisJaWNvblBNYXAudlJlcyA9IDcyIDw8IDE2OworCWljb25QTWFwLnBpeGVsVHlwZSA9IChzaG9ydClPUy5SR0JEaXJlY3Q7CisJaWNvblBNYXAucGl4ZWxTaXplID0gKHNob3J0KWJwcDsKKwlpY29uUE1hcC5waXhlbEZvcm1hdCA9IChzaG9ydClicHA7CisJT1MubWVtY3B5KGljb25QdHJbMF0sIGljb25QTWFwLCBQaXhNYXAuc2l6ZW9mKTsKKworCS8qIEluaXRpYWxpemUgdGhlIG1hc2sgKi8KKwlCaXRNYXAgaWNvbk1hc2sgPSBuZXcgQml0TWFwKCk7CisJaWNvbk1hc2sucm93Qnl0ZXMgPSAoc2hvcnQpbWFza0JwbDsKKwlpY29uTWFzay5yaWdodCA9IChzaG9ydCl3aWR0aDsKKwlpY29uTWFzay5ib3R0b20gPSAoc2hvcnQpaGVpZ2h0OworCU9TLm1lbWNweShpY29uUHRyWzBdICsgUGl4TWFwLnNpemVvZiwgaWNvbk1hc2ssIEJpdE1hcC5zaXplb2YpOworCisJLyogSW5pdGlhbGl6ZSB0aGUgaWNvbiBkYXRhICovCisJaW50IGljb25EYXRhID0gT1MuTmV3SGFuZGxlKHBpeG1hcFNpemUpOworCU9TLkhMb2NrKGljb25EYXRhKTsKKwlpbnRbXSBpY29uRGF0YVB0ciA9IG5ldyBpbnRbMV07CisJT1MubWVtY3B5KGljb25EYXRhUHRyLCBpY29uRGF0YSwgNCk7CisJT1MubWVtY3B5KGljb25EYXRhUHRyWzBdLCBpbWFnZS5kYXRhLCBwaXhtYXBTaXplKTsKKwlPUy5IVW5sb2NrKGljb25EYXRhKTsKKwlPUy5tZW1jcHkoaWNvblB0clswXSArIFBpeE1hcC5zaXplb2YgKyAyICogQml0TWFwLnNpemVvZiwgbmV3IGludFtde2ljb25EYXRhfSwgNCk7CisKKwkvKiBJbml0aWFsaXplIHRoZSBtYXNrIGRhdGEgKi8KKwlpZiAoYWxwaGFJbmZvICE9IE9TLmtDR0ltYWdlQWxwaGFGaXJzdCkgeworCQlPUy5tZW1zZXQoaWNvblB0clswXSArIFBpeE1hcC5zaXplb2YgKyAyICogQml0TWFwLnNpemVvZiArIDQsIC0xLCBtYXNrU2l6ZSk7CisJfSBlbHNlIHsKKwkJYnl0ZVtdIHNyY0RhdGEgPSBuZXcgYnl0ZVtwaXhtYXBTaXplXTsKKwkJT1MubWVtY3B5KHNyY0RhdGEsIGltYWdlLmRhdGEsIHBpeG1hcFNpemUpOworCQlieXRlW10gbWFza0RhdGEgPSBuZXcgYnl0ZVttYXNrU2l6ZV07CisJCWludCBvZmZzZXQgPSAwLCBtYXNrT2Zmc2V0ID0gMDsKKwkJZm9yIChpbnQgeSA9IDA7IHk8aGVpZ2h0OyB5KyspIHsKKwkJCWZvciAoaW50IHggPSAwOyB4PHdpZHRoOyB4KyspIHsKKwkJCQlpZiAoKHNyY0RhdGFbb2Zmc2V0XSAmIDB4RkYpID4gMTI4KSB7CisJCQkJCW1hc2tEYXRhW21hc2tPZmZzZXQgKyAoeCA+PiAzKV0gfD0gKDEgPDwgKDcgLSAoeCAmIDB4NykpKTsKKwkJCQl9IGVsc2UgeworCQkJCQltYXNrRGF0YVttYXNrT2Zmc2V0ICsgKHggPj4gMyldICY9IH4oMSA8PCAoNyAtICh4ICYgMHg3KSkpOworCQkJCX0KKwkJCQlvZmZzZXQgKz0gNDsKKwkJCX0KKwkJCW1hc2tPZmZzZXQgKz0gbWFza0JwbDsKKwkJfQorCQlPUy5tZW1jcHkoaWNvblB0clswXSArIFBpeE1hcC5zaXplb2YgKyAyICogQml0TWFwLnNpemVvZiArIDQsIG1hc2tEYXRhLCBtYXNrRGF0YS5sZW5ndGgpOworCX0KKwkKKwlPUy5IVW5sb2NrKGljb25IYW5kbGUpOwkKKwlyZXR1cm4gaWNvbkhhbmRsZTsKK30KKwordm9pZCBjcmVhdGVIYW5kbGUgKCkgeworfQorCit2b2lkIGNyZWF0ZVdpZGdldCAoKSB7CisJY3JlYXRlSGFuZGxlICgpOworCXJlZ2lzdGVyICgpOworCWhvb2tFdmVudHMgKCk7Cit9CisKK2ludCBjb21tYW5kUHJvYyAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWludCBldmVudEtpbmQgPSBPUy5HZXRFdmVudEtpbmQgKHRoZUV2ZW50KTsKKwlzd2l0Y2ggKGV2ZW50S2luZCkgeworCQljYXNlIE9TLmtFdmVudFByb2Nlc3NDb21tYW5kOglyZXR1cm4ga0V2ZW50UHJvY2Vzc0NvbW1hbmQgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCX0KKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCQordm9pZCBkZXJlZ2lzdGVyICgpIHsKK30KKwordm9pZCBkZXN0cm95V2lkZ2V0ICgpIHsKKwlyZWxlYXNlSGFuZGxlICgpOworfQorCit2b2lkIGRlc3Ryb3lDSWNvbiAoaW50IGljb25IYW5kbGUpIHsKKwlPUy5ITG9jayhpY29uSGFuZGxlKTsKKwkKKwkvKiBEaXNwb3NlIHRoZSBDb2xvclRhYmxlICovCisJaW50W10gaWNvblB0ciA9IG5ldyBpbnRbMV07CisJT1MubWVtY3B5KGljb25QdHIsIGljb25IYW5kbGUsIDQpOwkKKwlQaXhNYXAgaWNvblBNYXAgPSBuZXcgUGl4TWFwKCk7CisJT1MubWVtY3B5KGljb25QTWFwLCBpY29uUHRyWzBdLCBQaXhNYXAuc2l6ZW9mKTsKKwlpZiAoaWNvblBNYXAucG1UYWJsZSAhPSAwKSBPUy5EaXNwb3NlSGFuZGxlKGljb25QTWFwLnBtVGFibGUpOworCisJLyogRGlzcG9zZSB0aGUgaWNvbiBkYXRhICovCisJaW50W10gaWNvbkRhdGEgPSBuZXcgaW50WzFdOworCU9TLm1lbWNweShpY29uRGF0YSwgaWNvblB0clswXSArIFBpeE1hcC5zaXplb2YgKyAyICogQml0TWFwLnNpemVvZiwgNCk7CisJaWYgKGljb25EYXRhWzBdICE9IDApIE9TLkRpc3Bvc2VIYW5kbGUoaWNvbkRhdGFbMF0pOworCQorCU9TLkhVbmxvY2soaWNvbkhhbmRsZSk7CisJCisJLyogRGlzcG9zZSB0aGUgaWNvbiAqLworCU9TLkRpc3Bvc2VIYW5kbGUoaWNvbkhhbmRsZSk7Cit9CisKK2ludCBkcmF3SXRlbVByb2MgKGludCBicm93c2VyLCBpbnQgaXRlbSwgaW50IHByb3BlcnR5LCBpbnQgaXRlbVN0YXRlLCBpbnQgdGhlUmVjdCwgaW50IGdkRGVwdGgsIGludCBjb2xvckRldmljZSkgeworCXJldHVybiBPUy5ub0VycjsKK30KKwogcHVibGljIHZvaWQgZGlzcG9zZSAoKSB7CiAJLyoKIAkqIE5vdGU6ICBJdCBpcyB2YWxpZCB0byBhdHRlbXB0IHRvIGRpc3Bvc2UgYSB3aWRnZXQKQEAgLTI4OSw2NiArMjU3LDc0IEBACiAJcmVsZWFzZVdpZGdldCAoKTsKIAlkZXN0cm95V2lkZ2V0ICgpOwogfQotdm9pZCBlbmFibGVIYW5kbGUgKGJvb2xlYW4gZW5hYmxlZCwgaW50IHdpZGdldEhhbmRsZSkgewotCWlmIChlbmFibGVkKQotCQlPUy5FbmFibGVDb250cm9sKHdpZGdldEhhbmRsZSk7Ci0JZWxzZQotCQlPUy5EaXNhYmxlQ29udHJvbCh3aWRnZXRIYW5kbGUpOwotfQkKKwordm9pZCBkcmF3QmFja2dyb3VuZCAoaW50IGNvbnRyb2wsIGZsb2F0IFtdIGJhY2tncm91bmQpIHsKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChjb250cm9sLCByZWN0KTsKKwlpZiAoYmFja2dyb3VuZCAhPSBudWxsKSB7CisJCWludCByZWQgPSAoc2hvcnQpIChiYWNrZ3JvdW5kIFswXSAqIDI1NSk7CisJCWludCBncmVlbiA9IChzaG9ydCkgKGJhY2tncm91bmQgWzFdICogMjU1KTsKKwkJaW50IGJsdWUgPSAoc2hvcnQpIChiYWNrZ3JvdW5kIFsyXSAqIDI1NSk7CisJCVJHQkNvbG9yIGNvbG9yID0gbmV3IFJHQkNvbG9yICgpOworCQljb2xvci5yZWQgPSAoc2hvcnQpIChyZWQgPDwgOCB8IHJlZCk7CisJCWNvbG9yLmdyZWVuID0gKHNob3J0KSAoZ3JlZW4gPDwgOCB8IGdyZWVuKTsKKwkJY29sb3IuYmx1ZSA9IChzaG9ydCkgKGJsdWUgPDwgOCB8IGJsdWUpOworCQlPUy5SR0JGb3JlQ29sb3IgKGNvbG9yKTsKKwkJT1MuUGFpbnRSZWN0IChyZWN0KTsKKwl9IGVsc2UgeworCQlPUy5FcmFzZVJlY3QgKHJlY3QpOworCX0KK30KKwordm9pZCBkcmF3V2lkZ2V0IChpbnQgY29udHJvbCkgeworfQorCiB2b2lkIGVycm9yIChpbnQgY29kZSkgewogCVNXVC5lcnJvcihjb2RlKTsKIH0KLS8qKgotICogUmV0dXJucyB0aGUgYXBwbGljYXRpb24gZGVmaW5lZCB3aWRnZXQgZGF0YSBhc3NvY2lhdGVkCi0gKiB3aXRoIHRoZSByZWNlaXZlciwgb3IgbnVsbCBpZiBpdCBoYXMgbm90IGJlZW4gc2V0LiBUaGUKLSAqIDxlbT53aWRnZXQgZGF0YTwvZW0+IGlzIGEgc2luZ2xlLCB1bm5hbWVkIGZpZWxkIHRoYXQgaXMKLSAqIHN0b3JlZCB3aXRoIGV2ZXJ5IHdpZGdldC4gCi0gKiA8cD4KLSAqIEFwcGxpY2F0aW9ucyBtYXkgcHV0IGFyYml0cmFyeSBvYmplY3RzIGluIHRoaXMgZmllbGQuIElmCi0gKiB0aGUgb2JqZWN0IHN0b3JlZCBpbiB0aGUgd2lkZ2V0IGRhdGEgbmVlZHMgdG8gYmUgbm90aWZpZWQKLSAqIHdoZW4gdGhlIHdpZGdldCBpcyBkaXNwb3NlZCBvZiwgaXQgaXMgdGhlIGFwcGxpY2F0aW9uJ3MKLSAqIHJlc3BvbnNpYmlsaXR5IHRvIGhvb2sgdGhlIERpc3Bvc2UgZXZlbnQgb24gdGhlIHdpZGdldCBhbmQKLSAqIGRvIHNvLgotICogPC9wPgotICoKLSAqIEByZXR1cm4gdGhlIHdpZGdldCBkYXRhCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIHdoZW4gdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSB3aGVuIGNhbGxlZCBmcm9tIHRoZSB3cm9uZyB0aHJlYWQ8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlICNzZXREYXRhCi0gKi8KKworYm9vbGVhbiBmaWx0ZXJzIChpbnQgZXZlbnRUeXBlKSB7CisJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlyZXR1cm4gZGlzcGxheS5maWx0ZXJzIChldmVudFR5cGUpOworfQorCitSZWN0IGdldENvbnRyb2xCb3VuZHMgKGludCBjb250cm9sKSB7CisJUmVjdCByZWN0ID0gbmV3IFJlY3QoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChjb250cm9sLCByZWN0KTsKKwlpbnQgd2luZG93ID0gT1MuR2V0Q29udHJvbE93bmVyIChjb250cm9sKTsKKwlpbnQgW10gdGhlUm9vdCA9IG5ldyBpbnQgWzFdOworCU9TLkdldFJvb3RDb250cm9sICh3aW5kb3csIHRoZVJvb3QpOworCWludCBbXSBwYXJlbnRIYW5kbGUgPSBuZXcgaW50IFsxXTsKKwlPUy5HZXRTdXBlckNvbnRyb2wgKGNvbnRyb2wsIHBhcmVudEhhbmRsZSk7CisJaWYgKHBhcmVudEhhbmRsZSBbMF0gIT0gdGhlUm9vdCBbMF0pIHsKKwkJUmVjdCBwYXJlbnRSZWN0ID0gbmV3IFJlY3QgKCk7CisJCU9TLkdldENvbnRyb2xCb3VuZHMgKHBhcmVudEhhbmRsZSBbMF0sIHBhcmVudFJlY3QpOworCQlPUy5PZmZzZXRSZWN0IChyZWN0LCAoc2hvcnQpIC1wYXJlbnRSZWN0LmxlZnQsIChzaG9ydCkgLXBhcmVudFJlY3QudG9wKTsKKwl9CisJUmVjdCBpbnNldCA9IGdldEluc2V0ICgpOworCXJlY3QubGVmdCAtPSBpbnNldC5sZWZ0OworCXJlY3QudG9wIC09IGluc2V0LnRvcDsKKwlyZWN0LnJpZ2h0ICs9IGluc2V0LnJpZ2h0OworCXJlY3QuYm90dG9tICs9IGluc2V0LmJvdHRvbTsKKwlyZXR1cm4gcmVjdDsKK30KKworUmVjdCBnZXRDb250cm9sU2l6ZSAoaW50IGNvbnRyb2wpIHsKKwlSZWN0IHJlY3QgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChjb250cm9sLCByZWN0KTsKKwlSZWN0IGluc2V0ID0gZ2V0SW5zZXQgKCk7CisJcmVjdC5sZWZ0IC09IGluc2V0LmxlZnQ7CisJcmVjdC50b3AgLT0gaW5zZXQudG9wOworCXJlY3QucmlnaHQgKz0gaW5zZXQucmlnaHQ7CisJcmVjdC5ib3R0b20gKz0gaW5zZXQuYm90dG9tOworCXJldHVybiByZWN0OworfQorCiBwdWJsaWMgT2JqZWN0IGdldERhdGEgKCkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIGRhdGE7CiB9CiAKLS8qKgotICogUmV0dXJucyB0aGUgYXBwbGljYXRpb24gZGVmaW5lZCBwcm9wZXJ0eSBvZiB0aGUgcmVjZWl2ZXIKLSAqIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lLCBvciBudWxsIGlmIGl0IGhhcyBub3QgYmVlbiBzZXQuCi0gKiA8cD4KLSAqIEFwcGxpY2F0aW9ucyBtYXkgaGF2ZSBhc3NvY2lhdGVkIGFyYml0cmFyeSBvYmplY3RzIHdpdGggdGhlCi0gKiByZWNlaXZlciBpbiB0aGlzIGZhc2hpb24uIElmIHRoZSBvYmplY3RzIHN0b3JlZCBpbiB0aGUKLSAqIHByb3BlcnRpZXMgbmVlZCB0byBiZSBub3RpZmllZCB3aGVuIHRoZSB3aWRnZXQgaXMgZGlzcG9zZWQKLSAqIG9mLCBpdCBpcyB0aGUgYXBwbGljYXRpb24ncyByZXNwb25zaWJpbGl0eSB0byBob29rIHRoZQotICogRGlzcG9zZSBldmVudCBvbiB0aGUgd2lkZ2V0IGFuZCBkbyBzby4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0Ja2V5IHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eQotICogQHJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5IG9yIG51bGwgaWYgaXQgaGFzIG5vdCBiZWVuIHNldAotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGtleSBpcyBudWxsPC9saT4KLSAqIDwvdWw+Ci0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gaWYgdGhlIHJlY2VpdmVyIGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqICAgIDxsaT5FUlJPUl9USFJFQURfSU5WQUxJRF9BQ0NFU1MgLSBpZiBub3QgY2FsbGVkIGZyb20gdGhlIHRocmVhZCB0aGF0IGNyZWF0ZWQgdGhlIHJlY2VpdmVyPC9saT4KLSAqIDwvdWw+Ci0gKgotICogQHNlZSAjc2V0RGF0YQotICovCiBwdWJsaWMgT2JqZWN0IGdldERhdGEgKFN0cmluZyBrZXkpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChrZXkgPT0gbnVsbCkgZXJyb3IgKFNXVC5FUlJPUl9OVUxMX0FSR1VNRU5UKTsKQEAgLTM1OSwxMjMgKzMzNSwyNjUgQEAKIAlyZXR1cm4gbnVsbDsKIH0KIAotLyoqCi0gKiBSZXR1cm5zIHRoZSA8Y29kZT5EaXNwbGF5PC9jb2RlPiB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aAotICogdGhlIHJlY2VpdmVyLgotICogPHA+Ci0gKiBBIHdpZGdldCdzIGRpc3BsYXkgaXMgZWl0aGVyIHByb3ZpZGVkIHdoZW4gaXQgaXMgY3JlYXRlZAotICogKGZvciBleGFtcGxlLCB0b3AgbGV2ZWwgPGNvZGU+U2hlbGw8L2NvZGU+cykgb3IgaXMgdGhlCi0gKiBzYW1lIGFzIGl0cyBwYXJlbnQncyBkaXNwbGF5LgotICogPC9wPgotICoKLSAqIEByZXR1cm4gdGhlIHJlY2VpdmVyJ3MgZGlzcGxheQotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLwogcHVibGljIGFic3RyYWN0IERpc3BsYXkgZ2V0RGlzcGxheSAoKTsKKwogU3RyaW5nIGdldE5hbWUgKCkgewogCVN0cmluZyBzdHJpbmcgPSBnZXRDbGFzcyAoKS5nZXROYW1lICgpOwotCWludCBpbmRleCA9IHN0cmluZy5sYXN0SW5kZXhPZiAoJy4nKTsKKwlpbnQgaW5kZXggPSBzdHJpbmcubGFzdEluZGV4T2YoIi4iKTsKIAlpZiAoaW5kZXggPT0gLTEpIHJldHVybiBzdHJpbmc7Ci0JcmV0dXJuIHN0cmluZy5zdWJzdHJpbmcgKGluZGV4ICsgMSwgc3RyaW5nLmxlbmd0aCAoKSk7CisJcmV0dXJuIHN0cmluZy5zdWJzdHJpbmcoaW5kZXggKyAxLCBzdHJpbmcubGVuZ3RoICgpKTsKIH0KKwogU3RyaW5nIGdldE5hbWVUZXh0ICgpIHsKIAlyZXR1cm4gIiI7CiB9Ci0vKioKLSAqIFJldHVybnMgdGhlIHJlY2VpdmVyJ3Mgc3R5bGUgaW5mb3JtYXRpb24uCi0gKiA8cD4KLSAqIE5vdGUgdGhhdCB0aGUgdmFsdWUgd2hpY2ggaXMgcmV0dXJuZWQgYnkgdGhpcyBtZXRob2QgPGVtPm1heQotICogbm90IG1hdGNoPC9lbT4gdGhlIHZhbHVlIHdoaWNoIHdhcyBwcm92aWRlZCB0byB0aGUgY29uc3RydWN0b3IKLSAqIHdoZW4gdGhlIHJlY2VpdmVyIHdhcyBjcmVhdGVkLiBUaGlzIGNhbiBvY2N1ciB3aGVuIHRoZSB1bmRlcmx5aW5nCi0gKiBvcGVyYXRpbmcgc3lzdGVtIGRvZXMgbm90IHN1cHBvcnQgYSBwYXJ0aWN1bGFyIGNvbWJpbmF0aW9uIG9mCi0gKiByZXF1ZXN0ZWQgc3R5bGVzLiBGb3IgZXhhbXBsZSwgaWYgdGhlIHBsYXRmb3JtIHdpZGdldCB1c2VkIHRvCi0gKiBpbXBsZW1lbnQgYSBwYXJ0aWN1bGFyIFNXVCB3aWRnZXQgYWx3YXlzIGhhcyBzY3JvbGwgYmFycywgdGhlCi0gKiByZXN1bHQgb2YgY2FsbGluZyB0aGlzIG1ldGhvZCB3b3VsZCBhbHdheXMgaGF2ZSB0aGUKLSAqIDxjb2RlPlNXVC5IX1NDUk9MTDwvY29kZT4gYW5kIDxjb2RlPlNXVC5WX1NDUk9MTDwvY29kZT4gYml0cyBzZXQuCi0gKiA8L3A+Ci0gKgotICogQHJldHVybiB0aGUgc3R5bGUgYml0cwotICoKLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCiBwdWJsaWMgaW50IGdldFN0eWxlICgpIHsKIAljaGVja1dpZGdldCgpOwogCXJldHVybiBzdHlsZTsKIH0KLXZvaWQgaG9va0V2ZW50cyAoKSB7Ci0JLyogRG8gbm90aGluZyAqLworCitpbnQgZ2V0VmlzaWJsZVJlZ2lvbiAoaW50IGNvbnRyb2wpIHsKKwlpbnQgdmlzaWJsZVJnbiA9IE9TLk5ld1JnbiAoKSwgY2hpbGRSZ24gPSBPUy5OZXdSZ24gKCksIHRlbXBSZ24gPSBPUy5OZXdSZ24gKCk7CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAoY29udHJvbCk7CisJaW50IHBvcnQgPSBPUy5HZXRXaW5kb3dQb3J0ICh3aW5kb3cpOworCU9TLkdldFBvcnRWaXNpYmxlUmVnaW9uIChwb3J0LCB2aXNpYmxlUmduKTsKKwlzaG9ydCBbXSBjb3VudCA9IG5ldyBzaG9ydCBbMV07CisJaW50IFtdIG91dENvbnRyb2wgPSBuZXcgaW50IFsxXTsKKwlpbnQgdGVtcENvbnRyb2wgPSBjb250cm9sLCBsYXN0Q29udHJvbCA9IDA7CisJd2hpbGUgKHRlbXBDb250cm9sICE9IDApIHsKKwkJT1MuR2V0Q29udHJvbFJlZ2lvbiAodGVtcENvbnRyb2wsIChzaG9ydCkgT1Mua0NvbnRyb2xTdHJ1Y3R1cmVNZXRhUGFydCwgdGVtcFJnbik7CisJCU9TLlNlY3RSZ24gKHRlbXBSZ24sIHZpc2libGVSZ24sIHZpc2libGVSZ24pOworCQlpZiAoT1MuRW1wdHlSZ24gKHZpc2libGVSZ24pKSBicmVhazsKKwkJT1MuQ291bnRTdWJDb250cm9scyAodGVtcENvbnRyb2wsIGNvdW50KTsKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudCBbMF07IGkrKykgeworCQkJT1MuR2V0SW5kZXhlZFN1YkNvbnRyb2wgKHRlbXBDb250cm9sLCAoc2hvcnQpKGkgKyAxKSwgb3V0Q29udHJvbCk7CisJCQlpbnQgY2hpbGQgPSBvdXRDb250cm9sIFswXTsKKwkJCWlmIChjaGlsZCA9PSBsYXN0Q29udHJvbCkgYnJlYWs7CisJCQlpZiAoIU9TLklzQ29udHJvbFZpc2libGUgKGNoaWxkKSkgY29udGludWU7CisJCQlPUy5HZXRDb250cm9sUmVnaW9uIChjaGlsZCwgKHNob3J0KSBPUy5rQ29udHJvbFN0cnVjdHVyZU1ldGFQYXJ0LCB0ZW1wUmduKTsKKwkJCU9TLlVuaW9uUmduICh0ZW1wUmduLCBjaGlsZFJnbiwgY2hpbGRSZ24pOworCQl9CisJCWxhc3RDb250cm9sID0gdGVtcENvbnRyb2w7CisJCU9TLkdldFN1cGVyQ29udHJvbCAodGVtcENvbnRyb2wsIG91dENvbnRyb2wpOworCQl0ZW1wQ29udHJvbCA9IG91dENvbnRyb2wgWzBdOworCX0KKwlPUy5EaWZmUmduICh2aXNpYmxlUmduLCBjaGlsZFJnbiwgdmlzaWJsZVJnbik7CisJT1MuRGlzcG9zZVJnbiAoY2hpbGRSZ24pOworCU9TLkRpc3Bvc2VSZ24gKHRlbXBSZ24pOworCXJldHVybiB2aXNpYmxlUmduOwogfQorCitpbnQgaGVscFByb2MgKGludCBpbkNvbnRyb2wsIGludCBpbkdsb2JhbE1vdXNlLCBpbnQgaW5SZXF1ZXN0LCBpbnQgb3V0Q29udGVudFByb3ZpZGVkLCBpbnQgaW9IZWxwQ29udGVudCkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBoaXRUZXN0UHJvYyAoaW50IGJyb3dzZXIsIGludCBpdGVtLCBpbnQgcHJvcGVydHksIGludCB0aGVSZWN0LCBpbnQgbW91c2VSZWN0KSB7CisJLyogUmV0dXJuIHRydWUgdG8gaW5kaWNhdGUgdGhhdCB0aGUgaXRlbSBjYW4gYmUgc2VsZWN0ZWQgKi8KKwlyZXR1cm4gMTsKK30KKwordm9pZCBob29rRXZlbnRzICgpIHsKK30KKwogYm9vbGVhbiBob29rcyAoaW50IGV2ZW50VHlwZSkgewogCWlmIChldmVudFRhYmxlID09IG51bGwpIHJldHVybiBmYWxzZTsKIAlyZXR1cm4gZXZlbnRUYWJsZS5ob29rcyAoZXZlbnRUeXBlKTsKIH0KLS8qKgotICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgd2lkZ2V0IGhhcyBiZWVuIGRpc3Bvc2VkLAotICogYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCi0gKiA8cD4KLSAqIFRoaXMgbWV0aG9kIGdldHMgdGhlIGRpc3Bvc2Ugc3RhdGUgZm9yIHRoZSB3aWRnZXQuCi0gKiBXaGVuIGEgd2lkZ2V0IGhhcyBiZWVuIGRpc3Bvc2VkLCBpdCBpcyBhbiBlcnJvciB0bwotICogaW52b2tlIGFueSBvdGhlciBtZXRob2QgdXNpbmcgdGhlIHdpZGdldC4KLSAqIDwvcD4KLSAqCi0gKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IHdoZW4gdGhlIHdpZGdldCBpcyBkaXNwb3NlZCBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZQotICovCisKK1JlY3QgZ2V0SW5zZXQgKCkgeworCXJldHVybiBFTVBUWV9SRUNUOworfQorCiBwdWJsaWMgYm9vbGVhbiBpc0Rpc3Bvc2VkICgpIHsKLQlpZiAoaGFuZGxlICE9IDApIHJldHVybiBmYWxzZTsKLQlpZiAoKHN0YXRlICYgSEFORExFKSAhPSAwKSByZXR1cm4gdHJ1ZTsKIAlyZXR1cm4gKHN0YXRlICYgRElTUE9TRUQpICE9IDA7CiB9Ci0vKioKLSAqIFJldHVybiB0aGUgbGlzdGVuaW5nIHN0YXRlLgotICogPHA+Ci0gKiBSZXR1cm5zIHRydWUgaWYgdGhlcmUgaXMgYSBsaXN0ZW5lciwgbGlzdGVuaW5nIGZvciB0aGUgZXZlbnRUeXBlLgotICogT3RoZXJ3aXNlLCByZXR1cm5zIGZhbHNlLgotICoKLSAqIEBwYXJhbQlldmVudFR5cGUgdGhlIHR5cGUgb2YgZXZlbnQKLSAqIEByZXR1cm4JdHJ1ZSBpZiB0aGUgZXZlbnQgaXMgaG9va2VkCi0gKgotICogQGV4Y2VwdGlvbiBTV1RFcnJvciA8dWw+Ci0gKgkJPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyB3aGVuIGNhbGxlZCBmcm9tIHRoZSB3cm9uZyB0aHJlYWQ8L2xpPgotICoJCTxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgd2hlbiB0aGUgd2lkZ2V0IGhhcyBiZWVuIGRpc3Bvc2VkPC9saT4KLSAqCQk8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCB3aGVuIHRoZSBuYW1lIGlzIG51bGw8L2xpPgotICoJPC91bD4KLSAqLworCiBwcm90ZWN0ZWQgYm9vbGVhbiBpc0xpc3RlbmluZyAoaW50IGV2ZW50VHlwZSkgewogCWNoZWNrV2lkZ2V0KCk7CiAJcmV0dXJuIGhvb2tzIChldmVudFR5cGUpOwogfQorCiBib29sZWFuIGlzVmFsaWRTdWJjbGFzcyAoKSB7CiAJcmV0dXJuIERpc3BsYXkuaXNWYWxpZENsYXNzIChnZXRDbGFzcyAoKSk7CiB9CisKIGJvb2xlYW4gaXNWYWxpZFRocmVhZCAoKSB7CiAJcmV0dXJuIGdldERpc3BsYXkgKCkuaXNWYWxpZFRocmVhZCAoKTsKIH0KLXZvaWQgbWFuYWdlQ2hpbGRyZW4gKCkgewotCS8qIERvIG5vdGhpbmcgKi8KKworaW50IGl0ZW1EYXRhUHJvYyAoaW50IGJyb3dzZXIsIGludCBpdGVtLCBpbnQgcHJvcGVydHksIGludCBpdGVtRGF0YSwgaW50IHNldFZhbHVlKSB7CisJcmV0dXJuIE9TLm5vRXJyOwogfQotLyoqCi0gKiBOb3RpZmllcyBhbGwgb2YgdGhlIHJlY2VpdmVyJ3MgbGlzdGVuZXJzIGZvciBldmVudHMKLSAqIG9mIHRoZSBnaXZlbiB0eXBlIHRoYXQgb25lIHN1Y2ggZXZlbnQgaGFzIG9jY3VycmVkIGJ5Ci0gKiBpbnZva2luZyB0aGVpciA8Y29kZT5oYW5kbGVFdmVudCgpPC9jb2RlPiBtZXRob2QuCi0gKgotICogQHBhcmFtIGV2ZW50VHlwZSB0aGUgdHlwZSBvZiBldmVudCB3aGljaCBoYXMgb2NjdXJyZWQKLSAqIEBwYXJhbSBldmVudCB0aGUgZXZlbnQgZGF0YQotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGV2ZW50IGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqLworCitpbnQgaXRlbU5vdGlmaWNhdGlvblByb2MgKGludCBicm93c2VyLCBpbnQgaXRlbSwgaW50IG1lc3NhZ2UpIHsKKwlyZXR1cm4gT1Mubm9FcnI7Cit9CisKK2ludCBrRXZlbnRQcm9jZXNzQ29tbWFuZCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisJCitpbnQga0V2ZW50Q29udHJvbEFjdGl2YXRlIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKworaW50IGtFdmVudENvbnRyb2xCb3VuZHNDaGFuZ2VkIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKworaW50IGtFdmVudENvbnRyb2xDbGljayAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRDb250cm9sQ29udGV4dHVhbE1lbnVDbGljayAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRDb250cm9sRGVhY3RpdmF0ZSAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRDb250cm9sRHJhdyAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWludCBbXSB0aGVDb250cm9sID0gbmV3IGludCBbMV07CisJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbURpcmVjdE9iamVjdCwgT1MudHlwZUNvbnRyb2xSZWYsIG51bGwsIDQsIG51bGwsIHRoZUNvbnRyb2wpOworCWludCBbXSByZWdpb24gPSBuZXcgaW50IFsxXTsJCisJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbVJnbkhhbmRsZSwgT1MudHlwZVFEUmduSGFuZGxlLCBudWxsLCA0LCBudWxsLCByZWdpb24pOworCWludCB2aXNpYmxlUmduID0gZ2V0VmlzaWJsZVJlZ2lvbiAodGhlQ29udHJvbCBbMF0pOworCWludCBvbGRDbGlwID0gT1MuTmV3UmduICgpOworCU9TLkdldENsaXAgKG9sZENsaXApOworCU9TLlNlY3RSZ24ocmVnaW9uIFswXSwgdmlzaWJsZVJnbiwgdmlzaWJsZVJnbik7CisJT1MuU2V0Q2xpcCAodmlzaWJsZVJnbik7CisJZHJhd1dpZGdldCAodGhlQ29udHJvbCBbMF0pOworCWludCByZXN1bHQgPSBPUy5DYWxsTmV4dEV2ZW50SGFuZGxlciAobmV4dEhhbmRsZXIsIHRoZUV2ZW50KTsKKwlPUy5TZXRDbGlwIChvbGRDbGlwKTsKKwlPUy5EaXNwb3NlUmduICh2aXNpYmxlUmduKTsKKwlPUy5EaXNwb3NlUmduIChvbGRDbGlwKTsKKwlyZXR1cm4gcmVzdWx0OworfQorCitpbnQga0V2ZW50Q29udHJvbEhpdCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRDb250cm9sU2V0Q3Vyc29yIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKworaW50IGtFdmVudENvbnRyb2xTZXRGb2N1c1BhcnQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50TWVudUNsb3NlZCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRNZW51T3BlbmluZyAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRNb3VzZURvd24gKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50TW91c2VEcmFnZ2VkIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKworaW50IGtFdmVudE1vdXNlTW92ZWQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50TW91c2VVcCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRNb3VzZVdoZWVsTW92ZWQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50UmF3S2V5VXAgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50UmF3S2V5UmVwZWF0IChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKworaW50IGtFdmVudFJhd0tleU1vZGlmaWVyc0NoYW5nZWQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50UmF3S2V5RG93biAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRXaW5kb3dBY3RpdmF0ZWQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50V2luZG93Qm91bmRzQ2hhbmdlZCAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRXaW5kb3dDbG9zZSAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKK2ludCBrRXZlbnRXaW5kb3dDb2xsYXBzZWQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50V2luZG93RGVhY3RpdmF0ZWQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50V2luZG93RXhwYW5kZWQgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQga0V2ZW50V2luZG93SGlkZGVuIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKworaW50IGtFdmVudFdpbmRvd1Nob3duIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKworaW50IGtleWJvYXJkUHJvYyAoaW50IG5leHRIYW5kbGVyLCBpbnQgdGhlRXZlbnQsIGludCB1c2VyRGF0YSkgeworCWludCBldmVudEtpbmQgPSBPUy5HZXRFdmVudEtpbmQgKHRoZUV2ZW50KTsKKwlzd2l0Y2ggKGV2ZW50S2luZCkgeworCQljYXNlIE9TLmtFdmVudFJhd0tleURvd246CQkJCXJldHVybiBrRXZlbnRSYXdLZXlEb3duIChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwkJY2FzZSBPUy5rRXZlbnRSYXdLZXlNb2RpZmllcnNDaGFuZ2VkOglyZXR1cm4ga0V2ZW50UmF3S2V5TW9kaWZpZXJzQ2hhbmdlZCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJCWNhc2UgT1Mua0V2ZW50UmF3S2V5UmVwZWF0OgkJCXJldHVybiBrRXZlbnRSYXdLZXlSZXBlYXQgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCQljYXNlIE9TLmtFdmVudFJhd0tleVVwOgkJCQlyZXR1cm4ga0V2ZW50UmF3S2V5VXAgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCX0KKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQgbWVudVByb2MgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsJCisJaW50IGV2ZW50S2luZCA9IE9TLkdldEV2ZW50S2luZCAodGhlRXZlbnQpOworCXN3aXRjaCAoZXZlbnRLaW5kKSB7CisJCWNhc2UgT1Mua0V2ZW50TWVudU9wZW5pbmc6CXJldHVybiBrRXZlbnRNZW51T3BlbmluZyAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJCWNhc2UgT1Mua0V2ZW50TWVudUNsb3NlZDoJcmV0dXJuIGtFdmVudE1lbnVDbG9zZWQgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCX0KKwlyZXR1cm4gT1MuZXZlbnROb3RIYW5kbGVkRXJyOworfQorCitpbnQgbW91c2VQcm9jIChpbnQgbmV4dEhhbmRsZXIsIGludCB0aGVFdmVudCwgaW50IHVzZXJEYXRhKSB7CisJaW50IGV2ZW50S2luZCA9IE9TLkdldEV2ZW50S2luZCAodGhlRXZlbnQpOworCXN3aXRjaCAoZXZlbnRLaW5kKSB7CisJCWNhc2UgT1Mua0V2ZW50TW91c2VEb3duOiAJCXJldHVybiBrRXZlbnRNb3VzZURvd24gKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCQljYXNlIE9TLmtFdmVudE1vdXNlVXA6IAkJcmV0dXJuIGtFdmVudE1vdXNlVXAgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCQljYXNlIE9TLmtFdmVudE1vdXNlRHJhZ2dlZDoJcmV0dXJuIGtFdmVudE1vdXNlRHJhZ2dlZCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisvLwkJY2FzZSBPUy5rRXZlbnRNb3VzZUVudGVyZWQ6CQlyZXR1cm4ga0V2ZW50TW91c2VFbnRlcmVkIChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKy8vCQljYXNlIE9TLmtFdmVudE1vdXNlRXhpdGVkOgkJcmV0dXJuIGtFdmVudE1vdXNlRXhpdGVkIChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwkJY2FzZSBPUy5rRXZlbnRNb3VzZU1vdmVkOgkJcmV0dXJuIGtFdmVudE1vdXNlTW92ZWQgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCQljYXNlIE9TLmtFdmVudE1vdXNlV2hlZWxNb3ZlZDoJcmV0dXJuIGtFdmVudE1vdXNlV2hlZWxNb3ZlZCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJfQorCXJldHVybiBPUy5ldmVudE5vdEhhbmRsZWRFcnI7Cit9CisKIHB1YmxpYyB2b2lkIG5vdGlmeUxpc3RlbmVycyAoaW50IGV2ZW50VHlwZSwgRXZlbnQgZXZlbnQpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChldmVudCA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwpAQCAtNDg0LDIzNyArNjAyLDM5IEBACiAJZXZlbnQud2lkZ2V0ID0gdGhpczsKIAlldmVudFRhYmxlLnNlbmRFdmVudCAoZXZlbnQpOwogfQorCiB2b2lkIHBvc3RFdmVudCAoaW50IGV2ZW50VHlwZSkgewotCWlmIChldmVudFRhYmxlID09IG51bGwpIHJldHVybjsKLQlwb3N0RXZlbnQgKGV2ZW50VHlwZSwgbmV3IEV2ZW50ICgpKTsKKwlzZW5kRXZlbnQgKGV2ZW50VHlwZSwgbnVsbCwgZmFsc2UpOwogfQorCiB2b2lkIHBvc3RFdmVudCAoaW50IGV2ZW50VHlwZSwgRXZlbnQgZXZlbnQpIHsKLQlpZiAoZXZlbnRUYWJsZSA9PSBudWxsKSByZXR1cm47Ci0JRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKLQlldmVudC50eXBlID0gZXZlbnRUeXBlOwotCWV2ZW50LndpZGdldCA9IHRoaXM7Ci0JZXZlbnQuZGlzcGxheSA9IGRpc3BsYXk7Ci0JaWYgKGV2ZW50LnRpbWUgPT0gMCkgewotICAgICAgICAvKiBBVwotCQlldmVudC50aW1lID0gT1MuWHRMYXN0VGltZXN0YW1wUHJvY2Vzc2VkIChkaXNwbGF5LnhEaXNwbGF5KTsKLSAgICAgICAgKi8KLQkJZXZlbnQudGltZSA9IChpbnQpKE9TLkdldExhc3RVc2VyRXZlbnRUaW1lKCkgKiAxMDAwLjApOwotCX0KLQlkaXNwbGF5LnBvc3RFdmVudCAoZXZlbnQpOworCXNlbmRFdmVudCAoZXZlbnRUeXBlLCBldmVudCwgZmFsc2UpOwogfQotaW50IHByb2Nlc3NBcm0gKE9iamVjdCBjYWxsRGF0YSkgewotCXJldHVybiAwOworCit2b2lkIHJlZHJhd1dpZGdldCAoaW50IGNvbnRyb2wpIHsKKwlpZiAoIU9TLklzQ29udHJvbFZpc2libGUgKGNvbnRyb2wpKSByZXR1cm47CisJUmVjdCByZWN0ID0gbmV3IFJlY3QgKCk7CisJT1MuR2V0Q29udHJvbEJvdW5kcyAoY29udHJvbCwgcmVjdCk7CisJaW50IHdpbmRvdyA9IE9TLkdldENvbnRyb2xPd25lciAoY29udHJvbCk7CisJT1MuSW52YWxXaW5kb3dSZWN0ICh3aW5kb3csIHJlY3QpOwogfQotaW50IHByb2Nlc3NEaXNwb3NlIChPYmplY3QgY2FsbERhdGEpIHsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzRGVmYXVsdFNlbGVjdGlvbiAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0JcmV0dXJuIDA7Ci19Ci1maW5hbCBpbnQgcHJvY2Vzc0V2ZW50IChpbnQgZXZlbnROdW1iZXIpIHsKLQlzd2l0Y2ggKGV2ZW50TnVtYmVyKSB7Ci0JY2FzZSBTV1QuRGlzcG9zZToJCXJldHVybiBwcm9jZXNzRGlzcG9zZSAobnVsbCk7Ci0JY2FzZSBTV1QuSGVscDoJCQlyZXR1cm4gcHJvY2Vzc0hlbHAgKG51bGwpOwotCWRlZmF1bHQ6Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigiV2lkZ2V0LnByb2Nlc3NFdmVudCgpOiB1bmV4cGVjdGVkIGV2ZW50Iik7Ci0JCWJyZWFrOwotCX0KLQlyZXR1cm4gMDsKLX0KLWZpbmFsIGludCBwcm9jZXNzRXZlbnQgKGludCBldmVudE51bWJlciwgTWFjQ29udHJvbEV2ZW50IG1jRXZlbnQpIHsKLQlzd2l0Y2ggKGV2ZW50TnVtYmVyKSB7Ci0JY2FzZSBTV1QuU2VsZWN0aW9uOglyZXR1cm4gcHJvY2Vzc1NlbGVjdGlvbiAobWNFdmVudCk7Ci0JY2FzZSBTV1QuUGFpbnQ6CQlyZXR1cm4gcHJvY2Vzc1BhaW50IChtY0V2ZW50KTsKLQlkZWZhdWx0OgotCQlTeXN0ZW0ub3V0LnByaW50bG4oIldpZGdldC5wcm9jZXNzRXZlbnQoTWFjTW91c2VFdmVudCk6IHVuZXhwZWN0ZWQgZXZlbnQiKTsKLQkJYnJlYWs7Ci0JfQotCXJldHVybiAwOwotfQotZmluYWwgaW50IHByb2Nlc3NFdmVudCAoaW50IGV2ZW50TnVtYmVyLCBNYWNNb3VzZUV2ZW50IG1tRXZlbnQpIHsKLQlzd2l0Y2ggKGV2ZW50TnVtYmVyKSB7Ci0JY2FzZSBTV1QuTW91c2VEb3duOglyZXR1cm4gcHJvY2Vzc01vdXNlRG93biAobW1FdmVudCk7Ci0JY2FzZSBTV1QuTW91c2VFbnRlcjoJcmV0dXJuIHByb2Nlc3NNb3VzZUVudGVyIChtbUV2ZW50KTsKLQljYXNlIFNXVC5Nb3VzZUV4aXQ6CXJldHVybiBwcm9jZXNzTW91c2VFeGl0IChtbUV2ZW50KTsKLQljYXNlIFNXVC5Nb3VzZUhvdmVyOglyZXR1cm4gcHJvY2Vzc01vdXNlSG92ZXIgKG1tRXZlbnQpOwotCWNhc2UgU1dULk1vdXNlTW92ZToJcmV0dXJuIHByb2Nlc3NNb3VzZU1vdmUgKG1tRXZlbnQpOwotCWNhc2UgU1dULk1vdXNlVXA6CQlyZXR1cm4gcHJvY2Vzc01vdXNlVXAgKG1tRXZlbnQpOwotCWRlZmF1bHQ6Ci0JCVN5c3RlbS5vdXQucHJpbnRsbigiV2lkZ2V0LnByb2Nlc3NFdmVudChNYWNNb3VzZUV2ZW50KTogdW5leHBlY3RlZCBldmVudCIpOwotCQlicmVhazsKLQl9Ci0JcmV0dXJuIDA7Ci19Ci1maW5hbCBpbnQgcHJvY2Vzc0V2ZW50IChpbnQgZXZlbnROdW1iZXIsIE1hY0V2ZW50IG1lKSB7Ci0Jc3dpdGNoIChldmVudE51bWJlcikgewotCWNhc2UgU1dULkFybToJCQlyZXR1cm4gcHJvY2Vzc0FybSAobWUpOwotCWNhc2UgU1dULkRlZmF1bHRTZWxlY3Rpb246CXJldHVybiBwcm9jZXNzRGVmYXVsdFNlbGVjdGlvbiAobWUpOwotCWNhc2UgU1dULkhpZGU6CQkJcmV0dXJuIHByb2Nlc3NIaWRlIChtZSk7Ci0JY2FzZSBTV1QuS2V5RG93bjoJCXJldHVybiBwcm9jZXNzS2V5RG93biAobWUpOwotCWNhc2UgU1dULktleVVwOgkJcmV0dXJuIHByb2Nlc3NLZXlVcCAobWUpOwotCWNhc2UgU1dULk1vZGlmeToJCXJldHVybiBwcm9jZXNzTW9kaWZ5IChtZSk7Ci0JY2FzZSBTV1QuU2hvdzoJCQlyZXR1cm4gcHJvY2Vzc1Nob3cgKG1lKTsKLQljYXNlIFNXVC5WZXJpZnk6CQlyZXR1cm4gcHJvY2Vzc1ZlcmlmeSAobWUpOwotCWNhc2UgLTE6CQkJCXJldHVybiBwcm9jZXNzTm9uTWFza2FibGUgKG1lKTsKLQlkZWZhdWx0OgotCQlTeXN0ZW0ub3V0LnByaW50bG4oIldpZGdldC5wcm9jZXNzRXZlbnQoT2JqZWN0KTogdW5leHBlY3RlZCBldmVudCIpOwotCQlicmVhazsKLQl9Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc0hlbHAgKE9iamVjdCBjYWxsRGF0YSkgewotCXJldHVybiAwOwotfQotaW50IHByb2Nlc3NIaWRlIChPYmplY3QgY2FsbERhdGEpIHsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzS2V5RG93biAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc0tleVVwIChPYmplY3QgY2FsbERhdGEpIHsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzTW9kaWZ5IChPYmplY3QgY2FsbERhdGEpIHsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzTW91c2VEb3duIChNYWNNb3VzZUV2ZW50IG1tZSkgewotCXJldHVybiAwOwotfQotaW50IHByb2Nlc3NNb3VzZUVudGVyIChNYWNNb3VzZUV2ZW50IG1tZSkgewotCXJldHVybiAwOwotfQotaW50IHByb2Nlc3NNb3VzZUV4aXQgKE1hY01vdXNlRXZlbnQgbW1lKSB7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc01vdXNlSG92ZXIgKE1hY01vdXNlRXZlbnQgbW1lKSB7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc01vdXNlTW92ZSAoTWFjTW91c2VFdmVudCBtbWUpIHsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzTW91c2VVcCAoTWFjTW91c2VFdmVudCBtbWUpIHsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzTm9uTWFza2FibGUgKE9iamVjdCBjYWxsRGF0YSkgewotCXJldHVybiAwOwotfQotaW50IHByb2Nlc3NQYWludCAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc1Jlc2l6ZSAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc1NlbGVjdGlvbiAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc1NldEZvY3VzIChPYmplY3QgY2FsbERhdGEpIHsKLQlyZXR1cm4gMDsKLX0KLWludCBwcm9jZXNzU2hvdyAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0JcmV0dXJuIDA7Ci19Ci1pbnQgcHJvY2Vzc1ZlcmlmeSAoT2JqZWN0IGNhbGxEYXRhKSB7Ci0JcmV0dXJuIDA7Ci19Ci12b2lkIHByb3BhZ2F0ZUhhbmRsZSAoYm9vbGVhbiBlbmFibGVkLCBpbnQgd2lkZ2V0SGFuZGxlKSB7Ci0JLyogQVcKLQlpbnQgeERpc3BsYXkgPSBPUy5YdERpc3BsYXkgKHdpZGdldEhhbmRsZSk7Ci0JaWYgKHhEaXNwbGF5ID09IDApIHJldHVybjsKLQlpbnQgeFdpbmRvdyA9IE9TLlh0V2luZG93ICh3aWRnZXRIYW5kbGUpOwotCWlmICh4V2luZG93ID09IDApIHJldHVybjsKLQkqLwotCS8qCi0JKiBHZXQgdGhlIGV2ZW50IG1hc2sgZnJvbSB0aGUgd2lkZ2V0LiAgVGhlIGV2ZW50IG1hc2sKLQkqIHJldHVybmVkIGJ5IFh0QnVpbGRFdmVudE1hc2sgKCkgaW5jbHVkZXMgdGhlIG1hc2tzCi0JKiBhc3NvY2lhdGVkIHdpdGggYWxsIGNhbGxiYWNrcyBhbmQgZXZlbnQgaGFuZGxlcnMKLQkqIHRoYXQgaGF2ZSBiZWVuIGhvb2tlZCBvbiB0aGUgd2lkZ2V0LgotCSovCi0gICAgICAgIC8qIEFXCi0JaW50IGV2ZW50X21hc2sgPSBPUy5YdEJ1aWxkRXZlbnRNYXNrICh3aWRnZXRIYW5kbGUpOwotCWludCBkb19ub3RfcHJvcGFnYXRlX21hc2sgPQotCQlPUy5LZXlQcmVzc01hc2sgfCBPUy5LZXlSZWxlYXNlTWFzayB8IE9TLkJ1dHRvblByZXNzTWFzayB8Ci0JCU9TLkJ1dHRvblJlbGVhc2VNYXNrIHwgT1MuUG9pbnRlck1vdGlvbk1hc2s7Ci0JaWYgKCFlbmFibGVkKSB7Ci0gICAgICAgICovCi0JCS8qCi0JCSogQXR0ZW1wdGluZyB0byBwcm9wb2dhdGUgRW50ZXJXaW5kb3dNYXNrIGFuZCBMZWF2ZVdpbmRvd01hc2sKLQkJKiBjYXVzZXMgYW4gWCBlcnJvciBzbyB0aGVzZSBtdXN0IGJlIHNwZWNpYWxseSBjbGVhcmVkIG91dCBmcm9tCi0JCSogdGhlIGV2ZW50IG1hc2ssIG5vdCBpbmNsdWRlZCBpbiB0aGUgcHJvcG9nYXRlIG1hc2suCi0JCSovCi0gICAgICAgICAgICAgICAgLyogQVcKLQkJZXZlbnRfbWFzayAmPSB+KGRvX25vdF9wcm9wYWdhdGVfbWFzayB8IE9TLkVudGVyV2luZG93TWFzayB8IE9TLkxlYXZlV2luZG93TWFzayk7Ci0JCWRvX25vdF9wcm9wYWdhdGVfbWFzayA9IDA7Ci0JfQotCVhTZXRXaW5kb3dBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMgPSBuZXcgWFNldFdpbmRvd0F0dHJpYnV0ZXMgKCk7Ci0JYXR0cmlidXRlcy5ldmVudF9tYXNrID0gZXZlbnRfbWFzazsKLQlhdHRyaWJ1dGVzLmRvX25vdF9wcm9wYWdhdGVfbWFzayA9IGRvX25vdF9wcm9wYWdhdGVfbWFzazsKLQlPUy5YQ2hhbmdlV2luZG93QXR0cmlidXRlcyAoeERpc3BsYXksIHhXaW5kb3csIE9TLkNXRG9udFByb3BhZ2F0ZSB8IE9TLkNXRXZlbnRNYXNrLCBhdHRyaWJ1dGVzKTsKLQlpbnQgW10gYXJnTGlzdCA9IHtPUy5YbU50cmF2ZXJzYWxPbiwgZW5hYmxlZCA/IDEgOiAwfTsKLQlPUy5YdFNldFZhbHVlcyAod2lkZ2V0SGFuZGxlLCBhcmdMaXN0LCBhcmdMaXN0Lmxlbmd0aCAvIDIpOwotICAgICovCi19Ci1maW5hbCB2b2lkIHJlZHJhd0hhbmRsZSAoaW50IHgsIGludCB5LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCB3aWRnZXRIYW5kbGUsIGJvb2xlYW4gYWxsKSB7Ci0gICAgLyogQVcKLQlpbnQgZGlzcGxheSA9IE9TLlh0RGlzcGxheSAod2lkZ2V0SGFuZGxlKTsKLQlpZiAoZGlzcGxheSA9PSAwKSByZXR1cm47Ci0JaW50IHdpbmRvdyA9IE9TLlh0V2luZG93ICh3aWRnZXRIYW5kbGUpOwotCWlmICh3aW5kb3cgPT0gMCkgcmV0dXJuOwotCWludCBbXSBhcmdMaXN0ID0ge09TLlhtTmJvcmRlcldpZHRoLCAwLCBPUy5YbU5ib3JkZXJDb2xvciwgMH07Ci0JT1MuWHRHZXRWYWx1ZXMgKHdpZGdldEhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQlpZiAoYXJnTGlzdCBbMV0gIT0gMCkgewotICAgICAgICAqLwotCQkvKiBGb3JjZSB0aGUgYm9yZGVyIHRvIHJlcGFpbnQgYnkgc2V0dGluZyB0aGUgY29sb3IgKi8KLQkJLyoKLQkJT1MuWHRTZXRWYWx1ZXMgKHdpZGdldEhhbmRsZSwgYXJnTGlzdCwgYXJnTGlzdC5sZW5ndGggLyAyKTsKLQl9Ci0JT1MuWENsZWFyQXJlYSAoZGlzcGxheSwgd2luZG93LCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCB0cnVlKTsKLQkqLwotCQotCWlmIChmYWxzZSkgewotCQlpbnQgcmduPSBPUy5OZXdSZ24oKTsKLQkJT1MuUmVjdFJnbihyZ24sIG5ldyBNYWNSZWN0KHgsIHksIHdpZHRoLCBoZWlnaHQpLmdldERhdGEoKSk7Ci0JCU9TLkhJVmlld1NldE5lZWRzRGlzcGxheUluUmVnaW9uKHdpZGdldEhhbmRsZSwgcmduLCB0cnVlKTsKLQkJT1MuRGlzcG9zZVJnbihyZ24pOwotCX0gZWxzZSB7Ci0JCU1hY1JlY3QgYnI9IG5ldyBNYWNSZWN0KCk7Ci0JCU9TLkdldENvbnRyb2xCb3VuZHMod2lkZ2V0SGFuZGxlLCBici5nZXREYXRhKCkpOwotCSAgICBpZiAoIWJyLmlzRW1wdHkoKSkgewotCSAgICAgICAgeCs9IGJyLmdldFgoKTsKLQkgICAgICAgIHkrPSBici5nZXRZKCk7Ci0JICAgICAgICBpZiAod2lkdGggPT0gMCkKLQkgICAgICAgIAl3aWR0aD0gYnIuZ2V0V2lkdGgoKTsKLQkgICAgICAgIGVsc2UKLQkJCQl3aWR0aCs9IDE7IC8vIEFXIHN0cmFuZ2Ugd29ya2Fyb3VuZCBmb3IgQ2FyZXQKLQkgICAgICAgIGlmIChoZWlnaHQgPT0gMCkKLQkJCQloZWlnaHQ9IGJyLmdldEhlaWdodCgpOwotCSAgICAgICAgICAgICAgICAKLQkgICAgICAgIGludCByZ249IE9TLk5ld1JnbigpOwotCSAgICAgICAgT1MuUmVjdFJnbihyZ24sIG5ldyBNYWNSZWN0KHgsIHksIHdpZHRoLCBoZWlnaHQpLmdldERhdGEoKSk7Ci0JICAgICAgICAgICAgICAgIAotCSAgICAgICAgaW50IHJlZ2lvbj0gT1MuTmV3UmduKCk7Ci0JICAgICAgICBpZiAoTWFjVXRpbC5nZXRWaXNpYmxlUmVnaW9uKHdpZGdldEhhbmRsZSwgcmVnaW9uLCBhbGwpID09IE9TLmtOb0VycikgewotCSAgICAgICAgCi0JICAgICAgICAgICAgT1MuU2VjdFJnbihyZWdpb24sIHJnbiwgcmVnaW9uKTsKLQkgICAgICAgIAotCSAgICAgICAgICAgIE9TLkludmFsV2luZG93UmduKE9TLkdldENvbnRyb2xPd25lcih3aWRnZXRIYW5kbGUpLCByZWdpb24pOwotCSAgICAgICAgfQotCSAgICAgICAgCi0JICAgICAgICBPUy5EaXNwb3NlUmduKHJnbik7Ci0JICAgICAgICBPUy5EaXNwb3NlUmduKHJlZ2lvbik7Ci0JICAgIH0KLQl9Ci19CisKIHZvaWQgcmVnaXN0ZXIgKCkgewotCWlmIChoYW5kbGUgPT0gMCkgcmV0dXJuOwotCVdpZGdldFRhYmxlLnB1dCAoaGFuZGxlLCB0aGlzKTsKIH0KKwogdm9pZCByZWxlYXNlQ2hpbGQgKCkgewogCS8qIERvIG5vdGhpbmcgKi8KIH0KKwogdm9pZCByZWxlYXNlSGFuZGxlICgpIHsKLQloYW5kbGUgPSAwOwogCXN0YXRlIHw9IERJU1BPU0VEOwogfQorCit2b2lkIHJlbGVhc2VSZXNvdXJjZXMgKCkgeworCXJlbGVhc2VXaWRnZXQgKCk7CisJcmVsZWFzZUhhbmRsZSAoKTsKK30KKwogdm9pZCByZWxlYXNlV2lkZ2V0ICgpIHsKIAlzZW5kRXZlbnQgKFNXVC5EaXNwb3NlKTsKIAlkZXJlZ2lzdGVyICgpOwpAQCAtNzIzLDE2MyArNjQzLDEyNCBAQAogCWtleXMgPSBudWxsOwogCXZhbHVlcyA9IG51bGw7CiB9Ci0vKioKLSAqIFJlbW92ZXMgdGhlIGxpc3RlbmVyIGZyb20gdGhlIGNvbGxlY3Rpb24gb2YgbGlzdGVuZXJzIHdobyB3aWxsCi0gKiBiZSBub3RpZmVkIHdoZW4gYW4gZXZlbnQgb2YgdGhlIGdpdmVuIHR5cGUgb2NjdXJzLgotICoKLSAqIEBwYXJhbSBldmVudFR5cGUgdGhlIHR5cGUgb2YgZXZlbnQgdG8gbGlzdGVuIGZvcgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgbm8gbG9uZ2VyIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGV2ZW50IG9jY3VycwotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIExpc3RlbmVyCi0gKiBAc2VlICNhZGRMaXN0ZW5lcgotICovCisKIHB1YmxpYyB2b2lkIHJlbW92ZUxpc3RlbmVyIChpbnQgZXZlbnRUeXBlLCBMaXN0ZW5lciBoYW5kbGVyKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoaGFuZGxlciA9PSBudWxsKSBlcnJvciAoU1dULkVSUk9SX05VTExfQVJHVU1FTlQpOwogCWlmIChldmVudFRhYmxlID09IG51bGwpIHJldHVybjsKIAlldmVudFRhYmxlLnVuaG9vayAoZXZlbnRUeXBlLCBoYW5kbGVyKTsKIH0KLS8qKgotICogUmVtb3ZlcyB0aGUgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBvZiBsaXN0ZW5lcnMgd2hvIHdpbGwKLSAqIGJlIG5vdGlmZWQgd2hlbiBhbiBldmVudCBvZiB0aGUgZ2l2ZW4gdHlwZSBvY2N1cnMuCi0gKiA8cD4KLSAqIDxiPklNUE9SVEFOVDo8L2I+IFRoaXMgbWV0aG9kIGlzIDxlbT5ub3Q8L2VtPiBwYXJ0IG9mIHRoZSBTV1QKLSAqIHB1YmxpYyBBUEkuIEl0IGlzIG1hcmtlZCBwdWJsaWMgb25seSBzbyB0aGF0IGl0IGNhbiBiZSBzaGFyZWQKLSAqIHdpdGhpbiB0aGUgcGFja2FnZXMgcHJvdmlkZWQgYnkgU1dULiBJdCBzaG91bGQgbmV2ZXIgYmUKLSAqIHJlZmVyZW5jZWQgZnJvbSBhcHBsaWNhdGlvbiBjb2RlLgotICogPC9wPgotICoKLSAqIEBwYXJhbSBldmVudFR5cGUgdGhlIHR5cGUgb2YgZXZlbnQgdG8gbGlzdGVuIGZvcgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgbm8gbG9uZ2VyIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGV2ZW50IG9jY3VycwotICoKLSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9OVUxMX0FSR1VNRU5UIC0gaWYgdGhlIGxpc3RlbmVyIGlzIG51bGw8L2xpPgotICogPC91bD4KLSAqIEBleGNlcHRpb24gU1dURXhjZXB0aW9uIDx1bD4KLSAqICAgIDxsaT5FUlJPUl9XSURHRVRfRElTUE9TRUQgLSBpZiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIGlmIG5vdCBjYWxsZWQgZnJvbSB0aGUgdGhyZWFkIHRoYXQgY3JlYXRlZCB0aGUgcmVjZWl2ZXI8L2xpPgotICogPC91bD4KLSAqCi0gKiBAc2VlIExpc3RlbmVyCi0gKiBAc2VlICNhZGRMaXN0ZW5lcgotICovCisKIHByb3RlY3RlZCB2b2lkIHJlbW92ZUxpc3RlbmVyIChpbnQgZXZlbnRUeXBlLCBTV1RFdmVudExpc3RlbmVyIGhhbmRsZXIpIHsKIAljaGVja1dpZGdldCgpOwogCWlmIChoYW5kbGVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaWYgKGV2ZW50VGFibGUgPT0gbnVsbCkgcmV0dXJuOwogCWV2ZW50VGFibGUudW5ob29rIChldmVudFR5cGUsIGhhbmRsZXIpOwogfQotLyoqCi0gKiBSZW1vdmVzIHRoZSBsaXN0ZW5lciBmcm9tIHRoZSBjb2xsZWN0aW9uIG9mIGxpc3RlbmVycyB3aG8gd2lsbAotICogYmUgbm90aWZlZCB3aGVuIHRoZSB3aWRnZXQgaXMgZGlzcG9zZWQuCi0gKgotICogQHBhcmFtIGxpc3RlbmVyIHRoZSBsaXN0ZW5lciB3aGljaCBzaG91bGQgbm8gbG9uZ2VyIGJlIG5vdGlmaWVkIHdoZW4gdGhlIHJlY2VpdmVyIGlzIGRpc3Bvc2VkCi0gKgotICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX05VTExfQVJHVU1FTlQgLSBpZiB0aGUgbGlzdGVuZXIgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgRGlzcG9zZUxpc3RlbmVyCi0gKiBAc2VlICNhZGREaXNwb3NlTGlzdGVuZXIKLSAqLworCiBwdWJsaWMgdm9pZCByZW1vdmVEaXNwb3NlTGlzdGVuZXIgKERpc3Bvc2VMaXN0ZW5lciBsaXN0ZW5lcikgewogCWNoZWNrV2lkZ2V0KCk7CiAJaWYgKGxpc3RlbmVyID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CiAJaWYgKGV2ZW50VGFibGUgPT0gbnVsbCkgcmV0dXJuOwogCWV2ZW50VGFibGUudW5ob29rIChTV1QuRGlzcG9zZSwgbGlzdGVuZXIpOwogfQorCit2b2lkIHNlbmRFdmVudCAoRXZlbnQgZXZlbnQpIHsKKwlEaXNwbGF5IGRpc3BsYXkgPSBldmVudC5kaXNwbGF5OworCWlmICghZGlzcGxheS5maWx0ZXJFdmVudCAoZXZlbnQpKSB7CisJCWlmIChldmVudFRhYmxlICE9IG51bGwpIGV2ZW50VGFibGUuc2VuZEV2ZW50IChldmVudCk7CisJfQorfQorCiB2b2lkIHNlbmRFdmVudCAoaW50IGV2ZW50VHlwZSkgewotCWlmIChldmVudFRhYmxlID09IG51bGwpIHJldHVybjsKLQlzZW5kRXZlbnQgKGV2ZW50VHlwZSwgbmV3IEV2ZW50ICgpKTsKKwlzZW5kRXZlbnQgKGV2ZW50VHlwZSwgbnVsbCwgdHJ1ZSk7CiB9Ci0vKgotZmluYWwgdm9pZCBzZXRJbnB1dFN0YXRlIChFdmVudCBldmVudCwgTWFjRXZlbnQgbUV2ZW50KSB7Ci0JZXZlbnQuc3RhdGVNYXNrPSBtRXZlbnQuZ2V0U3RhdGVNYXNrKCk7Ci19Ci0qLwotdm9pZCBzZXRLZXlTdGF0ZSAoRXZlbnQgZXZlbnQsIE1hY0V2ZW50IG1FdmVudCkgewotCWludCBrYz0gRGlzcGxheS50cmFuc2xhdGVLZXkobUV2ZW50LmdldEtleUNvZGUoKSk7Ci0JaWYgKGtjICE9IDApIHsKLQkJZXZlbnQua2V5Q29kZSA9IGtjOwotCX0gZWxzZSB7Ci0JCS8vZXZlbnQua2V5Q29kZSA9IDA7Ci0JCWV2ZW50LmNoYXJhY3RlciA9IChjaGFyKSBtRXZlbnQuZ2V0TWFjQ2hhckNvZGVzKCk7Ci0JfQkKLQkvLyBBVyBzZXRJbnB1dFN0YXRlIChldmVudCwgbUV2ZW50KTsKLQlldmVudC5zdGF0ZU1hc2s9IG1FdmVudC5nZXRTdGF0ZU1hc2soKTsKLX0KKwogdm9pZCBzZW5kRXZlbnQgKGludCBldmVudFR5cGUsIEV2ZW50IGV2ZW50KSB7Ci0JaWYgKGV2ZW50VGFibGUgPT0gbnVsbCkgcmV0dXJuOworCXNlbmRFdmVudCAoZXZlbnRUeXBlLCBldmVudCwgdHJ1ZSk7Cit9CisKK3ZvaWQgc2VuZEV2ZW50IChpbnQgZXZlbnRUeXBlLCBFdmVudCBldmVudCwgYm9vbGVhbiBzZW5kKSB7CiAJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwlpZiAoZXZlbnRUYWJsZSA9PSBudWxsICYmICFkaXNwbGF5LmZpbHRlcnMgKGV2ZW50VHlwZSkpIHsKKwkJcmV0dXJuOworCX0KKwlpZiAoZXZlbnQgPT0gbnVsbCkgZXZlbnQgPSBuZXcgRXZlbnQgKCk7CiAJZXZlbnQudHlwZSA9IGV2ZW50VHlwZTsKIAlldmVudC5kaXNwbGF5ID0gZGlzcGxheTsKIAlldmVudC53aWRnZXQgPSB0aGlzOwogCWlmIChldmVudC50aW1lID09IDApIHsKLQkJZXZlbnQudGltZSA9IChpbnQpKE9TLkdldExhc3RVc2VyRXZlbnRUaW1lKCkgKiAxMDAwLjApOworCQlldmVudC50aW1lID0gZGlzcGxheS5nZXRMYXN0RXZlbnRUaW1lICgpOwogCX0KLQlldmVudFRhYmxlLnNlbmRFdmVudCAoZXZlbnQpOworCWlmIChzZW5kKSB7CisJCXNlbmRFdmVudCAoZXZlbnQpOworCX0gZWxzZSB7CisJCWRpc3BsYXkucG9zdEV2ZW50IChldmVudCk7CisJfQogfQotLyoqCi0gKiBTZXRzIHRoZSBhcHBsaWNhdGlvbiBkZWZpbmVkIHdpZGdldCBkYXRhIGFzc29jaWF0ZWQKLSAqIHdpdGggdGhlIHJlY2VpdmVyIHRvIGJlIHRoZSBhcmd1bWVudC4gVGhlIDxlbT53aWRnZXQKLSAqIGRhdGE8L2VtPiBpcyBhIHNpbmdsZSwgdW5uYW1lZCBmaWVsZCB0aGF0IGlzIHN0b3JlZAotICogd2l0aCBldmVyeSB3aWRnZXQuIAotICogPHA+Ci0gKiBBcHBsaWNhdGlvbnMgbWF5IHB1dCBhcmJpdHJhcnkgb2JqZWN0cyBpbiB0aGlzIGZpZWxkLiBJZgotICogdGhlIG9iamVjdCBzdG9yZWQgaW4gdGhlIHdpZGdldCBkYXRhIG5lZWRzIHRvIGJlIG5vdGlmaWVkCi0gKiB3aGVuIHRoZSB3aWRnZXQgaXMgZGlzcG9zZWQgb2YsIGl0IGlzIHRoZSBhcHBsaWNhdGlvbidzCi0gKiByZXNwb25zaWJpbGl0eSB0byBob29rIHRoZSBEaXNwb3NlIGV2ZW50IG9uIHRoZSB3aWRnZXQgYW5kCi0gKiBkbyBzby4KLSAqIDwvcD4KLSAqCi0gKiBAcGFyYW0gZGF0YSB0aGUgd2lkZ2V0IGRhdGEKLSAqCi0gKiBAZXhjZXB0aW9uIFNXVEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfV0lER0VUX0RJU1BPU0VEIC0gd2hlbiB0aGUgcmVjZWl2ZXIgaGFzIGJlZW4gZGlzcG9zZWQ8L2xpPgotICogICAgPGxpPkVSUk9SX1RIUkVBRF9JTlZBTElEX0FDQ0VTUyAtIHdoZW4gY2FsbGVkIGZyb20gdGhlIHdyb25nIHRocmVhZDwvbGk+Ci0gKiA8L3VsPgotICovCisKK2ludCBzZXRCb3VuZHMgKGludCBjb250cm9sLCBpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwgYm9vbGVhbiBtb3ZlLCBib29sZWFuIHJlc2l6ZSwgYm9vbGVhbiBldmVudHMpIHsKKwlSZWN0IGluc2V0ID0gZ2V0SW5zZXQgKCk7CisJUmVjdCBvbGRCb3VuZHMgPSBuZXcgUmVjdCAoKTsKKwlPUy5HZXRDb250cm9sQm91bmRzIChjb250cm9sLCBvbGRCb3VuZHMpOworCW9sZEJvdW5kcy5sZWZ0IC09IGluc2V0LmxlZnQ7CisJb2xkQm91bmRzLnRvcCAtPSBpbnNldC50b3A7CisJb2xkQm91bmRzLnJpZ2h0ICs9IGluc2V0LnJpZ2h0OworCW9sZEJvdW5kcy5ib3R0b20gKz0gaW5zZXQuYm90dG9tOworCWJvb2xlYW4gdmlzaWJsZSA9IE9TLklzQ29udHJvbFZpc2libGUgKGNvbnRyb2wpOworCWludCB3aW5kb3cgPSBPUy5HZXRDb250cm9sT3duZXIgKGNvbnRyb2wpOworCWlmICh2aXNpYmxlKSBPUy5JbnZhbFdpbmRvd1JlY3QgKHdpbmRvdywgb2xkQm91bmRzKTsKKwl4ICs9IGluc2V0LmxlZnQ7CisJeSArPSBpbnNldC50b3A7CisJd2lkdGggLT0gKGluc2V0LmxlZnQgKyBpbnNldC5yaWdodCk7CisJaGVpZ2h0IC09IChpbnNldC50b3AgKyBpbnNldC5ib3R0b20pOworCWlmIChtb3ZlKSB7CisJCWludCBbXSB0aGVSb290ID0gbmV3IGludCBbMV07CisJCU9TLkdldFJvb3RDb250cm9sICh3aW5kb3csIHRoZVJvb3QpOworCQlpbnQgW10gcGFyZW50SGFuZGxlID0gbmV3IGludCBbMV07CisJCU9TLkdldFN1cGVyQ29udHJvbCAoY29udHJvbCwgcGFyZW50SGFuZGxlKTsKKwkJaWYgKHBhcmVudEhhbmRsZSBbMF0gIT0gdGhlUm9vdCBbMF0pIHsKKwkJCVJlY3QgcmVjdCA9IG5ldyBSZWN0ICgpOworCQkJT1MuR2V0Q29udHJvbEJvdW5kcyAocGFyZW50SGFuZGxlIFswXSwgcmVjdCk7CisJCQl4ICs9IHJlY3QubGVmdDsKKwkJCXkgKz0gcmVjdC50b3A7CisJCX0KKwl9IGVsc2UgeworCQl4ID0gb2xkQm91bmRzLmxlZnQ7CisJCXkgPSBvbGRCb3VuZHMudG9wOworCX0KKwlpZiAoIXJlc2l6ZSkgeworCQl3aWR0aCA9IG9sZEJvdW5kcy5yaWdodCAtIG9sZEJvdW5kcy5sZWZ0OworCQloZWlnaHQgPSBvbGRCb3VuZHMuYm90dG9tIC0gb2xkQm91bmRzLnRvcDsKKwl9CisJd2lkdGggPSBNYXRoLm1heCAoMCwgd2lkdGgpOworCWhlaWdodCA9IE1hdGgubWF4ICgwLCBoZWlnaHQpOworCWJvb2xlYW4gc2FtZU9yaWdpbiA9IHggPT0gb2xkQm91bmRzLmxlZnQgJiYgeSA9PSBvbGRCb3VuZHMudG9wOworCWJvb2xlYW4gc2FtZUV4dGVudCA9IHdpZHRoID09IChvbGRCb3VuZHMucmlnaHQgLSBvbGRCb3VuZHMubGVmdCkgJiYgaGVpZ2h0ID09IChvbGRCb3VuZHMuYm90dG9tIC0gb2xkQm91bmRzLnRvcCk7CisJUmVjdCBuZXdCb3VuZHMgPSBuZXcgUmVjdCAoKTsKKwluZXdCb3VuZHMubGVmdCA9IChzaG9ydCkgeDsKKwluZXdCb3VuZHMudG9wID0gKHNob3J0KSB5OworCW5ld0JvdW5kcy5yaWdodCA9IChzaG9ydCkgKHggKyB3aWR0aCk7CisJbmV3Qm91bmRzLmJvdHRvbSA9IChzaG9ydCkgKHkgKyBoZWlnaHQpOworCU9TLlNldENvbnRyb2xCb3VuZHMgKGNvbnRyb2wsIG5ld0JvdW5kcyk7CisJaWYgKHZpc2libGUpIE9TLkludmFsV2luZG93UmVjdCAod2luZG93LCBuZXdCb3VuZHMpOworCWludCByZXN1bHQgPSAwOworCWlmIChtb3ZlICYmICFzYW1lT3JpZ2luKSB7CisJCWlmIChldmVudHMpIHNlbmRFdmVudCAoU1dULk1vdmUpOworCQlyZXN1bHQgfD0gTU9WRUQ7CisJfQorCWlmIChyZXNpemUgJiYgIXNhbWVFeHRlbnQpIHsKKwkJaWYgKGV2ZW50cykgc2VuZEV2ZW50IChTV1QuTW92ZSk7CisJCXJlc3VsdCB8PSBSRVNJWkVEOworCX0KKwlyZXR1cm4gcmVzdWx0OworfQorCiBwdWJsaWMgdm9pZCBzZXREYXRhIChPYmplY3QgZGF0YSkgewogCWNoZWNrV2lkZ2V0KCk7CiAJdGhpcy5kYXRhID0gZGF0YTsKIH0KIAotLyoqCi0gKiBTZXRzIHRoZSBhcHBsaWNhdGlvbiBkZWZpbmVkIHByb3BlcnR5IG9mIHRoZSByZWNlaXZlcgotICogd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgdG8gdGhlIGdpdmVuIHZhbHVlLgotICogPHA+Ci0gKiBBcHBsaWNhdGlvbnMgbWF5IGFzc29jaWF0ZSBhcmJpdHJhcnkgb2JqZWN0cyB3aXRoIHRoZQotICogcmVjZWl2ZXIgaW4gdGhpcyBmYXNoaW9uLiBJZiB0aGUgb2JqZWN0cyBzdG9yZWQgaW4gdGhlCi0gKiBwcm9wZXJ0aWVzIG5lZWQgdG8gYmUgbm90aWZpZWQgd2hlbiB0aGUgd2lkZ2V0IGlzIGRpc3Bvc2VkCi0gKiBvZiwgaXQgaXMgdGhlIGFwcGxpY2F0aW9uJ3MgcmVzcG9uc2liaWxpdHkgdG8gaG9vayB0aGUKLSAqIERpc3Bvc2UgZXZlbnQgb24gdGhlIHdpZGdldCBhbmQgZG8gc28uCi0gKiA8L3A+Ci0gKgotICogQHBhcmFtIGtleSB0aGUgbmFtZSBvZiB0aGUgcHJvcGVydHkKLSAqIEBwYXJhbSB2YWx1ZSB0aGUgbmV3IHZhbHVlIGZvciB0aGUgcHJvcGVydHkKLSAqCi0gKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA8dWw+Ci0gKiAgICA8bGk+RVJST1JfTlVMTF9BUkdVTUVOVCAtIGlmIHRoZSBrZXkgaXMgbnVsbDwvbGk+Ci0gKiA8L3VsPgotICogQGV4Y2VwdGlvbiBTV1RFeGNlcHRpb24gPHVsPgotICogICAgPGxpPkVSUk9SX1dJREdFVF9ESVNQT1NFRCAtIGlmIHRoZSByZWNlaXZlciBoYXMgYmVlbiBkaXNwb3NlZDwvbGk+Ci0gKiAgICA8bGk+RVJST1JfVEhSRUFEX0lOVkFMSURfQUNDRVNTIC0gaWYgbm90IGNhbGxlZCBmcm9tIHRoZSB0aHJlYWQgdGhhdCBjcmVhdGVkIHRoZSByZWNlaXZlcjwvbGk+Ci0gKiA8L3VsPgotICoKLSAqIEBzZWUgI2dldERhdGEKLSAqLwogcHVibGljIHZvaWQgc2V0RGF0YSAoU3RyaW5nIGtleSwgT2JqZWN0IHZhbHVlKSB7CiAJY2hlY2tXaWRnZXQoKTsKIAlpZiAoa2V5ID09IG51bGwpIGVycm9yIChTV1QuRVJST1JfTlVMTF9BUkdVTUVOVCk7CkBAIC05MjgsMTIgKzgwOSwxMjAgQEAKIAl2YWx1ZXMgPSBuZXdWYWx1ZXM7CiB9CiAKLS8qKgotICogUmV0dXJucyBhIHN0cmluZyBjb250YWluaW5nIGEgY29uY2lzZSwgaHVtYW4tcmVhZGFibGUKLSAqIGRlc2NyaXB0aW9uIG9mIHRoZSByZWNlaXZlci4KLSAqCi0gKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSByZWNlaXZlcgotICovCit2b2lkIHNldElucHV0U3RhdGUgKEV2ZW50IGV2ZW50LCBpbnQgdGhlRXZlbnQpIHsKKwlzaG9ydCBbXSBidXR0b24gPSBuZXcgc2hvcnQgWzFdOworCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1Nb3VzZUJ1dHRvbiwgT1MudHlwZU1vdXNlQnV0dG9uLCBudWxsLCAyLCBudWxsLCBidXR0b24pOworCWludCBbXSBjaG9yZCA9IG5ldyBpbnQgWzFdOworCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1Nb3VzZUNob3JkLCBPUy50eXBlVUludDMyLCBudWxsLCA0LCBudWxsLCBjaG9yZCk7CisJaW50IFtdIG1vZGlmaWVycyA9IG5ldyBpbnQgWzFdOworCU9TLkdldEV2ZW50UGFyYW1ldGVyICh0aGVFdmVudCwgT1Mua0V2ZW50UGFyYW1LZXlNb2RpZmllcnMsIE9TLnR5cGVVSW50MzIsIG51bGwsIDQsIG51bGwsIG1vZGlmaWVycyk7CisJc2V0SW5wdXRTdGF0ZSAoZXZlbnQsIGJ1dHRvbiBbMF0sIGNob3JkIFswXSwgbW9kaWZpZXJzIFswXSk7Cit9CisKK3ZvaWQgc2V0SW5wdXRTdGF0ZSAoRXZlbnQgZXZlbnQsIHNob3J0IGJ1dHRvbiwgaW50IGNob3JkLCBpbnQgbW9kaWZpZXJzKSB7CisJc3dpdGNoIChidXR0b24pIHsKKwkJY2FzZSAxOiBldmVudC5idXR0b24gPSAxOyBicmVhazsKKwkJY2FzZSAyOiBldmVudC5idXR0b24gPSAzOyBicmVhazsKKwkJY2FzZSAzOiBldmVudC5idXR0b24gPSAyOyBicmVhazsKKwl9CisJaWYgKChjaG9yZCAmIDB4MDEpICE9IDApIGV2ZW50LnN0YXRlTWFzayB8PSBTV1QuQlVUVE9OMTsKKwlpZiAoKGNob3JkICYgMHgwMikgIT0gMCkgZXZlbnQuc3RhdGVNYXNrIHw9IFNXVC5CVVRUT04zOworCWlmICgoY2hvcmQgJiAweDA0KSAhPSAwKSBldmVudC5zdGF0ZU1hc2sgfD0gU1dULkJVVFRPTjI7CisJaWYgKChtb2RpZmllcnMgJiBPUy5vcHRpb25LZXkpICE9IDApIGV2ZW50LnN0YXRlTWFzayB8PSBTV1QuQUxUOworCWlmICgobW9kaWZpZXJzICYgT1Muc2hpZnRLZXkpICE9IDApIGV2ZW50LnN0YXRlTWFzayB8PSBTV1QuU0hJRlQ7CisJaWYgKChtb2RpZmllcnMgJiBPUy5jb250cm9sS2V5KSAhPSAwKSBldmVudC5zdGF0ZU1hc2sgfD0gU1dULkNPTlRST0w7CisJaWYgKChtb2RpZmllcnMgJiBPUy5jbWRLZXkpICE9IDApIGV2ZW50LnN0YXRlTWFzayB8PSBTV1QuQ09NTUFORDsKKwlzd2l0Y2ggKGV2ZW50LnR5cGUpIHsKKwkJY2FzZSBTV1QuTW91c2VEb3duOgorCQljYXNlIFNXVC5Nb3VzZURvdWJsZUNsaWNrOgorCQkJaWYgKGV2ZW50LmJ1dHRvbiA9PSAxKSBldmVudC5zdGF0ZU1hc2sgJj0gflNXVC5CVVRUT04xOworCQkJaWYgKGV2ZW50LmJ1dHRvbiA9PSAyKSBldmVudC5zdGF0ZU1hc2sgJj0gflNXVC5CVVRUT04yOworCQkJaWYgKGV2ZW50LmJ1dHRvbiA9PSAzKSAgZXZlbnQuc3RhdGVNYXNrICY9IH5TV1QuQlVUVE9OMzsKKwkJCWJyZWFrOworCQljYXNlIFNXVC5Nb3VzZVVwOgorCQkJaWYgKGV2ZW50LmJ1dHRvbiA9PSAxKSBldmVudC5zdGF0ZU1hc2sgfD0gU1dULkJVVFRPTjE7CisJCQlpZiAoZXZlbnQuYnV0dG9uID09IDIpIGV2ZW50LnN0YXRlTWFzayB8PSBTV1QuQlVUVE9OMjsKKwkJCWlmIChldmVudC5idXR0b24gPT0gMykgZXZlbnQuc3RhdGVNYXNrIHw9IFNXVC5CVVRUT04zOworCQkJYnJlYWs7CisJCWNhc2UgU1dULktleURvd246CisJCWNhc2UgU1dULlRyYXZlcnNlOiB7CisJCQlpZiAoZXZlbnQua2V5Q29kZSAhPSAwIHx8IGV2ZW50LmNoYXJhY3RlciAhPSAwKSByZXR1cm47CisJCQlEaXNwbGF5IGRpc3BsYXkgPSBnZXREaXNwbGF5ICgpOworCQkJaW50IGxhc3RNb2RpZmllcnMgPSBkaXNwbGF5Lmxhc3RNb2RpZmllcnM7CisJCQlpZiAoKG1vZGlmaWVycyAmIE9TLnNoaWZ0S2V5KSAhPSAwICYmIChsYXN0TW9kaWZpZXJzICYgT1Muc2hpZnRLZXkpID09IDApIHsKKwkJCQlldmVudC5zdGF0ZU1hc2sgJj0gflNXVC5TSElGVDsKKwkJCQlldmVudC5rZXlDb2RlID0gU1dULlNISUZUOworCQkJCXJldHVybjsKKwkJCX0KKwkJCWlmICgobW9kaWZpZXJzICYgT1MuY29udHJvbEtleSkgIT0gMCAmJiAobGFzdE1vZGlmaWVycyAmIE9TLmNvbnRyb2xLZXkpID09IDApIHsKKwkJCQlldmVudC5zdGF0ZU1hc2sgJj0gflNXVC5DT05UUk9MOworCQkJCWV2ZW50LmtleUNvZGUgPSBTV1QuQ09OVFJPTDsKKwkJCQlyZXR1cm47CisJCQl9CisJCQlpZiAoKG1vZGlmaWVycyAmIE9TLmNtZEtleSkgIT0gMCAmJiAobGFzdE1vZGlmaWVycyAmIE9TLmNtZEtleSkgPT0gMCkgeworCQkJCWV2ZW50LnN0YXRlTWFzayAmPSB+U1dULkNPTU1BTkQ7CisJCQkJZXZlbnQua2V5Q29kZSA9IFNXVC5DT01NQU5EOworCQkJCXJldHVybjsKKwkJCX0JCisJCQlpZiAoKG1vZGlmaWVycyAmIE9TLm9wdGlvbktleSkgIT0gMCAmJiAobGFzdE1vZGlmaWVycyAmIE9TLm9wdGlvbktleSkgPT0gMCkgeworCQkJCWV2ZW50LnN0YXRlTWFzayAmPSB+U1dULkFMVDsKKwkJCQlldmVudC5rZXlDb2RlID0gU1dULkFMVDsKKwkJCQlyZXR1cm47CisJCQl9CisJCQlicmVhazsKKwkJfQorCQljYXNlIFNXVC5LZXlVcDogeworCQkJaWYgKGV2ZW50LmtleUNvZGUgIT0gMCB8fCBldmVudC5jaGFyYWN0ZXIgIT0gMCkgcmV0dXJuOworCQkJRGlzcGxheSBkaXNwbGF5ID0gZ2V0RGlzcGxheSAoKTsKKwkJCWludCBsYXN0TW9kaWZpZXJzID0gZGlzcGxheS5sYXN0TW9kaWZpZXJzOworCQkJaWYgKChtb2RpZmllcnMgJiBPUy5zaGlmdEtleSkgPT0gMCAmJiAobGFzdE1vZGlmaWVycyAmIE9TLnNoaWZ0S2V5KSAhPSAwKSB7CisJCQkJZXZlbnQuc3RhdGVNYXNrIHw9IFNXVC5TSElGVDsKKwkJCQlldmVudC5rZXlDb2RlID0gU1dULlNISUZUOworCQkJCXJldHVybjsKKwkJCX0KKwkJCWlmICgobW9kaWZpZXJzICYgT1MuY29udHJvbEtleSkgPT0gMCAmJiAobGFzdE1vZGlmaWVycyAmIE9TLmNvbnRyb2xLZXkpICE9IDApIHsKKwkJCQlldmVudC5zdGF0ZU1hc2sgfD0gU1dULkNPTlRST0w7CisJCQkJZXZlbnQua2V5Q29kZSA9IFNXVC5DT05UUk9MOworCQkJCXJldHVybjsKKwkJCX0KKwkJCWlmICgobW9kaWZpZXJzICYgT1MuY21kS2V5KSA9PSAwICYmIChsYXN0TW9kaWZpZXJzICYgT1MuY21kS2V5KSAhPSAwKSB7CisJCQkJZXZlbnQuc3RhdGVNYXNrIHw9IFNXVC5DT01NQU5EOworCQkJCWV2ZW50LmtleUNvZGUgPSBTV1QuQ09NTUFORDsKKwkJCQlyZXR1cm47CisJCQl9CQorCQkJaWYgKChtb2RpZmllcnMgJiBPUy5vcHRpb25LZXkpICE9IDAgJiYgKGxhc3RNb2RpZmllcnMgJiBPUy5vcHRpb25LZXkpID09IDApIHsKKwkJCQlldmVudC5zdGF0ZU1hc2sgfD0gU1dULkFMVDsKKwkJCQlldmVudC5rZXlDb2RlID0gU1dULkFMVDsKKwkJCQlyZXR1cm47CisJCQl9CisJCQlicmVhazsKKwkJfQorCX0KK30KKwordm9pZCBzZXRLZXlTdGF0ZSAoRXZlbnQgZXZlbnQsIGludCB0aGVFdmVudCkgeworCWludCBbXSBrZXlDb2RlID0gbmV3IGludCBbMV07CisJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbUtleUNvZGUsIE9TLnR5cGVVSW50MzIsIG51bGwsIGtleUNvZGUubGVuZ3RoICogNCwgbnVsbCwga2V5Q29kZSk7CisJZXZlbnQua2V5Q29kZSA9IERpc3BsYXkudHJhbnNsYXRlS2V5IChrZXlDb2RlIFswXSk7CisJc3dpdGNoIChldmVudC5rZXlDb2RlKSB7CisJCWNhc2UgMDoKKwkJY2FzZSBTV1QuQlM6CisJCWNhc2UgU1dULkNSOgorCQljYXNlIFNXVC5ERUw6CisJCWNhc2UgU1dULkVTQzoKKwkJY2FzZSBTV1QuVEFCOiB7CisJCQlieXRlIFtdIGNoYXJDb2RlID0gbmV3IGJ5dGUgWzFdOworCQkJT1MuR2V0RXZlbnRQYXJhbWV0ZXIgKHRoZUV2ZW50LCBPUy5rRXZlbnRQYXJhbUtleU1hY0NoYXJDb2RlcywgT1MudHlwZUNoYXIsIG51bGwsIGNoYXJDb2RlLmxlbmd0aCwgbnVsbCwgY2hhckNvZGUpOworCQkJZXZlbnQuY2hhcmFjdGVyID0gKGNoYXIpIGNoYXJDb2RlIFswXTsKKwkJCWJyZWFrOworCQl9CisJCWNhc2UgU1dULkxGOgorCQkJZXZlbnQuY2hhcmFjdGVyID0gJ1xuJzsKKwkJCWJyZWFrOworCX0KKwlzZXRJbnB1dFN0YXRlIChldmVudCwgdGhlRXZlbnQpOworfQorCiBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nICgpIHsKIAlTdHJpbmcgc3RyaW5nID0gIipEaXNwb3NlZCoiOwogCWlmICghaXNEaXNwb3NlZCAoKSkgewpAQCAtOTQyLDcgKzkzMSwyNSBAQAogCX0KIAlyZXR1cm4gZ2V0TmFtZSAoKSArICIgeyIgKyBzdHJpbmcgKyAifSI7CiB9Ci1pbnQgdG9wSGFuZGxlICgpIHsKLQlyZXR1cm4gaGFuZGxlOworCitpbnQgdHJhY2tpbmdQcm9jIChpbnQgYnJvd3NlciwgaW50IGl0ZW1JRCwgaW50IHByb3BlcnR5LCBpbnQgdGhlUmVjdCwgaW50IHN0YXJ0UHQsIGludCBtb2RpZmllcnMpIHsKKwkvKiBSZXR1cm4gb25lIHRvIGluZGljYXRlIHRoYXQgdGhlIGRhdGEgYnJvd3NlciBzaG91bGQgcHJvY2VzcyB0aGUgY2xpY2sgKi8KKwlyZXR1cm4gMTsKIH0KKworaW50IHdpbmRvd1Byb2MgKGludCBuZXh0SGFuZGxlciwgaW50IHRoZUV2ZW50LCBpbnQgdXNlckRhdGEpIHsKKwlpbnQgZXZlbnRLaW5kID0gT1MuR2V0RXZlbnRLaW5kICh0aGVFdmVudCk7CisJc3dpdGNoIChldmVudEtpbmQpIHsKKwkJY2FzZSBPUy5rRXZlbnRXaW5kb3dBY3RpdmF0ZWQ6CQkJcmV0dXJuIGtFdmVudFdpbmRvd0FjdGl2YXRlZCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CQorCQljYXNlIE9TLmtFdmVudFdpbmRvd0JvdW5kc0NoYW5nZWQ6CQlyZXR1cm4ga0V2ZW50V2luZG93Qm91bmRzQ2hhbmdlZCAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJCWNhc2UgT1Mua0V2ZW50V2luZG93Q2xvc2U6CQkJCXJldHVybiBrRXZlbnRXaW5kb3dDbG9zZSAobmV4dEhhbmRsZXIsIHRoZUV2ZW50LCB1c2VyRGF0YSk7CisJCWNhc2UgT1Mua0V2ZW50V2luZG93Q29sbGFwc2VkOgkJCXJldHVybiBrRXZlbnRXaW5kb3dDb2xsYXBzZWQgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCQljYXNlIE9TLmtFdmVudFdpbmRvd0RlYWN0aXZhdGVkOgkJcmV0dXJuIGtFdmVudFdpbmRvd0RlYWN0aXZhdGVkIChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwkJY2FzZSBPUy5rRXZlbnRXaW5kb3dFeHBhbmRlZDoJCQlyZXR1cm4ga0V2ZW50V2luZG93RXhwYW5kZWQgKG5leHRIYW5kbGVyLCB0aGVFdmVudCwgdXNlckRhdGEpOworCQljYXNlIE9TLmtFdmVudFdpbmRvd0hpZGRlbjoJCQlyZXR1cm4ga0V2ZW50V2luZG93SGlkZGVuIChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwkJY2FzZSBPUy5rRXZlbnRXaW5kb3dTaG93bjoJCQkJcmV0dXJuIGtFdmVudFdpbmRvd1Nob3duIChuZXh0SGFuZGxlciwgdGhlRXZlbnQsIHVzZXJEYXRhKTsKKwl9CisJcmV0dXJuIE9TLmV2ZW50Tm90SGFuZGxlZEVycjsKK30KKwogfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5zd3QvRWNsaXBzZSBTV1QvY2FyYm9uL29yZy9lY2xpcHNlL3N3dC93aWRnZXRzL1dpZGdldFRhYmxlLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvV2lkZ2V0VGFibGUuamF2YQppbmRleCAyMGY1MTRlLi4zYjNlMjY2IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvV2lkZ2V0VGFibGUuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLnN3dC9FY2xpcHNlIFNXVC9jYXJib24vb3JnL2VjbGlwc2Uvc3d0L3dpZGdldHMvV2lkZ2V0VGFibGUuamF2YQpAQCAtMSw1ICsxLDcgQEAKIHBhY2thZ2Ugb3JnLmVjbGlwc2Uuc3d0LndpZGdldHM7CiAKK2ltcG9ydCBvcmcuZWNsaXBzZS5zd3QuaW50ZXJuYWwuY2FyYm9uLio7CisKIC8qCiAgKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDIgSUJNIENvcnAuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogICogVGhpcyBmaWxlIGlzIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKQEAgLTcsMjMgKzksMjcgQEAKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAgKi8KIAotaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5pbnRlcm5hbC5jYXJib24uT1M7Ci0KIHB1YmxpYyBjbGFzcyBXaWRnZXRUYWJsZSB7CiAJc3RhdGljIGludCBGcmVlU2xvdCA9IDA7CiAJc3RhdGljIGludCBHcm93U2l6ZSA9IDEwMjQ7CiAJc3RhdGljIGludCBbXSBJbmRleFRhYmxlID0gbmV3IGludCBbR3Jvd1NpemVdOwogCXN0YXRpYyBXaWRnZXQgW10gV2lkZ2V0VGFibGUgPSBuZXcgV2lkZ2V0IFtHcm93U2l6ZV07CisJc3RhdGljIGZpbmFsIGludCBTV1QwID0gKCdzJzw8MjQpICsgKCd3Jzw8MTYpICsgKCd0Jzw8OCkgKyAnMCc7CisJc3RhdGljIGludCBbXSBQcm9wZXJ0eSA9IG5ldyBpbnQgWzFdOwogCXN0YXRpYyB7CiAJCWZvciAoaW50IGk9MDsgaTxHcm93U2l6ZS0xOyBpKyspIEluZGV4VGFibGUgW2ldID0gaSArIDE7CiAJCUluZGV4VGFibGUgW0dyb3dTaXplIC0gMV0gPSAtMTsKIAl9CisJCiBwdWJsaWMgc3RhdGljIHN5bmNocm9uaXplZCBXaWRnZXQgZ2V0IChpbnQgaGFuZGxlKSB7CiAJaWYgKGhhbmRsZSA9PSAwKSByZXR1cm4gbnVsbDsKLQlpbnQgaW5kZXggPSBnZXRVc2VyRGF0YShoYW5kbGUpIC0gMTsKKwlQcm9wZXJ0eSBbMF0gPSAwOworCU9TLkdldENvbnRyb2xQcm9wZXJ0eSAoaGFuZGxlLCBTV1QwLCBTV1QwLCA0LCBudWxsLCBQcm9wZXJ0eSk7CisJaW50IGluZGV4ID0gUHJvcGVydHkgWzBdIC0gMTsKIAlpZiAoMCA8PSBpbmRleCAmJiBpbmRleCA8IFdpZGdldFRhYmxlLmxlbmd0aCkgcmV0dXJuIFdpZGdldFRhYmxlIFtpbmRleF07CiAJcmV0dXJuIG51bGw7CiB9CisKIHB1YmxpYyBzeW5jaHJvbml6ZWQgc3RhdGljIHZvaWQgcHV0IChpbnQgaGFuZGxlLCBXaWRnZXQgd2lkZ2V0KSB7CiAJaWYgKGhhbmRsZSA9PSAwKSByZXR1cm47CiAJaWYgKEZyZWVTbG90ID09IC0xKSB7CkBAIC0zOSw0MCArNDUsNDcgQEAKIAkJSW5kZXhUYWJsZSA9IG5ld0luZGV4VGFibGU7CiAJCVdpZGdldFRhYmxlID0gbmV3V2lkZ2V0VGFibGU7CiAJfQotICAgIHNldFVzZXJEYXRhKGhhbmRsZSwgRnJlZVNsb3QgKyAxKTsKKwlQcm9wZXJ0eSBbMF0gPSBGcmVlU2xvdCArIDE7CisJT1MuU2V0Q29udHJvbFByb3BlcnR5IChoYW5kbGUsIFNXVDAsIFNXVDAsIDQsIFByb3BlcnR5KTsKIAlpbnQgb2xkU2xvdCA9IEZyZWVTbG90OwogCUZyZWVTbG90ID0gSW5kZXhUYWJsZSBbb2xkU2xvdF07CiAJSW5kZXhUYWJsZSBbb2xkU2xvdF0gPSAtMjsKIAlXaWRnZXRUYWJsZSBbb2xkU2xvdF0gPSB3aWRnZXQ7CiB9CisKIHB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIFdpZGdldCByZW1vdmUgKGludCBoYW5kbGUpIHsKIAlpZiAoaGFuZGxlID09IDApIHJldHVybiBudWxsOwogCVdpZGdldCB3aWRnZXQgPSBudWxsOwotICAgIGludCBpbmRleD0gZ2V0VXNlckRhdGEoaGFuZGxlKSAtIDE7CisJUHJvcGVydHkgWzBdID0gMDsKKwlPUy5HZXRDb250cm9sUHJvcGVydHkgKGhhbmRsZSwgU1dUMCwgU1dUMCwgNCwgbnVsbCwgUHJvcGVydHkpOworCWludCBpbmRleCA9IFByb3BlcnR5IFswXSAtIDE7CiAJaWYgKDAgPD0gaW5kZXggJiYgaW5kZXggPCBXaWRnZXRUYWJsZS5sZW5ndGgpIHsKIAkJd2lkZ2V0ID0gV2lkZ2V0VGFibGUgW2luZGV4XTsKIAkJV2lkZ2V0VGFibGUgW2luZGV4XSA9IG51bGw7CiAJCUluZGV4VGFibGUgW2luZGV4XSA9IEZyZWVTbG90OwogCQlGcmVlU2xvdCA9IGluZGV4OwotICAgICAgICBzZXRVc2VyRGF0YShoYW5kbGUsIDApOworCQlPUy5SZW1vdmVDb250cm9sUHJvcGVydHkgKGhhbmRsZSwgU1dUMCwgU1dUMCk7CisKIAl9CiAJcmV0dXJuIHdpZGdldDsKIH0KLXB1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIFNoZWxsIFtdIHNoZWxscyAoKSB7Ci0gICAgICBpbnQgc2l6ZT0gMDsKLSAgICAgIGZvciAoaW50IGk9IDA7IGkgPCBXaWRnZXRUYWJsZS5sZW5ndGg7IGkrKykKLSAgICAgICAgICAgIGlmIChXaWRnZXRUYWJsZVtpXSBpbnN0YW5jZW9mIFNoZWxsKQotCQkJCXNpemUrKzsKIAotICAgICAgaW50IGluZGV4PSAwOwotICAgICAgU2hlbGxbXSByZXN1bHQ9IG5ldyBTaGVsbFtzaXplXTsKK3B1YmxpYyBzdGF0aWMgc3luY2hyb25pemVkIFNoZWxsIFtdIHNoZWxscyAoKSB7CisgICAgICBpbnQgY291bnQgPSAwOwogICAgICAgZm9yIChpbnQgaT0gMDsgaSA8IFdpZGdldFRhYmxlLmxlbmd0aDsgaSsrKSB7Ci0gICAgICAgICAgICBXaWRnZXQgd2lkZ2V0PSBXaWRnZXRUYWJsZVtpXTsKLSAgICAgICAgICAgIGlmICh3aWRnZXQgaW5zdGFuY2VvZiBTaGVsbCkKKyAgICAgICAgICAgIGlmIChXaWRnZXRUYWJsZVtpXSBpbnN0YW5jZW9mIFNoZWxsKSBjb3VudCsrOworICAgICAgfQorICAgICAgaW50IGluZGV4PSAwOworICAgICAgU2hlbGwgW10gcmVzdWx0ID0gbmV3IFNoZWxsIFtjb3VudF07CisgICAgICBmb3IgKGludCBpPSAwOyBpIDwgV2lkZ2V0VGFibGUubGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIFdpZGdldCB3aWRnZXQgPSBXaWRnZXRUYWJsZSBbaV07CisgICAgICAgICAgICBpZiAod2lkZ2V0ICE9IG51bGwgJiYgd2lkZ2V0IGluc3RhbmNlb2YgU2hlbGwpIHsKICAgICAgICAgICAgICAgICAgIHJlc3VsdCBbaW5kZXgrK109IChTaGVsbCkgd2lkZ2V0OworICAgICAgICAgICAgfQogICAgICAgfQogICAgICAgcmV0dXJuIHJlc3VsdDsKIH0KKwogcHVibGljIHN0YXRpYyBzeW5jaHJvbml6ZWQgaW50IHNpemUgKCkgewogCWludCBsZW5ndGggPSAwOwogCWZvciAoaW50IGk9MDsgaTxXaWRnZXRUYWJsZS5sZW5ndGg7IGkrKykgewpAQCAtODAsMzggKzkzLDQgQEAKIAl9CiAJcmV0dXJuIGxlbmd0aDsKIH0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLS8vIE1hYyBzdHVmZgotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwotCi0JcHJpdmF0ZSBzdGF0aWMgaW50IGdldFVzZXJEYXRhKGludCBoYW5kbGUpIHsKLQkJaWYgKE9TLklzVmFsaWRDb250cm9sSGFuZGxlKGhhbmRsZSkpCi0JCQlyZXR1cm4gT1MuR2V0Q29udHJvbFJlZmVyZW5jZShoYW5kbGUpOwotCQlpZiAoT1MuSXNWYWxpZE1lbnUoaGFuZGxlKSkgewotCQkJaW50W10gcmVmQ29uPSBuZXcgaW50WzFdOwotCQkJT1MuR2V0TWVudUl0ZW1SZWZDb24oaGFuZGxlLCAoc2hvcnQpMCwgcmVmQ29uKTsKLQkJCS8vU3lzdGVtLm91dC5wcmludGxuKCJyZWZDb246ICIgKyByZWZDb25bMF0pOwotCQkJcmV0dXJuIHJlZkNvblswXTsKLQkJfQotCQlpZiAoT1MuSXNWYWxpZFdpbmRvd1B0cihoYW5kbGUpKQotCQkJcmV0dXJuIE9TLkdldFdSZWZDb24oaGFuZGxlKTsKLQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIldpZGdldFRhYmxlLmdldFVzZXJEYXRhOiB1bmtub3duIGhhbmRsZSB0eXBlIik7Ci0JCXJldHVybiAtMTsKLQl9Ci0JCi0JcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZXRVc2VyRGF0YShpbnQgaGFuZGxlLCBpbnQgZGF0YSkgewotCQlpZiAoT1MuSXNWYWxpZENvbnRyb2xIYW5kbGUoaGFuZGxlKSkgewotCQkJT1MuU2V0Q29udHJvbFJlZmVyZW5jZShoYW5kbGUsIGRhdGEpOwotCQkJcmV0dXJuOwotCQl9Ci0JCWlmIChPUy5Jc1ZhbGlkTWVudShoYW5kbGUpKSB7Ci0JCQlPUy5TZXRNZW51SXRlbVJlZkNvbihoYW5kbGUsIChzaG9ydCkwLCBkYXRhKTsKLQkJCXJldHVybjsKLQkJfQotCQlpZiAoT1MuSXNWYWxpZFdpbmRvd1B0cihoYW5kbGUpKSB7Ci0JCQlPUy5TZXRXUmVmQ29uKGhhbmRsZSwgZGF0YSk7Ci0JCQlyZXR1cm47Ci0JCX0KLQkJU3lzdGVtLm91dC5wcmludGxuKCJXaWRnZXRUYWJsZS5zZXRVc2VyRGF0YTogdW5rbm93biBoYW5kbGUgdHlwZTogIiArIGhhbmRsZSk7Ci0JfQogfQo=