LyoKICogQ29weXJpZ2h0IChjKSAyMDA2LCAyMDA3IEJvcmxhbmQgU29mdHdhcmUgQ29ycG9yYXRpb24KICogCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCiAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgRG1pdHJ5IFN0YWRuaWsgKEJvcmxhbmQpIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgIEFsZXhhbmRlciBTaGF0YWxpbiAoQm9ybGFuZCkgLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICovCgqrSU1QT1JUICJodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2dtZi8yMDA4L0dlbk1vZGVsIrsKq0VYVEVOU0lPTiB4cHQ6OmRpYWdyYW06OmVkaXRwYXJ0czo6VXRpbHO7CgqrREVGSU5FIGNvbnN0cnVjdG9yIEZPUiBnbWZnZW46Okdlbk5vZGVMYWJlbC27CgmrRVhQQU5EIHhwdDo6Q29tbW9uOjpnZW5lcmF0ZWRNZW1iZXJDb21tZW50uwoJcHVibGljIKtlZGl0UGFydENsYXNzTmFtZbsob3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uVmlldyB2aWV3KSB7CgkJc3VwZXIodmlldyk7Cgl9CqtFTkRERUZJTkW7CgqrREVGSU5FIGNyZWF0ZURlZmF1bHRFZGl0UG9saWNpZXNCb2R5IEZPUiBnbWZnZW46Okdlbk5vZGVMYWJlbC27CglzdXBlci5jcmVhdGVEZWZhdWx0RWRpdFBvbGljaWVzKCk7CglpbnN0YWxsRWRpdFBvbGljeShvcmcuZWNsaXBzZS5nZWYuRWRpdFBvbGljeS5ESVJFQ1RfRURJVF9ST0xFLCBuZXcgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS51aS5lZGl0cG9saWNpZXMuTGFiZWxEaXJlY3RFZGl0UG9saWN5KCkpOwoJaW5zdGFsbEVkaXRQb2xpY3kob3JnLmVjbGlwc2UuZ2VmLkVkaXRQb2xpY3kuUFJJTUFSWV9EUkFHX1JPTEUsIG5ldyBvcmcuZWNsaXBzZS5nZWYuZWRpdHBvbGljaWVzLk5vblJlc2l6YWJsZUVkaXRQb2xpY3koKSB7CgoJCXByb3RlY3RlZCBqYXZhLnV0aWwuTGlzdCBjcmVhdGVTZWxlY3Rpb25IYW5kbGVzKCkgewoJCQlqYXZhLnV0aWwuTGlzdCBoYW5kbGVzID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3QoKTsKCQkJb3JnLmVjbGlwc2UuZ2VmLmhhbmRsZXMuTm9uUmVzaXphYmxlSGFuZGxlS2l0LmFkZE1vdmVIYW5kbGUoKG9yZy5lY2xpcHNlLmdlZi5HcmFwaGljYWxFZGl0UGFydCkgZ2V0SG9zdCgpLCBoYW5kbGVzKTsKCQkJcmV0dXJuIGhhbmRsZXM7CgkJfQoKCQlwdWJsaWMgb3JnLmVjbGlwc2UuZ2VmLmNvbW1hbmRzLkNvbW1hbmQgZ2V0Q29tbWFuZChvcmcuZWNsaXBzZS5nZWYuUmVxdWVzdCByZXF1ZXN0KSB7CgkJCXJldHVybiBudWxsOwoJCX0KCgkJcHVibGljIGJvb2xlYW4gdW5kZXJzdGFuZHNSZXF1ZXN0KG9yZy5lY2xpcHNlLmdlZi5SZXF1ZXN0IHJlcXVlc3QpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX0pOwoJq0VYUEFORCB4cHQ6OmRpYWdyYW06OmVkaXRwYXJ0czo6Q29tbW9uOjpiZWhhdmlvdXIgRk9SIHRoaXMtuwqrRU5EREVGSU5FuwoKq0RFRklORSByZWZyZXNoQm91bmRzIEZPUiBnbWZnZW46Okdlbk5vZGVMYWJlbC27CgmrSUYgaXNTdG9yaW5nQ2hpbGRQb3NpdGlvbnMobm9kZSktuwoJCatFWFBBTkQgeHB0OjpDb21tb246OmdlbmVyYXRlZE1lbWJlckNvbW1lbnS7CgkJcHJvdGVjdGVkIHZvaWQgcmVmcmVzaEJvdW5kcygpIHsKCQkJaW50IHdpZHRoID0gKChJbnRlZ2VyKSBnZXRTdHJ1Y3R1cmFsRmVhdHVyZVZhbHVlKG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLm5vdGF0aW9uLk5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0U2l6ZV9XaWR0aCgpKSkuaW50VmFsdWUoKTsKCQkJaW50IGhlaWdodCA9ICgoSW50ZWdlcikgZ2V0U3RydWN0dXJhbEZlYXR1cmVWYWx1ZShvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5Ob3RhdGlvblBhY2thZ2UuZUlOU1RBTkNFLmdldFNpemVfSGVpZ2h0KCkpKS5pbnRWYWx1ZSgpOwoJCQlvcmcuZWNsaXBzZS5kcmF3MmQuZ2VvbWV0cnkuRGltZW5zaW9uIHNpemUgPSBuZXcgb3JnLmVjbGlwc2UuZHJhdzJkLmdlb21ldHJ5LkRpbWVuc2lvbih3aWR0aCwgaGVpZ2h0KTsKCQkJaW50IHggPSAoKEludGVnZXIpIGdldFN0cnVjdHVyYWxGZWF0dXJlVmFsdWUob3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRMb2NhdGlvbl9YKCkpKS5pbnRWYWx1ZSgpOwoJCQlpbnQgeSA9ICgoSW50ZWdlcikgZ2V0U3RydWN0dXJhbEZlYXR1cmVWYWx1ZShvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5Ob3RhdGlvblBhY2thZ2UuZUlOU1RBTkNFLmdldExvY2F0aW9uX1koKSkpLmludFZhbHVlKCk7CgkJCW9yZy5lY2xpcHNlLmRyYXcyZC5nZW9tZXRyeS5Qb2ludCBsb2MgPSBuZXcgb3JnLmVjbGlwc2UuZHJhdzJkLmdlb21ldHJ5LlBvaW50KHgsIHkpOwoJCQkoKG9yZy5lY2xpcHNlLmdlZi5HcmFwaGljYWxFZGl0UGFydCkgZ2V0UGFyZW50KCkpLnNldExheW91dENvbnN0cmFpbnQodGhpcywgZ2V0RmlndXJlKCksIG5ldyBvcmcuZWNsaXBzZS5kcmF3MmQuZ2VvbWV0cnkuUmVjdGFuZ2xlKGxvYywgc2l6ZSkpOwoJCX0KCatFTkRJRi27CqtFTkRERUZJTkW7CgqrREVGSU5FIGhhbmRsZU5vdGlmaWNhdGlvbkV2ZW50Qm9keSBGT1IgZ21mZ2VuOjpHZW5Ob2RlTGFiZWwtuwoJT2JqZWN0IGZlYXR1cmUgPSBldmVudC5nZXRGZWF0dXJlKCk7CgmrSUYgaXNTdG9yaW5nQ2hpbGRQb3NpdGlvbnMobm9kZSktuwoJCatFWFBBTkQgeHB0OjpkaWFncmFtOjplZGl0cGFydHM6OkNvbW1vbjo6aGFuZGxlQm91bmRzIEZPUiB0aGlzLbsKCatFTkRJRi27CgmrRVhQQU5EIHhwdDo6ZGlhZ3JhbTo6ZWRpdHBhcnRzOjpDb21tb246OmhhbmRsZVRleHQgRk9SIHRoaXMtuwoJc3VwZXIuaGFuZGxlTm90aWZpY2F0aW9uRXZlbnQoZXZlbnQpOwqrRU5EREVGSU5Fuw==