LyoNCiAqIA0KICovDQpwYWNrYWdlIGNvbXJlbC5kaWFncmFtLnBhcnQ7DQoNCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0Ow0KaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOw0KaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsNCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsNCmltcG9ydCBqYXZhLnV0aWwuTWFwOw0KaW1wb3J0IGphdmEudXRpbC5TZXQ7DQoNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLnV0aWwuQmFzaWNFTGlzdDsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLnV0aWwuRUxpc3Q7DQppbXBvcnQgb3JnLmVjbGlwc2UuZ2VmLlRvb2w7DQppbXBvcnQgb3JnLmVjbGlwc2UuZ2VmLnBhbGV0dGUuUGFsZXR0ZUNvbnRhaW5lcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5nZWYucGFsZXR0ZS5QYWxldHRlRHJhd2VyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmdlZi5wYWxldHRlLlBhbGV0dGVSb290Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLmdlZi5wYWxldHRlLlRvb2xFbnRyeTsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLnRvb2xzLlVuc3BlY2lmaWVkVHlwZUNvbm5lY3Rpb25Ub29sOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmRpYWdyYW0udWkudG9vbHMuVW5zcGVjaWZpZWRUeXBlQ3JlYXRpb25Ub29sOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmVtZi50eXBlLmNvcmUuSUVsZW1lbnRUeXBlOw0KDQppbXBvcnQgY29tcmVsLk1vZGVsUmVmYWN0b3Jpbmc7DQppbXBvcnQgY29tcmVsLk11bHRpRmVhdHVyZUhlbHBlcjsNCmltcG9ydCBjb21yZWwuTXVsdGlGaWx0ZXJIZWxwZXI7DQppbXBvcnQgY29tcmVsLlNpbmdsZUZlYXR1cmVIZWxwZXI7DQppbXBvcnQgY29tcmVsLlNpbmdsZUZpbHRlckhlbHBlcjsNCmltcG9ydCBjb21yZWwuZGlhZ3JhbS5wYXJ0LmN1c3RvbS5Ub29sRW50cnlDb21wYXJhdG9yOw0KaW1wb3J0IGNvbXJlbC5kaWFncmFtLnBhcnQuY3VzdG9tLlVuc3BlY2lmaWVkVHlwZUNyZWF0aW9uVG9vbFdpdGhVbml0SWQ7DQppbXBvcnQgY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlczsNCmltcG9ydCBjb21yZWwuaW1wbC5Db21wb3NpdGVSZWZhY3RvcmluZ0ltcGw7DQppbXBvcnQgY29tcmVsLnV0aWwuQ29tcmVsVXRpbDsNCmltcG9ydCBjb21yZWwudXRpbC5SZWdpc3RyeVV0aWw7DQoNCi8qKg0KICogQGdlbmVyYXRlZA0KICovDQpwdWJsaWMgY2xhc3MgQ29tcmVsUGFsZXR0ZUZhY3Rvcnkgew0KDQoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVU5JVF9JRCA9ICJVTklUX0lEIjsNCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwdWJsaWMgdm9pZCBmaWxsUGFsZXR0ZShQYWxldHRlUm9vdCBwYWxldHRlUm9vdCkgew0KCQlwYWxldHRlUm9vdC5hZGQoY3JlYXRlQ29tcG9zaXRlVW5pdHMxR3JvdXAoKSk7DQoJCXBhbGV0dGVSb290LmFkZChjcmVhdGVBdG9taWNVbml0czJHcm91cCgpKTsNCgkJcGFsZXR0ZVJvb3QuYWRkKGNyZWF0ZUZpbHRlclVuaXRzM0dyb3VwKCkpOw0KCQlwYWxldHRlUm9vdC5hZGQoY3JlYXRlRmVhdHVyZVVuaXRzNEdyb3VwKCkpOw0KCQlwYWxldHRlUm9vdC5hZGQoY3JlYXRlUG9ydHM1R3JvdXAoKSk7DQoJCXBhbGV0dGVSb290LmFkZChjcmVhdGVNYXBwaW5nczZHcm91cCgpKTsNCgl9DQoNCgkvKioNCgkgKiBFcnN0ZWxsdCBhbGxlIG72dGlnZW4gVG9vbGVpbnRy5GdlIGb8ciBhbGxlIHZlcmb8Z2JhcmVuIEF0b21pY1VOaXRzDQoJICogDQoJICogQHJldHVybg0KCSAqLw0KCXByaXZhdGUgRUxpc3Q8VG9vbEVudHJ5PiBjcmVhdGVBdG9taWNVbml0cygpIHsNCgkJRUxpc3Q8VG9vbEVudHJ5PiBlcmcgPSBuZXcgQmFzaWNFTGlzdDxUb29sRW50cnk+KCk7DQoJCUNvbGxlY3Rpb248TW9kZWxSZWZhY3RvcmluZz4gcmVmYWN0b3JpbmdzID0gUmVnaXN0cnlVdGlsDQoJCQkJLmdldEVtZlJlZmFjdG9yaW5nc0FzTW9kZWxSZWZhY3RvcmluZ3MoQ29tcG9zaXRlUmVmYWN0b3JpbmdJbXBsLm5zVXJpKTsNCgkJcmVmYWN0b3JpbmdzID0gQ29tcmVsVXRpbC5zb3J0QXRvbWljUmVmYWN0b3JpbmdzKHJlZmFjdG9yaW5ncyk7DQoJCUxpc3Q8SUVsZW1lbnRUeXBlPiB0eXBlczsNCgkJZm9yIChNb2RlbFJlZmFjdG9yaW5nIHJlZiA6IHJlZmFjdG9yaW5ncykgew0KCQkJaWYgKHJlZi5nZXROYW1lc3BhY2VVcmkoKS5lcXVhbHMoQ29tcG9zaXRlUmVmYWN0b3JpbmdJbXBsLm5zVXJpKSkgew0KCQkJCXR5cGVzID0gbmV3IEFycmF5TGlzdDxJRWxlbWVudFR5cGU+KDcpOyAvLygzKSA/Pz8NCgkJCQl0eXBlcy5hZGQoY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlcy5BdG9taWNVbml0XzIwMDcpOw0KCQkJCXR5cGVzLmFkZChjb21yZWwuZGlhZ3JhbS5wcm92aWRlcnMuQ29tcmVsRWxlbWVudFR5cGVzLkF0b21pY1VuaXRfMzAzNCk7DQoJCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuQXRvbWljVW5pdF8zMDQ5KTsNCgkJCQl0eXBlcy5hZGQoY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlcy5BdG9taWNVbml0XzMwNjgpOw0KCQkJCXR5cGVzLmFkZChjb21yZWwuZGlhZ3JhbS5wcm92aWRlcnMuQ29tcmVsRWxlbWVudFR5cGVzLkF0b21pY1VuaXRfMzA3NCk7DQoJCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuQXRvbWljVW5pdF8zMDc3KTsNCgkJCQl0eXBlcy5hZGQoY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlcy5BdG9taWNVbml0XzMwNzgpOw0KDQoJCQkJTm9kZVRvb2xFbnRyeSBlbnRyeSA9IG5ldyBOb2RlVG9vbEVudHJ5KHJlZi5nZXROYW1lKCksDQoJCQkJCQlyZWYuZ2V0TmFtZSgpLCB0eXBlcyk7DQoJCQkJZW50cnkuc2V0VW5pdElkKHJlZi5nZXRSZWZJZCgpKTsNCgkJCQllbnRyeS5zZXRJZChyZWYuZ2V0UmVmSWQoKSk7IC8vJE5PTi1OTFMtMSQNCgkJCQllbnRyeS5zZXRTbWFsbEljb24oY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlcw0KCQkJCQkJLmdldEltYWdlRGVzY3JpcHRvcihjb21yZWwuZGlhZ3JhbS5wcm92aWRlcnMuQ29tcmVsRWxlbWVudFR5cGVzLkF0b21pY1VuaXRfMjAwNykpOw0KCQkJCWVudHJ5LnNldExhcmdlSWNvbihlbnRyeS5nZXRTbWFsbEljb24oKSk7DQoJCQkJZXJnLmFkZChlbnRyeSk7DQoJCQl9DQoJCX0NCg0KCQlyZXR1cm4gZXJnOw0KCX0NCg0KCS8qKg0KCSAqIEVyc3RlbGx0IGFsbGUgbvZ0aWdlbiBUb29sZWludHLkZ2UgZvxyIGFsbGUgdmVyZvxnYmFyZW4gRmlsdGVyVW5pdHMNCgkgKiANCgkgKiBAcmV0dXJuDQoJICovDQoJcHJpdmF0ZSBFTGlzdDxUb29sRW50cnk+IGNyZWF0ZVNpbmdsZUZpbHRlclVuaXRzKCkgew0KCQlFTGlzdDxUb29sRW50cnk+IGVyZyA9IG5ldyBCYXNpY0VMaXN0PFRvb2xFbnRyeT4oKTsNCg0KCQlTZXQ8U2luZ2xlRmlsdGVySGVscGVyPiBoZWxwZXIgPSBSZWdpc3RyeVV0aWwNCgkJCQkubG9hZFNpbmdsZUZpbHRlckhlbHBlcihDb21wb3NpdGVSZWZhY3RvcmluZ0ltcGwubnNVcmkpOw0KCQlMaXN0PElFbGVtZW50VHlwZT4gdHlwZXM7DQoJCU5vZGVUb29sRW50cnkgZW50cnk7DQoJCWZvciAoU2luZ2xlRmlsdGVySGVscGVyIGZpbHRlciA6IGhlbHBlcikgew0KCQkJdHlwZXMgPSBuZXcgQXJyYXlMaXN0PElFbGVtZW50VHlwZT4oNSk7IC8vKDEpPz8/DQoJCQl0eXBlcy5hZGQoY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVGaWx0ZXJVbml0XzMwMTYpOw0KCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmlsdGVyVW5pdF8zMDQwKTsNCgkJCXR5cGVzLmFkZChjb21yZWwuZGlhZ3JhbS5wcm92aWRlcnMuQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZUZpbHRlclVuaXRfMzA1Mik7DQoJCQl0eXBlcy5hZGQoY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVGaWx0ZXJVbml0XzMwNTcpOw0KCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmlsdGVyVW5pdF8zMDYzKTsNCg0KCQkJZW50cnkgPSBuZXcgTm9kZVRvb2xFbnRyeShmaWx0ZXIuZ2V0TmFtZSgpLCBmaWx0ZXIuZ2V0TmFtZSgpLCB0eXBlcyk7DQoJCQllbnRyeS5zZXRVbml0SWQoZmlsdGVyLmdldEhlbHBlcklkKCkpOw0KCQkJZW50cnkuc2V0SWQoZmlsdGVyLmdldEhlbHBlcklkKCkpOyAvLyROT04tTkxTLTEkDQoJCQllbnRyeS5zZXRTbWFsbEljb24oY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlcw0KCQkJCQkuZ2V0SW1hZ2VEZXNjcmlwdG9yKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmlsdGVyVW5pdF8zMDE2KSk7DQoJCQllbnRyeS5zZXRMYXJnZUljb24oZW50cnkuZ2V0U21hbGxJY29uKCkpOw0KCQkJZXJnLmFkZChlbnRyeSk7DQoNCgkJfQ0KDQoJCXJldHVybiBlcmc7DQoJfQ0KDQoJLyoqDQoJICogRXJzdGVsbHQgYWxsZSBu9nRpZ2VuIFRvb2xlaW50cuRnZSBm/HIgYWxsZSB2ZXJm/GdiYXJlbiBGaWx0ZXJVbml0cw0KCSAqIA0KCSAqIEByZXR1cm4NCgkgKi8NCglwcml2YXRlIEVMaXN0PFRvb2xFbnRyeT4gY3JlYXRlTXVsdGlGaWx0ZXJVbml0cygpIHsNCgkJRUxpc3Q8VG9vbEVudHJ5PiBlcmcgPSBuZXcgQmFzaWNFTGlzdDxUb29sRW50cnk+KCk7DQoNCgkJU2V0PE11bHRpRmlsdGVySGVscGVyPiBoZWxwZXIgPSBSZWdpc3RyeVV0aWwNCgkJCQkubG9hZE11bHRpRmlsdGVySGVscGVyKENvbXBvc2l0ZVJlZmFjdG9yaW5nSW1wbC5uc1VyaSk7DQoJCUxpc3Q8SUVsZW1lbnRUeXBlPiB0eXBlczsNCgkJTm9kZVRvb2xFbnRyeSBlbnRyeTsNCgkJZm9yIChNdWx0aUZpbHRlckhlbHBlciBmaWx0ZXIgOiBoZWxwZXIpIHsNCgkJCXR5cGVzID0gbmV3IEFycmF5TGlzdDxJRWxlbWVudFR5cGU+KDUpOyAvLygxKT8/Pw0KCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuTXVsdGlGaWx0ZXJVbml0XzMwMTkpOw0KCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuTXVsdGlGaWx0ZXJVbml0XzMwNDEpOw0KCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuTXVsdGlGaWx0ZXJVbml0XzMwNTMpOw0KCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuTXVsdGlGaWx0ZXJVbml0XzMwNTgpOw0KCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuTXVsdGlGaWx0ZXJVbml0XzMwNjQpOw0KDQoJCQllbnRyeSA9IG5ldyBOb2RlVG9vbEVudHJ5KGZpbHRlci5nZXROYW1lKCksIGZpbHRlci5nZXROYW1lKCksIHR5cGVzKTsNCgkJCWVudHJ5LnNldFVuaXRJZChmaWx0ZXIuZ2V0SGVscGVySWQoKSk7DQoJCQllbnRyeS5zZXRJZChmaWx0ZXIuZ2V0SGVscGVySWQoKSk7IC8vJE5PTi1OTFMtMSQNCgkJCWVudHJ5LnNldFNtYWxsSWNvbihjb21yZWwuZGlhZ3JhbS5wcm92aWRlcnMuQ29tcmVsRWxlbWVudFR5cGVzDQoJCQkJCS5nZXRJbWFnZURlc2NyaXB0b3IoY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUZpbHRlclVuaXRfMzAxOSkpOw0KCQkJZW50cnkuc2V0TGFyZ2VJY29uKGVudHJ5LmdldFNtYWxsSWNvbigpKTsNCgkJCWVyZy5hZGQoZW50cnkpOw0KDQoJCX0NCg0KCQlyZXR1cm4gZXJnOw0KCX0NCg0KCS8qKg0KCSAqIEVyc3RlbGx0IGFsbGUgbvZ0aWdlbiBUb29sZWludHLkZ2UgZvxyIGFsbGUgdmVyZvxnYmFyZW4NCgkgKiBTaW5nbGVGZWF0dXJlVW5pdHMNCgkgKiANCgkgKiBAcmV0dXJuDQoJICovDQoJcHJpdmF0ZSBFTGlzdDxUb29sRW50cnk+IGNyZWF0ZVNpbmdsZUZlYXR1cmVVbml0cygpIHsNCgkJRUxpc3Q8VG9vbEVudHJ5PiBlcmcgPSBuZXcgQmFzaWNFTGlzdDxUb29sRW50cnk+KCk7DQoJCVNldDxTaW5nbGVGZWF0dXJlSGVscGVyPiBoZWxwZXIgPSBSZWdpc3RyeVV0aWwNCgkJCQkubG9hZFNpbmdsZUZlYXR1cmVIZWxwZXIoQ29tcG9zaXRlUmVmYWN0b3JpbmdJbXBsLm5zVXJpKTsNCgkJTGlzdDxJRWxlbWVudFR5cGU+IHR5cGVzOw0KCQlOb2RlVG9vbEVudHJ5IGVudHJ5Ow0KDQoJCWZvciAoU2luZ2xlRmVhdHVyZUhlbHBlciBzaW5nbGVGZWF0dXJlIDogaGVscGVyKSB7DQoJCQl0eXBlcyA9IG5ldyBBcnJheUxpc3Q8SUVsZW1lbnRUeXBlPig1KTsgLy8gKDEpID8/Pw0KCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmVhdHVyZVVuaXRfMzAwOCk7DQoJCQl0eXBlcy5hZGQoY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVGZWF0dXJlVW5pdF8zMDM4KTsNCgkJCXR5cGVzLmFkZChjb21yZWwuZGlhZ3JhbS5wcm92aWRlcnMuQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZUZlYXR1cmVVbml0XzMwNTApOw0KCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmVhdHVyZVVuaXRfMzA1NSk7DQoJCQl0eXBlcy5hZGQoY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVGZWF0dXJlVW5pdF8zMDYxKTsNCg0KCQkJZW50cnkgPSBuZXcgTm9kZVRvb2xFbnRyeShzaW5nbGVGZWF0dXJlLmdldE5hbWUoKSwNCgkJCQkJc2luZ2xlRmVhdHVyZS5nZXROYW1lKCksIHR5cGVzKTsNCgkJCWVudHJ5LnNldFVuaXRJZChzaW5nbGVGZWF0dXJlLmdldEhlbHBlcklkKCkpOw0KCQkJZW50cnkuc2V0SWQoc2luZ2xlRmVhdHVyZS5nZXRIZWxwZXJJZCgpKTsgLy8kTk9OLU5MUy0xJA0KCQkJZW50cnkuc2V0U21hbGxJY29uKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMNCgkJCQkJLmdldEltYWdlRGVzY3JpcHRvcihjb21yZWwuZGlhZ3JhbS5wcm92aWRlcnMuQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZUZlYXR1cmVVbml0XzMwMDgpKTsNCgkJCWVudHJ5LnNldExhcmdlSWNvbihlbnRyeS5nZXRTbWFsbEljb24oKSk7DQoJCQllcmcuYWRkKGVudHJ5KTsNCg0KCQl9DQoNCgkJcmV0dXJuIGVyZzsNCgl9DQoNCgkvKioNCgkgKiBFcnN0ZWxsdCBhbGxlIG72dGlnZW4gVG9vbGVpbnRy5GdlIGb8ciBhbGxlIHZlcmb8Z2JhcmVuIE11bHRpRmVhdHVyZVVuaXRzDQoJICogDQoJICogQHJldHVybg0KCSAqLw0KCXByaXZhdGUgRUxpc3Q8VG9vbEVudHJ5PiBjcmVhdGVNdWx0aUZlYXR1cmVVbml0cygpIHsNCgkJRUxpc3Q8VG9vbEVudHJ5PiBlcmcgPSBuZXcgQmFzaWNFTGlzdDxUb29sRW50cnk+KCk7DQoJCVNldDxNdWx0aUZlYXR1cmVIZWxwZXI+IGhlbHBlciA9IFJlZ2lzdHJ5VXRpbA0KCQkJCS5sb2FkTXVsdGlGZWF0dXJlSGVscGVyKENvbXBvc2l0ZVJlZmFjdG9yaW5nSW1wbC5uc1VyaSk7DQoJCUxpc3Q8SUVsZW1lbnRUeXBlPiB0eXBlczsNCgkJTm9kZVRvb2xFbnRyeSBlbnRyeTsNCg0KCQlmb3IgKE11bHRpRmVhdHVyZUhlbHBlciBtdWx0aUZlYXR1cmUgOiBoZWxwZXIpIHsNCg0KCQkJdHlwZXMgPSBuZXcgQXJyYXlMaXN0PElFbGVtZW50VHlwZT4oNSk7IC8vKDEpID8/Pw0KCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuTXVsdGlGZWF0dXJlVW5pdF8zMDEyKTsNCgkJCXR5cGVzLmFkZChjb21yZWwuZGlhZ3JhbS5wcm92aWRlcnMuQ29tcmVsRWxlbWVudFR5cGVzLk11bHRpRmVhdHVyZVVuaXRfMzAzOSk7DQoJCQl0eXBlcy5hZGQoY29tcmVsLmRpYWdyYW0ucHJvdmlkZXJzLkNvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUZlYXR1cmVVbml0XzMwNTEpOw0KCQkJdHlwZXMuYWRkKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMuTXVsdGlGZWF0dXJlVW5pdF8zMDU2KTsNCgkJCXR5cGVzLmFkZChjb21yZWwuZGlhZ3JhbS5wcm92aWRlcnMuQ29tcmVsRWxlbWVudFR5cGVzLk11bHRpRmVhdHVyZVVuaXRfMzA2Mik7DQoNCgkJCWVudHJ5ID0gbmV3IE5vZGVUb29sRW50cnkobXVsdGlGZWF0dXJlLmdldE5hbWUoKSwNCgkJCQkJbXVsdGlGZWF0dXJlLmdldE5hbWUoKSwgdHlwZXMpOw0KCQkJZW50cnkuc2V0VW5pdElkKG11bHRpRmVhdHVyZS5nZXRIZWxwZXJJZCgpKTsNCgkJCWVudHJ5LnNldElkKG11bHRpRmVhdHVyZS5nZXRIZWxwZXJJZCgpKTsgLy8kTk9OLU5MUy0xJA0KCQkJZW50cnkuc2V0U21hbGxJY29uKGNvbXJlbC5kaWFncmFtLnByb3ZpZGVycy5Db21yZWxFbGVtZW50VHlwZXMNCgkJCQkJLmdldEltYWdlRGVzY3JpcHRvcihjb21yZWwuZGlhZ3JhbS5wcm92aWRlcnMuQ29tcmVsRWxlbWVudFR5cGVzLk11bHRpRmVhdHVyZVVuaXRfMzAxMikpOw0KCQkJZW50cnkuc2V0TGFyZ2VJY29uKGVudHJ5LmdldFNtYWxsSWNvbigpKTsNCgkJCWVyZy5hZGQoZW50cnkpOw0KDQoJCX0NCg0KCQlyZXR1cm4gZXJnOw0KCX0NCg0KCS8qKg0KCSAqIENyZWF0ZXMgIkNvbXBvc2l0ZSBVbml0cyIgcGFsZXR0ZSB0b29sIGdyb3VwDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByaXZhdGUgUGFsZXR0ZUNvbnRhaW5lciBjcmVhdGVDb21wb3NpdGVVbml0czFHcm91cCgpIHsNCgkJUGFsZXR0ZURyYXdlciBwYWxldHRlQ29udGFpbmVyID0gbmV3IFBhbGV0dGVEcmF3ZXIoDQoJCQkJTWVzc2FnZXMuQ29tcG9zaXRlVW5pdHMxR3JvdXBfdGl0bGUpOw0KCQlwYWxldHRlQ29udGFpbmVyLnNldElkKCJjcmVhdGVDb21wb3NpdGVVbml0czFHcm91cCIpOyAvLyROT04tTkxTLTEkDQoJCXBhbGV0dGVDb250YWluZXIuYWRkKGNyZWF0ZUNhcnRlc2lhblF1ZXVlZFVuaXQxQ3JlYXRpb25Ub29sKCkpOw0KCQlwYWxldHRlQ29udGFpbmVyLmFkZChjcmVhdGVDb25kaXRpb25DaGVjazJDcmVhdGlvblRvb2woKSk7DQoJCXBhbGV0dGVDb250YWluZXIuYWRkKGNyZWF0ZUNvbmRpdGlvbmFsVW5pdDNDcmVhdGlvblRvb2woKSk7DQoJCXBhbGV0dGVDb250YWluZXIuYWRkKGNyZWF0ZVBhcmFsbGVsUXVldWVkVW5pdDRDcmVhdGlvblRvb2woKSk7DQoJCXBhbGV0dGVDb250YWluZXIuYWRkKGNyZWF0ZVNlcXVlbnRpYWxVbml0NUNyZWF0aW9uVG9vbCgpKTsNCgkJcGFsZXR0ZUNvbnRhaW5lci5hZGQoY3JlYXRlU2luZ2xlUXVldWVkVW5pdDZDcmVhdGlvblRvb2woKSk7DQoJCXJldHVybiBwYWxldHRlQ29udGFpbmVyOw0KCX0NCg0KCS8qKg0KCSAqIENyZWF0ZXMgIkF0b21pYyBVbml0cyIgcGFsZXR0ZSB0b29sIGdyb3VwDQoJICogQGdlbmVyYXRlZCBOT1QNCgkgKi8NCglwcml2YXRlIFBhbGV0dGVDb250YWluZXIgY3JlYXRlQXRvbWljVW5pdHMyR3JvdXAoKSB7DQoJCVBhbGV0dGVEcmF3ZXIgcGFsZXR0ZUNvbnRhaW5lciA9IG5ldyBQYWxldHRlRHJhd2VyKA0KCQkJCU1lc3NhZ2VzLkF0b21pY1VuaXRzMkdyb3VwX3RpdGxlKTsNCgkJcGFsZXR0ZUNvbnRhaW5lci5zZXRJZCgiY3JlYXRlQXRvbWljVW5pdHMyR3JvdXAiKTsgLy8kTk9OLU5MUy0xJA0KCQlwYWxldHRlQ29udGFpbmVyLmFkZEFsbCh0aGlzLmNyZWF0ZUF0b21pY1VuaXRzKCkpOw0KCQlyZXR1cm4gcGFsZXR0ZUNvbnRhaW5lcjsNCgl9DQoNCgkvKioNCgkgKiBDcmVhdGVzICJGaWx0ZXIgVW5pdHMiIHBhbGV0dGUgdG9vbCBncm91cA0KCSAqIEBnZW5lcmF0ZWQgTk9UDQoJICovDQoJcHJpdmF0ZSBQYWxldHRlQ29udGFpbmVyIGNyZWF0ZUZpbHRlclVuaXRzM0dyb3VwKCkgew0KCQlQYWxldHRlRHJhd2VyIHBhbGV0dGVDb250YWluZXIgPSBuZXcgUGFsZXR0ZURyYXdlcigNCgkJCQlNZXNzYWdlcy5GaWx0ZXJVbml0czNHcm91cF90aXRsZSk7DQoJCXBhbGV0dGVDb250YWluZXIuc2V0SWQoImNyZWF0ZUZpbHRlclVuaXRzM0dyb3VwIik7IC8vJE5PTi1OTFMtMSQNCgkJQXJyYXlMaXN0PFRvb2xFbnRyeT4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxUb29sRW50cnk+KCk7DQoJCXJlc3VsdC5hZGRBbGwoY3JlYXRlU2luZ2xlRmlsdGVyVW5pdHMoKSk7DQoJCXJlc3VsdC5hZGRBbGwoY3JlYXRlTXVsdGlGaWx0ZXJVbml0cygpKTsNCgkJQ29sbGVjdGlvbnMuc29ydChyZXN1bHQsIG5ldyBUb29sRW50cnlDb21wYXJhdG9yKCkpOw0KCQlwYWxldHRlQ29udGFpbmVyLmFkZEFsbChyZXN1bHQpOw0KCQlyZXR1cm4gcGFsZXR0ZUNvbnRhaW5lcjsNCgl9DQoNCgkvKioNCgkgKiBDcmVhdGVzICJGZWF0dXJlIFVuaXRzIiBwYWxldHRlIHRvb2wgZ3JvdXANCgkgKiBAZ2VuZXJhdGVkIE5PVA0KCSAqLw0KCXByaXZhdGUgUGFsZXR0ZUNvbnRhaW5lciBjcmVhdGVGZWF0dXJlVW5pdHM0R3JvdXAoKSB7DQoJCVBhbGV0dGVEcmF3ZXIgcGFsZXR0ZUNvbnRhaW5lciA9IG5ldyBQYWxldHRlRHJhd2VyKA0KCQkJCU1lc3NhZ2VzLkZlYXR1cmVVbml0czRHcm91cF90aXRsZSk7DQoJCXBhbGV0dGVDb250YWluZXIuc2V0SWQoImNyZWF0ZUZlYXR1cmVVbml0czRHcm91cCIpOyAvLyROT04tTkxTLTEkDQoJCUFycmF5TGlzdDxUb29sRW50cnk+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8VG9vbEVudHJ5PigpOw0KCQlyZXN1bHQuYWRkQWxsKGNyZWF0ZVNpbmdsZUZlYXR1cmVVbml0cygpKTsNCgkJcmVzdWx0LmFkZEFsbChjcmVhdGVNdWx0aUZlYXR1cmVVbml0cygpKTsNCgkJQ29sbGVjdGlvbnMuc29ydChyZXN1bHQsIG5ldyBUb29sRW50cnlDb21wYXJhdG9yKCkpOw0KCQlwYWxldHRlQ29udGFpbmVyLmFkZEFsbChyZXN1bHQpOw0KCQlyZXR1cm4gcGFsZXR0ZUNvbnRhaW5lcjsNCgl9DQoNCgkvKioNCgkgKiBDcmVhdGVzICJQb3J0cyIgcGFsZXR0ZSB0b29sIGdyb3VwDQoJICogQGdlbmVyYXRlZCBOT1QNCgkgKi8NCglwcml2YXRlIFBhbGV0dGVDb250YWluZXIgY3JlYXRlUG9ydHM1R3JvdXAoKSB7DQoJCVBhbGV0dGVEcmF3ZXIgcGFsZXR0ZUNvbnRhaW5lciA9IG5ldyBQYWxldHRlRHJhd2VyKA0KCQkJCU1lc3NhZ2VzLlBvcnRzNUdyb3VwX3RpdGxlKTsNCgkJcGFsZXR0ZUNvbnRhaW5lci5zZXRJZCgiY3JlYXRlUG9ydHM1R3JvdXAiKTsgLy8kTk9OLU5MUy0xJA0KCQlwYWxldHRlQ29udGFpbmVyLmFkZChjcmVhdGVNdWx0aUlucHV0UG9ydDFDcmVhdGlvblRvb2woKSk7DQoJCS8vIHBhbGV0dGVDb250YWluZXIuYWRkKGNyZWF0ZU11bHRpT3V0cHV0UG9ydDJDcmVhdGlvblRvb2woKSk7DQoJCXBhbGV0dGVDb250YWluZXIuYWRkKGNyZWF0ZVNpbmdsZUlucHV0UG9ydDNDcmVhdGlvblRvb2woKSk7DQoJCS8vIHBhbGV0dGVDb250YWluZXIuYWRkKGNyZWF0ZVNpbmdsZU91dHB1dFBvcnQ0Q3JlYXRpb25Ub29sKCkpOw0KCQlyZXR1cm4gcGFsZXR0ZUNvbnRhaW5lcjsNCgl9DQoNCgkvKioNCgkgKiBDcmVhdGVzICJNYXBwaW5ncyIgcGFsZXR0ZSB0b29sIGdyb3VwDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByaXZhdGUgUGFsZXR0ZUNvbnRhaW5lciBjcmVhdGVNYXBwaW5nczZHcm91cCgpIHsNCgkJUGFsZXR0ZURyYXdlciBwYWxldHRlQ29udGFpbmVyID0gbmV3IFBhbGV0dGVEcmF3ZXIoDQoJCQkJTWVzc2FnZXMuTWFwcGluZ3M2R3JvdXBfdGl0bGUpOw0KCQlwYWxldHRlQ29udGFpbmVyLnNldElkKCJjcmVhdGVNYXBwaW5nczZHcm91cCIpOyAvLyROT04tTkxTLTEkDQoJCXBhbGV0dGVDb250YWluZXIuYWRkKGNyZWF0ZU11bHRpUG9ydE1hcHBpbmcxQ3JlYXRpb25Ub29sKCkpOw0KCQlwYWxldHRlQ29udGFpbmVyLmFkZChjcmVhdGVNdWx0aVNpbmdsZVBvcnRNYXBwaW5nMkNyZWF0aW9uVG9vbCgpKTsNCgkJcGFsZXR0ZUNvbnRhaW5lci5hZGQoY3JlYXRlU2luZ2xlUG9ydE1hcHBpbmczQ3JlYXRpb25Ub29sKCkpOw0KCQlyZXR1cm4gcGFsZXR0ZUNvbnRhaW5lcjsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSBUb29sRW50cnkgY3JlYXRlQ2FydGVzaWFuUXVldWVkVW5pdDFDcmVhdGlvblRvb2woKSB7DQoJCUFycmF5TGlzdDxJRWxlbWVudFR5cGU+IHR5cGVzID0gbmV3IEFycmF5TGlzdDxJRWxlbWVudFR5cGU+KDcpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLkNhcnRlc2lhblF1ZXVlZFVuaXRfMjAwMik7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuQ2FydGVzaWFuUXVldWVkVW5pdF8zMDAzKTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5DYXJ0ZXNpYW5RdWV1ZWRVbml0XzMwMDcpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLkNhcnRlc2lhblF1ZXVlZFVuaXRfMzAyNSk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuQ2FydGVzaWFuUXVldWVkVW5pdF8zMDI5KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5DYXJ0ZXNpYW5RdWV1ZWRVbml0XzMwMzMpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLkNhcnRlc2lhblF1ZXVlZFVuaXRfMzA0Nyk7DQoJCU5vZGVUb29sRW50cnkgZW50cnkgPSBuZXcgTm9kZVRvb2xFbnRyeSgNCgkJCQlNZXNzYWdlcy5DYXJ0ZXNpYW5RdWV1ZWRVbml0MUNyZWF0aW9uVG9vbF90aXRsZSwNCgkJCQlNZXNzYWdlcy5DYXJ0ZXNpYW5RdWV1ZWRVbml0MUNyZWF0aW9uVG9vbF9kZXNjLCB0eXBlcyk7DQoJCWVudHJ5LnNldElkKCJjcmVhdGVDYXJ0ZXNpYW5RdWV1ZWRVbml0MUNyZWF0aW9uVG9vbCIpOyAvLyROT04tTkxTLTEkDQoJCWVudHJ5LnNldFNtYWxsSWNvbihDb21yZWxFbGVtZW50VHlwZXMNCgkJCQkuZ2V0SW1hZ2VEZXNjcmlwdG9yKENvbXJlbEVsZW1lbnRUeXBlcy5DYXJ0ZXNpYW5RdWV1ZWRVbml0XzIwMDIpKTsNCgkJZW50cnkuc2V0TGFyZ2VJY29uKGVudHJ5LmdldFNtYWxsSWNvbigpKTsNCgkJcmV0dXJuIGVudHJ5Ow0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcml2YXRlIFRvb2xFbnRyeSBjcmVhdGVDb25kaXRpb25DaGVjazJDcmVhdGlvblRvb2woKSB7DQoJCU5vZGVUb29sRW50cnkgZW50cnkgPSBuZXcgTm9kZVRvb2xFbnRyeSgNCgkJCQlNZXNzYWdlcy5Db25kaXRpb25DaGVjazJDcmVhdGlvblRvb2xfdGl0bGUsDQoJCQkJTWVzc2FnZXMuQ29uZGl0aW9uQ2hlY2syQ3JlYXRpb25Ub29sX2Rlc2MsDQoJCQkJQ29sbGVjdGlvbnMNCgkJCQkJCS5zaW5nbGV0b25MaXN0KENvbXJlbEVsZW1lbnRUeXBlcy5Db25kaXRpb25DaGVja18zMDc2KSk7DQoJCWVudHJ5LnNldElkKCJjcmVhdGVDb25kaXRpb25DaGVjazJDcmVhdGlvblRvb2wiKTsgLy8kTk9OLU5MUy0xJA0KCQllbnRyeS5zZXRTbWFsbEljb24oQ29tcmVsRWxlbWVudFR5cGVzDQoJCQkJLmdldEltYWdlRGVzY3JpcHRvcihDb21yZWxFbGVtZW50VHlwZXMuQ29uZGl0aW9uQ2hlY2tfMzA3NikpOw0KCQllbnRyeS5zZXRMYXJnZUljb24oZW50cnkuZ2V0U21hbGxJY29uKCkpOw0KCQlyZXR1cm4gZW50cnk7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByaXZhdGUgVG9vbEVudHJ5IGNyZWF0ZUNvbmRpdGlvbmFsVW5pdDNDcmVhdGlvblRvb2woKSB7DQoJCUFycmF5TGlzdDxJRWxlbWVudFR5cGU+IHR5cGVzID0gbmV3IEFycmF5TGlzdDxJRWxlbWVudFR5cGU+KDcpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLkNvbmRpdGlvbmFsVW5pdF8zMDMwKTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5Db25kaXRpb25hbFVuaXRfMzA0Nik7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuQ29uZGl0aW9uYWxVbml0XzMwNjYpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLkNvbmRpdGlvbmFsVW5pdF8zMDcxKTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5Db25kaXRpb25hbFVuaXRfMzA3Mik7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuQ29uZGl0aW9uYWxVbml0XzMwNzUpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLkNvbmRpdGlvbmFsVW5pdF8yMDA2KTsNCgkJTm9kZVRvb2xFbnRyeSBlbnRyeSA9IG5ldyBOb2RlVG9vbEVudHJ5KA0KCQkJCU1lc3NhZ2VzLkNvbmRpdGlvbmFsVW5pdDNDcmVhdGlvblRvb2xfdGl0bGUsDQoJCQkJTWVzc2FnZXMuQ29uZGl0aW9uYWxVbml0M0NyZWF0aW9uVG9vbF9kZXNjLCB0eXBlcyk7DQoJCWVudHJ5LnNldElkKCJjcmVhdGVDb25kaXRpb25hbFVuaXQzQ3JlYXRpb25Ub29sIik7IC8vJE5PTi1OTFMtMSQNCgkJZW50cnkuc2V0U21hbGxJY29uKENvbXJlbEVsZW1lbnRUeXBlcw0KCQkJCS5nZXRJbWFnZURlc2NyaXB0b3IoQ29tcmVsRWxlbWVudFR5cGVzLkNvbmRpdGlvbmFsVW5pdF8zMDMwKSk7DQoJCWVudHJ5LnNldExhcmdlSWNvbihlbnRyeS5nZXRTbWFsbEljb24oKSk7DQoJCXJldHVybiBlbnRyeTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSBUb29sRW50cnkgY3JlYXRlUGFyYWxsZWxRdWV1ZWRVbml0NENyZWF0aW9uVG9vbCgpIHsNCgkJQXJyYXlMaXN0PElFbGVtZW50VHlwZT4gdHlwZXMgPSBuZXcgQXJyYXlMaXN0PElFbGVtZW50VHlwZT4oNyk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuUGFyYWxsZWxRdWV1ZWRVbml0XzMwMDQpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlBhcmFsbGVsUXVldWVkVW5pdF8zMDM2KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5QYXJhbGxlbFF1ZXVlZFVuaXRfMzAzNyk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuUGFyYWxsZWxRdWV1ZWRVbml0XzMwNDMpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlBhcmFsbGVsUXVldWVkVW5pdF8zMDQ1KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5QYXJhbGxlbFF1ZXVlZFVuaXRfMzA0OCk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuUGFyYWxsZWxRdWV1ZWRVbml0XzIwMDMpOw0KCQlOb2RlVG9vbEVudHJ5IGVudHJ5ID0gbmV3IE5vZGVUb29sRW50cnkoDQoJCQkJTWVzc2FnZXMuUGFyYWxsZWxRdWV1ZWRVbml0NENyZWF0aW9uVG9vbF90aXRsZSwNCgkJCQlNZXNzYWdlcy5QYXJhbGxlbFF1ZXVlZFVuaXQ0Q3JlYXRpb25Ub29sX2Rlc2MsIHR5cGVzKTsNCgkJZW50cnkuc2V0SWQoImNyZWF0ZVBhcmFsbGVsUXVldWVkVW5pdDRDcmVhdGlvblRvb2wiKTsgLy8kTk9OLU5MUy0xJA0KCQllbnRyeS5zZXRTbWFsbEljb24oQ29tcmVsRWxlbWVudFR5cGVzDQoJCQkJLmdldEltYWdlRGVzY3JpcHRvcihDb21yZWxFbGVtZW50VHlwZXMuUGFyYWxsZWxRdWV1ZWRVbml0XzMwMDQpKTsNCgkJZW50cnkuc2V0TGFyZ2VJY29uKGVudHJ5LmdldFNtYWxsSWNvbigpKTsNCgkJcmV0dXJuIGVudHJ5Ow0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcml2YXRlIFRvb2xFbnRyeSBjcmVhdGVTZXF1ZW50aWFsVW5pdDVDcmVhdGlvblRvb2woKSB7DQoJCUFycmF5TGlzdDxJRWxlbWVudFR5cGU+IHR5cGVzID0gbmV3IEFycmF5TGlzdDxJRWxlbWVudFR5cGU+KDcpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNlcXVlbnRpYWxVbml0XzMwMjYpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNlcXVlbnRpYWxVbml0XzMwNDQpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNlcXVlbnRpYWxVbml0XzMwNjApOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNlcXVlbnRpYWxVbml0XzMwNjkpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNlcXVlbnRpYWxVbml0XzMwNzApOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNlcXVlbnRpYWxVbml0XzMwNzMpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNlcXVlbnRpYWxVbml0XzIwMDUpOw0KCQlOb2RlVG9vbEVudHJ5IGVudHJ5ID0gbmV3IE5vZGVUb29sRW50cnkoDQoJCQkJTWVzc2FnZXMuU2VxdWVudGlhbFVuaXQ1Q3JlYXRpb25Ub29sX3RpdGxlLA0KCQkJCU1lc3NhZ2VzLlNlcXVlbnRpYWxVbml0NUNyZWF0aW9uVG9vbF9kZXNjLCB0eXBlcyk7DQoJCWVudHJ5LnNldElkKCJjcmVhdGVTZXF1ZW50aWFsVW5pdDVDcmVhdGlvblRvb2wiKTsgLy8kTk9OLU5MUy0xJA0KCQllbnRyeS5zZXRTbWFsbEljb24oQ29tcmVsRWxlbWVudFR5cGVzDQoJCQkJLmdldEltYWdlRGVzY3JpcHRvcihDb21yZWxFbGVtZW50VHlwZXMuU2VxdWVudGlhbFVuaXRfMzAyNikpOw0KCQllbnRyeS5zZXRMYXJnZUljb24oZW50cnkuZ2V0U21hbGxJY29uKCkpOw0KCQlyZXR1cm4gZW50cnk7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByaXZhdGUgVG9vbEVudHJ5IGNyZWF0ZVNpbmdsZVF1ZXVlZFVuaXQ2Q3JlYXRpb25Ub29sKCkgew0KCQlBcnJheUxpc3Q8SUVsZW1lbnRUeXBlPiB0eXBlcyA9IG5ldyBBcnJheUxpc3Q8SUVsZW1lbnRUeXBlPig3KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVRdWV1ZWRVbml0XzMwMjIpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZVF1ZXVlZFVuaXRfMzA0Mik7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlUXVldWVkVW5pdF8zMDU0KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVRdWV1ZWRVbml0XzMwNTkpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZVF1ZXVlZFVuaXRfMzA2NSk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlUXVldWVkVW5pdF8zMDY3KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVRdWV1ZWRVbml0XzIwMDQpOw0KCQlOb2RlVG9vbEVudHJ5IGVudHJ5ID0gbmV3IE5vZGVUb29sRW50cnkoDQoJCQkJTWVzc2FnZXMuU2luZ2xlUXVldWVkVW5pdDZDcmVhdGlvblRvb2xfdGl0bGUsDQoJCQkJTWVzc2FnZXMuU2luZ2xlUXVldWVkVW5pdDZDcmVhdGlvblRvb2xfZGVzYywgdHlwZXMpOw0KCQllbnRyeS5zZXRJZCgiY3JlYXRlU2luZ2xlUXVldWVkVW5pdDZDcmVhdGlvblRvb2wiKTsgLy8kTk9OLU5MUy0xJA0KCQllbnRyeS5zZXRTbWFsbEljb24oQ29tcmVsRWxlbWVudFR5cGVzDQoJCQkJLmdldEltYWdlRGVzY3JpcHRvcihDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlUXVldWVkVW5pdF8zMDIyKSk7DQoJCWVudHJ5LnNldExhcmdlSWNvbihlbnRyeS5nZXRTbWFsbEljb24oKSk7DQoJCXJldHVybiBlbnRyeTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSBUb29sRW50cnkgY3JlYXRlQXRvbWljVW5pdDFDcmVhdGlvblRvb2woKSB7DQoJCUFycmF5TGlzdDxJRWxlbWVudFR5cGU+IHR5cGVzID0gbmV3IEFycmF5TGlzdDxJRWxlbWVudFR5cGU+KDcpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLkF0b21pY1VuaXRfMzAzNCk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuQXRvbWljVW5pdF8zMDQ5KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5BdG9taWNVbml0XzMwNjgpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLkF0b21pY1VuaXRfMzA3NCk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuQXRvbWljVW5pdF8zMDc3KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5BdG9taWNVbml0XzMwNzgpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLkF0b21pY1VuaXRfMjAwNyk7DQoJCU5vZGVUb29sRW50cnkgZW50cnkgPSBuZXcgTm9kZVRvb2xFbnRyeSgNCgkJCQlNZXNzYWdlcy5BdG9taWNVbml0MUNyZWF0aW9uVG9vbF90aXRsZSwNCgkJCQlNZXNzYWdlcy5BdG9taWNVbml0MUNyZWF0aW9uVG9vbF9kZXNjLCB0eXBlcyk7DQoJCWVudHJ5LnNldElkKCJjcmVhdGVBdG9taWNVbml0MUNyZWF0aW9uVG9vbCIpOyAvLyROT04tTkxTLTEkDQoJCWVudHJ5LnNldFNtYWxsSWNvbihDb21yZWxFbGVtZW50VHlwZXMNCgkJCQkuZ2V0SW1hZ2VEZXNjcmlwdG9yKENvbXJlbEVsZW1lbnRUeXBlcy5BdG9taWNVbml0XzMwMzQpKTsNCgkJZW50cnkuc2V0TGFyZ2VJY29uKGVudHJ5LmdldFNtYWxsSWNvbigpKTsNCgkJcmV0dXJuIGVudHJ5Ow0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcml2YXRlIFRvb2xFbnRyeSBjcmVhdGVNdWx0aUZpbHRlclVuaXQxQ3JlYXRpb25Ub29sKCkgew0KCQlBcnJheUxpc3Q8SUVsZW1lbnRUeXBlPiB0eXBlcyA9IG5ldyBBcnJheUxpc3Q8SUVsZW1lbnRUeXBlPig1KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUZpbHRlclVuaXRfMzAxOSk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuTXVsdGlGaWx0ZXJVbml0XzMwNDEpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLk11bHRpRmlsdGVyVW5pdF8zMDUzKTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUZpbHRlclVuaXRfMzA1OCk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuTXVsdGlGaWx0ZXJVbml0XzMwNjQpOw0KCQlOb2RlVG9vbEVudHJ5IGVudHJ5ID0gbmV3IE5vZGVUb29sRW50cnkoDQoJCQkJTWVzc2FnZXMuTXVsdGlGaWx0ZXJVbml0MUNyZWF0aW9uVG9vbF90aXRsZSwNCgkJCQlNZXNzYWdlcy5NdWx0aUZpbHRlclVuaXQxQ3JlYXRpb25Ub29sX2Rlc2MsIHR5cGVzKTsNCgkJZW50cnkuc2V0SWQoImNyZWF0ZU11bHRpRmlsdGVyVW5pdDFDcmVhdGlvblRvb2wiKTsgLy8kTk9OLU5MUy0xJA0KCQllbnRyeS5zZXRTbWFsbEljb24oQ29tcmVsRWxlbWVudFR5cGVzDQoJCQkJLmdldEltYWdlRGVzY3JpcHRvcihDb21yZWxFbGVtZW50VHlwZXMuTXVsdGlGaWx0ZXJVbml0XzMwMTkpKTsNCgkJZW50cnkuc2V0TGFyZ2VJY29uKGVudHJ5LmdldFNtYWxsSWNvbigpKTsNCgkJcmV0dXJuIGVudHJ5Ow0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcml2YXRlIFRvb2xFbnRyeSBjcmVhdGVTaW5nbGVGaWx0ZXJVbml0MkNyZWF0aW9uVG9vbCgpIHsNCgkJQXJyYXlMaXN0PElFbGVtZW50VHlwZT4gdHlwZXMgPSBuZXcgQXJyYXlMaXN0PElFbGVtZW50VHlwZT4oNSk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmlsdGVyVW5pdF8zMDE2KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVGaWx0ZXJVbml0XzMwNDApOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZUZpbHRlclVuaXRfMzA1Mik7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmlsdGVyVW5pdF8zMDU3KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVGaWx0ZXJVbml0XzMwNjMpOw0KCQlOb2RlVG9vbEVudHJ5IGVudHJ5ID0gbmV3IE5vZGVUb29sRW50cnkoDQoJCQkJTWVzc2FnZXMuU2luZ2xlRmlsdGVyVW5pdDJDcmVhdGlvblRvb2xfdGl0bGUsDQoJCQkJTWVzc2FnZXMuU2luZ2xlRmlsdGVyVW5pdDJDcmVhdGlvblRvb2xfZGVzYywgdHlwZXMpOw0KCQllbnRyeS5zZXRJZCgiY3JlYXRlU2luZ2xlRmlsdGVyVW5pdDJDcmVhdGlvblRvb2wiKTsgLy8kTk9OLU5MUy0xJA0KCQllbnRyeS5zZXRTbWFsbEljb24oQ29tcmVsRWxlbWVudFR5cGVzDQoJCQkJLmdldEltYWdlRGVzY3JpcHRvcihDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmlsdGVyVW5pdF8zMDE2KSk7DQoJCWVudHJ5LnNldExhcmdlSWNvbihlbnRyeS5nZXRTbWFsbEljb24oKSk7DQoJCXJldHVybiBlbnRyeTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSBUb29sRW50cnkgY3JlYXRlTXVsdGlGZWF0dXJlVW5pdDFDcmVhdGlvblRvb2woKSB7DQoJCUFycmF5TGlzdDxJRWxlbWVudFR5cGU+IHR5cGVzID0gbmV3IEFycmF5TGlzdDxJRWxlbWVudFR5cGU+KDUpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLk11bHRpRmVhdHVyZVVuaXRfMzAxMik7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuTXVsdGlGZWF0dXJlVW5pdF8zMDM5KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUZlYXR1cmVVbml0XzMwNTEpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLk11bHRpRmVhdHVyZVVuaXRfMzA1Nik7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuTXVsdGlGZWF0dXJlVW5pdF8zMDYyKTsNCgkJTm9kZVRvb2xFbnRyeSBlbnRyeSA9IG5ldyBOb2RlVG9vbEVudHJ5KA0KCQkJCU1lc3NhZ2VzLk11bHRpRmVhdHVyZVVuaXQxQ3JlYXRpb25Ub29sX3RpdGxlLA0KCQkJCU1lc3NhZ2VzLk11bHRpRmVhdHVyZVVuaXQxQ3JlYXRpb25Ub29sX2Rlc2MsIHR5cGVzKTsNCgkJZW50cnkuc2V0SWQoImNyZWF0ZU11bHRpRmVhdHVyZVVuaXQxQ3JlYXRpb25Ub29sIik7IC8vJE5PTi1OTFMtMSQNCgkJZW50cnkuc2V0U21hbGxJY29uKENvbXJlbEVsZW1lbnRUeXBlcw0KCQkJCS5nZXRJbWFnZURlc2NyaXB0b3IoQ29tcmVsRWxlbWVudFR5cGVzLk11bHRpRmVhdHVyZVVuaXRfMzAxMikpOw0KCQllbnRyeS5zZXRMYXJnZUljb24oZW50cnkuZ2V0U21hbGxJY29uKCkpOw0KCQlyZXR1cm4gZW50cnk7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByaXZhdGUgVG9vbEVudHJ5IGNyZWF0ZVNpbmdsZUZlYXR1cmVVbml0MkNyZWF0aW9uVG9vbCgpIHsNCgkJQXJyYXlMaXN0PElFbGVtZW50VHlwZT4gdHlwZXMgPSBuZXcgQXJyYXlMaXN0PElFbGVtZW50VHlwZT4oNSk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmVhdHVyZVVuaXRfMzAwOCk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmVhdHVyZVVuaXRfMzAzOCk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmVhdHVyZVVuaXRfMzA1MCk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmVhdHVyZVVuaXRfMzA1NSk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlRmVhdHVyZVVuaXRfMzA2MSk7DQoJCU5vZGVUb29sRW50cnkgZW50cnkgPSBuZXcgTm9kZVRvb2xFbnRyeSgNCgkJCQlNZXNzYWdlcy5TaW5nbGVGZWF0dXJlVW5pdDJDcmVhdGlvblRvb2xfdGl0bGUsDQoJCQkJTWVzc2FnZXMuU2luZ2xlRmVhdHVyZVVuaXQyQ3JlYXRpb25Ub29sX2Rlc2MsIHR5cGVzKTsNCgkJZW50cnkuc2V0SWQoImNyZWF0ZVNpbmdsZUZlYXR1cmVVbml0MkNyZWF0aW9uVG9vbCIpOyAvLyROT04tTkxTLTEkDQoJCWVudHJ5LnNldFNtYWxsSWNvbihDb21yZWxFbGVtZW50VHlwZXMNCgkJCQkuZ2V0SW1hZ2VEZXNjcmlwdG9yKENvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVGZWF0dXJlVW5pdF8zMDA4KSk7DQoJCWVudHJ5LnNldExhcmdlSWNvbihlbnRyeS5nZXRTbWFsbEljb24oKSk7DQoJCXJldHVybiBlbnRyeTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSBUb29sRW50cnkgY3JlYXRlTXVsdGlJbnB1dFBvcnQxQ3JlYXRpb25Ub29sKCkgew0KCQlBcnJheUxpc3Q8SUVsZW1lbnRUeXBlPiB0eXBlcyA9IG5ldyBBcnJheUxpc3Q8SUVsZW1lbnRUeXBlPig5KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUlucHV0UG9ydF8zMDAyKTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUlucHV0UG9ydF8zMDA2KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUlucHV0UG9ydF8zMDEwKTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUlucHV0UG9ydF8zMDE0KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUlucHV0UG9ydF8zMDE3KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUlucHV0UG9ydF8zMDIwKTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUlucHV0UG9ydF8zMDI0KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUlucHV0UG9ydF8zMDI4KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aUlucHV0UG9ydF8zMDMyKTsNCgkJTm9kZVRvb2xFbnRyeSBlbnRyeSA9IG5ldyBOb2RlVG9vbEVudHJ5KA0KCQkJCU1lc3NhZ2VzLk11bHRpSW5wdXRQb3J0MUNyZWF0aW9uVG9vbF90aXRsZSwNCgkJCQlNZXNzYWdlcy5NdWx0aUlucHV0UG9ydDFDcmVhdGlvblRvb2xfZGVzYywgdHlwZXMpOw0KCQllbnRyeS5zZXRJZCgiY3JlYXRlTXVsdGlJbnB1dFBvcnQxQ3JlYXRpb25Ub29sIik7IC8vJE5PTi1OTFMtMSQNCgkJZW50cnkuc2V0U21hbGxJY29uKENvbXJlbEVsZW1lbnRUeXBlcw0KCQkJCS5nZXRJbWFnZURlc2NyaXB0b3IoQ29tcmVsRWxlbWVudFR5cGVzLk11bHRpSW5wdXRQb3J0XzMwMDIpKTsNCgkJZW50cnkuc2V0TGFyZ2VJY29uKGVudHJ5LmdldFNtYWxsSWNvbigpKTsNCgkJcmV0dXJuIGVudHJ5Ow0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcml2YXRlIFRvb2xFbnRyeSBjcmVhdGVNdWx0aU91dHB1dFBvcnQyQ3JlYXRpb25Ub29sKCkgew0KCQlBcnJheUxpc3Q8SUVsZW1lbnRUeXBlPiB0eXBlcyA9IG5ldyBBcnJheUxpc3Q8SUVsZW1lbnRUeXBlPigyKTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aU91dHB1dFBvcnRfMzAxNSk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuTXVsdGlPdXRwdXRQb3J0XzMwMjEpOw0KCQlOb2RlVG9vbEVudHJ5IGVudHJ5ID0gbmV3IE5vZGVUb29sRW50cnkoDQoJCQkJTWVzc2FnZXMuTXVsdGlPdXRwdXRQb3J0MkNyZWF0aW9uVG9vbF90aXRsZSwNCgkJCQlNZXNzYWdlcy5NdWx0aU91dHB1dFBvcnQyQ3JlYXRpb25Ub29sX2Rlc2MsIHR5cGVzKTsNCgkJZW50cnkuc2V0SWQoImNyZWF0ZU11bHRpT3V0cHV0UG9ydDJDcmVhdGlvblRvb2wiKTsgLy8kTk9OLU5MUy0xJA0KCQllbnRyeS5zZXRTbWFsbEljb24oQ29tcmVsRWxlbWVudFR5cGVzDQoJCQkJLmdldEltYWdlRGVzY3JpcHRvcihDb21yZWxFbGVtZW50VHlwZXMuTXVsdGlPdXRwdXRQb3J0XzMwMTUpKTsNCgkJZW50cnkuc2V0TGFyZ2VJY29uKGVudHJ5LmdldFNtYWxsSWNvbigpKTsNCgkJcmV0dXJuIGVudHJ5Ow0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcml2YXRlIFRvb2xFbnRyeSBjcmVhdGVTaW5nbGVJbnB1dFBvcnQzQ3JlYXRpb25Ub29sKCkgew0KCQlBcnJheUxpc3Q8SUVsZW1lbnRUeXBlPiB0eXBlcyA9IG5ldyBBcnJheUxpc3Q8SUVsZW1lbnRUeXBlPig5KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVJbnB1dFBvcnRfMjAwMSk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlSW5wdXRQb3J0XzMwMDEpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZUlucHV0UG9ydF8zMDA1KTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVJbnB1dFBvcnRfMzAwOSk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlSW5wdXRQb3J0XzMwMTMpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZUlucHV0UG9ydF8zMDIzKTsNCgkJdHlwZXMuYWRkKENvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVJbnB1dFBvcnRfMzAyNyk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlSW5wdXRQb3J0XzMwMzEpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZUlucHV0UG9ydF8zMDM1KTsNCgkJTm9kZVRvb2xFbnRyeSBlbnRyeSA9IG5ldyBOb2RlVG9vbEVudHJ5KA0KCQkJCU1lc3NhZ2VzLlNpbmdsZUlucHV0UG9ydDNDcmVhdGlvblRvb2xfdGl0bGUsDQoJCQkJTWVzc2FnZXMuU2luZ2xlSW5wdXRQb3J0M0NyZWF0aW9uVG9vbF9kZXNjLCB0eXBlcyk7DQoJCWVudHJ5LnNldElkKCJjcmVhdGVTaW5nbGVJbnB1dFBvcnQzQ3JlYXRpb25Ub29sIik7IC8vJE5PTi1OTFMtMSQNCgkJZW50cnkuc2V0U21hbGxJY29uKENvbXJlbEVsZW1lbnRUeXBlcw0KCQkJCS5nZXRJbWFnZURlc2NyaXB0b3IoQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZUlucHV0UG9ydF8yMDAxKSk7DQoJCWVudHJ5LnNldExhcmdlSWNvbihlbnRyeS5nZXRTbWFsbEljb24oKSk7DQoJCXJldHVybiBlbnRyeTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSBUb29sRW50cnkgY3JlYXRlU2luZ2xlT3V0cHV0UG9ydDRDcmVhdGlvblRvb2woKSB7DQoJCUFycmF5TGlzdDxJRWxlbWVudFR5cGU+IHR5cGVzID0gbmV3IEFycmF5TGlzdDxJRWxlbWVudFR5cGU+KDIpOw0KCQl0eXBlcy5hZGQoQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZU91dHB1dFBvcnRfMzAxMSk7DQoJCXR5cGVzLmFkZChDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlT3V0cHV0UG9ydF8zMDE4KTsNCgkJTm9kZVRvb2xFbnRyeSBlbnRyeSA9IG5ldyBOb2RlVG9vbEVudHJ5KA0KCQkJCU1lc3NhZ2VzLlNpbmdsZU91dHB1dFBvcnQ0Q3JlYXRpb25Ub29sX3RpdGxlLA0KCQkJCU1lc3NhZ2VzLlNpbmdsZU91dHB1dFBvcnQ0Q3JlYXRpb25Ub29sX2Rlc2MsIHR5cGVzKTsNCgkJZW50cnkuc2V0SWQoImNyZWF0ZVNpbmdsZU91dHB1dFBvcnQ0Q3JlYXRpb25Ub29sIik7IC8vJE5PTi1OTFMtMSQNCgkJZW50cnkuc2V0U21hbGxJY29uKENvbXJlbEVsZW1lbnRUeXBlcw0KCQkJCS5nZXRJbWFnZURlc2NyaXB0b3IoQ29tcmVsRWxlbWVudFR5cGVzLlNpbmdsZU91dHB1dFBvcnRfMzAxMSkpOw0KCQllbnRyeS5zZXRMYXJnZUljb24oZW50cnkuZ2V0U21hbGxJY29uKCkpOw0KCQlyZXR1cm4gZW50cnk7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByaXZhdGUgVG9vbEVudHJ5IGNyZWF0ZU11bHRpUG9ydE1hcHBpbmcxQ3JlYXRpb25Ub29sKCkgew0KCQlMaW5rVG9vbEVudHJ5IGVudHJ5ID0gbmV3IExpbmtUb29sRW50cnkoDQoJCQkJTWVzc2FnZXMuTXVsdGlQb3J0TWFwcGluZzFDcmVhdGlvblRvb2xfdGl0bGUsDQoJCQkJTWVzc2FnZXMuTXVsdGlQb3J0TWFwcGluZzFDcmVhdGlvblRvb2xfZGVzYywNCgkJCQlDb2xsZWN0aW9ucw0KCQkJCQkJLnNpbmdsZXRvbkxpc3QoQ29tcmVsRWxlbWVudFR5cGVzLk11bHRpUG9ydE1hcHBpbmdfNDAwMikpOw0KCQllbnRyeS5zZXRJZCgiY3JlYXRlTXVsdGlQb3J0TWFwcGluZzFDcmVhdGlvblRvb2wiKTsgLy8kTk9OLU5MUy0xJA0KCQllbnRyeS5zZXRTbWFsbEljb24oQ29tcmVsRWxlbWVudFR5cGVzDQoJCQkJLmdldEltYWdlRGVzY3JpcHRvcihDb21yZWxFbGVtZW50VHlwZXMuTXVsdGlQb3J0TWFwcGluZ180MDAyKSk7DQoJCWVudHJ5LnNldExhcmdlSWNvbihlbnRyeS5nZXRTbWFsbEljb24oKSk7DQoJCXJldHVybiBlbnRyeTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSBUb29sRW50cnkgY3JlYXRlTXVsdGlTaW5nbGVQb3J0TWFwcGluZzJDcmVhdGlvblRvb2woKSB7DQoJCUxpbmtUb29sRW50cnkgZW50cnkgPSBuZXcgTGlua1Rvb2xFbnRyeSgNCgkJCQlNZXNzYWdlcy5NdWx0aVNpbmdsZVBvcnRNYXBwaW5nMkNyZWF0aW9uVG9vbF90aXRsZSwNCgkJCQlNZXNzYWdlcy5NdWx0aVNpbmdsZVBvcnRNYXBwaW5nMkNyZWF0aW9uVG9vbF9kZXNjLA0KCQkJCUNvbGxlY3Rpb25zDQoJCQkJCQkuc2luZ2xldG9uTGlzdChDb21yZWxFbGVtZW50VHlwZXMuTXVsdGlTaW5nbGVQb3J0TWFwcGluZ180MDAzKSk7DQoJCWVudHJ5LnNldElkKCJjcmVhdGVNdWx0aVNpbmdsZVBvcnRNYXBwaW5nMkNyZWF0aW9uVG9vbCIpOyAvLyROT04tTkxTLTEkDQoJCWVudHJ5LnNldFNtYWxsSWNvbihDb21yZWxFbGVtZW50VHlwZXMNCgkJCQkuZ2V0SW1hZ2VEZXNjcmlwdG9yKENvbXJlbEVsZW1lbnRUeXBlcy5NdWx0aVNpbmdsZVBvcnRNYXBwaW5nXzQwMDMpKTsNCgkJZW50cnkuc2V0TGFyZ2VJY29uKGVudHJ5LmdldFNtYWxsSWNvbigpKTsNCgkJcmV0dXJuIGVudHJ5Ow0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcml2YXRlIFRvb2xFbnRyeSBjcmVhdGVTaW5nbGVQb3J0TWFwcGluZzNDcmVhdGlvblRvb2woKSB7DQoJCUxpbmtUb29sRW50cnkgZW50cnkgPSBuZXcgTGlua1Rvb2xFbnRyeSgNCgkJCQlNZXNzYWdlcy5TaW5nbGVQb3J0TWFwcGluZzNDcmVhdGlvblRvb2xfdGl0bGUsDQoJCQkJTWVzc2FnZXMuU2luZ2xlUG9ydE1hcHBpbmczQ3JlYXRpb25Ub29sX2Rlc2MsDQoJCQkJQ29sbGVjdGlvbnMNCgkJCQkJCS5zaW5nbGV0b25MaXN0KENvbXJlbEVsZW1lbnRUeXBlcy5TaW5nbGVQb3J0TWFwcGluZ180MDAxKSk7DQoJCWVudHJ5LnNldElkKCJjcmVhdGVTaW5nbGVQb3J0TWFwcGluZzNDcmVhdGlvblRvb2wiKTsgLy8kTk9OLU5MUy0xJA0KCQllbnRyeS5zZXRTbWFsbEljb24oQ29tcmVsRWxlbWVudFR5cGVzDQoJCQkJLmdldEltYWdlRGVzY3JpcHRvcihDb21yZWxFbGVtZW50VHlwZXMuU2luZ2xlUG9ydE1hcHBpbmdfNDAwMSkpOw0KCQllbnRyeS5zZXRMYXJnZUljb24oZW50cnkuZ2V0U21hbGxJY29uKCkpOw0KCQlyZXR1cm4gZW50cnk7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByaXZhdGUgc3RhdGljIGNsYXNzIE5vZGVUb29sRW50cnkgZXh0ZW5kcyBUb29sRW50cnkgew0KDQoJCVN0cmluZyB1bml0SWQgPSAiIjsNCg0KCQkvKioNCgkJICogQGdlbmVyYXRlZA0KCQkgKi8NCgkJcHJpdmF0ZSBmaW5hbCBMaXN0PElFbGVtZW50VHlwZT4gZWxlbWVudFR5cGVzOw0KDQoJCS8qKg0KCQkgKiBAZ2VuZXJhdGVkDQoJCSAqLw0KCQlwcml2YXRlIE5vZGVUb29sRW50cnkoU3RyaW5nIHRpdGxlLCBTdHJpbmcgZGVzY3JpcHRpb24sDQoJCQkJTGlzdDxJRWxlbWVudFR5cGU+IGVsZW1lbnRUeXBlcykgew0KCQkJc3VwZXIodGl0bGUsIGRlc2NyaXB0aW9uLCBudWxsLCBudWxsKTsNCgkJCXRoaXMuZWxlbWVudFR5cGVzID0gZWxlbWVudFR5cGVzOw0KCQl9DQoNCgkJLyoqDQoJCSAqIEBnZW5lcmF0ZWQgTk9UDQoJCSAqLw0KCQlwdWJsaWMgVG9vbCBjcmVhdGVUb29sKCkgew0KCQkJLyoNCgkJCSAqIGNoYW5nZTogVW5zcGVjaWZpZWRUeXBlQ1JlYXRlaW9uVG9vbCAtPg0KCQkJICogVW5zcGVjaWZpZWRUeXBlQ3JlYXRpb25Ub29sV2l0aFVuaXRJZA0KCQkJICovDQoJCQlVbnNwZWNpZmllZFR5cGVDcmVhdGlvblRvb2wgdG9vbCA9IG5ldyBVbnNwZWNpZmllZFR5cGVDcmVhdGlvblRvb2xXaXRoVW5pdElkKA0KCQkJCQllbGVtZW50VHlwZXMsIHVuaXRJZCk7DQoJCQlNYXAgcHJvcCA9IGdldFRvb2xQcm9wZXJ0aWVzKCk7DQoJCQl0b29sLnNldFByb3BlcnRpZXMocHJvcCk7DQoJCQlyZXR1cm4gdG9vbDsNCgkJfQ0KDQoJCXB1YmxpYyB2b2lkIHNldFVuaXRJZChTdHJpbmcgdW5pdElkKSB7DQoJCQl0aGlzLnVuaXRJZCA9IHVuaXRJZDsNCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcml2YXRlIHN0YXRpYyBjbGFzcyBMaW5rVG9vbEVudHJ5IGV4dGVuZHMgVG9vbEVudHJ5IHsNCg0KCQkvKioNCgkJICogQGdlbmVyYXRlZA0KCQkgKi8NCgkJcHJpdmF0ZSBmaW5hbCBMaXN0PElFbGVtZW50VHlwZT4gcmVsYXRpb25zaGlwVHlwZXM7DQoNCgkJLyoqDQoJCSAqIEBnZW5lcmF0ZWQNCgkJICovDQoJCXByaXZhdGUgTGlua1Rvb2xFbnRyeShTdHJpbmcgdGl0bGUsIFN0cmluZyBkZXNjcmlwdGlvbiwNCgkJCQlMaXN0PElFbGVtZW50VHlwZT4gcmVsYXRpb25zaGlwVHlwZXMpIHsNCgkJCXN1cGVyKHRpdGxlLCBkZXNjcmlwdGlvbiwgbnVsbCwgbnVsbCk7DQoJCQl0aGlzLnJlbGF0aW9uc2hpcFR5cGVzID0gcmVsYXRpb25zaGlwVHlwZXM7DQoJCX0NCg0KCQkvKioNCgkJICogQGdlbmVyYXRlZA0KCQkgKi8NCgkJcHVibGljIFRvb2wgY3JlYXRlVG9vbCgpIHsNCgkJCVRvb2wgdG9vbCA9IG5ldyBVbnNwZWNpZmllZFR5cGVDb25uZWN0aW9uVG9vbChyZWxhdGlvbnNoaXBUeXBlcyk7DQoJCQl0b29sLnNldFByb3BlcnRpZXMoZ2V0VG9vbFByb3BlcnRpZXMoKSk7DQoJCQlyZXR1cm4gdG9vbDsNCgkJfQ0KCX0NCn0NCg==