LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQogKiBDb3B5cmlnaHQgKGMpIDIwMTAgQ0VBIExJU1QuDQogKiAgICANCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMNCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMA0KICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQNCiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sDQogKg0KICogQ29udHJpYnV0b3JzOg0KICogICBOaWNvbGFzIEJyb3MgKE1pYS1Tb2Z0d2FyZSkgLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24NCiAqICAgTmljb2xhcyBHdXlvbWFyIChNaWEtU29mdHdhcmUpIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uDQogKiAgIE5pY29sYXMgQnJvcyAoTWlhLVNvZnR3YXJlKSAtIEJ1ZyAzMzk2NjQgLSBvcmcuZWNsaXBzZS5tb2Rpc2NvLmZhY2V0LndpZGdldHMuY2VsbGVkaXRvcnMgQVBJIGNsZWFuaW5nDQogKiAgIE5pY29sYXMgQnJvcyAoTWlhLVNvZnR3YXJlKSAtIEJ1ZyAzMzQ1MzkgLSBbY2VsbGVkaXRvcnNdIGNoYW5nZSBsaXN0ZW5lcg0KICogICBHculnb2lyZSBEdXDpIChNaWEtU29mdHdhcmUpIC0gQnVnIDQyNDEyMiAtIFtUYWJsZV0gSW1hZ2VzLCBmb250cyBhbmQgY29sb3JzIGFyZSBub3Qgc2hhcmVkIGJldHdlZW4gdGhlIGluc3RhbmNlcyBvZiB0YWJsZQ0KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0KcGFja2FnZSBvcmcuZWNsaXBzZS5tb2Rpc2NvLmZhY2V0LndpZGdldHMuY2VsbGVkaXRvcnMuaW50ZXJuYWwuY29yZS5jb21wb3NpdGU7DQoNCmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsNCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsNCmltcG9ydCBqYXZhLnV0aWwuTWFwOw0KaW1wb3J0IGphdmEudXRpbC5NYXAuRW50cnk7DQppbXBvcnQgamF2YS51dGlsLlNldDsNCmltcG9ydCBqYXZhLnV0aWwuVHJlZU1hcDsNCg0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS5FT2JqZWN0Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuTWVzc2FnZURpYWxvZzsNCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5maWVsZGFzc2lzdC5Db21ib0NvbnRlbnRBZGFwdGVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmZpZWxkYXNzaXN0LkNvbnRlbnRQcm9wb3NhbEFkYXB0ZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZmllbGRhc3Npc3QuU2ltcGxlQ29udGVudFByb3Bvc2FsUHJvdmlkZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UubW9kaXNjby5mYWNldC51dGlsLnN3dC5mb250cHJvdmlkZXIuSUZvbnRQcm92aWRlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5tb2Rpc2NvLmZhY2V0LnV0aWwuc3d0LmZvbnRwcm92aWRlci5JRm9udFByb3ZpZGVyRmFjdG9yeTsNCmltcG9ydCBvcmcuZWNsaXBzZS5tb2Rpc2NvLmZhY2V0LndpZGdldHMuY2VsbGVkaXRvcnMuQWJzdHJhY3RDZWxsRWRpdG9yQ29tcG9zaXRlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLm1vZGlzY28uZmFjZXQud2lkZ2V0cy5jZWxsZWRpdG9ycy5pbnRlcm5hbC5NZXNzYWdlczsNCmltcG9ydCBvcmcuZWNsaXBzZS5tb2Rpc2NvLmZhY2V0LndpZGdldHMuaW50ZXJuYWwuQ3VzdG9taXphYmxlTGFiZWxQcm92aWRlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRGlzcG9zZUV2ZW50Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRGlzcG9zZUxpc3RlbmVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuS2V5QWRhcHRlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLktleUV2ZW50Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuTW9kaWZ5RXZlbnQ7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Nb2RpZnlMaXN0ZW5lcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkFkYXB0ZXI7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25FdmVudDsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuRm9udDsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuRm9udERhdGE7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWRMYXlvdXQ7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQnV0dG9uOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbWJvOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db250cm9sOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkRpc3BsYXk7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuRXZlbnQ7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTGlzdGVuZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UudWkuZGlhbG9ncy5FbGVtZW50TGlzdFNlbGVjdGlvbkRpYWxvZzsNCg0KLyoqIEEgY2VsbCBlZGl0b3IgZm9yIHVuYXJ5IHJlZmVyZW5jZXMgKi8NCnB1YmxpYyBjbGFzcyBVbmFyeVJlZmVyZW5jZUNlbGxFZGl0b3JDb21wb3NpdGUgZXh0ZW5kcyBBYnN0cmFjdENlbGxFZGl0b3JDb21wb3NpdGU8RU9iamVjdD4gew0KDQoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEdSSURfREFUQV9IRUlHSFQgPSA1MDsNCglwcml2YXRlIGZpbmFsIEJ1dHRvbiBidXR0b247DQoJcHJpdmF0ZSBmaW5hbCBDb21ibyBjb21ibzsNCglwcml2YXRlIGZpbmFsIENvbnRyb2wgcGFyZW50Q29udHJvbDsNCglwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIEVPYmplY3Q+IGZFbGVtZW50cyA9IG5ldyBUcmVlTWFwPFN0cmluZywgRU9iamVjdD4oKTsNCg0KCS8qKg0KCSAqIEBwYXJhbSBwYXJlbnQNCgkgKiAgICAgICAgICAgIHRoZSBwYXJlbnQgY29tcG9zaXRlDQoJICogQHBhcmFtIGVPYmplY3RzDQoJICogICAgICAgICAgICB0aGUgcG9zc2libGUgY2hvaWNlcw0KCSAqLw0KCXB1YmxpYyBVbmFyeVJlZmVyZW5jZUNlbGxFZGl0b3JDb21wb3NpdGUoZmluYWwgQ29tcG9zaXRlIHBhcmVudCwgZmluYWwgTGlzdDxFT2JqZWN0PiBlT2JqZWN0cykgew0KCQlzdXBlcihwYXJlbnQpOw0KCQl0aGlzLnBhcmVudENvbnRyb2wgPSBwYXJlbnQ7DQoNCgkJQ3VzdG9taXphYmxlTGFiZWxQcm92aWRlciBjdXN0b21pemFibGVMYWJlbFByb3ZpZGVyID0gbmV3IEN1c3RvbWl6YWJsZUxhYmVsUHJvdmlkZXIoKTsNCgkJZm9yIChFT2JqZWN0IGVPYmplY3QgOiBlT2JqZWN0cykgew0KCQkJU3RyaW5nIGxhYmVsID0gY3VzdG9taXphYmxlTGFiZWxQcm92aWRlci5nZXRUZXh0KGVPYmplY3QpOw0KCQkJLy8gZmluZCBhIHVuaXF1ZSBsYWJlbA0KCQkJaWYgKHRoaXMuZkVsZW1lbnRzLmdldChsYWJlbCkgIT0gbnVsbCkgew0KCQkJCWludCBzdWZmaXggPSAyOw0KCQkJCXdoaWxlICh0aGlzLmZFbGVtZW50cy5nZXQobGFiZWwgKyAiICgiICsgc3VmZml4ICsgIikiKSAhPSBudWxsKSB7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJA0KCQkJCQlzdWZmaXgrKzsNCgkJCQl9DQoJCQkJdGhpcy5mRWxlbWVudHMucHV0KGxhYmVsICsgIiAoIiArIHN1ZmZpeCArICIpIiwgZU9iamVjdCk7IC8vJE5PTi1OTFMtMSQvLyROT04tTkxTLTIkDQoJCQl9IGVsc2Ugew0KCQkJCXRoaXMuZkVsZW1lbnRzLnB1dChsYWJlbCwgZU9iamVjdCk7DQoJCQl9DQoJCX0NCg0KCQlHcmlkTGF5b3V0IGNvbXBvc2l0ZUxheW91dCA9IG5ldyBHcmlkTGF5b3V0KDIsIGZhbHNlKTsNCgkJY29tcG9zaXRlTGF5b3V0Lm1hcmdpbkhlaWdodCA9IDA7DQoJCWNvbXBvc2l0ZUxheW91dC5tYXJnaW5XaWR0aCA9IDA7DQoJCWNvbXBvc2l0ZUxheW91dC5ob3Jpem9udGFsU3BhY2luZyA9IDA7DQoJCXNldExheW91dChjb21wb3NpdGVMYXlvdXQpOw0KDQoJCXRoaXMuY29tYm8gPSBuZXcgQ29tYm8odGhpcywgU1dULkRST1BfRE9XTik7DQoJCS8vIHJlZHVjZSB0aGUgZm9udCBzbyB0aGF0IHRoZSBDb21ibyBmaXRzIGluIHRoZSBjZWxsDQoJCUZvbnREYXRhW10gZm9udERhdGEgPSBEaXNwbGF5LmdldERlZmF1bHQoKS5nZXRTeXN0ZW1Gb250KCkuZ2V0Rm9udERhdGEoKTsNCgkJZm9udERhdGFbMF0uc2V0SGVpZ2h0KGZvbnREYXRhWzBdLmdldEhlaWdodCgpIC0gMik7DQoJCWZpbmFsIElGb250UHJvdmlkZXIgZm9udFByb3ZpZGVyID0gSUZvbnRQcm92aWRlckZhY3RvcnkuREVGQVVMVA0KCQkJCS5nZXRPckNyZWF0ZUlGb250UHJvdmlkZXIoRGlzcGxheS5nZXREZWZhdWx0KCkpOw0KCQlmaW5hbCBGb250IGZvbnQgPSBmb250UHJvdmlkZXIuZ2V0Rm9udChmb250RGF0YVswXSk7DQoJCXRoaXMuY29tYm8uc2V0Rm9udChmb250KTsNCgkJZm9yIChTdHJpbmcgbGFiZWwgOiB0aGlzLmZFbGVtZW50cy5rZXlTZXQoKSkgew0KCQkJdGhpcy5jb21iby5hZGQobGFiZWwpOw0KCQl9DQoJCUdyaWREYXRhIGNvbWJvR3JpZERhdGEgPSBuZXcgR3JpZERhdGEoU1dULkZJTEwsIFNXVC5GSUxMLCB0cnVlLCB0cnVlKTsNCgkJdGhpcy5jb21iby5zZXRMYXlvdXREYXRhKGNvbWJvR3JpZERhdGEpOw0KCQlhZGRDb21wbGV0aW9uSGFuZGxlcih0aGlzLmNvbWJvLCB0aGlzLmZFbGVtZW50cy5rZXlTZXQoKSk7DQoNCgkJdGhpcy5jb21iby5hZGRLZXlMaXN0ZW5lcihuZXcgS2V5QWRhcHRlcigpIHsNCgkJCUBPdmVycmlkZQ0KCQkJcHVibGljIHZvaWQga2V5UHJlc3NlZChmaW5hbCBLZXlFdmVudCBldmVudCkgew0KCQkJCS8vIEVudGVyIGtleSBwcmVzc2VkDQoJCQkJaWYgKChldmVudC5rZXlDb2RlID09IFNXVC5DUiAmJiBldmVudC5zdGF0ZU1hc2sgPT0gMCkNCgkJCQkJCXx8IChldmVudC5rZXlDb2RlID09IFNXVC5LRVlQQURfQ1IgJiYgZXZlbnQuc3RhdGVNYXNrID09IDApKSB7DQoJCQkJCWlmIChpc1ZhbGlkKCkpIHsNCgkJCQkJCWNvbW1pdCgpOw0KCQkJCQl9IGVsc2Ugew0KCQkJCQkJTWVzc2FnZURpYWxvZy5vcGVuV2FybmluZyhwYXJlbnQuZ2V0U2hlbGwoKSwNCgkJCQkJCQkJTWVzc2FnZXMuVW5hcnlSZWZlcmVuY2VDZWxsRWRpdG9yQ29tcG9zaXRlXzAsDQoJCQkJCQkJCU1lc3NhZ2VzLlVuYXJ5UmVmZXJlbmNlQ2VsbEVkaXRvckNvbXBvc2l0ZV8xKTsNCgkJCQkJfQ0KCQkJCX0gZWxzZSBpZiAoZXZlbnQua2V5Q29kZSA9PSBTV1QuRVNDICYmIGV2ZW50LnN0YXRlTWFzayA9PSAwKSB7DQoJCQkJCS8vIEVzY2FwZSBrZXkgcHJlc3NlZA0KCQkJCQljbG9zZSgpOw0KCQkJCX0NCgkJCX0NCgkJfSk7DQoNCgkJdGhpcy5idXR0b24gPSBuZXcgQnV0dG9uKHRoaXMsIFNXVC5QVVNIKTsNCgkJdGhpcy5idXR0b24uc2V0VGV4dCgiLi4uIik7IC8vJE5PTi1OTFMtMSQNCgkJR3JpZERhdGEgYnV0dG9uR3JpZERhdGEgPSBuZXcgR3JpZERhdGEoU1dULkZJTEwsIFNXVC5GSUxMLCBmYWxzZSwgdHJ1ZSk7DQoJCWJ1dHRvbkdyaWREYXRhLmhlaWdodEhpbnQgPSBVbmFyeVJlZmVyZW5jZUNlbGxFZGl0b3JDb21wb3NpdGUuR1JJRF9EQVRBX0hFSUdIVDsNCgkJdGhpcy5idXR0b24uc2V0TGF5b3V0RGF0YShidXR0b25HcmlkRGF0YSk7DQoJCXRoaXMuYnV0dG9uLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgew0KCQkJQE92ZXJyaWRlDQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChmaW5hbCBTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQkJRWxlbWVudExpc3RTZWxlY3Rpb25EaWFsb2cgZGlhbG9nID0gbmV3IEVsZW1lbnRMaXN0U2VsZWN0aW9uRGlhbG9nKA0KCQkJCQkJVW5hcnlSZWZlcmVuY2VDZWxsRWRpdG9yQ29tcG9zaXRlLnRoaXMuZ2V0UGFyZW50Q29udHJvbCgpLmdldFNoZWxsKCksDQoJCQkJCQluZXcgQ3VzdG9taXphYmxlTGFiZWxQcm92aWRlcigpKSB7DQoJCQkJCUBPdmVycmlkZQ0KCQkJCQlwcm90ZWN0ZWQgdm9pZCBva1ByZXNzZWQoKSB7DQoJCQkJCQlPYmplY3RbXSBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0U2VsZWN0ZWRFbGVtZW50cygpOw0KCQkJCQkJU3RyaW5nIHNlbGVjdGVkRWxlbWVudExhYmVsID0gbnVsbDsNCgkJCQkJCWlmIChzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCA+IDApIHsNCgkJCQkJCQlTZXQ8RW50cnk8U3RyaW5nLCBFT2JqZWN0Pj4gZW50cnlTZXQgPSBVbmFyeVJlZmVyZW5jZUNlbGxFZGl0b3JDb21wb3NpdGUudGhpcw0KCQkJCQkJCQkJLmdldGZFbGVtZW50cygpLmVudHJ5U2V0KCk7DQoJCQkJCQkJZm9yIChFbnRyeTxTdHJpbmcsIEVPYmplY3Q+IGVudHJ5IDogZW50cnlTZXQpIHsNCgkJCQkJCQkJaWYgKGVudHJ5LmdldFZhbHVlKCkgPT0gc2VsZWN0ZWRFbGVtZW50c1swXSkgew0KCQkJCQkJCQkJc2VsZWN0ZWRFbGVtZW50TGFiZWwgPSBlbnRyeS5nZXRLZXkoKTsNCgkJCQkJCQkJCWJyZWFrOw0KCQkJCQkJCQl9DQoJCQkJCQkJfQ0KCQkJCQkJfQ0KCQkJCQkJVW5hcnlSZWZlcmVuY2VDZWxsRWRpdG9yQ29tcG9zaXRlLnRoaXMuZ2V0Q29tYm8oKS5zZXRUZXh0KA0KCQkJCQkJCQlzZWxlY3RlZEVsZW1lbnRMYWJlbCk7DQoJCQkJCQljb21taXQoKTsNCgkJCQkJCXN1cGVyLm9rUHJlc3NlZCgpOw0KCQkJCQl9DQoJCQkJfTsNCgkJCQlkaWFsb2cuc2V0VGl0bGUoTWVzc2FnZXMuVW5hcnlSZWZlcmVuY2VDZWxsRWRpdG9yQ29tcG9zaXRlXzIpOw0KCQkJCWRpYWxvZy5zZXRFbGVtZW50cyhlT2JqZWN0cy50b0FycmF5KCkpOw0KCQkJCWRpYWxvZy5vcGVuKCk7DQoJCQl9DQoJCX0pOw0KDQoJCS8vIGNvbW1pdCB0aGUgY2VsbCBlZGl0b3Igd2hlbiB0aGUgbW91c2UgaXMgY2xpY2tlZA0KCQkvLyBhbnl3aGVyZSBvdXRzaWRlIHRoZSB0ZXh0IGZpZWxkDQoJCWZpbmFsIExpc3RlbmVyIGNsaWNrTGlzdGVuZXIgPSBuZXcgTGlzdGVuZXIoKSB7DQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVFdmVudChmaW5hbCBFdmVudCBldmVudCkgew0KCQkJCWlmIChldmVudC53aWRnZXQgaW5zdGFuY2VvZiBDb250cm9sKSB7DQoJCQkJCUNvbnRyb2wgY29udHJvbCA9IChDb250cm9sKSBldmVudC53aWRnZXQ7DQoJCQkJCWlmIChjb250cm9sLmdldFNoZWxsKCkgPT0gVW5hcnlSZWZlcmVuY2VDZWxsRWRpdG9yQ29tcG9zaXRlLnRoaXMNCgkJCQkJCQkuZ2V0UGFyZW50Q29udHJvbCgpLmdldFNoZWxsKCkNCgkJCQkJCQkmJiBldmVudC53aWRnZXQgIT0gVW5hcnlSZWZlcmVuY2VDZWxsRWRpdG9yQ29tcG9zaXRlLnRoaXMuZ2V0QnV0dG9uKCkNCgkJCQkJCQkmJiBldmVudC53aWRnZXQgIT0gVW5hcnlSZWZlcmVuY2VDZWxsRWRpdG9yQ29tcG9zaXRlLnRoaXMuZ2V0Q29tYm8oKSkgew0KCQkJCQkJaWYgKGlzVmFsaWQoKSkgew0KCQkJCQkJCWNvbW1pdCgpOw0KCQkJCQkJfQ0KCQkJCQl9DQoJCQkJfQ0KDQoJCQl9DQoJCX07DQoJCURpc3BsYXkuZ2V0RGVmYXVsdCgpLmFkZEZpbHRlcihTV1QuTW91c2VEb3duLCBjbGlja0xpc3RlbmVyKTsNCg0KCQkvLyB0aGlzIGxpc3RlbmVyIGlzIG9ubHkgaGVyZSB0byByZW1vdmUNCgkJLy8gdGhlIG90aGVyIGxpc3RlbmVyIGZyb20gdGhlIERpc3BsYXkNCgkJYWRkRGlzcG9zZUxpc3RlbmVyKG5ldyBEaXNwb3NlTGlzdGVuZXIoKSB7DQoJCQlwdWJsaWMgdm9pZCB3aWRnZXREaXNwb3NlZChmaW5hbCBEaXNwb3NlRXZlbnQgZSkgew0KCQkJCURpc3BsYXkuZ2V0RGVmYXVsdCgpLnJlbW92ZUZpbHRlcihTV1QuTW91c2VEb3duLCBjbGlja0xpc3RlbmVyKTsNCgkJCX0NCgkJfSk7DQoJCQ0KCQl0aGlzLmNvbWJvLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsNCgkJCXB1YmxpYyB2b2lkIG1vZGlmeVRleHQoZmluYWwgTW9kaWZ5RXZlbnQgZSkgew0KCQkJCWZpcmVDaGFuZ2VkKCk7DQoJCQl9DQoJCX0pOw0KDQoJCXRoaXMuY29tYm8uZm9yY2VGb2N1cygpOw0KCX0NCg0KCXByb3RlY3RlZCBib29sZWFuIGlzVmFsaWQoKSB7DQoJCXJldHVybiB0aGlzLmZFbGVtZW50cy5nZXQodGhpcy5jb21iby5nZXRUZXh0KCkpICE9IG51bGw7DQoJfQ0KDQoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBhZGRDb21wbGV0aW9uSGFuZGxlcihmaW5hbCBDb21ibyBjb21ib0JveCwgZmluYWwgQ29sbGVjdGlvbjxTdHJpbmc+IGNvbXBsZXRpb25zKSB7DQoJCVN0cmluZ1tdIGNvbXBsZXRpb25zQXJyYXkgPSBjb21wbGV0aW9ucy50b0FycmF5KG5ldyBTdHJpbmdbY29tcGxldGlvbnMuc2l6ZSgpXSk7DQoJCVNpbXBsZUNvbnRlbnRQcm9wb3NhbFByb3ZpZGVyIGNvbnRlbnRQcm9wb3NhbFByb3ZpZGVyID0gbmV3IFNpbXBsZUNvbnRlbnRQcm9wb3NhbFByb3ZpZGVyKA0KCQkJCWNvbXBsZXRpb25zQXJyYXkpOw0KCQljb250ZW50UHJvcG9zYWxQcm92aWRlci5zZXRGaWx0ZXJpbmcodHJ1ZSk7DQoJCUNvbnRlbnRQcm9wb3NhbEFkYXB0ZXIgYWRhcHRlciA9IG5ldyBDb250ZW50UHJvcG9zYWxBZGFwdGVyKGNvbWJvQm94LA0KCQkJCW5ldyBDb21ib0NvbnRlbnRBZGFwdGVyKCksIGNvbnRlbnRQcm9wb3NhbFByb3ZpZGVyLCBudWxsLCBudWxsKTsNCgkJLy8gYWRhcHRlci5zZXRGaWx0ZXJTdHlsZShDb250ZW50UHJvcG9zYWxBZGFwdGVyLkZJTFRFUl9DSEFSQUNURVIpOw0KCQlhZGFwdGVyLnNldFByb3Bvc2FsQWNjZXB0YW5jZVN0eWxlKENvbnRlbnRQcm9wb3NhbEFkYXB0ZXIuUFJPUE9TQUxfUkVQTEFDRSk7DQoNCgl9DQoNCglwdWJsaWMgRU9iamVjdCBnZXRWYWx1ZSgpIHsNCgkJRU9iamVjdCBlT2JqZWN0ID0gdGhpcy5mRWxlbWVudHMuZ2V0KHRoaXMuY29tYm8uZ2V0VGV4dCgpKTsNCgkJcmV0dXJuIGVPYmplY3Q7DQoJfQ0KDQoJcHJvdGVjdGVkIHZvaWQgY29tbWl0KCkgew0KCQlmaXJlQ29tbWl0KCk7DQoJfQ0KDQoJcHVibGljIHZvaWQgc2V0VmFsdWUoZmluYWwgRU9iamVjdCB2YWx1ZSkgew0KCQkvLw0KCX0NCg0KCXByb3RlY3RlZCBCdXR0b24gZ2V0QnV0dG9uKCkgew0KCQlyZXR1cm4gdGhpcy5idXR0b247DQoJfQ0KDQoJcHJvdGVjdGVkIENvbWJvIGdldENvbWJvKCkgew0KCQlyZXR1cm4gdGhpcy5jb21ibzsNCgl9DQoNCglwcm90ZWN0ZWQgQ29udHJvbCBnZXRQYXJlbnRDb250cm9sKCkgew0KCQlyZXR1cm4gdGhpcy5wYXJlbnRDb250cm9sOw0KCX0NCg0KCXByb3RlY3RlZCBNYXA8U3RyaW5nLCBFT2JqZWN0PiBnZXRmRWxlbWVudHMoKSB7DQoJCXJldHVybiB0aGlzLmZFbGVtZW50czsNCgl9DQoNCn0NCg==