q0lNUE9SVCBlbWa7CqtJTVBPUlQgbWV0YWFibbsKq0lNUE9SVCBtZXRhYWJtOjphY3S7CqtJTVBPUlQgbWV0YWFibTo6ZnVuY3Rpb267CgqrRVhURU5TSU9OIG1ldGFhYm06OnRtcGw6OnR5cGVzuwqrRVhURU5TSU9OIG1ldGFhYm06OnRtcGw6Om5hbWVzuyAKq0VYVEVOU0lPTiBtZXRhYWJtOjp0bXBsOjppbmZlcrsKq0VYVEVOU0lPTiBtZXRhYWJtOjp0bXBsOjp1dGlsuwqrRVhURU5TSU9OIG1ldGFhYm06OnRtcGw6OnByb2plY3Rpb25zuwqrRVhURU5TSU9OIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6bmFtZXNhc2NhcGW7CqtFWFRFTlNJT04gbWV0YWFibTo6YXNjYXBlOjp0bXBsOjppbmZlcmFzY2FwZbsKq0VYVEVOU0lPTiBtZXRhYWJtOjplc2NhcGU6OnRtcGw6OmluZmVyZXNjYXBluwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbXBvcnRzIEZPUiBTU3R5bGUtuwppbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5DZWxsT2NjdXBhbnQ7CmltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLkhvc3RDZWxsOwppbXBvcnQgb3JnLmFzY2FwZS51dGlsLnZpcy5Db2xvckZlYXR1cmVDb25jcmV0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmRyYXcyZC5Db2xvckNvbnN0YW50czsKaW1wb3J0IG9yZy5lY2xpcHNlLmRyYXcyZC5JRmlndXJlOwppbXBvcnQgb3JnLmVjbGlwc2UuZHJhdzJkLlNoYXBlOwppbXBvcnQgb3JnLmVjbGlwc2UuZHJhdzJkLmdlb21ldHJ5LkRpbWVuc2lvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5Db2xvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmFtcC5hZ2YuZ2VmLkFnZW50RWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5hbXAuZXNjYXBlLmFzY2FwZS5nZWYuSG9zdENlbGxFZGl0UGFydDsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6SW1wb3J0cyBGT1IgU0FnZW50LbsKCWltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwoJaW1wb3J0IGphdmEudXRpbC5MaXN0OwoJaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKCQoJaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JQWRhcHRlckZhY3Rvcnk7CglpbXBvcnQgb3JnLmVjbGlwc2UuYW1wLmFnZi5JR3JhcGhpY3NBZGFwdGVkOwoJaW1wb3J0IG9yZy5lY2xpcHNlLmFtcC5hZ2YuSUdyYXBoaWNzQWRhcHRlcjsKCQoJaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5Db2xvcjsKCWltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLklDb2xvclByb3ZpZGVyOwoJCglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5BZ2VudDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLkNlbGw7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5DZWxsT2NjdXBhbnQ7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5Ib3N0Q2VsbDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLkxvY2F0ZWRBZ2VudDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLlNjYXBlOwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuZXZlbnQuU2NhcGVFdmVudDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLnJ1bGUuUnVsZTsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLnJ1bGUuRXhlY3V0ZVRoZW5VcGRhdGU7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5zcGFjZS5Db2xsZWN0aW9uU3BhY2U7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5zcGFjZS5Db29yZGluYXRlOwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuc3BhY2UuQ29vcmRpbmF0ZTJERGlzY3JldGU7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5zcGFjZS5HcmFwaDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLnNwYWNlLkxvY2F0aW9uOwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuc3BhY2UuU2luZ2xldG9uOwoJaW1wb3J0IG9yZy5hc2NhcGUucnVudGltZS5Ob25HcmFwaGljUnVubmVyOwoJaW1wb3J0IG9yZy5hc2NhcGUudXRpbC5Db25kaXRpb25hbDsKCWltcG9ydCBvcmcuYXNjYXBlLnV0aWwuZGF0YS5EYXRhUG9pbnQ7IAoJaW1wb3J0IG9yZy5hc2NhcGUudXRpbC5kYXRhLkRhdGFQb2ludENvbmNyZXRlOwoJaW1wb3J0IG9yZy5hc2NhcGUudXRpbC52aXMuQ29sb3JGZWF0dXJlOwoJaW1wb3J0IG9yZy5hc2NhcGUudXRpbC52aXMuQ29sb3JGZWF0dXJlQ29uY3JldGU7CglpbXBvcnQgb3JnLmFzY2FwZS52aWV3LnZpcy5DaGFydFZpZXc7CglpbXBvcnQgb3JnLmFzY2FwZS52aWV3LnZpcy5HRUZWaWV3OwoJaW1wb3J0IG9yZy5hc2NhcGUudmlldy52aXMuR3JhcGhWaWV3OwoJCgmrdGFyZ2V0RGVmLnByb2NlZWQoKbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6RXh0ZW5kVHlwZSBGT1IgU1Byb2plY3Rpb24tu1NjYXBlq0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpFeHRlbmRUeXBlIEZPUiBTQ29udGV4dC27q3R5cGVOYW1lKCktu6tFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6RXh0ZW5kVHlwZSBGT1IgU0FnZW50LbtTY2FwZatFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkNsYXNzSW5oZWlyaXRhbmNlIEZPUiBTQ29udGV4dC27IGV4dGVuZHMgU2NhcGUgaW1wbGVtZW50cyBJR3JhcGhpY3NBZGFwdGVkq0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpDbGFzc0luaGVpcml0YW5jZSBGT1IgU0FnZW50LbsgZXh0ZW5kcyCrZXh0ZW5kVHlwZSgpu6tFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6Q2xhc3NJbmhlaXJpdGFuY2UgRk9SIFNTdHlsZS27IGltcGxlbWVudHMgqyhhZ2VudC5pc0hvc3QoKSA/ICJIb3N0Q2VsbCIgOiAiQWdlbnQiKbtFZGl0UGFydKtFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkZpbGVzIEZPUiBTQWdlbnQtuwoJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpDbGFzc0ZpbGUtuwogICAgq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpDbGFzc0ZpbGUgRk9SRUFDSCBhdHRyaWJ1dGVzLnR5cGVTZWxlY3QoU1N0YXRlKS27CqtFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkJvZHkgRk9SIFNBZ2VudC27CgmrdGFyZ2V0RGVmLnByb2NlZWQoKS27CgmrRVhQQU5EIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6U2NhcGVBc3BlY3Q6OkFnZW50Qm9keS27CgmrRVhQQU5EIFN0YXJ0U2ltdWxhdGlvbkFnZW50Q2hpbGS7CgmrRVhQQU5EIENhbGN1bGF0ZVRpbWVTdGVwuwqrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpCb2R5IEZPUiBTQ29udGV4dC27CgogICAgq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpTY2FwZUJvZHktuwogICAgCiAgICCrRVhQQU5EIENyZWF0ZUdyYXBoaWNzTWV0aG9kcy27CgoJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7CglwdWJsaWMgSUdyYXBoaWNzQWRhcHRlciBnZXRHcmFwaGljc0FkYXB0ZXIoKSB7CiAgICAgICAgcmV0dXJuIKt0eXBlTmFtZSgpu0dyYXBoaWNzQWRhcHRlci5nZXREZWZhdWx0KCk7Cgl9CgmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKICAgIHByaXZhdGUgQ29sb3IgZ2V0SW5mZXJyZWRDaGFydENvbG9yKE9iamVjdCBhZ2VudCwKICAgICAgICBJQ29sb3JQcm92aWRlciBjb2xvclByb3ZpZGVyKSB7CiAgICAgICAgQ29sb3IgY29sb3IgPSBjb2xvclByb3ZpZGVyLmdldEZvcmVncm91bmQoYWdlbnQpOwoJCWlmIChjb2xvciA9PSBDb2xvckZlYXR1cmUuQkxBQ0spIHsKCQkJY29sb3IgPSBDb2xvckZlYXR1cmVDb25jcmV0ZQoJCQkJCS5jcmVhdGVIU0IoKGZsb2F0KSBqYXZhLmxhbmcuTWF0aC5yYW5kb20oKSAqIDM2MGYsIDEuMGYsCgkJCQkJCQkwLjhmKTsKCQl9CiAgICAgICAgcmV0dXJuIGNvbG9yOwogICAgfQogICAgq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7CiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgKG5ldyBOb25HcmFwaGljUnVubmVyKCkpLm9wZW5JbnN0YW5jZSgiq2ltcGxlbWVudGF0aW9uLnF1YWxpZmllZE5hbWW7Iik7CiAgICB9CgogICAgq0VYUEFORCBFeGVjSUFnZW50Q2hpbGS7CiAgICAKq0VOREFST1VORLsKCqtERUZJTkUgRXhlY0lBZ2VudENoaWxkIEZPUiBTQ29udGV4dLsKCatFWFBBTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6TWV0aG9kQ29tbWVudLsKCUBPdmVycmlkZQoJcHVibGljIHZvaWQgZXhlY3V0ZU9uTWVtYmVycygpewoJCWludCB0aW1lU3RlcCA9IGdldFJ1bm5lcigpLmdldFBlcmlvZCgpOwoJCXN0YXJ0U2ltdWxhdGlvbkFnZW50Q2hpbGQodGltZVN0ZXApOwoJCatGT1JFQUNIIGFnZW50cyBBUyBhZ2VudLsKCQkJq0lGICFhZ2VudC5pc0hvc3QoKbsKCQkJCS8vQSBub3JtYWwgbW92YWJsZSBhZ2VudAoJCQkJKCirYWdlbnQuaW1wbGVtZW50YXRpb24uY2xhc3NOYW1luymrYWdlbnQuc2NhcGUoKbsuZ2V0UHJvdG90eXBlQWdlbnQoKSkuc3RhcnRTaW11bGF0aW9uQWdlbnRDaGlsZCh0aW1lU3RlcCk7CgkJCatFTFNFuwoJCQkJLy90aGlzIGlzIGFuIGFnZW50IHRoYXQgcmVwcmVzZW50IGEgY2VsbCBhbmQgY2Fubm90IG1vdmUuCgkJCQmrRVhQQU5EIEhvc3RBZ2VudFN0YXJ0KGFnZW50LmltcGxlbWVudGF0aW9uLmNsYXNzTmFtZSkgRk9SIHJvb3RBY3Rpdml0ebsKCQkJq0VORElGuwoJCatFTkRGT1JFQUNIuwoJCXN1cGVyLmV4ZWN1dGVPbk1lbWJlcnMoKTsKCQljYWxjdWxhdGVUaW1lU3RlcCh0aW1lU3RlcCk7CgkJq0ZPUkVBQ0ggYWdlbnRzIEFTIGFnZW50uwoJCQmrSUYgIWFnZW50LmlzSG9zdCgpuwoJCQkJLy9BIG5vcm1hbCBtb3ZhYmxlIGFnZW50CgkJCQkoKKthZ2VudC5pbXBsZW1lbnRhdGlvbi5jbGFzc05hbWW7KathZ2VudC5zY2FwZSgpuy5nZXRQcm90b3R5cGVBZ2VudCgpKS5jYWxjdWxhdGVUaW1lU3RlcCh0aW1lU3RlcCk7CgkJCatFTFNFuwoJCQkJLy90aGlzIGlzIGFuIGFnZW50IHRoYXQgcmVwcmVzZW50IGEgY2VsbCBhbmQgY2Fubm90IG1vdmUuCgkJCQmrRVhQQU5EIEhvc3RBZ2VudENhbGMoYWdlbnQuaW1wbGVtZW50YXRpb24uY2xhc3NOYW1lKSBGT1Igcm9vdEFjdGl2aXR5uwoJCQmrRU5ESUa7CgkJq0VOREZPUkVBQ0i7Cgl9CqtFTkRERUZJTkW7CgqrUkVNuyBTVEFSVDsgY2hlY2sgaXMgaG9zdENlbGwgYW5kIHNldCB0aGUgc3RhcnQgdGltZSBvbiB0aGUgSUFnZW50Q2hpbGQgKHRyYXZlcnNlIHRoZSB0aHJlZSB0byB0aGUgQUJ1aWxkR3JpZCmrRU5EUkVNuwqrREVGSU5FIEhvc3RBZ2VudFN0YXJ0KFN0cmluZyB0eXBlTmFtZSkgRk9SIElBY3S7CqtFTkRERUZJTkW7CgqrREVGSU5FIEhvc3RBZ2VudFN0YXJ0KFN0cmluZyB0eXBlTmFtZSkgRk9SIEFHcm91cLsKCatFWFBBTkQgSG9zdEFnZW50U3RhcnQodHlwZU5hbWUpIEZPUkVBQ0ggcm9vdHO7CqtFTkRERUZJTkW7CgqrREVGSU5FIEhvc3RBZ2VudFN0YXJ0KFN0cmluZyB0eXBlTmFtZSkgRk9SIEFCdWlsZLsKCatFWFBBTkQgSG9zdEFnZW50U3RhcnQodHlwZU5hbWUpIEZPUkVBQ0ggdGFyZ2V0c7sKq0VORERFRklORbsKCqtERUZJTkUgSG9zdEFnZW50U3RhcnQoU3RyaW5nIHR5cGVOYW1lKSBGT1IgQUJ1aWxkR3JpZLsKCSgoq3R5cGVOYW1luykgq3RoaXMucHJvamVjdGlvbi5maWVsZE5hbWUoKbsuZ2V0UHJvdG90eXBlQWdlbnQoKSkuc3RhcnRTaW11bGF0aW9uQWdlbnRDaGlsZCh0aW1lU3RlcCk7CqtFTkRERUZJTkW7CqtSRU27RU5EIHNldCBzdGFydCB0aW1lIKtFTkRSRU27CgqrUkVNuyBTVEFSVDsgY2hlY2sgaXMgaG9zdENlbGwgYW5kIHN0YXJ0IHRoZSBjYWxjdWxhdGlvbiBvbiB0aGUgSUFnZW50Q2hpbGQgKHRyYXZlcnNlIHRoZSB0aHJlZSB0byB0aGUgQUJ1aWxkR3JpZCmrRU5EUkVNuwqrREVGSU5FIEhvc3RBZ2VudENhbGMoU3RyaW5nIHR5cGVOYW1lKSBGT1IgSUFjdLsKq0VORERFRklORbsKCqtERUZJTkUgSG9zdEFnZW50Q2FsYyhTdHJpbmcgdHlwZU5hbWUpIEZPUiBBR3JvdXC7CgmrRVhQQU5EIEhvc3RBZ2VudENhbGModHlwZU5hbWUpIEZPUkVBQ0ggcm9vdHO7CqtFTkRERUZJTkW7CgqrREVGSU5FIEhvc3RBZ2VudENhbGMoU3RyaW5nIHR5cGVOYW1lKSBGT1IgQUJ1aWxkuwoJq0VYUEFORCBIb3N0QWdlbnRDYWxjKHR5cGVOYW1lKSBGT1JFQUNIIHRhcmdldHO7CqtFTkRERUZJTkW7CgqrREVGSU5FIEhvc3RBZ2VudENhbGMoU3RyaW5nIHR5cGVOYW1lKSBGT1IgQUJ1aWxkR3JpZLsKCSgoq3R5cGVOYW1luykgq3RoaXMucHJvamVjdGlvbi5maWVsZE5hbWUoKbsuZ2V0UHJvdG90eXBlQWdlbnQoKSkuY2FsY3VsYXRlVGltZVN0ZXAodGltZVN0ZXApOwqrRU5EREVGSU5FuwqrUkVNu0VORCBjYWxjdWxhdGUgq0VORFJFTbsKCgqrREVGSU5FIFN0YXJ0U2ltdWxhdGlvbkFnZW50Q2hpbGQgRk9SIFNBZ2VudLsKCatFWFBBTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6TWV0aG9kQ29tbWVudLsKCXB1YmxpYyB2b2lkIHN0YXJ0U2ltdWxhdGlvbkFnZW50Q2hpbGQoaW50IHRpbWVTdGVwKXsKCQlpZih0aW1lU3RlcCA9PSBnZXRSb290KCkuZ2V0UnVubmVyKCkuZ2V0RWFybGllc3RQZXJpb2QoKSl7CgkJCWZvcihJQWdlbnRDaGlsZCB0bXA6Y2hpbGRyZW4pewoJCQkJdG1wLnN0YXJ0U2ltdWxhdGlvbih0aW1lU3RlcCk7CgkJCX0KCQl9CQoJfQqrRU5EREVGSU5FuwoKq0RFRklORSBDYWxjdWxhdGVUaW1lU3RlcCBGT1IgU0FnZW50uwoJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpNZXRob2RDb21tZW50uwoJcHVibGljIHZvaWQgY2FsY3VsYXRlVGltZVN0ZXAoaW50IHRpbWVTdGVwKXsKCQlmb3IoSUFnZW50Q2hpbGQgdG1wOmNoaWxkcmVuKXsKCQkJdG1wLmNhbGN1bGF0ZSh0aW1lU3RlcCk7CgkJfQoJfQqrRU5EREVGSU5FuwoKq0RFRklORSBDcmVhdGVHcmFwaGljc01ldGhvZHMgRk9SIFNDb250ZXh0uwogICAgq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7Cglwcm90ZWN0ZWQgdm9pZCBjcmVhdGVDaGFydFZpZXdzKCkgewoJCUNoYXJ0VmlldyBjaGFydCA9IG5ldyBDaGFydFZpZXcoKTsKCQmrRVhQQU5EIEJ1aWxkQ2hhcnRTZWxlY3Rpb24gRk9SRUFDSCBhZ2VudHMtuwoJICAgIGFkZFZpZXcoY2hhcnQpOwoJfQoKICAgIKtFWFBBTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6R2VuZXJhdGVDb21tZW50uwoJcHJvdGVjdGVkIHZvaWQgY3JlYXRlMkRWaWV3cygpIHsKCQlhZGRWaWV3KG5ldyBHRUZWaWV3KCkpOwoJfQoKICAgIKtFWFBBTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6R2VuZXJhdGVDb21tZW50uwoJcHJvdGVjdGVkIHZvaWQgY3JlYXRlR3JhcGhWaWV3cygpIHsKICAgIAmrRk9SRUFDSCBhY3RzKCkudHlwZVNlbGVjdChBQnVpbGROZXR3b3JrKSBBUyBncmFwaEJ1aWxkZXItuwoJCQmrZ3JhcGhCdWlsZGVyLnByb2plY3Rpb24uZmllbGROYW1lKCm7LmFkZFZpZXcobmV3IEdyYXBoVmlldygpKTsKICAgIAmrRU5ERk9SRUFDSC27IAogICAgfQqrRU5EREVGSU5FuwoKq0FST1VORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpWaWV3QnVpbGRlciBGT1IgQUdyb3VwLbsKCatJRiByZWZlcmVuY2UucGFyZW50ID09IG51bGwtuwoJY3JlYXRlQ2hhcnRWaWV3cygpOwogICAgq0VORElGLbsKICAgIKtJRiByZWZlcmVuY2UubWV0YVR5cGUgPT0gU0NvbnRleHQgJiYgISgoU0NvbnRleHQpIHJlZmVyZW5jZSkucHJvamVjdGlvbnMudHlwZVNlbGVjdChTTkRpbWVuc2lvbmFsKS5pc0VtcHR5LbsKCWNyZWF0ZTJEVmlld3MoKTsKCatFTkRJRi27CiAgICCrSUYgcmVmZXJlbmNlLm1ldGFUeXBlID09IFNDb250ZXh0ICYmICEoKFNDb250ZXh0KSByZWZlcmVuY2UpLnByb2plY3Rpb25zLnR5cGVTZWxlY3QoU05ldHdvcmspLmlzRW1wdHm7CgljcmVhdGVHcmFwaFZpZXdzKCk7CgmrRU5ESUYtuwogICAgq3RhcmdldERlZi5wcm9jZWVkKCktuwqrRU5EQVJPVU5EuwoKq0RFRklORSBCdWlsZENoYXJ0U2VsZWN0aW9uIEZPUiBTQWdlbnS7CiAgICCrSUYgIXN0eWxlcy5pc0VtcHR5LbsKICAgIGZpbmFsIKtvd25lci50eXBlTmFtZSgpuyCraWQoKbtTY2FwZSA9IG5ldyCrb3duZXIudHlwZU5hbWUoKbsoKTsKICAgIKtpZCgpu1NjYXBlLnNldFJ1bm5lcihuZXcgTm9uR3JhcGhpY1J1bm5lcigpKTsKCat0eXBlTmFtZSgpuyCraWQoKbsgPSBuZXcgq3R5cGVOYW1lKCm7KCkgewoJCQmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKICAgICAgICAgICAgcHVibGljIHZvaWQgcmVxdWVzdFVwZGF0ZSgpIHsKICAgICAgICAgICAgfQogICAgICAgICAgICCrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKICAgICAgICAgICAgcHVibGljIKtvd25lci50eXBlTmFtZSgpuyBnZXSrb3duZXIudHlwZU5hbWUoKbsoKSB7CiAgICAgICAgICAgIAlyZXR1cm4gq2lkKCm7U2NhcGU7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgq2lkKCm7U2NhcGUuYWRkKKtpZCgpuyk7CgmrSUYgIWlzSG9zdCgpICYmIGlzRGlzY3JldGUoKS27CglIb3N0Q2VsbCCraWQoKbtIb3N0ID0gbmV3IEhvc3RDZWxsKCkgewoJCQmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKICAgICAgICAgICAgcHVibGljIHZvaWQgcmVxdWVzdFVwZGF0ZSgpIHsKICAgICAgICAgICAgfQogICAgICAgIH07CgmraWQoKbtIb3N0LnNldE9jY3VwYW50KChDZWxsT2NjdXBhbnQpIKtpZCgpuyk7CgmrRU5ESUYtuwogICAgq0ZPUkVBQ0ggc3R5bGVzIEFTIHN0eWxluwogICAgSUNvbG9yUHJvdmlkZXIgq3N0eWxlLmlkKCm7Q29sb3JQcm92aWRlciA9IG5ldyCrc3R5bGVzLmdldCgwKS50eXBlTmFtZSgpu0NvbG9yUHJvdmlkZXIoKTsKCatGT1JFQUNIIHN0eWxlLnNldHRlclNwYWNlKCkgQVMgc2V0dGVyuwogICAgqygoTGlzdCkgc2V0dGVyKS5sYXN0KCm7OwoJY2hhcnQuYWRkU2VyaWVzKCJDb3VudCCrdHlwZU5hbWUoKbsgqygoTGlzdCkgc2V0dGVyKS5maXJzdCgpuyIsIGdldEluZmVycmVkQ2hhcnRDb2xvciiraWQoKbssIKtzdHlsZS5pZCgpu0NvbG9yUHJvdmlkZXIpKTsKICAgIKtFTkRGT1JFQUNILbsKICAgIKtFTkRGT1JFQUNILbsKICAgIKtFTkRJRi27CqtFTkRERUZJTkW7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkZ1bmN0aW9uSW5uZXJCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBU2luay27CiAgICCrSUYgZnVuY3Rpb24uaWQoKSA9PSAicmFuZG9tVW5pdCItuwogICAgICAgIGdldFJhbmRvbSgpLm5leHREb3VibGUoKQogICAgq0VMU0VJRiBmdW5jdGlvbi5pZCgpID09ICJyYW5kb21JcyItuwogICAgICAgIGdldFJhbmRvbSgpLm5leHRCb29sZWFuKCkKICAgIKtFTFNFSUYgZnVuY3Rpb24uaWQoKSA9PSAidW5pZm9ybURpc3RyaWJ1dGlvbiItuwogICAgICAgIHJhbmRvbUluUmFuZ2Uoq2lucHV0cy5leHByZXNzaW9uKHBhdGgsIGlubmVyKS50b1N0cmluZygiLCAiKbspOwogICAgq0VMU0VJRiBmdW5jdGlvbi5pZCgpID09ICJ0aW1lTm93Ii27CgkJq3BhdGgubGFzdCgpLmFjY2Vzc1BhdGgodGhpcywgaW5uZXIpu6tyZWZlcmVuY2Uub3duZXIucGFyZW50ICE9IG51bGwgPyAiZ2V0U2NhcGUoKS4iIDogIiK7Z2V0UGVyaW9kKCkKICAgIKtFTFNFSUYgZnVuY3Rpb24uaWQoKSA9PSAiYXZhaWxhYmxlIi27CiAgICAgICAgaXNBdmFpbGFibGUoKQogICAgq0VMU0VJRiBmdW5jdGlvbi5pZCgpID09ICJ3aXRoaW5Cb3VuZGFyaWVzIi27CiAgICAgICAgq2V4cHJlc3Npb25TaW5rKHBhdGgsIGZ1bmN0aW9uLCBpbm5lcim7CiAgICCrRUxTRUlGIGZ1bmN0aW9uLmlkKCkgPT0gImNvbG9yUkdCIi27CiAgICAgICAgQ29sb3JGZWF0dXJlQ29uY3JldGUuY3JlYXRlKChpbnQpICiraW5wdXRzLmV4cHJlc3Npb24ocGF0aCwgaW5uZXIpLnRvU3RyaW5nKCIgKiAyNTUpLCAoaW50KSAoIim7ICogMjU1KSkKICAgIKtFTFNFSUYgZnVuY3Rpb24uaWQoKS5zdGFydHNXaXRoKCJjb2xvciIpLbsKICAgICAgICBDb2xvckNvbnN0YW50cy6rZnVuY3Rpb24uaWQoKS5yZXBsYWNlRmlyc3QoImNvbG9yIiwiIikudG9GaXJzdExvd2VyKCm7CgmrRUxTRS27CgkJq3RhcmdldERlZi5wcm9jZWVkKCktuwoJq0VORElGLbsKq0VOREFST1VORLsKCqtERUZJTkUgU3R5bGVQcm92aWRlciBGT1IgU0FnZW50uwogICAgq0lGIHN0eWxlcy5zaXplID4gMC27CgkgICAgICAgIGlmIChtb2RlbCBpbnN0YW5jZW9mIKtpbXBsZW1lbnRhdGlvbi5jbGFzc05hbWW7KSB7CgkgICAgICAgICAgICByZXR1cm4gbmV3IKtzdHlsZXMuZ2V0KDApLmltcGxlbWVudGF0aW9uLnF1YWxpZmllZE5hbWW7KCk7CgkgICAgICAgIH0KICAgIKtFTkRJRi27CqtFTkRERUZJTkW7CqtERUZJTkUgUmVjdXJzZUFnZW50UHJvdmlkZXJzIEZPUiBTQWdlbnS7CgmrRVhQQU5EIFN0eWxlUHJvdmlkZXK7CqtFTkRERUZJTkW7CqtERUZJTkUgUmVjdXJzZUFnZW50UHJvdmlkZXJzIEZPUiBTQ29udGV4dLsKCatFWFBBTkQgU3R5bGVQcm92aWRlcrsKCatFWFBBTkQgUmVjdXJzZUFnZW50UHJvdmlkZXJzIEZPUkVBQ0ggYWdlbnRzuwqrRU5EREVGSU5FuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpFeHRlbmRUeXBlIEZPUiBBU2luay27CgmrSUYgZnVuY3Rpb24uY29sb3IoKS27Q29sb3IKCatFTFNFSUYgZnVuY3Rpb24uc2hhcGUoKS27U2hhcGUKCatFTFNFSUYgZnVuY3Rpb24uaWQoKS5zdGFydHNXaXRoKCJncmFwaGljIiktu1NoYXBlCgmrRUxTRUlGIGZ1bmN0aW9uLmlkKCkgPT0gInJhbmRvbVN0YXRlIi27q2lucHV0cy5nZXQoMCkudmFsdWUudHlwZU5hbWUoKbsKCatFTFNFLburdHlwZU5hbWUoKburRU5ESUYtuwqrRU5EQVJPVU5EuwoKq0RFRklORSBTdHlsZVNlbGVjdG9yIChTUHJvamVjdGlvbiBwcm9qZWN0aW9uKSBGT1IgU1Byb2plY3Rpb24tuwqrRU5EREVGSU5FuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpPdGhlckFjY2Vzc29ycyBGT1IgU0FnZW50LbsKCat0YXJnZXREZWYucHJvY2VlZCgpLbsKICAgIKtFWFBBTkQgbWV0YWFibTo6YXNjYXBlOjp0bXBsOjpTY2FwZUFzcGVjdDo6TmFtZUFjY2Vzc29yLbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6QnVpbGRlciBGT1IgU0FnZW50LbsKCatJRiAocm9vdEFjdGl2aXR5ICE9IG51bGwpLbsKCQmrRVhQQU5EIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6U2NhcGVBc3BlY3Q6OkNoaWxkQnVpbGRlciBGT1Igcm9vdEFjdGl2aXR5LbsKCatFTkRJRi27CqtFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6Ok1ldGhvZFBvdGVudGlhbCAobWV0YWFibTo6YWN0OjpBQWN0IHdpdGhpbikgRk9SIEZGdW5jdGlvbi27CgmrSUYgKGlkKCkgPT0gIndpdGhpbkJvdW5kYXJpZXMiKSB8fCAoaWQoKSA9PSAiZGlzdGFuY2UiKS27CgkJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpNZXRob2QtuwoJq0VMU0UtuwoJCat0YXJnZXREZWYucHJvY2VlZCgpLbsKCatFTkRJRi27CqtFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6Ok1ldGhvZFBvdGVudGlhbCAobWV0YWFibTo6YWN0OjpBQWN0IHdpdGhpbikgRk9SIEFRdWVyeS27CgmrSUYgKGZ1bmN0aW9uLmlkKCkgPT0gIm1pbmltaXplIikgfHwgKGZ1bmN0aW9uLmlkKCkgPT0gIm1heGltaXplIiktuwogICAgLyoqCiAgICAgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgogICAgICogQSBkYXRhIHBvaW50IHVzZWQgd2l0aGluIGEgc2VhcmNoIHRvIGZpbmQgdGhlIKtzZWxlY3RlZC5hZ2VudC5sYWJlbLsgd2l0aCB0aGUgq2Z1bmN0aW9uLmlkKCm7ZCCraW5wdXRzLnZhbHVlLmdldCgwKS5sYWJlbLsgdmFsdWUuCiAgICAgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KICAgICAqIEBnZW5lcmF0ZWQKICAgICAqLwogICAgcHVibGljIGZpbmFsIHN0YXRpYyBEYXRhUG9pbnQgq2RhdGFQb2ludCgpuyA9IG5ldyBEYXRhUG9pbnRDb25jcmV0ZSgiq2Z1bmN0aW9uLmlkKCkudG9GaXJzdFVwcGVyKCm7IKtpbnB1dHMudmFsdWUuZ2V0KDApLmlkKCm7IikgewoJCatFWFBBTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6R2VuZXJhdGVDb21tZW50uwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDM3NTU4MTA0NDMzMzU3MzkwMTJMOwoJCatFWFBBTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6R2VuZXJhdGVDb21tZW50uwogICAgICAgIHB1YmxpYyBkb3VibGUgZ2V0VmFsdWUoT2JqZWN0IG8pIHsKICAgICAgICAgICAgq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbm5lckV2YWx1YXRpb24oYWxsU291cmNlcy5zZWxlY3QoZXxlLnNlbGVjdGVkID09IHRoaXMuc2VsZWN0ZWQpLCBmYWxzZSktuwogICAgICAgICAgICByZXR1cm4gKCirc2VsZWN0ZWQuYWdlbnQudHlwZU5hbWUoKbspIG8pLqtpbnB1dHMudmFsdWUuZ2V0KDApLmdldHRlck5hbWUoKbsoKTsKICAgICAgICB9CiAgICB9OwoJq0VMU0UtuwoJCat0YXJnZXREZWYucHJvY2VlZCgpLbsKCatFTkRJRi27CqtFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkFjdGlvbkJvZHkgRk9SIEZGdW5jdGlvbi27CgmrSUYgaWQoKSA9PSAid2l0aGluQm91bmRhcmllcyItuwogICAgICAgIENvb3JkaW5hdGUyRERpc2NyZXRlIGNvb3IgPSAoQ29vcmRpbmF0ZTJERGlzY3JldGUpIGdldENvb3JkaW5hdGUoKTsKICAgICAgICByZXR1cm4gKGNvb3IuZ2V0WVZhbHVlKCkgPj0gYm91bmRzWzBdCiAgICAgICAgICAgICAgICAmJiBjb29yLmdldFhWYWx1ZSgpID49IGJvdW5kc1sxXQogICAgICAgICAgICAgICAgJiYgY29vci5nZXRZVmFsdWUoKSA8PSBib3VuZHNbMl0KICAgICAgICAgICAgICAgICYmIGNvb3IuZ2V0WFZhbHVlKCkgPD0gYm91bmRzWzNdKTsKICAgIKtFTFNFLburdGFyZ2V0RGVmLnByb2NlZWQoKburRU5ESUYtuwqrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpDb25kaXRpb25CbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBQWN0LbsKCatFWFBBTkQgbWV0YWFibTo6YXNjYXBlOjp0bXBsOjpTY2FwZUFzcGVjdDo6Q29uZGl0aW9uYWwocGF0aCwgaW5uZXIpLbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6QmVnaW5RdWVyeUJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFBY3QtuwoJq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpCZWdpblF1ZXJ5KHBhdGgsIGlubmVyKS27CqtFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6RW5kUXVlcnlCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBQWN0LbsKCatFWFBBTkQgbWV0YWFibTo6YXNjYXBlOjp0bXBsOjpTY2FwZUFzcGVjdDo6RW5kUXVlcnkocGF0aCwgaW5uZXIpLbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6QmVnaW5TZXJpYWxCbG9jayhMaXN0W0FBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBQ29udHJvbC27CgmrRVhQQU5EIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6U2NhcGVBc3BlY3Q6OkJlZ2luU2VyaWFsKHBhdGgsIGlubmVyKS27CiAgICCrdGFyZ2V0RGVmLnByb2NlZWQoKS27CqtFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6RW5kU2VyaWFsQmxvY2soTGlzdFtBQWN0XSBwYXRoLCBCb29sZWFuIGlubmVyKSBGT1IgQUNvbnRyb2wtuwoJq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpFbmRTZXJpYWwocGF0aCwgaW5uZXIpLbsKICAgIKt0YXJnZXREZWYucHJvY2VlZCgpLbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6SW5uZXJCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBTW92ZS27CgmrRVhQQU5EIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6U2NhcGVBc3BlY3Q6OklubmVyQmxvY2tDYWxsKHBhdGgsIGlubmVyKS27q0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbm5lckJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFDcmVhdGVBZ2VudHMtuwoJq2NhbGwocGF0aCwgaW5uZXIpu6tFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6SW5uZXJCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBRGllLbsKCatjYWxsKHBhdGgsIGlubmVyKburRU5EQVJPVU5EuwqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OklubmVyQmxvY2sgKExpc3RbbWV0YWFibTo6YWN0OjpBQWN0XSBwYXRoLCBCb29sZWFuIGlubmVyKSBGT1IgQUxlYXZlLbsKCatjYWxsKHBhdGgsIGlubmVyKburRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbm5lckJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFSZXBsYWNlLbsKCatjYWxsKHBhdGgsIGlubmVyKburRU5EQVJPVU5EuwqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OklubmVyQmxvY2sgKExpc3RbbWV0YWFibTo6YWN0OjpBQWN0XSBwYXRoLCBCb29sZWFuIGlubmVyKSBGT1IgQUNvbm5lY3QtuwoJq2NhbGwocGF0aCwgaW5uZXIpu6tFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6SW5uZXJCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBRGlzY29ubmVjdLsKCatjYWxsKHBhdGgsIGlubmVyKburRU5EQVJPVU5Euwo=