cGFja2FnZSBvcmcuZWNsaXBzZS51aS5leHRlcm5hbHRvb2xzLmludGVybmFsLnVpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSAyMDAyIElCTSBDb3JwLiBhbmQgb3RoZXJzLgpBbGwgcmlnaHRzIHJlc2VydmVkLiCgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYwLjUKd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjA1Lmh0bWwKoApDb250cmlidXRvcnM6CioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmltcG9ydCBqYXZhLnV0aWwuKjsKCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5wcmVmZXJlbmNlLlByZWZlcmVuY2VDb252ZXJ0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS50ZXh0Lio7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS51dGlsLio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuY3VzdG9tLlN0eWxlUmFuZ2U7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkRpc3BsYXk7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5leHRlcm5hbHRvb2xzLmludGVybmFsLmNvcmUuKjsKCi8qKgogKiBIb2xkcyBvbnRvIG1lc3NhZ2VzIGdlbmVyYXRlZCBieSB0aGUgZXhlY3V0aW9uIG9uIGFuCiAqIGV4dGVybmFsIHRvb2wuCiAqLwpwdWJsaWMgY2xhc3MgTG9nQ29uc29sZURvY3VtZW50IHsKCS8vIGNsYXNzIHZhcmlhYmxlcyB0aGF0IGhhbmRsZSB0aGUgY29sb3JzIGFuZCB0aGUgZm9udAoJcHJpdmF0ZSBzdGF0aWMgQ29sb3IgRVJST1JfQ09MT1I7Cglwcml2YXRlIHN0YXRpYyBDb2xvciBXQVJOX0NPTE9SOwoJcHJpdmF0ZSBzdGF0aWMgQ29sb3IgSU5GT19DT0xPUjsKCXByaXZhdGUgc3RhdGljIENvbG9yIFZFUkJPU0VfQ09MT1I7Cglwcml2YXRlIHN0YXRpYyBDb2xvciBERUJVR19DT0xPUjsKCS8qcGFja2FnZSovIHN0YXRpYyBGb250IEFOVF9GT05UOwoJCglwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNU0dfRVJSID0gMDsKCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1TR19XQVJOID0gMTA7CglwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNU0dfSU5GTyA9IDIwOwoJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTVNHX1ZFUkJPU0UgPSAzMDsKCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1TR19ERUJVRyA9IDQwOwoJCglwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2dDb25zb2xlRG9jdW1lbnQgaW5zdGFuY2UgPSBuZXcgTG9nQ29uc29sZURvY3VtZW50KCk7CgkKCXByaXZhdGUgTG9nUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBjaGFuZ2VMaXN0ZW5lcjsKCgkvKnBhY2thZ2UqLyBBcnJheUxpc3Qgdmlld3MgPSBuZXcgQXJyYXlMaXN0KCk7Cglwcml2YXRlIERvY3VtZW50IGRvY3VtZW50OwoJcHJpdmF0ZSBBcnJheUxpc3Qgc3R5bGVSYW5nZXM7CgkKCS8vIFN0cnVjdHVyZSB0byBzdG9yZSB0aGUgdGV4dHdpZGdldCBpbmRleCBpbmZvcm1hdGlvbgoJcHJpdmF0ZSBPdXRwdXRTdHJ1Y3R1cmVFbGVtZW50IHJvb3QgPSBudWxsOwkKCXByaXZhdGUgT3V0cHV0U3RydWN0dXJlRWxlbWVudCBjdXJyZW50RWxlbWVudCA9IG51bGw7CgoJcHJpdmF0ZSBMb2dDb25zb2xlRG9jdW1lbnQoKSB7CgkJY2hhbmdlTGlzdGVuZXIgPSBuZXcgTG9nUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigpOwoJCWRvY3VtZW50ID0gbmV3IERvY3VtZW50KCk7CgkJc3R5bGVSYW5nZXMgPSBuZXcgQXJyYXlMaXN0KDUpOwoJCWluaXRpYWxpemVPdXRwdXRTdHJ1Y3R1cmUoKTsJCQoJfQoKCXB1YmxpYyB2b2lkIGFwcGVuZChmaW5hbCBTdHJpbmcgbWVzc2FnZSwgZmluYWwgaW50IHByaW9yaXR5KSB7CgkJaWYgKHZpZXdzLnNpemUoKSA9PSAwKQoJCQlyZXR1cm47CgkJKChMb2dDb25zb2xlVmlldyl2aWV3cy5nZXQoMCkpLmdldFZpZXdTaXRlKCkuZ2V0U2hlbGwoKS5nZXREaXNwbGF5KCkuc3luY0V4ZWMobmV3IFJ1bm5hYmxlKCkgewoJCQlwdWJsaWMgdm9pZCBydW4oKSB7CgkJCQlpbnQgc3RhcnQgPSBnZXREb2N1bWVudCgpLmdldExlbmd0aCgpOwoJCQkJdHJ5IHsKCQkJCQkvLyBBcHBlbmQgbmV3IG1lc3NhZ2UgdG8gdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnQuIFRoaXMKCQkJCQkvLyBhdm9pZHMgY29uc29sZSBmbGlja2VyIHdoZW4gbWVzc2FnZXMgYXJlIGFwcGVuZGVkLgoJCQkJCWdldERvY3VtZW50KCkucmVwbGFjZShzdGFydCwgMCwgbWVzc2FnZSk7CgkJCQl9IGNhdGNoIChCYWRMb2NhdGlvbkV4Y2VwdGlvbiBlKSB7CgkJCQl9CgkJCQlzZXRPdXRwdXRMZXZlbENvbG9yKHByaW9yaXR5LCBzdGFydCwgbWVzc2FnZS5sZW5ndGgoKSk7CgkJCX0KCQl9KTsJCQoJCWZvciAoaW50IGk9MDsgaSA8IHZpZXdzLnNpemUoKTsgaSsrKSB7CgkJCSgoTG9nQ29uc29sZVZpZXcpdmlld3MuZ2V0KGkpKS5hcHBlbmQobWVzc2FnZSwgcHJpb3JpdHkpOwkKCQl9Cgl9CgkKCXByaXZhdGUgdm9pZCBhZGRSYW5nZVN0eWxlKGludCBzdGFydCwgaW50IGxlbmd0aCwgQ29sb3IgY29sb3IpIHsKCQkvLyBEb24ndCBhZGQgYSBTdHlsZVJhbmdlIGlmIHRoZSBsZW5ndGggaXMgMC4KCQlpZiAobGVuZ3RoID09IDApCgkJCXJldHVybjsJCgkJaWYgKHN0eWxlUmFuZ2VzLnNpemUoKSAhPSAwKSB7CgkJCVN0eWxlUmFuZ2UgbGFzdFN0eWxlID0gKFN0eWxlUmFuZ2UpIHN0eWxlUmFuZ2VzLmdldChzdHlsZVJhbmdlcy5zaXplKCktMSk7CgkJCWlmIChjb2xvci5lcXVhbHMobGFzdFN0eWxlLmZvcmVncm91bmQpKQoJCQkJbGFzdFN0eWxlLmxlbmd0aCArPSBsZW5ndGg7CgkJCWVsc2UKCQkJCXN0eWxlUmFuZ2VzLmFkZChuZXcgU3R5bGVSYW5nZShzdGFydCwgbGVuZ3RoLCBjb2xvciwgbnVsbCkpOwoJCX0gZWxzZQoJCQlzdHlsZVJhbmdlcy5hZGQobmV3IFN0eWxlUmFuZ2Uoc3RhcnQsIGxlbmd0aCwgY29sb3IsIG51bGwpKTsKCQlTdHlsZVJhbmdlW10gc3R5bGVBcnJheSA9IChTdHlsZVJhbmdlW10pIHN0eWxlUmFuZ2VzLnRvQXJyYXkobmV3IFN0eWxlUmFuZ2Vbc3R5bGVSYW5nZXMuc2l6ZSgpXSk7CQkJCgkJZm9yIChpbnQgaSA9IDA7IGkgPCB2aWV3cy5zaXplKCk7IGkrKykgewoJCQlUZXh0Vmlld2VyIHR2ID0gKChMb2dDb25zb2xlVmlldyl2aWV3cy5nZXQoaSkpLmdldFRleHRWaWV3ZXIoKTsKCQkJaWYgKHR2ICE9IG51bGwpCgkJCQl0di5nZXRUZXh0V2lkZ2V0KCkuc2V0U3R5bGVSYW5nZXMoc3R5bGVBcnJheSk7CgkJfQoJfQoJCglwdWJsaWMgdm9pZCBjbGVhck91dHB1dCgpIHsKCQlkb2N1bWVudC5zZXQoIiIpOwoJCXN0eWxlUmFuZ2VzLmNsZWFyKCk7CgkJLy8gdGhlIHRyZWUgY2FuIGJlIG51bGwgaWYgI2NyZWF0ZVBhcnRDb250cm9sIGhhcyBub3QgY2FsbGVkIHlldCwgCgkJLy8gaS5lLiBpZiB0aGUgY29uc29sZSBleGlzdHMgYnV0IGhhcyBuZXZlciBiZWVuIHNob3duIHNvIGZhcgoJCWluaXRpYWxpemVPdXRwdXRTdHJ1Y3R1cmUoKTsKCQlyZWZyZXNoVHJlZSgpOwoJfQkKCglwdWJsaWMgdm9pZCByZWZyZXNoVHJlZSgpIHsKCQlmb3IoaW50IGk9MDsgaTx2aWV3cy5zaXplKCk7IGkrKykgewoJCQkoKExvZ0NvbnNvbGVWaWV3KXZpZXdzLmdldChpKSkucmVmcmVzaFRyZWUoKTsKCQl9Cgl9CQoJCgkvKioKCSAqIFJldHVybnMgdGhlIGNvbG9yIHVzZWQgZm9yIGVycm9yIG1lc3NhZ2VzIG9uIHRoZSBsb2cgY29uc29sZS4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgQ29sb3IgZ2V0RXJyb3JDb2xvcigpIHsKCQlpZiAoRVJST1JfQ09MT1IgPT0gbnVsbCB8fCBFUlJPUl9DT0xPUi5pc0Rpc3Bvc2VkKCkpCgkJCUVSUk9SX0NPTE9SID0gbmV3IENvbG9yKG51bGwsIFByZWZlcmVuY2VDb252ZXJ0ZXIuZ2V0Q29sb3IoRXh0ZXJuYWxUb29sc1BsdWdpbi5nZXREZWZhdWx0KCkuZ2V0UHJlZmVyZW5jZVN0b3JlKCksSVByZWZlcmVuY2VDb25zdGFudHMuQ09OU09MRV9FUlJPUl9SR0IpKTsKCQlyZXR1cm4gRVJST1JfQ09MT1I7Cgl9CgkvKioKCSAqIFJldHVybnMgdGhlIGNvbG9yIHVzZWQgZm9yIHdhcm5pbmcgbWVzc2FnZXMgb24gdGhlIGxvZyBjb25zb2xlLgoJICovCglwcml2YXRlIHN0YXRpYyBDb2xvciBnZXRXYXJuQ29sb3IoKSB7CgkJaWYgKFdBUk5fQ09MT1IgPT0gbnVsbCB8fCBXQVJOX0NPTE9SLmlzRGlzcG9zZWQoKSkKCQkJV0FSTl9DT0xPUiA9IG5ldyBDb2xvcihudWxsLCBQcmVmZXJlbmNlQ29udmVydGVyLmdldENvbG9yKEV4dGVybmFsVG9vbHNQbHVnaW4uZ2V0RGVmYXVsdCgpLmdldFByZWZlcmVuY2VTdG9yZSgpLElQcmVmZXJlbmNlQ29uc3RhbnRzLkNPTlNPTEVfV0FSTklOR19SR0IpKTsJCgkJcmV0dXJuIFdBUk5fQ09MT1I7Cgl9CgkvKioKCSAqIFJldHVybnMgdGhlIGNvbG9yIHVzZWQgZm9yIGluZm8gKG5vcm1hbCkgbWVzc2FnZXMgb24gdGhlIGxvZyBjb25zb2xlLgoJICovCglwcml2YXRlIHN0YXRpYyBDb2xvciBnZXRJbmZvQ29sb3IoKSB7CgkJaWYgKElORk9fQ09MT1IgPT0gbnVsbCB8fCBJTkZPX0NPTE9SLmlzRGlzcG9zZWQoKSkKCQkJSU5GT19DT0xPUiA9IG5ldyBDb2xvcihudWxsLCBQcmVmZXJlbmNlQ29udmVydGVyLmdldENvbG9yKEV4dGVybmFsVG9vbHNQbHVnaW4uZ2V0RGVmYXVsdCgpLmdldFByZWZlcmVuY2VTdG9yZSgpLElQcmVmZXJlbmNlQ29uc3RhbnRzLkNPTlNPTEVfSU5GT19SR0IpKTsJCQoJCXJldHVybiBJTkZPX0NPTE9SOwoJfQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBjb2xvciB1c2VkIGZvciB2ZXJib3NlIG1lc3NhZ2VzIG9uIHRoZSBsb2cgY29uc29sZS4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgQ29sb3IgZ2V0VmVyYm9zZUNvbG9yKCkgewoJCWlmIChWRVJCT1NFX0NPTE9SID09IG51bGwgfHwgVkVSQk9TRV9DT0xPUi5pc0Rpc3Bvc2VkKCkpCgkJCVZFUkJPU0VfQ09MT1IgPSBuZXcgQ29sb3IobnVsbCwgUHJlZmVyZW5jZUNvbnZlcnRlci5nZXRDb2xvcihFeHRlcm5hbFRvb2xzUGx1Z2luLmdldERlZmF1bHQoKS5nZXRQcmVmZXJlbmNlU3RvcmUoKSxJUHJlZmVyZW5jZUNvbnN0YW50cy5DT05TT0xFX1ZFUkJPU0VfUkdCKSk7CQkKCQlyZXR1cm4gVkVSQk9TRV9DT0xPUjsKCX0KCS8qKgoJICogUmV0dXJucyB0aGUgY29sb3IgdXNlZCBmb3IgZGVidWcgbWVzc2FnZXMgb24gdGhlIGxvZyBjb25zb2xlLgoJICovCglwcml2YXRlIHN0YXRpYyBDb2xvciBnZXREZWJ1Z0NvbG9yKCkgewoJCWlmIChERUJVR19DT0xPUiA9PSBudWxsIHx8IERFQlVHX0NPTE9SLmlzRGlzcG9zZWQoKSkKCQkJREVCVUdfQ09MT1IgPSBuZXcgQ29sb3IobnVsbCwgUHJlZmVyZW5jZUNvbnZlcnRlci5nZXRDb2xvcihFeHRlcm5hbFRvb2xzUGx1Z2luLmdldERlZmF1bHQoKS5nZXRQcmVmZXJlbmNlU3RvcmUoKSxJUHJlZmVyZW5jZUNvbnN0YW50cy5DT05TT0xFX0RFQlVHX1JHQikpOwkKCQlyZXR1cm4gREVCVUdfQ09MT1I7Cgl9CgkKCXB1YmxpYyBEaXNwbGF5IGdldERpc3BsYXkoKSB7CgkJaWYgKCFoYXNWaWV3cygpKSAKCQkJcmV0dXJuIG51bGw7CgkJcmV0dXJuICgoTG9nQ29uc29sZVZpZXcpdmlld3MuZ2V0KDApKS5nZXRTaXRlKCkuZ2V0U2hlbGwoKS5nZXREaXNwbGF5KCk7CQoJfQoJCgkvKnBhY2thZ2UqLyBEb2N1bWVudCBnZXREb2N1bWVudCgpIHsKCQlyZXR1cm4gZG9jdW1lbnQ7CQoJfQoJCgkvKnBhY2thZ2UqLyAgQXJyYXlMaXN0IGdldFN0eWxlUmFuZ2VzKCkgewoJCXJldHVybiBzdHlsZVJhbmdlczsJCgl9CgkKCXB1YmxpYyBBcnJheUxpc3QgZ2V0Vmlld3MoKSB7CgkJcmV0dXJuIHZpZXdzOwoJfQoJCgkvKnBhY2thZ2UqLyBPdXRwdXRTdHJ1Y3R1cmVFbGVtZW50IGdldFJvb3QoKSB7CgkJcmV0dXJuIHJvb3Q7CQoJfQoJCglwdWJsaWMgYm9vbGVhbiBoYXNWaWV3cygpIHsKCQlyZXR1cm4gKHZpZXdzLnNpemUoKSA+IDApOwkKCX0KCQoJcHVibGljIHZvaWQgaW5pdGlhbGl6ZU91dHB1dFN0cnVjdHVyZSgpIHsKCQkvLyByb290IGlzIHRoZSBmaXJzdCBlbGVtZW50IG9mIHRoZSBzdHJ1Y3R1cmU6IGl0IGlzIGEgZmFrZSBzbyBpdCBkb2Vzbid0IG5lZWQgYSByZWFsIG5hbWUKCQlyb290ID0gbmV3IE91dHB1dFN0cnVjdHVyZUVsZW1lbnQoIi0tIHJvb3QgLS0iKTsgLy8gJE5PTi1OTFMtMSQKCQljdXJyZW50RWxlbWVudCA9IG5ldyBPdXRwdXRTdHJ1Y3R1cmVFbGVtZW50KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkxvZ0NvbnNvbGVEb2N1bWVudC5leHRlcm5hbFRvb2wiKSwgcm9vdCwgMCk7IC8vICROT04tTkxTLTEkCgkJCgkJZm9yIChpbnQgaT0wOyBpIDwgdmlld3Muc2l6ZSgpOyBpKyspIHsKCQkJTG9nQ29uc29sZVZpZXcgdmlldyA9IChMb2dDb25zb2xlVmlldyl2aWV3cy5nZXQoaSk7CgkJCWlmICh2aWV3LmdldFRyZWVWaWV3ZXIoKSAhPSBudWxsKQoJCQkJdmlldy5pbml0aWFsaXplVHJlZUlucHV0KCk7CgkJfQoJfQoJCglwdWJsaWMgdm9pZCByZWdpc3RlclZpZXcoTG9nQ29uc29sZVZpZXcgdmlldykgewoJCWlmICghaGFzVmlld3MoKSkgewoJCQkvLyBmaXJzdCB0aW1lIHRoZXJlIGlzIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3M6IGludGFudGlhdGUgdGhlIGZvbnQgYW5kIHJlZ2lzdGVyIHRoZSBsaXN0ZW5lcgoJCQlBTlRfRk9OVCA9IG5ldyBGb250KG51bGwsIFByZWZlcmVuY2VDb252ZXJ0ZXIuZ2V0Rm9udERhdGEoRXh0ZXJuYWxUb29sc1BsdWdpbi5nZXREZWZhdWx0KCkuZ2V0UHJlZmVyZW5jZVN0b3JlKCksSVByZWZlcmVuY2VDb25zdGFudHMuQ09OU09MRV9GT05UKSk7CgkJCUV4dGVybmFsVG9vbHNQbHVnaW4uZ2V0RGVmYXVsdCgpLmdldFByZWZlcmVuY2VTdG9yZSgpLmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoY2hhbmdlTGlzdGVuZXIpOwoJCX0KCQl2aWV3cy5hZGQodmlldyk7CQoJfQoJCglwdWJsaWMgdm9pZCB1bnJlZ2lzdGVyVmlldyhMb2dDb25zb2xlVmlldyB2aWV3KSB7CgkJdmlld3MucmVtb3ZlKHZpZXcpOwkKCQlpZiAoISBoYXNWaWV3cygpKSB7CgkJCS8vIGFsbCB0aGUgY29uc29sZXMgYXJlIGRpcG9zZWQ6IHdlIGNhbiBkaXNwb3NlIHRoZSBmb250IGFuZCByZW1vdmUgdGhlIHByb3BlcnR5IGxpc3RlbmVyCgkJCUFOVF9GT05ULmRpc3Bvc2UoKTsKCQkJRXh0ZXJuYWxUb29sc1BsdWdpbi5nZXREZWZhdWx0KCkuZ2V0UHJlZmVyZW5jZVN0b3JlKCkucmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihjaGFuZ2VMaXN0ZW5lcik7CgkJfQoJfQoJCglwdWJsaWMgc3RhdGljIExvZ0NvbnNvbGVEb2N1bWVudCBnZXRJbnN0YW5jZSgpIHsKCQlyZXR1cm4gaW5zdGFuY2U7CQoJfQoJCglwdWJsaWMgT3V0cHV0U3RydWN0dXJlRWxlbWVudCBnZXRDdXJyZW50T3V0cHV0U3RydWN0dXJlRWxlbWVudCgpIHsKCQlyZXR1cm4gY3VycmVudEVsZW1lbnQ7Cgl9CglwdWJsaWMgdm9pZCBzZXRDdXJyZW50T3V0cHV0U3RydWN0dXJlRWxlbWVudChPdXRwdXRTdHJ1Y3R1cmVFbGVtZW50IG91dHB1dCkgewoJCXRoaXMuY3VycmVudEVsZW1lbnQgPSBvdXRwdXQ7Cgl9CgkvKnBhY2thZ2UqLyB2b2lkIHNldE91dHB1dExldmVsQ29sb3IoaW50IGxldmVsLCBpbnQgc3RhcnQsIGludCBlbmQpIHsKCQlzd2l0Y2ggKGxldmVsKSB7CgkJCWNhc2UgTG9nQ29uc29sZURvY3VtZW50Lk1TR19FUlI6IAoJCQkJYWRkUmFuZ2VTdHlsZShzdGFydCwgZW5kLCBnZXRFcnJvckNvbG9yKCkpOyAKCQkJCWJyZWFrOwoJCQljYXNlIExvZ0NvbnNvbGVEb2N1bWVudC5NU0dfV0FSTjogCgkJCQlhZGRSYW5nZVN0eWxlKHN0YXJ0LCBlbmQsIGdldFdhcm5Db2xvcigpKTsgCgkJCQlicmVhazsKCQkJY2FzZSBMb2dDb25zb2xlRG9jdW1lbnQuTVNHX0lORk86IAoJCQkJYWRkUmFuZ2VTdHlsZShzdGFydCwgZW5kLCBnZXRJbmZvQ29sb3IoKSk7IAoJCQkJYnJlYWs7CgkJCWNhc2UgTG9nQ29uc29sZURvY3VtZW50Lk1TR19WRVJCT1NFOiAKCQkJCWFkZFJhbmdlU3R5bGUoc3RhcnQsIGVuZCwgZ2V0VmVyYm9zZUNvbG9yKCkpOyAKCQkJCWJyZWFrOwoJCQljYXNlIExvZ0NvbnNvbGVEb2N1bWVudC5NU0dfREVCVUc6IAoJCQkJYWRkUmFuZ2VTdHlsZShzdGFydCwgZW5kLCBnZXREZWJ1Z0NvbG9yKCkpOyAKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OiAKCQkJCWFkZFJhbmdlU3R5bGUoc3RhcnQsIGVuZCwgZ2V0SW5mb0NvbG9yKCkpOwoJCX0KCX0KCQoJLyoqCgkgKiBSZXBsYWNlcyB0aGUgb2xkIGNvbG9yIHdpdGggdGhlIG5ldyBvbmUgaW4gYWxsIHN0eWxlIHJhbmdlcywKCSAqLwoJcHJpdmF0ZSB2b2lkIHVwZGF0ZVN0eWxlUmFuZ2VzKENvbG9yIG9sZENvbG9yLCBDb2xvciBuZXdDb2xvcikgewoJCWZvciAoaW50IGk9MDsgaTxzdHlsZVJhbmdlcy5zaXplKCk7IGkrKykgewoJCQlTdHlsZVJhbmdlIHJhbmdlID0gKFN0eWxlUmFuZ2Upc3R5bGVSYW5nZXMuZ2V0KGkpOwoJCQlpZiAocmFuZ2UuZm9yZWdyb3VuZCA9PSBvbGRDb2xvcikKCQkJCXJhbmdlLmZvcmVncm91bmQgPSBuZXdDb2xvcjsKCQl9Cgl9CgoJcHJpdmF0ZSBjbGFzcyBMb2dQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIGltcGxlbWVudHMgSVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgewoJCgkJLy8gcHJpdmF0ZSBjb25zdHJ1Y3RvciB0byBlbnN1cmUgdGhlIHNpbmdsZXRvbgoJCXByaXZhdGUgTG9nUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigpIHsKCQl9CgkJCgkJLyoqCgkJICogQHNlZSBJUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciNwcm9wZXJ0eUNoYW5nZShQcm9wZXJ0eUNoYW5nZUV2ZW50KQoJCSAqLwoJCXB1YmxpYyB2b2lkIHByb3BlcnR5Q2hhbmdlKFByb3BlcnR5Q2hhbmdlRXZlbnQgZXZlbnQpIHsKCQkJCVN0cmluZyBwcm9wZXJ0eU5hbWU9IGV2ZW50LmdldFByb3BlcnR5KCk7CgkJCQoJCQkJaWYgKHByb3BlcnR5TmFtZS5lcXVhbHMoSVByZWZlcmVuY2VDb25zdGFudHMuQ09OU09MRV9FUlJPUl9SR0IpKSB7CgkJCQkJaWYgKExvZ0NvbnNvbGVEb2N1bWVudC5FUlJPUl9DT0xPUiA9PSBudWxsKQoJCQkJCQlyZXR1cm47CgkJCQkJQ29sb3IgdGVtcCA9IGdldEVycm9yQ29sb3IoKTsKCQkJCQlMb2dDb25zb2xlRG9jdW1lbnQuRVJST1JfQ09MT1IgPSBUb29sc1ByZWZlcmVuY2VQYWdlLmdldFByZWZlcmVuY2VDb2xvcihJUHJlZmVyZW5jZUNvbnN0YW50cy5DT05TT0xFX0VSUk9SX1JHQik7CgkJCQkJdXBkYXRlU3R5bGVSYW5nZXModGVtcCwgZ2V0RXJyb3JDb2xvcigpKTsKCQkJCQl0ZW1wLmRpc3Bvc2UoKTsKCQkJCX0gZWxzZSBpZiAocHJvcGVydHlOYW1lLmVxdWFscyhJUHJlZmVyZW5jZUNvbnN0YW50cy5DT05TT0xFX1dBUk5JTkdfUkdCKSkgewoJCQkJCWlmIChMb2dDb25zb2xlRG9jdW1lbnQuV0FSTl9DT0xPUiA9PSBudWxsKQoJCQkJCQlyZXR1cm47CgkJCQkJQ29sb3IgdGVtcCA9IGdldFdhcm5Db2xvcigpOwoJCQkJCUxvZ0NvbnNvbGVEb2N1bWVudC5XQVJOX0NPTE9SID0gVG9vbHNQcmVmZXJlbmNlUGFnZS5nZXRQcmVmZXJlbmNlQ29sb3IoSVByZWZlcmVuY2VDb25zdGFudHMuQ09OU09MRV9XQVJOSU5HX1JHQik7CgkJCQkJdXBkYXRlU3R5bGVSYW5nZXModGVtcCwgZ2V0V2FybkNvbG9yKCkpOwoJCQkJCXRlbXAuZGlzcG9zZSgpOwoJCQkJfSBlbHNlIGlmIChwcm9wZXJ0eU5hbWUuZXF1YWxzKElQcmVmZXJlbmNlQ29uc3RhbnRzLkNPTlNPTEVfSU5GT19SR0IpKSB7CgkJCQkJaWYgKExvZ0NvbnNvbGVEb2N1bWVudC5JTkZPX0NPTE9SID09IG51bGwpCgkJCQkJCXJldHVybjsKCQkJCQlDb2xvciB0ZW1wID0gZ2V0SW5mb0NvbG9yKCk7CgkJCQkJTG9nQ29uc29sZURvY3VtZW50LklORk9fQ09MT1IgPSBUb29sc1ByZWZlcmVuY2VQYWdlLmdldFByZWZlcmVuY2VDb2xvcihJUHJlZmVyZW5jZUNvbnN0YW50cy5DT05TT0xFX0lORk9fUkdCKTsKCQkJCQl1cGRhdGVTdHlsZVJhbmdlcyh0ZW1wLCBnZXRJbmZvQ29sb3IoKSk7CgkJCQkJdGVtcC5kaXNwb3NlKCk7CgkJCQl9IGVsc2UgaWYgKHByb3BlcnR5TmFtZS5lcXVhbHMoSVByZWZlcmVuY2VDb25zdGFudHMuQ09OU09MRV9WRVJCT1NFX1JHQikpIHsKCQkJCQlpZiAoTG9nQ29uc29sZURvY3VtZW50LlZFUkJPU0VfQ09MT1IgPT0gbnVsbCkKCQkJCQkJcmV0dXJuOwoJCQkJCUNvbG9yIHRlbXAgPSBnZXRWZXJib3NlQ29sb3IoKTsKCQkJCQlMb2dDb25zb2xlRG9jdW1lbnQuVkVSQk9TRV9DT0xPUiA9IFRvb2xzUHJlZmVyZW5jZVBhZ2UuZ2V0UHJlZmVyZW5jZUNvbG9yKElQcmVmZXJlbmNlQ29uc3RhbnRzLkNPTlNPTEVfVkVSQk9TRV9SR0IpOwoJCQkJCXVwZGF0ZVN0eWxlUmFuZ2VzKHRlbXAsIGdldFZlcmJvc2VDb2xvcigpKTsKCQkJCQl0ZW1wLmRpc3Bvc2UoKTsKCQkJCX0gZWxzZSBpZiAocHJvcGVydHlOYW1lLmVxdWFscyhJUHJlZmVyZW5jZUNvbnN0YW50cy5DT05TT0xFX0RFQlVHX1JHQikpIHsKCQkJCQlpZiAoTG9nQ29uc29sZURvY3VtZW50LkRFQlVHX0NPTE9SID09IG51bGwpCgkJCQkJCXJldHVybjsKCQkJCQlDb2xvciB0ZW1wID0gZ2V0RGVidWdDb2xvcigpOwoJCQkJCUxvZ0NvbnNvbGVEb2N1bWVudC5ERUJVR19DT0xPUiA9IFRvb2xzUHJlZmVyZW5jZVBhZ2UuZ2V0UHJlZmVyZW5jZUNvbG9yKElQcmVmZXJlbmNlQ29uc3RhbnRzLkNPTlNPTEVfREVCVUdfUkdCKTsKCQkJCQl1cGRhdGVTdHlsZVJhbmdlcyh0ZW1wLCBnZXREZWJ1Z0NvbG9yKCkpOwoJCQkJCXRlbXAuZGlzcG9zZSgpOwoJCQkJfSBlbHNlIGlmIChwcm9wZXJ0eU5hbWUuZXF1YWxzKElQcmVmZXJlbmNlQ29uc3RhbnRzLkNPTlNPTEVfRk9OVCkpIHsKCQkJCQlGb250RGF0YSBkYXRhPSBUb29sc1ByZWZlcmVuY2VQYWdlLmdldENvbnNvbGVGb250RGF0YSgpOwoJCQkJCUZvbnQgdGVtcD0gTG9nQ29uc29sZURvY3VtZW50LkFOVF9GT05UOwoJCQkJCUxvZ0NvbnNvbGVEb2N1bWVudC5BTlRfRk9OVCA9IG5ldyBGb250KERpc3BsYXkuZ2V0Q3VycmVudCgpLCBkYXRhKTsKCQkJCQl0ZW1wLmRpc3Bvc2UoKTsKCQkJCQl1cGRhdGVGb250KCk7CQoJCQkJfSBlbHNlCgkJCQkJcmV0dXJuOwoJCX0KCQoJCS8qKgoJCSAqIENsZWFycyB0aGUgb3V0cHV0IG9mIGFsbCB0aGUgY29uc29sZXMKCQkgKi8KCQlwcml2YXRlIHZvaWQgY2xlYXJPdXRwdXQoKSB7CgkJCUxvZ0NvbnNvbGVEb2N1bWVudC5nZXRJbnN0YW5jZSgpLmNsZWFyT3V0cHV0KCk7CgkJfQoJCQoJCS8qKgoJCSAqIFVwZGF0ZXMgdGVoIGZvbnQgaW4gYWxsIHRoZSBjb25zb2xlcwoJCSAqLwoJCXByaXZhdGUgdm9pZCB1cGRhdGVGb250KCkgewoJCQlmb3IgKEl0ZXJhdG9yIGl0ZXJhdG9yID0gTG9nQ29uc29sZURvY3VtZW50LmdldEluc3RhbmNlKCkuZ2V0Vmlld3MoKS5pdGVyYXRvcigpOyBpdGVyYXRvci5oYXNOZXh0KCk7KQoJCQkJICgoTG9nQ29uc29sZVZpZXcpIGl0ZXJhdG9yLm5leHQoKSkudXBkYXRlRm9udCgpOwoJCX0KCX0KCgp9Cg==