LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogQ29weXJpZ2h0IChDKSAxOTk2LTIwMDEsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCi8qKgoqIEZpbGUgdGJsY29sbC5oCioKKiBDcmVhdGVkIGJ5OiBIZWxlbmEgU2hpaAoqCiogTW9kaWZpY2F0aW9uIEhpc3Rvcnk6CioKKiAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgMi81Lzk3ICAgICAgYWxpdSAgICAgICAgQWRkZWQgc3RyZWFtSW4gYW5kIHN0cmVhbU91dCBtZXRob2RzLiAgQWRkZWQKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3Igd2hpY2ggcmVhZHMgUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0IGZyb20KKiAgICAgICAgICAgICAgICAgICAgICAgICAgYSBiaW5hcnkgZmlsZS4gIEFkZGVkIHdyaXRlVG9GaWxlIG1ldGhvZCB3aGljaCBzdHJlYW1zCiogICAgICAgICAgICAgICAgICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yIG91dCB0byBhIGJpbmFyeSBmaWxlLiAgVGhlIHN0cmVhbUluCiogICAgICAgICAgICAgICAgICAgICAgICAgIGFuZCBzdHJlYW1PdXQgbWV0aG9kcyB1c2UgaXN0cmVhbSBhbmQgb3N0cmVhbSBvYmplY3RzCiogICAgICAgICAgICAgICAgICAgICAgICAgIGluIGJpbmFyeSBtb2RlLgoqICAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byB1c2UgVGFibGVDb2xsYXRpb25EYXRhIHN1Yi1vYmplY3QgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgaG9sZCBpbnZhcmlhbnQgZGF0YS4KKiAgMi8xMy85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgc2V2ZXJhbCBtZXRob2RzIGludG8gdGhpcyBjbGFzcyBmcm9tIENvbGxhdGlvbi4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgYSBwcml2YXRlIFJ1bGVCYXNlZENvbGxhdG9yKExvY2FsZSYpIGNvbnN0cnVjdG9yLAoqICAgICAgICAgICAgICAgICAgICAgICAgICB0byBiZSB1c2VkIGJ5IENvbGxhdG9yOjpjcmVhdGVEZWZhdWx0KCkuICBHZW5lcmFsCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFuIHVwLgoqICAyLzIwLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjbG9uZSwgb3BlcmF0b3I9PSwgb3BlcmF0b3IhPSwgb3BlcmF0b3I9LCBhbmQgY29weQoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciBhbmQgZ2V0RHluYW1pY0NsYXNzSUQuCiogIDMvNS85NyAgICAgIGFsaXUgICAgICAgIE1vZGlmaWVkIGNvbnN0cnVjdEZyb21GaWxlKCkgdG8gYWRkIHBhcmFtZXRlcgoqICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWZ5aW5nIHdoZXRoZXIgb3Igbm90IGJpbmFyeSBsb2FkaW5nIGlzIHRvIGJlCiogICAgICAgICAgICAgICAgICAgICAgICAgIGF0dGVtcHRlZC4gIFRoaXMgaXMgcmVxdWlyZWQgZm9yIGR5bmFtaWMgcnVsZSBsb2FkaW5nLgoqIDA1LzA3Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBtZW1vcnkgYWxsb2NhdGlvbiBlcnJvciBkZXRlY3Rpb24uCiogIDYvMTcvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIElERU5USUNBTCBzdHJlbmd0aCBmb3IgY29tcGFyZSwgY2hhbmdlZCBnZXRSdWxlcyB0bwoqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2UgTWVyZ2VDb2xsYXRpb246OmdldFBhdHRlcm4uCiogIDYvMjAvOTcgICAgIGhlbGVuYSAgICAgIEphdmEgY2xhc3MgbmFtZSBjaGFuZ2UuCiogIDgvMTgvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGludGVybmFsIEFQSSBkb2N1bWVudGF0aW9uLgoqIDA5LzAzLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjcmVhdGVDb2xsYXRpb25LZXlWYWx1ZXMoKS4KKiAwMi8xMC85OCAgICAgZGFtaWJhICAgICAgQWRkZWQgY29tcGFyZSB3aXRoICJsZW5ndGgiIHBhcmFtZXRlcgoqIDA4LzA1Lzk4ICAgICBlcm0gICAgICAgICBTeW5jaGVkIHdpdGggMS4yIHZlcnNpb24gb2YgUnVsZUJhc2VkQ29sbGF0b3IuamF2YQoqIDA0LzIzLzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIEVEZWNvbXBvc2l0aW9uTW9kZSwgbWVyZ2VkIHdpdGgKKiAgICAgICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUKKiAwNi8xNC85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBrUmVzb3VyY2VCdW5kbGVTdWZmaXgKKiAxMS8wMi85OSAgICAgaGVsZW5hICAgICAgQ29sbGF0b3IgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiAgRWxpbWluYXRlcyB0aGUKKiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBjb25zdHJ1Y3Rpb24gYW5kIHNwZWNpYWwgY2FzZSBmb3IgTk9fT1AuCiogMTEvMjMvOTkgICAgIHNybCAgICAgICAgIE1vcmUgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiBVcGRhdGVzIHRvIE5vcm1hbGl6ZXJJdGVyYXRvcgoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbCBzdGF0ZSBtYW5hZ2VtZW50LgoqIDEyLzE1Lzk5ICAgICBhbGl1ICAgICAgICBVcGRhdGUgdG8gc3VwcG9ydCBUaGFpIGNvbGxhdGlvbi4gIE1vdmUgTm9ybWFsaXplckl0ZXJhdG9yCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGltcGxlbWVudGF0aW9uIGZpbGUuCiogMDEvMjkvMDEgICAgIHN5bndlZSAgICAgIE1vZGlmaWVkIGludG8gYSBDKysgd3JhcHBlciB3aGljaCBjYWxscyBDIEFQSQoqICAgICAgICAgICAgICAgICAgICAgICAgICAodWNvbC5oKQoqLwoKI2lmbmRlZiBUQkxDT0xMX0gKI2RlZmluZSBUQkxDT0xMX0gKCiNpbmNsdWRlICJ1bmljb2RlL2NvbGwuaCIKI2luY2x1ZGUgInVuaWNvZGUvc29ydGtleS5oIgojaW5jbHVkZSAidW5pY29kZS9ub3JtbHpyLmgiCgpjbGFzcyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I7CgovKioKICogVGhlIFJ1bGVCYXNlZENvbGxhdG9yIGNsYXNzIHByb3ZpZGVzIHRoZSBzaW1wbGUgaW1wbGVtZW50YXRpb24gb2YKICogQ29sbGF0b3IsIHVzaW5nIGRhdGEtZHJpdmVuIHRhYmxlcy4gVGhlIHVzZXIgY2FuIGNyZWF0ZSBhIGN1c3RvbWl6ZWQKICogdGFibGUtYmFzZWQgY29sbGF0aW9uLgogKiA8UD4KICogUnVsZUJhc2VkQ29sbGF0b3IgbWFwcyBjaGFyYWN0ZXJzIHRvIGNvbGxhdGlvbiBrZXlzLgogKiA8cD4KICogVGFibGUgQ29sbGF0aW9uIGhhcyB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9ucyBmb3IgZWZmaWNpZW5jeSAob3RoZXIKICogc3ViY2xhc3NlcyBtYXkgYmUgdXNlZCBmb3IgbW9yZSBjb21wbGV4IGxhbmd1YWdlcykgOgogKiAgICAgICA8cD4xLiBJZiB0aGUgRnJlbmNoIHNlY29uZGFyeSBvcmRlcmluZyBpcyBzcGVjaWZpZWQgaW4gYSBjb2xsYXRpb24KICogICAgICAgICAgICAgb2JqZWN0LCBpdCBpcyBhcHBsaWVkIHRvIHRoZSB3aG9sZSBvYmplY3QuCiAqICAgICAgIDxwPjIuIEFsbCBub24tbWVudGlvbmVkIFVuaWNvZGUgY2hhcmFjdGVycyBhcmUgYXQgdGhlIGVuZCBvZiB0aGUKICogICAgICAgICAgICAgY29sbGF0aW9uIG9yZGVyLgogKiAgICAgICA8cD4zLiBQcml2YXRlIHVzZSBjaGFyYWN0ZXJzIGFyZSB0cmVhdGVkIGFzIGlkZW50aWNhbC4gIFRoZSBwcml2YXRlCiAqICAgICAgICAgICAgIHVzZSBhcmVhIGluIFVuaWNvZGUgaXMgMHhFODAwLTB4RjhGRi4KICogPHA+VGhlIGNvbGxhdGlvbiB0YWJsZSBpcyBjb21wb3NlZCBvZiBhIGxpc3Qgb2YgY29sbGF0aW9uIHJ1bGVzLCB3aGVyZSBlYWNoCiAqIHJ1bGUgaXMgb2YgdGhyZWUgZm9ybXM6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICA8bW9kaWZpZXIgPgogKiAgICAgPHJlbGF0aW9uID4gJmx0OyB0ZXh0LWFyZ3VtZW50ID4KICogICAgIDxyZXNldCA+ICZsdDsgdGV4dC1hcmd1bWVudCA+CiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiBUaGUgZm9sbG93aW5nIGRlbW9uc3RyYXRlcyBob3cgdG8gY3JlYXRlIHlvdXIgb3duIGNvbGxhdGlvbiBydWxlczoKICogPFVMIFR5cGU9cm91bmQ+CiAqICAgIDxMST48c3Ryb25nPlRleHQgQXJndW1lbnQ8L3N0cm9uZz46IEEgdGV4dCBhcmd1bWVudCBpcyBhbnkgc2VxdWVuY2Ugb2YKICogICAgICAgIGNoYXJhY3RlcnMsIGV4Y2x1ZGluZyBzcGVjaWFsIGNoYXJhY3RlcnMgKHRoYXQgaXMsIHdoaXRlc3BhY2UKICogICAgICAgIGNoYXJhY3RlcnMgYW5kIHRoZSBjaGFyYWN0ZXJzIHVzZWQgaW4gbW9kaWZpZXIsIHJlbGF0aW9uIGFuZCByZXNldCkuCiAqICAgICAgICBJZiB0aG9zZSBjaGFyYWN0ZXJzIGFyZSBkZXNpcmVkLCB5b3UgY2FuIHB1dCB0aGVtIGluIHNpbmdsZSBxdW90ZXMKICogICAgICAgIChlLmcuIGFtcGVyc2FuZCA9PiAnJicpLjxQPgogKiAgICA8TEk+PHN0cm9uZz5Nb2RpZmllcjwvc3Ryb25nPjogVGhlcmUgaXMgYSBzaW5nbGUgbW9kaWZpZXIsCiAqICAgICAgICB3aGljaCBpcyB1c2VkIHRvIHNwZWNpZnkgdGhhdCBhbGwgc2Vjb25kYXJ5IGRpZmZlcmVuY2VzIGFyZQogKiAgICAgICAgc29ydGVkIGJhY2t3YXJkcy4KICogICAgICAgIDxwPidAJyA6IEluZGljYXRlcyB0aGF0IHNlY29uZGFyeSBkaWZmZXJlbmNlcywgc3VjaCBhcyBhY2NlbnRzLCBhcmUKICogICAgICAgICAgICAgICAgIHNvcnRlZCBiYWNrd2FyZHMsIGFzIGluIEZyZW5jaC48UD4KICogICAgPExJPjxzdHJvbmc+UmVsYXRpb248L3N0cm9uZz46IFRoZSByZWxhdGlvbnMgYXJlIHRoZSBmb2xsb3dpbmc6CiAqICAgICAgICA8VUwgVHlwZT1zcXVhcmU+CiAqICAgICAgICAgICAgPExJPicmbHQ7JyA6IEdyZWF0ZXIsIGFzIGEgbGV0dGVyIGRpZmZlcmVuY2UgKHByaW1hcnkpCiAqICAgICAgICAgICAgPExJPic7JyA6IEdyZWF0ZXIsIGFzIGFuIGFjY2VudCBkaWZmZXJlbmNlIChzZWNvbmRhcnkpCiAqICAgICAgICAgICAgPExJPicsJyA6IEdyZWF0ZXIsIGFzIGEgY2FzZSBkaWZmZXJlbmNlICh0ZXJ0aWFyeSkKICogICAgICAgICAgICA8TEk+Jz0nIDogRXF1YWwKICogICAgICAgIDwvVUw+PFA+CiAqICAgIDxMST48c3Ryb25nPlJlc2V0PC9zdHJvbmc+OiBUaGVyZSBpcyBhIHNpbmdsZSByZXNldCwKICogICAgICAgIHdoaWNoIGlzIHVzZWQgcHJpbWFyaWx5IGZvciBjb250cmFjdGlvbnMgYW5kIGV4cGFuc2lvbnMsIGJ1dCB3aGljaAogKiAgICAgICAgY2FuIGFsc28gYmUgdXNlZCB0byBhZGQgYSBtb2RpZmljYXRpb24gYXQgdGhlIGVuZCBvZiBhIHNldCBvZiBydWxlcy4KICogICAgICAgIDxwPicmJyA6IEluZGljYXRlcyB0aGF0IHRoZSBuZXh0IHJ1bGUgZm9sbG93cyB0aGUgcG9zaXRpb24gdG8gd2hlcmUKICogICAgICAgICAgICB0aGUgcmVzZXQgdGV4dC1hcmd1bWVudCB3b3VsZCBiZSBzb3J0ZWQuCiAqIDwvVUw+CiAqCiAqIDxwPgogKiBUaGlzIHNvdW5kcyBtb3JlIGNvbXBsaWNhdGVkIHRoYW4gaXQgaXMgaW4gcHJhY3RpY2UuIEZvciBleGFtcGxlLCB0aGUKICogZm9sbG93aW5nIGFyZSBlcXVpdmFsZW50IHdheXMgb2YgZXhwcmVzc2luZyB0aGUgc2FtZSB0aGluZzoKICogPHByZT4KICogXGNvZGUKICogICAgIGEgPCBiIDwgYwogKiAgICAgYSA8IGIgJiBiICA8IGMKICogICAgIGEgPCBjICYgYSAgPCBiCiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiBOb3RpY2UgdGhhdCB0aGUgb3JkZXIgaXMgaW1wb3J0YW50LCBhcyB0aGUgc3Vic2VxdWVudCBpdGVtIGdvZXMgaW1tZWRpYXRlbHkKICogYWZ0ZXIgdGhlIHRleHQtYXJndW1lbnQuIFRoZSBmb2xsb3dpbmcgYXJlIG5vdCBlcXVpdmFsZW50OgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgYSA8ICBiICYgYSAgPCBjCiAqICAgICBhIDwgIGMgJiBhICA8IGIKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIEVpdGhlciB0aGUgdGV4dC1hcmd1bWVudCBtdXN0IGFscmVhZHkgYmUgcHJlc2VudCBpbiB0aGUgc2VxdWVuY2UsIG9yIHNvbWUKICogaW5pdGlhbCBzdWJzdHJpbmcgb2YgdGhlIHRleHQtYXJndW1lbnQgbXVzdCBiZSBwcmVzZW50LiAoZS5nLiAiYSAmbHQ7IGIgJgogKiBhZSAmbHQ7IGUiIGlzIHZhbGlkIHNpbmNlICJhIiBpcyBwcmVzZW50IGluIHRoZSBzZXF1ZW5jZSBiZWZvcmUgImFlIiBpcwogKiByZXNldCkuIEluIHRoaXMgbGF0dGVyIGNhc2UsICJhZSIgaXMgbm90IGVudGVyZWQgYW5kIHRyZWF0ZWQgYXMgYSBzaW5nbGUKICogY2hhcmFjdGVyOyBpbnN0ZWFkLCAiZSIgaXMgc29ydGVkIGFzIGlmIGl0IHdlcmUgZXhwYW5kZWQgdG8gdHdvIGNoYXJhY3RlcnM6CiAqICJhIiBmb2xsb3dlZCBieSBhbiAiZSIuIFRoaXMgZGlmZmVyZW5jZSBhcHBlYXJzIGluIG5hdHVyYWwgbGFuZ3VhZ2VzOiBpbgogKiB0cmFkaXRpb25hbCBTcGFuaXNoICJjaCIgaXMgdHJlYXRlZCBhcyB0aG91Z2ggaXQgY29udHJhY3RzIHRvIGEgc2luZ2xlCiAqIGNoYXJhY3RlciAoZXhwcmVzc2VkIGFzICJjICZsdDsgY2ggJmx0OyBkIiksIHdoaWxlIGluIHRyYWRpdGlvbmFsIEdlcm1hbgogKiAi5CIgKGEtdW1sYXV0KSBpcyB0cmVhdGVkIGFzIHRob3VnaCBpdCBleHBhbmRzIHRvIHR3byBjaGFyYWN0ZXJzIChleHByZXNzZWQKICogYXMgImEgJiBhZSA7IOQgJmx0OyBiIikuCiAqIDxwPjxzdHJvbmc+SWdub3JhYmxlIENoYXJhY3RlcnM8L3N0cm9uZz4KICogPHA+Rm9yIGlnbm9yYWJsZSBjaGFyYWN0ZXJzLCB0aGUgZmlyc3QgcnVsZSBtdXN0IHN0YXJ0IHdpdGggYSByZWxhdGlvbiAodGhlCiAqIGV4YW1wbGVzIHdlIGhhdmUgdXNlZCBhYm92ZSBhcmUgcmVhbGx5IGZyYWdtZW50czsgImEgJmx0OyBiIiByZWFsbHkgc2hvdWxkCiAqIGJlICImbHQ7IGEgJmx0OyBiIikuIElmLCBob3dldmVyLCB0aGUgZmlyc3QgcmVsYXRpb24gaXMgbm90ICImbHQ7IiwgdGhlbgogKiBhbGwgdGhlIHRleHQtYXJndW1lbnRzIHVwIHRvIHRoZSBmaXJzdCAiJmx0OyIgYXJlIGlnbm9yYWJsZS4gRm9yIGV4YW1wbGUsCiAqICIsIC0gJmx0OyBhICZsdDsgYiIgbWFrZXMgIi0iIGFuIGlnbm9yYWJsZSBjaGFyYWN0ZXIsIGFzIHdlIHNhdyBlYXJsaWVyIGluCiAqIHRoZSB3b3JkICJibGFjay1iaXJkcyIuIEluIHRoZSBzYW1wbGVzIGZvciBkaWZmZXJlbnQgbGFuZ3VhZ2VzLCB5b3Ugc2VlCiAqIHRoYXQgbW9zdCBhY2NlbnRzIGFyZSBpZ25vcmFibGUuCiAqIDxwPjxzdHJvbmc+Tm9ybWFsaXphdGlvbiBhbmQgQWNjZW50czwvc3Ryb25nPgogKiA8cD5UaGUgQ29sbGF0b3Igb2JqZWN0IGF1dG9tYXRpY2FsbHkgbm9ybWFsaXplcyB0ZXh0IGludGVybmFsbHkgdG8KICogc2VwYXJhdGUgYWNjZW50cyBmcm9tIGJhc2UgY2hhcmFjdGVycyB3aGVyZSBwb3NzaWJsZS4gVGhpcyBpcyBkb25lIGJvdGgKICogd2hlbiBwcm9jZXNzaW5nIHRoZSBydWxlcywgYW5kIHdoZW4gY29tcGFyaW5nIHR3byBzdHJpbmdzLiBDb2xsYXRvciBhbHNvCiAqIHVzZXMgdGhlIFVuaWNvZGUgY2Fub25pY2FsIG1hcHBpbmcgdG8gZW5zdXJlIHRoYXQgY29tYmluaW5nIHNlcXVlbmNlcyBhcmUKICogc29ydGVkIHByb3Blcmx5IChmb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlCiAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuYXcuY29tL2RldnByZXNzIj4gVGhlIFVuaWNvZGUgU3RhbmRhcmQsIFZlcnNpb24gMi4wPC9BPgogKiAuKTwvUD4KICogPHA+PHN0cm9uZz5FcnJvcnM8L3N0cm9uZz4KICogPHA+VGhlIGZvbGxvd2luZyBhcmUgZXJyb3JzOgogKiA8VUwgVHlwZT1yb3VuZD4KICogICAgIDxMST5BIHRleHQtYXJndW1lbnQgY29udGFpbnMgdW5xdW90ZWQgcHVuY3R1YXRpb24gc3ltYm9scwogKiAgICAgICAgKGUuZy4gImEgJmx0OyBiLWMgJmx0OyBkIikuCiAqICAgICA8TEk+QSByZWxhdGlvbiBvciByZXNldCBjaGFyYWN0ZXIgbm90IGZvbGxvd2VkIGJ5IGEgdGV4dC1hcmd1bWVudAogKiAgICAgICAgKGUuZy4gImEgJmx0OyAsIGIiKS4KICogICAgIDxMST5BIHJlc2V0IHdoZXJlIHRoZSB0ZXh0LWFyZ3VtZW50IChvciBhbiBpbml0aWFsIHN1YnN0cmluZyBvZiB0aGUKICogICAgICAgICB0ZXh0LWFyZ3VtZW50KSBpcyBub3QgYWxyZWFkeSBpbiB0aGUgc2VxdWVuY2UuCiAqICAgICAgICAgKGUuZy4gImEgJmx0OyBiICYgZSAmbHQ7IGYiKQogKiA8L1VMPgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgRXhhbXBsZXM6CiAqICAgICBTaW1wbGU6ICAgICAiPCBhIDwgYiA8IGMgPCBkIgogKiAgICAgTm9yd2VnaWFuOiAgIjwgYSxBPCBiLEI8IGMsQzwgZCxEPCBlLEU8IGYsRjwgZyxHPCBoLEg8IGksSTwgaixKCiAqICAgICAgICAgICAgICAgICAgPCBrLEs8IGwsTDwgbSxNPCBuLE48IG8sTzwgcCxQPCBxLFE8IHIsUjwgcyxTPCB0LFQKICogICAgICAgICAgICAgICAgICA8IHUsVTwgdixWPCB3LFc8IHgsWDwgeSxZPCB6LFoKICogICAgICAgICAgICAgICAgICA8IOU9YbAsxT1BsAogKiAgICAgICAgICAgICAgICAgIDthYSxBQTwg5izGPCD4LNgiCiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiA8cD5UbyBjcmVhdGUgYSB0YWJsZS1iYXNlZCBjb2xsYXRpb24gb2JqZWN0LCBzaW1wbHkgc3VwcGx5IHRoZSBjb2xsYXRpb24KICogcnVsZXMgdG8gdGhlIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnRydWN0b3IuICBGb3IgZXhhbXBsZToKICogPHByZT4KICogXGNvZGUKICogICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15U2ltcGxlID0KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoU2ltcGxlLCBzdGF0dXMpOwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogPHA+QW5vdGhlciBleGFtcGxlOgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlOb3J3ZWdpYW4gPQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihOb3J3ZWdpYW4sIHN0YXR1cyk7CiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiBUbyBhZGQgcnVsZXMgb24gdG9wIG9mIGFuIGV4aXN0aW5nIHRhYmxlLCBzaW1wbHkgc3VwcGx5IHRoZSBvcmdpbmFsIHJ1bGVzCiAqIGFuZCBtb2RpZmljYXRpb25zIHRvIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiAgRm9yIGV4YW1wbGUsCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVHJhZGl0aW9uYWwgU3BhbmlzaCAoZnJhZ21lbnQpOiAuLi4gJiBDIDwgY2ggLCBjSCAsIENoICwgQ0ggLi4uCiAqICAgICAgR2VybWFuIChmcmFnbWVudCkgOiAuLi48IHkgLCBZIDwgeiAsIFoKICogICAgICAgICAgICAgICAgICAgICAgICAgICYgQUUsIMQgJiBBRSwg5AogKiAgICAgICAgICAgICAgICAgICAgICAgICAgJiBPRSAsINYgJiBPRSwg9gogKiAgICAgICAgICAgICAgICAgICAgICAgICAgJiBVRSAsINwgJiBVRSwg/AogKiAgICAgIFN5bWJvbHMgKGZyYWdtZW50KTogLi4uPCB5LCBZIDwgeiAsIFoKICogICAgICAgICAgICAgICAgICAgICAgICAgICYgUXVlc3Rpb24tbWFyayA7ICc/JwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgJiBBbXBlcnNhbmQgOyAnJicKICogICAgICAgICAgICAgICAgICAgICAgICAgICYgRG9sbGFyLXNpZ24gOyAnJCcKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPlRvIGNyZWF0ZSBhIGNvbGxhdGlvbiBvYmplY3QgZm9yIHRyYWRpdGlvbmFsIFNwYW5pc2gsIHRoZSB1c2VyIGNhbiB0YWtlCiAqIHRoZSBFbmdsaXNoIGNvbGxhdGlvbiBydWxlcyBhbmQgYWRkIHRoZSBhZGRpdGlvbmFsIHJ1bGVzIHRvIHRoZSB0YWJsZS4KICogRm9yIGV4YW1wbGU6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICAgVW5pY29kZVN0cmluZyBydWxlcyhERUZBVUxUUlVMRVMpOwogKiAgICAgIHJ1bGVzICs9ICImIEMgJmx0OyBjaCwgY0gsIENoLCBDSCI7CiAqICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15U3BhbmlzaCA9CiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihydWxlcywgc3RhdHVzKTsKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPkluIG9yZGVyIHRvIHNvcnQgc3ltYm9scyBpbiB0aGUgc2ltaWxpYXIgb3JkZXIgb2Ygc29ydGluZyB0aGVpcgogKiBhbHBoYWJldGljIGVxdWl2YWxlbnRzLCB5b3UgY2FuIGRvIHRoZSBmb2xsb3dpbmcsCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICAgVW5pY29kZVN0cmluZyBydWxlcyhERUZBVUxUUlVMRVMpOwogKiAgICAgIHJ1bGVzICs9ICImIFF1ZXN0aW9uLW1hcmsgOyAnPycgJiBBbXBlcnNhbmQgOyAnJicgJiBEb2xsYXItc2lnbiA7CiAqICAgICAgICAgICAgICAgJyQnICI7CiAqICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15VGFibGUgPQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUnVsZUJhc2VkQ29sbGF0b3IocnVsZXMsIHN0YXR1cyk7CiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiA8cD5Bbm90aGVyIHdheSBvZiBjcmVhdGluZyB0aGUgdGFibGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdCwgbXlTaW1wbGUsCiAqIGlzOgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteVNpbXBsZSA9IG5ldwogKiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IoIiA8IGEgPCBiICYgYiA8IGMgJiBjIDwgZCIsIHN0YXR1cyk7CiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiBPciwKICogPHByZT4KICogXGNvZGUKICogICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICogICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlTaW1wbGUgPSBuZXcKICogICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvcigiIDwgYSA8IGIgPCBkICYgYiA8IGMiLCBzdGF0dXMpOwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogQmVjYXVzZSAiICZsdDsgYSAmbHQ7IGIgJmx0OyBjICZsdDsgZCIgaXMgdGhlIHNhbWUgYXMgImEgJmx0OyBiICZsdDsgZCAmIGIKICogICAgICAgICAgJmx0OyBjIiBvciAiJmx0OyBhICZsdDsgYiAmIGIgJmx0OyBjICYgYyAmbHQ7IGQiLgogKgogKiA8cD5UbyBjb21iaW5lIGNvbGxhdGlvbnMgZnJvbSB0d28gbG9jYWxlcywgKHdpdGhvdXQgZXJyb3IgaGFuZGxpbmcgZm9yCiAqIGNsYXJpdHkpCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAvLyBDcmVhdGUgYW4gZW5fVVMgQ29sbGF0b3Igb2JqZWN0CiAqICAgICBMb2NhbGUgbG9jYWxlX2VuX1VTKCJlbiIsICJVUyIsICIiKTsKICogICAgIFJ1bGVCYXNlZENvbGxhdG9yKiBlbl9VU0NvbGxhdG9yID0gKFJ1bGVCYXNlZENvbGxhdG9yKikKICogICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoIGxvY2FsZV9lbl9VUywgc3VjY2VzcyApOwogKgogKiAgICAgLy8gQ3JlYXRlIGEgZGFfREsgQ29sbGF0b3Igb2JqZWN0CiAqICAgICBMb2NhbGUgbG9jYWxlX2RhX0RLKCJkYSIsICJESyIsICIiKTsKICogICAgIFJ1bGVCYXNlZENvbGxhdG9yKiBkYV9ES0NvbGxhdG9yID0gKFJ1bGVCYXNlZENvbGxhdG9yKikKICogICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoIGxvY2FsZV9kYV9ESywgc3VjY2VzcyApOwogKgogKiAgICAgLy8gQ29tYmluZSB0aGUgdHdvCiAqICAgICAvLyBGaXJzdCwgZ2V0IHRoZSBjb2xsYXRpb24gcnVsZXMgZnJvbSBlbl9VU0NvbGxhdG9yCiAqICAgICBVbmljb2RlU3RyaW5nIHJ1bGVzID0gZW5fVVNDb2xsYXRvci0+Z2V0UnVsZXMoKTsKICogICAgIC8vIFNlY29uZCwgZ2V0IHRoZSBjb2xsYXRpb24gcnVsZXMgZnJvbSBkYV9ES0NvbGxhdG9yCiAqICAgICBydWxlcyArPSBkYV9ES0NvbGxhdG9yLT5nZXRSdWxlcygpOwogKiAgICAgUnVsZUJhc2VkQ29sbGF0b3IqIG5ld0NvbGxhdG9yID0KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUnVsZUJhc2VkQ29sbGF0b3IocnVsZXMsIHN1Y2Nlc3MpOwogKiAgICAgLy8gbmV3Q29sbGF0b3IgaGFzIHRoZSBjb21iaW5lZCBydWxlcwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogPHA+QW5vdGhlciBtb3JlIGludGVyZXN0aW5nIGV4YW1wbGUgd291bGQgYmUgdG8gbWFrZSBjaGFuZ2VzIG9uIGFuIGV4aXN0aW5nCiAqIHRhYmxlIHRvIGNyZWF0ZSBhIG5ldyBjb2xsYXRpb24gb2JqZWN0LiAgRm9yIGV4YW1wbGUsIGFkZAogKiAiJiBDICZsdDsgY2gsIGNILCBDaCwgQ0giIHRvIHRoZSBlbl9VU0NvbGxhdGlvbiBvYmplY3QgdG8gY3JlYXRlIHlvdXIgb3duCiAqIEVuZ2xpc2ggY29sbGF0aW9uIG9iamVjdCwKICogPHByZT4KICogXGNvZGUKICogICAgIC8vIENyZWF0ZSBhIG5ldyBDb2xsYXRvciBvYmplY3Qgd2l0aCBhZGRpdGlvbmFsIHJ1bGVzCiAqICAgICBydWxlcyA9IGVuX1VTQ29sbGF0b3ItPmdldFJ1bGVzKCk7CiAqICAgICBydWxlcyArPSAiJiBDIDwgY2gsIGNILCBDaCwgQ0giOwogKiAgICAgUnVsZUJhc2VkQ29sbGF0b3IqIG15Q29sbGF0b3IgPQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihydWxlcywgc3VjY2Vzcyk7CiAqICAgICAvLyBteUNvbGxhdG9yIGNvbnRhaW5zIHRoZSBuZXcgcnVsZXMKICogXGVuZGNvZGUKICogPC9wcmU+CiAqCiAqIDxwPlRoZSBmb2xsb3dpbmcgZXhhbXBsZSBkZW1vbnN0cmF0ZXMgaG93IHRvIGNoYW5nZSB0aGUgb3JkZXIgb2YKICogbm9uLXNwYWNpbmcgYWNjZW50cywKICogPHByZT4KICogXGNvZGUKICogICAgICBVQ2hhciBjb250ZW50c1tdID0gewogKiAgICAgICAgICAnPScsIDB4MDMwMSwgJzsnLCAweDAzMDAsICc7JywgMHgwMzAyLAogKiAgICAgICAgICAnOycsIDB4MDMwOCwgJzsnLCAweDAzMjcsICcsJywgMHgwMzAzLCAgICAvLyBtYWluIGFjY2VudHMKICogICAgICAgICAgJzsnLCAweDAzMDQsICc7JywgMHgwMzA1LCAnOycsIDB4MDMwNiwgICAgLy8gbWFpbiBhY2NlbnRzCiAqICAgICAgICAgICc7JywgMHgwMzA3LCAnOycsIDB4MDMwOSwgJzsnLCAweDAzMEEsICAgIC8vIG1haW4gYWNjZW50cwogKiAgICAgICAgICAnOycsIDB4MDMwQiwgJzsnLCAweDAzMEMsICc7JywgMHgwMzBELCAgICAvLyBtYWluIGFjY2VudHMKICogICAgICAgICAgJzsnLCAweDAzMEUsICc7JywgMHgwMzBGLCAnOycsIDB4MDMxMCwgICAgLy8gbWFpbiBhY2NlbnRzCiAqICAgICAgICAgICc7JywgMHgwMzExLCAnOycsIDB4MDMxMiwgICAgICAgICAgICAgICAgIC8vIG1haW4gYWNjZW50cwogKiAgICAgICAgICAnPCcsICdhJywgJywnLCAnQScsICc7JywgJ2EnLCAnZScsICcsJywgJ0EnLCAnRScsCiAqICAgICAgICAgICc7JywgMHgwMGU2LCAnLCcsIDB4MDBjNiwgJzwnLCAnYicsICcsJywgJ0InLAogKiAgICAgICAgICAnPCcsICdjJywgJywnLCAnQycsICc8JywgJ2UnLCAnLCcsICdFJywgJyYnLAogKiAgICAgICAgICAnQycsICc8JywgJ2QnLCAnLCcsICdEJywgMCB9OwogKiAgICAgIFVuaWNvZGVTdHJpbmcgb2xkUnVsZXMoY29udGVudHMpOwogKiAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgIC8vIGNoYW5nZSB0aGUgb3JkZXIgb2YgYWNjZW50IGNoYXJhY3RlcnMKICogICAgICBVQ2hhciBhZGRPbltdID0geyAnJicsICcsJywgMHgwMzAwLCAnOycsIDB4MDMwOCwgJzsnLCAweDAzMDIsIDAgfTsKICogICAgICBvbGRSdWxlcyArPSBhZGRPbjsKICogICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlDb2xsYXRpb24gPQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUnVsZUJhc2VkQ29sbGF0b3Iob2xkUnVsZXMsIHN0YXR1cyk7CiAqICBcZW5kY29kZQogKiA8L3ByZT4KICoKICogPHA+IFRoZSBsYXN0IGV4YW1wbGUgc2hvd3MgaG93IHRvIHB1dCBuZXcgcHJpbWFyeSBvcmRlcmluZyBpbiBiZWZvcmUgdGhlCiAqIGRlZmF1bHQgc2V0dGluZy4gRm9yIGV4YW1wbGUsIGluIEphcGFuZXNlIGNvbGxhdGlvbiwgeW91IGNhbiBlaXRoZXIgc29ydAogKiBFbmdsaXNoIGNoYXJhY3RlcnMgYmVmb3JlIG9yIGFmdGVyIEphcGFuZXNlIGNoYXJhY3RlcnMsCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICAgLy8gZ2V0IGVuX1VTIGNvbGxhdGlvbiBydWxlcwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yKiBlbl9VU0NvbGxhdGlvbiA9IChSdWxlQmFzZWRDb2xsYXRvciopCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICogICAgICAvLyBBbHdheXMgY2hlY2sgdGhlIGVycm9yIGNvZGUgYWZ0ZXIgZWFjaCBjYWxsLgogKiAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogKiAgICAgIC8vIGFkZCBhIGZldyBKYXBhbmVzZSBjaGFyYWN0ZXIgdG8gc29ydCBiZWZvcmUgRW5nbGlzaCBjaGFyYWN0ZXJzCiAqICAgICAgLy8gc3VwcG9zZSB0aGUgbGFzdCBjaGFyYWN0ZXIgYmVmb3JlIHRoZSBmaXJzdCBiYXNlIGxldHRlciAnYScgaW4KICogICAgICAvLyB0aGUgRW5nbGlzaCBjb2xsYXRpb24gcnVsZSBpcyAweDIyMTIKICogICAgICBVQ2hhciBqYVN0cmluZ1tdID0geycmJywgMHgyMjEyLCAnPCcsIDB4MzA0MSwgJywnLCAweDMwNDIsICc8JywKICogICAgICAgICAgICAgICAgICAgICAgICAgIDB4MzA0MywgJywnLCAweDMwNDQsIDB9OwogKiAgICAgIFVuaWNvZGVTdHJpbmcgcnVsZXMoZW5fVVNDb2xsYXRpb24tPmdldFJ1bGVzKCkpOwogKiAgICAgIHJ1bGVzICs9IGphU3RyaW5nOwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteUphcGFuZXNlQ29sbGF0aW9uID0KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGVzLCBzdGF0dXMpOwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogPHA+PHN0cm9uZz5OT1RFPC9zdHJvbmc+OiBUeXBpY2FsbHksIGEgY29sbGF0aW9uIG9iamVjdCBpcyBjcmVhdGVkIHdpdGgKICogQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKCkuCiAqIDxwPgogKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IDxjb2RlPlJ1bGVCYXNlZENvbGxhdG9yPC9jb2RlPnMgd2l0aCBkaWZmZXJlbnQKICogTG9jYWxlLCBDb2xsYXRpb25TdHJlbmd0aCBhbmQgRGVjb21wb3NpdGlvbiBtb2RlIHNldHRpbmdzIHdpbGwgcmV0dXJuCiAqIGRpZmZlcmVudCBzb3J0IG9yZGVycyBmb3IgdGhlIHNhbWUgc2V0IG9mIHN0cmluZ3MuIExvY2FsZXMgaGF2ZSBzcGVjaWZpYwogKiBjb2xsYXRpb24gcnVsZXMsIGFuZCB0aGUgd2F5IGluIHdoaWNoIHNlY29uZGFyeSBhbmQgdGVydGlhcnkgZGlmZmVyZW5jZXMKICogYXJlIHRha2VuIGludG8gYWNjb3VudCwgZm9yIGV4YW1wbGUsIHdpbGwgcmVzdWx0IGluIGEgZGlmZmVyZW50IHNvcnRpbmcKICogb3JkZXIgZm9yIHNhbWUgc3RyaW5ncy4KICogPHA+CiAqIEBzZWUgICAgICAgIENvbGxhdG9yCiAqIEB2ZXJzaW9uICAgIDEuOCBKYW4gOCAyMDAxCiAqLwpjbGFzcyBVX0kxOE5fQVBJIFJ1bGVCYXNlZENvbGxhdG9yIDogcHVibGljIENvbGxhdG9yCnsKcHVibGljOgoKICAvLyBjb25zdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSB0YWJsZSBydWxlcyBhbmQgYnVpbGRzIGEKICAgKiBjb2xsYXRpb24gdGFibGUgb3V0IG9mIHRoZW0uIFBsZWFzZSBzZWUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MKICAgKiBkZXNjcmlwdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSBjb2xsYXRpb24gcnVsZSBzeW50YXguCiAgICogQHBhcmFtIHJ1bGVzIHRoZSBjb2xsYXRpb24gcnVsZXMgdG8gYnVpbGQgdGhlIGNvbGxhdGlvbiB0YWJsZSBmcm9tLgogICAqIEBwYXJhbSBzdGF0dXMgcmVwb3J0aW5nIGEgc3VjY2VzcyBvciBhbiBlcnJvci4KICAgKiBAc2VlIExvY2FsZQogICAqLwoJUnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSB0YWJsZSBydWxlcyBhbmQgYnVpbGRzIGEKICAgKiBjb2xsYXRpb24gdGFibGUgb3V0IG9mIHRoZW0uIFBsZWFzZSBzZWUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MKICAgKiBkZXNjcmlwdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSBjb2xsYXRpb24gcnVsZSBzeW50YXguCiAgICogQHBhcmFtIHJ1bGVzIHRoZSBjb2xsYXRpb24gcnVsZXMgdG8gYnVpbGQgdGhlIGNvbGxhdGlvbiB0YWJsZSBmcm9tLgogICAqIEBwYXJhbSBjb2xsYXRpb25TdHJlbmd0aCBkZWZhdWx0IHN0cmVuZ3RoIGZvciBjb21wYXJpc29uCiAgICogQHBhcmFtIHN0YXR1cyByZXBvcnRpbmcgYSBzdWNjZXNzIG9yIGFuIGVycm9yLgogICAqIEBzZWUgTG9jYWxlCiAgICovCiAgUnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSB0YWJsZSBydWxlcyBhbmQgYnVpbGRzIGEKICAgKiBjb2xsYXRpb24gdGFibGUgb3V0IG9mIHRoZW0uIFBsZWFzZSBzZWUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MKICAgKiBkZXNjcmlwdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSBjb2xsYXRpb24gcnVsZSBzeW50YXguCiAgICogQHBhcmFtIHJ1bGVzIHRoZSBjb2xsYXRpb24gcnVsZXMgdG8gYnVpbGQgdGhlIGNvbGxhdGlvbiB0YWJsZSBmcm9tLgogICAqIEBwYXJhbSBkZWNvbXBvc2l0aW9uTW9kZSB0aGUgbm9ybWFsaXNhdGlvbiBtb2RlCiAgICogQHBhcmFtIHN0YXR1cyByZXBvcnRpbmcgYSBzdWNjZXNzIG9yIGFuIGVycm9yLgogICAqIEBzZWUgTG9jYWxlCiAgICovCiAgUnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgLyoqCiAgICogUnVsZUJhc2VkQ29sbGF0b3IgY29uc3RydWN0b3IuIFRoaXMgdGFrZXMgdGhlIHRhYmxlIHJ1bGVzIGFuZCBidWlsZHMgYQogICAqIGNvbGxhdGlvbiB0YWJsZSBvdXQgb2YgdGhlbS4gUGxlYXNlIHNlZSBSdWxlQmFzZWRDb2xsYXRvciBjbGFzcwogICAqIGRlc2NyaXB0aW9uIGZvciBtb3JlIGRldGFpbHMgb24gdGhlIGNvbGxhdGlvbiBydWxlIHN5bnRheC4KICAgKiBAcGFyYW0gcnVsZXMgdGhlIGNvbGxhdGlvbiBydWxlcyB0byBidWlsZCB0aGUgY29sbGF0aW9uIHRhYmxlIGZyb20uCiAgICogQHBhcmFtIGNvbGxhdGlvblN0cmVuZ3RoIGRlZmF1bHQgc3RyZW5ndGggZm9yIGNvbXBhcmlzb24KICAgKiBAcGFyYW0gZGVjb21wb3NpdGlvbk1vZGUgdGhlIG5vcm1hbGlzYXRpb24gbW9kZQogICAqIEBwYXJhbSBzdGF0dXMgcmVwb3J0aW5nIGEgc3VjY2VzcyBvciBhbiBlcnJvci4KICAgKiBAc2VlIExvY2FsZQogICAqLwogIFJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgIEVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAgKiBDb3B5IGNvbnN0cnVjdG9yLgogICAqIEBwYXJhbSB0aGUgUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0IHRvIGJlIGNvcGllZAogICAqIEBzZWUgTG9jYWxlCiAgICovCglSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBSdWxlQmFzZWRDb2xsYXRvciYgb3RoZXIpOwoKICAvLyBkZXN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIERlc3RydWN0b3IuCiAgICovCgl2aXJ0dWFsIH5SdWxlQmFzZWRDb2xsYXRvcigpOwoKICAvLyBwdWJsaWMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuCiAgICogQHBhcmFtIG90aGVyIG90aGVyIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCB0byBjb21wYXJlIHdpdGguCiAgICovCglSdWxlQmFzZWRDb2xsYXRvciYgb3BlcmF0b3I9KGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yJiBvdGhlcik7CgogIC8qKgogICAqIFJldHVybnMgdHJ1ZSBpZiBhcmd1bWVudCBpcyB0aGUgc2FtZSBhcyB0aGlzIG9iamVjdC4KICAgKiBAcGFyYW0gb3RoZXIgQ29sbGF0b3Igb2JqZWN0IHRvIGJlIGNvbXBhcmVkLgogICAqIEByZXR1cm4gdHJ1ZSBpZiBhcmd1bWVudHMgaXMgdGhlIHNhbWUgYXMgdGhpcyBvYmplY3QuCiAgICovCiAgdmlydHVhbCBVQm9vbCBvcGVyYXRvcj09KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3Q7CgogIC8qKgogICAqIFJldHVybnMgdHJ1ZSBpZiBhcmd1bWVudCBpcyBub3QgdGhlIHNhbWUgYXMgdGhpcyBvYmplY3QuCiAgICogQHBhcmFtIG90aGVyIENvbGxhdG9yIG9iamVjdCB0byBiZSBjb21wYXJlZAogICAqIEByZXR1cm4gcmV0dXJucyB0cnVlIGlmIGFyZ3VtZW50IGlzIG5vdCB0aGUgc2FtZSBhcyB0aGlzIG9iamVjdC4KICAgKi8KICB2aXJ0dWFsIFVCb29sIG9wZXJhdG9yIT0oY29uc3QgQ29sbGF0b3ImIG90aGVyKSBjb25zdDsKCiAgLyoqCiAgICogTWFrZXMgYSBkZWVwIGNvcHkgb2YgdGhlIG9iamVjdC4KICAgKiBUaGUgY2FsbGVyIG93bnMgdGhlIHJldHVybmVkIG9iamVjdC4KICAgKiBAcmV0dXJuIHRoZSBjbG9uZWQgb2JqZWN0LgogICAqLwogIHZpcnR1YWwgQ29sbGF0b3IqIGNsb25lKHZvaWQpIGNvbnN0OwoKICAvKioKICAgKiBDcmVhdGVzIGEgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3IgZm9yIHRoZSBzb3VyY2Ugc3RyaW5nLiBUaGUgY2FsbGVyIG9mCiAgICogdGhpcyBtZXRob2QgaXMgcmVzcG9uc2libGUgZm9yIHRoZSBtZW1vcnkgbWFuYWdlbWVudCBvZiB0aGUgcmV0dXJuCiAgICogcG9pbnRlci4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzdHJpbmcgb3ZlciB3aGljaCB0aGUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHdpbGwKICAgKiAgICAgICAgaXRlcmF0ZS4KICAgKiBAcmV0dXJuIHRoZSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBvZiB0aGUgc291cmNlIHN0cmluZyB1c2luZyB0aGlzIGFzCiAgICogICAgICAgICB0aGUgYmFzZWQgQ29sbGF0b3IuCiAgICovCgl2aXJ0dWFsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciogY3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlKSBjb25zdDsKCiAgLyoqCiAgICogQ3JlYXRlcyBhIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIGZvciB0aGUgc291cmNlLiBUaGUgY2FsbGVyIG9mIHRoaXMKICAgKiBtZXRob2QgaXMgcmVzcG9uc2libGUgZm9yIHRoZSBtZW1vcnkgbWFuYWdlbWVudCBvZiB0aGUgcmV0dXJuZWQgcG9pbnRlci4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBDaGFyYWN0ZXJJdGVyYXRvciB3aGljaCBwcm9kdWNlcyB0aGUgY2hhcmFjdGVycyBvdmVyCiAgICogICAgICAgIHdoaWNoIHRoZSBDb2xsYXRpb25FbGVtZW50SXRnZXJhdG9yIHdpbGwgaXRlcmF0ZS4KICAgKiBAcmV0dXJuIHRoZSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBvZiB0aGUgc291cmNlIHVzaW5nIHRoaXMgYXMgdGhlCiAgICogICAgICAgICBiYXNlZCBDb2xsYXRvci4KICAgKi8KICB2aXJ0dWFsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciogY3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgc291cmNlKSBjb25zdDsKCiAgLyoqCiAgICogQ29tcGFyZXMgYSByYW5nZSBvZiBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvIGRpZmZlcmVudCBzdHJpbmdzIGJhc2VkCiAgICogb24gdGhlIGNvbGxhdGlvbiBydWxlcy4gUmV0dXJucyBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nIGlzCiAgICogbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcgaW4gYSBsYW5ndWFnZS4KICAgKiBUaGlzIGNhbiBiZSBvdmVycmlkZW4gaW4gYSBzdWJjbGFzcy4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcmV0dXJuIHRoZSBjb21wYXJpc29uIHJlc3VsdC4gR1JFQVRFUiBpZiB0aGUgc291cmNlIHN0cmluZyBpcyBncmVhdGVyCiAgICogICAgICAgICB0aGFuIHRoZSB0YXJnZXQgc3RyaW5nLCBMRVNTIGlmIHRoZSBzb3VyY2UgaXMgbGVzcyB0aGFuIHRoZQogICAqICAgICAgICAgdGFyZ2V0LiBPdGhlcndpc2UsIHJldHVybnMgRVFVQUwuCiAgICovCiAgdmlydHVhbCBFQ29tcGFyaXNvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdDsKCgogIC8qKgogICAqIENvbXBhcmVzIGEgcmFuZ2Ugb2YgY2hhcmFjdGVyIGRhdGEgc3RvcmVkIGluIHR3byBkaWZmZXJlbnQgc3RyaW5ncyBiYXNlZAogICAqIG9uIHRoZSBjb2xsYXRpb24gcnVsZXMgdXAgdG8gdGhlIHNwZWNpZmllZCBsZW5ndGguIFJldHVybnMgaW5mb3JtYXRpb24KICAgKiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nIGlzIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIKICAgKiBzdHJpbmcgaW4gYSBsYW5ndWFnZS4gVGhpcyBjYW4gYmUgb3ZlcnJpZGVuIGluIGEgc3ViY2xhc3MuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgICogQHBhcmFtIGxlbmd0aCBjb21wYXJlcyB1cCB0byB0aGUgc3BlY2lmaWVkIGxlbmd0aAogICAqIEByZXR1cm4gdGhlIGNvbXBhcmlzb24gcmVzdWx0LiBHUkVBVEVSIGlmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGdyZWF0ZXIKICAgKiAgICAgICAgIHRoYW4gdGhlIHRhcmdldCBzdHJpbmcsIExFU1MgaWYgdGhlIHNvdXJjZSBpcyBsZXNzIHRoYW4gdGhlCiAgICogICAgICAgICB0YXJnZXQuIE90aGVyd2lzZSwgcmV0dXJucyBFUVVBTC4KICAgKi8KICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0IGNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiAgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxlbmd0aCkgY29uc3Q7CgogIC8qKgogICAqIFRoZSBjb21wYXJpc29uIGZ1bmN0aW9uIGNvbXBhcmVzIHRoZSBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvCiAgICogZGlmZmVyZW50IHN0cmluZyBhcnJheXMuIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBhIHN0cmluZyBhcnJheQogICAqIGlzIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIgc3RyaW5nIGFycmF5LgogICAqIDxwPkV4YW1wbGUgb2YgdXNlOgogICAqIDxwcmU+CiAgICogLiAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgKiAuICAgICAgIENvbGxhdG9yICpteUNvbGxhdGlvbiA9CiAgICogLiAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6RVFVQUwgKCJhYmMiID09ICJBQkMiKQogICAqIC4gICAgICAgLy8gKG5vIHByaW1hcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpVQ29sbGF0aW9uUmVzdWx0IHJlc3VsdCA9CiAgICogLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15Q29sbGF0aW9uLT5jb21wYXJlKEwiYWJjIiwgMywgTCJBQkMiLCAzKTsKICAgKiAuICAgICAgIG15Q29sbGF0aW9uLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOwogICAqIC4gICAgICAgLy8gcmVzdWx0IHdvdWxkIGJlIENvbGxhdG9yOjpMRVNTIChhYmMiICZsdDsmbHQ7Jmx0OyAiQUJDIikKICAgKiAuICAgICAgIC8vICh3aXRoIHRlcnRpYXJ5IGRpZmZlcmVuY2UgYmV0d2VlbiAiYWJjIiBhbmQgIkFCQyIpCiAgICogLiAgICAgICBDb2xsYXRvcjo6VUNvbGxhdGlvblJlc3VsdCByZXN1bHQgPQogICAqIC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteUNvbGxhdGlvbi0+Y29tcGFyZShMImFiYyIsIDMsIEwiQUJDIiwgMyk7CiAgICogPC9wcmU+CiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyBhcnJheSB0byBiZSBjb21wYXJlZCB3aXRoLgogICAqIEBwYXJhbSBzb3VyY2VMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgc291cmNlIHN0cmluZyBhcnJheS4gSWYgdGhpcyB2YWx1ZQogICAqICAgICAgICBpcyBlcXVhbCB0byAtMSwgdGhlIHN0cmluZyBhcnJheSBpcyBudWxsLXRlcm1pbmF0ZWQuCiAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gdGFyZ2V0TGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIHRhcmdldCBzdHJpbmcgYXJyYXkuIElmIHRoaXMgdmFsdWUKICAgKiAgICAgICAgaXMgZXF1YWwgdG8gLTEsIHRoZSBzdHJpbmcgYXJyYXkgaXMgbnVsbC10ZXJtaW5hdGVkLgogICAqIEByZXR1cm4gUmV0dXJucyBhIGJ5dGUgdmFsdWUuIEdSRUFURVIgaWYgc291cmNlIGlzIGdyZWF0ZXIgdGhhbiB0YXJnZXQ7CiAgICogICAgICAgICBFUVVBTCBpZiBzb3VyY2UgaXMgZXF1YWwgdG8gdGFyZ2V0OyBMRVNTIGlmIHNvdXJjZSBpcyBsZXNzIHRoYW4KICAgKiAgICAgICAgIHRhcmdldAogICAqLwogIHZpcnR1YWwgRUNvbXBhcmlzb25SZXN1bHQgY29tcGFyZShjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNoYXIqIHRhcmdldCwgaW50MzJfdCB0YXJnZXRMZW5ndGgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0OwoKICAvKioKICAqIFRyYW5zZm9ybXMgYSBzcGVjaWZpZWQgcmVnaW9uIG9mIHRoZSBzdHJpbmcgaW50byBhIHNlcmllcyBvZiBjaGFyYWN0ZXJzCiAgKiB0aGF0IGNhbiBiZSBjb21wYXJlZCB3aXRoIENvbGxhdGlvbktleS5jb21wYXJlLiBVc2UgYSBDb2xsYXRpb25LZXkgd2hlbgogICogeW91IG5lZWQgdG8gZG8gcmVwZWF0ZWQgY29tcGFyaXNpb25zIG9uIHRoZSBzYW1lIHN0cmluZy4gRm9yIGEgc2luZ2xlCiAgKiBjb21wYXJpc29uIHRoZSBjb21wYXJlIG1ldGhvZCB3aWxsIGJlIGZhc3Rlci4KICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0ga2V5IHRoZSB0cmFuc2Zvcm1lZCBrZXkgb2YgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEByZXR1cm4gdGhlIHRyYW5zZm9ybWVkIGtleS4KICAqIEBzZWUgQ29sbGF0aW9uS2V5CiAgKi8KICB2aXJ0dWFsIENvbGxhdGlvbktleSYgZ2V0Q29sbGF0aW9uS2V5KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdDsKCiAgLyoqCiAgKiBUcmFuc2Zvcm1zIGEgc3BlY2lmaWVkIHJlZ2lvbiBvZiB0aGUgc3RyaW5nIGludG8gYSBzZXJpZXMgb2YgY2hhcmFjdGVycwogICogdGhhdCBjYW4gYmUgY29tcGFyZWQgd2l0aCBDb2xsYXRpb25LZXkuY29tcGFyZS4gVXNlIGEgQ29sbGF0aW9uS2V5IHdoZW4KICAqIHlvdSBuZWVkIHRvIGRvIHJlcGVhdGVkIGNvbXBhcmlzaW9ucyBvbiB0aGUgc2FtZSBzdHJpbmcuIEZvciBhIHNpbmdsZQogICogY29tcGFyaXNvbiB0aGUgY29tcGFyZSBtZXRob2Qgd2lsbCBiZSBmYXN0ZXIuCiAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nLgogICogQHBhcmFtIGtleSB0aGUgdHJhbnNmb3JtZWQga2V5IG9mIHRoZSBzb3VyY2Ugc3RyaW5nLgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAcmV0dXJuIHRoZSB0cmFuc2Zvcm1lZCBrZXkuCiAgKiBAc2VlIENvbGxhdGlvbktleQogICovCiAgdmlydHVhbCBDb2xsYXRpb25LZXkmIGdldENvbGxhdGlvbktleShjb25zdCBVQ2hhciAqc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmIGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgogIC8qKgogICAqIEdlbmVyYXRlcyB0aGUgaGFzaCBjb2RlIGZvciB0aGUgcnVsZS1iYXNlZCBjb2xsYXRpb24gb2JqZWN0LgogICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZS4KICAgKi8KICB2aXJ0dWFsIGludDMyX3QgaGFzaENvZGUodm9pZCkgY29uc3Q7CgogIC8qKgogICAqIEdldHMgdGhlIHRhYmxlLWJhc2VkIHJ1bGVzIGZvciB0aGUgY29sbGF0aW9uIG9iamVjdC4KICAgKiBAcmV0dXJuIHJldHVybnMgdGhlIGNvbGxhdGlvbiBydWxlcyB0aGF0IHRoZSB0YWJsZSBjb2xsYXRpb24gb2JqZWN0IHdhcwogICAqICAgICAgICAgY3JlYXRlZCBmcm9tLgogICAqLwogIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGdldFJ1bGVzKHZvaWQpIGNvbnN0OwoKICAvKioKICAgKiBSZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2VxdWVuY2VzIHRoYXQgZW5kIHdpdGggdGhlCiAgICogc3BlY2lmaWVkIGNvbXBhcmlzb24gb3JkZXIuCiAgICogQHBhcmFtIG9yZGVyIGEgY29sbGF0aW9uIG9yZGVyIHJldHVybmVkIGJ5IHByZXZpb3VzIG9yIG5leHQuCiAgICogQHJldHVybiBtYXhpbXVtIHNpemUgb2YgdGhlIGV4cGFuc2lvbiBzZXF1ZW5jZXMgZW5kaW5nIHdpdGggdGhlIGNvbGxhdGlvbgogICAqICAgICAgICAgZWxlbWVudCBvciAxIGlmIGNvbGxhdGlvbiBlbGVtZW50IGRvZXMgbm90IG9jY3VyIGF0IHRoZSBlbmQgb2YKICAgKiAgICAgICAgIGFueSBleHBhbnNpb24gc2VxdWVuY2UKICAgKiBAc2VlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciNnZXRNYXhFeHBhbnNpb24KICAgKi8KCWludDMyX3QgZ2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0OwoKICAvKioKICAgKiBSZXR1cm5zIGEgdW5pcXVlIGNsYXNzIElEIFBPTFlNT1JQSElDQUxMWS4gUHVyZSB2aXJ0dWFsIG92ZXJyaWRlLiBUaGlzCiAgICogbWV0aG9kIGlzIHRvIGltcGxlbWVudCBhIHNpbXBsZSB2ZXJzaW9uIG9mIFJUVEksIHNpbmNlIG5vdCBhbGwgQysrCiAgICogY29tcGlsZXJzIHN1cHBvcnQgZ2VudWluZSBSVFRJLiBQb2x5bW9ycGhpYyBvcGVyYXRvcj09KCkgYW5kIGNsb25lKCkKICAgKiBtZXRob2RzIGNhbGwgdGhpcyBtZXRob2QuCiAgICogQHJldHVybiBUaGUgY2xhc3MgSUQgZm9yIHRoaXMgb2JqZWN0LiBBbGwgb2JqZWN0cyBvZiBhIGdpdmVuIGNsYXNzIGhhdmUKICAgKiAgICAgICAgIHRoZSBzYW1lIGNsYXNzIElELiBPYmplY3RzIG9mIG90aGVyIGNsYXNzZXMgaGF2ZSBkaWZmZXJlbnQgY2xhc3MKICAgKiAgICAgICAgIElEcy4KICAgKi8KICB2aXJ0dWFsIFVDbGFzc0lEIGdldER5bmFtaWNDbGFzc0lEKHZvaWQpIGNvbnN0CiAgewogICAgcmV0dXJuIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRTdGF0aWNDbGFzc0lEKCk7CiAgfQoKICAvKioKICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBJRCBmb3IgdGhpcyBjbGFzcy4gVGhpcyBpcyB1c2VmdWwgb25seSBmb3IgY29tcGFyaW5nIHRvCiAgICogYSByZXR1cm4gdmFsdWUgZnJvbSBnZXREeW5hbWljQ2xhc3NJRCgpLiBGb3IgZXhhbXBsZToKICAgKiA8cHJlPgogICAqIEJhc2UqIHBvbHltb3JwaGljX3BvaW50ZXIgPSBjcmVhdGVQb2x5bW9ycGhpY09iamVjdCgpOwogICAqIGlmIChwb2x5bW9ycGhpY19wb2ludGVyLT5nZXREeW5hbWljQ2xhc3NJRCgpID09CiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXJpdmVkOjpnZXRTdGF0aWNDbGFzc0lEKCkpIC4uLgogICAqIDwvcHJlPgogICAqIEByZXR1cm4gVGhlIGNsYXNzIElEIGZvciBhbGwgb2JqZWN0cyBvZiB0aGlzIGNsYXNzLgogICAqLwogIHN0YXRpYyBVQ2xhc3NJRCBnZXRTdGF0aWNDbGFzc0lEKHZvaWQpCiAgewogICAgcmV0dXJuIChVQ2xhc3NJRCkmZmdDbGFzc0lEOwogIH0KCiAgLyoqCiAgICogUmV0dXJucyB0aGUgYmluYXJ5IGZvcm1hdCBvZiB0aGUgY2xhc3MncyBydWxlcy4gVGhlIGZvcm1hdCBpcyB0aGF0IG9mCiAgICogLmNvbCBmaWxlcy4KICAgKiBAcGFyYW0gbGVuZ3RoIFJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgZGF0YSwgaW4gYnl0ZXMKICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgKiBAcmV0dXJuIG1lbW9yeSwgb3duZWQgYnkgdGhlIGNhbGxlciwgb2Ygc2l6ZSAnbGVuZ3RoJyBieXRlcy4KICAgKi8KICB1aW50OF90ICpjbG9uZVJ1bGVEYXRhKGludDMyX3QgJmxlbmd0aCwgVUVycm9yQ29kZSAmc3RhdHVzKTsKCgkvKioKCSAqIFJldHVybnMgY3VycmVudCBydWxlcy4gRGVsdGEgZGVmaW5lcyB3aGV0aGVyIGZ1bGwgcnVsZXMgYXJlIHJldHVybmVkIG9yCiAgICoganVzdCB0aGUgdGFpbG9yaW5nLgoJICogQHBhcmFtIGRlbHRhIG9uZSBvZiAJVUNPTF9UQUlMT1JJTkdfT05MWSwgVUNPTF9GVUxMX1JVTEVTLgoJICogQHJldHVybiBVbmljb2RlU3RyaW5nIHdpdGggcnVsZXMKCSAqLwoJVW5pY29kZVN0cmluZyBnZXRSdWxlcyhVQ29sUnVsZU9wdGlvbiBkZWx0YSk7CgogIC8qKgogICAqIFVuaXZlcnNhbCBhdHRyaWJ1dGUgc2V0dGVyCiAgICogQHBhcmFtIGF0dHIgYXR0cmlidXRlIHR5cGUKICAgKiBAcGFyYW0gdmFsdWUgYXR0cmlidXRlIHZhbHVlCiAgICogQHBhcmFtIHN0YXR1cyB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoZSBvcGVyYXRpb24gd2VudCBvbiBzbW9vdGhseSBvciB0aGVyZSB3ZXJlIGVycm9ycwogICAqLwogIHZpcnR1YWwgdm9pZCBzZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCBVQ29sQXR0cmlidXRlVmFsdWUgdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpOwoKICAvKioKICAgKiBVbml2ZXJzYWwgYXR0cmlidXRlIGdldHRlci4KICAgKiBAcGFyYW0gYXR0ciBhdHRyaWJ1dGUgdHlwZQogICAqIEBwYXJhbSBzdGF0dXMgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgb3BlcmF0aW9uIHdlbnQgb24gc21vb3RobHkgb3IgdGhlcmUgd2VyZSBlcnJvcnMKICAgKiBAcmV0dXJuIGF0dHJpYnV0ZSB2YWx1ZQogICAqLwogIHZpcnR1YWwgVUNvbEF0dHJpYnV0ZVZhbHVlIGdldEF0dHJpYnV0ZShVQ29sQXR0cmlidXRlIGF0dHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cyk7CgogIC8qKgogICAqIFRocmVhZCBzYWZlIGNsb25pbmcgb3BlcmF0aW9uLgogICAqIEByZXR1cm4gcG9pbnRlciB0byB0aGUgbmV3IGNsb25lLCB1c2VyIHNob3VsZCByZW1vdmUgaXQuCiAgICovCiAgdmlydHVhbCBDb2xsYXRvciogc2FmZUNsb25lKHZvaWQpOwoKICAvKioKICAgKiBTdHJpbmcgY29tcGFyZSB0aGF0IHVzZXMgdXNlciBzdXBwbGllZCBjaGFyYWN0ZXIgaXRlcmF0aW9uLiBUaGUgaWRlYSBpcwogICAqIHRvIHByZXZlbnQgdXNlcnMgZnJvbSBoYXZpbmcgdG8gY29udmVydCB0aGUgd2hvbGUgc3RyaW5nIGludG8gVUNoYXIncwogICAqIGJlZm9yZSBjb21wYXJpbmcgc2luY2Ugc29tZXRpbWVzIHN0cmluZ3MgZGlmZmVyIG9uIGZpcnN0IGNvdXBsZSBvZgogICAqIGNoYXJhY3RlcnMuCiAgICogQHBhcmFtIGNvbGwgQ29sbGF0b3IgdG8gYmUgdXNlZCBmb3IgY29tcGFyaW5nCiAgICogQHBhcmFtIHNvdXJjZSBwb2ludGVyIHRvIGZ1bmN0aW9uIGZvciBpdGVyYXRpbmcgb3ZlciB0aGUgZmlyc3Qgc3RyaW5nCiAgICogQHBhcmFtIHRhcmdldCBwb2ludGVyIHRvIGZ1bmN0aW9uIGZvciBpdGVyYXRpbmcgb3ZlciB0aGUgc2Vjb25kIHN0cmluZwogICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiBjb21wYXJpbmcgdGhlIHN0cmluZ3M7IG9uZSBvZiBVQ09MX0VRVUFMLAogICAqICAgICAgICAgVUNPTF9HUkVBVEVSLCBVQ09MX0xFU1MKICAgKi8KICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0IGNvbXBhcmUoRm9yd2FyZENoYXJhY3Rlckl0ZXJhdG9yICZzb3VyY2UsCgkJCQkJCQkJICAgRm9yd2FyZENoYXJhY3Rlckl0ZXJhdG9yICZ0YXJnZXQpOwoKICAvKioKICAgKiBHZXQgdGhlIHNvcnQga2V5IGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZyb20gYW4gVW5pY29kZVN0cmluZy4KICAgKiBAcGFyYW0gc291cmNlIHN0cmluZyB0byBiZSBwcm9jZXNzZWQuCiAgICogQHBhcmFtIHJlc3VsdCBidWZmZXIgdG8gc3RvcmUgcmVzdWx0IGluLiBJZiBOVUxMLCBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkCiAgICogICAgICAgIHdpbGwgYmUgcmV0dXJuZWQuCiAgICogQHBhcmFtIHJlc3VsdExlbmd0aCBsZW5ndGggb2YgdGhlIHJlc3VsdCBidWZmZXIuIElmIGlmIG5vdCBlbm91Z2ggdGhlCiAgICogICAgICAgIGJ1ZmZlciB3aWxsIGJlIGZpbGxlZCB0byBjYXBhY2l0eS4KICAgKiBAcmV0dXJuIE51bWJlciBvZiBieXRlcyBuZWVkZWQgZm9yIHN0b3JpbmcgdGhlIHNvcnQga2V5CiAgICovCiAgdmlydHVhbCBpbnQzMl90IGdldFNvcnRLZXkoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCB1aW50OF90ICpyZXN1bHQsCgkJCQkJCSAgICAgICAgICAgICAgICAgaW50MzJfdCByZXN1bHRMZW5ndGgpIGNvbnN0OwoKICAvKioKICAgKiBHZXQgdGhlIHNvcnQga2V5IGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZyb20gYW4gVUNoYXIgYnVmZmVyLgogICAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4KICAgKiBAcGFyYW0gc291cmNlTGVuZ3RoIGxlbmd0aCBvZiBzdHJpbmcgdG8gYmUgcHJvY2Vzc2VkLiBJZiAtMSwgdGhlIHN0cmluZwogICAqICAgICAgICBpcyAwIHRlcm1pbmF0ZWQgYW5kIGxlbmd0aCB3aWxsIGJlIGRlY2lkZWQgYnkgdGhlIGZ1bmN0aW9uLgogICAqIEBwYXJhbSByZXN1bHQgYnVmZmVyIHRvIHN0b3JlIHJlc3VsdCBpbi4gSWYgTlVMTCwgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZAogICAqICAgICAgICB3aWxsIGJlIHJldHVybmVkLgogICAqIEBwYXJhbSByZXN1bHRMZW5ndGggbGVuZ3RoIG9mIHRoZSByZXN1bHQgYnVmZmVyLiBJZiBpZiBub3QgZW5vdWdoIHRoZQogICAqICAgICAgICBidWZmZXIgd2lsbCBiZSBmaWxsZWQgdG8gY2FwYWNpdHkuCiAgICogQHJldHVybiBOdW1iZXIgb2YgYnl0ZXMgbmVlZGVkIGZvciBzdG9yaW5nIHRoZSBzb3J0IGtleQogICAqLwogIHZpcnR1YWwgaW50MzJfdCBnZXRTb3J0S2V5KGNvbnN0IFVDaGFyICpzb3VyY2UsIGludDMyX3Qgc291cmNlTGVuZ3RoLAoJCQkJCQkgICAgICAgICAgICAgICAgIHVpbnQ4X3QgKnJlc3VsdCwgaW50MzJfdCByZXN1bHRMZW5ndGgpIGNvbnN0OwoKICAvKioKICAqIERldGVybWluZXMgdGhlIG1pbmltdW0gc3RyZW5ndGggdGhhdCB3aWxsIGJlIHVzZSBpbiBjb21wYXJpc29uIG9yCiAgKiB0cmFuc2Zvcm1hdGlvbi4KICAqIDxwPkUuZy4gd2l0aCBzdHJlbmd0aCA9PSBTRUNPTkRBUlksIHRoZSB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGlzIGlnbm9yZWQKICAqIDxwPkUuZy4gd2l0aCBzdHJlbmd0aCA9PSBQUklNQVJZLCB0aGUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgKiBhcmUgaWdub3JlZC4KICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY29tcGFyaXNvbiBsZXZlbC4KICAqIEBzZWUgUnVsZUJhc2VkQ29sbGF0b3Ijc2V0U3RyZW5ndGgKICAqLwogIHZpcnR1YWwgRUNvbGxhdGlvblN0cmVuZ3RoIGdldFN0cmVuZ3RoKHZvaWQpIGNvbnN0OwoKICAvKioKICAqIFNldHMgdGhlIG1pbmltdW0gc3RyZW5ndGggdG8gYmUgdXNlZCBpbiBjb21wYXJpc29uIG9yIHRyYW5zZm9ybWF0aW9uLgogICogPHA+RXhhbXBsZSBvZiB1c2U6CiAgKiA8cHJlPgogICogLiBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAqIC4gQ29sbGF0b3IqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywKICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAqIC4gaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgKiAuIG15Q29sbGF0aW9uLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6UFJJTUFSWSk7CiAgKiAuIC8vIHJlc3VsdCB3aWxsIGJlICJhYmMiID09ICJBQkMiCiAgKiAuIC8vIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIHdpbGwgYmUgaWdub3JlZAogICogLiBDb2xsYXRvcjo6Q29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZSgiYWJjIiwKICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFCQyIpOwogICogPC9wcmU+CiAgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yI2dldFN0cmVuZ3RoCiAgKiBAcGFyYW0gbmV3U3RyZW5ndGggdGhlIG5ldyBjb21wYXJpc29uIGxldmVsLgogICogQHN0YWJsZQogICovCiAgdmlydHVhbCB2b2lkIHNldFN0cmVuZ3RoKEVDb2xsYXRpb25TdHJlbmd0aCBuZXdTdHJlbmd0aCk7CgogIC8qKgogICogU2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIENvbGxhdG9yIG9iamVjdC4gc3VjY2VzcyBpcyBlcXVhbCB0bwogICogVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SIGlmIGVycm9yIG9jY3Vycy4KICAqIEBwYXJhbSB0aGUgbmV3IGRlY29tcG9zaXRpb24gbW9kZQogICogQHNlZSBDb2xsYXRvciNnZXREZWNvbXBvc2l0aW9uCiAgKi8KICB2aXJ0dWFsIHZvaWQgc2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpFTW9kZSAgbW9kZSk7CgogIC8qKgogICogR2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIENvbGxhdG9yIG9iamVjdC4KICAqIEByZXR1cm4gdGhlIGRlY29tcG9zaXRpb24gbW9kZQogICogQHNlZSBDb2xsYXRvciNzZXREZWNvbXBvc2l0aW9uCiAgKi8KICB2aXJ0dWFsIE5vcm1hbGl6ZXI6OkVNb2RlIGdldERlY29tcG9zaXRpb24odm9pZCkgY29uc3Q7Cgpwcml2YXRlOgoKICAvLyBwcml2YXRlIHN0YXRpYyBjb25zdGFudHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgc3RhdGljIGNvbnN0IGludDMyX3QgVU5NQVBQRUQ7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgQ0hBUklOREVYOyAgLy8gbmVlZCBsb29rIHVwIGluIC5jb21taXQoKQogIHN0YXRpYyBjb25zdCBpbnQzMl90IEVYUEFORENIQVJJTkRFWDsgLy8gRXhwYW5kIGluZGV4IGZvbGxvd3MKICBzdGF0aWMgY29uc3QgaW50MzJfdCBDT05UUkFDVENIQVJJTkRFWDsgIC8vIGNvbnRyYWN0IGluZGV4ZXMgZm9sbG93CgogIHN0YXRpYyBjb25zdCBpbnQzMl90IFBSSU1BUllPUkRFUklOQ1JFTUVOVDsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBTRUNPTkRBUllPUkRFUklOQ1JFTUVOVDsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBURVJUSUFSWU9SREVSSU5DUkVNRU5UOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IFBSSU1BUllPUkRFUk1BU0s7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgU0VDT05EQVJZT1JERVJNQVNLOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IFRFUlRJQVJZT1JERVJNQVNLOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IElHTk9SQUJMRU1BU0s7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgUFJJTUFSWURJRkZFUkVOQ0VPTkxZOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IFNFQ09OREFSWURJRkZFUkVOQ0VPTkxZOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IFBSSU1BUllPUkRFUlNISUZUOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IFNFQ09OREFSWU9SREVSU0hJRlQ7CgogIHN0YXRpYyBjb25zdCBpbnQzMl90IENPTEVMRU1FTlRTVEFSVDsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBQUklNQVJZTE9XWkVST01BU0s7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgUkVTRVRTRUNPTkRBUllURVJUSUFSWTsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBSRVNFVFRFUlRJQVJZOwoKICBzdGF0aWMgY29uc3QgaW50MzJfdCBQUklNSUdOT1JBQkxFOwoKICBzdGF0aWMgY29uc3QgaW50MTZfdCBGSUxFSUQ7CiAgc3RhdGljIGNvbnN0IGNoYXIgICAgKmtGaWxlbmFtZVN1ZmZpeDsKCiAgLy8gcHJpdmF0ZSBzdGF0aWMgdmFyaWFibGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogc3RhdGljIGNsYXNzIGlkCiAgKi8KICBzdGF0aWMgY2hhciBmZ0NsYXNzSUQ7CgogIC8vIHByaXZhdGUgZGF0YSBtZW1iZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICBVQm9vbCBkYXRhSXNPd25lZDsKCiAgLyoqCiAgKiBjIHN0cnVjdCBmb3IgY29sbGF0aW9uLiBBbGwgaW5pdGlhbGlzYXRpb24gZm9yIGl0IGhhcyB0byBiZSBkb25lIHRocm91Z2gKICAqIHNldFVDb2xsYXRvcigpLgogICovCiAgVUNvbGxhdG9yICp1Y29sbGF0b3I7CgogIC8qKgogICogUnVsZSBVbmljb2RlU3RyaW5nCiAgKi8KICBVbmljb2RlU3RyaW5nICp1cnVsZXN0cmluZzsKCiAgLy8gZnJpZW5kIGNsYXNzZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBTdHJlYW1lciB1c2VkIHRvIHJlYWQvd3JpdGUgYmluYXJ5IGNvbGxhdGlvbiBkYXRhIGZpbGVzLgogICovCiAgZnJpZW5kIGNsYXNzIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI7CgogIC8qKgogICogVXNlZCB0byBpdGVyYXRlIG92ZXIgY29sbGF0aW9uIGVsZW1lbnRzIGluIGEgY2hhcmFjdGVyIHNvdXJjZS4KICAqLwogIGZyaWVuZCBjbGFzcyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I7CgogIC8qKgogICogQ29sbGF0b3IgT05MWSBuZWVkcyBhY2Nlc3MgdG8gUnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgTG9jYWxlJiwKICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmKQogICovCiAgZnJpZW5kIGNsYXNzIENvbGxhdG9yOwoKICAvLyBwcml2YXRlIGNvbnN0cnVjdG9ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yCiAgICovCiAgUnVsZUJhc2VkQ29sbGF0b3IoKTsKCiAgLyoqCiAgKiBDb25zdHJ1Y3RvciB0aGF0IHRha2VzIGluIGEgVUNvbGxhdG9yIHN0cnVjdAogICogQHBhcmFtIGNvbGxhdG9yIFVDb2xsYXRvciBzdHJ1Y3QKICAqLwogIFJ1bGVCYXNlZENvbGxhdG9yKFVDb2xsYXRvciAqY29sbGF0b3IsIFVuaWNvZGVTdHJpbmcgKnJ1bGUpOwoKICAvKioKICAgKiBSdWxlQmFzZWRDb2xsYXRvciBjb25zdHJ1Y3Rvci4gVGhpcyBjb25zdHJ1Y3RvciB0YWtlcyBhIGxvY2FsZS4gVGhlCiAgICogb25seSBjYWxsZXIgb2YgdGhpcyBjbGFzcyBzaG91bGQgYmUgQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKCkuIElmCiAgICogY3JlYXRlSW5zdGFuY2UoKSBoYXBwZW5zIHRvIGtub3cgdGhhdCB0aGUgcmVxdWVzdGVkIGxvY2FsZSdzIGNvbGxhdGlvbiBpcwogICAqIGltcGxlbWVudGVkIGFzIGEgUnVsZUJhc2VkQ29sbGF0b3IsIGl0IGNhbiB0aGVuIGNhbGwgdGhpcyBjb25zdHJ1Y3Rvci4KICAgKiBPVEhFUldJU0UgSVQgU0hPVUxETidULCBzaW5jZSB0aGlzIGNvbnN0cnVjdG9yIEFMV0FZUyBSRVRVUk5TIEEgVkFMSUQKICAgKiBDT0xMQVRJT04gVEFCTEUuIEl0IGRvZXMgdGhpcyBieSBmYWxsaW5nIGJhY2sgdG8gZGVmYXVsdHMuCiAgICogQHBhcmFtIGRlc2lyZWRMb2NhbGUgbG9jYWxlIHVzZWQKICAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGUgc3RhdHVzCiAgICovCiAgUnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgTG9jYWxlJiBkZXNpcmVkTG9jYWxlLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvLyBwcml2YXRlIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAqIENyZWF0ZXMgdGhlIGMgc3RydWN0IGZvciB1Y29sbGF0b3IKICAqIEBwYXJhbSBsb2NhbGUgZGVzaXJlZCBsb2NhbGUKICAqIEBwYXJhbSBzdGF0dXMgZXJyb3Igc3RhdHVzCiAgKi8KICB2b2lkIHNldFVDb2xsYXRvcihjb25zdCBMb2NhbGUmIGxvY2FsZSwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgLyoqCiAgKiBDcmVhdGVzIHRoZSBjIHN0cnVjdCBmb3IgdWNvbGxhdG9yCiAgKiBAcGFyYW0gbG9jYWxlIGRlc2lyZWQgbG9jYWxlIG5hbWUKICAqIEBwYXJhbSBzdGF0dXMgZXJyb3Igc3RhdHVzCiAgKi8KICB2b2lkIHNldFVDb2xsYXRvcihjb25zdCBjaGFyKiBsb2NhbGUsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICogQ3JlYXRlcyB0aGUgYyBzdHJ1Y3QgZm9yIHVjb2xsYXRvcgogICogQHBhcmFtIGNvbGxhdG9yIG5ldyB1Y29sbGF0b3IgZGF0YQogICogQHBhcmFtIHN0YXR1cyBlcnJvciBzdGF0dXMKICAqLwogIHZvaWQgc2V0VUNvbGxhdG9yKFVDb2xsYXRvciAqY29sbGF0b3IpOwoKICAvKioKICAqIENvbnZlcnRzIEMncyBVQ29sbGF0aW9uUmVzdWx0IHRvIEVDb21wYXJpc29uUmVzdWx0CiAgKiBAcGFyYW0gcmVzdWx0IG1lbWJlciBvZiB0aGUgZW51bSBVQ29tcGFyaXNvblJlc3VsdAogICogQHJldHVybiBFQ29tcGFyaXNvblJlc3VsdCBlcXVpdmFsZW50IG9mIFVDb2xsYXRpb25SZXN1bHQKICAqLwogIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCBnZXRFQ29tcGFyaXNvblJlc3VsdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNvbGxhdGlvblJlc3VsdCAmcmVzdWx0KSBjb25zdDsKCiAgLyoqCiAgKiBDb252ZXJ0cyBDJ3MgVUNvbGxhdGlvblN0cmVuZ3RoIHRvIEVDb2xsYXRpb25TdHJlbmd0aAogICogQHBhcmFtIHN0cmVuZ3RoIG1lbWJlciBvZiB0aGUgZW51bSBVQ29sbGF0aW9uU3RyZW5ndGgKICAqIEByZXR1cm4gRUNvbGxhdGlvblN0cmVuZ3RoIGVxdWl2YWxlbnQgb2YgVUNvbGxhdGlvblN0cmVuZ3RoCiAgKi8KICBDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoIGdldEVDb2xsYXRpb25TdHJlbmd0aCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ29sbGF0aW9uU3RyZW5ndGggJnN0cmVuZ3RoKSBjb25zdDsKCiAgLyoqCiAgKiBDb252ZXJ0cyBDKysncyBFQ29sbGF0aW9uU3RyZW5ndGggdG8gVUNvbGxhdGlvblN0cmVuZ3RoCiAgKiBAcGFyYW0gc3RyZW5ndGggbWVtYmVyIG9mIHRoZSBlbnVtIEVDb2xsYXRpb25TdHJlbmd0aAogICogQHJldHVybiBVQ29sbGF0aW9uU3RyZW5ndGggZXF1aXZhbGVudCBvZiBFQ29sbGF0aW9uU3RyZW5ndGgKICAqLwogIFVDb2xsYXRpb25TdHJlbmd0aCBnZXRVQ29sbGF0aW9uU3RyZW5ndGgoCiAgICBjb25zdCBDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoICZzdHJlbmd0aCkgY29uc3Q7Cn07CgovLyBpbmxpbmUgbWV0aG9kIGltcGxlbWVudGF0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW5saW5lIFVCb29sIFJ1bGVCYXNlZENvbGxhdG9yOjpvcGVyYXRvciE9KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3QKewogIHJldHVybiAhKCp0aGlzID09IG90aGVyKTsKfQoKaW5saW5lIHZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OnNldFVDb2xsYXRvcihjb25zdCBjaGFyICpsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuOwogIGlmICh1Y29sbGF0b3IgJiYgZGF0YUlzT3duZWQpCiAgICB1Y29sX2Nsb3NlKHVjb2xsYXRvcik7CiAgdWNvbGxhdG9yID0gdWNvbF9vcGVuKGxvY2FsZSwgJnN0YXR1cyk7Cn0KCmlubGluZSB2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRVQ29sbGF0b3IoY29uc3QgTG9jYWxlICZsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKQp7CiAgc2V0VUNvbGxhdG9yKGxvY2FsZS5nZXROYW1lKCksIHN0YXR1cyk7Cn0KCmlubGluZSB2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRVQ29sbGF0b3IoVUNvbGxhdG9yICpjb2xsYXRvcikKewogIGlmICh1Y29sbGF0b3IgJiYgZGF0YUlzT3duZWQpCiAgICB1Y29sX2Nsb3NlKHVjb2xsYXRvcik7CiAgdWNvbGxhdG9yID0gY29sbGF0b3I7Cn0KCmlubGluZSBDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgUnVsZUJhc2VkQ29sbGF0b3I6OmdldEVDb21wYXJpc29uUmVzdWx0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNvbGxhdGlvblJlc3VsdCAmcmVzdWx0KSBjb25zdAp7CiAgc3dpdGNoIChyZXN1bHQpCiAgewogIGNhc2UgVUNPTF9MRVNTIDoKICAgIHJldHVybiBDb2xsYXRvcjo6TEVTUzsKICBjYXNlIFVDT0xfRVFVQUwgOgogICAgcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKICBkZWZhdWx0IDoKICAgIHJldHVybiBDb2xsYXRvcjo6R1JFQVRFUjsKICB9Cn0KCmlubGluZSBDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRFQ29sbGF0aW9uU3RyZW5ndGgoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDb2xsYXRpb25TdHJlbmd0aCAmc3RyZW5ndGgpIGNvbnN0CnsKICBzd2l0Y2ggKHN0cmVuZ3RoKQogIHsKICBjYXNlIFVDT0xfUFJJTUFSWSA6CiAgICByZXR1cm4gQ29sbGF0b3I6OlBSSU1BUlk7CiAgY2FzZSBVQ09MX1NFQ09OREFSWSA6CiAgICByZXR1cm4gQ29sbGF0b3I6OlNFQ09OREFSWTsKICBjYXNlIFVDT0xfVEVSVElBUlkgOgogICAgcmV0dXJuIENvbGxhdG9yOjpURVJUSUFSWTsKICBkZWZhdWx0IDoKICAgIHJldHVybiBDb2xsYXRvcjo6SURFTlRJQ0FMOwogIH0KfQoKaW5saW5lIFVDb2xsYXRpb25TdHJlbmd0aCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0VUNvbGxhdGlvblN0cmVuZ3RoKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGggJnN0cmVuZ3RoKSBjb25zdAp7CiAgc3dpdGNoIChzdHJlbmd0aCkKICB7CiAgY2FzZSBDb2xsYXRvcjo6UFJJTUFSWSA6CiAgICByZXR1cm4gVUNPTF9QUklNQVJZOwogIGNhc2UgQ29sbGF0b3I6OlNFQ09OREFSWSA6CiAgICByZXR1cm4gVUNPTF9TRUNPTkRBUlk7CiAgY2FzZSBDb2xsYXRvcjo6VEVSVElBUlkgOgogICAgcmV0dXJuIFVDT0xfVEVSVElBUlk7CiAgZGVmYXVsdCA6CiAgICByZXR1cm4gVUNPTF9JREVOVElDQUw7CiAgfQp9CgojZW5kaWYK