cGFja2FnZSBvcmcuZWNsaXBzZS51aS5leHRlcm5hbHRvb2xzLmludGVybmFsLnVpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSAyMDAyIElCTSBDb3JwLiBhbmQgb3RoZXJzLgpBbGwgcmlnaHRzIHJlc2VydmVkLiCgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYwLjUKd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjA1Lmh0bWwKoApDb250cmlidXRvcnM6CioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmltcG9ydCBqYXZhLm5ldC4qOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuSURpYWxvZ0NvbnN0YW50czsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuSW1hZ2U7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy4qOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuZXh0ZXJuYWx0b29scy5pbnRlcm5hbC5jb3JlLio7CgovKioKICogQSB3aWRnZXQgZ3JvdXAgZm9yIHRoZSBqYXJzIHRhYiBvZiB0aGUgYW50IGNsYXNzcGF0aCBwcmVmZXJlbmNlIHBhZ2UuCiAqLwpwdWJsaWMgY2xhc3MgQ2xhc3NwYXRoUGFnZSBleHRlbmRzIEFudFBhZ2UgewoJLy9idXR0b24gY29uc3RhbnRzCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQUREX0pBUl9CVVRUT04gPSBJRGlhbG9nQ29uc3RhbnRzLkNMSUVOVF9JRCArIDE7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQUREX0ZPTERFUl9CVVRUT04gPQoJCUlEaWFsb2dDb25zdGFudHMuQ0xJRU5UX0lEICsgMjsKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBSRU1PVkVfQlVUVE9OID0gSURpYWxvZ0NvbnN0YW50cy5DTElFTlRfSUQgKyAzOwoKCXB1YmxpYyBDbGFzc3BhdGhQYWdlKCkgewoJfQoJLyoqCgkgKiBAc2VlIEN1c3RvbWl6ZUFudFBhZ2UjYWRkQnV0dG9uc1RvQnV0dG9uR3JvdXAoQ29tcG9zaXRlKQoJICovCglwcm90ZWN0ZWQgdm9pZCBhZGRCdXR0b25zVG9CdXR0b25Hcm91cChDb21wb3NpdGUgcGFyZW50KSB7CgkJY3JlYXRlQnV0dG9uKHBhcmVudCwgIkNsYXNzcGF0aFBhZ2UuYWRkSmFyQnV0dG9uVGl0bGUiLCBBRERfSkFSX0JVVFRPTik7IC8vJE5PTi1OTFMtMSQ7CgkJY3JlYXRlQnV0dG9uKHBhcmVudCwgIkNsYXNzcGF0aFBhZ2UuYWRkRm9sZGVyQnV0dG9uVGl0bGUiLCBBRERfRk9MREVSX0JVVFRPTik7IC8vJE5PTi1OTFMtMSQ7CgkJY3JlYXRlU2VwYXJhdG9yKHBhcmVudCk7CgkJY3JlYXRlQnV0dG9uKHBhcmVudCwgIkNsYXNzcGF0aFBhZ2UucmVtb3ZlQnV0dG9uVGl0bGUiLCBSRU1PVkVfQlVUVE9OKTsgLy8kTk9OLU5MUy0xJDsKCX0KCXByaXZhdGUgdm9pZCBhZGRGb2xkZXJCdXR0b25QcmVzc2VkKCkgewoJCURpcmVjdG9yeURpYWxvZyBkaWFsb2cgPQoJCQluZXcgRGlyZWN0b3J5RGlhbG9nKHRhYmxlVmlld2VyLmdldENvbnRyb2woKS5nZXRTaGVsbCgpKTsKCQlTdHJpbmcgcmVzdWx0ID0gZGlhbG9nLm9wZW4oKTsKCQlpZiAocmVzdWx0ICE9IG51bGwpIHsKCQkJdHJ5IHsKCQkJCVVSTCB1cmwgPSBuZXcgVVJMKCJmaWxlOiIgKyByZXN1bHQgKyAiLyIpOyAvLyROT04tTkxTLTIkOy8vJE5PTi1OTFMtMSQ7CgkJCQljb250ZW50UHJvdmlkZXIuYWRkKHVybCk7CgkJCX0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7CgkJCX0KCQl9Cgl9Cglwcml2YXRlIHZvaWQgYWRkSmFyQnV0dG9uUHJlc3NlZCgpIHsKCQlGaWxlRGlhbG9nIGRpYWxvZyA9IG5ldyBGaWxlRGlhbG9nKHRhYmxlVmlld2VyLmdldENvbnRyb2woKS5nZXRTaGVsbCgpKTsKCQlkaWFsb2cuc2V0RmlsdGVyRXh0ZW5zaW9ucyhuZXcgU3RyaW5nW10geyAiKi5qYXIiIH0pOyAvLyROT04tTkxTLTEkOwoJCVN0cmluZyByZXN1bHQgPSBkaWFsb2cub3BlbigpOwoJCWlmIChyZXN1bHQgIT0gbnVsbCkgewoJCQl0cnkgewoJCQkJVVJMIHVybCA9IG5ldyBVUkwoImZpbGU6IiArIHJlc3VsdCk7IC8vJE5PTi1OTFMtMSQ7CgkJCQljb250ZW50UHJvdmlkZXIuYWRkKHVybCk7CgkJCX0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7CgkJCX0KCQl9Cgl9CgkvKioKCSAqIEBzZWUgQ3VzdG9taXplQW50UGFnZSNidXR0b25QcmVzc2VkKGludCkKCSAqLwoJcHJvdGVjdGVkIHZvaWQgYnV0dG9uUHJlc3NlZChpbnQgYnV0dG9uSWQpIHsKCQlzd2l0Y2ggKGJ1dHRvbklkKSB7CgkJCWNhc2UgQUREX0pBUl9CVVRUT04gOgoJCQkJYWRkSmFyQnV0dG9uUHJlc3NlZCgpOwoJCQkJYnJlYWs7CgkJCWNhc2UgQUREX0ZPTERFUl9CVVRUT04gOgoJCQkJYWRkRm9sZGVyQnV0dG9uUHJlc3NlZCgpOwoJCQkJYnJlYWs7CgkJCWNhc2UgUkVNT1ZFX0JVVFRPTiA6CgkJCQlyZW1vdmVCdXR0b25QcmVzc2VkKCk7CgkJCQlicmVhazsKCQl9Cgl9CgkvKioKCSAqIENyZWF0ZXMgYW5kIHJldHVybnMgYSB0YWIgaXRlbSB0aGF0IGNvbnRhaW5zIHRoaXMgd2lkZ2V0IGdyb3VwLgoJICovCglwdWJsaWMgVGFiSXRlbSBjcmVhdGVUYWJJdGVtKFRhYkZvbGRlciBmb2xkZXIpIHsKCQlUYWJJdGVtIGl0ZW0gPSBuZXcgVGFiSXRlbShmb2xkZXIsIFNXVC5OT05FKTsKCQlpdGVtLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiQ2xhc3NwYXRoUGFnZS50aXRsZSIpKTsgLy8kTk9OLU5MUy0xJDsKCQlmaW5hbCBJbWFnZSBpbWFnZSA9CgkJCUV4dGVybmFsVG9vbHNQbHVnaW4KCQkJCS5nZXREZWZhdWx0KCkKCQkJCS5nZXRJbWFnZURlc2NyaXB0b3IoRXh0ZXJuYWxUb29sc1BsdWdpbi5JTUdfQ0xBU1NQQVRIKQoJCQkJLmNyZWF0ZUltYWdlKCk7CgkJaXRlbS5zZXRJbWFnZShpbWFnZSk7CgkJaXRlbS5zZXREYXRhKHRoaXMpOwoJCWl0ZW0uc2V0Q29udHJvbChjcmVhdGVDb250cm9sKGZvbGRlcikpOwoJCWl0ZW0uYWRkRGlzcG9zZUxpc3RlbmVyKG5ldyBEaXNwb3NlTGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldERpc3Bvc2VkKERpc3Bvc2VFdmVudCBlKSB7CgkJCQlpZiAoaW1hZ2UgIT0gbnVsbCkKCQkJCQlpbWFnZS5kaXNwb3NlKCk7CgkJCX0KCQl9KTsKCgkJcmV0dXJuIGl0ZW07Cgl9Cgp9