rO0ABXNyACVqYXZhLnV0aWwuQ29sbGVjdGlvbnMkVW5tb2RpZmlhYmxlTWFw8aWo/nT1B0ICAAFMAAFtdAAPTGphdmEvdXRpbC9NYXA7eHBzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAMdwgAAAAQAAAABHQADkNvbnRlbnQtTGVuZ3Roc3IAJmphdmEudXRpbC5Db2xsZWN0aW9ucyRVbm1vZGlmaWFibGVMaXN0/A8lMbXsjhACAAFMAARsaXN0dAAQTGphdmEvdXRpbC9MaXN0O3hyACxqYXZhLnV0aWwuQ29sbGVjdGlvbnMkVW5tb2RpZmlhYmxlQ29sbGVjdGlvbhlCAIDLXvceAgABTAABY3QAFkxqYXZhL3V0aWwvQ29sbGVjdGlvbjt4cHNyABNqYXZhLnV0aWwuQXJyYXlMaXN0eIHSHZnHYZ0DAAFJAARzaXpleHAAAAABdwQAAAAKdAAENTIyNXhxAH4ADHQACkNvbm5lY3Rpb25zcQB+AAZzcQB+AAsAAAABdwQAAAAKdAAFY2xvc2V4cQB+ABBwc3EAfgAGc3EAfgALAAAAAXcEAAAACnQAD0hUVFAvMS4xIDIwMCBPS3hxAH4AE3QADENvbnRlbnQtVHlwZXNxAH4ABnNxAH4ACwAAAAF3BAAAAAp0AB10ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMXhxAH4AF3gvKiBAdGVzdCBAKCMpZmlsZTIuMQkxLjEgMDMvMDgvMDkKICogQHN1bW1hcnkgVW5pdCB0ZXN0IGZvciBqYXZhLm5ldC5SZXNwb25zZUNhY2hlSGFuZGxlcgogKiBAYnVnIDQ4MzcyNjcKICogQGF1dGhvciBZaW5neGlhbiBXYW5nCiAqLwoKaW1wb3J0IGphdmEubmV0Lio7CmltcG9ydCBqYXZhLnV0aWwuKjsKaW1wb3J0IGphdmEuaW8uKjsKaW1wb3J0IGphdmEubmlvLio7CmltcG9ydCBqYXZhLm5pby5jaGFubmVscy5SZWFkYWJsZUJ5dGVDaGFubmVsOwppbXBvcnQgc3VuLm5ldC53d3cuUGFyc2VVdGlsOwoKLyoqCiAqIFJlcXVlc3Qgc2hvdWxkIGdldCBzZXJ2aWNlZCBieSB0aGUgY2FjaGUgaGFuZGxlci4gUmVzcG9uc2UgZ2V0CiAqIHNhdmVkIHRocm91Z2ggdGhlIGNhY2hlIGhhbmRsZXIuCiAqLwpwdWJsaWMgY2xhc3MgUmVzcG9uc2VDYWNoZUhhbmRsZXJUZXN0IGltcGxlbWVudHMgUnVubmFibGUgewogICAgU2VydmVyU29ja2V0IHNzOwogICAgc3RhdGljIFVSTCB1cmwxOwogICAgc3RhdGljIFVSTCB1cmwyOwogICAgc3RhdGljIGJvb2xlYW4gZmxhZyA9IGZhbHNlOwogICAgLyogCiAgICAgKiBPdXIgImh0dHAiIHNlcnZlciB0byByZXR1cm4gYSA0MDQgKi8KICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKCXRyeSB7CgkgICAgU29ja2V0IHMgPSBzcy5hY2NlcHQoKTsKCgkgICAgLy8gY2hlY2sgcmVxdWVzdCBjb250YWlucyAiQ29va2llIgoJICAgIElucHV0U3RyZWFtIGlzID0gcy5nZXRJbnB1dFN0cmVhbSAoKTsKCSAgICBCdWZmZXJlZFJlYWRlciByID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpcykpOwoJICAgIGJvb2xlYW4gZmxhZyA9IGZhbHNlOwoJICAgIFN0cmluZyB4OwoJICAgIHdoaWxlICgoeD1yLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKCQlpZiAoeC5sZW5ndGgoKSA9PTApIHsKCQkgICAgYnJlYWs7CgkJfQoJICAgIH0KCSAgICBQcmludFN0cmVhbSBvdXQgPSBuZXcgUHJpbnRTdHJlYW0oIAoJCQkJIG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbSgKCQkJCSAgICBzLmdldE91dHB1dFN0cmVhbSgpICkpOwoJICAgIAoJICAgIC8qIHNlbmQgZmlsZTIuMSAqLwoJICAgIEZpbGUgZmlsZTIgPSBuZXcgRmlsZSgiZmlsZTIuMSIpOwoJICAgIG91dC5wcmludCgiSFRUUC8xLjEgMjAwIE9LXHJcbiIpOwoJICAgIG91dC5wcmludCgiQ29udGVudC1UeXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMVxyXG4iKTsKCSAgICBvdXQucHJpbnQoIkNvbnRlbnQtTGVuZ3RoOiAiK2ZpbGUyLmxlbmd0aCgpKyJcclxuIik7CgkgICAgb3V0LnByaW50KCJDb25uZWN0aW9uOiBjbG9zZVxyXG4iKTsKCSAgICBvdXQucHJpbnQoIlxyXG4iKTsKCSAgICBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlMik7CgkgICAgYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWyhpbnQpZmlsZTIubGVuZ3RoKCldOwoJICAgIGludCBsZW47CgkgICAgd2hpbGUgKChsZW4gPSBmaXMucmVhZChidWYpKSAhPSAtMSkgewoJCW91dC5wcmludChuZXcgU3RyaW5nKGJ1ZikpOwoJICAgIH0KCgkgICAgb3V0LmZsdXNoKCk7CgoJICAgIHMuY2xvc2UoKTsKCSAgICBzcy5jbG9zZSgpOwoJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsgCgkgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKCX0KICAgIH0KCiAgICBSZXNwb25zZUNhY2hlSGFuZGxlclRlc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKCS8qIHN0YXJ0IHRoZSBzZXJ2ZXIgKi8KCXNzID0gbmV3IFNlcnZlclNvY2tldCgwKTsKCShuZXcgVGhyZWFkKHRoaXMpKS5zdGFydCgpOwoKCS8qIGVzdGFibGlzaCBodHRwIGNvbm5lY3Rpb24gdG8gc2VydmVyICovCgl1cmwxID0gbmV3IFVSTCgiaHR0cDovL2xvY2FsaG9zdC9maWxlMS5jYWNoZSIpOwoJSHR0cFVSTENvbm5lY3Rpb24gaHR0cCA9IChIdHRwVVJMQ29ubmVjdGlvbil1cmwxLm9wZW5Db25uZWN0aW9uKCk7CglJbnB1dFN0cmVhbSBpcyA9IG51bGw7CglTeXN0ZW0ub3V0LnByaW50bG4oImhlYWRlcnMxOiIraHR0cC5nZXRIZWFkZXJGaWVsZHMoKSk7Cgl0cnkgewoJICAgIGlzID0gaHR0cC5nZXRJbnB1dFN0cmVhbSgpOwoJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgewoJICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGlvZXguZ2V0TWVzc2FnZSgpKTsKCX0KCUJ1ZmZlcmVkUmVhZGVyIHIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGlzKSk7CglTdHJpbmcgeDsKCUZpbGUgZmlsZW91dCA9IG5ldyBGaWxlKCJmaWxlMSIpOwoJUHJpbnRTdHJlYW0gb3V0ID0gbmV3IFByaW50U3RyZWFtKCAKCQkJCSBuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0oCgkJCQkgICAgbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZW91dCkpKTsKCXdoaWxlICgoeD1yLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKCSAgICBvdXQucHJpbnQoeCsiXG4iKTsKCX0KCW91dC5mbHVzaCgpOwoJb3V0LmNsb3NlKCk7CgoJLy8gaWYgIShmaWxlMS5vdXQgPT0gZmlsZTEuY2FjaGUpCgkvLyB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigidGVzdGluZyBSZXNwb25zZUNhY2hlSGFuZGxlci5nZXQoKSBmYWlsZWQiKTsKCWh0dHAuZGlzY29ubmVjdCgpOwoKCS8vIHRlc3RpbmcgUmVzcG9uc2VDYWNoZUhhbmRsZXIucHV0KCkKCXVybDIgPSBuZXcgVVJMKCJodHRwOi8vbG9jYWxob3N0OiIgKyAKCQkgICAgICAgSW50ZWdlci50b1N0cmluZyhzcy5nZXRMb2NhbFBvcnQoKSkrIi9maWxlMi4xIik7CglodHRwID0gKEh0dHBVUkxDb25uZWN0aW9uKXVybDIub3BlbkNvbm5lY3Rpb24oKTsKCVN5c3RlbS5vdXQucHJpbnRsbigiaGVhZGVyczI6IitodHRwLmdldEhlYWRlckZpZWxkcygpKTsKCgl0cnkgewoJICAgIGlzID0gaHR0cC5nZXRJbnB1dFN0cmVhbSgpOwoJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9leCkgewoJICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGlvZXguZ2V0TWVzc2FnZSgpKTsKCX0KCURhdGFJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGF0YUlucHV0U3RyZWFtKGlzKTsKCWZpbGVvdXQgPSBuZXcgRmlsZSgiZmlsZTIuMiIpOwoJYnl0ZVtdIGJ1ZiA9IG5ldyBieXRlWyhpbnQpbmV3IEZpbGUoImZpbGUyLjEiKS5sZW5ndGgoKV07CglEYXRhT3V0cHV0U3RyZWFtIGRvcyA9ICBuZXcgRGF0YU91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlb3V0KSk7CglpbnQgbGVuOwoJd2hpbGUgKChsZW49ZGlzLnJlYWQoYnVmKSkgIT0gLTEpIHsKCSAgICBkb3Mud3JpdGUoYnVmLCAwLCBsZW4pOwoJfQoJZG9zLmZsdXNoKCk7Cglkb3MuY2xvc2UoKTsKCgkvLyBpZiAhKGZpbGUyLjEgPT0gZmlsZTIuMiA9PSBmaWxlMi5jYWNoZSkKCS8vIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJ0ZXN0aW5nIFJlc3BvbnNlQ2FjaGVIYW5kbGVyLnB1dCgpIGZhaWxlZCIpOwogICAgfQogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3NbXSkgdGhyb3dzIEV4Y2VwdGlvbiB7CglSZXNwb25zZUNhY2hlSGFuZGxlci5zZXREZWZhdWx0KG5ldyBNeVJlc3BvbnNlQ2FjaGVIYW5kbGVyKCkpOwoKCW5ldyBSZXNwb25zZUNhY2hlSGFuZGxlclRlc3QoKTsKICAgIH0KCiAgICBzdGF0aWMgY2xhc3MgTXlSZXNwb25zZUNhY2hlSGFuZGxlciBleHRlbmRzIFJlc3BvbnNlQ2FjaGVIYW5kbGVyIHsKCXB1YmxpYyBSZXNwb25zZSAKCWdldChVUkkgdXJpLCBNYXAgcmVxdWVzdEhlYWRlcnMpCgkgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKCSAgICBpZiAodXJpLmVxdWFscyhQYXJzZVV0aWwudG9VUkkodXJsMSkpKSB7CgkJcmV0dXJuIG5ldyBNeVJlc3BvbnNlKCJmaWxlMS5jYWNoZSIpOwoJICAgIH0gaWYgKHVyaS5lcXVhbHMoUGFyc2VVdGlsLnRvVVJJKHVybDIpKSAmJiAhZmxhZykgewoJCWZsYWcgPSB0cnVlOwoJCXJldHVybiBudWxsOwoJICAgIH0gZWxzZSB7CgkJcmV0dXJuIG5ldyBNeVJlc3BvbnNlKCJmaWxlMi5jYWNoZSIpOwoJICAgIH0KCX0KCXB1YmxpYyBib29sZWFuIHB1dChVUkkgdXJpLCBSZXNwb25zZSByZXNwb25zZSkgIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkgICAgLy8gc2F2ZSBjYWNoZSB0byBmaWxlMi5jYWNoZQoJICAgIC8vIDEuIHNlcmlhbGl6ZSBoZWFkZXJzIGludG8gZmlsZTIuY2FjaGUKCSAgICAvLyAyLiB3cml0ZSBkYXRhIHRvIGZpbGUyLmNhY2hlCgkgICAgRmlsZSBmaWxlID0gbmV3IEZpbGUoImZpbGUyLmNhY2hlIik7CgkgICAgRmlsZU91dHB1dFN0cmVhbSBmb3MgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlKTsKCSAgICBPYmplY3RPdXRwdXRTdHJlYW0gb29zID0gbmV3IE9iamVjdE91dHB1dFN0cmVhbShmb3MpOwoJICAgIG9vcy53cml0ZU9iamVjdChyZXNwb25zZS5nZXRIZWFkZXJzKCkpOwoKCSAgICBSZWFkYWJsZUJ5dGVDaGFubmVsIHJiYyA9IHJlc3BvbnNlLmdldEJvZHkoKTsKCSAgICBpbnQgbGVuID0gKGludCluZXcgRmlsZSgiZmlsZTIuMSIpLmxlbmd0aCgpOwoJICAgIEJ5dGVCdWZmZXIgYnVmID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShsZW4pOwoJICAgIGJ5dGVbXSBiID0gbmV3IGJ5dGVbbGVuXTsKCSAgICB3aGlsZSAoKGxlbiA9IHJiYy5yZWFkKGJ1ZikpICE9IC0xKSB7CgkJYnVmLmZsaXAoKTsKCQlidWYuZ2V0KGIsIDAsIGxlbik7CgkJYnVmLmNvbXBhY3QoKTsKCQlvb3Mud3JpdGUoYiwgMCwgbGVuKTsKCSAgICB9CgkgICAgb29zLmNsb3NlKCk7CgkgICAgcmV0dXJuIHRydWU7Cgl9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIE15UmVzcG9uc2UgZXh0ZW5kcyBSZXNwb25zZSB7CglGaWxlSW5wdXRTdHJlYW0gZmlzOwoJTWFwIGhlYWRlcnM7CglwdWJsaWMgTXlSZXNwb25zZShTdHJpbmcgZmlsZW5hbWUpIHsKCSAgICB0cnkgewoJCWZpcyA9IG5ldyBGaWxlSW5wdXRTdHJlYW0obmV3IEZpbGUoZmlsZW5hbWUpKTsKCQloZWFkZXJzID0gKE1hcCluZXcgT2JqZWN0SW5wdXRTdHJlYW0oZmlzKS5yZWFkT2JqZWN0KCk7CgkgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CgkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZXguZ2V0TWVzc2FnZSgpKTsKCSAgICB9Cgl9CglwdWJsaWMgUmVhZGFibGVCeXRlQ2hhbm5lbCBnZXRCb2R5KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCSAgICByZXR1cm4gZmlzLmdldENoYW5uZWwoKTsKCX0KCglwdWJsaWMgTWFwIGdldEhlYWRlcnMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJICAgIHJldHVybiBoZWFkZXJzOwoJfQogICAgfQp9Cg==