LyoqCiAqIENvcHlyaWdodCAoYykgMjAxOCBDRUEKICogCiAqICBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqICBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKICogIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqICBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKiAKICogQ29udHJpYnV0b3JzOgogKiAgIErpcultaWUgVGF0aWJvdWV0IChDRUEpIGplcmVtaWUudGF0aWJvdWV0QGNlYS5mciAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKiAgIEJlbm9pdCBNYWdnaSAoQ0VBKSBiZW5vaXQubWFnZ2lAY2VhLmZyIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgU2h1YWkgTGkgKENFQSkgc2h1YWkubGlAY2VhLmZyIC0gSW50ZWdyYXRpb24gb2Ygc2Vuc2lOYWN0IGFuZCBXZWIgb2YgVGhpbmdzIFRoaW5nIERlc2NyaXB0aW9uCiAqIAogKi8KcGFja2FnZSBvcmcuZWNsaXBzZS5wYXB5cnVzLmlvdG1sLndvdC5pbXBsOwoKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5jb21tb24ubm90aWZ5Lk5vdGlmaWNhdGlvbjsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLnV0aWwuRUxpc3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLnV0aWwuVW5pcXVlRUxpc3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWNvcmUuRUNsYXNzOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS5JbnRlcm5hbEVPYmplY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWNvcmUuaW1wbC5FTm90aWZpY2F0aW9uSW1wbDsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWNvcmUuaW1wbC5NaW5pbWFsRU9iamVjdEltcGw7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWNvcmUudXRpbC5FRGF0YVR5cGVVbmlxdWVFTGlzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS51dGlsLkVPYmplY3RSZXNvbHZpbmdFTGlzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLnBhcHlydXMuaW90bWwud290LkZvcm07CmltcG9ydCBvcmcuZWNsaXBzZS5wYXB5cnVzLmlvdG1sLndvdC5PcEtpbmQ7CmltcG9ydCBvcmcuZWNsaXBzZS5wYXB5cnVzLmlvdG1sLndvdC5TZWN1cml0eVNjaGVtZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnBhcHlydXMuaW90bWwud290LlN1YlByb3RvY29sS2luZDsKaW1wb3J0IG9yZy5lY2xpcHNlLnBhcHlydXMuaW90bWwud290LldvVFBhY2thZ2U7CmltcG9ydCBvcmcuZWNsaXBzZS51bWwyLnVtbC5Db21tZW50OwoKaW1wb3J0IGNvbS5mYXN0ZXJ4bWwuamFja3Nvbi5hbm5vdGF0aW9uLkpzb25HZXR0ZXI7CmltcG9ydCBjb20uZmFzdGVyeG1sLmphY2tzb24uYW5ub3RhdGlvbi5Kc29uSWdub3JlOwppbXBvcnQgY29tLmZhc3RlcnhtbC5qYWNrc29uLmFubm90YXRpb24uSnNvblByb3BlcnR5T3JkZXI7CgovKioKICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KICogQW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIG1vZGVsIG9iamVjdCAnPGVtPjxiPkZvcm08L2I+PC9lbT4nLgogKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KICogPHA+CiAqIFRoZSBmb2xsb3dpbmcgZmVhdHVyZXMgYXJlIGltcGxlbWVudGVkOgogKiA8L3A+CiAqIDx1bD4KICogICA8bGk+e0BsaW5rIG9yZy5lY2xpcHNlLnBhcHlydXMuaW90bWwud290LmltcGwuRm9ybUltcGwjZ2V0T3AgPGVtPk9wPC9lbT59PC9saT4KICogICA8bGk+e0BsaW5rIG9yZy5lY2xpcHNlLnBhcHlydXMuaW90bWwud290LmltcGwuRm9ybUltcGwjZ2V0SHJlZiA8ZW0+SHJlZjwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5wYXB5cnVzLmlvdG1sLndvdC5pbXBsLkZvcm1JbXBsI2dldENvbnRlbnRUeXBlIDxlbT5Db250ZW50IFR5cGU8L2VtPn08L2xpPgogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2UucGFweXJ1cy5pb3RtbC53b3QuaW1wbC5Gb3JtSW1wbCNnZXRDb250ZW50Q29kaW5nIDxlbT5Db250ZW50IENvZGluZzwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5wYXB5cnVzLmlvdG1sLndvdC5pbXBsLkZvcm1JbXBsI2dldFN1YlByb3RvY29sIDxlbT5TdWIgUHJvdG9jb2w8L2VtPn08L2xpPgogKiAgIDxsaT57QGxpbmsgb3JnLmVjbGlwc2UucGFweXJ1cy5pb3RtbC53b3QuaW1wbC5Gb3JtSW1wbCNnZXRTY29wZXMgPGVtPlNjb3BlczwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5wYXB5cnVzLmlvdG1sLndvdC5pbXBsLkZvcm1JbXBsI2dldFJlc3BvbnNlIDxlbT5SZXNwb25zZTwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5wYXB5cnVzLmlvdG1sLndvdC5pbXBsLkZvcm1JbXBsI2dldFNlY3VyaXR5IDxlbT5TZWN1cml0eTwvZW0+fTwvbGk+CiAqICAgPGxpPntAbGluayBvcmcuZWNsaXBzZS5wYXB5cnVzLmlvdG1sLndvdC5pbXBsLkZvcm1JbXBsI2dldEJhc2VfQ29tbWVudCA8ZW0+QmFzZSBDb21tZW50PC9lbT59PC9saT4KICogPC91bD4KICoKICogQGdlbmVyYXRlZAogKi8KQEpzb25Qcm9wZXJ0eU9yZGVyKHsib3AiLCAiaHJlZiIsICJjb250ZW50VHlwZSIsICJjb250ZW50Q29kaW5nIiwgInN1YlByb3RvY29sIiwgInNlY3VyaXR5IiwgInNjb3BlcyIsICJyZXNwb25zZSJ9KQpwdWJsaWMgY2xhc3MgRm9ybUltcGwgZXh0ZW5kcyBNaW5pbWFsRU9iamVjdEltcGwuQ29udGFpbmVyIGltcGxlbWVudHMgRm9ybSB7CgkvKioKCSAqIFRoZSBjYWNoZWQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldE9wKCkgPGVtPk9wPC9lbT59JyBhdHRyaWJ1dGUgbGlzdC4KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBzZWUgI2dldE9wKCkKCSAqIEBnZW5lcmF0ZWQKCSAqIEBvcmRlcmVkCgkgKi8KCXByb3RlY3RlZCBFTGlzdDxPcEtpbmQ+IG9wOwoKCS8qKgoJICogVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldEhyZWYoKSA8ZW0+SHJlZjwvZW0+fScgYXR0cmlidXRlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHNlZSAjZ2V0SHJlZigpCgkgKiBAZ2VuZXJhdGVkCgkgKiBAb3JkZXJlZAoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBIUkVGX0VERUZBVUxUID0gbnVsbDsKCgkvKioKCSAqIFRoZSBjYWNoZWQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldEhyZWYoKSA8ZW0+SHJlZjwvZW0+fScgYXR0cmlidXRlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHNlZSAjZ2V0SHJlZigpCgkgKiBAZ2VuZXJhdGVkCgkgKiBAb3JkZXJlZAoJICovCglwcm90ZWN0ZWQgU3RyaW5nIGhyZWYgPSBIUkVGX0VERUZBVUxUOwoKCS8qKgoJICogVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldENvbnRlbnRUeXBlKCkgPGVtPkNvbnRlbnQgVHlwZTwvZW0+fScgYXR0cmlidXRlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHNlZSAjZ2V0Q29udGVudFR5cGUoKQoJICogQGdlbmVyYXRlZAoJICogQG9yZGVyZWQKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVEVOVF9UWVBFX0VERUZBVUxUID0gImFwcGxpY2F0aW9uL2pzb24iOwoKCS8qKgoJICogVGhlIGNhY2hlZCB2YWx1ZSBvZiB0aGUgJ3tAbGluayAjZ2V0Q29udGVudFR5cGUoKSA8ZW0+Q29udGVudCBUeXBlPC9lbT59JyBhdHRyaWJ1dGUuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAc2VlICNnZXRDb250ZW50VHlwZSgpCgkgKiBAZ2VuZXJhdGVkCgkgKiBAb3JkZXJlZAoJICovCglwcm90ZWN0ZWQgU3RyaW5nIGNvbnRlbnRUeXBlID0gQ09OVEVOVF9UWVBFX0VERUZBVUxUOwoKCS8qKgoJICogVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldENvbnRlbnRDb2RpbmcoKSA8ZW0+Q29udGVudCBDb2Rpbmc8L2VtPn0nIGF0dHJpYnV0ZS4KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBzZWUgI2dldENvbnRlbnRDb2RpbmcoKQoJICogQGdlbmVyYXRlZAoJICogQG9yZGVyZWQKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVEVOVF9DT0RJTkdfRURFRkFVTFQgPSBudWxsOwoKCS8qKgoJICogVGhlIGNhY2hlZCB2YWx1ZSBvZiB0aGUgJ3tAbGluayAjZ2V0Q29udGVudENvZGluZygpIDxlbT5Db250ZW50IENvZGluZzwvZW0+fScgYXR0cmlidXRlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHNlZSAjZ2V0Q29udGVudENvZGluZygpCgkgKiBAZ2VuZXJhdGVkCgkgKiBAb3JkZXJlZAoJICovCglwcm90ZWN0ZWQgU3RyaW5nIGNvbnRlbnRDb2RpbmcgPSBDT05URU5UX0NPRElOR19FREVGQVVMVDsKCgkvKioKCSAqIFRoZSBkZWZhdWx0IHZhbHVlIG9mIHRoZSAne0BsaW5rICNnZXRTdWJQcm90b2NvbCgpIDxlbT5TdWIgUHJvdG9jb2w8L2VtPn0nIGF0dHJpYnV0ZS4KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBzZWUgI2dldFN1YlByb3RvY29sKCkKCSAqIEBnZW5lcmF0ZWQKCSAqIEBvcmRlcmVkCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3ViUHJvdG9jb2xLaW5kIFNVQl9QUk9UT0NPTF9FREVGQVVMVCA9IFN1YlByb3RvY29sS2luZC5OT05FOwoKCS8qKgoJICogVGhlIGNhY2hlZCB2YWx1ZSBvZiB0aGUgJ3tAbGluayAjZ2V0U3ViUHJvdG9jb2woKSA8ZW0+U3ViIFByb3RvY29sPC9lbT59JyBhdHRyaWJ1dGUuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAc2VlICNnZXRTdWJQcm90b2NvbCgpCgkgKiBAZ2VuZXJhdGVkCgkgKiBAb3JkZXJlZAoJICovCglwcm90ZWN0ZWQgU3ViUHJvdG9jb2xLaW5kIHN1YlByb3RvY29sID0gU1VCX1BST1RPQ09MX0VERUZBVUxUOwoKCS8qKgoJICogVGhlIGNhY2hlZCB2YWx1ZSBvZiB0aGUgJ3tAbGluayAjZ2V0U2NvcGVzKCkgPGVtPlNjb3BlczwvZW0+fScgYXR0cmlidXRlIGxpc3QuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAc2VlICNnZXRTY29wZXMoKQoJICogQGdlbmVyYXRlZAoJICogQG9yZGVyZWQKCSAqLwoJcHJvdGVjdGVkIEVMaXN0PFN0cmluZz4gc2NvcGVzOwoKCS8qKgoJICogVGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldFJlc3BvbnNlKCkgPGVtPlJlc3BvbnNlPC9lbT59JyBhdHRyaWJ1dGUuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAc2VlICNnZXRSZXNwb25zZSgpCgkgKiBAZ2VuZXJhdGVkCgkgKiBAb3JkZXJlZAoJICovCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNQT05TRV9FREVGQVVMVCA9ICJhcHBsaWNhdGlvbi9qc29uIjsKCgkvKioKCSAqIFRoZSBjYWNoZWQgdmFsdWUgb2YgdGhlICd7QGxpbmsgI2dldFJlc3BvbnNlKCkgPGVtPlJlc3BvbnNlPC9lbT59JyBhdHRyaWJ1dGUuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAc2VlICNnZXRSZXNwb25zZSgpCgkgKiBAZ2VuZXJhdGVkCgkgKiBAb3JkZXJlZAoJICovCglwcm90ZWN0ZWQgU3RyaW5nIHJlc3BvbnNlID0gUkVTUE9OU0VfRURFRkFVTFQ7CgoJLyoqCgkgKiBUaGUgY2FjaGVkIHZhbHVlIG9mIHRoZSAne0BsaW5rICNnZXRTZWN1cml0eSgpIDxlbT5TZWN1cml0eTwvZW0+fScgcmVmZXJlbmNlIGxpc3QuCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAc2VlICNnZXRTZWN1cml0eSgpCgkgKiBAZ2VuZXJhdGVkCgkgKiBAb3JkZXJlZAoJICovCglwcm90ZWN0ZWQgRUxpc3Q8U2VjdXJpdHlTY2hlbWU+IHNlY3VyaXR5OwoKCS8qKgoJICogVGhlIGNhY2hlZCB2YWx1ZSBvZiB0aGUgJ3tAbGluayAjZ2V0QmFzZV9Db21tZW50KCkgPGVtPkJhc2UgQ29tbWVudDwvZW0+fScgcmVmZXJlbmNlLgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQHNlZSAjZ2V0QmFzZV9Db21tZW50KCkKCSAqIEBnZW5lcmF0ZWQKCSAqIEBvcmRlcmVkCgkgKi8KCXByb3RlY3RlZCBDb21tZW50IGJhc2VfQ29tbWVudDsKCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIEZvcm1JbXBsKCkgewoJCXN1cGVyKCk7Cgl9CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUBPdmVycmlkZQoJcHJvdGVjdGVkIEVDbGFzcyBlU3RhdGljQ2xhc3MoKSB7CgkJcmV0dXJuIFdvVFBhY2thZ2UuTGl0ZXJhbHMuRk9STTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQE92ZXJyaWRlCglASnNvbkdldHRlcigib3AiKQoJcHVibGljIEVMaXN0PE9wS2luZD4gZ2V0T3AoKSB7CgkJaWYgKG9wID09IG51bGwpIHsKCQkJb3AgPSBuZXcgRURhdGFUeXBlVW5pcXVlRUxpc3Q8T3BLaW5kPihPcEtpbmQuY2xhc3MsIHRoaXMsIFdvVFBhY2thZ2UuRk9STV9fT1ApOwoJCX0KCQlyZXR1cm4gb3A7Cgl9CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUBPdmVycmlkZQoJQEpzb25HZXR0ZXIoIm9wIikKCXB1YmxpYyBTdHJpbmcgZ2V0SHJlZigpIHsKCQlyZXR1cm4gaHJlZjsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQE92ZXJyaWRlCglASnNvbklnbm9yZQoJcHVibGljIHZvaWQgc2V0SHJlZihTdHJpbmcgbmV3SHJlZikgewoJCVN0cmluZyBvbGRIcmVmID0gaHJlZjsKCQlocmVmID0gbmV3SHJlZjsKCQlpZiAoZU5vdGlmaWNhdGlvblJlcXVpcmVkKCkpCgkJCWVOb3RpZnkobmV3IEVOb3RpZmljYXRpb25JbXBsKHRoaXMsIE5vdGlmaWNhdGlvbi5TRVQsIFdvVFBhY2thZ2UuRk9STV9fSFJFRiwgb2xkSHJlZiwgaHJlZikpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAT3ZlcnJpZGUKCUBKc29uR2V0dGVyKCJjb250ZW50VHlwZSIpCglwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRUeXBlKCkgewoJCXJldHVybiBjb250ZW50VHlwZTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQE92ZXJyaWRlCglASnNvbklnbm9yZQoJcHVibGljIHZvaWQgc2V0Q29udGVudFR5cGUoU3RyaW5nIG5ld0NvbnRlbnRUeXBlKSB7CgkJU3RyaW5nIG9sZENvbnRlbnRUeXBlID0gY29udGVudFR5cGU7CgkJY29udGVudFR5cGUgPSBuZXdDb250ZW50VHlwZTsKCQlpZiAoZU5vdGlmaWNhdGlvblJlcXVpcmVkKCkpCgkJCWVOb3RpZnkobmV3IEVOb3RpZmljYXRpb25JbXBsKHRoaXMsIE5vdGlmaWNhdGlvbi5TRVQsIFdvVFBhY2thZ2UuRk9STV9fQ09OVEVOVF9UWVBFLCBvbGRDb250ZW50VHlwZSwgY29udGVudFR5cGUpKTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQE92ZXJyaWRlCglASnNvbkdldHRlcigiY29udGVudENvZGluZyIpCglwdWJsaWMgU3RyaW5nIGdldENvbnRlbnRDb2RpbmcoKSB7CgkJcmV0dXJuIGNvbnRlbnRDb2Rpbmc7Cgl9CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUBPdmVycmlkZQoJQEpzb25JZ25vcmUKCXB1YmxpYyB2b2lkIHNldENvbnRlbnRDb2RpbmcoU3RyaW5nIG5ld0NvbnRlbnRDb2RpbmcpIHsKCQlTdHJpbmcgb2xkQ29udGVudENvZGluZyA9IGNvbnRlbnRDb2Rpbmc7CgkJY29udGVudENvZGluZyA9IG5ld0NvbnRlbnRDb2Rpbmc7CgkJaWYgKGVOb3RpZmljYXRpb25SZXF1aXJlZCgpKQoJCQllTm90aWZ5KG5ldyBFTm90aWZpY2F0aW9uSW1wbCh0aGlzLCBOb3RpZmljYXRpb24uU0VULCBXb1RQYWNrYWdlLkZPUk1fX0NPTlRFTlRfQ09ESU5HLCBvbGRDb250ZW50Q29kaW5nLCBjb250ZW50Q29kaW5nKSk7Cgl9CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUBPdmVycmlkZQoJQEpzb25HZXR0ZXIoInN1YlByb3RvY29sIikKCXB1YmxpYyBTdWJQcm90b2NvbEtpbmQgZ2V0U3ViUHJvdG9jb2woKSB7CgkJcmV0dXJuIHN1YlByb3RvY29sOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAT3ZlcnJpZGUKCUBKc29uSWdub3JlCglwdWJsaWMgdm9pZCBzZXRTdWJQcm90b2NvbChTdWJQcm90b2NvbEtpbmQgbmV3U3ViUHJvdG9jb2wpIHsKCQlTdWJQcm90b2NvbEtpbmQgb2xkU3ViUHJvdG9jb2wgPSBzdWJQcm90b2NvbDsKCQlzdWJQcm90b2NvbCA9IG5ld1N1YlByb3RvY29sID09IG51bGwgPyBTVUJfUFJPVE9DT0xfRURFRkFVTFQgOiBuZXdTdWJQcm90b2NvbDsKCQlpZiAoZU5vdGlmaWNhdGlvblJlcXVpcmVkKCkpCgkJCWVOb3RpZnkobmV3IEVOb3RpZmljYXRpb25JbXBsKHRoaXMsIE5vdGlmaWNhdGlvbi5TRVQsIFdvVFBhY2thZ2UuRk9STV9fU1VCX1BST1RPQ09MLCBvbGRTdWJQcm90b2NvbCwgc3ViUHJvdG9jb2wpKTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQE92ZXJyaWRlCglASnNvbkdldHRlcigic2NvcGVzIikKCXB1YmxpYyBFTGlzdDxTdHJpbmc+IGdldFNjb3BlcygpIHsKCQlpZiAoc2NvcGVzID09IG51bGwpIHsKCQkJc2NvcGVzID0gbmV3IEVEYXRhVHlwZVVuaXF1ZUVMaXN0PFN0cmluZz4oU3RyaW5nLmNsYXNzLCB0aGlzLCBXb1RQYWNrYWdlLkZPUk1fX1NDT1BFUyk7CgkJfQoJCXJldHVybiBzY29wZXM7Cgl9CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUBPdmVycmlkZQoJQEpzb25HZXR0ZXIoInJlc3BvbnNlIikKCXB1YmxpYyBTdHJpbmcgZ2V0UmVzcG9uc2UoKSB7CgkJcmV0dXJuIHJlc3BvbnNlOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAT3ZlcnJpZGUKCUBKc29uSWdub3JlCglwdWJsaWMgdm9pZCBzZXRSZXNwb25zZShTdHJpbmcgbmV3UmVzcG9uc2UpIHsKCQlTdHJpbmcgb2xkUmVzcG9uc2UgPSByZXNwb25zZTsKCQlyZXNwb25zZSA9IG5ld1Jlc3BvbnNlOwoJCWlmIChlTm90aWZpY2F0aW9uUmVxdWlyZWQoKSkKCQkJZU5vdGlmeShuZXcgRU5vdGlmaWNhdGlvbkltcGwodGhpcywgTm90aWZpY2F0aW9uLlNFVCwgV29UUGFja2FnZS5GT1JNX19SRVNQT05TRSwgb2xkUmVzcG9uc2UsIHJlc3BvbnNlKSk7Cgl9CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUBPdmVycmlkZQoJQEpzb25JZ25vcmUKCXB1YmxpYyBFTGlzdDxTZWN1cml0eVNjaGVtZT4gZ2V0U2VjdXJpdHkoKSB7CgkJaWYgKHNlY3VyaXR5ID09IG51bGwpIHsKCQkJc2VjdXJpdHkgPSBuZXcgRU9iamVjdFJlc29sdmluZ0VMaXN0PFNlY3VyaXR5U2NoZW1lPihTZWN1cml0eVNjaGVtZS5jbGFzcywgdGhpcywgV29UUGFja2FnZS5GT1JNX19TRUNVUklUWSk7CgkJfQoJCXJldHVybiBzZWN1cml0eTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQE92ZXJyaWRlCglASnNvbklnbm9yZQoJcHVibGljIENvbW1lbnQgZ2V0QmFzZV9Db21tZW50KCkgewoJCWlmIChiYXNlX0NvbW1lbnQgIT0gbnVsbCAmJiBiYXNlX0NvbW1lbnQuZUlzUHJveHkoKSkgewoJCQlJbnRlcm5hbEVPYmplY3Qgb2xkQmFzZV9Db21tZW50ID0gKEludGVybmFsRU9iamVjdCliYXNlX0NvbW1lbnQ7CgkJCWJhc2VfQ29tbWVudCA9IChDb21tZW50KWVSZXNvbHZlUHJveHkob2xkQmFzZV9Db21tZW50KTsKCQkJaWYgKGJhc2VfQ29tbWVudCAhPSBvbGRCYXNlX0NvbW1lbnQpIHsKCQkJCWlmIChlTm90aWZpY2F0aW9uUmVxdWlyZWQoKSkKCQkJCQllTm90aWZ5KG5ldyBFTm90aWZpY2F0aW9uSW1wbCh0aGlzLCBOb3RpZmljYXRpb24uUkVTT0xWRSwgV29UUGFja2FnZS5GT1JNX19CQVNFX0NPTU1FTlQsIG9sZEJhc2VfQ29tbWVudCwgYmFzZV9Db21tZW50KSk7CgkJCX0KCQl9CgkJcmV0dXJuIGJhc2VfQ29tbWVudDsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHVibGljIENvbW1lbnQgYmFzaWNHZXRCYXNlX0NvbW1lbnQoKSB7CgkJcmV0dXJuIGJhc2VfQ29tbWVudDsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQE92ZXJyaWRlCglASnNvbklnbm9yZQoJcHVibGljIHZvaWQgc2V0QmFzZV9Db21tZW50KENvbW1lbnQgbmV3QmFzZV9Db21tZW50KSB7CgkJQ29tbWVudCBvbGRCYXNlX0NvbW1lbnQgPSBiYXNlX0NvbW1lbnQ7CgkJYmFzZV9Db21tZW50ID0gbmV3QmFzZV9Db21tZW50OwoJCWlmIChlTm90aWZpY2F0aW9uUmVxdWlyZWQoKSkKCQkJZU5vdGlmeShuZXcgRU5vdGlmaWNhdGlvbkltcGwodGhpcywgTm90aWZpY2F0aW9uLlNFVCwgV29UUGFja2FnZS5GT1JNX19CQVNFX0NPTU1FTlQsIG9sZEJhc2VfQ29tbWVudCwgYmFzZV9Db21tZW50KSk7Cgl9CgoJLyoqCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPgoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+CgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUBPdmVycmlkZQoJcHVibGljIE9iamVjdCBlR2V0KGludCBmZWF0dXJlSUQsIGJvb2xlYW4gcmVzb2x2ZSwgYm9vbGVhbiBjb3JlVHlwZSkgewoJCXN3aXRjaCAoZmVhdHVyZUlEKSB7CgkJCWNhc2UgV29UUGFja2FnZS5GT1JNX19PUDoKCQkJCXJldHVybiBnZXRPcCgpOwoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fSFJFRjoKCQkJCXJldHVybiBnZXRIcmVmKCk7CgkJCWNhc2UgV29UUGFja2FnZS5GT1JNX19DT05URU5UX1RZUEU6CgkJCQlyZXR1cm4gZ2V0Q29udGVudFR5cGUoKTsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX0NPTlRFTlRfQ09ESU5HOgoJCQkJcmV0dXJuIGdldENvbnRlbnRDb2RpbmcoKTsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX1NVQl9QUk9UT0NPTDoKCQkJCXJldHVybiBnZXRTdWJQcm90b2NvbCgpOwoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fU0NPUEVTOgoJCQkJcmV0dXJuIGdldFNjb3BlcygpOwoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fUkVTUE9OU0U6CgkJCQlyZXR1cm4gZ2V0UmVzcG9uc2UoKTsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX1NFQ1VSSVRZOgoJCQkJcmV0dXJuIGdldFNlY3VyaXR5KCk7CgkJCWNhc2UgV29UUGFja2FnZS5GT1JNX19CQVNFX0NPTU1FTlQ6CgkJCQlpZiAocmVzb2x2ZSkgcmV0dXJuIGdldEJhc2VfQ29tbWVudCgpOwoJCQkJcmV0dXJuIGJhc2ljR2V0QmFzZV9Db21tZW50KCk7CgkJfQoJCXJldHVybiBzdXBlci5lR2V0KGZlYXR1cmVJRCwgcmVzb2x2ZSwgY29yZVR5cGUpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKCUBPdmVycmlkZQoJcHVibGljIHZvaWQgZVNldChpbnQgZmVhdHVyZUlELCBPYmplY3QgbmV3VmFsdWUpIHsKCQlzd2l0Y2ggKGZlYXR1cmVJRCkgewoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fT1A6CgkJCQlnZXRPcCgpLmNsZWFyKCk7CgkJCQlnZXRPcCgpLmFkZEFsbCgoQ29sbGVjdGlvbjw/IGV4dGVuZHMgT3BLaW5kPiluZXdWYWx1ZSk7CgkJCQlyZXR1cm47CgkJCWNhc2UgV29UUGFja2FnZS5GT1JNX19IUkVGOgoJCQkJc2V0SHJlZigoU3RyaW5nKW5ld1ZhbHVlKTsKCQkJCXJldHVybjsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX0NPTlRFTlRfVFlQRToKCQkJCXNldENvbnRlbnRUeXBlKChTdHJpbmcpbmV3VmFsdWUpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fQ09OVEVOVF9DT0RJTkc6CgkJCQlzZXRDb250ZW50Q29kaW5nKChTdHJpbmcpbmV3VmFsdWUpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fU1VCX1BST1RPQ09MOgoJCQkJc2V0U3ViUHJvdG9jb2woKFN1YlByb3RvY29sS2luZCluZXdWYWx1ZSk7CgkJCQlyZXR1cm47CgkJCWNhc2UgV29UUGFja2FnZS5GT1JNX19TQ09QRVM6CgkJCQlnZXRTY29wZXMoKS5jbGVhcigpOwoJCQkJZ2V0U2NvcGVzKCkuYWRkQWxsKChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBTdHJpbmc+KW5ld1ZhbHVlKTsKCQkJCXJldHVybjsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX1JFU1BPTlNFOgoJCQkJc2V0UmVzcG9uc2UoKFN0cmluZyluZXdWYWx1ZSk7CgkJCQlyZXR1cm47CgkJCWNhc2UgV29UUGFja2FnZS5GT1JNX19TRUNVUklUWToKCQkJCWdldFNlY3VyaXR5KCkuY2xlYXIoKTsKCQkJCWdldFNlY3VyaXR5KCkuYWRkQWxsKChDb2xsZWN0aW9uPD8gZXh0ZW5kcyBTZWN1cml0eVNjaGVtZT4pbmV3VmFsdWUpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fQkFTRV9DT01NRU5UOgoJCQkJc2V0QmFzZV9Db21tZW50KChDb21tZW50KW5ld1ZhbHVlKTsKCQkJCXJldHVybjsKCQl9CgkJc3VwZXIuZVNldChmZWF0dXJlSUQsIG5ld1ZhbHVlKTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQE92ZXJyaWRlCglwdWJsaWMgdm9pZCBlVW5zZXQoaW50IGZlYXR1cmVJRCkgewoJCXN3aXRjaCAoZmVhdHVyZUlEKSB7CgkJCWNhc2UgV29UUGFja2FnZS5GT1JNX19PUDoKCQkJCWdldE9wKCkuY2xlYXIoKTsKCQkJCXJldHVybjsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX0hSRUY6CgkJCQlzZXRIcmVmKEhSRUZfRURFRkFVTFQpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fQ09OVEVOVF9UWVBFOgoJCQkJc2V0Q29udGVudFR5cGUoQ09OVEVOVF9UWVBFX0VERUZBVUxUKTsKCQkJCXJldHVybjsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX0NPTlRFTlRfQ09ESU5HOgoJCQkJc2V0Q29udGVudENvZGluZyhDT05URU5UX0NPRElOR19FREVGQVVMVCk7CgkJCQlyZXR1cm47CgkJCWNhc2UgV29UUGFja2FnZS5GT1JNX19TVUJfUFJPVE9DT0w6CgkJCQlzZXRTdWJQcm90b2NvbChTVUJfUFJPVE9DT0xfRURFRkFVTFQpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fU0NPUEVTOgoJCQkJZ2V0U2NvcGVzKCkuY2xlYXIoKTsKCQkJCXJldHVybjsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX1JFU1BPTlNFOgoJCQkJc2V0UmVzcG9uc2UoUkVTUE9OU0VfRURFRkFVTFQpOwoJCQkJcmV0dXJuOwoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fU0VDVVJJVFk6CgkJCQlnZXRTZWN1cml0eSgpLmNsZWFyKCk7CgkJCQlyZXR1cm47CgkJCWNhc2UgV29UUGFja2FnZS5GT1JNX19CQVNFX0NPTU1FTlQ6CgkJCQlzZXRCYXNlX0NvbW1lbnQoKENvbW1lbnQpbnVsbCk7CgkJCQlyZXR1cm47CgkJfQoJCXN1cGVyLmVVbnNldChmZWF0dXJlSUQpOwoJfQoKCS8qKgoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPgoJICogQGdlbmVyYXRlZAoJICovCglAT3ZlcnJpZGUKCXB1YmxpYyBib29sZWFuIGVJc1NldChpbnQgZmVhdHVyZUlEKSB7CgkJc3dpdGNoIChmZWF0dXJlSUQpIHsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX09QOgoJCQkJcmV0dXJuIG9wICE9IG51bGwgJiYgIW9wLmlzRW1wdHkoKTsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX0hSRUY6CgkJCQlyZXR1cm4gSFJFRl9FREVGQVVMVCA9PSBudWxsID8gaHJlZiAhPSBudWxsIDogIUhSRUZfRURFRkFVTFQuZXF1YWxzKGhyZWYpOwoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fQ09OVEVOVF9UWVBFOgoJCQkJcmV0dXJuIENPTlRFTlRfVFlQRV9FREVGQVVMVCA9PSBudWxsID8gY29udGVudFR5cGUgIT0gbnVsbCA6ICFDT05URU5UX1RZUEVfRURFRkFVTFQuZXF1YWxzKGNvbnRlbnRUeXBlKTsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX0NPTlRFTlRfQ09ESU5HOgoJCQkJcmV0dXJuIENPTlRFTlRfQ09ESU5HX0VERUZBVUxUID09IG51bGwgPyBjb250ZW50Q29kaW5nICE9IG51bGwgOiAhQ09OVEVOVF9DT0RJTkdfRURFRkFVTFQuZXF1YWxzKGNvbnRlbnRDb2RpbmcpOwoJCQljYXNlIFdvVFBhY2thZ2UuRk9STV9fU1VCX1BST1RPQ09MOgoJCQkJcmV0dXJuIHN1YlByb3RvY29sICE9IFNVQl9QUk9UT0NPTF9FREVGQVVMVDsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX1NDT1BFUzoKCQkJCXJldHVybiBzY29wZXMgIT0gbnVsbCAmJiAhc2NvcGVzLmlzRW1wdHkoKTsKCQkJY2FzZSBXb1RQYWNrYWdlLkZPUk1fX1JFU1BPTlNFOgoJCQkJcmV0dXJuIFJFU1BPTlNFX0VERUZBVUxUID09IG51bGwgPyByZXNwb25zZSAhPSBudWxsIDogIVJFU1BPTlNFX0VERUZBVUxULmVxdWFscyhyZXNwb25zZSk7CgkJCWNhc2UgV29UUGFja2FnZS5GT1JNX19TRUNVUklUWToKCQkJCXJldHVybiBzZWN1cml0eSAhPSBudWxsICYmICFzZWN1cml0eS5pc0VtcHR5KCk7CgkJCWNhc2UgV29UUGFja2FnZS5GT1JNX19CQVNFX0NPTU1FTlQ6CgkJCQlyZXR1cm4gYmFzZV9Db21tZW50ICE9IG51bGw7CgkJfQoJCXJldHVybiBzdXBlci5lSXNTZXQoZmVhdHVyZUlEKTsKCX0KCgkvKioKCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+CgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4KCSAqIEBnZW5lcmF0ZWQKCSAqLwoJQE92ZXJyaWRlCglwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewoJCWlmIChlSXNQcm94eSgpKSByZXR1cm4gc3VwZXIudG9TdHJpbmcoKTsKCgkJU3RyaW5nQnVpbGRlciByZXN1bHQgPSBuZXcgU3RyaW5nQnVpbGRlcihzdXBlci50b1N0cmluZygpKTsKCQlyZXN1bHQuYXBwZW5kKCIgKG9wOiAiKTsKCQlyZXN1bHQuYXBwZW5kKG9wKTsKCQlyZXN1bHQuYXBwZW5kKCIsIGhyZWY6ICIpOwoJCXJlc3VsdC5hcHBlbmQoaHJlZik7CgkJcmVzdWx0LmFwcGVuZCgiLCBjb250ZW50VHlwZTogIik7CgkJcmVzdWx0LmFwcGVuZChjb250ZW50VHlwZSk7CgkJcmVzdWx0LmFwcGVuZCgiLCBjb250ZW50Q29kaW5nOiAiKTsKCQlyZXN1bHQuYXBwZW5kKGNvbnRlbnRDb2RpbmcpOwoJCXJlc3VsdC5hcHBlbmQoIiwgc3ViUHJvdG9jb2w6ICIpOwoJCXJlc3VsdC5hcHBlbmQoc3ViUHJvdG9jb2wpOwoJCXJlc3VsdC5hcHBlbmQoIiwgc2NvcGVzOiAiKTsKCQlyZXN1bHQuYXBwZW5kKHNjb3Blcyk7CgkJcmVzdWx0LmFwcGVuZCgiLCByZXNwb25zZTogIik7CgkJcmVzdWx0LmFwcGVuZChyZXNwb25zZSk7CgkJcmVzdWx0LmFwcGVuZCgnKScpOwoJCXJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKCX0KCQoJLyoqCgkgKiBTZWN1cml0eSBhdHRyaWJ1dGUgZ2V0dGVyIGZvciBKU09OIHNlcmlhbGl6YXRpb24KCSAqIEBnZW5lcmF0ZWQgTk9UCgkgKi8KCUBKc29uR2V0dGVyKCJzZWN1cml0eSIpCglwdWJsaWMgRUxpc3Q8U3RyaW5nPiBnZXRTZWN1cml0eUFzU3RyaW5nKCkgewoJCUVMaXN0PFN0cmluZz4gc2VjdXJpdHlBc1N0cmluZyA9IG5ldyBVbmlxdWVFTGlzdDxTdHJpbmc+KCk7CgkJaWYgKHNlY3VyaXR5ID09IG51bGwpIHsKCQkJc2VjdXJpdHkgPSBuZXcgRU9iamVjdFJlc29sdmluZ0VMaXN0PFNlY3VyaXR5U2NoZW1lPihTZWN1cml0eVNjaGVtZS5jbGFzcywgdGhpcywgV29UUGFja2FnZS5USElOR19fU0VDVVJJVFkpOwoJCX0KCQlmb3IgKFNlY3VyaXR5U2NoZW1lIHNlY3VyaXR5U2NoZW1lIDogc2VjdXJpdHkpIHsKCQkJaWYgKHNlY3VyaXR5U2NoZW1lLmdldFRpdGxlKCkgIT0gbnVsbCAmJiAhc2VjdXJpdHlTY2hlbWUuZ2V0VGl0bGUoKS5pc0VtcHR5KCkpIHsKCQkJCXNlY3VyaXR5QXNTdHJpbmcuYWRkKHNlY3VyaXR5U2NoZW1lLmdldFRpdGxlKCkpOwoJCQl9CgkJfQoJCXJldHVybiBzZWN1cml0eUFzU3RyaW5nOwoJfQoKfSAvL0Zvcm1JbXBsCg==