q0lNUE9SVCBlbWa7CqtJTVBPUlQgbWV0YWFibbsKq0lNUE9SVCBtZXRhYWJtOjphY3S7CqtJTVBPUlQgbWV0YWFibTo6ZnVuY3Rpb267CgqrRVhURU5TSU9OIG1ldGFhYm06OnRtcGw6Om5hbWVzuwqrRVhURU5TSU9OIG1ldGFhYm06OnRtcGw6OnR5cGVzuwqrRVhURU5TSU9OIG1ldGFhYm06OnRtcGw6OmluZmVyuwqrRVhURU5TSU9OIG1ldGFhYm06OnRtcGw6OnV0aWy7CqtFWFRFTlNJT04gbWV0YWFibTo6dG1wbDo6cHJvamVjdGlvbnO7CqtFWFRFTlNJT04gbWV0YWFibTo6YXNjYXBlOjp0bXBsOjppbmZlcmFzY2FwZbsgCqtFWFRFTlNJT04gbWV0YWFibTo6YXNjYXBlOjp0bXBsOjpuYW1lc2FzY2FwZbsgCgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkV4dGVuZFR5cGUgRk9SIFNQcm9qZWN0aW9uLbtTY2FwZatFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6RXh0ZW5kVHlwZSBGT1IgU0NvbnRleHQtu6t0eXBlTmFtZSgpLburRU5EQVJPVU5EuwqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkV4dGVuZFR5cGUgRk9SIFNBZ2VudC27q3BrZ20oKS27U2NhcGWrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpDbGFzc0luaGVpcml0YW5jZSBGT1IgU0NvbnRleHQtuyBleHRlbmRzIFNjYXBlq0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpDbGFzc0luaGVpcml0YW5jZSBGT1IgU0FnZW50LbsgZXh0ZW5kcyCrZXh0ZW5kVHlwZSgpu6tFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6Q2xhc3NJbmhlaXJpdGFuY2UgRk9SIFNTdHlsZS27IGV4dGVuZHMgRHJhd0ZlYXR1cmWrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbXBvcnRzIEZPUiBTU3R5bGUtuwppbXBvcnQgamF2YS5hd3QuR3JhcGhpY3M7CmltcG9ydCBqYXZhLmF3dC5HcmFwaGljczJEOwppbXBvcnQgamF2YS5hd3QuU2hhcGU7CmltcG9ydCBqYXZhLmF3dC5nZW9tLkVsbGlwc2UyRDsKaW1wb3J0IGphdmEuYXd0Lmdlb20uUmVjdGFuZ2xlMkQ7CmltcG9ydCBvcmcuYXNjYXBlLnV0aWwudmlzLkRyYXdGZWF0dXJlOwoKaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuQ2VsbE9jY3VwYW50OwppbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5Ib3N0Q2VsbDsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6SW1wb3J0cyBGT1IgU0FnZW50LbsKCWltcG9ydCBqYXZhLmF3dC5Db2xvcjsKCWltcG9ydCBqYXZhLmF3dC5HcmFwaGljczsKCWltcG9ydCBqYXZhLmF3dC5pbWFnZS5CdWZmZXJlZEltYWdlOwoJCglpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKCWltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCWltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CgkKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLkFnZW50OwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuQ2VsbDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLkNlbGxPY2N1cGFudDsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLkhvc3RDZWxsOwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuTG9jYXRlZEFnZW50OwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuU2NhcGU7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5ldmVudC5TY2FwZUV2ZW50OwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwucnVsZS5SdWxlOwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwucnVsZS5FeGVjdXRlVGhlblVwZGF0ZTsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLnNwYWNlLkNvbGxlY3Rpb25TcGFjZTsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLnNwYWNlLkNvb3JkaW5hdGU7CglpbXBvcnQgb3JnLmFzY2FwZS5tb2RlbC5zcGFjZS5Db29yZGluYXRlMkREaXNjcmV0ZTsKCWltcG9ydCBvcmcuYXNjYXBlLm1vZGVsLnNwYWNlLkdyYXBoOwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuc3BhY2UuU2luZ2xldG9uOwoJaW1wb3J0IG9yZy5hc2NhcGUubW9kZWwuc3BhY2UuTG9jYXRpb247CglpbXBvcnQgb3JnLmFzY2FwZS51dGlsLkNvbmRpdGlvbmFsOwoJCgmrdGFyZ2V0RGVmLnByb2NlZWQoKbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6Qm9keSBGT1IgU0FnZW50LbsKCat0YXJnZXREZWYucHJvY2VlZCgpuwoJq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpBZ2VudEJvZHktuwoJCgmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKICAgIHB1YmxpYyBDb2xvciBnZXRDb2xvcigpIHsKICAgIAlyZXR1cm4gQ29sb3IuTElHSFRfR1JBWTsKICAgIH0Kq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6Qm9keSBGT1IgU0NvbnRleHQtuwogICAgq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpTY2FwZUJvZHktuwoKCXB1YmxpYyB2b2lkIGNyZWF0ZUV4dGVuc2lvbnMoT2JqZWN0IG9iamVjdCkgewoJfQogICAgCgmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKCQkobmV3IG9yZy5hc2NhcGUucnVudGltZS5zd2luZy5Td2luZ1J1bm5lcigpKS5vcGVuKCKraW1wbGVtZW50YXRpb24ucXVhbGlmaWVkTmFtZbsiLCBhcmdzKTsKCX0Kq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6Qm9keSBGT1IgU1N0eWxlLbsKCat0YXJnZXREZWYucHJvY2VlZCgpuwoJCgmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKICAgIHB1YmxpYyB2b2lkIGRyYXcoR3JhcGhpY3MgZywgT2JqZWN0IG9iamVjdCwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7CiAgICAJU2hhcGUgc2hhcGUgPSBudWxsOwoJCatJRiBhZ2VudC5pc0hvc3QoKS27CgkJCathZ2VudC50eXBlTmFtZSgpuyCrcm9vdEFjdGl2aXR5LmlkKCm7ID0gKKthZ2VudC50eXBlTmFtZSgpuykgb2JqZWN0OwoJCQmrRk9SRUFDSCAoKEFHcm91cCkgcm9vdEFjdGl2aXR5KS5yb290cyBBUyBhY3S7q2FnZW50LnR5cGVOYW1lKCm7IKthY3QuaWQoKbsgPSCrcm9vdEFjdGl2aXR5LmlkKCm7O6tFTkRGT1JFQUNIuwoJCQmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkFjdGlvbkJvZHktuwoJCatFTFNFLbsKCSAgICAgICAgSG9zdENlbGwgq3Jvb3RBY3Rpdml0eS5pZCgpu0NlbGwgPSAoSG9zdENlbGwpIG9iamVjdDsKCSAgICAgICAgaWYgKKtyb290QWN0aXZpdHkuaWQoKbtDZWxsLmdldE9jY3VwYW50KCkgaW5zdGFuY2VvZiCrYWdlbnQudHlwZU5hbWUoKbspIHsKCQkJCathZ2VudC50eXBlTmFtZSgpuyCrcm9vdEFjdGl2aXR5LmlkKCm7ID0gKKthZ2VudC50eXBlTmFtZSgpuykgq3Jvb3RBY3Rpdml0eS5pZCgpu0NlbGwuZ2V0T2NjdXBhbnQoKTsKCQkJCatGT1JFQUNIICgoQUdyb3VwKSByb290QWN0aXZpdHkpLnJvb3RzIEFTIGFjdLurYWdlbnQudHlwZU5hbWUoKbsgq2FjdC5pZCgpuyA9IKtyb290QWN0aXZpdHkuaWQoKbs7q0VOREZPUkVBQ0i7CgkJCQmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkFjdGlvbkJvZHktuwoJCQl9CgkJq0VORElGLbsKCX0Kq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6YXNjYXBlOjp0bXBsOjpTY2FwZUFzcGVjdDo6Vmlld0J1aWxkZXIgRk9SIEFHcm91cC27Cgl7CiAgICCrdGFyZ2V0RGVmLnByb2NlZWQoKS27CiAgICB9Cgl7CglvcmcuYXNjYXBlLnZpZXcudmlzLkNoYXJ0VmlldyBjaGFydCA9IG5ldyBvcmcuYXNjYXBlLnZpZXcudmlzLkNoYXJ0VmlldygpOwogICAgYWRkVmlldyhjaGFydCk7CgkvL2lmIChnZXRSdW5uZXIoKS5nZXRFbnZpcm9ubWVudCgpIGluc3RhbmNlb2Ygb3JnLmFzY2FwZS5ydW50aW1lLmFwcGxldC5BcHBsZXRFbnZpcm9ubWVudCkgewogICAgLy8gICAgY2hhcnQuZ2V0Q2hhcnQoKS5nZXRMZWdlbmQoKS5zZXRBbmNob3IoY29tLmpyZWZpbmVyeS5jaGFydC5MZWdlbmQuU09VVEgpOwoJLy99CglHcmFwaGljcyBkdW1teUdyYXBoaWNzID0gbmV3IEJ1ZmZlcmVkSW1hZ2UoMTAsIDEwLCBCdWZmZXJlZEltYWdlLlRZUEVfSU5UX1JHQikuZ2V0R3JhcGhpY3MoKTsKCiAgICCrRk9SRUFDSCAoKFNDb250ZXh0KSByZWZlcmVuY2UpLmFnZW50cyBBUyBhZ2VudLsKICAgIKtJRiAhYWdlbnQuc3R5bGVzLmlzRW1wdHktuwogICAgZmluYWwgq2FnZW50Lm93bmVyLnR5cGVOYW1lKCm7IKthZ2VudC5pZCgpu1NjYXBlID0gbmV3IKthZ2VudC5vd25lci50eXBlTmFtZSgpuygpOwogICAgq2FnZW50LmlkKCm7U2NhcGUuc2V0UnVubmVyKG5ldyBvcmcuYXNjYXBlLnJ1bnRpbWUuTm9uR3JhcGhpY1J1bm5lcigpKTsKCathZ2VudC50eXBlTmFtZSgpuyCrYWdlbnQuaWQoKbsgPSBuZXcgq2FnZW50LnR5cGVOYW1lKCm7KCkgewoJCQkJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7CiAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCByZXF1ZXN0VXBkYXRlKCkgewogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7CiAgICAgICAgICAgICAgICBwdWJsaWMgq2FnZW50Lm93bmVyLnR5cGVOYW1lKCm7IGdldKthZ2VudC5vd25lci50eXBlTmFtZSgpuygpIHsKICAgICAgICAgICAgICAgIAlyZXR1cm4gq2FnZW50LmlkKCm7U2NhcGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICCrYWdlbnQuaWQoKbtTY2FwZS5hZGQoq2FnZW50LmlkKCm7KTsKCatJRiAhYWdlbnQuaXNIb3N0KCktuwoJb3JnLmFzY2FwZS5tb2RlbC5Ib3N0Q2VsbCCrYWdlbnQuaWQoKbtIb3N0ID0gbmV3IG9yZy5hc2NhcGUubW9kZWwuSG9zdENlbGwoKSB7CgkJCQmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkdlbmVyYXRlQ29tbWVudLsKICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJlcXVlc3RVcGRhdGUoKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgmrYWdlbnQuaWQoKbtIb3N0LnNldE9jY3VwYW50KChvcmcuYXNjYXBlLm1vZGVsLkNlbGxPY2N1cGFudCkgq2FnZW50LmlkKCm7KTsKCatFTkRJRi27CgmrRU5ESUYtuwogICAgq0ZPUkVBQ0ggYWdlbnQuc3R5bGVzIEFTIHN0eWxluwoJq3N0eWxlLnR5cGVOYW1lKCm7IKtzdHlsZS5pZCgpuyA9IG5ldyCrc3R5bGUudHlwZU5hbWUoKbsoKTsKCatGT1JFQUNIIHN0eWxlLnNldHRlclNwYWNlKCkgQVMgc2V0dGVyuwogICAgqygoTGlzdCkgc2V0dGVyKS5sYXN0KCm7OwoJq0lGIGFnZW50LmlzSG9zdCgpLbsKICAgIKtzdHlsZS5pZCgpuy5kcmF3KGR1bW15R3JhcGhpY3MsIKthZ2VudC5pZCgpuywgNCwgNCk7CiAgICCrRUxTRbsKICAgIKtzdHlsZS5pZCgpuy5kcmF3KGR1bW15R3JhcGhpY3MsIKthZ2VudC5pZCgpu0hvc3QsIDQsIDQpOwogICAgq0VORElGLbsKICAgIHsKICAgIENvbG9yIGFnZW50Q29sb3IgPSBkdW1teUdyYXBoaWNzLmdldENvbG9yKCk7CgljaGFydC5hZGRTZXJpZXMoIkNvdW50IKthZ2VudC50eXBlTmFtZSgpuyCrKChMaXN0KSBzZXR0ZXIpLmZpcnN0KCm7IiwgYWdlbnRDb2xvcik7Cgl9CiAgICCrRU5ERk9SRUFDSC27CiAgICCrRU5ERk9SRUFDSC27CiAgICCrRU5ERk9SRUFDSC27CiAgICB9CqtFTkRBUk9VTkS7CgqrREVGSU5FIFN0eWxlQnVpbGRlciAoU1Byb2plY3Rpb24gcHJvamVjdGlvbikgRk9SIFNTdHlsZS27CiAgICAgICAgq0lGIGFwcHJvcHJpYXRlKHByb2plY3Rpb24sIHRoaXMpLbsKICAgICAgICBvcmcuYXNjYXBlLnV0aWwudmlzLkRyYXdGZWF0dXJlIKtpZCgpuyA9IG5ldyCraW1wbGVtZW50YXRpb24ucXVhbGlmaWVkTmFtZbsoKTsKICAgICAgICCraWQoKbsuc2V0TmFtZSgiq2xhYmVsuyIpOwogICAgICAgIKtwcm9qZWN0aW9uLmZpZWxkTmFtZSgpuy5hZGREcmF3RmVhdHVyZSiraWQoKbspOwogICAgICAgIKtFTkRJRi27CqtFTkRERUZJTkW7CqtERUZJTkUgU3R5bGVTZWxlY3RvciAoU1Byb2plY3Rpb24gcHJvamVjdGlvbikgRk9SIFNTdHlsZS27CiAgICAgICAgq0lGIGFwcHJvcHJpYXRlKHByb2plY3Rpb24sIHRoaXMpLbsKICAgICAgICCrcHJvamVjdGlvbi5pZCgpu1ZpZXcuZ2V0RHJhd1NlbGVjdGlvbigpLnNldFNlbGVjdGVkKKtpZCgpuywgdHJ1ZSk7CiAgICAgICAgq0VORElGLbsKq0VORERFRklORbsKq0RFRklORSBTdHlsZVNlbGVjdG9yIChTUHJvamVjdGlvbiBwcm9qZWN0aW9uKSBGT1IgU1Byb2plY3Rpb24tu6tFTkRERUZJTkW7CqtERUZJTkUgU3R5bGVTZWxlY3RvciAoU1Byb2plY3Rpb24gcHJvamVjdGlvbikgRk9SIFNHcmlkLbsKICAgICAgICCraWQoKbtWaWV3LmdldERyYXdTZWxlY3Rpb24oKS5zZXRTZWxlY3RlZCiraWQoKbtWaWV3LmFnZW50c19vdmFsX2NlbGxzX2RyYXdfZmVhdHVyZSwgZmFsc2UpOwogICAgICAgIKtpZCgpu1ZpZXcuZ2V0RHJhd1NlbGVjdGlvbigpLnNldFNlbGVjdGVkKKtpZCgpu1ZpZXcuY2VsbHNfZmlsbF9kcmF3X2ZlYXR1cmUsIHRydWUpOwogICAgICAgIKtpZCgpu1ZpZXcuZ2V0RHJhd1NlbGVjdGlvbigpLm1vdmVUb0Zyb250KKtpZCgpu1ZpZXcuY2VsbHNfZmlsbF9kcmF3X2ZlYXR1cmUpOwqrRU5EREVGSU5FuwqrQVJPVU5EIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6U2NhcGVBc3BlY3Q6OlZpZXdCdWlsZGVyIEZPUiBBQnVpbGRHcmlkLbsKCatJRiAocHJvamVjdGlvbi5kZWZhdWx0VmlldygpICE9IG51bGwpLbsKCQmrcHJvamVjdGlvbi5kZWZhdWx0VmlldygpuyCrcHJvamVjdGlvbi5pZCgpu1ZpZXcgPSBuZXcgq3Byb2plY3Rpb24uZGVmYXVsdFZpZXcoKbsoKTsKCQmrcHJvamVjdGlvbi5pZCgpu1ZpZXcuc2V0QWdlbnRTaXplKKsoKFNHcmlkKSBwcm9qZWN0aW9uKS5hZ2VudFBpeGVsU2l6ZSgpuyk7CgkJq3Byb2plY3Rpb24uZmllbGROYW1lKCm7LmFkZFZpZXcoq3Byb2plY3Rpb24uaWQoKbtWaWV3KTsKCQmrSUYgISgoU0NvbnRleHQpIHJlZmVyZW5jZSkucHJvamVjdGlvbnMudHlwZVNlbGVjdChTTmV0d29yaykuaXNFbXB0eS27CgkJq3Byb2plY3Rpb24uaWQoKbtWaWV3LnNldERyYXdOZXR3b3JrKHRydWUpOwoJCatFTkRJRi27CgkJq0lGIGZpbGxBZ2VudCAhPSBudWxsLbsKICAgICAgICCrRVhQQU5EIFN0eWxlQnVpbGRlciAocHJvamVjdGlvbikgRk9SRUFDSCBmaWxsQWdlbnQuc3R5bGVzLbsKICAgICAgICCrRU5ESUYtuwogICAgICAgIKtGT1JFQUNIIGFnZW50cyBBUyBidWlsZEFnZW50LbsKICAgICAgICCrRVhQQU5EIFN0eWxlQnVpbGRlciAocHJvamVjdGlvbikgRk9SRUFDSCBidWlsZEFnZW50LnN0eWxlcy27CiAgICAgICAgq0VOREZPUkVBQ0gtuwogICAgICAgIKtGT1JFQUNIIGFnZW50cyBBUyBidWlsZEFnZW50LbsKICAgICAgICCrRVhQQU5EIFN0eWxlU2VsZWN0b3IgKHByb2plY3Rpb24pIEZPUkVBQ0ggYnVpbGRBZ2VudC5zdHlsZXMtuwogICAgICAgIKtFTkRGT1JFQUNILbsKCQmrSUYgZmlsbEFnZW50ICE9IG51bGwtuwogICAgICAgIKtFWFBBTkQgU3R5bGVTZWxlY3RvciAocHJvamVjdGlvbikgRk9SRUFDSCBmaWxsQWdlbnQuc3R5bGVzLbsKICAgICAgICCrRU5ESUYtuwogICAgICAgIKtFWFBBTkQgU3R5bGVTZWxlY3RvciAocHJvamVjdGlvbikgRk9SIHByb2plY3Rpb24tuwoJq0VORElGLbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6SW5uZXJCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBRXZhbHVhdGUtuwoJq0lGIGZ1bmN0aW9uLmlkKCkuc3RhcnRzV2l0aCgiY29sb3IiKS27CgkJq3RhcmdldERlZi5wcm9jZWVkKCm7CgkJZy5zZXRDb2xvciiraWQoKbspOwoJq0VMU0VJRiBmdW5jdGlvbi5pZCgpID09ICJzaGFwZU92YWwiLbsKCQlzaGFwZSA9IG5ldyBFbGxpcHNlMkQuRG91YmxlKDAsIDAsIHdpZHRoIC0gMiwgaGVpZ2h0IC0gMik7CgmrRUxTRUlGIGZ1bmN0aW9uLmlkKCkgPT0gInNoYXBlUmVjdGFuZ2xlIi27CgkJq0lGICFyZWZlcmVuY2UuaXNIb3N0KCktuwoJCXNoYXBlID0gbmV3IFJlY3RhbmdsZTJELkRvdWJsZSgwLCAwLCB3aWR0aCAtIDEsIGhlaWdodCAtIDEpOwoJCatFTFNFLbsKCQlzaGFwZSA9IG5ldyBSZWN0YW5nbGUyRC5Eb3VibGUoMCwgMCwgd2lkdGgsIGhlaWdodCk7CgkJq0VORElGLbsKCatFTFNFSUYgZnVuY3Rpb24uaWQoKSA9PSAic2hhcGVNYXJrZXIiLbsKICAgICAgICBzaGFwZSA9IG5ldyBFbGxpcHNlMkQuRG91YmxlKHdpZHRoICogLjI1IC0gMSwgd2lkdGggKiAuMjUgLSAxLCB3aWR0aCAqIC41IC0gMSwgd2lkdGggKiAuNSAtIDEpOwoJq0VMU0VJRiBmdW5jdGlvbi5pZCgpLnN0YXJ0c1dpdGgoImdyYXBoaWNGaWxsIiktuwogICAgICAgICgoR3JhcGhpY3MyRCkgZykuZmlsbChzaGFwZSk7CgmrRUxTRUlGIGZ1bmN0aW9uLmlkKCkuc3RhcnRzV2l0aCgiZ3JhcGhpY091dGxpbmUiKS27CiAgICAgICAgKChHcmFwaGljczJEKSBnKS5kcmF3KHNoYXBlKTsKICAgIKtFTFNFLbsKCSAJq0lGIHNlbGVjdGVkID09IHJvb3RTZWxlY3RlZCB8fCBhbGxUYXJnZXRzLnR5cGVTZWxlY3QoQVNldCkuY29sbGVjdChlIHwgZS5wYXJhbWV0ZXIpLnNpemUgPiAwLbsKCQkJq3RhcmdldERlZi5wcm9jZWVkKCm7CgkJq0VORElGLbsKCatFTkRJRi27CqtFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkZ1bmN0aW9uSW5uZXJCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBU2luay27CiAgICCrSUYgZnVuY3Rpb24uaWQoKSA9PSAicmFuZG9tVW5pdCItuwogICAgICAgIGdldFJhbmRvbSgpLm5leHREb3VibGUoKQogICAgq0VMU0VJRiBmdW5jdGlvbi5pZCgpID09ICJyYW5kb21JcyItuwogICAgICAgIGdldFJhbmRvbSgpLm5leHRCb29sZWFuKCkKICAgIKtFTFNFSUYgZnVuY3Rpb24uaWQoKSA9PSAidW5pZm9ybURpc3RyaWJ1dGlvbiItuwogICAgICAgIHJhbmRvbUluUmFuZ2Uoq2lucHV0cy5leHByZXNzaW9uKHBhdGgsIGlubmVyKS50b1N0cmluZygiLCAiKbspOwoJq0VMU0VJRiBmdW5jdGlvbi5pZCgpID09ICJ0aW1lTm93Ii27CgkJq3BhdGgubGFzdCgpLmFjY2Vzc1BhdGgodGhpcywgaW5uZXIpu6tyZWZlcmVuY2Uub3duZXIgIT0gbnVsbCA/ICJnZXRTY2FwZSgpLiIgOiAiIrtnZXRQZXJpb2QoKQogICAgq0VMU0VJRiBmdW5jdGlvbi5pZCgpID09ICJhdmFpbGFibGUiLbsKICAgICAgICBpc0F2YWlsYWJsZSgpCiAgICCrRUxTRUlGIGZ1bmN0aW9uLmlkKCkgPT0gIndpdGhpbkJvdW5kYXJpZXMiLbsKICAgICAgICCrZXhwcmVzc2lvblNpbmsocGF0aCwgZnVuY3Rpb24sIGlubmVyKbsKCatFTFNFLbsKCQmrdGFyZ2V0RGVmLnByb2NlZWQoKbsKCatFTkRJRi27CqtFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6Ok90aGVyQWNjZXNzb3JzIEZPUiBTQWdlbnQtuwoJq3RhcmdldERlZi5wcm9jZWVkKCktuwogICAgq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpOYW1lQWNjZXNzb3ItuwqrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpCdWlsZGVyIEZPUiBTQWdlbnQtuwoJq0lGIChyb290QWN0aXZpdHkgIT0gbnVsbCktuwoJCatFWFBBTkQgbWV0YWFibTo6YXNjYXBlOjp0bXBsOjpTY2FwZUFzcGVjdDo6Q2hpbGRCdWlsZGVyIEZPUiByb290QWN0aXZpdHktuwoJq0VORElGLbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6TWV0aG9kUG90ZW50aWFsIChtZXRhYWJtOjphY3Q6OkFBY3Qgd2l0aGluKSBGT1IgRkZ1bmN0aW9uLbsKCatJRiAoaWQoKSA9PSAid2l0aGluQm91bmRhcmllcyIpIHx8IChpZCgpID09ICJkaXN0YW5jZSIpLbsKCQmrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6Ok1ldGhvZC27CgmrRUxTRS27CgkJq3RhcmdldERlZi5wcm9jZWVkKCktuwoJq0VORElGLbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6TWV0aG9kUG90ZW50aWFsIChtZXRhYWJtOjphY3Q6OkFBY3Qgd2l0aGluKSBGT1IgQVF1ZXJ5LbsKCatJRiAoZnVuY3Rpb24uaWQoKSA9PSAibWluaW1pemUiKSB8fCAoZnVuY3Rpb24uaWQoKSA9PSAibWF4aW1pemUiKS27CiAgICAvKioKICAgICAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CiAgICAgKiBBIGRhdGEgcG9pbnQgdXNlZCB3aXRoaW4gYSBzZWFyY2ggdG8gZmluZCB0aGUgq3NlbGVjdGVkLmFnZW50LmxhYmVsuyB3aXRoIHRoZSCrZnVuY3Rpb24uaWQoKbtkIKtpbnB1dHMudmFsdWUuZ2V0KDApLmxhYmVsuyB2YWx1ZS4KICAgICAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgogICAgICogQGdlbmVyYXRlZAogICAgICovCiAgICBwdWJsaWMgZmluYWwgc3RhdGljIERhdGFQb2ludCCrZGF0YVBvaW50KCm7ID0gbmV3IERhdGFQb2ludENvbmNyZXRlKCKrZnVuY3Rpb24uaWQoKS50b0ZpcnN0VXBwZXIoKbsgq2lucHV0cy52YWx1ZS5nZXQoMCkuaWQoKbsiKSB7CgkJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMzc1NTgxMDQ0MzMzNTczOTAxMkw7CgkJq0VYUEFORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpHZW5lcmF0ZUNvbW1lbnS7CiAgICAgICAgcHVibGljIGRvdWJsZSBnZXRWYWx1ZShPYmplY3QgbykgewogICAgICAgICAgICCrRVhQQU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OklubmVyRXZhbHVhdGlvbihhbGxTb3VyY2VzLnNlbGVjdChlfGUuc2VsZWN0ZWQgPT0gdGhpcy5zZWxlY3RlZCksIGZhbHNlKS27CiAgICAgICAgICAgIHJldHVybiAoKKtzZWxlY3RlZC5hZ2VudC50eXBlTmFtZSgpuykgbykuq2lucHV0cy52YWx1ZS5nZXQoMCkuZ2V0dGVyTmFtZSgpuygpOwogICAgICAgIH0KICAgIH07CgmrRUxTRS27CgkJq3RhcmdldERlZi5wcm9jZWVkKCktuwoJq0VORElGLbsKq0VOREFST1VORLsKCqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6QWN0aW9uQm9keSBGT1IgRkZ1bmN0aW9uLbsKCatJRiBpZCgpID09ICJ3aXRoaW5Cb3VuZGFyaWVzIi27CiAgICAgICAgQ29vcmRpbmF0ZTJERGlzY3JldGUgY29vciA9IChDb29yZGluYXRlMkREaXNjcmV0ZSkgZ2V0Q29vcmRpbmF0ZSgpOwogICAgICAgIHJldHVybiAoY29vci5nZXRZVmFsdWUoKSA+PSBib3VuZHNbMF0KICAgICAgICAgICAgICAgICYmIGNvb3IuZ2V0WFZhbHVlKCkgPj0gYm91bmRzWzFdCiAgICAgICAgICAgICAgICAmJiBjb29yLmdldFlWYWx1ZSgpIDw9IGJvdW5kc1syXQogICAgICAgICAgICAgICAgJiYgY29vci5nZXRYVmFsdWUoKSA8PSBib3VuZHNbM10pOwogICAgq0VMU0Utu6t0YXJnZXREZWYucHJvY2VlZCgpu6tFTkRJRi27CqtFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OkNvbmRpdGlvbkJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFBY3QtuwoJq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpDb25kaXRpb25hbChwYXRoLCBpbm5lciktuwqrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpCZWdpblF1ZXJ5QmxvY2sgKExpc3RbbWV0YWFibTo6YWN0OjpBQWN0XSBwYXRoLCBCb29sZWFuIGlubmVyKSBGT1IgQUFjdC27CgmrRVhQQU5EIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6U2NhcGVBc3BlY3Q6OkJlZ2luUXVlcnkocGF0aCwgaW5uZXIpLbsKq0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpFbmRRdWVyeUJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFBY3QtuwoJq0VYUEFORCBtZXRhYWJtOjphc2NhcGU6OnRtcGw6OlNjYXBlQXNwZWN0OjpFbmRRdWVyeShwYXRoLCBpbm5lciktuwqrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpCZWdpblNlcmlhbEJsb2NrKExpc3RbQUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFDb250cm9sLbsKCatFWFBBTkQgbWV0YWFibTo6YXNjYXBlOjp0bXBsOjpTY2FwZUFzcGVjdDo6QmVnaW5TZXJpYWwocGF0aCwgaW5uZXIpLbsKICAgIKt0YXJnZXREZWYucHJvY2VlZCgpLbsKq0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpFbmRTZXJpYWxCbG9jayhMaXN0W0FBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBQ29udHJvbC27CgmrRVhQQU5EIG1ldGFhYm06OmFzY2FwZTo6dG1wbDo6U2NhcGVBc3BlY3Q6OkVuZFNlcmlhbChwYXRoLCBpbm5lciktuwogICAgq3RhcmdldERlZi5wcm9jZWVkKCktuwqrRU5EQVJPVU5EuwoKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbm5lckJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFNb3ZlLbsKCatFWFBBTkQgbWV0YWFibTo6YXNjYXBlOjp0bXBsOjpTY2FwZUFzcGVjdDo6SW5uZXJCbG9ja0NhbGwocGF0aCwgaW5uZXIpLburRU5EQVJPVU5EuwqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OklubmVyQmxvY2sgKExpc3RbbWV0YWFibTo6YWN0OjpBQWN0XSBwYXRoLCBCb29sZWFuIGlubmVyKSBGT1IgQUNyZWF0ZUFnZW50cy27CgmrY2FsbChwYXRoLCBpbm5lcim7q0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbm5lckJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFEaWUtuwoJq2NhbGwocGF0aCwgaW5uZXIpu6tFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6SW5uZXJCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBTGVhdmUtuwoJq2NhbGwocGF0aCwgaW5uZXIpu6tFTkRBUk9VTkS7CgqrQVJPVU5EIG1ldGFhYm06OnRtcGw6OkphdmE6OklubmVyQmxvY2sgKExpc3RbbWV0YWFibTo6YWN0OjpBQWN0XSBwYXRoLCBCb29sZWFuIGlubmVyKSBGT1IgQVJlcGxhY2UtuwoJq2NhbGwocGF0aCwgaW5uZXIpu6tFTkRBUk9VTkS7CqtBUk9VTkQgbWV0YWFibTo6dG1wbDo6SmF2YTo6SW5uZXJCbG9jayAoTGlzdFttZXRhYWJtOjphY3Q6OkFBY3RdIHBhdGgsIEJvb2xlYW4gaW5uZXIpIEZPUiBBQ29ubmVjdC27CgmrY2FsbChwYXRoLCBpbm5lcim7q0VOREFST1VORLsKq0FST1VORCBtZXRhYWJtOjp0bXBsOjpKYXZhOjpJbm5lckJsb2NrIChMaXN0W21ldGFhYm06OmFjdDo6QUFjdF0gcGF0aCwgQm9vbGVhbiBpbm5lcikgRk9SIEFEaXNjb25uZWN0uwoJq2NhbGwocGF0aCwgaW5uZXIpu6tFTkRBUk9VTkS7CgkK