LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IKkgMjAwMCwgMjAwNyBJQk0gQ29ycG9yYXRpb24gYW5kIG90aGVycy4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIDIuMAogKiB3aGljaCBpcyBhdmFpbGFibGUgYXQKICogaHR0cHM6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC8KICogCiAqIENvbnRyaWJ1dG9yczoKICogICAgIElCTSBDb3Jwb3JhdGlvbiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnBhY2thZ2Ugb3JnLmVjbGlwc2UuZGF0YXRvb2xzLnNxbHRvb2xzLnNxbGJ1aWxkZXIuZXhwcmVzc2lvbmJ1aWxkZXIuY2FzZWV4cHI7CgppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKCmltcG9ydCBvcmcuZWNsaXBzZS5kYXRhdG9vbHMubW9kZWxiYXNlLnNxbC5xdWVyeS5QcmVkaWNhdGU7CmltcG9ydCBvcmcuZWNsaXBzZS5kYXRhdG9vbHMubW9kZWxiYXNlLnNxbC5xdWVyeS5RdWVyeVNlYXJjaENvbmRpdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRhdGF0b29scy5tb2RlbGJhc2Uuc3FsLnF1ZXJ5LlF1ZXJ5VmFsdWVFeHByZXNzaW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuZGF0YXRvb2xzLm1vZGVsYmFzZS5zcWwucXVlcnkuU1FMUXVlcnlPYmplY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5kYXRhdG9vbHMubW9kZWxiYXNlLnNxbC5xdWVyeS5TZWFyY2hDb25kaXRpb25Db21iaW5lZDsKaW1wb3J0IG9yZy5lY2xpcHNlLmRhdGF0b29scy5tb2RlbGJhc2Uuc3FsLnF1ZXJ5LlZhbHVlRXhwcmVzc2lvbkNhc2VTZWFyY2g7CmltcG9ydCBvcmcuZWNsaXBzZS5kYXRhdG9vbHMubW9kZWxiYXNlLnNxbC5xdWVyeS5WYWx1ZUV4cHJlc3Npb25DYXNlU2VhcmNoQ29udGVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLmRhdGF0b29scy5tb2RlbGJhc2Uuc3FsLnF1ZXJ5LlZhbHVlRXhwcmVzc2lvbkNvbHVtbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRhdGF0b29scy5tb2RlbGJhc2Uuc3FsLnF1ZXJ5LlZhbHVlRXhwcmVzc2lvblNpbXBsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmRhdGF0b29scy5zcWx0b29scy5zcWxidWlsZGVyLk1lc3NhZ2VzOwppbXBvcnQgb3JnLmVjbGlwc2UuZGF0YXRvb2xzLnNxbHRvb2xzLnNxbGJ1aWxkZXIuZXhwcmVzc2lvbmJ1aWxkZXIuRXhwcmVzc2lvbkJ1aWxkZXJEaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5kYXRhdG9vbHMuc3FsdG9vbHMuc3FsYnVpbGRlci5leHByZXNzaW9uYnVpbGRlci5FeHByZXNzaW9uQnVpbGRlcldpemFyZDsKaW1wb3J0IG9yZy5lY2xpcHNlLmRhdGF0b29scy5zcWx0b29scy5zcWxidWlsZGVyLmV4cHJlc3Npb25idWlsZGVyLmFjdGlvbnMuRGVsZXRlQ2FzZUNsYXVzZUFjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRhdGF0b29scy5zcWx0b29scy5zcWxidWlsZGVyLm1vZGVsLkV4cHJlc3Npb25IZWxwZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5kYXRhdG9vbHMuc3FsdG9vbHMuc3FsYnVpbGRlci5tb2RlbC5TUUxCdWlsZGVyQ29uc3RhbnRzOwppbXBvcnQgb3JnLmVjbGlwc2UuZGF0YXRvb2xzLnNxbHRvb2xzLnNxbGJ1aWxkZXIubW9kZWwuU1FMRG9tYWluTW9kZWw7CmltcG9ydCBvcmcuZWNsaXBzZS5kYXRhdG9vbHMuc3FsdG9vbHMuc3FsYnVpbGRlci51dGlsLkxhYmVsVmFsdWVQYWlyOwppbXBvcnQgb3JnLmVjbGlwc2UuZGF0YXRvb2xzLnNxbHRvb2xzLnNxbGJ1aWxkZXIudmlld3MuQnVpbGRlclV0aWxpdHk7CmltcG9ydCBvcmcuZWNsaXBzZS5kYXRhdG9vbHMuc3FsdG9vbHMuc3FsYnVpbGRlci52aWV3cy5EeW5hbWljQ29tYm9Cb3hDZWxsRWRpdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuZGF0YXRvb2xzLnNxbHRvb2xzLnNxbGJ1aWxkZXIudmlld3MuTmF2aWdhYmxlVGFibGVWaWV3ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5hY3Rpb24uSU1lbnVMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmFjdGlvbi5JTWVudU1hbmFnZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5hY3Rpb24uTWVudU1hbmFnZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5hY3Rpb24uU2VwYXJhdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UudXRpbC5Bc3NlcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLkNlbGxFZGl0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLkNvbHVtblBpeGVsRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSUNlbGxNb2RpZmllcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVN0cnVjdHVyZWRDb250ZW50UHJvdmlkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLklUYWJsZUxhYmVsUHJvdmlkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLkxhYmVsUHJvdmlkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLlRhYmxlTGF5b3V0OwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5WaWV3ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25BZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25FdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5HQzsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5JbWFnZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5Qb2ludDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkRpc3BsYXk7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5NZW51OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGFibGU7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5UYWJsZUNvbHVtbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlRhYmxlSXRlbTsKCgpwdWJsaWMgY2xhc3MgQ2FzZVNlYXJjaFRhYmxlIGV4dGVuZHMgTmF2aWdhYmxlVGFibGVWaWV3ZXIgaW1wbGVtZW50cyBJTWVudUxpc3RlbmVyIHsKCiAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBQX1dIRU4gPSAib3JnLmVjbGlwc2UuZGF0YXRvb2xzLnNxbHRvb2xzLnNxbGJ1aWxkZXIuZXhwcmVzc2lvbmJ1aWxkZXIuUF9XSEVOIjsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFBfTEVGVF9FWFBSRVNTSU9OID0gIm9yZy5lY2xpcHNlLmRhdGF0b29scy5zcWx0b29scy5zcWxidWlsZGVyLmV4cHJlc3Npb25idWlsZGVyLlBfTEVGVF9FWFBSRVNTSU9OIjsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFBfT1BFUkFUT1IgPSAib3JnLmVjbGlwc2UuZGF0YXRvb2xzLnNxbHRvb2xzLnNxbGJ1aWxkZXIuZXhwcmVzc2lvbmJ1aWxkZXIuUF9PUEVSQVRPUiI7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBQX1JJR0hUX0VYUFJFU1NJT04gPSAib3JnLmVjbGlwc2UuZGF0YXRvb2xzLnNxbHRvb2xzLnNxbGJ1aWxkZXIuZXhwcmVzc2lvbmJ1aWxkZXIuUF9SSUdIVF9FWFBSRVNTSU9OIjsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFBfQU5ET1IgPSAib3JnLmVjbGlwc2UuZGF0YXRvb2xzLnNxbHRvb2xzLnNxbGJ1aWxkZXIuZXhwcmVzc2lvbmJ1aWxkZXIuUF9BTkRPUiI7CiAgICBwdWJsaWMgZmluYWwgc3RhdGljIFN0cmluZyBQX1RIRU4gPSAib3JnLmVjbGlwc2UuZGF0YXRvb2xzLnNxbHRvb2xzLnNxbGJ1aWxkZXIuZXhwcmVzc2lvbmJ1aWxkZXIuUF9USEVOIjsKICAgIHB1YmxpYyBmaW5hbCBzdGF0aWMgU3RyaW5nIFBfUkVTVUxUX0VYUFJFU1NJT04gPSAib3JnLmVjbGlwc2UuZGF0YXRvb2xzLnNxbHRvb2xzLnNxbGJ1aWxkZXIuZXhwcmVzc2lvbmJ1aWxkZXIuUF9SRVNVTFRfRVhQUkVTU0lPTiI7CgogICAgcHJpdmF0ZSBTUUxEb21haW5Nb2RlbCBkb21haW5Nb2RlbDsKICAgIHByaXZhdGUgU1FMUXVlcnlPYmplY3Qgc3FsU3RhdGVtZW50OwogICAgcHJpdmF0ZSBEeW5hbWljQ29tYm9Cb3hDZWxsRWRpdG9yIGxlZnRFeHByZXNzaW9uc0NvbWJvQm94Q2VsbEVkaXRvcjsKICAgIHByaXZhdGUgRHluYW1pY0NvbWJvQm94Q2VsbEVkaXRvciByaWdodEV4cHJlc3Npb25zQ29tYm9Cb3hDZWxsRWRpdG9yOwogICAgcHJpdmF0ZSBEeW5hbWljQ29tYm9Cb3hDZWxsRWRpdG9yIHJlc3VsdEV4cHJlc3Npb25zQ29tYm9Cb3hDZWxsRWRpdG9yOwogICAgcHJpdmF0ZSBvcmcuZWNsaXBzZS5kYXRhdG9vbHMuc3FsdG9vbHMuc3FsYnVpbGRlci52aWV3cy5Db21ib0JveENlbGxFZGl0b3Igb3BlcmF0b3JzQ29tYm9Cb3hDZWxsRWRpdG9yOwogICAgcHJpdmF0ZSBvcmcuZWNsaXBzZS5kYXRhdG9vbHMuc3FsdG9vbHMuc3FsYnVpbGRlci52aWV3cy5Db21ib0JveENlbGxFZGl0b3IgYW5kT3JFZGl0b3I7CiAgICBwcml2YXRlIENhc2VTZWFyY2hQYWdlIGNhc2VTZWFyY2hQYWdlOwogICAgcHJpdmF0ZSBUYWJsZSB0YWJsZTsKICAgIHByaXZhdGUgVGFibGVDb2x1bW4gYzEsIGMyLCBjMywgYzQsIGM1LCBjNjsKICAgIHByaXZhdGUgQ2VsbEVkaXRvcltdIGVkaXRvcnM7CiAgICBwcml2YXRlIENlbGxFZGl0b3JbXSBlZGl0b3JzRm9yRWxzZTsKCiAgICBDYXNlU2VhcmNoVGFibGUoQ2FzZVNlYXJjaFBhZ2Ugc2VhcmNoUGFnZSwgQ29tcG9zaXRlIHBhcmVudCwgU1FMRG9tYWluTW9kZWwgZG9tYWluTW9kZWwsIFNRTFF1ZXJ5T2JqZWN0IHNxbFN0bXQpIHsKICAgICAgICBzdXBlcihuZXcgVGFibGUocGFyZW50LCBTV1QuTVVMVEkgfCBTV1QuRlVMTF9TRUxFQ1RJT04pKTsKCiAgICAgICAgdGhpcy5kb21haW5Nb2RlbCA9IGRvbWFpbk1vZGVsOwogICAgICAgIHRoaXMuc3FsU3RhdGVtZW50ID0gc3FsU3RtdDsKICAgICAgICB0aGlzLmNhc2VTZWFyY2hQYWdlID0gc2VhcmNoUGFnZTsKCiAgICAgICAgdGFibGUgPSBnZXRUYWJsZSgpOwogICAgICAgIHRhYmxlLnNldExpbmVzVmlzaWJsZSh0cnVlKTsKICAgICAgICB0YWJsZS5zZXRIZWFkZXJWaXNpYmxlKHRydWUpOwogICAgICAgIAogICAgICAgIHRhYmxlLmFkZFNlbGVjdGlvbkxpc3RlbmVyKAogICAgICAgICAgICBuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKICAgICAgICAgICAgICAgICAgICByZWZyZXNoQ2VsbEVkaXRvcihnZXRUYWJsZSgpLmdldFNlbGVjdGlvbkluZGV4KCkgPj0gMCA/IGdldFRhYmxlKCkuZ2V0U2VsZWN0aW9uSW5kZXgoKSA6IDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgKTsKCiAgICAgICAgYzEgPSBuZXcgVGFibGVDb2x1bW4odGFibGUsIFNXVC5OVUxMKTsKICAgICAgICBjMS5zZXRUZXh0KCJDQVNFIik7CgogICAgICAgIGxlZnRFeHByZXNzaW9uc0NvbWJvQm94Q2VsbEVkaXRvciA9IG5ldyBEeW5hbWljQ29tYm9Cb3hDZWxsRWRpdG9yKHRhYmxlLCBudWxsLCB0aGlzKTsKICAgICAgICBjMiA9IG5ldyBUYWJsZUNvbHVtbih0YWJsZSwgU1dULk5VTEwpOwogICAgICAgIGMyLnNldFRleHQoTWVzc2FnZXMuX1VJX0NPTFVNTl9DQVNFX1NFQVJDSF9FWFBSRVNTSU9OKTsKCiAgICAgICAgb3BlcmF0b3JzQ29tYm9Cb3hDZWxsRWRpdG9yID0gbmV3IG9yZy5lY2xpcHNlLmRhdGF0b29scy5zcWx0b29scy5zcWxidWlsZGVyLnZpZXdzLkNvbWJvQm94Q2VsbEVkaXRvcih0YWJsZSwgbnVsbCk7CiAgICAgICAgYzMgPSBuZXcgVGFibGVDb2x1bW4odGFibGUsIFNXVC5OVUxMKTsKICAgICAgICBjMy5zZXRUZXh0KE1lc3NhZ2VzLl9VSV9DT0xVTU5fQ0FTRV9TRUFSQ0hfT1BFUkFUT1IpOwogICAgICAgIGZpbGxPcGVyYXRvcnNDb21ib0JveCgpOwoKICAgICAgICByaWdodEV4cHJlc3Npb25zQ29tYm9Cb3hDZWxsRWRpdG9yID0gbmV3IER5bmFtaWNDb21ib0JveENlbGxFZGl0b3IodGFibGUsIG51bGwsIHRoaXMpOwogICAgICAgIGM0ID0gbmV3IFRhYmxlQ29sdW1uKHRhYmxlLCBTV1QuTlVMTCk7CiAgICAgICAgYzQuc2V0VGV4dChNZXNzYWdlcy5fVUlfQ09MVU1OX0NBU0VfU0VBUkNIX0VYUFJFU1NJT04pOwoKICAgICAgICBhbmRPckVkaXRvciA9IG5ldyBvcmcuZWNsaXBzZS5kYXRhdG9vbHMuc3FsdG9vbHMuc3FsYnVpbGRlci52aWV3cy5Db21ib0JveENlbGxFZGl0b3IodGFibGUsIG51bGwpOwogICAgICAgIGM1ID0gbmV3IFRhYmxlQ29sdW1uKHRhYmxlLCBTV1QuTlVMTCk7CiAgICAgICAgYzUuc2V0VGV4dCgiQU5EL09SIik7CiAgICAgICAgZmlsbEFuZE9yQ29tYm9Cb3goKTsKCiAgICAgICAgcmVzdWx0RXhwcmVzc2lvbnNDb21ib0JveENlbGxFZGl0b3IgPSBuZXcgRHluYW1pY0NvbWJvQm94Q2VsbEVkaXRvcih0YWJsZSwgbnVsbCwgdGhpcyk7CiAgICAgICAgYzYgPSBuZXcgVGFibGVDb2x1bW4odGFibGUsIFNXVC5OVUxMKTsKICAgICAgICBjNi5zZXRUZXh0KCJUSEVOIik7CgogICAgICAgIEdDIGdjID0gbmV3IEdDKERpc3BsYXkuZ2V0Q3VycmVudCgpKTsKICAgICAgICBQb2ludCBwMSA9IGdjLnN0cmluZ0V4dGVudChjMS5nZXRUZXh0KCkpOwogICAgICAgIFBvaW50IHA1ID0gZ2Muc3RyaW5nRXh0ZW50KGM1LmdldFRleHQoKSk7CiAgICAgICAgaW50IG1pbldpZHRoQzEgPSBwMS54ICsgMTU7CiAgICAgICAgaW50IG1pbldpZHRoQzUgPSBwNS54ICsgMTU7CiAgICAgICAgaWYgKG1pbldpZHRoQzEgPD0gMCkKICAgICAgICAgICAgbWluV2lkdGhDMSA9IDQ1OwogICAgICAgIGlmIChtaW5XaWR0aEM1IDw9IDApCiAgICAgICAgICAgIG1pbldpZHRoQzUgPSA2MTsKCiAgICAgICAgVGFibGVMYXlvdXQgbGF5b3V0ID0gbmV3IFRhYmxlTGF5b3V0KCk7CgogICAgICAgIGxheW91dC5hZGRDb2x1bW5EYXRhKG5ldyBDb2x1bW5QaXhlbERhdGEoNDUsIGZhbHNlKSk7IC8vNDEKICAgICAgICBsYXlvdXQuYWRkQ29sdW1uRGF0YShuZXcgQ29sdW1uUGl4ZWxEYXRhKDEwMCwgdHJ1ZSkpOyAvLzE0MAogICAgICAgIGxheW91dC5hZGRDb2x1bW5EYXRhKG5ldyBDb2x1bW5QaXhlbERhdGEoNjAsIGZhbHNlKSk7IC8vNzAKICAgICAgICBsYXlvdXQuYWRkQ29sdW1uRGF0YShuZXcgQ29sdW1uUGl4ZWxEYXRhKDEwMCwgdHJ1ZSkpOyAvLzE0MAogICAgICAgIGxheW91dC5hZGRDb2x1bW5EYXRhKG5ldyBDb2x1bW5QaXhlbERhdGEoNjEsIGZhbHNlKSk7IC8vNTYKICAgICAgICBsYXlvdXQuYWRkQ29sdW1uRGF0YShuZXcgQ29sdW1uUGl4ZWxEYXRhKDE3MCwgdHJ1ZSkpOyAvLzE0MAoKICAgICAgICB0YWJsZS5zZXRMYXlvdXQobGF5b3V0KTsKCiAgICAgICAgU3RyaW5nIHByb3BlcnRpZXNbXSA9IHsgUF9XSEVOLCBQX0xFRlRfRVhQUkVTU0lPTiwgUF9PUEVSQVRPUiwgUF9SSUdIVF9FWFBSRVNTSU9OLCBQX0FORE9SLCBQX1JFU1VMVF9FWFBSRVNTSU9OIH07CgogICAgICAgIHNldENvbHVtblByb3BlcnRpZXMocHJvcGVydGllcyk7CgogICAgICAgIGVkaXRvcnMgPSBuZXcgQ2VsbEVkaXRvcls2XTsKICAgICAgICBlZGl0b3JzWzBdID0gbnVsbDsKICAgICAgICBlZGl0b3JzWzFdID0gbGVmdEV4cHJlc3Npb25zQ29tYm9Cb3hDZWxsRWRpdG9yOwogICAgICAgIGVkaXRvcnNbMl0gPSBvcGVyYXRvcnNDb21ib0JveENlbGxFZGl0b3I7CiAgICAgICAgZWRpdG9yc1szXSA9IHJpZ2h0RXhwcmVzc2lvbnNDb21ib0JveENlbGxFZGl0b3I7CiAgICAgICAgZWRpdG9yc1s0XSA9IGFuZE9yRWRpdG9yOwogICAgICAgIGVkaXRvcnNbNV0gPSByZXN1bHRFeHByZXNzaW9uc0NvbWJvQm94Q2VsbEVkaXRvcjsKCiAgICAgICAgZWRpdG9yc0ZvckVsc2UgPSBuZXcgQ2VsbEVkaXRvcls2XTsKICAgICAgICBlZGl0b3JzRm9yRWxzZVswXSA9IG51bGw7CiAgICAgICAgZWRpdG9yc0ZvckVsc2VbMV0gPSBsZWZ0RXhwcmVzc2lvbnNDb21ib0JveENlbGxFZGl0b3I7CiAgICAgICAgZWRpdG9yc0ZvckVsc2VbMl0gPSBudWxsOwogICAgICAgIGVkaXRvcnNGb3JFbHNlWzNdID0gbnVsbDsKICAgICAgICBlZGl0b3JzRm9yRWxzZVs0XSA9IG51bGw7CiAgICAgICAgZWRpdG9yc0ZvckVsc2VbNV0gPSBudWxsOwoKICAgICAgICBzZXRDZWxsRWRpdG9ycyhlZGl0b3JzKTsKICAgICAgICBzZXRDZWxsTW9kaWZpZXIobmV3IENhc2VTZWFyY2hUYWJsZUNlbGxNb2RpZmllcih0aGlzKSk7CgogICAgICAgIHNldExhYmVsUHJvdmlkZXIobmV3IENhc2VTZWFyY2hUYWJsZUxhYmVsUHJvdmlkZXIoKSk7CiAgICAgICAgc2V0Q29udGVudFByb3ZpZGVyKG5ldyBDYXNlU2VhcmNoVGFibGVDb250ZW50UHJvdmlkZXIoKSk7CgogICAgICAgIE1lbnVNYW5hZ2VyIGNvbnRleHRNZW51ID0gbmV3IE1lbnVNYW5hZ2VyKCIjUG9wVXAiKTsKICAgICAgICBjb250ZXh0TWVudS5hZGQobmV3IFNlcGFyYXRvcigiYWRkaXRpb25zIikpOwogICAgICAgIGNvbnRleHRNZW51LnNldFJlbW92ZUFsbFdoZW5TaG93bih0cnVlKTsKICAgICAgICBjb250ZXh0TWVudS5hZGRNZW51TGlzdGVuZXIodGhpcyk7CiAgICAgICAgTWVudSBtZW51ID0gY29udGV4dE1lbnUuY3JlYXRlQ29udGV4dE1lbnUoZ2V0Q29udHJvbCgpKTsKICAgICAgICBnZXRDb250cm9sKCkuc2V0TWVudShtZW51KTsKICAgIH0KCiAgICBwdWJsaWMgQ2FzZVNlYXJjaFBhZ2UgZ2V0Q2FzZVNlYXJjaFBhZ2UoKSB7CiAgICAgICAgcmV0dXJuIGNhc2VTZWFyY2hQYWdlOwogICAgfQogICAgCiAgICBwdWJsaWMgU1FMRG9tYWluTW9kZWwgZ2V0RG9tYWluTW9kZWwoKSB7CiAgICAgICAgcmV0dXJuIGRvbWFpbk1vZGVsOwogICAgfQogICAgCiAgICBwdWJsaWMgU1FMUXVlcnlPYmplY3QgZ2V0U1FMU3RhdGVtZW50KCkgewogICAgICAgIHJldHVybiBzcWxTdGF0ZW1lbnQ7CiAgICB9CiAgICAKICAgIHB1YmxpYyB2b2lkIHJlZnJlc2goKSB7CiAgICAgICAgc3VwZXIucmVmcmVzaCgpOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHJlZnJlc2hDZWxsRWRpdG9yKGludCByb3cpIHsKICAgICAgICBib29sZWFuIGxlZnRFeGlzdHNFeHByZXNzaW9uID0gZmFsc2U7CiAgICAgICAgYm9vbGVhbiByaWdodEV4aXN0c0V4cHJlc3Npb24gPSBmYWxzZTsKICAgICAgICBib29sZWFuIHJlc3VsdEV4aXN0c0V4cHJlc3Npb24gPSBmYWxzZTsKICAgICAgICBib29sZWFuIGVsc2VFeGlzdHNFeHByZXNzaW9uID0gZmFsc2U7CgogICAgICAgIE9iamVjdCBvYmogPSBnZXRFbGVtZW50QXQocm93KTsKICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgQ2FzZVNlYXJjaFdoZW5Db250ZW50RWxlbWVudCkgewogICAgICAgICAgICBPYmplY3QgbGVmdCA9ICgoQ2FzZVNlYXJjaFdoZW5Db250ZW50RWxlbWVudCkgb2JqKS5nZXRMZWZ0KCk7CiAgICAgICAgICAgIE9iamVjdCByaWdodCA9ICgoQ2FzZVNlYXJjaFdoZW5Db250ZW50RWxlbWVudCkgb2JqKS5nZXRSaWdodCgpOwogICAgICAgICAgICBPYmplY3QgcmVzdWx0ID0gKChDYXNlU2VhcmNoV2hlbkNvbnRlbnRFbGVtZW50KSBvYmopLmdldFJlc3VsdCgpOwoKICAgICAgICAgICAgaWYgKGxlZnQgaW5zdGFuY2VvZiBRdWVyeVZhbHVlRXhwcmVzc2lvbikgewogICAgICAgICAgICAgICAgbGVmdEV4aXN0c0V4cHJlc3Npb24gPSB0cnVlOwogICAgICAgICAgICAgICAgLy8qKioqKkFkZGVkIGZvbGxvd2luZyB0byBzdXBwb3J0IHNpbmdsZSBxdW90ZXMgaW4gRXhwcmVzc2lvbmJ1aWxkZXIKICAgICAgICAgICAgICAgIC8vYjM3MCBuYiAyMDA0MDcyOSAtIGJlZ2luCiAgICAgICAgICAgICAgICBUYWJsZUl0ZW0gdGl0ZW0gPSB0YWJsZS5nZXRJdGVtKHJvdyk7CiAgICAgICAgICAgICAgICBTdHJpbmcgb3ByID0gdGl0ZW0uZ2V0VGV4dCgyKTsKICAgICAgICAgICAgICAgIGlmIChsZWZ0IGluc3RhbmNlb2YgVmFsdWVFeHByZXNzaW9uQ29sdW1uKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKG9wci5lcXVhbHNJZ25vcmVDYXNlKCIiKSB8fCBvcHIuZXF1YWxzSWdub3JlQ2FzZSgiPSIpIHx8IG9wci5lcXVhbHNJZ25vcmVDYXNlKCI8IikgfHwgb3ByLmVxdWFsc0lnbm9yZUNhc2UoIjw9IikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IG9wci5lcXVhbHNJZ25vcmVDYXNlKCI+IikgfHwgb3ByLmVxdWFsc0lnbm9yZUNhc2UoIj49IikgfHwgb3ByLmVxdWFsc0lnbm9yZUNhc2UoIjw+IikgfHwgb3ByLmVxdWFsc0lnbm9yZUNhc2UoIkxJS0UiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgb3ByLmVxdWFsc0lnbm9yZUNhc2UoIk5PVCBMSUtFIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHRFeHByZXNzaW9uc0NvbWJvQm94Q2VsbEVkaXRvci5zZXROZWVkUXVvdGVzKHRydWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHRFeHByZXNzaW9uc0NvbWJvQm94Q2VsbEVkaXRvci5zZXROZWVkUXVvdGVzKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgVmFsdWVFeHByZXNzaW9uQ29sdW1uIHNjZSA9IChWYWx1ZUV4cHJlc3Npb25Db2x1bW4pIGxlZnQ7CiAgICAgICAgICAgICAgICAgICAgcmlnaHRFeHByZXNzaW9uc0NvbWJvQm94Q2VsbEVkaXRvci5zZXRQYWlyRGF0YVR5cGUoc2NlLmdldERhdGFUeXBlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmlnaHRFeHByZXNzaW9uc0NvbWJvQm94Q2VsbEVkaXRvci5zZXROZWVkUXVvdGVzKGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vYjM3MCBuYiAyMDA0MDcyOSAtIGVuZAogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChyaWdodCBpbnN0YW5jZW9mIFF1ZXJ5VmFsdWVFeHByZXNzaW9uKSB7CiAgICAgICAgICAgICAgICByaWdodEV4aXN0c0V4cHJlc3Npb24gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBRdWVyeVZhbHVlRXhwcmVzc2lvbikgewogICAgICAgICAgICAgICAgcmVzdWx0RXhpc3RzRXhwcmVzc2lvbiA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEJ1aWxkZXJVdGlsaXR5LmZpbGxDb2x1bW5Db21ib0JveChsZWZ0RXhwcmVzc2lvbnNDb21ib0JveENlbGxFZGl0b3IsIHNxbFN0YXRlbWVudCwgdHJ1ZSwgbGVmdEV4aXN0c0V4cHJlc3Npb24pOwogICAgICAgICAgICBCdWlsZGVyVXRpbGl0eS5maWxsQ29sdW1uQ29tYm9Cb3gocmlnaHRFeHByZXNzaW9uc0NvbWJvQm94Q2VsbEVkaXRvciwgc3FsU3RhdGVtZW50LCB0cnVlLCByaWdodEV4aXN0c0V4cHJlc3Npb24pOwogICAgICAgICAgICBCdWlsZGVyVXRpbGl0eS5maWxsQ29sdW1uQ29tYm9Cb3gocmVzdWx0RXhwcmVzc2lvbnNDb21ib0JveENlbGxFZGl0b3IsIHNxbFN0YXRlbWVudCwgdHJ1ZSwgcmVzdWx0RXhpc3RzRXhwcmVzc2lvbik7CgogICAgICAgICAgICBlZGl0b3JzWzBdID0gbnVsbDsKICAgICAgICAgICAgZWRpdG9yc1sxXSA9IGxlZnRFeHByZXNzaW9uc0NvbWJvQm94Q2VsbEVkaXRvcjsKICAgICAgICAgICAgZWRpdG9yc1syXSA9IG9wZXJhdG9yc0NvbWJvQm94Q2VsbEVkaXRvcjsKICAgICAgICAgICAgZWRpdG9yc1szXSA9IHJpZ2h0RXhwcmVzc2lvbnNDb21ib0JveENlbGxFZGl0b3I7CiAgICAgICAgICAgIGVkaXRvcnNbNF0gPSBhbmRPckVkaXRvcjsKICAgICAgICAgICAgZWRpdG9yc1s1XSA9IHJlc3VsdEV4cHJlc3Npb25zQ29tYm9Cb3hDZWxsRWRpdG9yOwoKICAgICAgICAgICAgc2V0Q2VsbEVkaXRvcnMoZWRpdG9ycyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIENhc2VFbHNlQ2xhdXNlRWxlbWVudCkgewogICAgICAgICAgICBPYmplY3QgZXhwciA9ICgoQ2FzZUVsc2VDbGF1c2VFbGVtZW50KSBvYmopLmdldFJlc3VsdCgpOwoKICAgICAgICAgICAgaWYgKGV4cHIgaW5zdGFuY2VvZiBRdWVyeVZhbHVlRXhwcmVzc2lvbikgewogICAgICAgICAgICAgICAgZWxzZUV4aXN0c0V4cHJlc3Npb24gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEJ1aWxkZXJVdGlsaXR5LmZpbGxDb2x1bW5Db21ib0JveChsZWZ0RXhwcmVzc2lvbnNDb21ib0JveENlbGxFZGl0b3IsIHNxbFN0YXRlbWVudCwgdHJ1ZSwgZWxzZUV4aXN0c0V4cHJlc3Npb24pOwoKICAgICAgICAgICAgZWRpdG9yc0ZvckVsc2VbMF0gPSBudWxsOwogICAgICAgICAgICBlZGl0b3JzRm9yRWxzZVsxXSA9IGxlZnRFeHByZXNzaW9uc0NvbWJvQm94Q2VsbEVkaXRvcjsKICAgICAgICAgICAgZWRpdG9yc0ZvckVsc2VbMl0gPSBudWxsOwogICAgICAgICAgICBlZGl0b3JzRm9yRWxzZVszXSA9IG51bGw7CiAgICAgICAgICAgIGVkaXRvcnNGb3JFbHNlWzRdID0gbnVsbDsKICAgICAgICAgICAgZWRpdG9yc0ZvckVsc2VbNV0gPSBudWxsOwoKICAgICAgICAgICAgc2V0Q2VsbEVkaXRvcnMoZWRpdG9yc0ZvckVsc2UpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgdm9pZCBtZW51QWJvdXRUb1Nob3coSU1lbnVNYW5hZ2VyIG1lbnUpIHsKICAgICAgICBEZWxldGVDYXNlQ2xhdXNlQWN0aW9uIGRlbGV0ZUNhc2VDbGF1c2VBY3Rpb24gPSBuZXcgRGVsZXRlQ2FzZUNsYXVzZUFjdGlvbih0aGlzLCBjYXNlU2VhcmNoUGFnZSk7CgogICAgICAgIGlmICh0YWJsZS5nZXRTZWxlY3Rpb25Db3VudCgpID4gMCkgewogICAgICAgICAgICBUYWJsZUl0ZW0gdGFibGVJdGVtID0gKHRhYmxlLmdldFNlbGVjdGlvbigpKVswXTsKICAgICAgICAgICAgT2JqZWN0IGRhdGEgPSB0YWJsZUl0ZW0uZ2V0RGF0YSgpOwogICAgICAgICAgICBpZiAoZGF0YSBpbnN0YW5jZW9mIENhc2VTZWFyY2hXaGVuQ29udGVudEVsZW1lbnQpIHsKICAgICAgICAgICAgICAgIENhc2VTZWFyY2hXaGVuQ29udGVudEVsZW1lbnQgY29udGVudEVsZW1lbnQgPSAoQ2FzZVNlYXJjaFdoZW5Db250ZW50RWxlbWVudCkgZGF0YTsKICAgICAgICAgICAgICAgIGlmIChjb250ZW50RWxlbWVudC5nZXRGaXJzdENsYXVzZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlQ2FzZUNsYXVzZUFjdGlvbi5zZXRUZXh0KE1lc3NhZ2VzLl9VSV9BQ1RJT05fREVMRVRFX1dIRU5fQ0xBVVNFX1NFQVJDSCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBkZWxldGVDYXNlQ2xhdXNlQWN0aW9uLnNldFRleHQoTWVzc2FnZXMuX1VJX0FDVElPTl9ERUxFVEVfU0VBUkNIX0NPTkRJVElPTik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoZGF0YSBpbnN0YW5jZW9mIENhc2VFbHNlQ2xhdXNlRWxlbWVudCkgewogICAgICAgICAgICAgICAgZGVsZXRlQ2FzZUNsYXVzZUFjdGlvbi5zZXRUZXh0KE1lc3NhZ2VzLl9VSV9BQ1RJT05fREVMRVRFX0VMU0VfRVhQUkVTU0lPTl9TRUFSQ0gpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBtZW51LmFkZChkZWxldGVDYXNlQ2xhdXNlQWN0aW9uKTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgZmlsbE9wZXJhdG9yc0NvbWJvQm94KCkgewogICAgICAgIExhYmVsVmFsdWVQYWlyW10gb3BlcmF0b3JJdGVtcyA9IG5ldyBMYWJlbFZhbHVlUGFpclsxNl07CiAgICAgICAgb3BlcmF0b3JJdGVtc1swXSA9IG5ldyBMYWJlbFZhbHVlUGFpcigiIiwgIiIpOwogICAgICAgIG9wZXJhdG9ySXRlbXNbMV0gPSBuZXcgTGFiZWxWYWx1ZVBhaXIoIj0iLCAiPSIpOwogICAgICAgIG9wZXJhdG9ySXRlbXNbMl0gPSBuZXcgTGFiZWxWYWx1ZVBhaXIoIjwiLCAiPCIpOwogICAgICAgIG9wZXJhdG9ySXRlbXNbM10gPSBuZXcgTGFiZWxWYWx1ZVBhaXIoIjw9IiwgIjw9Iik7CiAgICAgICAgb3BlcmF0b3JJdGVtc1s0XSA9IG5ldyBMYWJlbFZhbHVlUGFpcigiPiIsICI+Iik7CiAgICAgICAgb3BlcmF0b3JJdGVtc1s1XSA9IG5ldyBMYWJlbFZhbHVlUGFpcigiPj0iLCAiPj0iKTsKICAgICAgICBvcGVyYXRvckl0ZW1zWzZdID0gbmV3IExhYmVsVmFsdWVQYWlyKCI8PiIsICI8PiIpOwogICAgICAgIG9wZXJhdG9ySXRlbXNbN10gPSBuZXcgTGFiZWxWYWx1ZVBhaXIoIkJFVFdFRU4iLCAiQkVUV0VFTiIpOwogICAgICAgIG9wZXJhdG9ySXRlbXNbOF0gPSBuZXcgTGFiZWxWYWx1ZVBhaXIoIk5PVCBCRVRXRUVOIiwgIk5PVCBCRVRXRUVOIik7CiAgICAgICAgb3BlcmF0b3JJdGVtc1s5XSA9IG5ldyBMYWJlbFZhbHVlUGFpcigiSVMgTlVMTCIsICJJUyBOVUxMIik7CiAgICAgICAgb3BlcmF0b3JJdGVtc1sxMF0gPSBuZXcgTGFiZWxWYWx1ZVBhaXIoIklTIE5PVCBOVUxMIiwgIklTIE5PVCBOVUxMIik7CiAgICAgICAgb3BlcmF0b3JJdGVtc1sxMV0gPSBuZXcgTGFiZWxWYWx1ZVBhaXIoIkxJS0UiLCAiTElLRSIpOwogICAgICAgIG9wZXJhdG9ySXRlbXNbMTJdID0gbmV3IExhYmVsVmFsdWVQYWlyKCJOT1QgTElLRSIsICJOT1QgTElLRSIpOwogICAgICAgIG9wZXJhdG9ySXRlbXNbMTNdID0gbmV3IExhYmVsVmFsdWVQYWlyKCJJTiIsICJJTiIpOwogICAgICAgIG9wZXJhdG9ySXRlbXNbMTRdID0gbmV3IExhYmVsVmFsdWVQYWlyKCJOT1QgSU4iLCAiTk9UIElOIik7CiAgICAgICAgb3BlcmF0b3JJdGVtc1sxNV0gPSBuZXcgTGFiZWxWYWx1ZVBhaXIoIkVYSVNUUyIsICJFWElTVFMiKTsKICAgICAgICBvcGVyYXRvcnNDb21ib0JveENlbGxFZGl0b3IuY3JlYXRlSXRlbXMob3BlcmF0b3JJdGVtcyk7CiAgICB9CgogICAgcHJvdGVjdGVkIHZvaWQgZmlsbEFuZE9yQ29tYm9Cb3goKSB7CiAgICAgICAgTGFiZWxWYWx1ZVBhaXJbXSBhbmRPckl0ZW1zID0gbmV3IExhYmVsVmFsdWVQYWlyWzNdOwogICAgICAgIGFuZE9ySXRlbXNbMF0gPSBuZXcgTGFiZWxWYWx1ZVBhaXIoIiIsICIiKTsKICAgICAgICBhbmRPckl0ZW1zWzFdID0gbmV3IExhYmVsVmFsdWVQYWlyKCJBTkQiLCAiQU5EIik7CiAgICAgICAgYW5kT3JJdGVtc1syXSA9IG5ldyBMYWJlbFZhbHVlUGFpcigiT1IiLCAiT1IiKTsKICAgICAgICBhbmRPckVkaXRvci5jcmVhdGVJdGVtcyhhbmRPckl0ZW1zKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgdm9pZCBpbnB1dENoYW5nZWQoT2JqZWN0IGlucHV0LCBPYmplY3Qgb2xkSW5wdXQpIHsKICAgICAgICBzdXBlci5pbnB1dENoYW5nZWQoaW5wdXQsIG9sZElucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgQ2FzZVNlYXJjaFRhYmxlQ29udGVudFByb3ZpZGVyIGltcGxlbWVudHMgSVN0cnVjdHVyZWRDb250ZW50UHJvdmlkZXIgewoKICAgICAgICBwcm90ZWN0ZWQgVmVjdG9yIHRhYmxlRWxlbWVudHM7CiAgICAgICAgcHJvdGVjdGVkIFZhbHVlRXhwcmVzc2lvbkNhc2VTZWFyY2ggc3FsQ2FzZVNlYXJjaDsKICAgICAgICBwcm90ZWN0ZWQgYm9vbGVhbiBmaXJzdENsYXVzZTsKCiAgICAgICAgcHVibGljIENhc2VTZWFyY2hUYWJsZUNvbnRlbnRQcm92aWRlcigpIHsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBpbnB1dENoYW5nZWQoVmlld2VyIHZpZXdlciwgT2JqZWN0IG9sZCwgT2JqZWN0IG5ld29iaikgewogICAgICAgIH0KCiAgICAgICAgcHVibGljIE9iamVjdFtdIGdldEVsZW1lbnRzKGphdmEubGFuZy5PYmplY3QgcHJvcGVydHkpIHsKICAgICAgICAgICAgaWYgKHByb3BlcnR5IGluc3RhbmNlb2YgVmFsdWVFeHByZXNzaW9uQ2FzZVNlYXJjaCkgewogICAgICAgICAgICAgICAgdGFibGVFbGVtZW50cyA9IG5ldyBWZWN0b3IoKTsKCiAgICAgICAgICAgICAgICBzcWxDYXNlU2VhcmNoID0gKFZhbHVlRXhwcmVzc2lvbkNhc2VTZWFyY2gpIHByb3BlcnR5OwoKICAgICAgICAgICAgICAgIEl0ZXJhdG9yIGUgPSBzcWxDYXNlU2VhcmNoLmdldFNlYXJjaENvbnRlbnRMaXN0KCkuaXRlcmF0b3IoKTsKICAgICAgICAgICAgICAgIFZhbHVlRXhwcmVzc2lvbkNhc2VTZWFyY2hDb250ZW50IGNvbnRlbnQgPSBudWxsOwogICAgICAgICAgICAgICAgUXVlcnlTZWFyY2hDb25kaXRpb24gc2VhcmNoQ29uZGl0aW9uID0gbnVsbDsKICAgICAgICAgICAgICAgIGludCBjbGF1c2VOdW1iZXIgPSAwOyAvLyB6ZXJvLWJhc2VkCiAgICAgICAgICAgICAgICBmb3IgKDsgZS5oYXNOZXh0KCk7KSB7CiAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IChWYWx1ZUV4cHJlc3Npb25DYXNlU2VhcmNoQ29udGVudCkgZS5uZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgc2VhcmNoQ29uZGl0aW9uID0gY29udGVudC5nZXRTZWFyY2hDb25kaXRpb24oKTsKICAgICAgICAgICAgICAgICAgICBmaXJzdENsYXVzZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgZ2V0QWxsUHJlZGljYXRlcyhwcm9wZXJ0eSwgY29udGVudCwgc2VhcmNoQ29uZGl0aW9uLCBjbGF1c2VOdW1iZXIpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoc2VhcmNoQ29uZGl0aW9uID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlTmV3Q29udGVudEVsZW1lbnQoY29udGVudCwgbnVsbCwgY2xhdXNlTnVtYmVyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2xhdXNlTnVtYmVyKys7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHNxbENhc2VTZWFyY2guZ2V0Q2FzZUVsc2UoKSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ2FzZUVsc2VDbGF1c2VFbGVtZW50KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBnZXRDYXNlU2VhcmNoUGFnZSgpLnVwZGF0ZUZpbmlzaEJ1dHRvbigpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRhYmxlRWxlbWVudHMudG9BcnJheSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBnZXRBbGxQcmVkaWNhdGVzKE9iamVjdCBwcm9wZXJ0eSwgVmFsdWVFeHByZXNzaW9uQ2FzZVNlYXJjaENvbnRlbnQgY29udGVudCwgUXVlcnlTZWFyY2hDb25kaXRpb24gY29uZCwgaW50IGNsYXVzZU51bWJlcikgewogICAgICAgICAgICBpZiAoY29uZCBpbnN0YW5jZW9mIFByZWRpY2F0ZSkgewogICAgICAgICAgICAgICAgY3JlYXRlTmV3Q29udGVudEVsZW1lbnQoY29udGVudCwgKFByZWRpY2F0ZSkgY29uZCwgY2xhdXNlTnVtYmVyKTsKICAgICAgICAgICAgICAgIGZpcnN0Q2xhdXNlID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoY29uZCBpbnN0YW5jZW9mIFNlYXJjaENvbmRpdGlvbkNvbWJpbmVkKSB7CiAgICAgICAgICAgICAgICBRdWVyeVNlYXJjaENvbmRpdGlvbiBsZWZ0ID0gKChTZWFyY2hDb25kaXRpb25Db21iaW5lZCkgY29uZCkuZ2V0TGVmdENvbmRpdGlvbigpOwogICAgICAgICAgICAgICAgZ2V0QWxsUHJlZGljYXRlcyhwcm9wZXJ0eSwgY29udGVudCwgbGVmdCwgY2xhdXNlTnVtYmVyKTsKCiAgICAgICAgICAgICAgICBRdWVyeVNlYXJjaENvbmRpdGlvbiByaWdodCA9ICgoU2VhcmNoQ29uZGl0aW9uQ29tYmluZWQpIGNvbmQpLmdldFJpZ2h0Q29uZGl0aW9uKCk7CiAgICAgICAgICAgICAgICBnZXRBbGxQcmVkaWNhdGVzKHByb3BlcnR5LCBjb250ZW50LCByaWdodCwgY2xhdXNlTnVtYmVyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGNyZWF0ZU5ld0NvbnRlbnRFbGVtZW50KFZhbHVlRXhwcmVzc2lvbkNhc2VTZWFyY2hDb250ZW50IGNvbnRlbnQsIFByZWRpY2F0ZSBwcmVkaWNhdGUsIGludCBjbGF1c2VOdW1iZXIpIHsKICAgICAgICAgICAgdGFibGVFbGVtZW50cy5hZGQobmV3IENhc2VTZWFyY2hXaGVuQ29udGVudEVsZW1lbnQoZ2V0RG9tYWluTW9kZWwoKSwgZ2V0U1FMU3RhdGVtZW50KCksIHNxbENhc2VTZWFyY2gsIGNvbnRlbnQsIHByZWRpY2F0ZSwgY2xhdXNlTnVtYmVyLAogICAgICAgICAgICAgICAgICAgIGZpcnN0Q2xhdXNlKSk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgY3JlYXRlQ2FzZUVsc2VDbGF1c2VFbGVtZW50KCkgewogICAgICAgICAgICB0YWJsZUVsZW1lbnRzLmFkZChuZXcgQ2FzZUVsc2VDbGF1c2VFbGVtZW50KHNxbENhc2VTZWFyY2gpKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGNsYXNzIENhc2VTZWFyY2hUYWJsZUNlbGxNb2RpZmllciBpbXBsZW1lbnRzIElDZWxsTW9kaWZpZXIgewoKICAgICAgICBDYXNlU2VhcmNoVGFibGUgdmlld2VyOwoKICAgICAgICBwdWJsaWMgQ2FzZVNlYXJjaFRhYmxlQ2VsbE1vZGlmaWVyKENhc2VTZWFyY2hUYWJsZSB2aWV3ZXIpIHsKICAgICAgICAgICAgdGhpcy52aWV3ZXIgPSB2aWV3ZXI7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBjYW5Nb2RpZnkoT2JqZWN0IGVsZW1lbnQsIFN0cmluZyBwcm9wZXJ0eSkgewogICAgICAgICAgICBpZiAocHJvcGVydHkuZXF1YWxzKENhc2VTZWFyY2hUYWJsZS5QX0xFRlRfRVhQUkVTU0lPTikgfHwgcHJvcGVydHkuZXF1YWxzKENhc2VTZWFyY2hUYWJsZS5QX09QRVJBVE9SKQogICAgICAgICAgICAgICAgICAgIHx8IHByb3BlcnR5LmVxdWFscyhDYXNlU2VhcmNoVGFibGUuUF9SSUdIVF9FWFBSRVNTSU9OKSB8fCBwcm9wZXJ0eS5lcXVhbHMoQ2FzZVNlYXJjaFRhYmxlLlBfQU5ET1IpCiAgICAgICAgICAgICAgICAgICAgfHwgcHJvcGVydHkuZXF1YWxzKENhc2VTZWFyY2hUYWJsZS5QX1JFU1VMVF9FWFBSRVNTSU9OKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0VmFsdWUoT2JqZWN0IGVsZW1lbnQsIFN0cmluZyBwcm9wZXJ0eSkgewogICAgICAgICAgICAvLyBUaGlzIGltcGxpY2l0bHkgdXNlcyB0aGUgZWxlbWVudCdzIHRvU3RyaW5nIG1ldGhvZAogICAgICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgICAgICB9CgogICAgICAgIE9iamVjdCBjdXJyZW50RWxlbWVudCwgY3VycmVudFZhbHVlOwogICAgICAgIFN0cmluZyBjdXJyZW50UHJvcGVydHk7CiAgICAgICAgQ2FzZVNlYXJjaFdoZW5Db250ZW50RWxlbWVudCBjb250ZW50RWxlbWVudDsKICAgICAgICBDYXNlRWxzZUNsYXVzZUVsZW1lbnQgZWxzZUVsZW1lbnQ7CiAgICAgICAgUXVlcnlWYWx1ZUV4cHJlc3Npb24gZXhwcjsKCiAgICAgICAgcHVibGljIHZvaWQgbW9kaWZ5KE9iamVjdCBlbGVtZW50LCBTdHJpbmcgcHJvcGVydHksIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgICBjdXJyZW50RWxlbWVudCA9IGVsZW1lbnQ7CiAgICAgICAgICAgIGN1cnJlbnRQcm9wZXJ0eSA9IHByb3BlcnR5OwogICAgICAgICAgICBjdXJyZW50VmFsdWUgPSB2YWx1ZTsKCiAgICAgICAgICAgIGlmIChwcm9wZXJ0eS5lcXVhbHMoQ2FzZVNlYXJjaFRhYmxlLlBfTEVGVF9FWFBSRVNTSU9OKSB8fCBwcm9wZXJ0eS5lcXVhbHMoQ2FzZVNlYXJjaFRhYmxlLlBfUklHSFRfRVhQUkVTU0lPTikKICAgICAgICAgICAgICAgICAgICB8fCBwcm9wZXJ0eS5lcXVhbHMoQ2FzZVNlYXJjaFRhYmxlLlBfUkVTVUxUX0VYUFJFU1NJT04pKSB7CiAgICAgICAgICAgICAgICBBc3NlcnQuaXNUcnVlKGN1cnJlbnRFbGVtZW50IGluc3RhbmNlb2YgVGFibGVJdGVtKTsKICAgICAgICAgICAgICAgIE9iamVjdCBkYXRhID0gKChUYWJsZUl0ZW0pIGN1cnJlbnRFbGVtZW50KS5nZXREYXRhKCk7CgogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChkYXRhIGluc3RhbmNlb2YgQ2FzZVNlYXJjaFdoZW5Db250ZW50RWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50ID0gKENhc2VTZWFyY2hXaGVuQ29udGVudEVsZW1lbnQpIGRhdGE7CgogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50VmFsdWUgaW5zdGFuY2VvZiBRdWVyeVZhbHVlRXhwcmVzc2lvbikgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudFZhbHVlIGluc3RhbmNlb2YgVmFsdWVFeHByZXNzaW9uQ29sdW1uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3FtcC1uYgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9TUUxDb3B5SGVscGVyIGNoID0gbmV3IFNRTENvcHlIZWxwZXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZXhwciA9IGNoLmNsb25lRXhwcmVzc2lvbigoU1FMQ29sdW1uRXhwcmVzc2lvbiljdXJyZW50VmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwciA9IEV4cHJlc3Npb25IZWxwZXIuY3JlYXRlVmFsdWVFeHByZXNzaW9uQ29sdW1uKChWYWx1ZUV4cHJlc3Npb25Db2x1bW4pIGN1cnJlbnRWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudFZhbHVlIGluc3RhbmNlb2YgVmFsdWVFeHByZXNzaW9uU2ltcGxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1NRTENvcHlIZWxwZXIgY2ggPSBuZXcgU1FMQ29weUhlbHBlcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9leHByID0gY2guY2xvbmVFeHByZXNzaW9uKChTUUxTaW1wbGVFeHByZXNzaW9uKWN1cnJlbnRWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHByID0gKFZhbHVlRXhwcmVzc2lvblNpbXBsZSkgY3VycmVudFZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwciA9IChRdWVyeVZhbHVlRXhwcmVzc2lvbikgY3VycmVudFZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydHkuZXF1YWxzKENhc2VTZWFyY2hUYWJsZS5QX0xFRlRfRVhQUkVTU0lPTikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50LnNldExlZnRFeHByZXNzaW9uKGV4cHIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHByb3BlcnR5LmVxdWFscyhDYXNlU2VhcmNoVGFibGUuUF9SSUdIVF9FWFBSRVNTSU9OKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnQuc2V0UmlnaHRFeHByZXNzaW9uKGV4cHIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHByb3BlcnR5LmVxdWFscyhDYXNlU2VhcmNoVGFibGUuUF9SRVNVTFRfRVhQUkVTU0lPTikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50LnNldFJlc3VsdEV4cHJlc3Npb24oZXhwcik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIERpc3BsYXkuZ2V0Q3VycmVudCgpLmFzeW5jRXhlYyhuZXcgUnVubmFibGUoKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdlci5yZWZyZXNoKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q2FzZVNlYXJjaFBhZ2UoKS51cGRhdGVGaW5pc2hCdXR0b24oKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudFZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZVN0cmluZyA9IChTdHJpbmcpIGN1cnJlbnRWYWx1ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50RWxlbWVudC5nZXRQcmVkaWNhdGUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudC5jcmVhdGVTZWFyY2hDb25kaXRpb24oKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IGN1cnJFeHByID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnR5LmVxdWFscyhDYXNlU2VhcmNoVGFibGUuUF9MRUZUX0VYUFJFU1NJT04pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyRXhwciA9IGNvbnRlbnRFbGVtZW50LmdldExlZnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eS5lcXVhbHMoQ2FzZVNlYXJjaFRhYmxlLlBfUklHSFRfRVhQUkVTU0lPTikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJFeHByID0gY29udGVudEVsZW1lbnQuZ2V0UmlnaHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eS5lcXVhbHMoQ2FzZVNlYXJjaFRhYmxlLlBfUkVTVUxUX0VYUFJFU1NJT04pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyRXhwciA9IGNvbnRlbnRFbGVtZW50LmdldFJlc3VsdCgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGdldENhc2VTZWFyY2hQYWdlKCkuc2V0RWxlbWVudFRvVXBkYXRlKGNvbnRlbnRFbGVtZW50KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZVN0cmluZy5lcXVhbHMoU1FMQnVpbGRlckNvbnN0YW50cy5QX0JVSUxEX0VYUFJFU1NJT04pIHx8IHZhbHVlU3RyaW5nLmVxdWFscyhTUUxCdWlsZGVyQ29uc3RhbnRzLlBfRURJVF9FWFBSRVNTSU9OKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHZhbHVlU3RyaW5nLmVxdWFscyhTUUxCdWlsZGVyQ29uc3RhbnRzLlBfUkVQTEFDRV9FWFBSRVNTSU9OKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhwcmVzc2lvbkJ1aWxkZXJXaXphcmQgd2l6YXJkOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpemFyZCA9IG5ldyBFeHByZXNzaW9uQnVpbGRlcldpemFyZChnZXREb21haW5Nb2RlbCgpLCBnZXRTUUxTdGF0ZW1lbnQoKSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlU3RyaW5nLmVxdWFscyhTUUxCdWlsZGVyQ29uc3RhbnRzLlBfQlVJTERfRVhQUkVTU0lPTikgfHwgdmFsdWVTdHJpbmcuZXF1YWxzKFNRTEJ1aWxkZXJDb25zdGFudHMuUF9SRVBMQUNFX0VYUFJFU1NJT04pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l6YXJkLnNldElucHV0RXhwcmVzc2lvbihudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlU3RyaW5nLmVxdWFscyhTUUxCdWlsZGVyQ29uc3RhbnRzLlBfRURJVF9FWFBSRVNTSU9OKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpemFyZC5zZXRJbnB1dEV4cHJlc3Npb24oKFF1ZXJ5VmFsdWVFeHByZXNzaW9uKSBjdXJyRXhwcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l6YXJkLnNldElzQ29sdW1uKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4cHJlc3Npb25CdWlsZGVyRGlhbG9nIGRpYWxvZyA9IG5ldyBFeHByZXNzaW9uQnVpbGRlckRpYWxvZyhEaXNwbGF5LmdldERlZmF1bHQoKS5nZXRBY3RpdmVTaGVsbCgpLCB3aXphcmQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmNyZWF0ZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nLnNldEJsb2NrT25PcGVuKHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHJlc3VsdCA9IGRpYWxvZy5vcGVuKCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnlWYWx1ZUV4cHJlc3Npb24gbmV3RXhwciA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdFeHByID0gd2l6YXJkLmdldFNRTEV4cHJlc3Npb24oKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3RXhwciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnR5LmVxdWFscyhDYXNlU2VhcmNoVGFibGUuUF9MRUZUX0VYUFJFU1NJT04pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50LnNldExlZnRFeHByZXNzaW9uKG5ld0V4cHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eS5lcXVhbHMoQ2FzZVNlYXJjaFRhYmxlLlBfUklHSFRfRVhQUkVTU0lPTikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnQuc2V0UmlnaHRFeHByZXNzaW9uKG5ld0V4cHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eS5lcXVhbHMoQ2FzZVNlYXJjaFRhYmxlLlBfUkVTVUxUX0VYUFJFU1NJT04pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50LnNldFJlc3VsdEV4cHJlc3Npb24obmV3RXhwcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaXNwbGF5LmdldEN1cnJlbnQoKS5hc3luY0V4ZWMobmV3IFJ1bm5hYmxlKCkgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgcnVuKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld2VyLnJlZnJlc2goKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q2FzZVNlYXJjaFBhZ2UoKS51cGRhdGVGaW5pc2hCdXR0b24oKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChkYXRhIGluc3RhbmNlb2YgQ2FzZUVsc2VDbGF1c2VFbGVtZW50KSB7CiAgICAgICAgICAgICAgICAgICAgZWxzZUVsZW1lbnQgPSAoQ2FzZUVsc2VDbGF1c2VFbGVtZW50KSBkYXRhOwoKICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudFZhbHVlIGluc3RhbmNlb2YgUXVlcnlWYWx1ZUV4cHJlc3Npb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSBpbnN0YW5jZW9mIFZhbHVlRXhwcmVzc2lvbkNvbHVtbikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwciA9IEV4cHJlc3Npb25IZWxwZXIuY3JlYXRlVmFsdWVFeHByZXNzaW9uQ29sdW1uKChWYWx1ZUV4cHJlc3Npb25Db2x1bW4pIGN1cnJlbnRWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudFZhbHVlIGluc3RhbmNlb2YgVmFsdWVFeHByZXNzaW9uU2ltcGxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHByID0gKFZhbHVlRXhwcmVzc2lvblNpbXBsZSkgY3VycmVudFZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwciA9IChRdWVyeVZhbHVlRXhwcmVzc2lvbikgY3VycmVudFZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydHkuZXF1YWxzKENhc2VTZWFyY2hUYWJsZS5QX0xFRlRfRVhQUkVTU0lPTikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VFbGVtZW50LnNldFJlc3VsdChleHByKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgRGlzcGxheS5nZXRDdXJyZW50KCkuYXN5bmNFeGVjKG5ldyBSdW5uYWJsZSgpIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld2VyLnJlZnJlc2goKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgICAgICBnZXRDYXNlU2VhcmNoUGFnZSgpLnVwZGF0ZUZpbmlzaEJ1dHRvbigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyZW50VmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHZhbHVlU3RyaW5nID0gKFN0cmluZykgY3VycmVudFZhbHVlOwoKICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IGN1cnJFeHByID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnR5LmVxdWFscyhDYXNlU2VhcmNoVGFibGUuUF9MRUZUX0VYUFJFU1NJT04pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyRXhwciA9IGVsc2VFbGVtZW50LmdldFJlc3VsdCgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGdldENhc2VTZWFyY2hQYWdlKCkuc2V0RWxlbWVudFRvVXBkYXRlKGNvbnRlbnRFbGVtZW50KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZVN0cmluZy5lcXVhbHMoU1FMQnVpbGRlckNvbnN0YW50cy5QX0JVSUxEX0VYUFJFU1NJT04pIHx8IHZhbHVlU3RyaW5nLmVxdWFscyhTUUxCdWlsZGVyQ29uc3RhbnRzLlBfRURJVF9FWFBSRVNTSU9OKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHZhbHVlU3RyaW5nLmVxdWFscyhTUUxCdWlsZGVyQ29uc3RhbnRzLlBfUkVQTEFDRV9FWFBSRVNTSU9OKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhwcmVzc2lvbkJ1aWxkZXJXaXphcmQgd2l6YXJkOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpemFyZCA9IG5ldyBFeHByZXNzaW9uQnVpbGRlcldpemFyZChnZXREb21haW5Nb2RlbCgpLCBnZXRTUUxTdGF0ZW1lbnQoKSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlU3RyaW5nLmVxdWFscyhTUUxCdWlsZGVyQ29uc3RhbnRzLlBfQlVJTERfRVhQUkVTU0lPTikgfHwgdmFsdWVTdHJpbmcuZXF1YWxzKFNRTEJ1aWxkZXJDb25zdGFudHMuUF9SRVBMQUNFX0VYUFJFU1NJT04pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l6YXJkLnNldElucHV0RXhwcmVzc2lvbihudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlU3RyaW5nLmVxdWFscyhTUUxCdWlsZGVyQ29uc3RhbnRzLlBfRURJVF9FWFBSRVNTSU9OKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpemFyZC5zZXRJbnB1dEV4cHJlc3Npb24oKFF1ZXJ5VmFsdWVFeHByZXNzaW9uKSBjdXJyRXhwcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l6YXJkLnNldElzQ29sdW1uKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4cHJlc3Npb25CdWlsZGVyRGlhbG9nIGRpYWxvZyA9IG5ldyBFeHByZXNzaW9uQnVpbGRlckRpYWxvZyhEaXNwbGF5LmdldERlZmF1bHQoKS5nZXRBY3RpdmVTaGVsbCgpLCB3aXphcmQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nLmNyZWF0ZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nLnNldEJsb2NrT25PcGVuKHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHJlc3VsdCA9IGRpYWxvZy5vcGVuKCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnlWYWx1ZUV4cHJlc3Npb24gbmV3RXhwciA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdFeHByID0gd2l6YXJkLmdldFNRTEV4cHJlc3Npb24oKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3RXhwciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnR5LmVxdWFscyhDYXNlU2VhcmNoVGFibGUuUF9MRUZUX0VYUFJFU1NJT04pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VFbGVtZW50LnNldFJlc3VsdChuZXdFeHByKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERpc3BsYXkuZ2V0Q3VycmVudCgpLmFzeW5jRXhlYyhuZXcgUnVubmFibGUoKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3ZXIucmVmcmVzaCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRDYXNlU2VhcmNoUGFnZSgpLnVwZGF0ZUZpbmlzaEJ1dHRvbigpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChwcm9wZXJ0eS5lcXVhbHMoQ2FzZVNlYXJjaFRhYmxlLlBfT1BFUkFUT1IpKSB7CiAgICAgICAgICAgICAgICBBc3NlcnQuaXNUcnVlKGVsZW1lbnQgaW5zdGFuY2VvZiBUYWJsZUl0ZW0pOwogICAgICAgICAgICAgICAgT2JqZWN0IGRhdGEgPSAoKFRhYmxlSXRlbSkgY3VycmVudEVsZW1lbnQpLmdldERhdGEoKTsKCiAgICAgICAgICAgICAgICBpZiAoY3VycmVudFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBDYXNlU2VhcmNoV2hlbkNvbnRlbnRFbGVtZW50KSB7CiAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnQgPSAoQ2FzZVNlYXJjaFdoZW5Db250ZW50RWxlbWVudCkgZGF0YTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudC5zZXRPcGVyYXRvcigoU3RyaW5nKSBjdXJyZW50VmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICBEaXNwbGF5LmdldEN1cnJlbnQoKS5hc3luY0V4ZWMobmV3IFJ1bm5hYmxlKCkgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3ZXIucmVmcmVzaCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGdldENhc2VTZWFyY2hQYWdlKCkudXBkYXRlRmluaXNoQnV0dG9uKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHByb3BlcnR5LmVxdWFscyhDYXNlU2VhcmNoVGFibGUuUF9BTkRPUikpIHsKICAgICAgICAgICAgICAgIEFzc2VydC5pc1RydWUoZWxlbWVudCBpbnN0YW5jZW9mIFRhYmxlSXRlbSk7CiAgICAgICAgICAgICAgICBPYmplY3QgZGF0YSA9ICgoVGFibGVJdGVtKSBjdXJyZW50RWxlbWVudCkuZ2V0RGF0YSgpOwoKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50VmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoZGF0YSBpbnN0YW5jZW9mIENhc2VTZWFyY2hXaGVuQ29udGVudEVsZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudCA9IChDYXNlU2VhcmNoV2hlbkNvbnRlbnRFbGVtZW50KSBkYXRhOwoKICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudFZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKChTdHJpbmcpIGN1cnJlbnRWYWx1ZSkuZXF1YWxzKCIiKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnQuc2V0QW5kT3IoY3VycmVudFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERpc3BsYXkuZ2V0Q3VycmVudCgpLmFzeW5jRXhlYyhuZXcgUnVubmFibGUoKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld2VyLnJlZnJlc2goKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBnZXRDYXNlU2VhcmNoUGFnZSgpLnVwZGF0ZUZpbmlzaEJ1dHRvbigpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICB9CgogICAgY2xhc3MgQ2FzZVNlYXJjaFRhYmxlTGFiZWxQcm92aWRlciBleHRlbmRzIExhYmVsUHJvdmlkZXIgaW1wbGVtZW50cyBJVGFibGVMYWJlbFByb3ZpZGVyIHsKCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRDb2x1bW5UZXh0KE9iamVjdCBvYmplY3QsIGludCBjb2x1bW5JbmRleCkgewogICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQ2FzZVNlYXJjaFdoZW5Db250ZW50RWxlbWVudCkgewogICAgICAgICAgICAgICAgQ2FzZVNlYXJjaFdoZW5Db250ZW50RWxlbWVudCBjb250ZW50RWxlbWVudCA9IChDYXNlU2VhcmNoV2hlbkNvbnRlbnRFbGVtZW50KSBvYmplY3Q7CiAgICAgICAgICAgICAgICByZXR1cm4gY29udGVudEVsZW1lbnQuZ2V0Q29sdW1uVGV4dChjb2x1bW5JbmRleCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAob2JqZWN0IGluc3RhbmNlb2YgQ2FzZUVsc2VDbGF1c2VFbGVtZW50KSB7CiAgICAgICAgICAgICAgICBDYXNlRWxzZUNsYXVzZUVsZW1lbnQgZWxzZUVsZW1lbnQgPSAoQ2FzZUVsc2VDbGF1c2VFbGVtZW50KSBvYmplY3Q7CiAgICAgICAgICAgICAgICByZXR1cm4gZWxzZUVsZW1lbnQuZ2V0Q29sdW1uVGV4dChjb2x1bW5JbmRleCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIEltYWdlIGdldENvbHVtbkltYWdlKE9iamVjdCBvYmplY3QsIGludCBjb2x1bW5JbmRleCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9Cn0=