q0lNUE9SVCBlbWa7CqtJTVBPUlQgbWV0YWFibbsKq0lNUE9SVCBtZXRhYWJtOjphY3S7CqtJTVBPUlQgbWV0YWFibTo6ZnVuY3Rpb267CgqrRVhURU5TSU9OIG1ldGFhYm06OnRtcGw6OnR5cGVzuwqrRVhURU5TSU9OIG1ldGFhYm06OnRtcGw6Om5hbWVzuyAKq0VYVEVOU0lPTiBtZXRhYWJtOjp0bXBsOjppbmZlcrsKq0VYVEVOU0lPTiBtZXRhYWJtOjp0bXBsOjp1dGlsuwqrRVhURU5TSU9OIG1ldGFhYm06OnRtcGw6OnByb2plY3Rpb25zuwqrRVhURU5TSU9OIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6bmFtZXNhc2NhcGW7CqtFWFRFTlNJT04gbWV0YWFibTo6YXNjYXBlOjp0bXBsOjppbmZlcmFzY2FwZbsKq0VYVEVOU0lPTiBtZXRhYWJtOjplc2NhcGU6OnRtcGw6OmluZmVyZXNjYXBluwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbXBvcnRzIEZPUiBTU3R5bGUtuwppbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5DZWxsT2NjdXBhbnQ7CmltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLkhvc3RDZWxsOwppbXBvcnQgb3JnLmFzY2FwZS51dGlsLnZpcy5Db2xvckZlYXR1cmVDb25jcmV0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmRyYXcyZC5Db2xvckNvbnN0YW50czsKaW1wb3J0IG9yZy5lY2xpcHNlLmRyYXcyZC5JRmlndXJlOwppbXBvcnQgb3JnLmVjbGlwc2UuZHJhdzJkLlNoYXBlOwppbXBvcnQgb3JnLmVjbGlwc2UuZHJhdzJkLmdlb21ldHJ5LkRpbWVuc2lvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5Db2xvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmFtcC5hZ2YuZ2VmLkFnZW50RWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5hbXAuZXNjYXBlLmFzY2FwZS5nZWYuSG9zdENlbGxFZGl0UGFydDsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6SW1wb3J0cyBGT1IgU0FnZW50LbsKCWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwoJaW1wb3J0IGphdmEudXRpbC5MaXN0OwoJaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKCQoJaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JQWRhcHRlckZhY3Rvcnk7CglpbXBvcnQgb3JnLmVjbGlwc2UuYW1wLmFnZi5JR3JhcGhpY3NBZGFwdGVkOwoJaW1wb3J0IG9yZy5lY2xpcHNlLmFtcC5hZ2YuSUdyYXBoaWNzQWRhcHRlcjsKCQoJaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5Db2xvcjsKCWltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLklDb2xvclByb3ZpZGVyOwoJCglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5BZ2VudDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLkNlbGw7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5DZWxsT2NjdXBhbnQ7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5Ib3N0Q2VsbDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLkxvY2F0ZWRBZ2VudDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLlNjYXBlOwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuZXZlbnQuU2NhcGVFdmVudDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLnJ1bGUuUnVsZTsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLnJ1bGUuRXhlY3V0ZVRoZW5VcGRhdGU7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5zcGFjZS5Db2xsZWN0aW9uU3BhY2U7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5zcGFjZS5Db29yZGluYXRlOwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuc3BhY2UuQ29vcmRpbmF0ZTJERGlzY3JldGU7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5zcGFjZS5HcmFwaDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLnNwYWNlLkxvY2F0aW9uOwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuc3BhY2UuU2luZ2xldG9uOwoJaW1wb3J0IG9yZy5hc2NhcGUucnVudGltZS5Ob25HcmFwaGljUnVubmVyOwoJaW1wb3J0IG9yZy5hc2NhcGUudXRpbC5Db25kaXRpb25hbDsKCWltcG9ydCBvcmcuYXNjYXBlLnV0aWwuZGF0YS5EYXRhUG9pbnQ7IAoJaW1wb3J0IG9yZy5hc2NhcGUudXRpbC5kYXRhLkRhdGFQb2ludENvbmNyZXRlOwoJaW1wb3J0IG9yZy5hc2NhcGUudXRpbC52aXMuQ29sb3JGZWF0dXJlOwoJaW1wb3J0IG9yZy5hc2NhcGUudXRpbC52aXMuQ29sb3JGZWF0dXJlQ29uY3JldGU7CglpbXBvcnQgb3JnLmFzY2FwZS52aWV3LnZpcy5DaGFydFZpZXc7CglpbXBvcnQgb3JnLmFzY2FwZS52aWV3LnZpcy5HRUZWaWV3OwoJaW1wb3J0IG9yZy5hc2NhcGUudmlldy52aXMuR3JhcGhWaWV3OwoJCgmrdGFyZ2V0RGVmLnByb2NlZWQoKbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6RXh0ZW5kVHlwZSBGT1IgU1Byb2plY3Rpb24tu1NjYXBlq0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpFeHRlbmRUeXBlIEZPUiBTQ29udGV4dC27q3R5cGVOYW1lKCktu6tFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6RXh0ZW5kVHlwZSBGT1IgU0FnZW50LbtTY2FwZatFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkNsYXNzSW5oZWlyaXRhbmNlIEZPUiBTQ29udGV4dC27IGV4dGVuZHMgU2NhcGUgaW1wbGVtZW50cyBJR3JhcGhpY3NBZGFwdGVkq0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpDbGFzc0luaGVpcml0YW5jZSBGT1IgU0FnZW50LbsgZXh0ZW5kcyCrZXh0ZW5kVHlwZSgpu6tFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6Q2xhc3NJbmhlaXJpdGFuY2UgRk9SIFNTdHlsZS27IGltcGxlbWVudHMgqyhhZ2VudC5pc0hvc3QoKSA/ICJIb3N0Q2VsbCIgOiAiQWdlbnQiKbtFZGl0UGFydKtFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkZpbGVzIEZPUiBTQWdlbnQtuwoJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpDbGFzc0ZpbGUtuwogICAgq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpDbGFzc0ZpbGUgRk9SRUFDSCBhdHRyaWJ1dGVzLnR5cGVTZWxlY3QoU1N0YXRlKS27CqtFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkJvZHkgRk9SIFNBZ2VudC27CgmrdGFyZ2V0RGVmLnByb2NlZWQoKS27CgmrRVhQQU5EIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6U2NhcGVBc3BlY3Q6OkFnZW50Qm9keS27CgmrRVhQQU5EIFN0YXJ0U2ltdWxhdGlvbkFnZW50Q2hpbGS7CgmrRVhQQU5EIENhbGN1bGF0ZVRpbWVTdGVwuwqrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpCb2R5IEZPUiBTQ29udGV4dC27CgogICAgq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpTY2FwZUJvZHktuwogICAgCiAgICCrRVhQQU5EIENyZWF0ZUdyYXBoaWNzTWV0aG9kcy27CgoJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7CglwdWJsaWMgSUdyYXBoaWNzQWRhcHRlciBnZXRHcmFwaGljc0FkYXB0ZXIoKSB7CiAgICAgICAgcmV0dXJuIKt0eXBlTmFtZSgpu0dyYXBoaWNzQWRhcHRlci5nZXREZWZhdWx0KCk7Cgl9CgmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKICAgIHByaXZhdGUgQ29sb3IgZ2V0SW5mZXJyZWRDaGFydENvbG9yKE9iamVjdCBhZ2VudCwKICAgICAgICBJQ29sb3JQcm92aWRlciBjb2xvclByb3ZpZGVyKSB7CiAgICAgICAgQ29sb3IgY29sb3IgPSBjb2xvclByb3ZpZGVyLmdldEZvcmVncm91bmQoYWdlbnQpOwoJCWlmIChjb2xvciA9PSBDb2xvckZlYXR1cmUuQkxBQ0spIHsKCQkJY29sb3IgPSBDb2xvckZlYXR1cmVDb25jcmV0ZQoJCQkJCS5jcmVhdGVIU0IoKGZsb2F0KSBqYXZhLmxhbmcuTWF0aC5yYW5kb20oKSAqIDM2MGYsIDEuMGYsCgkJCQkJCQkwLjhmKTsKCQl9CiAgICAgICAgcmV0dXJuIGNvbG9yOwogICAgfQogICAgq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7CiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgKG5ldyBOb25HcmFwaGljUnVubmVyKCkpLm9wZW5JbnN0YW5jZSgiq2ltcGxlbWVudGF0aW9uLnF1YWxpZmllZE5hbWW7Iik7CiAgICB9CgogICAgq0VYUEFORCBFeGVjSUFnZW50Q2hpbGS7CiAgICAKq0VOREFST1VORLsKCqtERUZJTkUgRXhlY0lBZ2VudENoaWxkIEZPUiBTQ29udGV4dLsKCatFWFBBTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6TWV0aG9kQ29tbWVudLsKCUBPdmVycmlkZQoJcHVibGljIHZvaWQgZXhlY3V0ZU9uTWVtYmVycygpewoJCWludCB0aW1lU3RlcCA9IGdldFJ1bm5lcigpLmdldFBlcmlvZCgpOwoJCXN0YXJ0U2ltdWxhdGlvbkFnZW50Q2hpbGQodGltZVN0ZXApOwoJCatGT1JFQUNIIGFnZW50cyBBUyBhZ2VudLsKCQkJq0lGICFhZ2VudC5pc0hvc3QoKbsKCQkJCS8vQSBub3JtYWwgbW92YWJsZSBhZ2VudAoJCQkJKCirYWdlbnQuaW1wbGVtZW50YXRpb24uY2xhc3NOYW1luymrYWdlbnQuc2NhcGUoKbsuZ2V0UHJvdG90eXBlQWdlbnQoKSkuc3RhcnRTaW11bGF0aW9uQWdlbnRDaGlsZCh0aW1lU3RlcCk7CgkJCatFTFNFuwoJCQkJLy90aGlzIGlzIGFuIGFnZW50IHRoYXQgcmVwcmVzZW50IGEgY2VsbCBhbmQgY2Fubm90IG1vdmUuCgkJCQmrRVhQQU5EIEhvc3RBZ2VudFN0YXJ0KGFnZW50LmltcGxlbWVudGF0aW9uLmNsYXNzTmFtZSkgRk9SIHJvb3RBY3Rpdml0ebsKCQkJq0VORElGuwoJCatFTkRGT1JFQUNIuwoJCXN1cGVyLmV4ZWN1dGVPbk1lbWJlcnMoKTsKCQljYWxjdWxhdGVUaW1lU3RlcCh0aW1lU3RlcCk7CgkJq0ZPUkVBQ0ggYWdlbnRzIEFTIGFnZW50uwoJCQmrSUYgIWFnZW50LmlzSG9zdCgpuwoJCQkJLy9BIG5vcm1hbCBtb3ZhYmxlIGFnZW50CgkJCQkoKKthZ2VudC5pbXBsZW1lbnRhdGlvbi5jbGFzc05hbWW7KathZ2VudC5zY2FwZSgpuy5nZXRQcm90b3R5cGVBZ2VudCgpKS5jYWxjdWxhdGVUaW1lU3RlcCh0aW1lU3RlcCk7CgkJCatFTFNFuwoJCQkJLy90aGlzIGlzIGFuIGFnZW50IHRoYXQgcmVwcmVzZW50IGEgY2VsbCBhbmQgY2Fubm90IG1vdmUuCgkJCQmrRVhQQU5EIEhvc3RBZ2VudENhbGMoYWdlbnQuaW1wbGVtZW50YXRpb24uY2xhc3NOYW1lKSBGT1Igcm9vdEFjdGl2aXR5uwoJCQmrRU5ESUa7CgkJq0VOREZPUkVBQ0i7Cgl9CqtFTkRERUZJTkW7CgqrUkVNuyBTVEFSVDsgY2hlY2sgaXMgaG9zdENlbGwgYW5kIHNldCB0aGUgc3RhcnQgdGltZSBvbiB0aGUgSUFnZW50Q2hpbGQgKHRyYXZlcnNlIHRoZSB0aHJlZSB0byB0aGUgQUJ1aWxkR3JpZCmrRU5EUkVNuwqrREVGSU5FIEhvc3RBZ2VudFN0YXJ0KFN0cmluZyB0eXBlTmFtZSkgRk9SIElBY3S7CqtFTkRERUZJTkW7CgqrREVGSU5FIEhvc3RBZ2VudFN0YXJ0KFN0cmluZyB0eXBlTmFtZSkgRk9SIEFHcm91cLsKCatFWFBBTkQgSG9zdEFnZW50U3RhcnQodHlwZU5hbWUpIEZPUkVBQ0ggcm9vdHO7CqtFTkRERUZJTkW7CgqrREVGSU5FIEhvc3RBZ2VudFN0YXJ0KFN0cmluZyB0eXBlTmFtZSkgRk9SIEFCdWlsZLsKCatFWFBBTkQgSG9zdEFnZW50U3RhcnQodHlwZU5hbWUpIEZPUkVBQ0ggdGFyZ2V0c7sKq0VORERFRklORbsKCqtERUZJTkUgSG9zdEFnZW50U3RhcnQoU3RyaW5nIHR5cGVOYW1lKSBGT1IgQUJ1aWxkR3JpZLsKCSgoq3R5cGVOYW1luykgq3RoaXMucHJvamVjdGlvbi5maWVsZE5hbWUoKbsuZ2V0UHJvdG90eXBlQWdlbnQoKSkuc3RhcnRTaW11bGF0aW9uQWdlbnRDaGlsZCh0aW1lU3RlcCk7CqtFTkRERUZJTkW7CqtSRU27RU5EIHNldCBzdGFydCB0aW1lIKtFTkRSRU27CgqrUkVNuyBTVEFSVDsgY2hlY2sgaXMgaG9zdENlbGwgYW5kIHN0YXJ0IHRoZSBjYWxjdWxhdGlvbiBvbiB0aGUgSUFnZW50Q2hpbGQgKHRyYXZlcnNlIHRoZSB0aHJlZSB0byB0aGUgQUJ1aWxkR3JpZCmrRU5EUkVNuwqrREVGSU5FIEhvc3RBZ2VudENhbGMoU3RyaW5nIHR5cGVOYW1lKSBGT1IgSUFjdLsKq0VORERFRklORbsKCqtERUZJTkUgSG9zdEFnZW50Q2FsYyhTdHJpbmcgdHlwZU5hbWUpIEZPUiBBR3JvdXC7CgmrRVhQQU5EIEhvc3RBZ2VudENhbGModHlwZU5hbWUpIEZPUkVBQ0ggcm9vdHO7CqtFTkRERUZJTkW7CgqrREVGSU5FIEhvc3RBZ2VudENhbGMoU3RyaW5nIHR5cGVOYW1lKSBGT1IgQUJ1aWxkuwoJq0VYUEFORCBIb3N0QWdlbnRDYWxjKHR5cGVOYW1lKSBGT1JFQUNIIHRhcmdldHO7CqtFTkRERUZJTkW7CgqrREVGSU5FIEhvc3RBZ2VudENhbGMoU3RyaW5nIHR5cGVOYW1lKSBGT1IgQUJ1aWxkR3JpZLsKCSgoq3R5cGVOYW1luykgq3RoaXMucHJvamVjdGlvbi5maWVsZE5hbWUoKbsuZ2V0UHJvdG90eXBlQWdlbnQoKSkuY2FsY3VsYXRlVGltZVN0ZXAodGltZVN0ZXApOwqrRU5EREVGSU5FuwqrUkVNu0VORCBjYWxjdWxhdGUgq0VORFJFTbsKCgqrREVGSU5FIFN0YXJ0U2ltdWxhdGlvbkFnZW50Q2hpbGQgRk9SIFNBZ2VudLsKCatFWFBBTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6TWV0aG9kQ29tbWVudLsKCXB1YmxpYyB2b2lkIHN0YXJ0U2ltdWxhdGlvbkFnZW50Q2hpbGQoaW50IHRpbWVTdGVwKXsKCQlpZih0aW1lU3RlcCA9PSBnZXRSb290KCkuZ2V0UnVubmVyKCkuZ2V0RWFybGllc3RQZXJpb2QoKSl7CgkJCWZvcihJQWdlbnRDaGlsZCB0bXA6Y2hpbGRyZW4pewoJCQkJdG1wLnN0YXJ0U2ltdWxhdGlvbih0aW1lU3RlcCk7CgkJCX0KCQl9CQoJfQqrRU5EREVGSU5FuwoKq0RFRklORSBDYWxjdWxhdGVUaW1lU3RlcCBGT1IgU0FnZW50uwoJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpNZXRob2RDb21tZW50uwoJcHVibGljIHZvaWQgY2FsY3VsYXRlVGltZVN0ZXAoaW50IHRpbWVTdGVwKXsKCQlmb3IoSUFnZW50Q2hpbGQgdG1wOmNoaWxkcmVuKXsKCQkJdG1wLmNhbGN1bGF0ZSh0aW1lU3RlcCk7CgkJfQoJfQqrRU5EREVGSU5FuwoKq0RFRklORSBDcmVhdGVHcmFwaGljc01ldGhvZHMgRk9SIFNDb250ZXh0uwogICAgq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7Cglwcm90ZWN0ZWQgdm9pZCBjcmVhdGVDaGFydFZpZXdzKCkgewoJCUNoYXJ0VmlldyBjaGFydCA9IG5ldyBDaGFydFZpZXcoKTsKCQmrRVhQQU5EIEJ1aWxkQ2hhcnRTZWxlY3Rpb24gRk9SRUFDSCBhZ2VudHMtuwoJICAgIGFkZFZpZXcoY2hhcnQpOwoJfQoKICAgIKtFWFBBTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6R2VuZXJhdGVDb21tZW50uwoJcHJvdGVjdGVkIHZvaWQgY3JlYXRlMkRWaWV3cygpIHsKCQlhZGRWaWV3KG5ldyBHRUZWaWV3KCkpOwoJfQoKICAgIKtFWFBBTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6R2VuZXJhdGVDb21tZW50uwoJcHJvdGVjdGVkIHZvaWQgY3JlYXRlR3JhcGhWaWV3cygpIHsKICAgIAmrRk9SRUFDSCBhY3RzKCkudHlwZVNlbGVjdChBQnVpbGROZXR3b3JrKSBBUyBncmFwaEJ1aWxkZXItuwoJCQmrZ3JhcGhCdWlsZGVyLnByb2plY3Rpb24uZmllbGROYW1lKCm7LmFkZFZpZXcobmV3IEdyYXBoVmlldygpKTsKICAgIAmrRU5ERk9SRUFDSC27IAogICAgfQqrRU5EREVGSU5FuwoKq0FST1VORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpWaWV3QnVpbGRlciBGT1IgQUdyb3VwLbsKCatJRiByZWZlcmVuY2UucGFyZW50ID09IG51bGwtuwoJY3JlYXRlQ2hhcnRWaWV3cygpOwogICAgq0VORElGLbsKICAgIKtJRiByZWZlcmVuY2UubWV0YVR5cGUgPT0gU0NvbnRleHQgJiYgISgoU0NvbnRleHQpIHJlZmVyZW5jZSkucHJvamVjdGlvbnMudHlwZVNlbGVjdChTTkRpbWVuc2lvbmFsKS5pc0VtcHR5LbsKCWNyZWF0ZTJEVmlld3MoKTsKCatFTkRJRi27CiAgICCrSUYgcmVmZXJlbmNlLm1ldGFUeXBlID09IFNDb250ZXh0ICYmICEoKFNDb250ZXh0KSByZWZlcmVuY2UpLnByb2plY3Rpb25zLnR5cGVTZWxlY3QoU05ldHdvcmspLmlzRW1wdHm7CgljcmVhdGVHcmFwaFZpZXdzKCk7CgmrRU5ESUYtuwogICAgq3RhcmdldERlZi5wcm9jZWVkKCktuwqrRU5EQVJPVU5EuwoKq0RFRklORSBCdWlsZENoYXJ0U2VsZWN0aW9uIEZPUiBTQWdlbnS7CiAgICCrSUYgIXN0eWxlcy5pc0VtcHR5LbsKICAgIGZpbmFsIKtvd25lci50eXBlTmFtZSgpuyCraWQoKbtTY2FwZSA9IG5ldyCrb3duZXIudHlwZU5hbWUoKbsoKTsKICAgIKtpZCgpu1NjYXBlLnNldFJ1bm5lcihuZXcgTm9uR3JhcGhpY1J1bm5lcigpKTsKCat0eXBlTmFtZSgpuyCraWQoKbsgPSBuZXcgq3R5cGVOYW1lKCm7KCkgewoJCQmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKICAgICAgICAgICAgcHVibGljIHZvaWQgcmVxdWVzdFVwZGF0ZSgpIHsKICAgICAgICAgICAgfQogICAgICAgICAgICCrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKICAgICAgICAgICAgcHVibGljIKtvd25lci50eXBlTmFtZSgpuyBnZXSrb3duZXIudHlwZU5hbWUoKbsoKSB7CiAgICAgICAgICAgIAlyZXR1cm4gq2lkKCm7U2NhcGU7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgq2lkKCm7U2NhcGUuYWRkKKtpZCgpuyk7CgmrSUYgIWlzSG9zdCgpICYmIGlzRGlzY3JldGUoKS27CglIb3N0Q2VsbCCraWQoKbtIb3N0ID0gbmV3IEhvc3RDZWxsKCkgewoJCQmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKICAgICAgICAgICAgcHVibGljIHZvaWQgcmVxdWVzdFVwZGF0ZSgpIHsKICAgICAgICAgICAgfQogICAgICAgIH07CgmraWQoKbtIb3N0LnNldE9jY3VwYW50KChDZWxsT2NjdXBhbnQpIKtpZCgpuyk7CgmrRU5ESUYtuwogICAgq0ZPUkVBQ0ggc3R5bGVzIEFTIHN0eWxluwogICAgSUNvbG9yUHJvdmlkZXIgq3N0eWxlLmlkKCm7Q29sb3JQcm92aWRlciA9IG5ldyCrc3R5bGVzLmdldCgwKS50eXBlTmFtZSgpu0NvbG9yUHJvdmlkZXIoKTsKCatGT1JFQUNIIHN0eWxlLnNldHRlclNwYWNlKCkgQVMgc2V0dGVyuwogICAgqygoTGlzdCkgc2V0dGVyKS5sYXN0KCm7OwoJY2hhcnQuYWRkU2VyaWVzKCJDb3VudCCrdHlwZU5hbWUoKbsgqygoTGlzdCkgc2V0dGVyKS5maXJzdCgpuyIsIGdldEluZmVycmVkQ2hhcnRDb2xvciiraWQoKbssIKtzdHlsZS5pZCgpu0NvbG9yUHJvdmlkZXIpKTsKICAgIKtFTkRGT1JFQUNILbsKICAgIKtFTkRGT1JFQUNILbsKICAgIKtFTkRJRi27CqtFTkRERUZJTkW7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkZ1bmN0aW9uSW5uZXJCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBU2luay27CiAgICCrSUYgZnVuY3Rpb24uaWQoKSA9PSAicmFuZG9tVW5pdCItuwogICAgICAgIGdldFJhbmRvbSgpLm5leHREb3VibGUoKQogICAgq0VMU0VJRiBmdW5jdGlvbi5pZCgpID09ICJyYW5kb21JcyItuwogICAgICAgIGdldFJhbmRvbSgpLm5leHRCb29sZWFuKCkKICAgIKtFTFNFSUYgZnVuY3Rpb24uaWQoKSA9PSAidW5pZm9ybURpc3RyaWJ1dGlvbiItuwogICAgICAgIHJhbmRvbUluUmFuZ2Uoq2lucHV0cy5leHByZXNzaW9uKHBhdGgsIGlubmVyKS50b1N0cmluZygiLCAiKbspOwogICAgq0VMU0VJRiBmdW5jdGlvbi5pZCgpID09ICJ0aW1lTm93Ii27CgkJq3BhdGgubGFzdCgpLmFjY2Vzc1BhdGgodGhpcywgaW5uZXIpu6tyZWZlcmVuY2Uub3duZXIgIT0gbnVsbCA/ICJnZXRTY2FwZSgpLiIgOiAiIrtnZXRQZXJpb2QoKQogICAgq0VMU0VJRiBmdW5jdGlvbi5pZCgpID09ICJhdmFpbGFibGUiLbsKICAgICAgICBpc0F2YWlsYWJsZSgpCiAgICCrRUxTRUlGIGZ1bmN0aW9uLmlkKCkgPT0gIndpdGhpbkJvdW5kYXJpZXMiLbsKICAgICAgICCrZXhwcmVzc2lvblNpbmsocGF0aCwgZnVuY3Rpb24sIGlubmVyKbsKICAgIKtFTFNFSUYgZnVuY3Rpb24uaWQoKSA9PSAiY29sb3JSR0IiLbsKICAgICAgICBDb2xvckZlYXR1cmVDb25jcmV0ZS5jcmVhdGUoKGludCkgKKtpbnB1dHMuZXhwcmVzc2lvbihwYXRoLCBpbm5lcikudG9TdHJpbmcoIiAqIDI1NSksIChpbnQpICgiKbsgKiAyNTUpKQogICAgq0VMU0VJRiBmdW5jdGlvbi5pZCgpLnN0YXJ0c1dpdGgoImNvbG9yIiktuwogICAgICAgIENvbG9yQ29uc3RhbnRzLqtmdW5jdGlvbi5pZCgpLnJlcGxhY2VGaXJzdCgiY29sb3IiLCIiKS50b0ZpcnN0TG93ZXIoKbsKCatFTFNFLbsKCQmrdGFyZ2V0RGVmLnByb2NlZWQoKS27CgmrRU5ESUYtuwqrRU5EQVJPVU5EuwoKq0RFRklORSBTdHlsZVByb3ZpZGVyIEZPUiBTQWdlbnS7CiAgICCrSUYgc3R5bGVzLnNpemUgPiAwLbsKCSAgICAgICAgaWYgKG1vZGVsIGluc3RhbmNlb2Ygq2ltcGxlbWVudGF0aW9uLmNsYXNzTmFtZbspIHsKCSAgICAgICAgICAgIHJldHVybiBuZXcgq3N0eWxlcy5nZXQoMCkuaW1wbGVtZW50YXRpb24ucXVhbGlmaWVkTmFtZbsoKTsKCSAgICAgICAgfQogICAgq0VORElGLbsKq0VORERFRklORbsKq0RFRklORSBSZWN1cnNlQWdlbnRQcm92aWRlcnMgRk9SIFNBZ2VudLsKCatFWFBBTkQgU3R5bGVQcm92aWRlcrsKq0VORERFRklORbsKq0RFRklORSBSZWN1cnNlQWdlbnRQcm92aWRlcnMgRk9SIFNDb250ZXh0uwoJq0VYUEFORCBTdHlsZVByb3ZpZGVyuwoJq0VYUEFORCBSZWN1cnNlQWdlbnRQcm92aWRlcnMgRk9SRUFDSCBhZ2VudHO7CqtFTkRERUZJTkW7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkV4dGVuZFR5cGUgRk9SIEFTaW5rLbsKCatJRiBmdW5jdGlvbi5jb2xvcigpLbtDb2xvcgoJq0VMU0VJRiBmdW5jdGlvbi5zaGFwZSgpLbtTaGFwZQoJq0VMU0VJRiBmdW5jdGlvbi5pZCgpLnN0YXJ0c1dpdGgoImdyYXBoaWMiKS27U2hhcGUKCatFTFNFSUYgZnVuY3Rpb24uaWQoKSA9PSAicmFuZG9tU3RhdGUiLburaW5wdXRzLmdldCgwKS52YWx1ZS50eXBlTmFtZSgpuwoJq0VMU0Utu6t0eXBlTmFtZSgpu6tFTkRJRi27CqtFTkRBUk9VTkS7CgqrREVGSU5FIFN0eWxlU2VsZWN0b3IgKFNQcm9qZWN0aW9uIHByb2plY3Rpb24pIEZPUiBTUHJvamVjdGlvbi27CqtFTkRERUZJTkW7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6Ok90aGVyQWNjZXNzb3JzIEZPUiBTQWdlbnQtuwoJq3RhcmdldERlZi5wcm9jZWVkKCktuwogICAgq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpOYW1lQWNjZXNzb3ItuwqrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpCdWlsZGVyIEZPUiBTQWdlbnQtuwoJq0lGIChyb290QWN0aXZpdHkgIT0gbnVsbCktuwoJCatFWFBBTkQgbWV0YWFibTo6YXNjYXBlOjp0bXBsOjpTY2FwZUFzcGVjdDo6Q2hpbGRCdWlsZGVyIEZPUiByb290QWN0aXZpdHktuwoJq0VORElGLbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6TWV0aG9kUG90ZW50aWFsIChtZXRhYWJtOjphY3Q6OkFBY3Qgd2l0aGluKSBGT1IgRkZ1bmN0aW9uLbsKCatJRiAoaWQoKSA9PSAid2l0aGluQm91bmRhcmllcyIpIHx8IChpZCgpID09ICJkaXN0YW5jZSIpLbsKCQmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6Ok1ldGhvZC27CgmrRUxTRS27CgkJq3RhcmdldERlZi5wcm9jZWVkKCktuwoJq0VORElGLbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6TWV0aG9kUG90ZW50aWFsIChtZXRhYWJtOjphY3Q6OkFBY3Qgd2l0aGluKSBGT1IgQVF1ZXJ5LbsKCatJRiAoZnVuY3Rpb24uaWQoKSA9PSAibWluaW1pemUiKSB8fCAoZnVuY3Rpb24uaWQoKSA9PSAibWF4aW1pemUiKS27CiAgICAvKioKICAgICAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CiAgICAgKiBBIGRhdGEgcG9pbnQgdXNlZCB3aXRoaW4gYSBzZWFyY2ggdG8gZmluZCB0aGUgq3NlbGVjdGVkLmFnZW50LmxhYmVsuyB3aXRoIHRoZSCrZnVuY3Rpb24uaWQoKbtkIKtpbnB1dHMudmFsdWUuZ2V0KDApLmxhYmVsuyB2YWx1ZS4KICAgICAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgogICAgICogQGdlbmVyYXRlZAogICAgICovCiAgICBwdWJsaWMgZmluYWwgc3RhdGljIERhdGFQb2ludCCrZGF0YVBvaW50KCm7ID0gbmV3IERhdGFQb2ludENvbmNyZXRlKCKrZnVuY3Rpb24uaWQoKS50b0ZpcnN0VXBwZXIoKbsgq2lucHV0cy52YWx1ZS5nZXQoMCkuaWQoKbsiKSB7CgkJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzc1NTgxMDQ0MzMzNTczOTAxMkw7CgkJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7CiAgICAgICAgcHVibGljIGRvdWJsZSBnZXRWYWx1ZShPYmplY3QgbykgewogICAgICAgICAgICCrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OklubmVyRXZhbHVhdGlvbihhbGxTb3VyY2VzLnNlbGVjdChlfGUuc2VsZWN0ZWQgPT0gdGhpcy5zZWxlY3RlZCksIGZhbHNlKS27CiAgICAgICAgICAgIHJldHVybiAoKKtzZWxlY3RlZC5hZ2VudC50eXBlTmFtZSgpuykgbykuq2lucHV0cy52YWx1ZS5nZXQoMCkuZ2V0dGVyTmFtZSgpuygpOwogICAgICAgIH0KICAgIH07CgmrRUxTRS27CgkJq3RhcmdldERlZi5wcm9jZWVkKCktuwoJq0VORElGLbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6QWN0aW9uQm9keSBGT1IgRkZ1bmN0aW9uLbsKCatJRiBpZCgpID09ICJ3aXRoaW5Cb3VuZGFyaWVzIi27CiAgICAgICAgQ29vcmRpbmF0ZTJERGlzY3JldGUgY29vciA9IChDb29yZGluYXRlMkREaXNjcmV0ZSkgZ2V0Q29vcmRpbmF0ZSgpOwogICAgICAgIHJldHVybiAoY29vci5nZXRZVmFsdWUoKSA+PSBib3VuZHNbMF0KICAgICAgICAgICAgICAgICYmIGNvb3IuZ2V0WFZhbHVlKCkgPj0gYm91bmRzWzFdCiAgICAgICAgICAgICAgICAmJiBjb29yLmdldFlWYWx1ZSgpIDw9IGJvdW5kc1syXQogICAgICAgICAgICAgICAgJiYgY29vci5nZXRYVmFsdWUoKSA8PSBib3VuZHNbM10pOwogICAgq0VMU0Utu6t0YXJnZXREZWYucHJvY2VlZCgpu6tFTkRJRi27CqtFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkNvbmRpdGlvbkJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFBY3QtuwoJq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpDb25kaXRpb25hbChwYXRoLCBpbm5lciktuwqrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpCZWdpblF1ZXJ5QmxvY2sgKExpc3RbbWV0YWFibTo6YWN0OjpBQWN0XSBwYXRoLCBCb29sZWFuIGlubmVyKSBGT1IgQUFjdC27CgmrRVhQQU5EIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6U2NhcGVBc3BlY3Q6OkJlZ2luUXVlcnkocGF0aCwgaW5uZXIpLbsKq0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpFbmRRdWVyeUJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFBY3QtuwoJq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpFbmRRdWVyeShwYXRoLCBpbm5lciktuwqrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpCZWdpblNlcmlhbEJsb2NrKExpc3RbQUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFDb250cm9sLbsKCatFWFBBTkQgbWV0YWFibTo6YXNjYXBlOjp0bXBsOjpTY2FwZUFzcGVjdDo6QmVnaW5TZXJpYWwocGF0aCwgaW5uZXIpLbsKICAgIKt0YXJnZXREZWYucHJvY2VlZCgpLbsKq0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpFbmRTZXJpYWxCbG9jayhMaXN0W0FBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBQ29udHJvbC27CgmrRVhQQU5EIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6U2NhcGVBc3BlY3Q6OkVuZFNlcmlhbChwYXRoLCBpbm5lciktuwogICAgq3RhcmdldERlZi5wcm9jZWVkKCktuwqrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbm5lckJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFNb3ZlLbsKCatFWFBBTkQgbWV0YWFibTo6YXNjYXBlOjp0bXBsOjpTY2FwZUFzcGVjdDo6SW5uZXJCbG9ja0NhbGwocGF0aCwgaW5uZXIpLburRU5EQVJPVU5EuwqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OklubmVyQmxvY2sgKExpc3RbbWV0YWFibTo6YWN0OjpBQWN0XSBwYXRoLCBCb29sZWFuIGlubmVyKSBGT1IgQUNyZWF0ZUFnZW50cy27CgmrY2FsbChwYXRoLCBpbm5lcim7q0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbm5lckJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFEaWUtuwoJq2NhbGwocGF0aCwgaW5uZXIpu6tFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6SW5uZXJCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBTGVhdmUtuwoJq2NhbGwocGF0aCwgaW5uZXIpu6tFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OklubmVyQmxvY2sgKExpc3RbbWV0YWFibTo6YWN0OjpBQWN0XSBwYXRoLCBCb29sZWFuIGlubmVyKSBGT1IgQVJlcGxhY2UtuwoJq2NhbGwocGF0aCwgaW5uZXIpu6tFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6SW5uZXJCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBQ29ubmVjdC27CgmrY2FsbChwYXRoLCBpbm5lcim7q0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbm5lckJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFEaXNjb25uZWN0uwoJq2NhbGwocGF0aCwgaW5uZXIpu6tFTkRBUk9VTkS7Cg==